/* * 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/callbacks.c,v 1.2 1993/04/22 20:14:10 martinh Exp martinh $ (UW)"; #endif #include #ifdef __STDC__ #include #endif #include #include #include #include #include #include #include "interface.h" #include #include #include #include #include #include #include #include "tcpview.h" #include "filter.h" #include "motif.h" extern Widget summary_list_widget; /* summary (top) window */ extern Widget detail_list_widget; /* detail (middle) window */ extern Widget hex_text_widget; /* hex (bottom) window */ extern Widget packet_label; extern __const char *__const sys_errlist[]; #ifdef __STDC__ void redisplay_current_list(void); void print2hexwindow (char *); static void setpackets (void); void readfile(char *); void xperror( char *); int sniff_next_packet(struct packet_header *, u_char *, int); void redisplay_entire_list(void); struct bpf_program *parse(char *, int, int, u_long); /* gencode.c */ void (*lookup_printer(int))(); static void do_detail( int ); u_int bpf_filter(register struct bpf_insn *, register u_char *, u_int, register u_int ); void hd(u_char *, u_char *, int); #else void redisplay_current_list(); void print2hexwindow (); void setpackets (); void readfile(); void xperror(); int sniff_next_packet(); void redisplay_entire_list(); struct bpf_program *parse(); /* gencode.c */ void (*lookup_printer())(); static void do_detail(); u_int bpf_filter(); void hd(); #endif /* __STDC__ */ int errno; /* these are set when files are read in */ int Linktype; long thiszone; int snaplen=DEFAULT_SNAPLEN; int Precision; struct printer { void (*f)(); int type; }; static struct printer printers[] = { { ether_if_print, DLT_EN10MB }, { sl_if_print, DLT_SLIP }, { ppp_if_print, DLT_PPP }, { fddi_if_print, DLT_FDDI }, { null_if_print, DLT_NULL }, { 0, 0 }, }; void (*PrintIt)(); struct bpf_insn *Fcode; struct packet_list { struct packet_header hdr; u_char *buf; struct packet_list *next; }; static struct packet_list *PacketList=NULL; /* always points to start of the list */ static struct packet_list **PL=NULL; u_long Packet_Count=0; /* total number of packets */ u_long Current_Packets=0; /* number of packets currently displayed */ static XmString *LList=NULL; /* list for summary widget. size is Packet_Count */ static long CurrP = -1; /* number of the currently selected packet */ extern char FileName1[]; /* current file name */ static u_short DetailHeaders[10]; /* list of header line numbers in detail window */ static u_short Header = 0; /* current header number in detail window */ static u_short NumHeaders = 0; /* number of headers in detail window */ static u_short HeaderOffset = 0; /* current offset in header window */ /* track highlighting in hex window */ static int highlight[64][2]; static int numhigh=0; void summary_list_callback( widget, client_data, list_data ) Widget widget; caddr_t client_data; XmListCallbackStruct *list_data; { struct packet_list *p; char *s, *t; static char str[8192], *buffer=NULL; int len, line_num, num; XmListDeleteAllItems( detail_list_widget ); CurrP = list_data->item_position-1; p = PL[CurrP]; StrPtr = str; Phdr = &(p->hdr); PrintIt(p->buf,&p->hdr.ts,p->hdr.len,p->hdr.caplen); StrPtr = str; detail_ether(p->buf); num = 0; line_num = 1; s=t=str; len = strlen(str); while (*t) { if (*t=='\n') { *t++ = '\0'; if( !strncmp( s, "-----", 5) ) DetailHeaders[num++] = line_num; line_num++; AddToList( detail_list_widget, s, 0); s=t; } else t++; } NumHeaders = num; num = line_num-1; /* number of lines */ /* now update hex window */ if (buffer==NULL) buffer = (char *)malloc(10000); hd(buffer,p->buf,p->hdr.caplen); print2hexwindow(buffer); /* now highlight proper section of detail window */ if( Header && (Header <= NumHeaders) ) { line_num = DetailHeaders[Header-1]+HeaderOffset; if( line_num <= num ) { do_detail( line_num ); XmListSelectPos(detail_list_widget,line_num,(Boolean)0); XmListSetPos(detail_list_widget,line_num); } } } /* summary_list_callback */ void detail_list_callback( widget, client_data, list_data ) Widget widget; caddr_t client_data; XmListCallbackStruct *list_data; { register int i, line; int header_line=0; line = list_data->item_position; /* new detail line, so reset the header and offset */ for(i=0;ivalue, XmSTRING_DEFAULT_CHARSET, &string ); XtUnmanageChild(widget); readfile(string); strcpy(FileName1,string); XmListDeleteAllItems( detail_list_widget ); XtFree(string); } /* file_callback */ static Widget filesel; static void cancel_callback( widget, client_data, file_struct ) Widget widget; caddr_t client_data; XmFileSelectionBoxCallbackStruct *file_struct; { XtUnmanageChild(filesel); } /* cancel_callback */ void open_callback( widget, name, call_data ) Widget widget; char *name; caddr_t call_data; { Widget help; Arg args[5]; int n=0; XmString xms; char temp[128]; *temp=0; if( *FileName1 ) { strcpy(temp,FileName1); if( temp[strlen(FileName1)] == '/') strcat(temp,".."); else strcat(temp,"/.."); xms = XmStringCreateSimple(temp); XtSetArg( args[n], XmNdirectory, xms); n++; } XtSetArg( args[n], XmNtextColumns, 60); n++; XtSetArg( args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL ); n++; filesel = XmCreateFileSelectionDialog( widget,"",args,n); XtAddCallback(filesel, XmNokCallback, file_callback, 0); XtAddCallback(filesel, XmNcancelCallback, cancel_callback, 0); help = XmFileSelectionBoxGetChild(filesel,XmDIALOG_HELP_BUTTON); XtUnmanageChild( help ); XtManageChild( filesel ); if( *temp ) XmStringFree(xms); } /* open_callback */ void generic_callback( widget, name, call_data ) Widget widget; char *name; caddr_t call_data; { printf( "Menu choice was [%s]\n", name ); } /* generic_callback */ void free_packet_list() { struct packet_list *p; if( LList ) { free( LList ); LList = NULL; } if (PacketList) { p=PacketList; do { free(p->buf); free(p); } while (p=p->next); free(PL); PacketList = NULL; PL = NULL; Packet_Count = 0; } Packet_Count=0; CurrP = -1; } void readfile(filename) char *filename; { struct packet_list *p, *prev; unsigned char *buf; int n; int sniff=0; int (*next_pack)(); free_packet_list(); n = sf_read_init(filename,&Linktype,&thiszone,&snaplen,&Precision); if( n == -1 ) return; if( n>0 ) { sniff++; if (sniff_rinit(filename,&Linktype,&thiszone,&snaplen,&Precision)) { ErrorDialog(summary_list_widget,"error","Unrecognized file format"); return; } } buf = (u_char *)malloc(snaplen); if( sniff ) next_pack = sniff_next_packet; else next_pack = sf_next_packet; prev = NULL; while(1) { p = (struct packet_list *)malloc(sizeof(struct packet_list)); if (next_pack(&p->hdr,buf,snaplen)!=0) { free(p); break; } p->buf = (u_char *)malloc(p->hdr.caplen); bcopy(buf,p->buf,p->hdr.caplen); if (prev==NULL) PacketList = p; else prev->next=p; p->next=NULL; prev = p; Packet_Count++; }; if( Packet_Count==0 ) { ErrorDialog(summary_list_widget,"warn","No packets found in file"); return; } fprintf(stderr,"%d packets read\n",Packet_Count); PL = (struct packet_list **)malloc(Packet_Count*4); PrintIt = lookup_printer(Linktype); LList = (XmString *)malloc(Packet_Count*sizeof(XmString)); redisplay_entire_list(); } void redisplay_current_list() { struct packet_list *p, **pl; char str[2048]; register int i, n, cp; XmString *plist; if( PacketList == NULL ) return; XtUnmanageChild(summary_list_widget); XmListDeleteAllItems( summary_list_widget ); /* pl is the new packet list */ pl = (struct packet_list **)malloc(Packet_Count*4); plist = LList; cp = -1; n = 0; HighlightPacket=0; ts_print(0); /* reset */ Fcode = parse(Fstr, 1, Linktype, 0)->bf_insns; for(i=0;ihdr); if( bpf_filter(Fcode,p->buf,p->hdr.len,p->hdr.caplen) ) { PrintIt(p->buf,&p->hdr.ts,p->hdr.len,p->hdr.caplen); *StrPtr=0; if( HighlightPacket ) { *plist++ = XmStringCreate( str, "chset2" ); HighlightPacket = 0; } else *plist++ = XmStringCreate( str, "chset1" ); if( i == CurrP) cp = n; pl[n++] = p; } } XmListAddItems( summary_list_widget, LList, n, 0 ); Current_Packets = n; plist = LList; for(n=0;n= 0 ) cp = PL[CurrP]; else cp = (struct packet_list *)-1; CurrP = -1; n = 0; plist = LList; HighlightPacket=0; ts_print(0); /* reset */ Fcode = parse(Fstr, 1, Linktype, 0)->bf_insns; p = PacketList; do { StrPtr = str; Phdr = &(p->hdr); if( bpf_filter(Fcode,p->buf,p->hdr.len,p->hdr.caplen) ) { PrintIt(p->buf,&p->hdr.ts,p->hdr.len,p->hdr.caplen); *StrPtr=0; if( p == cp ) CurrP = n; if( HighlightPacket ) { *plist++ = XmStringCreate( str, "chset2" ); HighlightPacket = 0; } else *plist++ = XmStringCreate( str, "chset1" ); PL[n++] = p; } } while( p = p->next ); XmListAddItems( summary_list_widget, LList, n, 0 ); Current_Packets = n; plist = LList; for(n=0;nbuf, &(p->hdr.ts), p->hdr.len, p->hdr.caplen); else sniff_write( p->buf, &(p->hdr.ts), p->hdr.len, p->hdr.caplen); } while( p = p->next ); if( type ) sf_write_end(); else sniff_end("w"); } void savefile( name, all, type ) char *name; Boolean all; u_short type; { struct packet_list *p; register int i; int sf_write_init(); if( PacketList == NULL || ( all==False && Current_Packets==0 )) return; if( type ) { if( sf_write_init( name, Linktype, thiszone, snaplen, Precision) ) return; } else { if( sniff_winit( name, Linktype, thiszone, snaplen, Precision) ) return; } if( all==True ) { save_entire_list(name, type); return; } /* save_current_list */ for(i=0;ibuf, &(p->hdr.ts), p->hdr.len, p->hdr.caplen); else sniff_write( p->buf, &(p->hdr.ts), p->hdr.len, p->hdr.caplen); } if( type ) sf_write_end(); else sniff_end("w"); } void print_entire_list(fp, detail, str) FILE *fp; u_short detail; char *str; { struct packet_list *p; if( PacketList == NULL ) return; ts_print(0); /* reset */ p = PacketList; do { StrPtr = str; Phdr = &(p->hdr); if( detail ) detail_ether(p->buf); else PrintIt(p->buf,&p->hdr.ts,p->hdr.len,p->hdr.caplen); *StrPtr=0; fprintf(fp,"%s\n",str); } while( p = p->next ); fclose(fp); } void printfile( name, all, detail ) char *name; Boolean all; u_short detail; { struct packet_list *p; register int i; char str[8192]; FILE *fp; if( PacketList == NULL || (Current_Packets == 0 && all==False) ) { iprint("No packets to print"); return; } if( name[0] == '-' && name[1] == '\0' ) fp = stdout; else { fp = fopen(name,"w"); if( !fp ) { xperror(name); return; } } if( all==True ) { print_entire_list(fp, detail, str); return; } ts_print(0); /* reset */ for(i=0;ihdr); if( detail ) detail_ether(p->buf); else PrintIt(p->buf,&p->hdr.ts,p->hdr.len,p->hdr.caplen); *StrPtr=0; fprintf(fp,"%s\n",str); } fclose(fp); } void print2hexwindow(str) char *str; { static short end=0; /* turn off any highlighted text */ XmTextSetHighlight(hex_text_widget,0,end,XmHIGHLIGHT_NORMAL); numhigh = 0; XmTextSetString( hex_text_widget,str); end = strlen(str); } static void setpackets() { char buf[25]; Arg args[3]; XmString ms; sprintf(buf," %d/%d packets ",Current_Packets,Packet_Count); ms = XmStringCreateSimple(buf); XtSetArg( args[0], XmNlabelString, ms ); XtSetValues(packet_label,args,1); XmStringFree( ms ); } void xperror(str) char *str; { char *str2, buf[128]; str2 = sys_errlist[errno]; if(str[0]!='\0') sprintf(buf,"%s: %s\n",str,str2); else strcpy(buf,str2); ErrorDialog(summary_list_widget,"error",buf); } void eprintv(char *fmt, va_list ap) { char str[128]; (void)vsprintf(str, fmt, ap); ErrorDialog(summary_list_widget, "error", str); } void eprint(char *fmt, ...) { va_list args; va_start(args, fmt); eprintv(fmt, args); va_end(args); } void iprint(char *fmt, ...) { va_list args; char str[128]; Widget widget; XmString ms; Arg a[2]; int n; va_start(args, fmt); (void)vsprintf(str,fmt,args); va_end(args); ms = XmStringCreateSimple( str ); n=0; XtSetArg( a[n], XmNmessageString, ms ); n++; widget = XmCreateInformationDialog(summary_list_widget, "info", a, n ); RemoveDialButton( widget, XmDIALOG_CANCEL_BUTTON ); RemoveDialButton( widget, XmDIALOG_HELP_BUTTON ); XtManageChild(widget); XmStringFree(ms); } void (*lookup_printer(type))() int type; { struct printer *p; for (p = printers; p->f; ++p) if (type == p->type) return p->f; eprint("unknown data link type 0x%x", type); return NULL; }