[svn] r5194 - in trunk/rpms: . splitvt tcpshow tcpstat

packagers at lists.rpmforge.net packagers at lists.rpmforge.net
Thu Feb 22 23:33:12 CET 2007


Author: dag
Date: 2007-02-22 23:33:11 +0100 (Thu, 22 Feb 2007)
New Revision: 5194

Added:
   trunk/rpms/splitvt/
   trunk/rpms/splitvt/splitvt-1.6.5-config.patch
   trunk/rpms/splitvt/splitvt.spec
   trunk/rpms/tcpshow/
   trunk/rpms/tcpshow/tcpshow.1
   trunk/rpms/tcpshow/tcpshow.c
   trunk/rpms/tcpshow/tcpshow.patch
   trunk/rpms/tcpshow/tcpshow.spec
   trunk/rpms/tcpstat/
   trunk/rpms/tcpstat/tcpstat.spec
Log:
Updates

Added: trunk/rpms/splitvt/splitvt-1.6.5-config.patch
===================================================================
--- trunk/rpms/splitvt/splitvt-1.6.5-config.patch	                        (rev 0)
+++ trunk/rpms/splitvt/splitvt-1.6.5-config.patch	2007-02-22 22:33:11 UTC (rev 5194)
@@ -0,0 +1,38 @@
+--- config.c.orig	2003-05-03 22:48:04.000000000 +0200
++++ config.c	2007-02-22 23:34:45.598421000 +0100
+@@ -213,7 +213,12 @@
+ 	fprintf(makefile, 
+ "# Shareware copyright 1993, by Sam Lantinga\n\n");
+ #ifdef linux
+-	fprintf(makefile, "\nCC = gcc\n");
++	fprintf(makefile, "DESTDIR = \n");
++	fprintf(makefile, "prefix = /usr\n");
++	fprintf(makefile, "bindir = $(prefix)/bin\n");
++	fprintf(makefile, "datadir = $(prefix)/share\n");
++	fprintf(makefile, "mandir = $(datadir)/man\n");
++	fprintf(makefile, "CC = gcc\n");
+ #endif
+ 	fclose(makefile);
+ 	system("sh scanpty >>Makefile");
+@@ -231,17 +236,17 @@
+ 	fprintf(makefile, "       parserc.o lock.o cut-paste.o\n\n");
+ 	fprintf(makefile, "splitvt: $(OBJS)\n");
+ #if defined(linux) && !defined(DEBUG)
+-	fprintf(makefile, "\t$(CC) -s -o $@ $(OBJS) $(LIBS)\n");
++	fprintf(makefile, "\t$(CC) -s $(CFLAGS) -o $@ $(OBJS) $(LIBS)\n");
+ #else
+ 	fprintf(makefile, "\t$(CC) -o $@ $(OBJS) $(LIBS)\n");
+ #endif
+ 	fprintf(makefile, "\nclean: \n\trm -f *.o core \n");
+ 	fprintf(makefile, "\ndistclean: clean\n\trm -f splitvt Makefile\n");
+ 	fprintf(makefile, "\ninstall: install-man\n");
+-	fprintf(makefile, "\tmv splitvt /usr/local/bin/splitvt\n");
+-	fprintf(makefile, "\tmv examples/xsplitvt /usr/local/bin/xsplitvt\n");
++	fprintf(makefile, "\tinstall -Dp -m0755 splitvt $(DESTDIR)$(bindir)/splitvt\n");
++	fprintf(makefile, "\tinstall -Dp -m0755 examples/xsplitvt $(DESTDIR)$(bindir)/xsplitvt\n");
+ 	fprintf(makefile, "\ninstall-man:\n");
+-	fprintf(makefile, "\tcp splitvt.man /usr/local/man/man1/splitvt.1\n");
++	fprintf(makefile, "\tinstall -Dp -m0644 splitvt.man $(DESTDIR)$(mandir)/man1/splitvt.1\n");
+ 
+ 	fclose(makefile);
+ 	exit(0);

