/*
 * 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 <stdio.h>
#include <sys/types.h>
#include <limits.h>
#include  <X11/Xlib.h>
#include  <X11/Intrinsic.h>
#include  <X11/StringDefs.h>
#include  <Xm/Xm.h>
#include  <Xm/List.h>
#include  <Xm/PanedW.h>
#include  <Xm/Text.h>
#include  <Xm/RowColumn.h>
#include  <Xm/CascadeB.h>
#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;
}







syntax highlighted by Code2HTML, v. 0.9.1