[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