Added: trunk/rpms/splitvt/splitvt.spec
===================================================================
--- trunk/rpms/splitvt/splitvt.spec	                        (rev 0)
+++ trunk/rpms/splitvt/splitvt.spec	2007-02-22 22:33:11 UTC (rev 5194)
@@ -0,0 +1,52 @@
+# $Id$
+# Authority: dag
+
+Summary: Splits any VT100 terminal window into two shell window
+Name: splitvt
+Version: 1.6.5
+Release: 1
+License: GPL
+Group: System Environment/Console
+URL: http://www.devolution.com/~slouken/projects/splitvt/
+
+Source: http://www.devolution.com/~slouken/projects/splitvt/splitvt-%{version}.tar.gz
+Patch: splitvt-1.6.5-config.patch
+Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root
+
+%description
+This program takes any VT100 terminal window and splits it into two shell
+windows, one on top and one on bottom. It allows you to watch two terminal
+sessions at once, which can be very useful whenever you want more screen
+real-estate without messing with windows. 
+
+%prep
+%setup
+%patch -p0 -b .orig
+%{__rm} -f Makefile
+
+%build
+./configure -q
+%{__make} %{?_smp_mflags}
+
+%install
+%{__rm} -rf %{buildroot}
+%{__make} install DESTDIR="%{buildroot}"
+#%{__install} -Dp -m0755 splitvt.1 %{buildroot}%{_mandir}/man1/splitvt.1
+
+%post -p /sbin/ldconfig
+%postun -p /sbin/ldconfig
+
+%clean
+%{__rm} -rf %{buildroot}
+
+%files
+%defattr(-, root, root, 0755)
+%doc ANNOUNCE BLURB COPYING README TODO splitvt-1.6.5.lsm
+%doc escapes/* examples/*
+%doc %{_mandir}/man1/splitvt.1*
+%{_bindir}/splitvt
+%{_bindir}/xsplitvt
+
+%changelog
+* Thu Feb 22 2007 Dag Wieers <dag at wieers.com> - 1.6.5-1
+- Initial package. (using DAR)


Property changes on: trunk/rpms/splitvt/splitvt.spec
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: trunk/rpms/tcpshow/tcpshow.1
===================================================================
--- trunk/rpms/tcpshow/tcpshow.1	                        (rev 0)
+++ trunk/rpms/tcpshow/tcpshow.1	2007-02-22 22:33:11 UTC (rev 5194)
@@ -0,0 +1,292 @@
+.\" @(#) $Id: tcpshow.1,v 1.0 1996/07/03 20:17:25 mike Exp $
+.\"
+.\" #if !defined(MAY_NOT_MODIFY)
+.\"
+.\" Copyright (c) 1996 I.T. NetworX Ltd.  All rights reserved.
+.\"
+.\" The conditions applying to the use of this manual page are the same as
+.\" those conditions applying to the file "tcpshow.c".  See that file for
+.\" the conditions.
+.\"
+.\" #endif
+.TH TCPSHOW 1  "03 July 1996"
+.SH NAME
+tcpshow \- decode a \fBtcpdump\fP savefile
+.SH SYNOPSIS
+.na
+.B tcpshow
+[
+.B \-b
+] [
+.B \-sb
+] [
+.B \-w
+.I width
+] [
+.B \-nolink
+] [
+.B \-noip
+]
+.br
+.ti +8
+[
+.B \-nodata
+] [
+.B \-data
+] [
+.B \-track
+] [
+.B \-terse
+]
+.br
+.ti +8
+[
+.B \-cooked
+] [
+.B \-pp
+] [
+.B \-s
+] [
+.B \-h
+]
+.br
+.ti +8
+[
+.B expression
+]
+.br
+.ad
+.SH DESCRIPTION
+.LP
+\fBtcpshow\fP reads a \fBtcpdump\fP(1) savefile and provides a
+reasonably complete decode
+of Ethernet, IP, ICMP, UDP and TCP headers, in packets that match the
+boolean \fIexpression\fP.  The data belonging to these packets is
+displayed in ASCII.
+.LP
+Currently, protocol data is not decoded.  This is not considered a
+serious problem for applications that use ASCII data streams.
+.LP
+Also, IP and TCP options are not decoded.
+.LP
+The input file must be in the format produced by
+\fItcpdump -enx\fP.  This file can be generated from
+.br
+1. a prior run of
+.B tcpdump -w
+.I file
+.br
+2. a live run of
+.B tcpdump
+(without -w)
+.br
+3. any other program that produces a correctly formatted
+.br
+   trace
+.br
+See under EXAMPLES for each of these different methods, plus a
+description of the format the input file needs to be in.
+.LP
+Except when \fI-cooked\fP is used, \fBtcpdump\fP(1) is required
+to be on your PATH, to process the raw savefile.
+.SH OPTIONS
+The following options can be used in just about any sane combination.
+.TP
+.B \-b
+break long lines so they don't wrap
+.IP
+This produces a neater, more readable display of the application
+data.  The default width is 60 columns.  See the \fI-w\fP flag for
+how to change this default.
+.TP
+.B \-sb
+show line breaks
+.IP
+When \fI-b\fP is used, it may be useful to see exactly where
+\fBtcpshow\fP wrapped each line, in its display of application data.
+This option causes the string ``<break>'' to be displayed at the
+end of each wrapped line.  (Lines which were not wrapped, but
+terminated before the page width, are not so marked.)
+.TP
+.B \-w \fIwidth\fP
+.br
+set pagewidth to \fIwidth\fP columns
+.IP
+This determines where \fBtcpshow\fP will fold long lines, when the
+\fI-b\fP switch is used.
+.TP
+.B \-nolink
+don't decode the link header
+.IP
+The data link header (Ethernet header) is not decoded and displayed.
+.TP
+.B \-noip
+don't decode the IP header
+.IP
+The IP header is not decoded and displayed.
+.TP
+.B \-nodata
+don't show the data
+.IP
+The protocol data is not displayed (a count of data bytes is shown).
+.TP
+.B \-data
+display only the data
+.IP
+The data, plus a minimal decode of the IP and transport/ICMP headers,
+is displayed.
+.TP
+.B \-track
+track TCP sequence numbers
+.IP
+An additional field is produced in the output which shows the TCP
+acknowledgement number which this side of the connection should
+receive once the current packet has been received by its peer.
+.TP
+.B \-terse
+show the header decode in compact format
+.IP
+Without this option, the display of the decoded header is verbose,
+occupying a lot of display-space real-estate.  With this option,
+the decoded header information is much more compact and terse.
+Once you're familiar with the meanings of the header fields, you'll
+probably always use this option.  (Maybe this should be the
+default, with a \fI-verbose\fP flag to get long-winded header decodes?)
+.TP
+.B \-cooked
+don't run \fBtcpdump\fP(1) to pre-process the input
+.IP
+If the input file is already in the expected format, this option
+must be used.  See EXAMPLES below of where this flag is appropriate.
+.TP
+.B \-pp
+point-to-point link
+.IP
+If the input file was collected from data travelling over a
+point-to-point link (one which doesn't make an Ethernet header available),
+this option needs to be used.
+.TP
+.B \-s
+also display a hex dump of spurious data at packet-end
+.IP
+For a reason unknown to the author, \fBtcpdump\fP(1) output sometimes
+contains data at the end of packets which don't belong to those packets.
+This spurious data is suppressed from the output, except when this
+option is used.
+.TP
+.B \-h
+display a help summary
+.IP
+This list of options is displayed, with one-liner descriptions.
+.TP
+.B expression
+filter the input file using a \fBtcpdump\fP(1) expression
+.IP
+If the \fI-cooked\fP option is not used, then \fBtcpdump\fP(1) is
+required to be on your PATH.  It is used to read the raw savefile,
+producing output in the format \fBtcpshow\fP expects.  The
+\fIexpression\fP should be a valid \fBtcpdump\fP(1) expression.
+It is not parsed or interpreted by \fBtcpshow\fP, but passed on
+to \fBtcpdump\fP(1) for its consumption.
+.SH EXAMPLES
+In the following examples, where \fBtcpdump\fP(1) is used, the
+flag \fI-s 1518\fP is used to be sure of saving the complete Ethernet
+frame.
+.LP
+Also, where \fBtcpdump\fP(1) expressions are used, these could equally
+have been given to \fBtcpdump\fP(1) directly, if it was known at this
+time what data you're interested in.
+.LP
+Capture a raw savefile and decode it later.
+.IP
+# tcpdump -s 1518 -w savefile
+.br
+# tcpshow < savefile
+.LP
+Decode the data as quickly as \fBtcpdump\fP(1) gives it to us.
+.IP
+# tcpdump -s 1518 -lenx | tcpshow
+.LP
+Display headers only.
+.IP
+# tcpshow -nodata < savefile
+.LP
+Display data only (minimal header decode).
+.IP
+# tcpshow -data
+.LP
+Display a decode of Telnet traffic only, omitting the link and IP headers.
+.IP
+# tcpdump -s 1518 -w savefile
+.br
+# tcpshow -nolink -noip tcp port telnet < savefile
+.LP
+Give a compact display of the TCP headers, and a full display of
+the data, for all packets going into or coming from the host "sam"
+-- this host is on a LAN accessible through a PPP link.
+.IP
+# tcpdump -i ppp0 -s 1518 -w savefile
+.br
+# tcpshow -pp -terse host sam < savefile
+.LP
+Show all SMTP mail transfers, omitting the headers and wrapping the
+message bodies to make it easy to read them (you're not supposed to
+do this).
+.IP
+# tcpdump -s 1518 -w savefile
+.br
+# tcpshow -b -w 40 -data port smtp < savefile
+.LP
+To display a decode of data not captured via \fBtcpdump\fP(1), you
+would typically use the application that captured the trace to dump
+that trace into a file in ASCII-hex format.  You feed that file into
+a Perl/sh/awk script (that you write), which produces a file in the
+format \fBtcpshow\fP expects.  Such scripts are easy to write.  For
+example, if your application is "capture" and your script
+is "convert", then \fBtcpshow\fP might be used as follows.
+.IP
+# capture -hexoutput | convert | tcpshow
+.LP
+A loose definition of the format \fBtcpshow\fP expects is: the 1st
+line of each packet must begin in column 1.  All other lines must
+begin with a TAB.  The hex bytes can be separated from each other by
+any amount of whitespace, including none.
+.br
+When using \fI-cooked\fP, the first field should be the time the
+packet was captured (or a string like "no-time-recorded" if the time
+isn't available).  The remaining fields should be the bytes of the
+IP datagram.
+.br
+When \fI-cooked\fP is not used, the first field should be as above,
+with the next three fields being the Ethernet source address, the
+Ethernet destination address and the DIX Ethernet Type field.
+.SH FILES
+\fBtcpshow\fP reads from standard input and writes to standard
+output.
+.SH SEE ALSO
+tcpdump(1), nit(4P), bpf(4)
+.\"
+.\" #if !defined(MAY_NOT_MODIFY)
+.\"
+.SH AUTHOR
+Mike Ryan <mike at NetworX.ie>
+.SH RESTRICTIONS
+This program and its source code are freely available.  See the
+Conditions governing their use in the source code.
+.\"
+.\" #endif
+.\"
+.SH BUGS
+It should decode IP and TCP options.
+.LP
+It should decode data from application protocols that don't send their
+data in ASCII (e.g. DNS/BIND).
+.LP
+It should not depend on \fBtcpdump\fP(1) as much as it does.  It should
+be modified to use pcap(3) directly.
+.LP
+It doesn't bother mapping IP addresses into their host names.  The option
+to do this should be provided.
+.LP
+The \fI-terse\fP option should be a default, with \fI-verbose\fP avaiable
+to produce a verbose display of the headers.

Added: trunk/rpms/tcpshow/tcpshow.c
===================================================================
--- trunk/rpms/tcpshow/tcpshow.c	                        (rev 0)
+++ trunk/rpms/tcpshow/tcpshow.c	2007-02-22 22:33:11 UTC (rev 5194)
@@ -0,0 +1,1516 @@
+#if !defined(MAY_NOT_MODIFY)
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* tcpshow, v1.0                                                            */
+/*                                                                          */
+/* Quickie to decode a "tcpdump" savefile.                                  */
+/*                                                                          */
+/* The application data is displayed as ASCII -- application protocols are  */
+/* not decoded.                                                             */
+/*                                                                          */
+/* The data captured by "tcpdump" might be less than in the original        */
+/* packet.  We kludge a solution to this with setjmp()/longjmp().           */
+/*                                                                          */
+/* Although written to read tcpdump savefiles, with tcpdump itself as a     */
+/* front-end, it'll decode any hex dump that adheres to the format          */
+/* expected.  Some programs which capture network data offer an option to   */
+/* save the trace to a file in hex format -- this can often be massaged     */
+/* easily with Perl/awk/sh scripts to turn it into the format expected.     */
+/* As a special case, "tcpdump -s 1518 -lenx | tcpshow -cooked" works       */
+/* rather well, and "tcpdump -s 1518 -lenx | tcpshow -cooked -data" is nice */
+/* for watching the data traffic in real time.                              */
+/*                                                                          */
+/* ------------------------------------------------------------------------ */
+/*                                                                          */
+/* Copyright (c) 1996 I.T. NetworX Ltd.  All rights reserved.               */
+/*                                                                          */
+/* This source code is owned and copyrighted by I.T. NetworX Ltd.  This     */
+/* file and all files derived from it, directly or indirectly (such files   */
+/* collectively and separately being referred to henceforth as "this file") */
+/* may be used, modified and redistributed subject to the following six     */
+/* Conditions.                                                              */
+/*                                                                          */
+/* Condition 1 of 6:                                                        */
+/* That all text (code/comments, etc.) in this file surrounded by the macro */
+/* block "#if !defined(MAY_NOT_MODIFY) ... #endif", including the macro     */
+/* statements themselves, may not be modified in any way, or deleted.  In   */
+/* particular, this comment block and the printf() statements identifying   */
+/* I.T. NetworX as being the copyright owner, in the function usage(), may  */
+/* not be modified or deleted.  The single, only, exception to this is that */
+/* the non-inclusion of C comments by a C compiler/linker, in the object    */
+/* and executable images it produces, is permitted.                         */
+/*                                                                          */
+/* Condition 2 of 6:                                                        */
+/* That no financial gain be made from using this file or modifying this    */
+/* file.  It is permitted to charge for redistributing this file.           */
+/*                                                                          */
+/* Condition 3 of 6:                                                        */
+/* That no conditions other than these six Conditions be applied to the     */
+/* use, modification or redistribution of this file.                        */
+/*                                                                          */
+/* Condition 4 of 6:                                                        */
+/* That all modifications to this file show prominently the name of the     */
+/* person that made the change and the date on which the change was made.   */
+/*                                                                          */
+/* Condition 5 of 6:                                                        */
+/* That I.T. NetworX, its employees, agents and everybody else in the world */
+/* dead, living and yet to be born, are hereby free from liability of all   */
+/* and every kind arising from the use of this file by anybody for any      */
+/* purpose.  This file comes "as is" and all warranties, express or         */
+/* implied, are disclaimed.  As the manual page for chat(1) says, "if it    */
+/* breaks, then you get to keep both pieces".                               */
+/*                                                                          */
+/* Condition 6 of 6:                                                        */
+/* That I.T. NetworX reserves the right to alter these Conditions at any    */
+/* time without giving prior notice, such alterations to apply only to the  */
+/* version current at the time of issue of the alterations and all later    */
+/* versions, and such alterations to apply only to versions produced        */
+/* exclusively by I.T. NetworX or its agents.                               */
+/*                                                                          */
+/* Addendum to Copyright:                                                   */
+/* I'm not a legal eagle and I worded the above notice off the top of my    */
+/* head, so it may be full of holes, but the spirit of my intentions are    */
+/* clear from reading it.  Please respect these intentions.                 */
+/*                                                                          */
+/* Me too:                                                                  */
+/* If anybody makes significant improvements to this file, such as adding   */
+/* decode support for DNS traffic or IP and TCP options, I would appreciate */
+/* it if they sent me a copy of their work (mike at NetworX.ie).  Thanks.      */
+/*                                                                          */
+/* ------------------------------------------------------------------------ */
+/*                                                                          */
+/* File layout is as follows:                                               */
+/* system includes                                                          */
+/* local includes                                                           */
+/* #define macros                                                           */
+/* typedefs                                                                 */
+/* declarations of extern variables                                         */
+/* declarations of extern functions                                         */
+/* declarations of global variables                                         */
+/* declarations of global functions                                         */
+/* declarations of static variables                                         */
+/* declarations of static functions                                         */
+/* definitions of functions                                                 */
+/* (all functions and variables are declared/defined in alphabetical order) */
+/*                                                                          */
+/* ------------------------------------------------------------------------ */
+/*                                                                          */
+/* Compiles as follows:                                                     */
+/* cc -s -O -o tcpshow tcpshow.c                                            */
+/*                                                                          */
+/* ------------------------------------------------------------------------ */
+/*                                                                          */
+/* Who and when:                                                            */
+/* MikeRyan, 11apr96.                                                       */
+/*                                                                          */
+/* I.T. NetworX,                                                            */
+/* 67 Merrion Square,                                                       */
+/* Dublin 2,                                                                */
+/* Ireland.                                                                 */
+/* Phone: +353-1-676-8866                                                   */
+/* Fax:   +353-1-676-8868                                                   */
+/* Email: mike at NetworX.ie                                                   */
+/*                                                                          */
+/* ------------------------------------------------------------------------ */
+/*                                                                          */
+/* Modification History                                                     */
+/* MikeRyan, 14may96: Allow "tcpdump" expressions to be passed in.          */
+/* MikeRyan, 15may96: Added UDP decode logic.                               */
+/* MikeRyan, 16may96: Added ICMP decode logic.                              */
+/* MikeRyan, 16may96: Added -b switch to break long lines                   */
+/*                          -w option to specify the width of the page      */
+/*                          -h flag to give help on usage.                  */
+/* MikeRyan, 28may96: Added -nolink                                         */
+/*                          -nodata                                         */
+/*                          -noip                                           */
+/*                          -track                                          */
+/*                          -terse                                          */
+/*                          -sb                                             */
+/*                          -s                                              */
+/* MikeRyan, 25jun96: Incorporated my "general.h" typedef's, so that the    */
+/* present source file doesn't depend on any non-standard header files.     */
+/* This allows it to be distributed as a single file.  Also included the    */
+/* copyright notice, as I'm making the program freely available.            */
+/*                                                                          */
+/* MikeRyan, 26jun96: Added -cooked                                         */
+/*                          -pp                                             */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <setjmp.h>
+
+
+/* Some general defines.                                                    */
+#if defined(FALSE)
+#undef FALSE
+#endif
+#if defined(TRUE)
+#undef TRUE
+#endif
+#define FALSE        (boolean)0
+#define TRUE         (boolean)1
+#define elif            else if
+#if !defined(reg)
+#define reg            register        /* For debugging purposes            */
+#endif
+
+
+#define VERSION             1.0        /* Please change when appropriate    */
+#define COOKER        "tcpdump"
+#define MAXCOOKARGS         100        /* Max tcpdump expression words      */
+
+#define MAXPKT            10240        /* Should be 1518 for Ethernet       */
+#define NCOLS                60
+
+/* IP header elements.                                                      */
+#define IPHDRLEN             20
+#define FRAGOFF          0x1FFF
+#define MF               0x2000
+#define DF               0x4000
+
+/* TCP header elements.                                                     */
+#define TCPHDRLEN            20
+#define URG              0x0020
+#define ACK              0x0010
+#define PSH              0x0008
+#define RST              0x0004
+#define SYN              0x0002
+#define FIN              0x0001
+
+/* UDP header elements.                                                     */
+#define UDPHDRLEN             8
+
+/* ICMP header elements.                                                    */
+#define ICMPHDRLEN            4
+
+/* IP protocol types.                                                       */
+#define IP                    0
+#define ICMP                  1
+#define IGMP                  2
+#define GGP                   3
+#define IPENCAP               4
+#define ST                    5
+#define TCP                   6
+#define EGP                   8
+#define PUP                  12
+#define UDP                  17
+#define HMP                  20
+#define XNSIDP               22
+#define RDP                  27
+#define ISOTP4               29
+#define XTP                  36
+#define IDPRCMTP             39
+#define RSVP                 46
+#define VMTP                 81
+#define OSPF                 89
+#define IPIP                 94
+#define ENCAP                98
+
+/* ICMP types.                                                              */
+#define ECHO_REPLY            0
+#define DST_UNREACH           3
+#define SRC_QUENCH            4
+#define REDIRECT              5
+#define ECHO_REQ              8
+#define ROUTER_AD             9
+#define ROUTER_SOL           10
+#define TIME_EXCEED          11
+#define PARAM_PROB           12
+#define TIME_REQ             13
+#define TIME_REPLY           14
+#define INFO_REQ             15
+#define INFO_REPLY           16
+#define MASK_REQ             17
+#define MASK_REPLY           18
+
+/* ICMP codes for type == Destination Unreachable.                          */
+#define NET_UNREACH           0
+#define HOST_UNREACH          1
+#define PROTO_UNREACH         2
+#define PORT_UNREACH          3
+#define DF_SET                4
+#define SRCROUTE_FAILED       5
+#define DSTNET_UNKNOWN        6
+#define DSTHOST_UNKNOWN       7
+#define SRCHOST_ISOLATED      8
+#define DSTNET_PROHIB         9
+#define DSTHOST_PROHIB       10
+#define NET_UNREACH_TOS      11
+#define HOST_UNREACH_TOS     12
+#define COMM_PROHIB          13
+#define HOST_PREC_VIOL       14
+#define PREC_CUTOFF          15
+
+/* ICMP codes for type == Redirect.                                         */
+#define REDIR_FOR_NET         0
+#define REDIR_FOR_HOST        1
+#define REDIR_FOR_TOSNET      2
+#define REDIR_FOR_TOSHOST     3
+
+/* ICMP codes for type == Time Exceeded.                                    */
+#define TTL_ZERO              0
+#define REASS_TIMEOUT         1
+
+/* ICMP codes for type == Parameter Problem.                                */
+#define IP_HDR_BAD            0
+#define MISSING_OPT           1
+
+/* Skip remaining lines of current packet.  Note that this causes a         */
+/* longjmp(), so a succeeding "return" from a function isn't needed.        */
+#define nextpkt()   for ( ; ; ) (void)getpkt()
+/* Display a separator line between packet decodes.                         */
+#define prsep() \
+printf( \
+   "-----------------------------------------------------------------\n" \
+)
+
+
+/* My own preferred basic data types -- amend per target machine.           */
+typedef char boolean;
+typedef float float4;
+typedef double float8;
+typedef char int1;
+typedef short int2;
+typedef int int4;
+typedef unsigned char uint1;
+typedef unsigned short uint2;
+typedef unsigned int uint4;
+typedef unsigned char uchar;
+
+
+void main(int, char **);
+
+
+static boolean bflag = FALSE;
+static char *cookargs[MAXCOOKARGS+1];
+static boolean cookedflag = FALSE;
+static boolean dataflag = FALSE;
+static uint2 datalen = 0;
+static char *dflt_cookargs[] = {
+   COOKER, "-enx", "-s10240", "-r-", (char *)NULL
+};
+static char dip[16];
+static boolean isip;
+static jmp_buf jmpbuf;
+static boolean nodataflag = FALSE;
+static boolean noipflag = FALSE;
+static boolean nolinkflag = FALSE;
+static int npkts_shown = 0;
+static char *off = "off,";             /* "off" in middle of list           */
+static char *off_e = "off";            /* "off" at end of list              */
+static char *on = "on, ";              /* "on" in middle of list            */
+static char *on_e = "on";              /* "on" at end of list               */
+static int pagewidth = NCOLS;
+static char *pkt;
+static boolean ppflag = FALSE;
+static uint1 proto;
+static boolean sflag = FALSE;
+static boolean sbflag = FALSE;
+static char sip[16];
+static boolean terseflag = FALSE;
+static boolean trackflag = FALSE;
+static char *unknown = "<unknown>";
+
+
+static void error(char *);
+static char *etheraddr(char *);
+static char *ether_proto(char *);
+static void fork_tcpdump(int, char **);
+static uint1 getbyte(char **);
+static uint4 getlongword(char **);
+static char *getpkt(void);
+static uint2 getword(char **);
+static char *icmpcode(uint1, uint1);
+static char *icmptype(uint1);
+static char *ipaddr(char **);
+static char *ip_proto(uint1);
+static char nextchar(char **);
+static char *rmwspace(char *);
+static char *showdata(char *);
+static char *showhdr(char *);
+static char *showicmp(char *);
+static char *showip(char *);
+static void showpkt(char *);
+static char *showtcp(char *);
+static char *showudp(char *);
+static char *skip(char *, uint2);
+static char *svcname(uint2, char *, boolean);
+static void usage(void);
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Print an error message and exit.                                         */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static void error (
+   char *msg
+) {
+
+   fprintf(stderr, "***Error: %s\n", msg);
+   exit(1);
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Print a formatted Ethernet address.                                      */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *etheraddr (
+   char *eaddr
+) {
+
+   static char formatted[18];
+   int i;
+   int j;
+
+
+   for (i = j = 0; i < 6; i++)
+      if (eaddr[1] == ':') {
+         formatted[j++] = '0';
+         formatted[j++] = toupper(eaddr[0]);
+         formatted[j++] = ':';
+         eaddr += 2;
+      }
+      else {
+         formatted[j++] = toupper(eaddr[0]);
+         formatted[j++] = toupper(eaddr[1]);
+         formatted[j++] = ':';
+         eaddr += 3;
+      }
+   formatted[j-1] = '\0';
+
+   return formatted;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Print the type of protocol encapsulated in the Ethernet frame.           */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *ether_proto (
+   char *type
+) {
+
+   if (strcmp(type, "0800") == 0)
+      return "IP";
+   elif (strcmp(type, "0806") == 0)
+      return "ARP";
+   elif (strcmp(type, "8035") == 0)
+      return "RARP";
+   else
+      return type;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Run tcpdump to pre-process the trace file.                               */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static void fork_tcpdump (
+   int argc,
+   char **argv
+) {
+
+   int fd[2];
+   int i;
+   pid_t pid;
+
+
+   /* Required "tcpdump" flags.                                             */
+   i = 0;
+   while (dflt_cookargs[i]) {
+      cookargs[i] = dflt_cookargs[i];
+      i++;
+   }
+   while (argc-- > 0) {
+      if (i >= MAXCOOKARGS) error("Too many expressions");
+      cookargs[i++] = *argv++;
+   }
+   cookargs[i] = (char *)NULL;
+
+   /* Fork tcpdump to cook our input.                                       */
+   if (pipe(fd)) error("pipe() failed");
+   if ((pid=fork()) < 0) error("fork() failed");
+   if (pid == 0) {
+      (void)close(1);
+      if (dup(fd[1]) != 1) error("dup() failed");
+      (void)close(fd[0]);
+      (void)close(fd[1]);
+      execvp(COOKER, cookargs);
+      error("execvp() failed");
+   }
+
+   (void)close(0);
+   if (dup(fd[0]) != 0) error("dup() failed");
+   (void)close(fd[0]);
+   (void)close(fd[1]);
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Return the byte value and increment the pointer by sizeof(byte).         */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static uint1 getbyte (
+   char **pkt
+) {
+
+   char byte[1*2+1];                   /* ASCII representation of a byte    */
+   unsigned int val;
+
+
+   byte[0] = nextchar(pkt);
+   byte[1] = nextchar(pkt);
+   byte[2] = '\0';
+
+   (void)sscanf(byte, "%x", &val);
+
+   return (uint1)val;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Return the longword value and increment the pointer by sizeof(longword). */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static uint4 getlongword (
+   char **pkt
+) {
+
+   char longword[4*2+1];              /* ASCII representation of a longword */
+   unsigned long val;
+
+
+   longword[0] = nextchar(pkt);
+   longword[1] = nextchar(pkt);
+   longword[2] = nextchar(pkt);
+   longword[3] = nextchar(pkt);
+   longword[4] = nextchar(pkt);
+   longword[5] = nextchar(pkt);
+   longword[6] = nextchar(pkt);
+   longword[7] = nextchar(pkt);
+   longword[8] = '\0';
+
+   (void)sscanf(longword, "%lx", &val);
+
+   return (uint4)val;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Read in the next line of packet data.                                    */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *getpkt (
+) {
+
+   static boolean been_here_already = FALSE;
+   static char pktbuf[MAXPKT+1];
+
+
+   if (fgets(pktbuf, MAXPKT+1, stdin) == (char *)NULL) exit(0);
+
+   /* Line without leading <tab> means start of new packet.                 */
+   if (*pktbuf == '\t')
+      return rmwspace(pktbuf);
+   elif (! been_here_already) {        /* setjmp() won't have been called   */
+      been_here_already = TRUE;        /*  before reading 1st packet        */
+      return pkt = pktbuf;
+   }
+   else {
+      if (datalen > 0)
+         printf("\n\t<*** Rest of data missing from packet dump ***>\n");
+      pkt = pktbuf;
+      longjmp(jmpbuf, 1);
+   }
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Return the word value and increment the pointer by sizeof(word).         */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static uint2 getword (
+   char **pkt
+) {
+
+   char word[2*2+1];                   /* ASCII representation of a word    */
+   unsigned int val;
+
+
+   word[0] = nextchar(pkt);
+   word[1] = nextchar(pkt);
+   word[2] = nextchar(pkt);
+   word[3] = nextchar(pkt);
+   word[4] = '\0';
+
+   (void)sscanf(word, "%x", &val);
+
+   return (uint2)val;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Print the code relating to the ICMP type.                                */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *icmpcode (
+   uint1 type,
+   uint1 code
+) {
+
+   char *bad;
+   char *descr;
+
+
+   bad = "<*** CORRUPT ***>";
+   descr = (char *)NULL;
+
+   switch (type) {
+    case ECHO_REPLY:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case DST_UNREACH:
+      switch (code) {
+       case NET_UNREACH:       descr = "network-unreachable";           break;
+       case HOST_UNREACH:      descr = "host-unreachable";              break;
+       case PROTO_UNREACH:     descr = "protocol-unreachable";          break;
+       case PORT_UNREACH:      descr = "port-unreachable";              break;
+       case DF_SET:            descr = "frag-needed-but-DF-set";        break;
+       case SRCROUTE_FAILED:   descr = "source-route-failed";           break;
+       case DSTNET_UNKNOWN:    descr = "destination-network-unknown";   break;
+       case DSTHOST_UNKNOWN:   descr = "destination-host-unknown";      break;
+       case SRCHOST_ISOLATED:  descr = "source-host-isolated";          break;
+       case DSTNET_PROHIB:     descr = "dest-net-admin-prohibited";     break;
+       case DSTHOST_PROHIB:    descr = "dest-host-admin-prohibited";    break;
+       case NET_UNREACH_TOS:   descr = "network-unreachable-for-TOS";   break;
+       case HOST_UNREACH_TOS:  descr = "host-unreachable-for-TOS";      break;
+       case COMM_PROHIB:       descr = "trafffic-prohibited-by-filter"; break;
+       case HOST_PREC_VIOL:    descr = "host-precedence-violation";     break;
+       case PREC_CUTOFF:       descr = "precedence-cutoff-in-effect";   break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case SRC_QUENCH:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case REDIRECT:
+      switch (code) {
+       case REDIR_FOR_NET:     descr = "route-wrong-for-network";       break;
+       case REDIR_FOR_HOST:    descr = "route-wrong-for-host";          break;
+       case REDIR_FOR_TOSNET:  descr = "route-wrong-for-TOS-and-net";   break;
+       case REDIR_FOR_TOSHOST: descr = "route-wrong-for-TOS-and-host";  break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case ECHO_REQ:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case ROUTER_AD:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case ROUTER_SOL:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case TIME_EXCEED:
+      switch (code) {
+       case TTL_ZERO:          descr = "TTL-reached-zero";              break;
+       case REASS_TIMEOUT:     descr = "reassembly-timer-expired";      break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case PARAM_PROB:
+      switch (code) {
+       case IP_HDR_BAD:        descr = "IP-header-bad";                 break;
+       case MISSING_OPT:       descr = "required-option-is-missing";    break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case TIME_REQ:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case TIME_REPLY:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case INFO_REQ:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case INFO_REPLY:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case MASK_REQ:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    case MASK_REPLY:
+      switch (code) {
+       case 0:                                                          break;
+       default:                descr = bad;                             break;
+      }
+      break;
+    default:
+      break;
+   }
+
+   return descr;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Print the type of ICMP packet.                                           */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *icmptype (
+   uint1 type
+) {
+
+   char *descr;
+
+
+   switch (type) {
+    case ECHO_REPLY:  descr = "echo-reply";              break;
+    case DST_UNREACH: descr = "destination-unreachable"; break;
+    case SRC_QUENCH:  descr = "source-quench";           break;
+    case REDIRECT:    descr = "redirect";                break;
+    case ECHO_REQ:    descr = "echo-request";            break;
+    case ROUTER_AD:   descr = "router-advertisement";    break;
+    case ROUTER_SOL:  descr = "router-solicitation";     break;
+    case TIME_EXCEED: descr = "time-exceeded";           break;
+    case PARAM_PROB:  descr = "parameter-problem";       break;
+    case TIME_REQ:    descr = "timestamp-request";       break;
+    case TIME_REPLY:  descr = "timestamp-reply";         break;
+    case INFO_REQ:    descr = "information-request";     break;
+    case INFO_REPLY:  descr = "information-reply";       break;
+    case MASK_REQ:    descr = "address-mask-request";    break;
+    case MASK_REPLY:  descr = "address-mask-reply";      break;
+    default:          descr = unknown;                   break;
+   }
+
+   return descr;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Print the IP address in dotted-quad.                                     */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *ipaddr (
+   char **pkt
+) {
+
+   static char addr[16];
+   uint2 byte1;
+   uint2 byte2;
+   uint2 byte3;
+   uint2 byte4;
+
+
+   /* We don't use inet_ntoa() because it wants a socket structure.         */
+   byte1 = (uint2)getbyte(pkt);
+   byte2 = (uint2)getbyte(pkt);
+   byte3 = (uint2)getbyte(pkt);
+   byte4 = (uint2)getbyte(pkt);
+   (void)sprintf(addr, "%d.%d.%d.%d", byte1, byte2, byte3, byte4);
+
+   return addr;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Print the type of protocol encapsulated in the IP datagram.              */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *ip_proto (
+   uint1 code
+) {
+
+   char *name;
+
+
+   /* A simple table won't do, as the codes aren't contiguous.               */
+   switch (code) {
+    case IP:
+       name = "IP"; break;
+    case ICMP:
+       name = "ICMP"; break;
+    case IGMP:
+       name = "IGMP"; break;
+    case GGP:
+       name = "GGP"; break;
+    case IPENCAP:
+       name = "IPENCAP"; break;
+    case ST:
+       name = "ST"; break;
+    case TCP:
+       name = "TCP"; break;
+    case EGP:
+       name = "EGP"; break;
+    case PUP:
+       name = "PUP"; break;
+    case UDP:
+       name = "UDP"; break;
+    case HMP:
+       name = "HMP"; break;
+    case XNSIDP:
+       name = "XNSIDP"; break;
+    case RDP:
+       name = "RDP"; break;
+    case ISOTP4:
+       name = "ISOTP4"; break;
+    case XTP:
+       name = "XTP"; break;
+    case IDPRCMTP:
+       name = "IDPRCMTP"; break;
+    case RSVP:
+       name = "RSVP"; break;
+    case VMTP:
+       name = "VMTP"; break;
+    case OSPF:
+       name = "OSPF"; break;
+    case IPIP:
+       name = "IPIP"; break;
+    case ENCAP:
+       name = "ENCAP"; break;
+    default:
+       name = unknown; break;
+   }
+
+   return name;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Decode a "tcpdump" savefile.                                             */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+void main (
+   int argc,
+   char **argv
+) {
+
+   /* Command line options.                                                 */
+   while (--argc > 0 && **++argv == '-')
+      if (strcmp(*argv, "-data") == 0)
+	 dataflag = nolinkflag = noipflag = TRUE;
+      elif (strcmp(*argv, "-s") == 0) sflag = TRUE;
+      elif (strcmp(*argv, "-b") == 0) bflag = TRUE;
+      elif (strcmp(*argv, "-sb") == 0) sbflag = TRUE;
+      elif (strcmp(*argv, "-terse") == 0) terseflag = TRUE;
+      elif (strcmp(*argv, "-track") == 0) trackflag = TRUE;
+      elif (strcmp(*argv, "-nodata") == 0) nodataflag = TRUE;
+      elif (strcmp(*argv, "-nolink") == 0) nolinkflag = TRUE;
+      elif (strcmp(*argv, "-noip") == 0) noipflag = TRUE;
+      elif (strcmp(*argv, "-cooked") == 0) cookedflag = TRUE;
+      elif (strcmp(*argv, "-pp") == 0) ppflag = TRUE;
+      elif (strcmp(*argv, "-h") == 0) usage();
+      elif (strcmp(*argv, "-w") == 0) {
+         if (--argc <= 0) error("-w needs a numeric argument");
+         if ((pagewidth=atoi(*++argv)) < 1) error("-w value too small");
+      }
+      else error("Unknown command line flag");
+
+   if (! cookedflag)
+      fork_tcpdump(argc, argv);
+   elif (argc != 0)
+      fprintf(stderr, "input is cooked -- ignoring tcpdump expressions\n");
+
+   pkt = getpkt();
+   for ( ; ; ) if (! setjmp(jmpbuf)) showpkt(pkt);
+
+   exit(0);
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Return the next character in the packet buffer.                          */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char nextchar (
+   char **pkt
+) {
+
+   if (! **pkt) *pkt = getpkt();
+
+   return *(*pkt)++;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Remove whitespace from the buffer.                                       */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *rmwspace (
+   reg char *pktbuf
+) {
+
+   static char cleanpkt[MAXPKT+1];
+   reg char *pkt;
+
+
+   pkt = cleanpkt;
+   while (*pktbuf) {
+      if (! isspace(*pktbuf)) *pkt++ = *pktbuf;
+      pktbuf++;
+   }
+   *pkt = '\0';
+
+   return cleanpkt;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Decode the TCP/UDP data.                                                 */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *showdata (
+   char *pkt
+) {
+
+   uint1 byte;
+   int col;
+   char *descr;
+
+
+   if (dataflag)
+      putchar('\t');
+   elif (terseflag)
+      printf("DATA:\t");
+   else {
+      switch (proto) {
+       case TCP:  descr = "TCP";   break;
+       case UDP:  descr = "UDP";   break;
+       case ICMP: descr = "ICMP";  break;
+       default:   descr = unknown; break;
+      }
+      printf("%s Data\n\t", descr);
+   }
+   if (nodataflag) {
+      uint2 ndatabytes = datalen;
+      datalen = 0;
+      printf("%d bytes\n", ndatabytes);
+      return skip(pkt, ndatabytes);
+   }
+
+   if (datalen == 0) {
+      printf("<No data>\n");
+      return pkt;
+   }
+
+   switch (bflag) {
+    case TRUE:
+      for (col = 1; datalen > 0; datalen--, col++) {
+         byte = getbyte(&pkt);
+	 if (byte == '\n') {
+	    putchar('\n');
+	    byte = '\t';
+	    col = 0;
+         }
+	 elif (col > pagewidth) {
+            printf("%s\n\t", sbflag? "<break>": "");
+	    col = 1;
+	 }
+         if (byte != '\t' && byte != '\n' && !isprint(byte)) byte = '.';
+         putchar(byte);
+      }
+      break;
+    case FALSE:
+      for ( ; datalen > 0; datalen--) {
+         byte = getbyte(&pkt);
+         if (byte == '\n') {
+	    putchar('\n');
+	    byte = '\t';
+         }
+         if (byte != '\t' && byte != '\n' && !isprint(byte)) byte = '.';
+         putchar(byte);
+      }
+      break;
+    default:
+      error("Tri-valued boolean!");
+   }
+   putchar('\n');
+
+   return pkt;
+   
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Decode the packet header.                                                */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *showhdr (
+   char *pkt
+) {
+
+   char efrom[18];                     /* Source Ethernet address           */
+   char eto[18];                       /* Destination Ethernet address      */
+   char time[16];                      /* Packet timestamp                  */
+   char etype[20];                     /* Ethernet type (decoded to ASCII)  */
+
+
+   if (ppflag) {
+      (void)sscanf(pkt, "%s", time);
+      isip = TRUE;                     /* tcpdump doesn't supply link type  */
+      if (! nolinkflag)
+	 if (terseflag) printf("TIME:\t%s\n", time);
+	 else printf("\tTimestamp:\t\t\t%s\n", time);
+      return getpkt();
+   }
+
+   (void)sscanf(pkt, "%s %s %s %s", time, efrom, eto, etype);
+
+   isip = (boolean)(strcmp(etype, "0800") == 0);
+   (void)strcpy(efrom, etheraddr(efrom));
+   (void)strcpy(eto, etheraddr(eto));
+
+   if (! nolinkflag)
+      if (terseflag) {
+	 printf("TIME:\t%s\n", time);
+	 printf("LINK:\t%s -> %s type=%s\n", efrom, eto, ether_proto(etype));
+      }
+      else {
+	 printf("\tTimestamp:\t\t\t%s\n", time);
+	 printf("\tSource Ethernet Address:\t%s\n", efrom);
+	 printf("\tDestination Ethernet Address:\t%s\n", eto);
+	 printf("\tEncapsulated Protocol:\t\t%s\n", ether_proto(etype));
+      }
+
+   return getpkt();
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Decode the ICMP header.                                                  */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *showicmp (
+   char *pkt
+) {
+
+   uint2 cksum;
+   uint1 code;
+   uint2 nskipped;
+   uint1 type;
+   char *why;
+
+
+   type = getbyte(&pkt);  nskipped  = sizeof(type);
+   code = getbyte(&pkt);  nskipped += sizeof(code);
+   cksum = getword(&pkt); nskipped += sizeof(cksum);
+
+   /* The length of the ICMP packet isn't recorded in the packet itself.    */
+   /* Must calculate it from the size of the IP datagram - the IP header.   */
+   datalen -= ICMPHDRLEN;
+
+   why = icmpcode(type, code);
+   if (dataflag) {
+      printf(
+         "%s -> %s ICMP%s%s%s%s\n",
+         sip, dip,
+         why? "\n": " ", icmptype(type), why? " because ": "", why? why: ""
+      );
+      return pkt;                      /* Header is read; nothing to skip   */
+   }
+
+   if (terseflag)
+      printf(
+	 "ICMP:\t%s%s%s cksum=%04X\n",
+	 icmptype(type), why? " because ": "", why? why: "", cksum
+      );
+   else {
+      printf("ICMP Header\n");
+      printf(
+	 "\tType:\t\t\t\t%s%s%s\n",
+	 icmptype(type), why? "\n\tBecause:\t\t\t": "", why? why: ""
+      );
+      printf("\tChecksum:\t\t\t0x%04X\n", cksum);
+   }
+
+   return pkt;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Decode the IP header.                                                    */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *showip (
+   char *pkt
+) {
+
+   uint2 cksum;
+   uint2 dgramlen;
+   uint2 flags;
+   uint2 hlen;
+   uint2 id;
+   uint2 nskipped;
+   uint1 servtype;
+   uint1 ttl;
+   uint1 ver;
+
+
+   ver = getbyte(&pkt);             nskipped  = sizeof(ver);
+   if ((ver & 0xF0) != 0x40) {
+      if (terseflag) printf("IP:\tnot v4\n");
+      else
+	 printf(
+	    "IP Header\n\t<Not an IPv4 datagram (ver=%d)>\n",
+	    (ver & 0xF0) >> 4
+	 );
+      nextpkt();
+   }
+   servtype = getbyte(&pkt);        nskipped += sizeof(servtype);
+   dgramlen = getword(&pkt);        nskipped += sizeof(dgramlen);
+   id = getword(&pkt);              nskipped += sizeof(id);
+   flags = getword(&pkt);           nskipped += sizeof(flags);
+   ttl = getbyte(&pkt);             nskipped += sizeof(ttl);
+   proto = getbyte(&pkt);           nskipped += sizeof(proto);
+   cksum = getword(&pkt);           nskipped += sizeof(cksum);
+   (void)strcpy(sip, ipaddr(&pkt)); nskipped += 4;
+   (void)strcpy(dip, ipaddr(&pkt)); nskipped += 4;
+   hlen = (ver & 0x0F) * 4;
+   datalen = dgramlen - hlen;
+
+   if (noipflag) return skip(pkt, hlen - nskipped);
+
+   printf("%s", terseflag? "  IP:\t": "IP Header\n");
+
+   if (terseflag) {
+      printf(
+	 "%s -> %s hlen=%d TOS=%02X dgramlen=%d id=%04X\n",
+	 sip, dip, hlen, (uint2)servtype, dgramlen, id
+      );
+      printf(
+	 "\tMF/DF=%s/%s frag=%d TTL=%d proto=%s cksum=%04X\n",
+	 (flags & MF) == MF? "1": "0", (flags & DF) == DF? "1": "0",
+	 flags & FRAGOFF, ttl, ip_proto(proto), cksum
+      );
+   }
+
+   else {
+      printf("\tVersion:\t\t\t4\n\tHeader Length:\t\t\t%d bytes\n", hlen);
+      printf("\tService Type:\t\t\t0x%02X\n", (uint2)servtype);
+      printf("\tDatagram Length:\t\t%d bytes\n", dgramlen);
+      printf("\tIdentification:\t\t\t0x%04X\n", id);
+      printf(
+	 "\tFlags:\t\t\t\tMF=%s DF=%s\n",
+	 (flags & MF) == MF? on: off, (flags & DF) == DF? on_e: off_e
+      );
+      printf("\tFragment Offset:\t\t%d\n", flags & FRAGOFF);
+      printf("\tTTL:\t\t\t\t%d\n", ttl);
+      printf("\tEncapsulated Protocol:\t\t%s\n", ip_proto(proto));
+      printf("\tHeader Checksum:\t\t0x%04X\n", cksum);
+      printf("\tSource IP Address:\t\t%s\n", sip);
+      printf("\tDestination IP Address:\t\t%s\n", dip);
+   }
+
+   if (hlen > IPHDRLEN) {
+      if (! terseflag) printf("\t<Options not displayed>\n");
+      pkt = skip(pkt, hlen - IPHDRLEN);
+   }
+
+   return pkt;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Decode the packet chunk in the buffer.                                   */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static void showpkt (
+   reg char *pkt
+) {
+
+   isip = FALSE;
+
+   if (++npkts_shown > 1) prsep();
+   if (! dataflag) printf("Packet %d\n", npkts_shown);
+
+   pkt = showhdr(pkt);
+   if (! isip) {
+      if (! dataflag)
+         printf("\t<*** No decode support for non-IP protocols ***>\n");
+      nextpkt();                       /* Doesn't return                    */
+   }
+   pkt = showip(pkt);
+   switch (proto) {
+    case TCP:
+      pkt = showtcp(pkt);
+      pkt = showdata(pkt);
+      break;
+    case UDP:
+      pkt = showudp(pkt);
+      pkt = showdata(pkt);
+      break;
+    case ICMP:
+      pkt = showicmp(pkt);
+      pkt = showdata(pkt);
+      break;
+    default:
+      printf("\t<*** No decode support for encapsulated protocol ***>\n");
+      datalen = 0;
+      nextpkt();                       /* Doesn't return                    */
+   }
+   /* "tcpdump" sometimes displays data at the end of a packet which, given */
+   /* the recorded Datagram Length, don't belong to the packet.             */
+   if (*pkt && sflag)
+      printf("\t<*** Spurious data at end: \"%s\" ***>\n", pkt);
+   (void)getpkt();                     /* Load start of next packet         */
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Decode the TCP header.                                                   */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *showtcp (
+   char *pkt
+) {
+
+   uint4 ack;
+   uint2 advert;
+   uint2 cksum;
+   uint2 dport;
+   uint4 expect;
+   uint2 flags;
+   uint2 hlen;
+   uint2 nskipped;
+   uint4 seq;
+   uint2 sport;
+   uint2 urgptr;
+
+
+   sport = getword(&pkt);   nskipped  = sizeof(sport);
+   dport = getword(&pkt);   nskipped += sizeof(dport);
+   seq = getlongword(&pkt); nskipped += sizeof(seq);
+   ack = getlongword(&pkt); nskipped += sizeof(ack);
+   flags = getword(&pkt);   nskipped += sizeof(flags);
+   advert = getword(&pkt);  nskipped += sizeof(advert);
+   cksum = getword(&pkt);   nskipped += sizeof(cksum);
+   urgptr = getword(&pkt);  nskipped += sizeof(urgptr);
+
+   hlen = (flags >> 12 & 0x0F) * 4;
+   datalen -= hlen;
+
+   if (dataflag) {
+      char dname[20];
+      char sname[20];
+      (void)strcpy(sname, svcname(sport, "tcp", TRUE));
+      (void)strcpy(dname, svcname(dport, "tcp", TRUE));
+      printf("%s.%s -> %s.%s over TCP\n", sip, sname, dip, dname);
+      return skip(pkt, hlen - nskipped);
+   }
+
+   if (trackflag) {
+      expect = seq + datalen;
+      if ((flags & SYN) == SYN || (flags & FIN) == FIN) expect++;
+   }
+
+   if (terseflag) {
+      printf(" TCP:\tport %d -> %d seq=%010lu", sport, dport, seq);
+      if (trackflag) printf(" (expect=%010lu)", expect);
+      printf(" ack=%010lu\n", ack);
+      printf(
+	 "\thlen=%d (data=%u) UAPRSF=%s%s%s%s%s%s",
+	 hlen, datalen,
+	 (flags & URG) == URG? "1": "0", (flags & ACK) == ACK? "1": "0",
+	 (flags & PSH) == PSH? "1": "0", (flags & RST) == RST? "1": "0",
+	 (flags & SYN) == SYN? "1": "0", (flags & FIN) == FIN? "1": "0"
+      );
+      printf(" wnd=%d cksum=%04X urg=%d\n", advert, cksum, urgptr);
+   }
+
+   else {
+      printf("TCP Header\n");
+      printf(
+	 "\tSource Port:\t\t\t%d (%s)\n",
+	 sport, svcname(sport, "tcp", FALSE)
+      );
+      printf(
+	 "\tDestination Port:\t\t%d (%s)\n",
+	 dport, svcname(dport, "tcp", FALSE)
+      );
+      printf("\tSequence Number:\t\t%010lu\n", seq);
+      if (trackflag) printf("\tExpect peer ACK:\t\t%010lu\n", expect);
+      printf("\tAcknowledgement Number:\t\t%010lu\n", ack);
+      printf("\tHeader Length:\t\t\t%d bytes (data=%u)\n", hlen, datalen);
+      printf(
+	 "\tFlags:%s%s%s%s%s%s\n%s%s%s%s%s%s\n",
+	 "\t\t\t\tURG=",   (flags & URG) == URG? on: off,
+	 " ACK=",          (flags & ACK) == ACK? on: off,
+	 " PSH=",          (flags & PSH) == PSH? on_e: off_e,
+	 "\t\t\t\t\tRST=", (flags & RST) == RST? on: off,
+	 " SYN=",          (flags & SYN) == SYN? on: off,
+	 " FIN=",          (flags & FIN) == FIN? on_e: off_e
+      );
+      printf("\tWindow Advertisement:\t\t%d bytes\n", advert);
+      printf("\tChecksum:\t\t\t0x%04X\n", cksum);
+      printf("\tUrgent Pointer:\t\t\t%d\n", urgptr);
+   }
+
+   if (hlen > TCPHDRLEN) {
+      if (! terseflag) printf("\t<Options not displayed>\n");
+      pkt = skip(pkt, hlen - TCPHDRLEN);
+   }
+
+   return pkt;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Decode the UDP header.                                                   */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *showudp (
+   char *pkt
+) {
+
+   uint2 cksum;
+   uint2 dgramlen;
+   uint2 dport;
+   uint2 nskipped;
+   uint2 sport;
+
+
+   sport     = getword(&pkt); nskipped  = sizeof(sport);
+   dport     = getword(&pkt); nskipped += sizeof(dport);
+   dgramlen  = getword(&pkt); nskipped += sizeof(dgramlen);
+   cksum     = getword(&pkt); nskipped += sizeof(cksum);
+
+   /* The size of the IP data field should equal the UDP packet length.     */
+   if (datalen != dgramlen) {
+      printf("\t<*** Packet length corrupt ***>\n");
+      nextpkt();                       /* Doesn't return                    */
+   }
+   datalen -= UDPHDRLEN;
+
+   if (dataflag) {
+      char dname[20];
+      char sname[20];
+      (void)strcpy(sname, svcname(sport, "udp", TRUE));
+      (void)strcpy(dname, svcname(dport, "udp", TRUE));
+      printf("%s.%s -> %s.%s over UDP\n", sip, sname, dip, dname);
+      return pkt;                      /* Header is read; nothing to skip   */
+   }
+
+   if (terseflag)
+      printf(
+	 " UDP:\tport %d -> %d hdr=%u data=%u\n",
+	 sport, dport, UDPHDRLEN, datalen
+      );
+   else {
+      printf("UDP Header\n");
+      printf(
+	 "\tSource Port:\t\t\t%d (%s)\n",
+	 sport, svcname(sport, "udp", FALSE)
+      );
+      printf(
+	 "\tDestination Port:\t\t%d (%s)\n",
+	 dport, svcname(dport, "udp", FALSE)
+      );
+      printf(
+	 "\tDatagram Length:\t\t%u bytes (Header=%u, Data=%u)\n",
+	 dgramlen, UDPHDRLEN, datalen
+      );
+      printf("\tChecksum:\t\t\t0x%04X\n", cksum);
+   }
+
+   return pkt;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Skip over un-interesting bytes.                                          */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *skip (
+   char *pkt,
+   uint2 nbytes
+) {
+
+   for ( ; nbytes > 0; nbytes--) (void)getbyte(&pkt);
+   return pkt;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Return the WKS name for the given port.                                  */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static char *svcname (
+   uint2 port,
+   char *proto,
+   boolean want_number
+) {
+
+   char *name;
+   static char number[6];
+   struct servent *service;            /* Doesn't need to be static         */
+
+
+   /* The crappy manpage doesn't say the port must be in net byte order.    */
+   if (service = getservbyport((int)htons(port), proto))
+      name = service->s_name;
+   elif (! want_number)
+      name = unknown;
+   else {
+      sprintf(number, "%u", port);
+      name = number;
+   }
+
+   return name;
+
+}
+
+
+/****==========------------------------------------------------==========****/
+/*                                                                          */
+/* Give a summary of usage.                                                 */
+/*                                                                          */
+/****==========------------------------------------------------==========****/
+
+static void usage (
+) {
+
+#if !defined(MAY_NOT_MODIFY)
+   printf("\nCopyright (c) 1996 I.T. NetworX Ltd.  All rights reserved.\n");
+   printf("mailto:mike at NetworX.ie\n\n");
+#endif
+   printf("tcpshow -- decode a tcpdump(1) savefile, giving a verbose\n");
+   printf("           display of the headers and an ASCII display of\n");
+   printf("           ICMP, UDP and TCP data.\n\n");
+   printf("Version %3.1f\n\n", VERSION);
+   printf("Usage: tcpshow [ options ... ] [ expr ]\n");
+   printf("\nwhere options are as follows\n");
+   printf("\t-b\t\tbreak long lines so they don't wrap\n");
+   printf("\t-sb\t\tshow breaks (show where we broke a line)\n");
+   printf("\t-w width\tset pagewidth to \"width\" columns (used by -b)\n");
+   printf("\t-nolink\t\tdon't decode link header (Ethernet header)\n");
+   printf("\t-noip\t\tdon't decode IP header\n");
+   printf("\t-nodata\t\tdon't show data (show headers only)\n");
+   printf("\t-data\t\tdisplay data only; minimal header decode\n");
+   printf("\t-track\t\ttrack sequence numbers (show next-expected ACK)\n");
+   printf("\t-terse\t\tshow header decode in compact format\n");
+   printf("\t-cooked\t\tdon't run tcpdump to pre-process the input\n");
+   printf("\t-pp\t\tpoint-to-point link (no Ethernet header available)\n");
+   printf("\t-s\t\tdisplay hex dump of spurious data at packet-end\n");
+   printf("\t-h\t\tdisplay this help summary\n\n");
+   printf("expr is a tcpdump(1) expression, and is only valid when ");
+   printf("the -cooked\noption is not used.\n\n");
+   printf("Input is from stdin, ");
+   printf("which must be a raw tcpdump(1) data file (savefile),\n");
+   printf("unless the -cooked option is used, in which case stdin ");
+   printf("must be in the\nformat produced by tcpdump -lenx.\n\n");
+   printf("Output is to stdout\n\n");
+   printf("tcpdump(1) must be on your PATH unless -cooked is used.\n\n");
+
+   exit(0);
+
+}

Added: trunk/rpms/tcpshow/tcpshow.patch
===================================================================
--- trunk/rpms/tcpshow/tcpshow.patch	                        (rev 0)
+++ trunk/rpms/tcpshow/tcpshow.patch	2007-02-22 22:33:11 UTC (rev 5194)
@@ -0,0 +1,20 @@
+--- tcpshow.c.cln	Sat Jan 16 11:32:43 1999
++++ tcpshow.c	Sat Jan 16 12:11:01 1999
+@@ -286,7 +286,7 @@
+ typedef unsigned char uchar;
+ 
+ 
+-void main(int, char **);
++int main(int, char **);
+ 
+ 
+ static boolean bflag = FALSE;
+@@ -858,7 +858,7 @@
+ /*                                                                          */
+ /****==========------------------------------------------------==========****/
+ 
+-void main (
++int main (
+    int argc,
+    char **argv
+ ) {

Added: trunk/rpms/tcpshow/tcpshow.spec
===================================================================
--- trunk/rpms/tcpshow/tcpshow.spec	                        (rev 0)
+++ trunk/rpms/tcpshow/tcpshow.spec	2007-02-22 22:33:11 UTC (rev 5194)
@@ -0,0 +1,46 @@
+# $Id$
+# Authority: dag
+
+Summary: Prints dump files created by tcpdump
+Name: tcpshow
+Version: 1.0
+Release: 1
+License: distributable; see tcpshow.c for details
+Group: Applications/Internet
+URL: http://www.cs.berkeley.edu/~daw/mike/
+
+Source0: http://www.cs.berkeley.edu/~daw/mike/tcpshow.c
+Source1: http://www.cs.berkeley.edu/~daw/mike/tcpshow.1
+Patch0: tcpshow.patch
+BuildRoot: %{_tmppath}/%{name}-%{release}-%{version}-root
+
+Requires: tcpdump
+
+%description
+Utility to print raw packet dumps from tcpdump(8).
+
+%prep
+%setup -c -T
+%{__cp} -av %{SOURCE0} %{SOURCE1} .
+%patch0 -p0
+
+%build
+#%{__cc} -static %{optflags} -o tcpshow tcpshow.c
+%{__cc} %{optflags} -o tcpshow tcpshow.c
+
+%install
+%{__rm} -rf %{buildroot}
+%{__install} -Dp -m0755 tcpshow %{buildroot}%{_sbindir}/tcpshow
+%{__install} -Dp -m0644 tcpshow.1 %{buildroot}%{_mandir}/man1/tcpshow.1
+
+%files
+%defattr(-, root, root, 0755)
+%doc %{_mandir}/man1/tcpshow.1*
+%{_sbindir}/tcpshow
+
+%clean
+%{__rm} -rf %{buildroot}
+
+%changelog
+* Thu Feb 22 2007 Dag Wieers <dag at wieers.com> - 1.0-1
+- Initial package. (using DAR)


Property changes on: trunk/rpms/tcpshow/tcpshow.spec
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: trunk/rpms/tcpstat/tcpstat.spec
===================================================================
--- trunk/rpms/tcpstat/tcpstat.spec	                        (rev 0)
+++ trunk/rpms/tcpstat/tcpstat.spec	2007-02-22 22:33:11 UTC (rev 5194)
@@ -0,0 +1,45 @@
+# $Id$
+# Authority: dag
+
+Summary: Reports certain network interface statistics
+Name: tcpstat
+Version: 1.5
+Release: 1
+License: NSD
+Group: System Environment/Tools
+URL: http://www.frenchfries.net/paul/tcpstat/
+
+Source: http://www.frenchfries.net/paul/tcpstat/tcpstat-%{version}.tar.gz
+Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root
+
+%description
+tcpstat reports certain network interface statistics much like vmstat does
+for system statistics.
+
+tcpstat gets its information by either monitoring a specific interface, or
+by reading previously saved tcpdump data from a file. 
+
+%prep
+%setup
+
+%build
+%configure 
+%{__make} %{?_smp_mflags}
+
+%install
+%{__rm} -rf %{buildroot}
+%{__make} install DESTDIR="%{buildroot}"
+
+%files
+%defattr(-, root, root, 0755)
+%doc AUTHORS COPYING INSTALL LICENSE NEWS README doc/Tips_and_Tricks.txt
+%doc %{_mandir}/man1/tcpprof.1*
+%doc %{_mandir}/man1/tcpstat.1*
+%{_bindir}/tcpstat
+
+%clean
+%{__rm} -rf %{buildroot}
+
+%changelog
+* Thu Feb 22 2007 Dag Wieers <dag at wieers.com> - 1.5-1
+- Initial package. (using DAR)


Property changes on: trunk/rpms/tcpstat/tcpstat.spec
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native



More information about the svn-commits mailing list