1 /*
2 * TCPVIEW
3 *
4 * Author: Martin Hunt
5 * Networks and Distributed Computing
6 * Computing & Communications
7 * University of Washington
8 * Administration Building, AG-44
9 * Seattle, WA 98195
10 * Internet: martinh@cac.washington.edu
11 *
12 *
13 * Copyright 1992 by the University of Washington
14 *
15 * Permission to use, copy, modify, and distribute this software and its
16 * documentation for any purpose and without fee is hereby granted, provided
17 * that the above copyright notice appears in all copies and that both the
18 * above copyright notice and this permission notice appear in supporting
19 * documentation, and that the name of the University of Washington not be
20 * used in advertising or publicity pertaining to distribution of the software
21 * without specific, written prior permission. This software is made
22 * available "as is", and
23 * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
24 * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
26 * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
27 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
28 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
29 * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
30 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 *
32 */
33
34 #include <stdio.h>
35 #include <sys/types.h>
36 #include <limits.h>
37 #include <X11/Xlib.h>
38 #include <X11/Intrinsic.h>
39 #include <X11/StringDefs.h>
40 #include <Xm/Xm.h>
41 #include <Xm/List.h>
42 #include <Xm/PanedW.h>
43 #include <Xm/Text.h>
44 #include <Xm/RowColumn.h>
45 #include <Xm/CascadeB.h>
46 #include "tcpview.h"
47 #include "motif.h"
48
49 #ifndef lint
50 static char rcsid[] =
51 "@(#) $Header: /usr/staff/martinh/tcpview/RCS/tcpview.c,v 1.2 1993/04/22 20:36:16 martinh Exp $ (UW)";
52 #endif
53
54 /* callbacks.c */
55 #ifdef __STDC__
56 void summary_list_callback ( Widget, caddr_t, XmListCallbackStruct *);
57 void detail_list_callback ( Widget, caddr_t, XmListCallbackStruct *);
58 void open_callback ( Widget, char *, caddr_t);
59 void time_callback ( Widget, char *, caddr_t);
60 void quit_callback (Widget, caddr_t, caddr_t);
61 void cap_opt_callback (Widget, caddr_t, caddr_t);
62 void capture_callback (Widget, caddr_t, caddr_t);
63 void SaveDialog (Widget, char *, void (*)() );
64 void PrintDialog (Widget, char *, void (*)() );
65 void AboutDialog (Widget, char *, void (*)() );
66 void FilterDialog (Widget, char *, void (*)() );
67 void SummaryOptionDialog (Widget, char *, void (*)() );
68 void readfile(char *);
69 /* filter-dialog.c */
70 void init_filter(void);
71 void FilterStream(Widget, char *, void (*)() );
72 void init_addrtoname(void);
73 #else
74 void summary_list_callback ();
75 void detail_list_callback ();
76 void open_callback ();
77 void time_callback ();
78 void quit_callback ();
79 void cap_opt_callback ();
80 void capture_callback ();
81 void SaveDialog ();
82 void PrintDialog ();
83 void AboutDialog ();
84 void FilterDialog ();
85 void SummaryOptionDialog ();
86 void readfile();
87 /* filter-dialog.c */
88 void init_filter();
89 void FilterStream();
90 void init_addrtoname();
91 #endif /* __STDC__ */
92
93 Widget summary_list_widget; /* summary (top) window */
94 Widget detail_list_widget; /* detail (middle) window */
95 Widget hex_text_widget; /* hex (bottom) window */
96 Widget packet_label; /* label in menubar which has packet count */
97
98 struct packet_header *Phdr; /* packet header of current packet */
99 u_int Offset;
100 char *StrPtr; /* buffer pointer ( used by print() ) */
101
102 /* FLAGS */
103 int fflag=0; /* don't translate "foreign" IP address */
104 int nflag; /* leave addresses as numbers */
105 int Nflag=0; /* remove domains from printed host names */
106 int pflag=0; /* don't go promiscuous */
107 int qflag=0; /* quick (shorter) output */
108 int tflag; /* print packet arrival time */
109 int eflag; /* print ethernet header */
110 int vflag=0; /* verbose */
111 int xflag=0; /* print packet in hex */
112 int Oflag=1; /* run filter code optimizer */
113 int Sflag=0; /* print relative TCP sequence numbers */
114 int Rflag=0; /* read Sniffer format file */
115 int Wflag=0; /* write Sniffer format file */
116 int dflag=0; /* print filter code */
117 int aflag=0; /* assemble TCP packets into stream */
118 int zflag=0; /* write TCP or UDP data to stdout */
119 int Zflag=0; /* write packets and data to stdout */
120 int Xflag=0; /* write TCP or UDP data in hex */
121
122 u_short Line_Flag;
123 u_short Man_Flag;
124
125 extern int MaxBytes;
126 extern char *Device;
127
128 char *program_name;
129 char FileName1[128];
130 extern char PrintName[128];
131
132 char HostFile[128], ManufFile[128], ServicesFile[128], FilterDir[128], Viewer[128];
133 char PrintCommand[64];
134
135 typedef struct _params {
136 char *hostnames;
137 char *manuf;
138 char *services;
139 char *filters;
140 char *viewer;
141 char *printcom;
142 char *device;
143 int time;
144 int verbose;
145 int maxbytes;
146 Boolean foreign;
147 Boolean domain;
148 Boolean numeric;
149 Boolean use_manuf;
150 Boolean dlc;
151 Boolean relative_seq;
152 Boolean lines;
153 } params, *params_ptr;
154
155
156 static XtResource resources[] = {
157 { "hostnames", "Hostnames", XtRString, sizeof(String),
158 XtOffset(params_ptr, hostnames), XtRString, "/usr/local/lib/tcpview/hosts" },
159 { "manuf", "Manuf", XtRString, sizeof(String),
160 XtOffset(params_ptr, manuf), XtRString, "/usr/local/lib/tcpview/manuf" },
161 { "services", "Services", XtRString, sizeof(String),
162 XtOffset(params_ptr, services), XtRString, "/etc/services" },
163 { "filters", "Filters", XtRString, sizeof(String),
164 XtOffset(params_ptr, filters), XtRString, "/usr/local/lib/tcpview/filters" },
165 { "viewer", "Viewer", XtRString, sizeof(String),
166 XtOffset(params_ptr, viewer), XtRString, "*" },
167 { "printcommand", "Printcommand", XtRString, sizeof(String),
168 XtOffset(params_ptr, printcom), XtRString, "lpr" },
169 { "device", "Device", XtRString, sizeof(String),
170 XtOffset(params_ptr, device), XtRString, "" },
171 { "foreign", "Foreign", XtRBoolean, sizeof(Boolean),
172 XtOffset(params_ptr, foreign), XtRString, "TRUE" },
173 { "domain", "Domain", XtRBoolean, sizeof(Boolean),
174 XtOffset(params_ptr, domain), XtRString, "FALSE" },
175 { "numeric", "Numeric", XtRBoolean, sizeof(Boolean),
176 XtOffset(params_ptr, numeric), XtRString, "FALSE" },
177 { "use_manuf", "Use_Manuf", XtRBoolean, sizeof(Boolean),
178 XtOffset(params_ptr, use_manuf), XtRString, "TRUE" },
179 { "dlc", "DLC", XtRBoolean, sizeof(Boolean),
180 XtOffset(params_ptr, dlc), XtRString, "FALSE" },
181 { "relative_seq", "Realtive_Seq", XtRBoolean, sizeof(Boolean),
182 XtOffset(params_ptr, relative_seq), XtRString, "TRUE" },
183 { "lines", "Lines", XtRBoolean, sizeof(Boolean),
184 XtOffset(params_ptr, lines), XtRString, "FALSE" },
185 { "time", "Time", XtRInt, sizeof(int),
186 XtOffset(params_ptr, time), XtRString, "4" },
187 { "verbose", "Verbose", XtRInt, sizeof(int),
188 XtOffset(params_ptr, verbose), XtRString, "1" },
189 { "maxbytes", "MaxBytes", XtRInt, sizeof(int),
190 XtOffset(params_ptr, maxbytes), XtRString, "68" }
191 };
192
main(argc,argv)193 void main(argc, argv)
194 int argc;
195 char **argv;
196 {
197 Widget parent, pane_widget, menu_bar;
198 Widget opt_menu, file_menu, filter_menu, help_menu, capture_menu;
199 Arg args[10];
200 int n;
201 XmString ms;
202 params par;
203
204 program_name=argv[0];
205
206 parent = XtInitialize( argv[0],"Tcpview",NULL,0,&argc,argv );
207
208 /* read in initial parameters from resource file */
209
210 XtGetApplicationResources(parent, &par, resources, XtNumber(resources), NULL, 0);
211 strcpy(HostFile,par.hostnames);
212 strcpy(ManufFile,par.manuf);
213 strcpy(ServicesFile,par.services);
214 strcpy(FilterDir,par.filters);
215 strcpy(Viewer,par.viewer);
216 strcpy(PrintCommand,par.printcom);
217 if( *(par.device) )
218 Device = par.device;
219 tflag = par.time;
220 if( par.verbose==0 )
221 qflag=1;
222 else if( par.verbose==2 )
223 vflag=1;
224 if( par.domain==0 ) Nflag=1;
225 nflag = par.numeric;
226 Man_Flag = par.use_manuf;
227 eflag = par.dlc;
228 if(par.relative_seq==0)
229 Sflag = 1;
230 Line_Flag = par.lines;
231 MaxBytes = par.maxbytes;
232 *PrintName='\0';
233
234 if( argc > 1 && *argv[argc-1] != '-' )
235 strcpy(FileName1,argv[argc-1]);
236 else
237 FileName1[0]='\0';
238
239 init_addrtoname();
240 init_filter();
241
242 n = 0;
243 XtSetArg( args[n], XmNallowShellResize, True ); n++;
244 XtSetValues( parent, args, n );
245
246 n=0;
247 XtSetArg( args[n], XmNallowResize, True ); n++;
248 pane_widget = XtCreateManagedWidget("pane",xmPanedWindowWidgetClass,
249 parent,args,n);
250 n = 0;
251 menu_bar = XmCreateMenuBar(pane_widget, "menu_bar", args, n);
252 XtManageChild (menu_bar);
253
254 file_menu = simple_menu(menu_bar,"File ",'F');
255 simple_menu_call(file_menu,"Open",'O',False,open_callback);
256 simple_menu_call(file_menu,"Save",'S',False,SaveDialog);
257 simple_menu_call(file_menu,"Print",'P',False,PrintDialog);
258 simple_menu_call(file_menu,"About",'A',False,AboutDialog);
259 simple_menu_call(file_menu,"Exit",'x',True,quit_callback);
260
261 capture_menu = simple_menu(menu_bar,"Capture ",'C');
262 simple_menu_call(capture_menu,"Set Options",'S',False,cap_opt_callback);
263 simple_menu_call(capture_menu,"GO",'G',False,capture_callback);
264
265 filter_menu = simple_menu(menu_bar,"Filter ",'l');
266 simple_menu_call(filter_menu,"Edit",'E',False,FilterDialog);
267 simple_menu_call(filter_menu,"Follow Stream",'F',False,FilterStream);
268 /* simple_menu_call(filter_menu,"Search for String",'S',False,StringSearch); */
269
270 opt_menu = simple_menu(menu_bar,"Options ",'O');
271 simple_menu_call(opt_menu,"Summary Options",'S',False,SummaryOptionDialog);
272 /* simple_menu_item(opt_menu,"Detail Options",'D',False); */
273
274 ms = XmStringCreateSimple(" ");
275 n = 0;
276 XtSetArg( args[n], XmNlabelString, ms ); n++;
277 packet_label = XmCreateCascadeButton( menu_bar,"pack_list", args, n );
278 XtManageChild( packet_label );
279 XmStringFree( ms );
280
281 help_menu = simple_menu(menu_bar,"Help",'H');
282
283 n = 0;
284 summary_list_widget = CreateScrolledList( pane_widget,
285 "SummaryList",
286 args, n,
287 summary_list_callback );
288 n = 0;
289 /* XtSetArg( args[n], XmNvisibleItemCount, 10 ); n++; */
290 detail_list_widget = CreateScrolledList( pane_widget,
291 "DetailList",
292 args, n,
293 detail_list_callback );
294 n = 0;
295 XtSetArg( args[n], XmNeditable, False ); n++;
296 /* XtSetArg( args[n], XmNrows, 15 ); n++; */
297 XtSetArg( args[n], XmNresizeWidth, True ); n++;
298 XtSetArg( args[n], XmNresizeHeight, True ); n++;
299 XtSetArg( args[n], XmNscrollHorizontal, False ); n++;
300 XtSetArg( args[n], XmNscrollVertical, True ); n++;
301 XtSetArg( args[n], XmNeditMode, XmMULTI_LINE_EDIT ); n++;
302 XtSetArg( args[n], XmNcursorPositionVisible, False ); n++;
303
304 hex_text_widget = XmCreateScrolledText( pane_widget, "Hex", args, n);
305 XtManageChild(hex_text_widget);
306 XtRealizeWidget( parent );
307 if(*FileName1) readfile(FileName1);
308 XtMainLoop();
309 }
310
default_print(sp,length)311 void default_print(sp, length)
312 register u_char *sp;
313 register int length;
314 {
315 char *p;
316 static char *buffer=NULL;
317
318 #ifdef __STDC__
319 void hd(u_char *, u_char *, int);
320 #else
321 void hd();
322 #endif
323
324 if( Xfile==NULL)
325 return;
326
327 if (buffer==NULL)
328 buffer = (char *)malloc(10000);
329 hd( buffer, sp, length );
330 fwrite( "\t", 1, 1, Xfile );
331
332 p = buffer;
333 while( *p ) {
334 if( *p=='\n' )
335 fwrite( "\n\t", 1, 2, Xfile );
336 else
337 fwrite( p, 1, 1, Xfile );
338 p++;
339 }
340 fwrite( "\n", 1, 1, Xfile );
341 }
342
343 struct hexdetail {
344 short start;
345 short stop;
346 };
347
348 static struct hexdetail hexlist[128]; /* support up to 128 lines of detail */
349 static int line; /* Line counter for hexlist */
350
hex(start,stop)351 void hex( start, stop )
352 int start, stop;
353 {
354 if( start >= 0 )
355 hexlist[line].start = Offset + start;
356 else
357 hexlist[line].start = -1;
358
359 if( stop >= 0 )
360 hexlist[line++].stop = Offset + stop;
361 else
362 hexlist[line++].stop = -1;
363 }
364
hex_reset()365 void hex_reset()
366 {
367 line = 0;
368 }
369
hex_start(position)370 int hex_start( position )
371 int position;
372 {
373 return hexlist[position].start;
374 }
375
hex_stop(position)376 int hex_stop( position )
377 int position;
378 {
379 return hexlist[position].stop;
380 }
381
382
383
384
385
386