/* * TCPVIEW * * Author: Martin Hunt * Networks and Distributed Computing * Computing & Communications * University of Washington * Administration Building, AG-44 * Seattle, WA 98195 * Internet: martinh@cac.washington.edu * * * Copyright 1992 by the University of Washington * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appears in all copies and that both the * above copyright notice and this permission notice appear in supporting * documentation, and that the name of the University of Washington not be * used in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. This software is made * available "as is", and * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "tcpview.h" #include "motif.h" #ifndef lint static char rcsid[] = "@(#) $Header: /usr/staff/martinh/tcpview/RCS/tcpview.c,v 1.2 1993/04/22 20:36:16 martinh Exp $ (UW)"; #endif /* callbacks.c */ #ifdef __STDC__ void summary_list_callback ( Widget, caddr_t, XmListCallbackStruct *); void detail_list_callback ( Widget, caddr_t, XmListCallbackStruct *); void open_callback ( Widget, char *, caddr_t); void time_callback ( Widget, char *, caddr_t); void quit_callback (Widget, caddr_t, caddr_t); void cap_opt_callback (Widget, caddr_t, caddr_t); void capture_callback (Widget, caddr_t, caddr_t); void SaveDialog (Widget, char *, void (*)() ); void PrintDialog (Widget, char *, void (*)() ); void AboutDialog (Widget, char *, void (*)() ); void FilterDialog (Widget, char *, void (*)() ); void SummaryOptionDialog (Widget, char *, void (*)() ); void readfile(char *); /* filter-dialog.c */ void init_filter(void); void FilterStream(Widget, char *, void (*)() ); void init_addrtoname(void); #else void summary_list_callback (); void detail_list_callback (); void open_callback (); void time_callback (); void quit_callback (); void cap_opt_callback (); void capture_callback (); void SaveDialog (); void PrintDialog (); void AboutDialog (); void FilterDialog (); void SummaryOptionDialog (); void readfile(); /* filter-dialog.c */ void init_filter(); void FilterStream(); void init_addrtoname(); #endif /* __STDC__ */ Widget summary_list_widget; /* summary (top) window */ Widget detail_list_widget; /* detail (middle) window */ Widget hex_text_widget; /* hex (bottom) window */ Widget packet_label; /* label in menubar which has packet count */ struct packet_header *Phdr; /* packet header of current packet */ u_int Offset; char *StrPtr; /* buffer pointer ( used by print() ) */ /* FLAGS */ int fflag=0; /* don't translate "foreign" IP address */ int nflag; /* leave addresses as numbers */ int Nflag=0; /* remove domains from printed host names */ int pflag=0; /* don't go promiscuous */ int qflag=0; /* quick (shorter) output */ int tflag; /* print packet arrival time */ int eflag; /* print ethernet header */ int vflag=0; /* verbose */ int xflag=0; /* print packet in hex */ int Oflag=1; /* run filter code optimizer */ int Sflag=0; /* print relative TCP sequence numbers */ int Rflag=0; /* read Sniffer format file */ int Wflag=0; /* write Sniffer format file */ int dflag=0; /* print filter code */ int aflag=0; /* assemble TCP packets into stream */ int zflag=0; /* write TCP or UDP data to stdout */ int Zflag=0; /* write packets and data to stdout */ int Xflag=0; /* write TCP or UDP data in hex */ u_short Line_Flag; u_short Man_Flag; extern int MaxBytes; extern char *Device; char *program_name; char FileName1[128]; extern char PrintName[128]; char HostFile[128], ManufFile[128], ServicesFile[128], FilterDir[128], Viewer[128]; char PrintCommand[64]; typedef struct _params { char *hostnames; char *manuf; char *services; char *filters; char *viewer; char *printcom; char *device; int time; int verbose; int maxbytes; Boolean foreign; Boolean domain; Boolean numeric; Boolean use_manuf; Boolean dlc; Boolean relative_seq; Boolean lines; } params, *params_ptr; static XtResource resources[] = { { "hostnames", "Hostnames", XtRString, sizeof(String), XtOffset(params_ptr, hostnames), XtRString, "/usr/local/lib/tcpview/hosts" }, { "manuf", "Manuf", XtRString, sizeof(String), XtOffset(params_ptr, manuf), XtRString, "/usr/local/lib/tcpview/manuf" }, { "services", "Services", XtRString, sizeof(String), XtOffset(params_ptr, services), XtRString, "/etc/services" }, { "filters", "Filters", XtRString, sizeof(String), XtOffset(params_ptr, filters), XtRString, "/usr/local/lib/tcpview/filters" }, { "viewer", "Viewer", XtRString, sizeof(String), XtOffset(params_ptr, viewer), XtRString, "*" }, { "printcommand", "Printcommand", XtRString, sizeof(String), XtOffset(params_ptr, printcom), XtRString, "lpr" }, { "device", "Device", XtRString, sizeof(String), XtOffset(params_ptr, device), XtRString, "" }, { "foreign", "Foreign", XtRBoolean, sizeof(Boolean), XtOffset(params_ptr, foreign), XtRString, "TRUE" }, { "domain", "Domain", XtRBoolean, sizeof(Boolean), XtOffset(params_ptr, domain), XtRString, "FALSE" }, { "numeric", "Numeric", XtRBoolean, sizeof(Boolean), XtOffset(params_ptr, numeric), XtRString, "FALSE" }, { "use_manuf", "Use_Manuf", XtRBoolean, sizeof(Boolean), XtOffset(params_ptr, use_manuf), XtRString, "TRUE" }, { "dlc", "DLC", XtRBoolean, sizeof(Boolean), XtOffset(params_ptr, dlc), XtRString, "FALSE" }, { "relative_seq", "Realtive_Seq", XtRBoolean, sizeof(Boolean), XtOffset(params_ptr, relative_seq), XtRString, "TRUE" }, { "lines", "Lines", XtRBoolean, sizeof(Boolean), XtOffset(params_ptr, lines), XtRString, "FALSE" }, { "time", "Time", XtRInt, sizeof(int), XtOffset(params_ptr, time), XtRString, "4" }, { "verbose", "Verbose", XtRInt, sizeof(int), XtOffset(params_ptr, verbose), XtRString, "1" }, { "maxbytes", "MaxBytes", XtRInt, sizeof(int), XtOffset(params_ptr, maxbytes), XtRString, "68" } }; void main(argc, argv) int argc; char **argv; { Widget parent, pane_widget, menu_bar; Widget opt_menu, file_menu, filter_menu, help_menu, capture_menu; Arg args[10]; int n; XmString ms; params par; program_name=argv[0]; parent = XtInitialize( argv[0],"Tcpview",NULL,0,&argc,argv ); /* read in initial parameters from resource file */ XtGetApplicationResources(parent, &par, resources, XtNumber(resources), NULL, 0); strcpy(HostFile,par.hostnames); strcpy(ManufFile,par.manuf); strcpy(ServicesFile,par.services); strcpy(FilterDir,par.filters); strcpy(Viewer,par.viewer); strcpy(PrintCommand,par.printcom); if( *(par.device) ) Device = par.device; tflag = par.time; if( par.verbose==0 ) qflag=1; else if( par.verbose==2 ) vflag=1; if( par.domain==0 ) Nflag=1; nflag = par.numeric; Man_Flag = par.use_manuf; eflag = par.dlc; if(par.relative_seq==0) Sflag = 1; Line_Flag = par.lines; MaxBytes = par.maxbytes; *PrintName='\0'; if( argc > 1 && *argv[argc-1] != '-' ) strcpy(FileName1,argv[argc-1]); else FileName1[0]='\0'; init_addrtoname(); init_filter(); n = 0; XtSetArg( args[n], XmNallowShellResize, True ); n++; XtSetValues( parent, args, n ); n=0; XtSetArg( args[n], XmNallowResize, True ); n++; pane_widget = XtCreateManagedWidget("pane",xmPanedWindowWidgetClass, parent,args,n); n = 0; menu_bar = XmCreateMenuBar(pane_widget, "menu_bar", args, n); XtManageChild (menu_bar); file_menu = simple_menu(menu_bar,"File ",'F'); simple_menu_call(file_menu,"Open",'O',False,open_callback); simple_menu_call(file_menu,"Save",'S',False,SaveDialog); simple_menu_call(file_menu,"Print",'P',False,PrintDialog); simple_menu_call(file_menu,"About",'A',False,AboutDialog); simple_menu_call(file_menu,"Exit",'x',True,quit_callback); capture_menu = simple_menu(menu_bar,"Capture ",'C'); simple_menu_call(capture_menu,"Set Options",'S',False,cap_opt_callback); simple_menu_call(capture_menu,"GO",'G',False,capture_callback); filter_menu = simple_menu(menu_bar,"Filter ",'l'); simple_menu_call(filter_menu,"Edit",'E',False,FilterDialog); simple_menu_call(filter_menu,"Follow Stream",'F',False,FilterStream); /* simple_menu_call(filter_menu,"Search for String",'S',False,StringSearch); */ opt_menu = simple_menu(menu_bar,"Options ",'O'); simple_menu_call(opt_menu,"Summary Options",'S',False,SummaryOptionDialog); /* simple_menu_item(opt_menu,"Detail Options",'D',False); */ ms = XmStringCreateSimple(" "); n = 0; XtSetArg( args[n], XmNlabelString, ms ); n++; packet_label = XmCreateCascadeButton( menu_bar,"pack_list", args, n ); XtManageChild( packet_label ); XmStringFree( ms ); help_menu = simple_menu(menu_bar,"Help",'H'); n = 0; summary_list_widget = CreateScrolledList( pane_widget, "SummaryList", args, n, summary_list_callback ); n = 0; /* XtSetArg( args[n], XmNvisibleItemCount, 10 ); n++; */ detail_list_widget = CreateScrolledList( pane_widget, "DetailList", args, n, detail_list_callback ); n = 0; XtSetArg( args[n], XmNeditable, False ); n++; /* XtSetArg( args[n], XmNrows, 15 ); n++; */ XtSetArg( args[n], XmNresizeWidth, True ); n++; XtSetArg( args[n], XmNresizeHeight, True ); n++; XtSetArg( args[n], XmNscrollHorizontal, False ); n++; XtSetArg( args[n], XmNscrollVertical, True ); n++; XtSetArg( args[n], XmNeditMode, XmMULTI_LINE_EDIT ); n++; XtSetArg( args[n], XmNcursorPositionVisible, False ); n++; hex_text_widget = XmCreateScrolledText( pane_widget, "Hex", args, n); XtManageChild(hex_text_widget); XtRealizeWidget( parent ); if(*FileName1) readfile(FileName1); XtMainLoop(); } void default_print(sp, length) register u_char *sp; register int length; { char *p; static char *buffer=NULL; #ifdef __STDC__ void hd(u_char *, u_char *, int); #else void hd(); #endif if( Xfile==NULL) return; if (buffer==NULL) buffer = (char *)malloc(10000); hd( buffer, sp, length ); fwrite( "\t", 1, 1, Xfile ); p = buffer; while( *p ) { if( *p=='\n' ) fwrite( "\n\t", 1, 2, Xfile ); else fwrite( p, 1, 1, Xfile ); p++; } fwrite( "\n", 1, 1, Xfile ); } struct hexdetail { short start; short stop; }; static struct hexdetail hexlist[128]; /* support up to 128 lines of detail */ static int line; /* Line counter for hexlist */ void hex( start, stop ) int start, stop; { if( start >= 0 ) hexlist[line].start = Offset + start; else hexlist[line].start = -1; if( stop >= 0 ) hexlist[line++].stop = Offset + stop; else hexlist[line++].stop = -1; } void hex_reset() { line = 0; } int hex_start( position ) int position; { return hexlist[position].start; } int hex_stop( position ) int position; { return hexlist[position].stop; }