/* * 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. * */ #ifndef lint static char rcsid[] = "@(#) $Header: /usr/staff/martinh/tcpview/RCS/filter-stream.c,v 1.2 1993/04/22 20:19:39 martinh Exp $ (UW)"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tcpview.h" #include "filter.h" #include "motif.h" #ifdef __STDC__ void show_text( char *, char * ); static void help_callback( Widget, char *, caddr_t ); static void cancel_callback( Widget, char *, caddr_t ); static void dir_callback( Widget, caddr_t, caddr_t ); static void ooo_callback( Widget, caddr_t, caddr_t ); static void timeout_callback( Widget, caddr_t, caddr_t ); static void time_callback(); static void filtername_callback( Widget, char *, caddr_t); static void filter_cancel_callback(); static void filter_ok_callback(); static void filterstream( Widget, char *, caddr_t ); static void update_external_filter(void); static void ext_callback( Widget, char *, caddr_t ); static void extfil_callback( Widget, char *, caddr_t ); static void extfra_callback( Widget, char *, caddr_t ); static void data_callback( Widget, char *, caddr_t ); void update_fstr(struct filter *); void redisplay_entire_list(void); #else void show_text(); static void help_callback(); static void cancel_callback(); static void dir_callback(); static void ooo_callback(); static void timeout_callback(); static void time_callback(); static void filtername_callback(); static void filter_cancel_callback(); static void filter_ok_callback(); static void filterstream(); static void update_external_filter(); static void ext_callback(); static void extfil_callback(); static void extfra_callback(); static void data_callback(); void update_fstr(); void redisplay_entire_list(); #endif /* __STDC__ */ static u_short filter_direction=1; static u_short DataFormat; static char *DataFormatStr[] = { "BINARY","HEX" }; static Widget bb_widget, timeout_widget; extern char Fstr[]; /* filter-dialog.c */ static char *protostr[] = { "ALL","IP","ARP","RARP","ICMP","UDP","TCP" }; char D_Src_Host[64], D_Dst_Host[64], D_Proto[8]; u_short D_Src_Port=0, D_Dst_Port=0; static u_short ExternalOn=0; static u_short ExternalFil = 0; static u_short ExternalFra = 0; static Widget ExOn, ExFil, ExFilNam, ExFra, ExLab, ExtW[2], DataLab, DataPB; static char ExFilterBName[32], ExFilterName[128], ExFileName[128]; static char *extstr1[] = { "DON'T"," DO " }; static char *extstr2[] = { "DATA", "FRAMES and DATA" }; static char *extstr3[] = { "FILTER", "FILE", "WINDOW" }; FILE *Xfile; /* These are global flags that determine if a packet is highlighted or not */ u_short HighlightTimeout, AssembleOOO; u_short HighlightPacket = 0; /* Ho and Ht are the permanent state variables for highlighting */ static u_short Ho = 0; static u_short Ht = 0; struct timeval Timeout; void FilterStream(parent, nam, callback) Widget parent; char *nam; void (*callback)(); { Widget rb, rc, rd, frame, main_row; Arg args[10]; int n; char str[20]; HighlightTimeout = Ht; AssembleOOO = Ho; n=0; XtSetArg( args[n], XmNautoUnmanage, False ); n++; XtSetArg( args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL ); n++; bb_widget = XmCreateBulletinBoardDialog (parent,"filterstream",args,n); n = 0; XtSetArg( args[n], XmNorientation, XmVERTICAL ); n++; main_row = XmCreateRowColumn( bb_widget,"main",args,n); XtManageChild( main_row ); n=0; CreateLabelWidget (main_row, "filterstreamlabel"," STREAM FILTER OPTIONS ",args,n); n=0; XtSetArg ( args[n], XmNshadowThickness, 4 ); n++; frame = XmCreateFrame (main_row,"frame",args,n); XtManageChild(frame); n = 0; XtSetArg( args[n], XmNorientation, XmVERTICAL ); n++; rc = XmCreateRowColumn( frame,"row",args,n); XtManageChild( rc ); n=0; CreateLabelWidget (rc, "xxx"," STREAM ",args,n); rb = CreateRadioBox(rc, "dir"); CreateSimpleToggle( rb, "unidirectional",filter_direction==0,XmONE_OF_MANY,dir_callback,(caddr_t)0); CreateSimpleToggle( rb, "bidirectional",filter_direction,XmONE_OF_MANY,dir_callback,(caddr_t)1); XtManageChild( rb ); /* create a new frame and options */ n=0; XtSetArg ( args[n], XmNshadowThickness, 4 ); n++; frame = XmCreateFrame (main_row,"frame",args,n); XtManageChild(frame); n = 0; XtSetArg( args[n], XmNorientation, XmVERTICAL ); n++; rc = XmCreateRowColumn( frame,"row",args,n); XtManageChild( rc ); n=0; CreateLabelWidget (rc, "xxx"," TCP OPTIONS ",args,n); n = 0; XtSetArg( args[n], XmNorientation, XmVERTICAL ); n++; rb = XmCreateRowColumn( rc,"other",args,n); CreateSimpleToggle( rb, "Assemble Out-Of-Order Packets",AssembleOOO,XmN_OF_MANY,ooo_callback,0); CreateSimpleToggle( rb, "Highlight Timeouts",HighlightTimeout,XmN_OF_MANY, timeout_callback,(caddr_t)0); n=0; XtSetArg( args[n], XmNorientation, XmHORIZONTAL ); n++; rd = XmCreateRowColumn( rb,"data",args,n); XtManageChild( rd ); n=0; (void)CreateLabelWidget( rd, "","Timeout Interval is ",args,n ); (void)sprintf(str,"%d.%d",Timeout.tv_sec,Timeout.tv_usec); timeout_widget = CreateSimpleButton( rd, str, timeout_callback, (caddr_t)1 ); (void)CreateLabelWidget( rd, "","Seconds.",args, n ); XtManageChild( rb ); /** EXTERNAL FILTER **/ /* create a new frame and options */ n=0; XtSetArg ( args[n], XmNshadowThickness, 4 ); n++; frame = XmCreateFrame (main_row,"frame",args,n); XtManageChild(frame); n = 0; XtSetArg( args[n], XmNorientation, XmVERTICAL ); n++; rc = XmCreateRowColumn( frame,"row",args,n); XtManageChild( rc ); n=0; CreateLabelWidget (rc, "xxx"," EXTERNAL FILTER ",args,n); n=0; XtSetArg( args[n], XmNorientation, XmHORIZONTAL ); n++; rb = XmCreateRowColumn( rc,"data",args,n); XtManageChild( rb ); n=0; ExOn = CreateSimpleButton( rb, extstr1[ExternalOn], ext_callback, (caddr_t)0 ); ExtW[0] = CreateLabelWidget( rb, "","Send",args,n ); ExFra = CreateSimpleButton( rb, extstr2[ExternalFra], extfra_callback, (caddr_t)0 ); ExtW[1] = CreateLabelWidget( rb, "","To External",args,n ); ExFil = CreateSimpleButton( rb, extstr3[ExternalFil], extfil_callback, (caddr_t)0 ); n=0; XtSetArg( args[n], XmNorientation, XmHORIZONTAL ); n++; rb = XmCreateRowColumn( rc,"data",args,n); XtManageChild( rb ); n=0; if( ExternalFil ) { ExLab = CreateLabelWidget( rb, "", "External File Name", args, n ); if( *ExFileName=='\0') strcpy( ExFileName, "foobar" ); ExFilNam= CreateSimpleButton( rb, ExFileName, filtername_callback, (caddr_t)0 ); } else { ExLab = CreateLabelWidget( rb, "", "External Filter Name", args, n ); if( *ExFilterBName=='\0') strcpy( ExFilterBName, " " ); ExFilNam= CreateSimpleButton( rb, ExFilterBName, filtername_callback, (caddr_t)0 ); } n=0; XtSetArg( args[n], XmNorientation, XmHORIZONTAL ); n++; rb = XmCreateRowColumn( rc,"data",args,n); XtManageChild( rb ); DataLab = CreateLabelWidget( rb, "", "Data Format", args, n ); DataPB = CreateSimpleButton( rb, DataFormatStr[DataFormat], data_callback, NULL ); if( ExternalOn==0 ) { for( n=0;n<2;n++ ) XtSetSensitive( ExtW[n], False ); XtSetSensitive( ExFra, False ); XtSetSensitive( ExFil, False ); XtSetSensitive( ExLab, False ); } XtSetSensitive( ExFilNam, ExternalOn&&(ExternalFil<2) ); XtSetSensitive( DataLab, ExternalOn&&ExternalFil ); XtSetSensitive( DataPB, ExternalOn&&ExternalFil ); /* create FILTER, CANCEL, HELP buttons */ /* create a form to hold OK, Cancel, and Help buttons */ n = 0; rc = XtCreateManagedWidget("buttons", xmFormWidgetClass,main_row,args,n); /* create 'Filter' pushbutton */ n = 0; /* XtSetArg( args[n], XmNshowAsDefault, 1 ); n++; */ XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNrightPosition, 30); n++; rb = CreatePushButton( rc, "Filter", "Filter" ,args, n, filterstream ); /* Set OK button as default */ BulletinDefaultButton( bb_widget, rb ); /* create 'Cancel' pushbutton */ n = 0; XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNleftPosition, 35); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNrightPosition, 65); n++; (void)CreatePushButton( rc, "Cancel", "Cancel", args, n, cancel_callback ); /* create 'Help' pushbutton */ n = 0; XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNleftPosition, 70); n++; rb = CreatePushButton( rc, "Help", "Help", args, n, help_callback ); /* turn off 'Help' pushbutton for now */ XtSetSensitive( rb, False ); XtManageChild(rc); XtManageChild(bb_widget); } static void dir_callback( widget, data, foo ) Widget widget; caddr_t data; caddr_t foo; { filter_direction = (int)data; } /* dir_callback */ static void ooo_callback( widget, data, foo ) Widget widget; caddr_t data; caddr_t foo; { if( AssembleOOO ) { AssembleOOO = 0; aflag = 0; } else { AssembleOOO = 1; aflag = 1; } } /* ooo_callback */ static void timeout_callback( widget, data, foo ) Widget widget; caddr_t data; caddr_t foo; { Widget w; Arg args[2]; int n; XmString ms; if( data ) { /* request new timeout value */ ms = XmStringCreateSimple("Timeout value in seconds"); n = 0; XtSetArg (args[n], XmNselectionLabelString, ms); n++; XtSetArg( args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL ); n++; w = XmCreatePromptDialog( bb_widget, "Timeout Selection",args,n); XtAddCallback( w, XmNokCallback, time_callback, (caddr_t)0); XtManageChild( w ); XmStringFree( ms ); } else { /* just toggle HighlightTimeout */ if( HighlightTimeout ) HighlightTimeout = 0; else HighlightTimeout = 1; } } /* timeout_callback */ static void time_callback( widget, data, foo ) Widget widget; char *data; XmSelectionBoxCallbackStruct *foo; { char *string; char str[20]; XtUnmanageChild(widget); XmStringGetLtoR( foo->value, XmSTRING_DEFAULT_CHARSET, &string); Timeout.tv_sec = atoi(string); Timeout.tv_usec = (atof(string) - (double)(Timeout.tv_sec))*1000000; /* don't allow a timeout of <= 0.0 seconds */ if( (Timeout.tv_usec==0 && Timeout.tv_sec==0) || Timeout.tv_sec < 0 || Timeout.tv_usec < 0 ) { Timeout.tv_sec = 1; Timeout.tv_usec = 0; } sprintf(str,"%d.%d",Timeout.tv_sec,Timeout.tv_usec); SetLabel(timeout_widget,str); } static void help_callback( widget, name, call_data ) Widget widget; char *name; caddr_t call_data; { } /* help_callback */ static void ext_callback( widget, name, call_data ) Widget widget; char *name; caddr_t call_data; { if( ExternalOn ) ExternalOn = 0; else ExternalOn = 1; update_external_filter(); } /* ext_callback */ static void data_callback( widget, name, call_data ) Widget widget; char *name; caddr_t call_data; { if( DataFormat ) DataFormat = 0; else DataFormat = 1; update_external_filter(); } /* ext_callback */ static void extfil_callback( widget, name, call_data ) Widget widget; char *name; caddr_t call_data; { if( ++ExternalFil == 3 ) ExternalFil = 0; update_external_filter(); } /* ext_callback */ static void extfra_callback( widget, name, call_data ) Widget widget; char *name; caddr_t call_data; { if( ExternalFra ) ExternalFra = 0; else ExternalFra = 1; update_external_filter(); } /* ext_callback */ static void filterstream(parent, nam, foo) Widget parent; char *nam; caddr_t foo; { struct filter filt; struct address_filter *f; int i; char str[128], *temp, Xfilename[128]; extern char Viewer[]; void reset_tcp_assembly(); XtUnmanageChild( bb_widget ); reset_tcp_assembly(); if( D_Src_Port==0 && D_Dst_Port==0 ) return; f = &filt.addr[0]; f->level = 0; /* IP */ strcpy(f->address1,D_Src_Host); strcpy(f->address2,D_Dst_Host); f->direction = filter_direction; f->include = 1; f->and = 1; filt.protocol = 0; for(i=1;i %s\n",Xfilename,ExFilterName,temp ); else sprintf( str, "cat %s | %s > %s\n",Xfilename,ExFilterName,temp ); (void)system( str ); unlink( Xfilename ); strcpy( Xfilename, temp ); } if( ExternalFil != 1 ) { if( *Viewer == '*' ) { show_text( Xfilename, ExFilterBName ); unlink( Xfilename ); } else { sprintf( str, "( %s %s ; rm %s ) &", Viewer, Xfilename, Xfilename ); system( str ); } } } /* reset all global state variables */ *Fstr = '\0'; reset_tcp_assembly(); Ho = AssembleOOO; Ht = HighlightTimeout; AssembleOOO = 0; HighlightTimeout = 0; aflag = Zflag = zflag = Xflag = 0; } static void cancel_callback( widget, name, foo ) Widget widget; char *name; caddr_t foo; { XtUnmanageChild( bb_widget ); AssembleOOO = 0; HighlightTimeout = 0; aflag = 0; } static void update_external_filter() { int n; SetLabel( ExOn, extstr1[ExternalOn] ); SetLabel( ExFra, extstr2[ExternalFra] ); SetLabel( ExFil, extstr3[ExternalFil] ); if( ExternalFil ) { SetLabel( ExLab, "External File Name" ); if( *ExFileName=='\0') strcpy( ExFileName, "foobar" ); SetLabel( ExFilNam, ExFileName ); } else { SetLabel( ExLab, "External Filter Name" ); if( *ExFilterBName=='\0') strcpy( ExFilterBName, " " ); SetLabel( ExFilNam, ExFilterBName ); } SetLabel( DataPB, DataFormatStr[DataFormat] ); for( n=0;n<2;n++ ) XtSetSensitive( ExtW[n], ExternalOn ); XtSetSensitive( ExFra, ExternalOn ); XtSetSensitive( ExFil, ExternalOn ); XtSetSensitive( ExLab, ExternalOn&&(ExternalFil<2) ); XtSetSensitive( ExFilNam, ExternalOn&&(ExternalFil<2) ); XtSetSensitive( DataLab, ExternalOn&&ExternalFil); XtSetSensitive( DataPB, ExternalOn&&ExternalFil); } static void filtername_callback( widget, name, call_data ) Widget widget; char *name; caddr_t call_data; { Widget help, filew; Arg args[5]; int t=0, n=0; XmString xms; extern char FilterDir[]; if( !ExternalFil && *FilterDir ) { xms = XmStringCreateSimple(FilterDir); XtSetArg( args[n], XmNdirectory, xms); n++; t = 1; } XtSetArg( args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL ); n++; filew = XmCreateFileSelectionDialog( widget,"XX",args,n); XtAddCallback(filew, XmNokCallback, filter_ok_callback, 0); XtAddCallback(filew, XmNcancelCallback, filter_cancel_callback, 0); help = XmFileSelectionBoxGetChild(filew,XmDIALOG_HELP_BUTTON); XtUnmanageChild( help ); XtManageChild( filew ); if( t ) XmStringFree(xms); } /* filtername_callback */ static void filter_cancel_callback( widget, name, foo ) Widget widget; char *name; caddr_t foo; { XtUnmanageChild( widget ); } static void filter_ok_callback( widget, name, file_struct ) Widget widget; char *name; XmFileSelectionBoxCallbackStruct *file_struct; { char *string, *str; XmStringGetLtoR( file_struct->value, XmSTRING_DEFAULT_CHARSET, &string ); XtUnmanageChild(widget); if( ExternalFil==0 ) { /* Filter */ strcpy( ExFilterName, string ); str = strrchr(string,'/'); if( *(++str) ) strcpy( ExFilterBName, str ); } else strcpy(ExFileName, string ); update_external_filter(); XtFree(string); }