summaryrefslogtreecommitdiffstats
path: root/usr.sbin/tcpdump
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>1995-10-18 08:37:01 +0000
committerderaadt <deraadt@openbsd.org>1995-10-18 08:37:01 +0000
commitdf930be708d50e9715f173caa26ffe1b7599b157 (patch)
treeaa317e49e28cb999c9cf3db7f00c20903fe6010a /usr.sbin/tcpdump
downloadwireguard-openbsd-df930be708d50e9715f173caa26ffe1b7599b157.tar.xz
wireguard-openbsd-df930be708d50e9715f173caa26ffe1b7599b157.zip
initial import of NetBSD tree
Diffstat (limited to 'usr.sbin/tcpdump')
-rw-r--r--usr.sbin/tcpdump/CHANGES197
-rw-r--r--usr.sbin/tcpdump/Makefile43
-rw-r--r--usr.sbin/tcpdump/README209
-rw-r--r--usr.sbin/tcpdump/addrtoname.c724
-rw-r--r--usr.sbin/tcpdump/addrtoname.h37
-rw-r--r--usr.sbin/tcpdump/appletalk.h169
-rw-r--r--usr.sbin/tcpdump/atime.awk20
-rw-r--r--usr.sbin/tcpdump/bootp.h111
-rw-r--r--usr.sbin/tcpdump/bpf_dump.c67
-rw-r--r--usr.sbin/tcpdump/decnet.h482
-rw-r--r--usr.sbin/tcpdump/ethertype.h72
-rw-r--r--usr.sbin/tcpdump/extract.h51
-rw-r--r--usr.sbin/tcpdump/fddi.h78
-rw-r--r--usr.sbin/tcpdump/interface.h152
-rw-r--r--usr.sbin/tcpdump/ipx.h31
-rw-r--r--usr.sbin/tcpdump/llc.h122
-rw-r--r--usr.sbin/tcpdump/makemib175
-rw-r--r--usr.sbin/tcpdump/md.h35
-rw-r--r--usr.sbin/tcpdump/mib.h1258
-rw-r--r--usr.sbin/tcpdump/nfsfh.h36
-rw-r--r--usr.sbin/tcpdump/nfsv2.h262
-rw-r--r--usr.sbin/tcpdump/ntp.h119
-rw-r--r--usr.sbin/tcpdump/os.h62
-rw-r--r--usr.sbin/tcpdump/ospf.h225
-rw-r--r--usr.sbin/tcpdump/packetdat.awk63
-rw-r--r--usr.sbin/tcpdump/parsenfsfh.c427
-rw-r--r--usr.sbin/tcpdump/print-arp.c123
-rw-r--r--usr.sbin/tcpdump/print-atalk.c573
-rw-r--r--usr.sbin/tcpdump/print-bootp.c359
-rw-r--r--usr.sbin/tcpdump/print-decnet.c765
-rw-r--r--usr.sbin/tcpdump/print-domain.c276
-rw-r--r--usr.sbin/tcpdump/print-egp.c358
-rw-r--r--usr.sbin/tcpdump/print-ether.c194
-rw-r--r--usr.sbin/tcpdump/print-fddi.c353
-rw-r--r--usr.sbin/tcpdump/print-icmp.c217
-rw-r--r--usr.sbin/tcpdump/print-ip.c364
-rw-r--r--usr.sbin/tcpdump/print-ipx.c214
-rw-r--r--usr.sbin/tcpdump/print-isoclns.c317
-rw-r--r--usr.sbin/tcpdump/print-llc.c198
-rw-r--r--usr.sbin/tcpdump/print-nfs.c856
-rw-r--r--usr.sbin/tcpdump/print-ntp.c287
-rw-r--r--usr.sbin/tcpdump/print-null.c113
-rw-r--r--usr.sbin/tcpdump/print-ospf.c580
-rw-r--r--usr.sbin/tcpdump/print-ppp.c104
-rw-r--r--usr.sbin/tcpdump/print-rip.c117
-rw-r--r--usr.sbin/tcpdump/print-sl.c245
-rw-r--r--usr.sbin/tcpdump/print-snmp.c1034
-rw-r--r--usr.sbin/tcpdump/print-sunrpc.c114
-rw-r--r--usr.sbin/tcpdump/print-tcp.c278
-rw-r--r--usr.sbin/tcpdump/print-tftp.c147
-rw-r--r--usr.sbin/tcpdump/print-udp.c259
-rw-r--r--usr.sbin/tcpdump/print-wb.c447
-rw-r--r--usr.sbin/tcpdump/send-ack.awk70
-rw-r--r--usr.sbin/tcpdump/stime.awk21
-rw-r--r--usr.sbin/tcpdump/tcpdump.81173
-rw-r--r--usr.sbin/tcpdump/tcpdump.c413
-rw-r--r--usr.sbin/tcpdump/util.c337
-rw-r--r--usr.sbin/tcpdump/version.c3
58 files changed, 16136 insertions, 0 deletions
diff --git a/usr.sbin/tcpdump/CHANGES b/usr.sbin/tcpdump/CHANGES
new file mode 100644
index 00000000000..78281761384
--- /dev/null
+++ b/usr.sbin/tcpdump/CHANGES
@@ -0,0 +1,197 @@
+$NetBSD: CHANGES,v 1.2 1995/03/06 19:09:42 mycroft Exp $
+@(#) Header: CHANGES,v 1.6 94/06/20 19:34:38 leres Exp (LBL)
+
+v3.0 Mon Jun 20 19:23:27 PDT 1994
+
+- Reorganize protocol dumpers to take const pointers to packets so they
+ never change the contents (i.e., they used to do endian conversions
+ in place). Previously, whenever more than one pass was taken over
+ the packet, the packet contents would be dumped incorrectly (i.e.,
+ the output form -x would be wrong on little endian machines because
+ the protocol dumpers would modify the data). Thanks to Charles Hannum
+ (mycroft@gnu.ai.mit.edu) for reporting this problem.
+
+- Added support for decnet protocol dumping thanks to Jeff Mogul
+ (mogul@pa.dec.com).
+
+- Fix bug that caused length of packet to be incorrectly printed
+ (off by ether header size) for unknown ethernet types thanks
+ to Greg Miller (gmiller@kayak.mitre.org).
+
+- Added support for IPX protocol dumping thanks to Brad Parker
+ (brad@fcr.com).
+
+- Added check to verify IP header checksum under -v thanks to
+ Brad Parker (brad@fcr.com).
+
+- Move packet capture code to new libpcap library (which is
+ packaged separately).
+
+- Prototype everything and assume an ansi compiler.
+
+- print-arp.c: Print hardware ethernet addresses if they're not
+ what we expect.
+
+- print-bootp.c: Decode the cmu vendor field. Add RFC1497 tags.
+ Many helpful suggestions from Gordon Ross (gwr@jericho.mc.com).
+
+- print-fddi.c: Improvements. Thanks to Jeffrey Mogul
+ (mogul@pa.dec.com).
+
+- print-icmp.c: Byte swap netmask before printing. Thanks to
+ Richard Stevens (rstevens@noao.edu). Print icmp type when unknown.
+
+- print-ip.c: Print the inner ip datagram of ip-in-ip encapsulated packets.
+ By default, only the inner packet is dumped, appended with the token
+ "(encap)". Under -v, both the inner and output packets are dumped
+ (on the same line). Note that the filter applies to the original packet,
+ not the encapsulated packet. So if you run tcpdump on a net with an
+ IP Multicast tunnel, you cannot filter out the datagrams using the
+ conventional syntax. (You can filter away all the ip-in-ip traffic
+ with "not ip proto 4".)
+
+- print-nfs.c: Keep pending rpc's in circular table. Add generic
+ nfs header and remove os dependences. Thanks to Jeffrey Mogul.
+
+- print-ospf.c: Improvements. Thanks to Jeffrey Mogul.
+
+- tcpdump.c: Add -T flag allows interpretation of "vat", "wb", "rpc"
+ (sunrpc) and rtp packets. Added "inbound" and "outbound" keywords
+ Add && and || operators
+
+v2.2.1 Tue Jun 6 17:57:22 PDT 1992
+
+- Fix bug with -c flag.
+
+v2.2 Fri May 22 17:19:41 PDT 1992
+
+- savefile.c: Remove hack that shouldn't have been exported. Add
+ truncate checks.
+
+- Added the 'icmp' keyword. For example, 'icmp[0] != 8 and icmp[0] != 0'
+ matches non-echo/reply ICMP packets.
+
+- Many improvements to filter code optimizer.
+
+- Added 'multicast' keyword and extended the 'broadcast' keyword can now be
+ so that protocol qualitfications are allowed. For example, "ip broadcast"
+ and "ether multicast" are valid filters.
+
+- Added support for monitoring the loopback interface (i.e. 'tcpdump -i lo').
+ Jeffrey Honig (jch@MITCHELL.CIT.CORNELL.EDU) contributed the kernel
+ patches to netinet/if_loop.c.
+
+- Added support for the Ungermann-Bass Ethernet on IBM/PC-RTs running AOS.
+ Contact Jeffrey Honig (jch@MITCHELL.CIT.CORNELL.EDU) for the diffs.
+
+- Added EGP and OSPF printers, thanks to Jeffrey Honig.
+
+v2.1 Tue Jan 28 11:00:14 PST 1992
+
+- Internal release (never publically exported).
+
+v2.0.1 Sun Jan 26 21:10:10 PDT
+
+- Various byte ordering fixes.
+
+- Add truncation checks.
+
+- inet.c: Support BSD style SIOCGIFCONF.
+
+- nametoaddr.c: Handle multi addresses for single host.
+
+- optimize.c: Rewritten.
+
+- pcap-bpf.c: don't choke when we get ptraced. only set promiscuous
+ for broadcast nets.
+
+- print-atal.c: Fix an alignment bug (thanks to
+ stanonik@nprdc.navy.mil) Add missing printf() argument.
+
+- print-bootp.c: First attempt at decoding the vendor buffer.
+
+- print-domain.c: Fix truncation checks.
+
+- print-icmp.c: Calculate length of packets from the ip header.
+
+- print-ip.c: Print frag id in decimal (so it's easier to match up
+ with non-frags). Add support for ospf, egp and igmp.
+
+- print-nfs.c: Lots of changes.
+
+- print-ntp.c: Make some verbose output depend on -v.
+
+- print-snmp.c: New version from John LoVerso.
+
+- print-tcp.c: Print rfc1072 tcp options.
+
+- tcpdump.c: Print "0x" prefix for %x formats. Always print 6 digits
+ (microseconds) worth of precision. Fix uid bugs.
+
+- A packet dumper has been added (thanks to Jeff Mogul of DECWRL).
+ With this option, you can create an architecture independent binary
+ trace file in real time, without the overhead of the packet printer.
+ At a later time, the packets can be filtered (again) and printed.
+
+- BSD is supported. You must have BPF in your kernel.
+ Since the filtering is now done in the kernel, fewer packets are
+ dropped. In fact, with BPF and the packet dumper option, a measly
+ Sun 3/50 can keep up with a busy network.
+
+- Compressed SLIP packets can now be dumped, provided you use our
+ SLIP software and BPF. These packets are dumped as any other IP
+ packet; the compressed headers are dumped with the '-e' option.
+
+- Machines with little-endian byte ordering are supported (thanks to
+ Jeff Mogul).
+
+- Ultrix 4.0 is supported (also thanks to Jeff Mogul).
+
+- IBM RT and Stanford Enetfilter support has been added by
+ Rayan Zachariassen <rayan@canet.ca>. Tcpdump has been tested under
+ both the vanilla Enetfilter interface, and the extended interface
+ (#ifdef'd by IBMRTPC) present in the MERIT version of the Enetfilter.
+
+- TFTP packets are now printed (requests only).
+
+- BOOTP packets are now printed.
+
+- SNMP packets are now printed. (thanks to John LoVerso of Xylogics).
+
+- Sparc architectures, including the Sparcstation-1, are now
+ supported thanks to Steve McCanne and Craig Leres.
+
+- SunOS 4 is now supported thanks to Micky Liu of Columbia
+ University (micky@cunixc.cc.columbia.edu).
+
+- IP options are now printed.
+
+- RIP packets are now printed.
+
+- There's a -v flag that prints out more information than the
+ default (e.g., it will enable printing of IP ttl, tos and id)
+ and -q flag that prints out less (e.g., it will disable
+ interpretation of AppleTalk-in-UDP).
+
+- The grammar has undergone substantial changes (if you have an
+ earlier version of tcpdump, you should re-read the manual
+ entry).
+
+ The most useful change is the addition of an expression
+ syntax that lets you filter on arbitrary fields or values in the
+ packet. E.g., "ip[0] > 0x45" would print only packets with IP
+ options, "tcp[13] & 3 != 0" would print only TCP SYN and FIN
+ packets.
+
+ The most painful change is that concatenation no longer means
+ "and" -- e.g., you have to say "host foo and port bar" instead
+ of "host foo port bar". The up side to this down is that
+ repeated qualifiers can be omitted, making most filter
+ expressions shorter. E.g., you can now say "ip host foo and
+ (bar or baz)" to look at ip traffic between hosts foo and bar or
+ between hosts foo and baz. [The old way of saying this was "ip
+ host foo and (ip host bar or ip host baz)".]
+
+v2.0 Sun Jan 13 12:20:40 PST 1991
+
+- Initial public release.
diff --git a/usr.sbin/tcpdump/Makefile b/usr.sbin/tcpdump/Makefile
new file mode 100644
index 00000000000..9d9f4dd4fa2
--- /dev/null
+++ b/usr.sbin/tcpdump/Makefile
@@ -0,0 +1,43 @@
+# $NetBSD: Makefile,v 1.6 1995/03/07 23:18:39 mycroft Exp $
+#
+# Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that: (1) source code distributions
+# retain the above copyright notice and this paragraph in its entirety, (2)
+# distributions including binary code include the above copyright notice and
+# this paragraph in its entirety in the documentation or other materials
+# provided with the distribution, and (3) all advertising materials mentioning
+# features or use of this software display the following acknowledgement:
+# ``This product includes software developed by the University of California,
+# Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+# the University nor the names of its contributors may be used to endorse
+# or promote products derived from this software without specific prior
+# written permission.
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+# @(#) $Header: /home/cvs/src/usr.sbin/tcpdump/Makefile,v 1.1.1.1 1995/10/18 08:48:23 deraadt Exp $ (LBL)
+
+PROG= tcpdump
+MAN= tcpdump.8
+
+CFLAGS+=-DCSLIP -DPPP -DFDDI -DETHER_SERVICE
+
+LDADD+= -lpcap -ll
+DPADD+= ${LIBL} ${LIBPCAP}
+
+SRCS= tcpdump.c addrtoname.c \
+ print-ether.c print-ip.c print-arp.c print-tcp.c print-udp.c \
+ print-atalk.c print-domain.c print-tftp.c print-bootp.c print-nfs.c \
+ print-icmp.c print-sl.c print-ppp.c print-rip.c \
+ print-snmp.c print-ntp.c print-null.c print-egp.c print-ospf.c \
+ print-fddi.c print-llc.c print-sunrpc.c \
+ print-wb.c print-decnet.c print-isoclns.c print-ipx.c \
+ util.c bpf_dump.c parsenfsfh.c version.c
+
+AWKS = atime.awk packetdat.awk send-ack.awk stime.awk
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/tcpdump/README b/usr.sbin/tcpdump/README
new file mode 100644
index 00000000000..b88305fd35d
--- /dev/null
+++ b/usr.sbin/tcpdump/README
@@ -0,0 +1,209 @@
+$NetBSD: README,v 1.3 1995/03/07 23:18:35 mycroft Exp $
+@(#) Header: README,v 1.39 94/06/20 20:15:16 leres Exp (LBL)
+
+TCPDUMP 3.0
+Lawrence Berkeley Laboratory
+Network Research Group
+tcpdump@ee.lbl.gov
+ftp://ftp.ee.lbl.gov/tcpdump-*.tar.Z
+
+This directory contains source code for tcpdump, a tool for network
+monitoring and data acquisition. The original distribution is
+available via anonymous ftp to ftp.ee.lbl.gov, in tcpdump-*.tar.Z.
+
+Tcpdump now uses libcap, a system-independent interface for
+user-level packet capture. Before building tcpdump, you must
+first retrieve and build libpcap, also from LBL, in:
+
+ ftp://ftp.ee.lbl.gov/libpcap-*.tar.Z.
+
+Once libpcap is built (either install it or make sure it's in
+../libpcap), you can build tcpdump using the procedure in the INSTALL
+file.
+
+Tcpdump and libpcap have been built and tested under SGI Irix 4.x & 5.2,
+SunOS 4.x, Solaris 2.3, BSD/386 v1.1, DEC/OSF v1.3 v2.0, and Ultrix 4.x.
+SunOS 3.5, 4.3BSD Reno/Tahoe and 4.4BSD are supported as well, but we
+currently do not have the resources to carry out testing in these
+environments (we suspect you'll run into problems building the most
+recent version under these systems -- please send us the patches if
+you fix any porting problems).
+
+Tcpdump has reportedly been ported to Mach 3.0 and Linux, but we have
+not received patches to integrate back into the master source tree.
+
+The program is loosely based on SMI's "etherfind" although none
+of the etherfind code remains. It was originally written by Van
+Jacobson as part of an ongoing research project to investigate and
+improve tcp and internet gateway performance. The parts of the
+program originally taken from Sun's etherfind were later re-written
+by Steven McCanne of LBL. To insure that there would be no vestige
+of proprietary code in tcpdump, Steve wrote these pieces from the
+specification given by the manual entry, with no access to the
+source of tcpdump or etherfind.
+
+Over the past few years, tcpdump has been steadily improved
+by the excellent contributions from the Internet community
+(just browse through the CHANGES file). We are grateful for
+all the input.
+
+Richard Stevens gives an excellent treatment of the Internet
+protocols in his book ``TCP/IP Illustrated, Volume 1''.
+If you want to learn more about tcpdump and how to interpret
+it's output, pick up this book.
+
+Problems, bugs, questions, desirable enhancements, etc., should be
+sent to the email address "tcpdump@ee.lbl.gov".
+
+ - Steve McCanne (mccanne@ee.lbl.gov)
+ Craig Leres (leres@ee.lbl.gov)
+ Van Jacobson (van@ee.lbl.gov)
+-------------------------------------
+This directory also contains some short awk programs intended as
+examples of ways to reduce tcpdump data when you're tracking
+particular network problems:
+
+send-ack.awk
+ Simplifies the tcpdump trace for an ftp (or other unidirectional
+ tcp transfer). Since we assume that one host only sends and
+ the other only acks, all address information is left off and
+ we just note if the packet is a "send" or an "ack".
+
+ There is one output line per line of the original trace.
+ Field 1 is the packet time in decimal seconds, relative
+ to the start of the conversation. Field 2 is delta-time
+ from last packet. Field 3 is packet type/direction.
+ "Send" means data going from sender to receiver, "ack"
+ means an ack going from the receiver to the sender. A
+ preceding "*" indicates that the data is a retransmission.
+ A preceding "-" indicates a hole in the sequence space
+ (i.e., missing packet(s)), a "#" means an odd-size (not max
+ seg size) packet. Field 4 has the packet flags
+ (same format as raw trace). Field 5 is the sequence
+ number (start seq. num for sender, next expected seq number
+ for acks). The number in parens following an ack is
+ the delta-time from the first send of the packet to the
+ ack. A number in parens following a send is the
+ delta-time from the first send of the packet to the
+ current send (on duplicate packets only). Duplicate
+ sends or acks have a number in square brackets showing
+ the number of duplicates so far.
+
+ Here is a short sample from near the start of an ftp:
+ 3.00 0.20 send . 512
+ 3.20 0.20 ack . 1024 (0.20)
+ 3.20 0.00 send P 1024
+ 3.40 0.20 ack . 1536 (0.20)
+ 3.80 0.40 * send . 0 (3.80) [2]
+ 3.82 0.02 * ack . 1536 (0.62) [2]
+ Three seconds into the conversation, bytes 512 through 1023
+ were sent. 200ms later they were acked. Shortly thereafter
+ bytes 1024-1535 were sent and again acked after 200ms.
+ Then, for no apparent reason, 0-511 is retransmitted, 3.8
+ seconds after its initial send (the round trip time for this
+ ftp was 1sec, +-500ms). Since the receiver is expecting
+ 1536, 1536 is re-acked when 0 arrives.
+
+packetdat.awk
+ Computes chunk summary data for an ftp (or similar
+ unidirectional tcp transfer). [A "chunk" refers to
+ a chunk of the sequence space -- essentially the packet
+ sequence number divided by the max segment size.]
+
+ A summary line is printed showing the number of chunks,
+ the number of packets it took to send that many chunks
+ (if there are no lost or duplicated packets, the number
+ of packets should equal the number of chunks) and the
+ number of acks.
+
+ Following the summary line is one line of information
+ per chunk. The line contains eight fields:
+ 1 - the chunk number
+ 2 - the start sequence number for this chunk
+ 3 - time of first send
+ 4 - time of last send
+ 5 - time of first ack
+ 6 - time of last ack
+ 7 - number of times chunk was sent
+ 8 - number of times chunk was acked
+ (all times are in decimal seconds, relative to the start
+ of the conversation.)
+
+ As an example, here is the first part of the output for
+ an ftp trace:
+
+ # 134 chunks. 536 packets sent. 508 acks.
+ 1 1 0.00 5.80 0.20 0.20 4 1
+ 2 513 0.28 6.20 0.40 0.40 4 1
+ 3 1025 1.16 6.32 1.20 1.20 4 1
+ 4 1561 1.86 15.00 2.00 2.00 6 1
+ 5 2049 2.16 15.44 2.20 2.20 5 1
+ 6 2585 2.64 16.44 2.80 2.80 5 1
+ 7 3073 3.00 16.66 3.20 3.20 4 1
+ 8 3609 3.20 17.24 3.40 5.82 4 11
+ 9 4097 6.02 6.58 6.20 6.80 2 5
+
+ This says that 134 chunks were transferred (about 70K
+ since the average packet size was 512 bytes). It took
+ 536 packets to transfer the data (i.e., on the average
+ each chunk was transmitted four times). Looking at,
+ say, chunk 4, we see it represents the 512 bytes of
+ sequence space from 1561 to 2048. It was first sent
+ 1.86 seconds into the conversation. It was last
+ sent 15 seconds into the conversation and was sent
+ a total of 6 times (i.e., it was retransmitted every
+ 2 seconds on the average). It was acked once, 140ms
+ after it first arrived.
+
+stime.awk
+atime.awk
+ Output one line per send or ack, respectively, in the form
+ <time> <seq. number>
+ where <time> is the time in seconds since the start of the
+ transfer and <seq. number> is the sequence number being sent
+ or acked. I typically plot this data looking for suspicious
+ patterns.
+
+
+The problem I was looking at was the bulk-data-transfer
+throughput of medium delay network paths (1-6 sec. round trip
+time) under typical DARPA Internet conditions. The trace of the
+ftp transfer of a large file was used as the raw data source.
+The method was:
+
+ - On a local host (but not the Sun running tcpdump), connect to
+ the remote ftp.
+
+ - On the monitor Sun, start the trace going. E.g.,
+ tcpdump host local-host and remote-host and port ftp-data >tracefile
+
+ - On local, do either a get or put of a large file (~500KB),
+ preferably to the null device (to minimize effects like
+ closing the receive window while waiting for a disk write).
+
+ - When transfer is finished, stop tcpdump. Use awk to make up
+ two files of summary data (maxsize is the maximum packet size,
+ tracedata is the file of tcpdump tracedata):
+ awk -f send-ack.awk packetsize=avgsize tracedata >sa
+ awk -f packetdat.awk packetsize=avgsize tracedata >pd
+
+ - While the summary data files are printing, take a look at
+ how the transfer behaved:
+ awk -f stime.awk tracedata | xgraph
+ (90% of what you learn seems to happen in this step).
+
+ - Do all of the above steps several times, both directions,
+ at different times of day, with different protocol
+ implementations on the other end.
+
+ - Using one of the Unix data analysis packages (in my case,
+ S and Gary Perlman's Unix|Stat), spend a few months staring
+ at the data.
+
+ - Change something in the local protocol implementation and
+ redo the steps above.
+
+ - Once a week, tell your funding agent that you're discovering
+ wonderful things and you'll write up that research report
+ "real soon now".
+
diff --git a/usr.sbin/tcpdump/addrtoname.c b/usr.sbin/tcpdump/addrtoname.c
new file mode 100644
index 00000000000..d4e3aae843a
--- /dev/null
+++ b/usr.sbin/tcpdump/addrtoname.c
@@ -0,0 +1,724 @@
+/* $NetBSD: addrtoname.c,v 1.4 1995/04/24 13:27:39 cgd Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Internet, ethernet, port, and protocol string to address
+ * and address to string conversion routines
+ */
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: addrtoname.c,v 1.37 94/06/16 00:42:28 mccanne Exp (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <pcap.h>
+#include <pcap-namedb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <unistd.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "llc.h"
+
+static SIGRET nohostname(int);
+#ifdef ETHER_SERVICE
+struct ether_addr;
+extern int ether_ntohost(char *, struct ether_addr *);
+#endif
+
+/*
+ * hash tables for whatever-to-name translations
+ */
+
+#define HASHNAMESIZE 4096
+
+struct hnamemem {
+ u_int32 addr;
+ char *name;
+ struct hnamemem *nxt;
+};
+
+struct hnamemem hnametable[HASHNAMESIZE];
+struct hnamemem tporttable[HASHNAMESIZE];
+struct hnamemem uporttable[HASHNAMESIZE];
+struct hnamemem eprototable[HASHNAMESIZE];
+struct hnamemem dnaddrtable[HASHNAMESIZE];
+struct hnamemem llcsaptable[HASHNAMESIZE];
+
+struct enamemem {
+ u_short e_addr0;
+ u_short e_addr1;
+ u_short e_addr2;
+ char *e_name;
+ u_char *e_nsap; /* used only for nsaptable[] */
+ struct enamemem *e_nxt;
+};
+
+struct enamemem enametable[HASHNAMESIZE];
+struct enamemem nsaptable[HASHNAMESIZE];
+
+struct protoidmem {
+ u_long p_oui;
+ u_short p_proto;
+ char *p_name;
+ struct protoidmem *p_nxt;
+};
+
+struct protoidmem protoidtable[HASHNAMESIZE];
+
+/*
+ * A faster replacement for inet_ntoa().
+ */
+char *
+intoa(u_int32 addr)
+{
+ register char *cp;
+ register u_int byte;
+ register int n;
+ static char buf[sizeof(".xxx.xxx.xxx.xxx")];
+
+ NTOHL(addr);
+ cp = &buf[sizeof buf];
+ *--cp = '\0';
+
+ n = 4;
+ do {
+ byte = addr & 0xff;
+ *--cp = byte % 10 + '0';
+ byte /= 10;
+ if (byte > 0) {
+ *--cp = byte % 10 + '0';
+ byte /= 10;
+ if (byte > 0)
+ *--cp = byte + '0';
+ }
+ *--cp = '.';
+ addr >>= 8;
+ } while (--n > 0);
+
+ return cp + 1;
+}
+
+static u_int32 f_netmask;
+static u_int32 f_localnet;
+static u_int32 netmask;
+
+/*
+ * "getname" is written in this atrocious way to make sure we don't
+ * wait forever while trying to get hostnames from yp.
+ */
+#include <setjmp.h>
+
+jmp_buf getname_env;
+
+static SIGRET
+nohostname(int signo)
+{
+ longjmp(getname_env, 1);
+}
+
+/*
+ * Return a name for the IP address pointed to by ap. This address
+ * is assumed to be in network byte order.
+ */
+char *
+getname(const u_char *ap)
+{
+ register struct hostent *hp;
+ register char *cp;
+ u_int32 addr;
+ static struct hnamemem *p; /* static for longjmp() */
+
+#ifndef TCPDUMP_ALIGN
+ addr = *(const u_int32 *)ap;
+#else
+ /*
+ * Deal with alignment.
+ */
+ switch ((long)ap & 3) {
+
+ case 0:
+ addr = *(u_int32 *)ap;
+ break;
+
+ case 2:
+#if BYTE_ORDER == LITTLE_ENDIAN
+ addr = ((u_int32)*(u_short *)(ap + 2) << 16) |
+ (u_int32)*(u_short *)ap;
+#else
+ addr = ((u_int32)*(u_short *)ap << 16) |
+ (u_int32)*(u_short *)(ap + 2);
+#endif
+ break;
+
+ default:
+#if BYTE_ORDER == LITTLE_ENDIAN
+ addr = ((u_int32)ap[0] << 24) |
+ ((u_int32)ap[1] << 16) |
+ ((u_int32)ap[2] << 8) |
+ (u_int32)ap[3];
+#else
+ addr = ((u_int32)ap[3] << 24) |
+ ((u_int32)ap[2] << 16) |
+ ((u_int32)ap[1] << 8) |
+ (u_int32)ap[0];
+#endif
+ break;
+ }
+#endif
+ p = &hnametable[addr & (HASHNAMESIZE-1)];
+ for (; p->nxt; p = p->nxt) {
+ if (p->addr == addr)
+ return (p->name);
+ }
+ p->addr = addr;
+ p->nxt = (struct hnamemem *)calloc(1, sizeof (*p));
+
+ /*
+ * Only print names when:
+ * (1) -n was not given.
+ * (2) Address is foreign and -f was given. If -f was not
+ * present, f_netmask and f_local are 0 and the second
+ * test will succeed.
+ * (3) The host portion is not 0 (i.e., a network address).
+ * (4) The host portion is not broadcast.
+ */
+ if (!nflag && (addr & f_netmask) == f_localnet
+ && (addr &~ netmask) != 0 && (addr | netmask) != 0xffffffff) {
+ if (!setjmp(getname_env)) {
+ (void)signal(SIGALRM, nohostname);
+ (void)alarm(20);
+ hp = gethostbyaddr((char *)&addr, 4, AF_INET);
+ (void)alarm(0);
+ if (hp) {
+ char *dotp;
+
+ p->name = savestr(hp->h_name);
+ if (Nflag) {
+ /* Remove domain qualifications */
+ dotp = strchr(p->name, '.');
+ if (dotp)
+ *dotp = 0;
+ }
+ return (p->name);
+ }
+ }
+ }
+ cp = intoa(addr);
+ p->name = savestr(cp);
+ return (p->name);
+}
+
+static char hex[] = "0123456789abcdef";
+
+
+/* Find the hash node that corresponds the ether address 'ep'. */
+
+static inline struct enamemem *
+lookup_emem(const u_char *ep)
+{
+ register u_int i, j, k;
+ struct enamemem *tp;
+
+ k = (ep[0] << 8) | ep[1];
+ j = (ep[2] << 8) | ep[3];
+ i = (ep[4] << 8) | ep[5];
+
+ tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
+ while (tp->e_nxt)
+ if (tp->e_addr0 == i &&
+ tp->e_addr1 == j &&
+ tp->e_addr2 == k)
+ return tp;
+ else
+ tp = tp->e_nxt;
+ tp->e_addr0 = i;
+ tp->e_addr1 = j;
+ tp->e_addr2 = k;
+ tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
+
+ return tp;
+}
+
+/* Find the hash node that corresponds the NSAP 'nsap'. */
+
+static inline struct enamemem *
+lookup_nsap(register const u_char *nsap)
+{
+ register u_int i, j, k;
+ int nlen = *nsap;
+ struct enamemem *tp;
+ const u_char *ensap = nsap + nlen - 6;
+
+ if (nlen > 6) {
+ k = (ensap[0] << 8) | ensap[1];
+ j = (ensap[2] << 8) | ensap[3];
+ i = (ensap[4] << 8) | ensap[5];
+ }
+ else
+ i = j = k = 0;
+
+ tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
+ while (tp->e_nxt)
+ if (tp->e_addr0 == i &&
+ tp->e_addr1 == j &&
+ tp->e_addr2 == k &&
+ tp->e_nsap[0] == nlen &&
+ bcmp((char *)&(nsap[1]),
+ (char *)&(tp->e_nsap[1]), nlen) == 0)
+ return tp;
+ else
+ tp = tp->e_nxt;
+ tp->e_addr0 = i;
+ tp->e_addr1 = j;
+ tp->e_addr2 = k;
+ tp->e_nsap = (u_char *) calloc(1, nlen + 1);
+ bcopy(nsap, tp->e_nsap, nlen + 1);
+ tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
+
+ return tp;
+}
+
+/* Find the hash node that corresponds the protoid 'pi'. */
+
+static inline struct protoidmem *
+lookup_protoid(const u_char *pi)
+{
+ register u_int i, j;
+ struct protoidmem *tp;
+
+ /* 5 octets won't be aligned */
+ i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
+ j = (pi[3] << 8) + pi[4];
+ /* XXX should be endian-insensitive, but do big-endian testing XXX */
+
+ tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
+ while (tp->p_nxt)
+ if (tp->p_oui == i && tp->p_proto == j)
+ return tp;
+ else
+ tp = tp->p_nxt;
+ tp->p_oui = i;
+ tp->p_proto = j;
+ tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
+
+ return tp;
+}
+
+char *
+etheraddr_string(register const u_char *ep)
+{
+ register u_int i, j;
+ register char *cp;
+ register struct enamemem *tp;
+
+ tp = lookup_emem(ep);
+ if (tp->e_name)
+ return (tp->e_name);
+#ifdef ETHER_SERVICE
+ if (!nflag) {
+ char buf[128];
+ if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) {
+ tp->e_name = savestr(buf);
+ return (tp->e_name);
+ }
+ }
+#endif
+ tp->e_name = cp = (char *)malloc(sizeof("00:00:00:00:00:00"));
+
+ if ((j = *ep >> 4) != 0)
+ *cp++ = hex[j];
+ *cp++ = hex[*ep++ & 0xf];
+ for (i = 5; (int)--i >= 0;) {
+ *cp++ = ':';
+ if ((j = *ep >> 4) != 0)
+ *cp++ = hex[j];
+ *cp++ = hex[*ep++ & 0xf];
+ }
+ *cp = '\0';
+ return (tp->e_name);
+}
+
+char *
+etherproto_string(u_short port)
+{
+ register char *cp;
+ register struct hnamemem *tp;
+ register u_long i = port;
+
+ for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ tp->name = cp = (char *)malloc(sizeof("0000"));
+ tp->addr = i;
+ tp->nxt = (struct hnamemem *)calloc(1, sizeof (*tp));
+
+ NTOHS(port);
+ *cp++ = hex[port >> 12 & 0xf];
+ *cp++ = hex[port >> 8 & 0xf];
+ *cp++ = hex[port >> 4 & 0xf];
+ *cp++ = hex[port & 0xf];
+ *cp++ = '\0';
+ return (tp->name);
+}
+
+char *
+protoid_string(register const u_char *pi)
+{
+ register u_int i, j;
+ register char *cp;
+ register struct protoidmem *tp;
+
+ tp = lookup_protoid(pi);
+ if (tp->p_name)
+ return tp->p_name;
+
+ tp->p_name = cp = (char *)malloc(sizeof("00:00:00:00:00"));
+
+ if ((j = *pi >> 4) != 0)
+ *cp++ = hex[j];
+ *cp++ = hex[*pi++ & 0xf];
+ for (i = 4; (int)--i >= 0;) {
+ *cp++ = ':';
+ if ((j = *pi >> 4) != 0)
+ *cp++ = hex[j];
+ *cp++ = hex[*pi++ & 0xf];
+ }
+ *cp = '\0';
+ return (tp->p_name);
+}
+
+char *
+llcsap_string(u_char sap)
+{
+ register char *cp;
+ register struct hnamemem *tp;
+ register u_long i = sap;
+
+ for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ tp->name = cp = (char *)malloc(sizeof("sap 00"));
+ tp->addr = i;
+ tp->nxt = (struct hnamemem *)calloc(1, sizeof (*tp));
+
+ (void)strcpy(cp, "sap ");
+ cp += strlen(cp);
+ *cp++ = hex[sap >> 4 & 0xf];
+ *cp++ = hex[sap & 0xf];
+ *cp++ = '\0';
+ return (tp->name);
+}
+
+char *
+isonsap_string(const u_char *nsap)
+{
+ register u_int i, nlen = nsap[0];
+ register char *cp;
+ register struct enamemem *tp;
+
+ tp = lookup_nsap(nsap);
+ if (tp->e_name)
+ return tp->e_name;
+
+ tp->e_name = cp = (char *)malloc(nlen * 2 + 2);
+
+ nsap++;
+ *cp++ = '/';
+ for (i = nlen; (int)--i >= 0;) {
+ *cp++ = hex[*nsap >> 4];
+ *cp++ = hex[*nsap++ & 0xf];
+ }
+ *cp = '\0';
+ return (tp->e_name);
+}
+
+char *
+tcpport_string(u_short port)
+{
+ register struct hnamemem *tp;
+ register u_long i = port;
+
+ for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ tp->name = (char *)malloc(sizeof("00000"));
+ tp->addr = i;
+ tp->nxt = (struct hnamemem *)calloc(1, sizeof (*tp));
+
+ (void)sprintf(tp->name, "%d", i);
+ return (tp->name);
+}
+
+char *
+udpport_string(register u_short port)
+{
+ register struct hnamemem *tp;
+ register u_long i = port;
+
+ for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ tp->name = (char *)malloc(sizeof("00000"));
+ tp->addr = i;
+ tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
+
+ (void)sprintf(tp->name, "%d", i);
+
+ return (tp->name);
+}
+
+static void
+init_servarray(void)
+{
+ struct servent *sv;
+ register struct hnamemem *table;
+ register int i;
+
+ while ((sv = getservent()) != NULL) {
+ int port = ntohs(sv->s_port);
+ i = port & (HASHNAMESIZE-1);
+ if (strcmp(sv->s_proto, "tcp") == 0)
+ table = &tporttable[i];
+ else if (strcmp(sv->s_proto, "udp") == 0)
+ table = &uporttable[i];
+ else
+ continue;
+
+ while (table->name)
+ table = table->nxt;
+ if (nflag) {
+ char buf[32];
+
+ (void)sprintf(buf, "%d", port);
+ table->name = savestr(buf);
+ } else
+ table->name = savestr(sv->s_name);
+ table->addr = port;
+ table->nxt = (struct hnamemem *)calloc(1, sizeof(*table));
+ }
+ endservent();
+}
+
+/*XXX from libbpfc.a */
+extern struct eproto {
+ char *s;
+ u_short p;
+} eproto_db[];
+
+static void
+init_eprotoarray(void)
+{
+ register int i;
+ register struct hnamemem *table;
+
+ for (i = 0; eproto_db[i].s; i++) {
+ int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1);
+ table = &eprototable[j];
+ while (table->name)
+ table = table->nxt;
+ table->name = eproto_db[i].s;
+ table->addr = ntohs(eproto_db[i].p);
+ table->nxt = (struct hnamemem *)calloc(1, sizeof(*table));
+ }
+}
+
+/*
+ * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
+ * types.
+ */
+static void
+init_protoidarray(void)
+{
+ register int i;
+ register struct protoidmem *tp;
+ u_char protoid[5];
+
+ protoid[0] = 0;
+ protoid[1] = 0;
+ protoid[2] = 0;
+ for (i = 0; eproto_db[i].s; i++) {
+ u_short etype = htons(eproto_db[i].p);
+ bcopy((char *)&etype, (char *)&protoid[3], 2);
+ tp = lookup_protoid(protoid);
+ tp->p_name = savestr(eproto_db[i].s);
+ }
+}
+
+static struct etherlist {
+ u_char addr[6];
+ char *name;
+} etherlist[] = {
+ {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
+ {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
+};
+
+/*
+ * Initialize the ethers hash table. We take two different approaches
+ * depending on whether or not the system provides the ethers name
+ * service. If it does, we just wire in a few names at startup,
+ * and etheraddr_string() fills in the table on demand. If it doesn't,
+ * then we suck in the entire /etc/ethers file at startup. The idea
+ * is that parsing the local file will be fast, but spinning through
+ * all the ethers entries via NIS & next_etherent might be very slow.
+ *
+ * XXX pcap_next_etherent doesn't belong in the pcap interface, but
+ * since the pcap module already does name-to-address translation,
+ * it's already does most of the work for the ethernet address-to-name
+ * translation, so we just pcap_next_etherent as a convenience.
+ */
+static void
+init_etherarray(void)
+{
+ register struct etherlist *el;
+ register struct enamemem *tp;
+#ifndef ETHER_SERVICE
+ register struct pcap_etherent *ep;
+ register FILE *fp;
+
+ /* Suck in entire ethers file */
+ fp = fopen(PCAP_ETHERS_FILE, "r");
+ if (fp != NULL) {
+ while ((ep = pcap_next_etherent(fp)) != NULL) {
+ tp = lookup_emem(ep->addr);
+ tp->e_name = savestr(ep->name);
+ }
+ (void)fclose(fp);
+ }
+#endif
+
+ /* Hardwire some ethernet names */
+ for (el = etherlist; el->name != NULL; ++el) {
+#ifdef ETHER_SERVICE
+ /* Use yp/nis version of name if available */
+ char wrk[256];
+ if (ether_ntohost(wrk, (struct ether_addr *)el->addr) == 0) {
+ tp = lookup_emem(el->addr);
+ tp->e_name = savestr(wrk);
+ }
+#else
+ /* install if not already present */
+ tp = lookup_emem(el->addr);
+ if (tp->e_name == NULL)
+ tp->e_name = el->name;
+#endif
+
+ }
+}
+
+static struct token llcsap_db[] = {
+ { LLCSAP_NULL, "null" },
+ { LLCSAP_8021B_I, "802.1b-gsap" },
+ { LLCSAP_8021B_G, "802.1b-isap" },
+ { LLCSAP_IP, "ip-sap" },
+ { LLCSAP_PROWAYNM, "proway-nm" },
+ { LLCSAP_8021D, "802.1d" },
+ { LLCSAP_RS511, "eia-rs511" },
+ { LLCSAP_ISO8208, "x.25/llc2" },
+ { LLCSAP_PROWAY, "proway" },
+ { LLCSAP_ISONS, "iso-clns" },
+ { LLCSAP_GLOBAL, "global" },
+ { 0, NULL }
+};
+
+static void
+init_llcsaparray(void)
+{
+ register int i;
+ register struct hnamemem *table;
+
+ for (i = 0; llcsap_db[i].s != NULL; i++) {
+ table = &llcsaptable[llcsap_db[i].v];
+ while (table->name)
+ table = table->nxt;
+ table->name = llcsap_db[i].s;
+ table->addr = llcsap_db[i].v;
+ table->nxt = (struct hnamemem *)calloc(1, sizeof(*table));
+ }
+}
+
+/*
+ * Initialize the address to name translation machinery. We map all
+ * non-local IP addresses to numeric addresses if fflag is true (i.e.,
+ * to prevent blocking on the nameserver). localnet is the IP address
+ * of the local network. mask is its subnet mask.
+ */
+void
+init_addrtoname(int fflag, u_int32 localnet, u_int32 mask)
+{
+ netmask = mask;
+ if (fflag) {
+ f_localnet = localnet;
+ f_netmask = mask;
+ }
+ if (nflag)
+ /*
+ * Simplest way to suppress names.
+ */
+ return;
+
+ init_etherarray();
+ init_servarray();
+ init_eprotoarray();
+ init_llcsaparray();
+ init_protoidarray();
+}
+
+char *
+dnaddr_string(u_short dnaddr)
+{
+ register struct hnamemem *tp;
+
+ for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
+ tp = tp->nxt)
+ if (tp->addr == dnaddr)
+ return (tp->name);
+
+ tp->addr = dnaddr;
+ tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
+ if (nflag)
+ tp->name = dnnum_string(dnaddr);
+ else
+ tp->name = dnname_string(dnaddr);
+
+ return(tp->name);
+}
diff --git a/usr.sbin/tcpdump/addrtoname.h b/usr.sbin/tcpdump/addrtoname.h
new file mode 100644
index 00000000000..74a6ba0baa0
--- /dev/null
+++ b/usr.sbin/tcpdump/addrtoname.h
@@ -0,0 +1,37 @@
+/* $NetBSD: addrtoname.h,v 1.2 1995/03/06 19:09:50 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1990, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: addrtoname.h,v 1.11 94/06/14 20:11:41 leres Exp (LBL)
+ */
+
+/* Name to address translation routines. */
+
+extern char *etheraddr_string(const u_char *);
+extern char *etherproto_string(u_short);
+extern char *tcpport_string(u_short);
+extern char *udpport_string(u_short);
+extern char *getname(const u_char *);
+extern char *intoa(u_int32);
+
+extern void init_addrtoname(int, u_int32, u_int32);
+
+#define ipaddr_string(p) getname((const u_char *)(p))
diff --git a/usr.sbin/tcpdump/appletalk.h b/usr.sbin/tcpdump/appletalk.h
new file mode 100644
index 00000000000..d0941667d02
--- /dev/null
+++ b/usr.sbin/tcpdump/appletalk.h
@@ -0,0 +1,169 @@
+/* $NetBSD: appletalk.h,v 1.2 1995/03/06 19:09:51 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * AppleTalk protocol formats (courtesy Bill Croft of Stanford/SUMEX).
+ *
+ * @(#) Header: appletalk.h,v 1.10 94/06/14 20:11:44 leres Exp (LBL)
+ */
+
+struct LAP {
+ u_char dst;
+ u_char src;
+ u_char type;
+};
+#define lapShortDDP 1 /* short DDP type */
+#define lapDDP 2 /* DDP type */
+#define lapKLAP 'K' /* Kinetics KLAP type */
+
+/* Datagram Delivery Protocol */
+
+struct atDDP {
+ u_short length;
+ u_short checksum;
+ u_short dstNet;
+ u_short srcNet;
+ u_char dstNode;
+ u_char srcNode;
+ u_char dstSkt;
+ u_char srcSkt;
+ u_char type;
+};
+
+struct atShortDDP {
+ u_short length;
+ u_char dstSkt;
+ u_char srcSkt;
+ u_char type;
+};
+
+#define ddpMaxWKS 0x7F
+#define ddpMaxData 586
+#define ddpLengthMask 0x3FF
+#define ddpHopShift 10
+#define ddpSize 13 /* size of DDP header (avoid struct padding) */
+#define ddpSSize 5
+#define ddpWKS 128 /* boundary of DDP well known sockets */
+#define ddpRTMP 1 /* RTMP type */
+#define ddpRTMPrequest 5 /* RTMP request type */
+#define ddpNBP 2 /* NBP type */
+#define ddpATP 3 /* ATP type */
+#define ddpECHO 4 /* ECHO type */
+#define ddpIP 22 /* IP type */
+#define ddpARP 23 /* ARP type */
+#define ddpKLAP 0x4b /* Kinetics KLAP type */
+
+
+/* AppleTalk Transaction Protocol */
+
+struct atATP {
+ u_char control;
+ u_char bitmap;
+ u_short transID;
+ int32 userData;
+};
+
+#define atpReqCode 0x40
+#define atpRspCode 0x80
+#define atpRelCode 0xC0
+#define atpXO 0x20
+#define atpEOM 0x10
+#define atpSTS 0x08
+#define atpFlagMask 0x3F
+#define atpControlMask 0xF8
+#define atpMaxNum 8
+#define atpMaxData 578
+
+
+/* AppleTalk Echo Protocol */
+
+struct atEcho {
+ u_char echoFunction;
+ u_char *echoData;
+};
+
+#define echoSkt 4 /* the echoer socket */
+#define echoSize 1 /* size of echo header */
+#define echoRequest 1 /* echo request */
+#define echoReply 2 /* echo request */
+
+
+/* Name Binding Protocol */
+
+struct atNBP {
+ u_char control;
+ u_char id;
+};
+
+struct atNBPtuple {
+ u_short net;
+ u_char node;
+ u_char skt;
+ u_char enumerator;
+};
+
+#define nbpBrRq 0x10
+#define nbpLkUp 0x20
+#define nbpLkUpReply 0x30
+
+#define nbpNIS 2
+#define nbpTupleMax 15
+
+#define nbpHeaderSize 2
+#define nbpTupleSize 5
+
+#define nbpSkt 2 /* NIS */
+
+
+/* Routing Table Maint. Protocol */
+
+#define rtmpSkt 1 /* number of RTMP socket */
+#define rtmpSize 4 /* minimum size */
+#define rtmpTupleSize 3
+
+
+/* Zone Information Protocol */
+
+struct zipHeader {
+ u_char command;
+ u_char netcount;
+};
+
+#define zipHeaderSize 2
+#define zipQuery 1
+#define zipReply 2
+#define zipTakedown 3
+#define zipBringup 4
+#define ddpZIP 6
+#define zipSkt 6
+#define GetMyZone 7
+#define GetZoneList 8
+
+/*
+ * UDP port range used for ddp-in-udp encapsulation is 16512-16639
+ * for client sockets (128-255) and 200-327 for server sockets
+ * (0-127). We also try to recognize the pre-April 88 server
+ * socket range of 768-895.
+ */
+#define atalk_port(p) \
+ (((unsigned)((p) - 16512) < 128) || \
+ ((unsigned)((p) - 200) < 128) || \
+ ((unsigned)((p) - 768) < 128))
diff --git a/usr.sbin/tcpdump/atime.awk b/usr.sbin/tcpdump/atime.awk
new file mode 100644
index 00000000000..9f5d9d145a6
--- /dev/null
+++ b/usr.sbin/tcpdump/atime.awk
@@ -0,0 +1,20 @@
+# $NetBSD: atime.awk,v 1.2 1995/03/06 19:09:52 mycroft Exp $
+
+$6 ~ /^ack/ && $5 !~ /[SFR]/ {
+ # given a tcpdump ftp trace, output one line for each ack
+ # in the form
+ # <ack time> <seq no>
+ # where <ack time> is the time packet was acked (in seconds with
+ # zero at time of first packet) and <seq no> is the tcp sequence
+ # number of the ack divided by 1024 (i.e., Kbytes acked).
+ #
+ # convert time to seconds
+ n = split ($1,t,":")
+ tim = t[1]*3600 + t[2]*60 + t[3]
+ if (! tzero) {
+ tzero = tim
+ OFS = "\t"
+ }
+ # get packet sequence number
+ printf "%7.2f\t%g\n", tim-tzero, $7/1024
+ }
diff --git a/usr.sbin/tcpdump/bootp.h b/usr.sbin/tcpdump/bootp.h
new file mode 100644
index 00000000000..6e2a328f414
--- /dev/null
+++ b/usr.sbin/tcpdump/bootp.h
@@ -0,0 +1,111 @@
+/* $NetBSD: bootp.h,v 1.2 1995/03/06 19:09:54 mycroft Exp $ */
+
+/* @(#) Header: bootp.h,v 1.6 94/01/13 19:06:29 leres Exp (LBL) */
+/*
+ * Bootstrap Protocol (BOOTP). RFC951 and RFC1048.
+ *
+ * This file specifies the "implementation-independent" BOOTP protocol
+ * information which is common to both client and server.
+ *
+ * Copyright 1988 by Carnegie Mellon.
+ *
+ * Permission to use, copy, modify, and distribute this program for any
+ * purpose and without fee is hereby granted, provided that this copyright
+ * and permission notice appear on all copies and supporting documentation,
+ * the name of Carnegie Mellon not be used in advertising or publicity
+ * pertaining to distribution of the program without specific prior
+ * permission, and notice be given in supporting documentation that copying
+ * and distribution is by permission of Carnegie Mellon and Stanford
+ * University. Carnegie Mellon makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+
+struct bootp {
+ unsigned char bp_op; /* packet opcode type */
+ unsigned char bp_htype; /* hardware addr type */
+ unsigned char bp_hlen; /* hardware addr length */
+ unsigned char bp_hops; /* gateway hops */
+ u_int32 bp_xid; /* transaction ID */
+ unsigned short bp_secs; /* seconds since boot began */
+ unsigned short bp_unused;
+ struct in_addr bp_ciaddr; /* client IP address */
+ struct in_addr bp_yiaddr; /* 'your' IP address */
+ struct in_addr bp_siaddr; /* server IP address */
+ struct in_addr bp_giaddr; /* gateway IP address */
+ unsigned char bp_chaddr[16]; /* client hardware address */
+ unsigned char bp_sname[64]; /* server host name */
+ unsigned char bp_file[128]; /* boot file name */
+ unsigned char bp_vend[64]; /* vendor-specific area */
+};
+
+/*
+ * UDP port numbers, server and client.
+ */
+#define IPPORT_BOOTPS 67
+#define IPPORT_BOOTPC 68
+
+#define BOOTREPLY 2
+#define BOOTREQUEST 1
+
+
+/*
+ * Vendor magic cookie (v_magic) for CMU
+ */
+#define VM_CMU "CMU"
+
+/*
+ * Vendor magic cookie (v_magic) for RFC1048
+ */
+#define VM_RFC1048 { 99, 130, 83, 99 }
+
+
+
+/*
+ * RFC1048 tag values used to specify what information is being supplied in
+ * the vendor field of the packet.
+ */
+
+#define TAG_PAD ((unsigned char) 0)
+#define TAG_SUBNET_MASK ((unsigned char) 1)
+#define TAG_TIME_OFFSET ((unsigned char) 2)
+#define TAG_GATEWAY ((unsigned char) 3)
+#define TAG_TIME_SERVER ((unsigned char) 4)
+#define TAG_NAME_SERVER ((unsigned char) 5)
+#define TAG_DOMAIN_SERVER ((unsigned char) 6)
+#define TAG_LOG_SERVER ((unsigned char) 7)
+#define TAG_COOKIE_SERVER ((unsigned char) 8)
+#define TAG_LPR_SERVER ((unsigned char) 9)
+#define TAG_IMPRESS_SERVER ((unsigned char) 10)
+#define TAG_RLP_SERVER ((unsigned char) 11)
+#define TAG_HOSTNAME ((unsigned char) 12)
+#define TAG_BOOTSIZE ((unsigned char) 13)
+#define TAG_END ((unsigned char) 255)
+/* RFC1497 tags */
+#define TAG_DUMPPATH ((unsigned char) 14)
+#define TAG_DOMAINNAME ((unsigned char) 15)
+#define TAG_SWAP_SERVER ((unsigned char) 16)
+#define TAG_ROOTPATH ((unsigned char) 17)
+#define TAG_EXTPATH ((unsigned char) 18)
+
+
+
+/*
+ * "vendor" data permitted for CMU bootp clients.
+ */
+
+struct cmu_vend {
+ unsigned char v_magic[4]; /* magic number */
+ u_int32 v_flags; /* flags/opcodes, etc. */
+ struct in_addr v_smask; /* Subnet mask */
+ struct in_addr v_dgate; /* Default gateway */
+ struct in_addr v_dns1, v_dns2; /* Domain name servers */
+ struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */
+ struct in_addr v_ts1, v_ts2; /* Time servers */
+ unsigned char v_unused[24]; /* currently unused */
+};
+
+
+/* v_flags values */
+#define VF_SMASK 1 /* Subnet mask field contains valid data */
diff --git a/usr.sbin/tcpdump/bpf_dump.c b/usr.sbin/tcpdump/bpf_dump.c
new file mode 100644
index 00000000000..100d147db81
--- /dev/null
+++ b/usr.sbin/tcpdump/bpf_dump.c
@@ -0,0 +1,67 @@
+/* $NetBSD: bpf_dump.c,v 1.2 1995/03/06 19:09:55 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: bpf_dump.c,v 1.6 94/06/06 14:31:21 leres Exp (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <pcap.h>
+#include <stdio.h>
+
+#include "interface.h"
+
+extern void bpf_dump(struct bpf_program *, int);
+
+void
+bpf_dump(struct bpf_program *p, int option)
+{
+ struct bpf_insn *insn;
+ int i;
+ int n = p->bf_len;
+
+ insn = p->bf_insns;
+ if (option > 2) {
+ printf("%d\n", n);
+ for (i = 0; i < n; ++insn, ++i) {
+ printf("%lu %lu %lu %lu\n", insn->code,
+ insn->jt, insn->jf, insn->k);
+ }
+ return ;
+ }
+ if (option > 1) {
+ for (i = 0; i < n; ++insn, ++i)
+ printf("{ 0x%x, %d, %d, 0x%08x },\n",
+ insn->code, insn->jt, insn->jf, insn->k);
+ return;
+ }
+ for (i = 0; i < n; ++insn, ++i) {
+#ifdef BDEBUG
+ extern int bids[];
+ printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1);
+#endif
+ puts(bpf_image(insn, i));
+ }
+}
diff --git a/usr.sbin/tcpdump/decnet.h b/usr.sbin/tcpdump/decnet.h
new file mode 100644
index 00000000000..5965f77dfde
--- /dev/null
+++ b/usr.sbin/tcpdump/decnet.h
@@ -0,0 +1,482 @@
+/* $NetBSD: decnet.h,v 1.2 1995/03/06 19:09:58 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1992, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: decnet.h,v 1.3 94/06/14 20:11:44 leres Exp (LBL)
+ */
+
+typedef unsigned char byte[1]; /* single byte field */
+typedef unsigned char word[2]; /* 2 byte field */
+typedef unsigned char longword[4]; /* 4 bytes field */
+
+/*
+ * Definitions for DECNET Phase IV protocol headers
+ */
+union etheraddress {
+ unsigned char dne_addr[6]; /* full ethernet address */
+ struct {
+ unsigned char dne_hiord[4]; /* DECnet HIORD prefix */
+ unsigned char dne_nodeaddr[2]; /* DECnet node address */
+ } dne_remote;
+};
+
+typedef union etheraddress etheraddr; /* Ethernet address */
+
+#define HIORD 0x000400aa /* high 32-bits of address (swapped) */
+
+#define AREAMASK 0176000 /* mask for area field */
+#define AREASHIFT 10 /* bit-offset for area field */
+#define NODEMASK 01777 /* mask for node address field */
+
+#define DN_MAXADDL 20 /* max size of DECnet address */
+struct dn_naddr {
+ unsigned short a_len; /* length of address */
+ unsigned char a_addr[DN_MAXADDL]; /* address as bytes */
+};
+
+/*
+ * Define long and short header formats.
+ */
+struct shorthdr
+ {
+ byte sh_flags; /* route flags */
+ word sh_dst; /* destination node address */
+ word sh_src; /* source node address */
+ byte sh_visits; /* visit count */
+ };
+
+struct longhdr
+ {
+ byte lg_flags; /* route flags */
+ byte lg_darea; /* destination area (reserved) */
+ byte lg_dsarea; /* destination subarea (reserved) */
+ etheraddr lg_dst; /* destination id */
+ byte lg_sarea; /* source area (reserved) */
+ byte lg_ssarea; /* source subarea (reserved) */
+ etheraddr lg_src; /* source id */
+ byte lg_nextl2; /* next level 2 router (reserved) */
+ byte lg_visits; /* visit count */
+ byte lg_service; /* service class (reserved) */
+ byte lg_pt; /* protocol type (reserved) */
+ };
+
+union routehdr
+ {
+ struct shorthdr rh_short; /* short route header */
+ struct longhdr rh_long; /* long route header */
+ };
+
+/*
+ * Define the values of various fields in the protocol messages.
+ *
+ * 1. Data packet formats.
+ */
+#define RMF_MASK 7 /* mask for message type */
+#define RMF_SHORT 2 /* short message format */
+#define RMF_LONG 6 /* long message format */
+#ifndef RMF_RQR
+#define RMF_RQR 010 /* request return to sender */
+#define RMF_RTS 020 /* returning to sender */
+#define RMF_IE 040 /* intra-ethernet packet */
+#endif /* RMR_RQR */
+#define RMF_FVER 0100 /* future version flag */
+#define RMF_PAD 0200 /* pad field */
+#define RMF_PADMASK 0177 /* pad field mask */
+
+#define VIS_MASK 077 /* visit field mask */
+
+/*
+ * 2. Control packet formats.
+ */
+#define RMF_CTLMASK 017 /* mask for message type */
+#define RMF_CTLMSG 01 /* control message indicator */
+#define RMF_INIT 01 /* initialisation message */
+#define RMF_VER 03 /* verification message */
+#define RMF_TEST 05 /* hello and test message */
+#define RMF_L1ROUT 07 /* level 1 routing message */
+#define RMF_L2ROUT 011 /* level 2 routing message */
+#define RMF_RHELLO 013 /* router hello message */
+#define RMF_EHELLO 015 /* endnode hello message */
+
+#define TI_L2ROUT 01 /* level 2 router */
+#define TI_L1ROUT 02 /* level 1 router */
+#define TI_ENDNODE 03 /* endnode */
+#define TI_VERIF 04 /* verification required */
+#define TI_BLOCK 010 /* blocking requested */
+
+#define VE_VERS 2 /* version number (2) */
+#define VE_ECO 0 /* ECO number */
+#define VE_UECO 0 /* user ECO number (0) */
+
+#define P3_VERS 1 /* phase III version number (1) */
+#define P3_ECO 3 /* ECO number (3) */
+#define P3_UECO 0 /* user ECO number (0) */
+
+#define II_L2ROUT 01 /* level 2 router */
+#define II_L1ROUT 02 /* level 1 router */
+#define II_ENDNODE 03 /* endnode */
+#define II_VERIF 04 /* verification required */
+#define II_NOMCAST 040 /* no multicast traffic accepted */
+#define II_BLOCK 0100 /* blocking requested */
+#define II_TYPEMASK 03 /* mask for node type */
+
+#define TESTDATA 0252 /* test data bytes */
+#define TESTLEN 1 /* length of transmitted test data */
+
+/*
+ * Define control message formats.
+ */
+struct initmsgIII /* phase III initialisation message */
+ {
+ byte inIII_flags; /* route flags */
+ word inIII_src; /* source node address */
+ byte inIII_info; /* routing layer information */
+ word inIII_blksize; /* maximum data link block size */
+ byte inIII_vers; /* version number */
+ byte inIII_eco; /* ECO number */
+ byte inIII_ueco; /* user ECO number */
+ byte inIII_rsvd; /* reserved image field */
+ };
+
+struct initmsg /* initialisation message */
+ {
+ byte in_flags; /* route flags */
+ word in_src; /* source node address */
+ byte in_info; /* routing layer information */
+ word in_blksize; /* maximum data link block size */
+ byte in_vers; /* version number */
+ byte in_eco; /* ECO number */
+ byte in_ueco; /* user ECO number */
+ word in_hello; /* hello timer */
+ byte in_rsvd; /* reserved image field */
+ };
+
+struct verifmsg /* verification message */
+ {
+ byte ve_flags; /* route flags */
+ word ve_src; /* source node address */
+ byte ve_fcnval; /* function value image field */
+ };
+
+struct testmsg /* hello and test message */
+ {
+ byte te_flags; /* route flags */
+ word te_src; /* source node address */
+ byte te_data; /* test data image field */
+ };
+
+struct l1rout /* level 1 routing message */
+ {
+ byte r1_flags; /* route flags */
+ word r1_src; /* source node address */
+ byte r1_rsvd; /* reserved field */
+ };
+
+struct l2rout /* level 2 routing message */
+ {
+ byte r2_flags; /* route flags */
+ word r2_src; /* source node address */
+ byte r2_rsvd; /* reserved field */
+ };
+
+struct rhellomsg /* router hello message */
+ {
+ byte rh_flags; /* route flags */
+ byte rh_vers; /* version number */
+ byte rh_eco; /* ECO number */
+ byte rh_ueco; /* user ECO number */
+ etheraddr rh_src; /* source id */
+ byte rh_info; /* routing layer information */
+ word rh_blksize; /* maximum data link block size */
+ byte rh_priority; /* router's priority */
+ byte rh_area; /* reserved */
+ word rh_hello; /* hello timer */
+ byte rh_mpd; /* reserved */
+ };
+
+struct ehellomsg /* endnode hello message */
+ {
+ byte eh_flags; /* route flags */
+ byte eh_vers; /* version number */
+ byte eh_eco; /* ECO number */
+ byte eh_ueco; /* user ECO number */
+ etheraddr eh_src; /* source id */
+ byte eh_info; /* routing layer information */
+ word eh_blksize; /* maximum data link block size */
+ byte eh_area; /* area (reserved) */
+ byte eh_seed[8]; /* verification seed */
+ etheraddr eh_router; /* designated router */
+ word eh_hello; /* hello timer */
+ byte eh_mpd; /* (reserved) */
+ byte eh_data; /* test data image field */
+ };
+
+union controlmsg
+ {
+ struct initmsg cm_init; /* initialisation message */
+ struct verifmsg cm_ver; /* verification message */
+ struct testmsg cm_test; /* hello and test message */
+ struct l1rout cm_l1rou; /* level 1 routing message */
+ struct l2rout cm_l2rout; /* level 2 routing message */
+ struct rhellomsg cm_rhello; /* router hello message */
+ struct ehellomsg cm_ehello; /* endnode hello message */
+ };
+
+/* Macros for decoding routing-info fields */
+#define RI_COST(x) ((x)&0777)
+#define RI_HOPS(x) (((x)>>10)&037)
+
+/*
+ * NSP protocol fields and values.
+ */
+
+#define NSP_TYPEMASK 014 /* mask to isolate type code */
+#define NSP_SUBMASK 0160 /* mask to isolate subtype code */
+#define NSP_SUBSHFT 4 /* shift to move subtype code */
+
+#define MFT_DATA 0 /* data message */
+#define MFT_ACK 04 /* acknowledgement message */
+#define MFT_CTL 010 /* control message */
+
+#define MFS_ILS 020 /* data or I/LS indicator */
+#define MFS_BOM 040 /* beginning of message (data) */
+#define MFS_MOM 0 /* middle of message (data) */
+#define MFS_EOM 0100 /* end of message (data) */
+#define MFS_INT 040 /* interrupt message */
+
+#define MFS_DACK 0 /* data acknowledgement */
+#define MFS_IACK 020 /* I/LS acknowledgement */
+#define MFS_CACK 040 /* connect acknowledgement */
+
+#define MFS_NOP 0 /* no operation */
+#define MFS_CI 020 /* connect initiate */
+#define MFS_CC 040 /* connect confirm */
+#define MFS_DI 060 /* disconnect initiate */
+#define MFS_DC 0100 /* disconnect confirm */
+#define MFS_RCI 0140 /* retransmitted connect initiate */
+
+#define SGQ_ACK 0100000 /* ack */
+#define SGQ_NAK 0110000 /* negative ack */
+#define SGQ_OACK 0120000 /* other channel ack */
+#define SGQ_ONAK 0130000 /* other channel negative ack */
+#define SGQ_MASK 07777 /* mask to isolate seq # */
+#define SGQ_OTHER 020000 /* other channel qualifier */
+#define SGQ_DELAY 010000 /* ack delay flag */
+
+#define SGQ_EOM 0100000 /* pseudo flag for end-of-message */
+
+#define LSM_MASK 03 /* mask for modifier field */
+#define LSM_NOCHANGE 0 /* no change */
+#define LSM_DONOTSEND 1 /* do not send data */
+#define LSM_SEND 2 /* send data */
+
+#define LSI_MASK 014 /* mask for interpretation field */
+#define LSI_DATA 0 /* data segment or message count */
+#define LSI_INTR 4 /* interrupt request count */
+#define LSI_INTM 0377 /* funny marker for int. message */
+
+#define COS_MASK 014 /* mask for flow control field */
+#define COS_NONE 0 /* no flow control */
+#define COS_SEGMENT 04 /* segment flow control */
+#define COS_MESSAGE 010 /* message flow control */
+#define COS_CRYPTSER 020 /* cryptographic services requested */
+#define COS_DEFAULT 1 /* default value for field */
+
+#define COI_MASK 3 /* mask for version field */
+#define COI_32 0 /* version 3.2 */
+#define COI_31 1 /* version 3.1 */
+#define COI_40 2 /* version 4.0 */
+#define COI_41 3 /* version 4.1 */
+
+#define MNU_MASK 140 /* mask for session control version */
+#define MNU_10 000 /* session V1.0 */
+#define MNU_20 040 /* session V2.0 */
+#define MNU_ACCESS 1 /* access control present */
+#define MNU_USRDATA 2 /* user data field present */
+#define MNU_INVKPROXY 4 /* invoke proxy field present */
+#define MNU_UICPROXY 8 /* use uic-based proxy */
+
+#define DC_NORESOURCES 1 /* no resource reason code */
+#define DC_NOLINK 41 /* no link terminate reason code */
+#define DC_COMPLETE 42 /* disconnect complete reason code */
+
+#define DI_NOERROR 0 /* user disconnect */
+#define DI_SHUT 3 /* node is shutting down */
+#define DI_NOUSER 4 /* destination end user does not exist */
+#define DI_INVDEST 5 /* invalid end user destination */
+#define DI_REMRESRC 6 /* insufficient remote resources */
+#define DI_TPA 8 /* third party abort */
+#define DI_PROTOCOL 7 /* protocol error discovered */
+#define DI_ABORT 9 /* user abort */
+#define DI_LOCALRESRC 32 /* insufficient local resources */
+#define DI_REMUSERRESRC 33 /* insufficient remote user resources */
+#define DI_BADACCESS 34 /* bad access control information */
+#define DI_BADACCNT 36 /* bad ACCOUNT information */
+#define DI_CONNECTABORT 38 /* connect request cancelled */
+#define DI_TIMEDOUT 38 /* remote node or user crashed */
+#define DI_UNREACHABLE 39 /* local timers expired due to ... */
+#define DI_BADIMAGE 43 /* bad image data in connect */
+#define DI_SERVMISMATCH 54 /* cryptographic service mismatch */
+
+#define UC_OBJREJECT 0 /* object rejected connect */
+#define UC_USERDISCONNECT 0 /* user disconnect */
+#define UC_RESOURCES 1 /* insufficient resources (local or remote) */
+#define UC_NOSUCHNODE 2 /* unrecognised node name */
+#define UC_REMOTESHUT 3 /* remote node shutting down */
+#define UC_NOSUCHOBJ 4 /* unrecognised object */
+#define UC_INVOBJFORMAT 5 /* invalid object name format */
+#define UC_OBJTOOBUSY 6 /* object too busy */
+#define UC_NETWORKABORT 8 /* network abort */
+#define UC_USERABORT 9 /* user abort */
+#define UC_INVNODEFORMAT 10 /* invalid node name format */
+#define UC_LOCALSHUT 11 /* local node shutting down */
+#define UC_ACCESSREJECT 34 /* invalid access control information */
+#define UC_NORESPONSE 38 /* no response from object */
+#define UC_UNREACHABLE 39 /* node unreachable */
+
+/*
+ * NSP message formats.
+ */
+struct nsphdr /* general nsp header */
+ {
+ byte nh_flags; /* message flags */
+ word nh_dst; /* destination link address */
+ word nh_src; /* source link address */
+ };
+
+struct seghdr /* data segment header */
+ {
+ byte sh_flags; /* message flags */
+ word sh_dst; /* destination link address */
+ word sh_src; /* source link address */
+ word sh_seq[3]; /* sequence numbers */
+ };
+
+struct minseghdr /* minimum data segment header */
+ {
+ byte ms_flags; /* message flags */
+ word ms_dst; /* destination link address */
+ word ms_src; /* source link address */
+ word ms_seq; /* sequence number */
+ };
+
+struct lsmsg /* link service message (after hdr) */
+ {
+ byte ls_lsflags; /* link service flags */
+ byte ls_fcval; /* flow control value */
+ };
+
+struct ackmsg /* acknowledgement message */
+ {
+ byte ak_flags; /* message flags */
+ word ak_dst; /* destination link address */
+ word ak_src; /* source link address */
+ word ak_acknum[2]; /* acknowledgement numbers */
+ };
+
+struct minackmsg /* minimum acknowledgement message */
+ {
+ byte mk_flags; /* message flags */
+ word mk_dst; /* destination link address */
+ word mk_src; /* source link address */
+ word mk_acknum; /* acknowledgement number */
+ };
+
+struct ciackmsg /* connect acknowledgement message */
+ {
+ byte ck_flags; /* message flags */
+ word ck_dst; /* destination link address */
+ };
+
+struct cimsg /* connect initiate message */
+ {
+ byte ci_flags; /* message flags */
+ word ci_dst; /* destination link address (0) */
+ word ci_src; /* source link address */
+ byte ci_services; /* requested services */
+ byte ci_info; /* information */
+ word ci_segsize; /* maximum segment size */
+ };
+
+struct ccmsg /* connect confirm message */
+ {
+ byte cc_flags; /* message flags */
+ word cc_dst; /* destination link address */
+ word cc_src; /* source link address */
+ byte cc_services; /* requested services */
+ byte cc_info; /* information */
+ word cc_segsize; /* maximum segment size */
+ byte cc_optlen; /* optional data length */
+ };
+
+struct cnmsg /* generic connect message */
+ {
+ byte cn_flags; /* message flags */
+ word cn_dst; /* destination link address */
+ word cn_src; /* source link address */
+ byte cn_services; /* requested services */
+ byte cn_info; /* information */
+ word cn_segsize; /* maximum segment size */
+ };
+
+struct dimsg /* disconnect initiate message */
+ {
+ byte di_flags; /* message flags */
+ word di_dst; /* destination link address */
+ word di_src; /* source link address */
+ word di_reason; /* reason code */
+ byte di_optlen; /* optional data length */
+ };
+
+struct dcmsg /* disconnect confirm message */
+ {
+ byte dc_flags; /* message flags */
+ word dc_dst; /* destination link address */
+ word dc_src; /* source link address */
+ word dc_reason; /* reason code */
+ };
+
+/*
+ * Like the macros in extract.h, except that since DECNET is a little-endian
+ * protocol, the BYTEORDER sense is reversed.
+ */
+#define EXTRACT_8BITS(p) (*(p))
+#if BYTEORDER == BIG_ENDIAN
+#define EXTRACT_16BITS(p)\
+ ((u_short)\
+ (*((u_char *)p+1)<<8|\
+ *((u_char *)p+0)<<0))
+#define EXTRACT_32BITS(p)\
+ (*((u_char *)p+3)<<24|\
+ *((u_char *)p+2)<<16|\
+ *((u_char *)p+1)<<8|\
+ *((u_char *)p+0)<<0)
+#else
+#define EXTRACT_16BITS(p)\
+ ((u_short)\
+ (*((u_char *)p+0)<<8|\
+ *((u_char *)p+1)<<0))
+#define EXTRACT_32BITS(p)\
+ (*((u_char *)p+0)<<24|\
+ *((u_char *)p+1)<<16|\
+ *((u_char *)p+2)<<8|\
+ *((u_char *)p+3)<<0)
+#endif
diff --git a/usr.sbin/tcpdump/ethertype.h b/usr.sbin/tcpdump/ethertype.h
new file mode 100644
index 00000000000..c4ec760218f
--- /dev/null
+++ b/usr.sbin/tcpdump/ethertype.h
@@ -0,0 +1,72 @@
+/* $NetBSD: ethertype.h,v 1.2 1995/03/06 19:10:06 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: ethertype.h,v 1.4 94/06/14 20:11:45 leres Exp (LBL)
+ */
+
+/* Map between Ethernet protocol types and names */
+
+/* Add other Ethernet packet types here */
+#ifndef ETHERTYPE_SPRITE
+#define ETHERTYPE_SPRITE 0x0500
+#endif
+#ifndef ETHERTYPE_MOPDL
+#define ETHERTYPE_MOPDL 0x6001
+#endif
+#ifndef ETHERTYPE_MOPRC
+#define ETHERTYPE_MOPRC 0x6002
+#endif
+#ifndef ETHERTYPE_DN
+#define ETHERTYPE_DN 0x6003
+#endif
+#ifndef ETHERTYPE_LAT
+#define ETHERTYPE_LAT 0x6004
+#endif
+#ifndef ETHERTYPE_LANBRIDGE
+#define ETHERTYPE_LANBRIDGE 0x8038
+#endif
+#ifndef ETHERTYPE_DECDNS
+#define ETHERTYPE_DECDNS 0x803c
+#endif
+#ifndef ETHERTYPE_DECDTS
+#define ETHERTYPE_DECDTS 0x803e
+#endif
+#ifndef ETHERTYPE_VEXP
+#define ETHERTYPE_VEXP 0x805b
+#endif
+#ifndef ETHERTYPE_VPROD
+#define ETHERTYPE_VPROD 0x805c
+#endif
+#ifndef ETHERTYPE_LOOPBACK
+#define ETHERTYPE_LOOPBACK 0x9000
+#endif
+
+#ifndef ETHERTYPE_ATALK
+#define ETHERTYPE_ATALK 0x809b
+#endif
+#ifndef ETHERTYPE_AARP
+#define ETHERTYPE_AARP 0x80f3
+#endif
+#ifndef ETHERTYPE_NS
+#define ETHERTYPE_NS 0x0600
+#endif
+
diff --git a/usr.sbin/tcpdump/extract.h b/usr.sbin/tcpdump/extract.h
new file mode 100644
index 00000000000..2288ca55d58
--- /dev/null
+++ b/usr.sbin/tcpdump/extract.h
@@ -0,0 +1,51 @@
+/* $NetBSD: extract.h,v 1.2 1995/03/06 19:10:08 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: extract.h,v 1.7 94/06/14 20:11:45 leres Exp (LBL)
+ */
+
+#ifdef TCPDUMP_ALIGN
+#if BYTEORDER == LITTLE_ENDIAN
+#define EXTRACT_SHORT(p)\
+ ((u_short)\
+ ((u_short)*((u_char *)p+1)<<8|\
+ (u_short)*((u_char *)p+0)<<0))
+#define EXTRACT_LONG(p)\
+ ((u_int32)*((u_char *)p+3)<<24|\
+ (u_int32)*((u_char *)p+2)<<16|\
+ (u_int32)*((u_char *)p+1)<<8|\
+ (u_int32)*((u_char *)p+0)<<0)
+#else
+#define EXTRACT_SHORT(p)\
+ ((u_short)\
+ ((u_short)*((u_char *)p+0)<<8|\
+ (u_short)*((u_char *)p+1)<<0))
+#define EXTRACT_LONG(p)\
+ ((u_int32)*((u_char *)p+0)<<24|\
+ (u_int32)*((u_char *)p+1)<<16|\
+ (u_int32)*((u_char *)p+2)<<8|\
+ (u_int32)*((u_char *)p+3)<<0)
+#endif
+#else
+#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
+#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p))
+#endif
diff --git a/usr.sbin/tcpdump/fddi.h b/usr.sbin/tcpdump/fddi.h
new file mode 100644
index 00000000000..2d91b70454f
--- /dev/null
+++ b/usr.sbin/tcpdump/fddi.h
@@ -0,0 +1,78 @@
+/* $NetBSD: fddi.h,v 1.2 1995/03/06 19:10:10 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: fddi.h,v 1.6 94/06/14 20:12:35 leres Exp (LBL)
+ */
+
+/*
+ * Based on Ultrix if_fddi.h
+ */
+
+/*
+ * This stuff should come from a system header file, but there's no
+ * obviously portable way to do that and it's not really going
+ * to change from system to system (except for the padding business).
+ */
+
+struct fddi_header {
+#if defined(ultrix) || defined(__alpha)
+ /* Ultrix pads to make everything line up on a nice boundary */
+#define FDDIPAD 3
+ u_char fddi_ph[FDDIPAD];
+#else
+#define FDDIPAD 0
+#endif
+ u_char fddi_fc; /* frame control */
+ u_char fddi_dhost[6];
+ u_char fddi_shost[6];
+};
+
+
+/* Useful values for fddi_fc (frame control) field */
+
+/*
+ * FDDI Frame Control bits
+ */
+#define FDDIFC_C 0x80 /* Class bit */
+#define FDDIFC_L 0x40 /* Address length bit */
+#define FDDIFC_F 0x30 /* Frame format bits */
+#define FDDIFC_Z 0x0f /* Control bits */
+
+/*
+ * FDDI Frame Control values. (48-bit addressing only).
+ */
+#define FDDIFC_VOID 0x40 /* Void frame */
+#define FDDIFC_NRT 0x80 /* Nonrestricted token */
+#define FDDIFC_RT 0xc0 /* Restricted token */
+#define FDDIFC_SMT_INFO 0x41 /* SMT Info */
+#define FDDIFC_SMT_NSA 0x4F /* SMT Next station adrs */
+#define FDDIFC_MAC_BEACON 0xc2 /* MAC Beacon frame */
+#define FDDIFC_MAC_CLAIM 0xc3 /* MAC Claim frame */
+#define FDDIFC_LLC_ASYNC 0x50 /* Async. LLC frame */
+#define FDDIFC_LLC_SYNC 0xd0 /* Sync. LLC frame */
+#define FDDIFC_IMP_ASYNC 0x60 /* Implementor Async. */
+#define FDDIFC_IMP_SYNC 0xe0 /* Implementor Synch. */
+#define FDDIFC_SMT 0x40 /* SMT frame */
+#define FDDIFC_MAC 0xc0 /* MAC frame */
+
+#define FDDIFC_CLFF 0xF0 /* Class/Length/Format bits */
+#define FDDIFC_ZZZZ 0x0F /* Control bits */
diff --git a/usr.sbin/tcpdump/interface.h b/usr.sbin/tcpdump/interface.h
new file mode 100644
index 00000000000..2e321153116
--- /dev/null
+++ b/usr.sbin/tcpdump/interface.h
@@ -0,0 +1,152 @@
+/* $NetBSD: interface.h,v 1.2 1995/03/06 19:10:18 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: interface.h,v 1.66 94/06/14 20:21:37 leres Exp (LBL)
+ */
+
+#ifdef __GNUC__
+#define inline __inline
+#ifndef __dead
+#define __dead volatile
+#endif
+#else
+#define inline
+#define __dead
+#endif
+
+#include "os.h" /* operating system stuff */
+#include "md.h" /* machine dependent stuff */
+
+#ifndef SIGRET
+#define SIGRET void /* default */
+#endif
+
+struct token {
+ int v; /* value */
+ char *s; /* string */
+};
+
+extern int dflag; /* print filter code */
+extern int eflag; /* print ethernet header */
+extern int nflag; /* leave addresses as numbers */
+extern int Nflag; /* remove domains from printed host names */
+extern int qflag; /* quick (shorter) output */
+extern int Sflag; /* print raw TCP sequence numbers */
+extern int tflag; /* print packet arrival time */
+extern int vflag; /* verbose */
+extern int xflag; /* print packet in hex */
+
+extern char *program_name; /* used to generate self-identifying messages */
+
+extern int snaplen;
+/* global pointers to beginning and end of current packet (during printing) */
+extern const u_char *packetp;
+extern const u_char *snapend;
+
+extern int fddipad; /* alignment offset for FDDI headers, in bytes */
+
+/* Eliminate some bogus warnings. */
+struct timeval;
+
+typedef void (*printfunc)(u_char *, struct timeval *, int, int);
+
+extern void ts_print(const struct timeval *);
+extern int clock_sigfigs(void);
+int gmt2local(void);
+
+extern int fn_print(const u_char *, const u_char *);
+extern int fn_printn(const u_char *, u_int, const u_char *);
+extern const char *tok2str(const struct token *, const char *, int);
+extern char *dnaddr_string(u_short);
+extern char *savestr(const char *);
+
+extern int initdevice(char *, int, int *);
+extern void wrapup(int);
+
+extern __dead void error(char *, ...);
+extern void warning(char *, ...);
+
+extern char *read_infile(char *);
+extern char *copy_argv(char **);
+
+extern void usage(void);
+extern char *isonsap_string(const u_char *);
+extern char *llcsap_string(u_char);
+extern char *protoid_string(const u_char *);
+extern char *dnname_string(u_short);
+extern char *dnnum_string(u_short);
+
+/* The printer routines. */
+
+struct pcap_pkthdr;
+
+extern void ether_if_print(u_char *, const struct pcap_pkthdr *,
+ const u_char *);
+extern void fddi_if_print(u_char *, const struct pcap_pkthdr *, const u_char*);
+extern void null_if_print(u_char *, const struct pcap_pkthdr *, const u_char*);
+extern void ppp_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern void sl_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+
+extern void arp_print(const u_char *, int, int);
+extern void ip_print(const u_char *, int);
+extern void tcp_print(const u_char *, int, const u_char *);
+extern void udp_print(const u_char *, int, const u_char *);
+extern void icmp_print(const u_char *, const u_char *);
+extern void default_print(const u_char *, int);
+extern void default_print_unaligned(const u_char *, int);
+
+extern void aarp_print(const u_char *, int);
+extern void atalk_print(const u_char *, int);
+extern void bootp_print(const u_char *, int, u_short, u_short);
+extern void decnet_print(const u_char *, int, int);
+extern void egp_print(const u_char *, int, const u_char *);
+extern int ether_encap_print(u_short, const u_char *, int, int);
+extern void ipx_print(const u_char *, int length);
+extern void isoclns_print(const u_char *, int, int,
+ const u_char *, const u_char *);
+extern int llc_print(const u_char *, int, int, const u_char *, const u_char *);
+extern void nfsreply_print(const u_char *, int, const u_char *);
+extern void nfsreq_print(const u_char *, int, const u_char *);
+extern void ns_print(const u_char *, int);
+extern void ntp_print(const u_char *, int);
+extern void ospf_print(const u_char *, int, const u_char *);
+extern void rip_print(const u_char *, int);
+extern void snmp_print(const u_char *, int);
+extern void sunrpcrequest_print(const u_char *, int, const u_char *);
+extern void tftp_print(const u_char *, int);
+extern void wb_print(const void *, int);
+
+#define min(a,b) ((a)>(b)?(b):(a))
+#define max(a,b) ((b)>(a)?(b):(a))
+
+/*
+ * The default snapshot length. This value allows most printers to print
+ * useful information while keeping the amount of unwanted data down.
+ * In particular, it allows for an ethernet header, tcp/ip header, and
+ * 14 bytes of data (assuming no ip options).
+ */
+#define DEFAULT_SNAPLEN 68
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234
+#endif
diff --git a/usr.sbin/tcpdump/ipx.h b/usr.sbin/tcpdump/ipx.h
new file mode 100644
index 00000000000..e943f6e7673
--- /dev/null
+++ b/usr.sbin/tcpdump/ipx.h
@@ -0,0 +1,31 @@
+/* $NetBSD: ipx.h,v 1.2 1995/03/06 19:10:19 mycroft Exp $ */
+
+/*
+ * IPX protocol formats
+ *
+ * @(#) Header: ipx.h,v 1.1 94/06/09 11:47:03 mccanne Exp
+ */
+
+/* well-known sockets */
+#define IPX_SKT_NCP 0x0451
+#define IPX_SKT_SAP 0x0452
+#define IPX_SKT_RIP 0x0453
+#define IPX_SKT_NETBIOS 0x0455
+#define IPX_SKT_DIAGNOSTICS 0x0456
+
+/* IPX transport header */
+struct ipxHdr {
+ u_short cksum; /* Checksum */
+ u_short length; /* Length, in bytes, including header */
+ u_char tCtl; /* Transport Control (i.e. hop count) */
+ u_char pType; /* Packet Type (i.e. level 2 protocol) */
+ u_short dstNet[2]; /* destination net */
+ u_char dstNode[6]; /* destination node */
+ u_short dstSkt; /* destination socket */
+ u_short srcNet[2]; /* source net */
+ u_char srcNode[6]; /* source node */
+ u_short srcSkt; /* source socket */
+} ipx_hdr_t;
+
+#define ipxSize 30
+
diff --git a/usr.sbin/tcpdump/llc.h b/usr.sbin/tcpdump/llc.h
new file mode 100644
index 00000000000..2712fda70a1
--- /dev/null
+++ b/usr.sbin/tcpdump/llc.h
@@ -0,0 +1,122 @@
+/* $NetBSD: llc.h,v 1.2 1995/03/06 19:10:20 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: llc.h,v 1.4 94/06/14 20:11:46 leres Exp (LBL)
+ */
+
+/*
+ * This stuff should come from a system header file, but there's no
+ * obviously portable way to do that and it's not really going
+ * to change from system to system.
+ */
+
+/*
+ * A somewhat abstracted view of the LLC header
+ */
+
+struct llc {
+ u_char dsap;
+ u_char ssap;
+ union {
+ u_char u_ctl;
+ u_short is_ctl;
+ struct {
+ u_char snap_ui;
+ u_char snap_pi[5];
+ } snap;
+ struct {
+ u_char snap_ui;
+ u_char snap_orgcode[3];
+ u_char snap_ethertype[2];
+ } snap_ether;
+ } ctl;
+};
+
+#define llcui ctl.snap.snap_ui
+#define llcpi ctl.snap.snap_pi
+#define orgcode ctl.snap_ether.snap_orgcode
+#define ethertype ctl.snap_ether.snap_ethertype
+#define llcis ctl.is_ctl
+#define llcu ctl.u_ctl
+
+#define LLC_U_FMT 3
+#define LLC_GSAP 1
+#define LLC_S_FMT 1
+
+#define LLC_U_POLL 0x10
+#define LLC_IS_POLL 0x0001
+#define LLC_XID_FI 0x81
+
+#define LLC_U_CMD(u) ((u) & 0xef)
+#define LLC_UI 0x03
+#define LLC_UA 0x63
+#define LLC_DISC 0x43
+#define LLC_DM 0x0f
+#define LLC_SABME 0x6f
+#define LLC_TEST 0xe3
+#define LLC_XID 0xaf
+#define LLC_FRMR 0x87
+
+#define LLC_S_CMD(is) (((is) >> 10) & 0x03)
+#define LLC_RR 0x0100
+#define LLC_RNR 0x0500
+#define LLC_REJ 0x0900
+
+#define LLC_IS_NR(is) (((is) >> 9) & 0x7f)
+#define LLC_I_NS(is) (((is) >> 1) & 0x7f)
+
+#ifndef LLCSAP_NULL
+#define LLCSAP_NULL 0x00
+#endif
+#ifndef LLCSAP_GLOBAL
+#define LLCSAP_GLOBAL 0xff
+#endif
+#ifndef LLCSAP_8021B
+#define LLCSAP_8021B_I 0x02
+#endif
+#ifndef LLCSAP_8021B
+#define LLCSAP_8021B_G 0x03
+#endif
+#ifndef LLCSAP_IP
+#define LLCSAP_IP 0x06
+#endif
+#ifndef LLCSAP_PROWAYNM
+#define LLCSAP_PROWAYNM 0x0e
+#endif
+#ifndef LLCSAP_8021D
+#define LLCSAP_8021D 0x42
+#endif
+#ifndef LLCSAP_RS511
+#define LLCSAP_RS511 0x4e
+#endif
+#ifndef LLCSAP_ISO8208
+#define LLCSAP_ISO8208 0x7e
+#endif
+#ifndef LLCSAP_PROWAY
+#define LLCSAP_PROWAY 0x8e
+#endif
+#ifndef LLCSAP_SNAP
+#define LLCSAP_SNAP 0xaa
+#endif
+#ifndef LLCSAP_ISONS
+#define LLCSAP_ISONS 0xfe
+#endif
diff --git a/usr.sbin/tcpdump/makemib b/usr.sbin/tcpdump/makemib
new file mode 100644
index 00000000000..debab1f3763
--- /dev/null
+++ b/usr.sbin/tcpdump/makemib
@@ -0,0 +1,175 @@
+#!/bin/sh
+#
+# $NetBSD: makemib,v 1.2 1995/03/06 19:10:22 mycroft Exp $
+#
+# Copyright (c) 1990, by John Robert LoVerso.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are permitted
+# provided that the above copyright notice and this paragraph are
+# duplicated in all such forms and that any documentation,
+# advertising materials, and other materials related to such
+# distribution and use acknowledge that the software was developed
+# by John Robert LoVerso.
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+# @(#) Id: makemib,v 2.1 90/07/10 23:51:54 loverso Exp Locker: loverso (jlv
+)
+
+#
+# This script will read either ASN.1-style MIB files or the ".defs" files
+# created by the ISODE "mosy" program on such files.
+#
+# The output of this script is the "mib.h" file used by tcpdumps' ASN.1/SNMP
+# decoding code.
+#
+# This script needs to be run by "gawk" (GNU awk). "nawk" will work, but
+# dump will get a recursion error if you process LARGE mibs. While it would
+# by farily easy to rewrite this not to use recursion (and also easy to
+# eliminate use of gsub and functions to use classic "awk"), you have to
+# order the structure declarations in defined-first order for the compiler
+# not to barf; too bad tsort doesn't take arguments.
+#
+
+cat << EOF
+/*
+ * This file was generated by tcpdump/makemib on `date`
+ * You probably don't want to edit this by hand!
+ *
+ * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer
+};
+ */
+
+EOF
+
+# use sed to make the ASN.1 easier to parse
+# I should really just use a recursive descent parser in awk, but...
+sed \
+ -e 's/--\*.*\*--//' \
+ -e 's/--.*//' \
+ -e 's/\([{}]\)/ \1 /g' \
+ $@ \
+| gawk '
+BEGIN {
+ # for sanity, we prep the namespace with objects from RFC-1155
+ # (we manually establish the root)
+ oid["iso"]=1
+ oidadd("org", "iso", 3)
+ oidadd("dod", "org", 6)
+ oidadd("internet", "dod", 1)
+ oidadd("directory", "internet", 1)
+ oidadd("mgmt", "internet", 2)
+ oidadd("mib", "mgmt", 1)
+ oidadd("experimental", "internet", 3)
+ oidadd("private", "internet", 4)
+ oidadd("enterprises", "private", 1)
+
+ holddesc="none"
+}
+
+#
+# Read mosy "*.defs" file. mosy does all the parsing work; we just read
+# its simple and straightforward output. It would not be too hard to make
+# tcpdump directly read mosy output, but...
+#
+
+NF > 1 && index($2,".")>0 {
+ # currently ignore items of the form "{ iso.3.6.1 }"
+ if (split($2, p, ".") == 2)
+ oidadd($1, p[1], p[2])
+ next
+}
+
+#
+# this next section is simple and naive, but does the job 100%
+#
+
+$2$3$4 == "OBJECTIDENTIFIER::=" {
+ holddesc="none"
+ if (NF == 8)
+ oidadd($1, $6, $7)
+}
+$2 == "OBJECT-TYPE" {
+ holddesc=$1
+}
+$1 == "::=" && holddesc != "none" && NF == 5 {
+ oidadd(holddesc, $3, $4)
+ holddesc="none"
+}
+
+#
+# End of the road - output the data.
+#
+
+END {
+ print "struct obj"
+ dump("iso")
+ print "*mibroot = &_iso_obj;"
+}
+
+#
+# add a new object to the tree
+#
+# new OBJECT IDENTIFIER ::= { parent value }
+#
+
+function oidadd(new, parent, value) {
+ # use safe C identifiers
+ gsub(/[-&\/]/,"",new)
+ gsub(/[-&\/]/,"",parent)
+ # check if parent missing
+ if (oid[parent] == 0) {
+ printf "/* parse problem: no parent for %s.%s(%d) */\n", \
+ parent, new, value
+ return
+ }
+ # check if parent.value already exists
+ if (oid[new] > 0 && oid[new] != value) {
+ printf "/* parse problem: dup %s.%s(%d) != old (%d) */\n", \
+ parent, new, value, oid[new]
+ return
+ }
+ # check for new name for parent.value
+ if (child[parent] != "") {
+ for (sib = child[parent]; sib != ""; sib = sibling[sib])
+ if (oid[sib] == value) {
+ printf "/* parse problem: new name \"%s\"" \
+ " for %s.%s(%d) ignored */\n", \
+ new, parent, sib, value
+ return
+ }
+ }
+
+ oid[new]=value
+ if (child[parent] == "") {
+ child[parent] = new
+ } else {
+ sibling[new] = child[parent]
+ child[parent] = new
+ }
+}
+
+#
+# old(?) routine to recurse down the tree (in postfix order for convenience)
+#
+
+function dump(item, c, s) {
+# newitem=sofar"."item"("oid[item]")"
+# printf "/* %s c=%s s=%s */\n", newitem, child[item], sibling[item]
+ c="NULL"
+ if (child[item] != "") {
+ dump(child[item])
+ c = "&_"child[item]"_obj"
+ }
+ s="NULL"
+ if (sibling[item] != "") {
+ dump(sibling[item])
+ s = "&_"sibling[item]"_obj"
+ }
+ printf "_%s_obj = {\n\t\"%s\", %d, 0,\n\t%s, %s\n},\n", \
+ item, item, oid[item], c, s
+}
+'
+exit 0
diff --git a/usr.sbin/tcpdump/md.h b/usr.sbin/tcpdump/md.h
new file mode 100644
index 00000000000..35306653f23
--- /dev/null
+++ b/usr.sbin/tcpdump/md.h
@@ -0,0 +1,35 @@
+/* $NetBSD: md.h,v 1.2 1995/03/06 19:10:33 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: md-i386.h,v 1.5 94/06/14 20:14:40 leres Exp (LBL)
+ */
+
+#define TCPDUMP_ALIGN
+
+#include <machine/endian.h>
+
+/* 32-bit data types */
+/* N.B.: this doesn't address printf()'s %d vs. %ld formats */
+typedef int32_t int32; /* signed 32-bit integer */
+#ifndef AUTH_UNIX
+typedef u_int32_t u_int32; /* unsigned 32-bit integer */
+#endif
diff --git a/usr.sbin/tcpdump/mib.h b/usr.sbin/tcpdump/mib.h
new file mode 100644
index 00000000000..747af862f9c
--- /dev/null
+++ b/usr.sbin/tcpdump/mib.h
@@ -0,0 +1,1258 @@
+/* $NetBSD: mib.h,v 1.2 1995/03/06 19:10:34 mycroft Exp $ */
+
+/*
+ * This file was generated by tcpdump/makemib on Wed Sep 26 12:12:31 EDT 1990
+ * You probably don't want to edit this by hand!
+ *
+ * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer
+};
+ */
+
+/* parse problem: new name "mib" for mgmt.mib(1) ignored */
+/* parse problem: no parent for 0.nullSpecific(0) */
+struct obj
+_proteon_obj = {
+ "proteon", 1, 0,
+ NULL, NULL
+},
+_ibm_obj = {
+ "ibm", 2, 0,
+ NULL, &_proteon_obj
+},
+_cmu_obj = {
+ "cmu", 3, 0,
+ NULL, &_ibm_obj
+},
+_unix_obj = {
+ "unix", 4, 0,
+ NULL, &_cmu_obj
+},
+_acc_obj = {
+ "acc", 5, 0,
+ NULL, &_unix_obj
+},
+_twg_obj = {
+ "twg", 6, 0,
+ NULL, &_acc_obj
+},
+_cayman_obj = {
+ "cayman", 7, 0,
+ NULL, &_twg_obj
+},
+_nysernet_obj = {
+ "nysernet", 8, 0,
+ NULL, &_cayman_obj
+},
+_cisco_obj = {
+ "cisco", 9, 0,
+ NULL, &_nysernet_obj
+},
+_nsc_obj = {
+ "nsc", 10, 0,
+ NULL, &_cisco_obj
+},
+_hp_obj = {
+ "hp", 11, 0,
+ NULL, &_nsc_obj
+},
+_epilogue_obj = {
+ "epilogue", 12, 0,
+ NULL, &_hp_obj
+},
+_utennessee_obj = {
+ "utennessee", 13, 0,
+ NULL, &_epilogue_obj
+},
+_bbn_obj = {
+ "bbn", 14, 0,
+ NULL, &_utennessee_obj
+},
+_xylogics_obj = {
+ "xylogics", 15, 0,
+ NULL, &_bbn_obj
+},
+_unisys_obj = {
+ "unisys", 16, 0,
+ NULL, &_xylogics_obj
+},
+_canstar_obj = {
+ "canstar", 17, 0,
+ NULL, &_unisys_obj
+},
+_wellfleet_obj = {
+ "wellfleet", 18, 0,
+ NULL, &_canstar_obj
+},
+_trw_obj = {
+ "trw", 19, 0,
+ NULL, &_wellfleet_obj
+},
+_mit_obj = {
+ "mit", 20, 0,
+ NULL, &_trw_obj
+},
+_eon_obj = {
+ "eon", 21, 0,
+ NULL, &_mit_obj
+},
+_spartacus_obj = {
+ "spartacus", 22, 0,
+ NULL, &_eon_obj
+},
+_excelan_obj = {
+ "excelan", 23, 0,
+ NULL, &_spartacus_obj
+},
+_spider_obj = {
+ "spider", 24, 0,
+ NULL, &_excelan_obj
+},
+_nsfnet_obj = {
+ "nsfnet", 25, 0,
+ NULL, &_spider_obj
+},
+_sytek_obj = {
+ "sytek", 26, 0,
+ NULL, &_nsfnet_obj
+},
+_intergraph_obj = {
+ "intergraph", 27, 0,
+ NULL, &_sytek_obj
+},
+_interlan_obj = {
+ "interlan", 28, 0,
+ NULL, &_intergraph_obj
+},
+_vitalink_obj = {
+ "vitalink", 29, 0,
+ NULL, &_interlan_obj
+},
+_ulana_obj = {
+ "ulana", 30, 0,
+ NULL, &_vitalink_obj
+},
+_nswc_obj = {
+ "nswc", 31, 0,
+ NULL, &_ulana_obj
+},
+_santacruzoperation_obj = {
+ "santacruzoperation", 32, 0,
+ NULL, &_nswc_obj
+},
+_xyplex_obj = {
+ "xyplex", 33, 0,
+ NULL, &_santacruzoperation_obj
+},
+_cray_obj = {
+ "cray", 34, 0,
+ NULL, &_xyplex_obj
+},
+_bellnorthernresearch_obj = {
+ "bellnorthernresearch", 35, 0,
+ NULL, &_cray_obj
+},
+_dec_obj = {
+ "dec", 36, 0,
+ NULL, &_bellnorthernresearch_obj
+},
+_touch_obj = {
+ "touch", 37, 0,
+ NULL, &_dec_obj
+},
+_networkresearchcorp_obj = {
+ "networkresearchcorp", 38, 0,
+ NULL, &_touch_obj
+},
+_baylor_obj = {
+ "baylor", 39, 0,
+ NULL, &_networkresearchcorp_obj
+},
+_nmfeccllnl_obj = {
+ "nmfeccllnl", 40, 0,
+ NULL, &_baylor_obj
+},
+_sri_obj = {
+ "sri", 41, 0,
+ NULL, &_nmfeccllnl_obj
+},
+_sun_obj = {
+ "sun", 42, 0,
+ NULL, &_sri_obj
+},
+_3com_obj = {
+ "3com", 43, 0,
+ NULL, &_sun_obj
+},
+_cmc_obj = {
+ "cmc", 44, 0,
+ NULL, &_3com_obj
+},
+_synoptics_obj = {
+ "synoptics", 45, 0,
+ NULL, &_cmc_obj
+},
+_cheyenne_obj = {
+ "cheyenne", 46, 0,
+ NULL, &_synoptics_obj
+},
+_prime_obj = {
+ "prime", 47, 0,
+ NULL, &_cheyenne_obj
+},
+_mcnc_obj = {
+ "mcnc", 48, 0,
+ NULL, &_prime_obj
+},
+_chipcom_obj = {
+ "chipcom", 49, 0,
+ NULL, &_mcnc_obj
+},
+_opticaldatasystems_obj = {
+ "opticaldatasystems", 50, 0,
+ NULL, &_chipcom_obj
+},
+_gated_obj = {
+ "gated", 51, 0,
+ NULL, &_opticaldatasystems_obj
+},
+_cabletron_obj = {
+ "cabletron", 52, 0,
+ NULL, &_gated_obj
+},
+_apollo_obj = {
+ "apollo", 53, 0,
+ NULL, &_cabletron_obj
+},
+_desktalksystems_obj = {
+ "desktalksystems", 54, 0,
+ NULL, &_apollo_obj
+},
+_ssds_obj = {
+ "ssds", 55, 0,
+ NULL, &_desktalksystems_obj
+},
+_castlerock_obj = {
+ "castlerock", 56, 0,
+ NULL, &_ssds_obj
+},
+_mips_obj = {
+ "mips", 57, 0,
+ NULL, &_castlerock_obj
+},
+_tgv_obj = {
+ "tgv", 58, 0,
+ NULL, &_mips_obj
+},
+_silicongraphics_obj = {
+ "silicongraphics", 59, 0,
+ NULL, &_tgv_obj
+},
+_ubc_obj = {
+ "ubc", 60, 0,
+ NULL, &_silicongraphics_obj
+},
+_merit_obj = {
+ "merit", 61, 0,
+ NULL, &_ubc_obj
+},
+_fibercom_obj = {
+ "fibercom", 62, 0,
+ NULL, &_merit_obj
+},
+_apple_obj = {
+ "apple", 63, 0,
+ NULL, &_fibercom_obj
+},
+_gandalf_obj = {
+ "gandalf", 64, 0,
+ NULL, &_apple_obj
+},
+_dartmouth_obj = {
+ "dartmouth", 65, 0,
+ NULL, &_gandalf_obj
+},
+_davidsystems_obj = {
+ "davidsystems", 66, 0,
+ NULL, &_dartmouth_obj
+},
+_reuter_obj = {
+ "reuter", 67, 0,
+ NULL, &_davidsystems_obj
+},
+_cornell_obj = {
+ "cornell", 68, 0,
+ NULL, &_reuter_obj
+},
+_tmac_obj = {
+ "tmac", 69, 0,
+ NULL, &_cornell_obj
+},
+_locus_obj = {
+ "locus", 70, 0,
+ NULL, &_tmac_obj
+},
+_nasa_obj = {
+ "nasa", 71, 0,
+ NULL, &_locus_obj
+},
+_retix_obj = {
+ "retix", 72, 0,
+ NULL, &_nasa_obj
+},
+_boeing_obj = {
+ "boeing", 73, 0,
+ NULL, &_retix_obj
+},
+_att_obj = {
+ "att", 74, 0,
+ NULL, &_boeing_obj
+},
+_ungermannbass_obj = {
+ "ungermannbass", 75, 0,
+ NULL, &_att_obj
+},
+_digitalanalysis_obj = {
+ "digitalanalysis", 76, 0,
+ NULL, &_ungermannbass_obj
+},
+_hplanman_obj = {
+ "hplanman", 77, 0,
+ NULL, &_digitalanalysis_obj
+},
+_netlabs_obj = {
+ "netlabs", 78, 0,
+ NULL, &_hplanman_obj
+},
+_icl_obj = {
+ "icl", 79, 0,
+ NULL, &_netlabs_obj
+},
+_auspex_obj = {
+ "auspex", 80, 0,
+ NULL, &_icl_obj
+},
+_lannet_obj = {
+ "lannet", 81, 0,
+ NULL, &_auspex_obj
+},
+_ncd_obj = {
+ "ncd", 82, 0,
+ NULL, &_lannet_obj
+},
+_raycom_obj = {
+ "raycom", 83, 0,
+ NULL, &_ncd_obj
+},
+_pirellifocom_obj = {
+ "pirellifocom", 84, 0,
+ NULL, &_raycom_obj
+},
+_datability_obj = {
+ "datability", 85, 0,
+ NULL, &_pirellifocom_obj
+},
+_networkappltech_obj = {
+ "networkappltech", 86, 0,
+ NULL, &_datability_obj
+},
+_link_obj = {
+ "link", 87, 0,
+ NULL, &_networkappltech_obj
+},
+_nyu_obj = {
+ "nyu", 88, 0,
+ NULL, &_link_obj
+},
+_rnd_obj = {
+ "rnd", 89, 0,
+ NULL, &_nyu_obj
+},
+_intercon_obj = {
+ "intercon", 90, 0,
+ NULL, &_rnd_obj
+},
+_learningtree_obj = {
+ "learningtree", 91, 0,
+ NULL, &_intercon_obj
+},
+_webstercomputer_obj = {
+ "webstercomputer", 92, 0,
+ NULL, &_learningtree_obj
+},
+_frontier_obj = {
+ "frontier", 93, 0,
+ NULL, &_webstercomputer_obj
+},
+_nokia_obj = {
+ "nokia", 94, 0,
+ NULL, &_frontier_obj
+},
+_allenbradley_obj = {
+ "allenbradley", 95, 0,
+ NULL, &_nokia_obj
+},
+_cern_obj = {
+ "cern", 96, 0,
+ NULL, &_allenbradley_obj
+},
+_sigma_obj = {
+ "sigma", 97, 0,
+ NULL, &_cern_obj
+},
+_emergingtech_obj = {
+ "emergingtech", 98, 0,
+ NULL, &_sigma_obj
+},
+_snmpresearch_obj = {
+ "snmpresearch", 99, 0,
+ NULL, &_emergingtech_obj
+},
+_ohiostate_obj = {
+ "ohiostate", 100, 0,
+ NULL, &_snmpresearch_obj
+},
+_ultra_obj = {
+ "ultra", 101, 0,
+ NULL, &_ohiostate_obj
+},
+_ccur_obj = {
+ "ccur", 136, 0,
+ NULL, &_ultra_obj
+},
+_enterprises_obj = {
+ "enterprises", 1, 0,
+ &_ccur_obj, NULL
+},
+_snmpInPkts_obj = {
+ "snmpInPkts", 1, 0,
+ NULL, NULL
+},
+_snmpOutPkts_obj = {
+ "snmpOutPkts", 2, 0,
+ NULL, &_snmpInPkts_obj
+},
+_snmpInBadVersions_obj = {
+ "snmpInBadVersions", 3, 0,
+ NULL, &_snmpOutPkts_obj
+},
+_snmpInBadCommunityNames_obj = {
+ "snmpInBadCommunityNames", 4, 0,
+ NULL, &_snmpInBadVersions_obj
+},
+_snmpInBadCommunityUses_obj = {
+ "snmpInBadCommunityUses", 5, 0,
+ NULL, &_snmpInBadCommunityNames_obj
+},
+_snmpInASNParseErrs_obj = {
+ "snmpInASNParseErrs", 6, 0,
+ NULL, &_snmpInBadCommunityUses_obj
+},
+_snmpInBadTypes_obj = {
+ "snmpInBadTypes", 7, 0,
+ NULL, &_snmpInASNParseErrs_obj
+},
+_snmpInTooBigs_obj = {
+ "snmpInTooBigs", 8, 0,
+ NULL, &_snmpInBadTypes_obj
+},
+_snmpInNoSuchNames_obj = {
+ "snmpInNoSuchNames", 9, 0,
+ NULL, &_snmpInTooBigs_obj
+},
+_snmpInBadValues_obj = {
+ "snmpInBadValues", 10, 0,
+ NULL, &_snmpInNoSuchNames_obj
+},
+_snmpInReadOnlys_obj = {
+ "snmpInReadOnlys", 11, 0,
+ NULL, &_snmpInBadValues_obj
+},
+_snmpInGenErrs_obj = {
+ "snmpInGenErrs", 12, 0,
+ NULL, &_snmpInReadOnlys_obj
+},
+_snmpInTotalReqVars_obj = {
+ "snmpInTotalReqVars", 13, 0,
+ NULL, &_snmpInGenErrs_obj
+},
+_snmpInTotalSetVars_obj = {
+ "snmpInTotalSetVars", 14, 0,
+ NULL, &_snmpInTotalReqVars_obj
+},
+_snmpInGetRequests_obj = {
+ "snmpInGetRequests", 15, 0,
+ NULL, &_snmpInTotalSetVars_obj
+},
+_snmpInGetNexts_obj = {
+ "snmpInGetNexts", 16, 0,
+ NULL, &_snmpInGetRequests_obj
+},
+_snmpInSetRequests_obj = {
+ "snmpInSetRequests", 17, 0,
+ NULL, &_snmpInGetNexts_obj
+},
+_snmpInGetResponses_obj = {
+ "snmpInGetResponses", 18, 0,
+ NULL, &_snmpInSetRequests_obj
+},
+_snmpInTraps_obj = {
+ "snmpInTraps", 19, 0,
+ NULL, &_snmpInGetResponses_obj
+},
+_snmpOutTooBigs_obj = {
+ "snmpOutTooBigs", 20, 0,
+ NULL, &_snmpInTraps_obj
+},
+_snmpOutNoSuchNames_obj = {
+ "snmpOutNoSuchNames", 21, 0,
+ NULL, &_snmpOutTooBigs_obj
+},
+_snmpOutBadValues_obj = {
+ "snmpOutBadValues", 22, 0,
+ NULL, &_snmpOutNoSuchNames_obj
+},
+_snmpOutReadOnlys_obj = {
+ "snmpOutReadOnlys", 23, 0,
+ NULL, &_snmpOutBadValues_obj
+},
+_snmpOutGenErrs_obj = {
+ "snmpOutGenErrs", 24, 0,
+ NULL, &_snmpOutReadOnlys_obj
+},
+_snmpOutGetRequests_obj = {
+ "snmpOutGetRequests", 25, 0,
+ NULL, &_snmpOutGenErrs_obj
+},
+_snmpOutGetNexts_obj = {
+ "snmpOutGetNexts", 26, 0,
+ NULL, &_snmpOutGetRequests_obj
+},
+_snmpOutSetRequests_obj = {
+ "snmpOutSetRequests", 27, 0,
+ NULL, &_snmpOutGetNexts_obj
+},
+_snmpOutGetResponses_obj = {
+ "snmpOutGetResponses", 28, 0,
+ NULL, &_snmpOutSetRequests_obj
+},
+_snmpOutTraps_obj = {
+ "snmpOutTraps", 29, 0,
+ NULL, &_snmpOutGetResponses_obj
+},
+_snmpEnableAuthTraps_obj = {
+ "snmpEnableAuthTraps", 30, 0,
+ NULL, &_snmpOutTraps_obj
+},
+_egpNeighState_obj = {
+ "egpNeighState", 1, 0,
+ NULL, NULL
+},
+_egpNeighAddr_obj = {
+ "egpNeighAddr", 2, 0,
+ NULL, &_egpNeighState_obj
+},
+_egpNeighAs_obj = {
+ "egpNeighAs", 3, 0,
+ NULL, &_egpNeighAddr_obj
+},
+_egpNeighInMsgs_obj = {
+ "egpNeighInMsgs", 4, 0,
+ NULL, &_egpNeighAs_obj
+},
+_egpNeighInErrs_obj = {
+ "egpNeighInErrs", 5, 0,
+ NULL, &_egpNeighInMsgs_obj
+},
+_egpNeighOutMsgs_obj = {
+ "egpNeighOutMsgs", 6, 0,
+ NULL, &_egpNeighInErrs_obj
+},
+_egpNeighOutErrs_obj = {
+ "egpNeighOutErrs", 7, 0,
+ NULL, &_egpNeighOutMsgs_obj
+},
+_egpNeighInErrMsgs_obj = {
+ "egpNeighInErrMsgs", 8, 0,
+ NULL, &_egpNeighOutErrs_obj
+},
+_egpNeighOutErrMsgs_obj = {
+ "egpNeighOutErrMsgs", 9, 0,
+ NULL, &_egpNeighInErrMsgs_obj
+},
+_egpNeighStateUps_obj = {
+ "egpNeighStateUps", 10, 0,
+ NULL, &_egpNeighOutErrMsgs_obj
+},
+_egpNeighStateDowns_obj = {
+ "egpNeighStateDowns", 11, 0,
+ NULL, &_egpNeighStateUps_obj
+},
+_egpNeighIntervalHello_obj = {
+ "egpNeighIntervalHello", 12, 0,
+ NULL, &_egpNeighStateDowns_obj
+},
+_egpNeighIntervalPoll_obj = {
+ "egpNeighIntervalPoll", 13, 0,
+ NULL, &_egpNeighIntervalHello_obj
+},
+_egpNeighMode_obj = {
+ "egpNeighMode", 14, 0,
+ NULL, &_egpNeighIntervalPoll_obj
+},
+_egpNeighEventTrigger_obj = {
+ "egpNeighEventTrigger", 15, 0,
+ NULL, &_egpNeighMode_obj
+},
+_egpNeighEntry_obj = {
+ "egpNeighEntry", 1, 0,
+ &_egpNeighEventTrigger_obj, NULL
+},
+_egpInMsgs_obj = {
+ "egpInMsgs", 1, 0,
+ NULL, NULL
+},
+_egpInErrors_obj = {
+ "egpInErrors", 2, 0,
+ NULL, &_egpInMsgs_obj
+},
+_egpOutMsgs_obj = {
+ "egpOutMsgs", 3, 0,
+ NULL, &_egpInErrors_obj
+},
+_egpOutErrors_obj = {
+ "egpOutErrors", 4, 0,
+ NULL, &_egpOutMsgs_obj
+},
+_egpNeighTable_obj = {
+ "egpNeighTable", 5, 0,
+ &_egpNeighEntry_obj, &_egpOutErrors_obj
+},
+_egpAs_obj = {
+ "egpAs", 6, 0,
+ NULL, &_egpNeighTable_obj
+},
+_udpLocalAddress_obj = {
+ "udpLocalAddress", 1, 0,
+ NULL, NULL
+},
+_udpLocalPort_obj = {
+ "udpLocalPort", 2, 0,
+ NULL, &_udpLocalAddress_obj
+},
+_udpEntry_obj = {
+ "udpEntry", 1, 0,
+ &_udpLocalPort_obj, NULL
+},
+_udpInDatagrams_obj = {
+ "udpInDatagrams", 1, 0,
+ NULL, NULL
+},
+_udpNoPorts_obj = {
+ "udpNoPorts", 2, 0,
+ NULL, &_udpInDatagrams_obj
+},
+_udpInErrors_obj = {
+ "udpInErrors", 3, 0,
+ NULL, &_udpNoPorts_obj
+},
+_udpOutDatagrams_obj = {
+ "udpOutDatagrams", 4, 0,
+ NULL, &_udpInErrors_obj
+},
+_udpTable_obj = {
+ "udpTable", 5, 0,
+ &_udpEntry_obj, &_udpOutDatagrams_obj
+},
+_tcpConnState_obj = {
+ "tcpConnState", 1, 0,
+ NULL, NULL
+},
+_tcpConnLocalAddress_obj = {
+ "tcpConnLocalAddress", 2, 0,
+ NULL, &_tcpConnState_obj
+},
+_tcpConnLocalPort_obj = {
+ "tcpConnLocalPort", 3, 0,
+ NULL, &_tcpConnLocalAddress_obj
+},
+_tcpConnRemAddress_obj = {
+ "tcpConnRemAddress", 4, 0,
+ NULL, &_tcpConnLocalPort_obj
+},
+_tcpConnRemPort_obj = {
+ "tcpConnRemPort", 5, 0,
+ NULL, &_tcpConnRemAddress_obj
+},
+_tcpConnEntry_obj = {
+ "tcpConnEntry", 1, 0,
+ &_tcpConnRemPort_obj, NULL
+},
+_tcpRtoAlgorithm_obj = {
+ "tcpRtoAlgorithm", 1, 0,
+ NULL, NULL
+},
+_tcpRtoMin_obj = {
+ "tcpRtoMin", 2, 0,
+ NULL, &_tcpRtoAlgorithm_obj
+},
+_tcpRtoMax_obj = {
+ "tcpRtoMax", 3, 0,
+ NULL, &_tcpRtoMin_obj
+},
+_tcpMaxConn_obj = {
+ "tcpMaxConn", 4, 0,
+ NULL, &_tcpRtoMax_obj
+},
+_tcpActiveOpens_obj = {
+ "tcpActiveOpens", 5, 0,
+ NULL, &_tcpMaxConn_obj
+},
+_tcpPassiveOpens_obj = {
+ "tcpPassiveOpens", 6, 0,
+ NULL, &_tcpActiveOpens_obj
+},
+_tcpAttemptFails_obj = {
+ "tcpAttemptFails", 7, 0,
+ NULL, &_tcpPassiveOpens_obj
+},
+_tcpEstabResets_obj = {
+ "tcpEstabResets", 8, 0,
+ NULL, &_tcpAttemptFails_obj
+},
+_tcpCurrEstab_obj = {
+ "tcpCurrEstab", 9, 0,
+ NULL, &_tcpEstabResets_obj
+},
+_tcpInSegs_obj = {
+ "tcpInSegs", 10, 0,
+ NULL, &_tcpCurrEstab_obj
+},
+_tcpOutSegs_obj = {
+ "tcpOutSegs", 11, 0,
+ NULL, &_tcpInSegs_obj
+},
+_tcpRetransSegs_obj = {
+ "tcpRetransSegs", 12, 0,
+ NULL, &_tcpOutSegs_obj
+},
+_tcpConnTable_obj = {
+ "tcpConnTable", 13, 0,
+ &_tcpConnEntry_obj, &_tcpRetransSegs_obj
+},
+_tcpInErrs_obj = {
+ "tcpInErrs", 14, 0,
+ NULL, &_tcpConnTable_obj
+},
+_tcpOutRsts_obj = {
+ "tcpOutRsts", 15, 0,
+ NULL, &_tcpInErrs_obj
+},
+_icmpInMsgs_obj = {
+ "icmpInMsgs", 1, 0,
+ NULL, NULL
+},
+_icmpInErrors_obj = {
+ "icmpInErrors", 2, 0,
+ NULL, &_icmpInMsgs_obj
+},
+_icmpInDestUnreachs_obj = {
+ "icmpInDestUnreachs", 3, 0,
+ NULL, &_icmpInErrors_obj
+},
+_icmpInTimeExcds_obj = {
+ "icmpInTimeExcds", 4, 0,
+ NULL, &_icmpInDestUnreachs_obj
+},
+_icmpInParmProbs_obj = {
+ "icmpInParmProbs", 5, 0,
+ NULL, &_icmpInTimeExcds_obj
+},
+_icmpInSrcQuenchs_obj = {
+ "icmpInSrcQuenchs", 6, 0,
+ NULL, &_icmpInParmProbs_obj
+},
+_icmpInRedirects_obj = {
+ "icmpInRedirects", 7, 0,
+ NULL, &_icmpInSrcQuenchs_obj
+},
+_icmpInEchos_obj = {
+ "icmpInEchos", 8, 0,
+ NULL, &_icmpInRedirects_obj
+},
+_icmpInEchoReps_obj = {
+ "icmpInEchoReps", 9, 0,
+ NULL, &_icmpInEchos_obj
+},
+_icmpInTimestamps_obj = {
+ "icmpInTimestamps", 10, 0,
+ NULL, &_icmpInEchoReps_obj
+},
+_icmpInTimestampReps_obj = {
+ "icmpInTimestampReps", 11, 0,
+ NULL, &_icmpInTimestamps_obj
+},
+_icmpInAddrMasks_obj = {
+ "icmpInAddrMasks", 12, 0,
+ NULL, &_icmpInTimestampReps_obj
+},
+_icmpInAddrMaskReps_obj = {
+ "icmpInAddrMaskReps", 13, 0,
+ NULL, &_icmpInAddrMasks_obj
+},
+_icmpOutMsgs_obj = {
+ "icmpOutMsgs", 14, 0,
+ NULL, &_icmpInAddrMaskReps_obj
+},
+_icmpOutErrors_obj = {
+ "icmpOutErrors", 15, 0,
+ NULL, &_icmpOutMsgs_obj
+},
+_icmpOutDestUnreachs_obj = {
+ "icmpOutDestUnreachs", 16, 0,
+ NULL, &_icmpOutErrors_obj
+},
+_icmpOutTimeExcds_obj = {
+ "icmpOutTimeExcds", 17, 0,
+ NULL, &_icmpOutDestUnreachs_obj
+},
+_icmpOutParmProbs_obj = {
+ "icmpOutParmProbs", 18, 0,
+ NULL, &_icmpOutTimeExcds_obj
+},
+_icmpOutSrcQuenchs_obj = {
+ "icmpOutSrcQuenchs", 19, 0,
+ NULL, &_icmpOutParmProbs_obj
+},
+_icmpOutRedirects_obj = {
+ "icmpOutRedirects", 20, 0,
+ NULL, &_icmpOutSrcQuenchs_obj
+},
+_icmpOutEchos_obj = {
+ "icmpOutEchos", 21, 0,
+ NULL, &_icmpOutRedirects_obj
+},
+_icmpOutEchoReps_obj = {
+ "icmpOutEchoReps", 22, 0,
+ NULL, &_icmpOutEchos_obj
+},
+_icmpOutTimestamps_obj = {
+ "icmpOutTimestamps", 23, 0,
+ NULL, &_icmpOutEchoReps_obj
+},
+_icmpOutTimestampReps_obj = {
+ "icmpOutTimestampReps", 24, 0,
+ NULL, &_icmpOutTimestamps_obj
+},
+_icmpOutAddrMasks_obj = {
+ "icmpOutAddrMasks", 25, 0,
+ NULL, &_icmpOutTimestampReps_obj
+},
+_icmpOutAddrMaskReps_obj = {
+ "icmpOutAddrMaskReps", 26, 0,
+ NULL, &_icmpOutAddrMasks_obj
+},
+_ipNetToMediaIfIndex_obj = {
+ "ipNetToMediaIfIndex", 1, 0,
+ NULL, NULL
+},
+_ipNetToMediaPhysAddress_obj = {
+ "ipNetToMediaPhysAddress", 2, 0,
+ NULL, &_ipNetToMediaIfIndex_obj
+},
+_ipNetToMediaNetAddress_obj = {
+ "ipNetToMediaNetAddress", 3, 0,
+ NULL, &_ipNetToMediaPhysAddress_obj
+},
+_ipNetToMediaType_obj = {
+ "ipNetToMediaType", 4, 0,
+ NULL, &_ipNetToMediaNetAddress_obj
+},
+_ipNetToMediaEntry_obj = {
+ "ipNetToMediaEntry", 1, 0,
+ &_ipNetToMediaType_obj, NULL
+},
+_ipRouteDest_obj = {
+ "ipRouteDest", 1, 0,
+ NULL, NULL
+},
+_ipRouteIfIndex_obj = {
+ "ipRouteIfIndex", 2, 0,
+ NULL, &_ipRouteDest_obj
+},
+_ipRouteMetric1_obj = {
+ "ipRouteMetric1", 3, 0,
+ NULL, &_ipRouteIfIndex_obj
+},
+_ipRouteMetric2_obj = {
+ "ipRouteMetric2", 4, 0,
+ NULL, &_ipRouteMetric1_obj
+},
+_ipRouteMetric3_obj = {
+ "ipRouteMetric3", 5, 0,
+ NULL, &_ipRouteMetric2_obj
+},
+_ipRouteMetric4_obj = {
+ "ipRouteMetric4", 6, 0,
+ NULL, &_ipRouteMetric3_obj
+},
+_ipRouteNextHop_obj = {
+ "ipRouteNextHop", 7, 0,
+ NULL, &_ipRouteMetric4_obj
+},
+_ipRouteType_obj = {
+ "ipRouteType", 8, 0,
+ NULL, &_ipRouteNextHop_obj
+},
+_ipRouteProto_obj = {
+ "ipRouteProto", 9, 0,
+ NULL, &_ipRouteType_obj
+},
+_ipRouteAge_obj = {
+ "ipRouteAge", 10, 0,
+ NULL, &_ipRouteProto_obj
+},
+_ipRouteMask_obj = {
+ "ipRouteMask", 11, 0,
+ NULL, &_ipRouteAge_obj
+},
+_ipRouteEntry_obj = {
+ "ipRouteEntry", 1, 0,
+ &_ipRouteMask_obj, NULL
+},
+_ipAdEntAddr_obj = {
+ "ipAdEntAddr", 1, 0,
+ NULL, NULL
+},
+_ipAdEntIfIndex_obj = {
+ "ipAdEntIfIndex", 2, 0,
+ NULL, &_ipAdEntAddr_obj
+},
+_ipAdEntNetMask_obj = {
+ "ipAdEntNetMask", 3, 0,
+ NULL, &_ipAdEntIfIndex_obj
+},
+_ipAdEntBcastAddr_obj = {
+ "ipAdEntBcastAddr", 4, 0,
+ NULL, &_ipAdEntNetMask_obj
+},
+_ipAdEntReasmMaxSize_obj = {
+ "ipAdEntReasmMaxSize", 5, 0,
+ NULL, &_ipAdEntBcastAddr_obj
+},
+_ipAddrEntry_obj = {
+ "ipAddrEntry", 1, 0,
+ &_ipAdEntReasmMaxSize_obj, NULL
+},
+_ipForwarding_obj = {
+ "ipForwarding", 1, 0,
+ NULL, NULL
+},
+_ipDefaultTTL_obj = {
+ "ipDefaultTTL", 2, 0,
+ NULL, &_ipForwarding_obj
+},
+_ipInReceives_obj = {
+ "ipInReceives", 3, 0,
+ NULL, &_ipDefaultTTL_obj
+},
+_ipInHdrErrors_obj = {
+ "ipInHdrErrors", 4, 0,
+ NULL, &_ipInReceives_obj
+},
+_ipInAddrErrors_obj = {
+ "ipInAddrErrors", 5, 0,
+ NULL, &_ipInHdrErrors_obj
+},
+_ipForwDatagrams_obj = {
+ "ipForwDatagrams", 6, 0,
+ NULL, &_ipInAddrErrors_obj
+},
+_ipInUnknownProtos_obj = {
+ "ipInUnknownProtos", 7, 0,
+ NULL, &_ipForwDatagrams_obj
+},
+_ipInDiscards_obj = {
+ "ipInDiscards", 8, 0,
+ NULL, &_ipInUnknownProtos_obj
+},
+_ipInDelivers_obj = {
+ "ipInDelivers", 9, 0,
+ NULL, &_ipInDiscards_obj
+},
+_ipOutRequests_obj = {
+ "ipOutRequests", 10, 0,
+ NULL, &_ipInDelivers_obj
+},
+_ipOutDiscards_obj = {
+ "ipOutDiscards", 11, 0,
+ NULL, &_ipOutRequests_obj
+},
+_ipOutNoRoutes_obj = {
+ "ipOutNoRoutes", 12, 0,
+ NULL, &_ipOutDiscards_obj
+},
+_ipReasmTimeout_obj = {
+ "ipReasmTimeout", 13, 0,
+ NULL, &_ipOutNoRoutes_obj
+},
+_ipReasmReqds_obj = {
+ "ipReasmReqds", 14, 0,
+ NULL, &_ipReasmTimeout_obj
+},
+_ipReasmOKs_obj = {
+ "ipReasmOKs", 15, 0,
+ NULL, &_ipReasmReqds_obj
+},
+_ipReasmFails_obj = {
+ "ipReasmFails", 16, 0,
+ NULL, &_ipReasmOKs_obj
+},
+_ipFragOKs_obj = {
+ "ipFragOKs", 17, 0,
+ NULL, &_ipReasmFails_obj
+},
+_ipFragFails_obj = {
+ "ipFragFails", 18, 0,
+ NULL, &_ipFragOKs_obj
+},
+_ipFragCreates_obj = {
+ "ipFragCreates", 19, 0,
+ NULL, &_ipFragFails_obj
+},
+_ipAddrTable_obj = {
+ "ipAddrTable", 20, 0,
+ &_ipAddrEntry_obj, &_ipFragCreates_obj
+},
+_ipRoutingTable_obj = {
+ "ipRoutingTable", 21, 0,
+ &_ipRouteEntry_obj, &_ipAddrTable_obj
+},
+_ipNetToMediaTable_obj = {
+ "ipNetToMediaTable", 22, 0,
+ &_ipNetToMediaEntry_obj, &_ipRoutingTable_obj
+},
+_atIfIndex_obj = {
+ "atIfIndex", 1, 0,
+ NULL, NULL
+},
+_atPhysAddress_obj = {
+ "atPhysAddress", 2, 0,
+ NULL, &_atIfIndex_obj
+},
+_atNetAddress_obj = {
+ "atNetAddress", 3, 0,
+ NULL, &_atPhysAddress_obj
+},
+_atEntry_obj = {
+ "atEntry", 1, 0,
+ &_atNetAddress_obj, NULL
+},
+_atTable_obj = {
+ "atTable", 1, 0,
+ &_atEntry_obj, NULL
+},
+_ifIndex_obj = {
+ "ifIndex", 1, 0,
+ NULL, NULL
+},
+_ifDescr_obj = {
+ "ifDescr", 2, 0,
+ NULL, &_ifIndex_obj
+},
+_ifType_obj = {
+ "ifType", 3, 0,
+ NULL, &_ifDescr_obj
+},
+_ifMtu_obj = {
+ "ifMtu", 4, 0,
+ NULL, &_ifType_obj
+},
+_ifSpeed_obj = {
+ "ifSpeed", 5, 0,
+ NULL, &_ifMtu_obj
+},
+_ifPhysAddress_obj = {
+ "ifPhysAddress", 6, 0,
+ NULL, &_ifSpeed_obj
+},
+_ifAdminStatus_obj = {
+ "ifAdminStatus", 7, 0,
+ NULL, &_ifPhysAddress_obj
+},
+_ifOperStatus_obj = {
+ "ifOperStatus", 8, 0,
+ NULL, &_ifAdminStatus_obj
+},
+_ifLastChange_obj = {
+ "ifLastChange", 9, 0,
+ NULL, &_ifOperStatus_obj
+},
+_ifInOctets_obj = {
+ "ifInOctets", 10, 0,
+ NULL, &_ifLastChange_obj
+},
+_ifInUcastPkts_obj = {
+ "ifInUcastPkts", 11, 0,
+ NULL, &_ifInOctets_obj
+},
+_ifInNUcastPkts_obj = {
+ "ifInNUcastPkts", 12, 0,
+ NULL, &_ifInUcastPkts_obj
+},
+_ifInDiscards_obj = {
+ "ifInDiscards", 13, 0,
+ NULL, &_ifInNUcastPkts_obj
+},
+_ifInErrors_obj = {
+ "ifInErrors", 14, 0,
+ NULL, &_ifInDiscards_obj
+},
+_ifInUnknownProtos_obj = {
+ "ifInUnknownProtos", 15, 0,
+ NULL, &_ifInErrors_obj
+},
+_ifOutOctets_obj = {
+ "ifOutOctets", 16, 0,
+ NULL, &_ifInUnknownProtos_obj
+},
+_ifOutUcastPkts_obj = {
+ "ifOutUcastPkts", 17, 0,
+ NULL, &_ifOutOctets_obj
+},
+_ifOutNUcastPkts_obj = {
+ "ifOutNUcastPkts", 18, 0,
+ NULL, &_ifOutUcastPkts_obj
+},
+_ifOutDiscards_obj = {
+ "ifOutDiscards", 19, 0,
+ NULL, &_ifOutNUcastPkts_obj
+},
+_ifOutErrors_obj = {
+ "ifOutErrors", 20, 0,
+ NULL, &_ifOutDiscards_obj
+},
+_ifOutQLen_obj = {
+ "ifOutQLen", 21, 0,
+ NULL, &_ifOutErrors_obj
+},
+_ifSpecific_obj = {
+ "ifSpecific", 22, 0,
+ NULL, &_ifOutQLen_obj
+},
+_ifEntry_obj = {
+ "ifEntry", 1, 0,
+ &_ifSpecific_obj, NULL
+},
+_ifNumber_obj = {
+ "ifNumber", 1, 0,
+ NULL, NULL
+},
+_ifTable_obj = {
+ "ifTable", 2, 0,
+ &_ifEntry_obj, &_ifNumber_obj
+},
+_sysDescr_obj = {
+ "sysDescr", 1, 0,
+ NULL, NULL
+},
+_sysObjectID_obj = {
+ "sysObjectID", 2, 0,
+ NULL, &_sysDescr_obj
+},
+_sysUpTime_obj = {
+ "sysUpTime", 3, 0,
+ NULL, &_sysObjectID_obj
+},
+_sysContact_obj = {
+ "sysContact", 4, 0,
+ NULL, &_sysUpTime_obj
+},
+_sysName_obj = {
+ "sysName", 5, 0,
+ NULL, &_sysContact_obj
+},
+_sysLocation_obj = {
+ "sysLocation", 6, 0,
+ NULL, &_sysName_obj
+},
+_sysServices_obj = {
+ "sysServices", 7, 0,
+ NULL, &_sysLocation_obj
+},
+_system_obj = {
+ "system", 1, 0,
+ &_sysServices_obj, NULL
+},
+_interfaces_obj = {
+ "interfaces", 2, 0,
+ &_ifTable_obj, &_system_obj
+},
+_at_obj = {
+ "at", 3, 0,
+ &_atTable_obj, &_interfaces_obj
+},
+_ip_obj = {
+ "ip", 4, 0,
+ &_ipNetToMediaTable_obj, &_at_obj
+},
+_icmp_obj = {
+ "icmp", 5, 0,
+ &_icmpOutAddrMaskReps_obj, &_ip_obj
+},
+_tcp_obj = {
+ "tcp", 6, 0,
+ &_tcpOutRsts_obj, &_icmp_obj
+},
+_udp_obj = {
+ "udp", 7, 0,
+ &_udpTable_obj, &_tcp_obj
+},
+_egp_obj = {
+ "egp", 8, 0,
+ &_egpAs_obj, &_udp_obj
+},
+_transmission_obj = {
+ "transmission", 10, 0,
+ NULL, &_egp_obj
+},
+_snmp_obj = {
+ "snmp", 11, 0,
+ &_snmpEnableAuthTraps_obj, &_transmission_obj
+},
+_mib_obj = {
+ "mib", 1, 0,
+ &_snmp_obj, NULL
+},
+_directory_obj = {
+ "directory", 1, 0,
+ NULL, NULL
+},
+_mgmt_obj = {
+ "mgmt", 2, 0,
+ &_mib_obj, &_directory_obj
+},
+_experimental_obj = {
+ "experimental", 3, 0,
+ NULL, &_mgmt_obj
+},
+_private_obj = {
+ "private", 4, 0,
+ &_enterprises_obj, &_experimental_obj
+},
+_internet_obj = {
+ "internet", 1, 0,
+ &_private_obj, NULL
+},
+_dod_obj = {
+ "dod", 6, 0,
+ &_internet_obj, NULL
+},
+_org_obj = {
+ "org", 3, 0,
+ &_dod_obj, NULL
+},
+_iso_obj = {
+ "iso", 1, 0,
+ &_org_obj, NULL
+},
+*mibroot = &_iso_obj;
diff --git a/usr.sbin/tcpdump/nfsfh.h b/usr.sbin/tcpdump/nfsfh.h
new file mode 100644
index 00000000000..5d6ff780203
--- /dev/null
+++ b/usr.sbin/tcpdump/nfsfh.h
@@ -0,0 +1,36 @@
+/* $NetBSD: nfsfh.h,v 1.2 1995/03/06 19:10:39 mycroft Exp $ */
+
+/*
+ * Header: nfsfh.h,v 1.3 94/06/12 14:32:58 leres Exp
+ *
+ * nfsfh.h - NFS file handle definitions (for portable use)
+ *
+ * Jeffrey C. Mogul
+ * Digital Equipment Corporation
+ * Western Research Laboratory
+ */
+
+/*
+ * Internal representation of dev_t, because different NFS servers
+ * that we might be spying upon use different external representations.
+ */
+typedef struct {
+ u_long Minor; /* upper case to avoid clashing with macro names */
+ u_long Major;
+} my_devt;
+
+#define dev_eq(a,b) ((a.Minor == b.Minor) && (a.Major == b.Major))
+
+/*
+ * Many file servers now use a large file system ID. This is
+ * our internal representation of that.
+ */
+typedef struct {
+ my_devt fsid_dev;
+ u_long fsid_code;
+} my_fsid;
+
+#define fsid_eq(a,b) ((a.fsid_code == b.fsid_code) &&\
+ dev_eq(a.fsid_dev, b.fsid_dev))
+
+extern void Parse_fh(caddr_t *, my_fsid *, ino_t *, char **, char **, int);
diff --git a/usr.sbin/tcpdump/nfsv2.h b/usr.sbin/tcpdump/nfsv2.h
new file mode 100644
index 00000000000..e8cdba97dca
--- /dev/null
+++ b/usr.sbin/tcpdump/nfsv2.h
@@ -0,0 +1,262 @@
+/* $NetBSD: nfsv2.h,v 1.2 1995/03/06 19:10:40 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)nfsv2.h 7.11 (Berkeley) 9/30/92
+ */
+
+/*
+ * nfs definitions as per the version 2 specs
+ */
+
+/*
+ * Constants as defined in the Sun NFS Version 2 spec.
+ * "NFS: Network File System Protocol Specification" RFC1094
+ */
+
+#define NFS_PORT 2049
+#define NFS_PROG 100003
+#define NFS_VER2 2
+#define NFS_MAXDGRAMDATA 8192
+#define NFS_MAXDATA 32768
+#define NFS_MAXPATHLEN 1024
+#define NFS_MAXNAMLEN 255
+#define NFS_FHSIZE 32
+#define NFS_MAXPKTHDR 404
+#define NFS_MAXPACKET (NFS_MAXPKTHDR+NFS_MAXDATA)
+#define NFS_MINPACKET 20
+#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */
+
+/* Stat numbers for rpc returns */
+#define NFS_OK 0
+#define NFSERR_PERM 1
+#define NFSERR_NOENT 2
+#define NFSERR_IO 5
+#define NFSERR_NXIO 6
+#define NFSERR_ACCES 13
+#define NFSERR_EXIST 17
+#define NFSERR_NODEV 19
+#define NFSERR_NOTDIR 20
+#define NFSERR_ISDIR 21
+#define NFSERR_FBIG 27
+#define NFSERR_NOSPC 28
+#define NFSERR_ROFS 30
+#define NFSERR_NAMETOL 63
+#define NFSERR_NOTEMPTY 66
+#define NFSERR_DQUOT 69
+#define NFSERR_STALE 70
+#define NFSERR_WFLUSH 99
+
+/* Sizes in bytes of various nfs rpc components */
+#define NFSX_FH 32
+#define NFSX_UNSIGNED 4
+#define NFSX_NFSFATTR 68
+#define NFSX_NQFATTR 92
+#define NFSX_NFSSATTR 32
+#define NFSX_NQSATTR 44
+#define NFSX_COOKIE 4
+#define NFSX_NFSSTATFS 20
+#define NFSX_NQSTATFS 28
+#define NFSX_FATTR(isnq) ((isnq) ? NFSX_NQFATTR : NFSX_NFSFATTR)
+#define NFSX_SATTR(isnq) ((isnq) ? NFSX_NQSATTR : NFSX_NFSSATTR)
+#define NFSX_STATFS(isnq) ((isnq) ? NFSX_NQSTATFS : NFSX_NFSSTATFS)
+
+/* nfs rpc procedure numbers */
+#define NFSPROC_NULL 0
+#define NFSPROC_GETATTR 1
+#define NFSPROC_SETATTR 2
+#define NFSPROC_NOOP 3
+#define NFSPROC_ROOT NFSPROC_NOOP /* Obsolete */
+#define NFSPROC_LOOKUP 4
+#define NFSPROC_READLINK 5
+#define NFSPROC_READ 6
+#define NFSPROC_WRITECACHE NFSPROC_NOOP /* Obsolete */
+#define NFSPROC_WRITE 8
+#define NFSPROC_CREATE 9
+#define NFSPROC_REMOVE 10
+#define NFSPROC_RENAME 11
+#define NFSPROC_LINK 12
+#define NFSPROC_SYMLINK 13
+#define NFSPROC_MKDIR 14
+#define NFSPROC_RMDIR 15
+#define NFSPROC_READDIR 16
+#define NFSPROC_STATFS 17
+
+/* NQ nfs numbers */
+#define NQNFSPROC_READDIRLOOK 18
+#define NQNFSPROC_GETLEASE 19
+#define NQNFSPROC_VACATED 20
+#define NQNFSPROC_EVICTED 21
+#define NQNFSPROC_ACCESS 22
+
+#define NFS_NPROCS 23
+/* Conversion macros */
+extern int vttoif_tab[];
+#define vtonfs_mode(t,m) \
+ txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \
+ MAKEIMODE((t), (m)))
+#define nfstov_mode(a) (fxdr_unsigned(u_short, (a))&07777)
+#define vtonfs_type(a) txdr_unsigned(nfs_type[((long)(a))])
+#define nfstov_type(a) ntov_type[fxdr_unsigned(u_long,(a))&0x7]
+
+/* File types */
+typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5 } nfstype;
+
+/* Structs for common parts of the rpc's */
+struct nfsv2_time {
+ u_long nfs_sec;
+ u_long nfs_usec;
+};
+
+struct nqnfs_time {
+ u_long nq_sec;
+ u_long nq_nsec;
+};
+
+/*
+ * File attributes and setable attributes. These structures cover both
+ * NFS version 2 and the NQNFS protocol. Note that the union is only
+ * used to that one pointer can refer to both variants. These structures
+ * go out on the wire and must be densely packed, so no quad data types
+ * are used. (all fields are longs or u_longs or structures of same)
+ * NB: You can't do sizeof(struct nfsv2_fattr), you must use the
+ * NFSX_FATTR(isnq) macro.
+ */
+struct nfsv2_fattr {
+ u_long fa_type;
+ u_long fa_mode;
+ u_long fa_nlink;
+ u_long fa_uid;
+ u_long fa_gid;
+ union {
+ struct {
+ u_long nfsfa_size;
+ u_long nfsfa_blocksize;
+ u_long nfsfa_rdev;
+ u_long nfsfa_blocks;
+ u_long nfsfa_fsid;
+ u_long nfsfa_fileid;
+ struct nfsv2_time nfsfa_atime;
+ struct nfsv2_time nfsfa_mtime;
+ struct nfsv2_time nfsfa_ctime;
+ } fa_nfsv2;
+ struct {
+ struct {
+ u_long nqfa_qsize[2];
+ } nqfa_size;
+ u_long nqfa_blocksize;
+ u_long nqfa_rdev;
+ struct {
+ u_long nqfa_qbytes[2];
+ } nqfa_bytes;
+ u_long nqfa_fsid;
+ u_long nqfa_fileid;
+ struct nqnfs_time nqfa_atime;
+ struct nqnfs_time nqfa_mtime;
+ struct nqnfs_time nqfa_ctime;
+ u_long nqfa_flags;
+ u_long nqfa_gen;
+ struct {
+ u_long nqfa_qfilerev[2];
+ } nqfa_filerev;
+ } fa_nqnfs;
+ } fa_un;
+};
+
+/* and some ugly defines for accessing union components */
+#define fa_nfssize fa_un.fa_nfsv2.nfsfa_size
+#define fa_nfsblocksize fa_un.fa_nfsv2.nfsfa_blocksize
+#define fa_nfsrdev fa_un.fa_nfsv2.nfsfa_rdev
+#define fa_nfsblocks fa_un.fa_nfsv2.nfsfa_blocks
+#define fa_nfsfsid fa_un.fa_nfsv2.nfsfa_fsid
+#define fa_nfsfileid fa_un.fa_nfsv2.nfsfa_fileid
+#define fa_nfsatime fa_un.fa_nfsv2.nfsfa_atime
+#define fa_nfsmtime fa_un.fa_nfsv2.nfsfa_mtime
+#define fa_nfsctime fa_un.fa_nfsv2.nfsfa_ctime
+#define fa_nqsize fa_un.fa_nqnfs.nqfa_size
+#define fa_nqblocksize fa_un.fa_nqnfs.nqfa_blocksize
+#define fa_nqrdev fa_un.fa_nqnfs.nqfa_rdev
+#define fa_nqbytes fa_un.fa_nqnfs.nqfa_bytes
+#define fa_nqfsid fa_un.fa_nqnfs.nqfa_fsid
+#define fa_nqfileid fa_un.fa_nqnfs.nqfa_fileid
+#define fa_nqatime fa_un.fa_nqnfs.nqfa_atime
+#define fa_nqmtime fa_un.fa_nqnfs.nqfa_mtime
+#define fa_nqctime fa_un.fa_nqnfs.nqfa_ctime
+#define fa_nqflags fa_un.fa_nqnfs.nqfa_flags
+#define fa_nqgen fa_un.fa_nqnfs.nqfa_gen
+#define fa_nqfilerev fa_un.fa_nqnfs.nqfa_filerev
+
+struct nfsv2_sattr {
+ u_long sa_mode;
+ u_long sa_uid;
+ u_long sa_gid;
+ union {
+ struct {
+ u_long nfssa_size;
+ struct nfsv2_time nfssa_atime;
+ struct nfsv2_time nfssa_mtime;
+ } sa_nfsv2;
+ struct {
+ struct {
+ u_long nqsa_qsize[2];
+ } nqsa_size;
+ struct nqnfs_time nqsa_atime;
+ struct nqnfs_time nqsa_mtime;
+ u_long nqsa_flags;
+ u_long nqsa_rdev;
+ } sa_nqnfs;
+ } sa_un;
+};
+
+/* and some ugly defines for accessing the unions */
+#define sa_nfssize sa_un.sa_nfsv2.nfssa_size
+#define sa_nfsatime sa_un.sa_nfsv2.nfssa_atime
+#define sa_nfsmtime sa_un.sa_nfsv2.nfssa_mtime
+#define sa_nqsize sa_un.sa_nqnfs.nqsa_size
+#define sa_nqatime sa_un.sa_nqnfs.nqsa_atime
+#define sa_nqmtime sa_un.sa_nqnfs.nqsa_mtime
+#define sa_nqflags sa_un.sa_nqnfs.nqsa_flags
+#define sa_nqrdev sa_un.sa_nqnfs.nqsa_rdev
+
+struct nfsv2_statfs {
+ u_long sf_tsize;
+ u_long sf_bsize;
+ u_long sf_blocks;
+ u_long sf_bfree;
+ u_long sf_bavail;
+ u_long sf_files; /* Nqnfs only */
+ u_long sf_ffree; /* ditto */
+};
diff --git a/usr.sbin/tcpdump/ntp.h b/usr.sbin/tcpdump/ntp.h
new file mode 100644
index 00000000000..7443ce6e80c
--- /dev/null
+++ b/usr.sbin/tcpdump/ntp.h
@@ -0,0 +1,119 @@
+/* $NetBSD: ntp.h,v 1.2 1995/03/06 19:10:41 mycroft Exp $ */
+
+/* Header: ntp.h,v 1.2 93/11/12 21:43:36 mccanne Exp */
+
+/*
+ * Based on ntp.h from the U of MD implementation
+ * This file is based on Version 2 of the NTP spec (RFC1119).
+ */
+
+/*
+ * Definitions for the masses
+ */
+#define JAN_1970 2208988800 /* 1970 - 1900 in seconds */
+
+/*
+ * Structure definitions for NTP fixed point values
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Integer Part |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Fraction Part |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Integer Part | Fraction Part |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+struct l_fixedpt {
+ u_int32 int_part;
+ u_int32 fraction;
+};
+
+struct s_fixedpt {
+ u_short int_part;
+ u_short fraction;
+};
+
+/* ================= Table 3.3. Packet Variables ================= */
+/*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |LI | VN | Mode| Stratum | Poll | Precision |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Synchronizing Distance |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Synchronizing Dispersion |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reference Clock Identifier |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Reference Timestamp (64 bits) |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Originate Timestamp (64 bits) |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Receive Timestamp (64 bits) |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Transmit Timestamp (64 bits) |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+struct ntpdata {
+ u_char status; /* status of local clock and leap info */
+ u_char stratum; /* Stratum level */
+ u_char ppoll; /* poll value */
+ int precision:8;
+ struct s_fixedpt distance;
+ struct s_fixedpt dispersion;
+ u_int32 refid;
+ struct l_fixedpt reftime;
+ struct l_fixedpt org;
+ struct l_fixedpt rec;
+ struct l_fixedpt xmt;
+};
+/*
+ * Leap Second Codes (high order two bits)
+ */
+#define NO_WARNING 0x00 /* no warning */
+#define PLUS_SEC 0x40 /* add a second (61 seconds) */
+#define MINUS_SEC 0x80 /* minus a second (59 seconds) */
+#define ALARM 0xc0 /* alarm condition (clock unsynchronized) */
+
+/*
+ * Clock Status Bits that Encode Version
+ */
+#define NTPVERSION_1 0x08
+#define VERSIONMASK 0x38
+#define LEAPMASK 0xc0
+#define MODEMASK 0x07
+
+/*
+ * Code values
+ */
+#define MODE_UNSPEC 0 /* unspecified */
+#define MODE_SYM_ACT 1 /* symmetric active */
+#define MODE_SYM_PAS 2 /* symmetric passive */
+#define MODE_CLIENT 3 /* client */
+#define MODE_SERVER 4 /* server */
+#define MODE_BROADCAST 5 /* broadcast */
+#define MODE_RES1 6 /* reserved */
+#define MODE_RES2 7 /* reserved */
+
+/*
+ * Stratum Definitions
+ */
+#define UNSPECIFIED 0
+#define PRIM_REF 1 /* radio clock */
+#define INFO_QUERY 62 /* **** THIS implementation dependent **** */
+#define INFO_REPLY 63 /* **** THIS implementation dependent **** */
diff --git a/usr.sbin/tcpdump/os.h b/usr.sbin/tcpdump/os.h
new file mode 100644
index 00000000000..9f807522041
--- /dev/null
+++ b/usr.sbin/tcpdump/os.h
@@ -0,0 +1,62 @@
+/* $NetBSD: os.h,v 1.2 1995/03/06 19:10:56 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) Header: os-bsd.h,v 1.18 94/06/14 20:15:17 leres Exp (LBL)
+ */
+
+#include <sys/param.h>
+
+#ifndef BSD
+#define BSD
+#endif
+
+#define SHA(ap) ((ap)->arp_sha)
+#define SPA(ap) ((ap)->arp_spa)
+#define THA(ap) ((ap)->arp_tha)
+#define TPA(ap) ((ap)->arp_tpa)
+
+#define EDST(ep) ((ep)->ether_dhost)
+#define ESRC(ep) ((ep)->ether_shost)
+
+#ifndef ETHERTYPE_REVARP
+#define ETHERTYPE_REVARP 0x8035
+#endif
+
+#ifndef IPPROTO_ND
+/* From <netinet/in.h> on a Sun somewhere. */
+#define IPPROTO_ND 77
+#endif
+
+#ifndef REVARP_REQUEST
+#define REVARP_REQUEST 3
+#endif
+#ifndef REVARP_REPLY
+#define REVARP_REPLY 4
+#endif
+
+/* newish RIP commands */
+#ifndef RIPCMD_POLL
+#define RIPCMD_POLL 5
+#endif
+#ifndef RIPCMD_POLLENTRY
+#define RIPCMD_POLLENTRY 6
+#endif
diff --git a/usr.sbin/tcpdump/ospf.h b/usr.sbin/tcpdump/ospf.h
new file mode 100644
index 00000000000..3a6d2b5632f
--- /dev/null
+++ b/usr.sbin/tcpdump/ospf.h
@@ -0,0 +1,225 @@
+/* $NetBSD: ospf.h,v 1.2 1995/03/06 19:10:57 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
+ */
+#define OSPF_TYPE_UMD 0 /* UMd's special monitoring packets */
+#define OSPF_TYPE_HELLO 1 /* Hello */
+#define OSPF_TYPE_DB 2 /* Database Description */
+#define OSPF_TYPE_LSR 3 /* Link State Request */
+#define OSPF_TYPE_LSU 4 /* Link State Update */
+#define OSPF_TYPE_LSA 5 /* Link State Ack */
+#define OSPF_TYPE_MAX 6
+
+/* Options *_options */
+#define OSPF_OPTION_T 0x01 /* T bit: TOS support */
+#define OSPF_OPTION_E 0x02 /* E bit: External routes advertised */
+#define OSPF_OPTION_MC 0x04 /* MC bit: Multicast capable */
+
+/* ospf_authtype */
+#define OSPF_AUTH_NONE 0 /* No auth-data */
+#define OSPF_AUTH_SIMPLE 1 /* Simple password */
+
+/* db_flags */
+#define OSPF_DB_INIT 0x04 /* */
+#define OSPF_DB_MORE 0x02
+#define OSPF_DB_MASTER 0x01
+
+/* ls_type */
+#define LS_TYPE_ROUTER 1 /* router link */
+#define LS_TYPE_NETWORK 2 /* network link */
+#define LS_TYPE_SUM_IP 3 /* summary link */
+#define LS_TYPE_SUM_ABR 4 /* summary area link */
+#define LS_TYPE_ASE 5 /* ASE */
+#define LS_TYPE_GROUP 6 /* Group membership (multicast */
+ /* extensions 23 July 1991) */
+#define LS_TYPE_MAX 7
+
+/*************************************************
+ *
+ * is the above a bug in the documentation?
+ *
+ *************************************************/
+
+
+/* rla_link.link_type */
+#define RLA_TYPE_ROUTER 1 /* point-to-point to another router */
+#define RLA_TYPE_TRANSIT 2 /* connection to transit network */
+#define RLA_TYPE_STUB 3 /* connection to stub network */
+#define RLA_TYPE_VIRTUAL 4 /* virtual link */
+
+/* rla_flags */
+#define RLA_FLAG_B 0x01
+#define RLA_FLAG_E 0x02
+#define RLA_FLAG_W1 0x04
+#define RLA_FLAG_W2 0x08
+
+/* sla_tosmetric breakdown */
+#define SLA_MASK_TOS 0x7f000000
+#define SLA_MASK_METRIC 0x00ffffff
+#define SLA_SHIFT_TOS 24
+
+/* asla_tosmetric breakdown */
+#define ASLA_FLAG_EXTERNAL 0x80000000
+#define ASLA_MASK_TOS 0x7f000000
+#define ASLA_SHIFT_TOS 24
+#define ASLA_MASK_METRIC 0x00ffffff
+
+/* multicast vertex type */
+#define MCLA_VERTEX_ROUTER 1
+#define MCLA_VERTEX_NETWORK 2
+
+/* link state advertisement header */
+struct lsa_hdr {
+ u_short ls_age;
+ u_char ls_options;
+ u_char ls_type;
+ struct in_addr ls_stateid;
+ struct in_addr ls_router;
+ u_int32 ls_seq;
+ u_short ls_chksum;
+ u_short ls_length;
+} ;
+
+/* link state advertisement */
+struct lsa {
+ struct lsa_hdr ls_hdr;
+
+ /* Link state types */
+ union {
+ /* Router links advertisements */
+ struct {
+ u_char rla_flags;
+ u_char rla_zero[1];
+ u_short rla_count;
+ struct rlalink {
+ struct in_addr link_id;
+ struct in_addr link_data;
+ u_char link_type;
+ u_char link_toscount;
+ u_short link_tos0metric;
+ } rla_link[1]; /* may repeat */
+ } un_rla;
+
+ /* Network links advertisements */
+ struct {
+ struct in_addr nla_mask;
+ struct in_addr nla_router[1]; /* may repeat */
+ } un_nla;
+
+ /* Summary links advertisements */
+ struct {
+ struct in_addr sla_mask;
+ u_int32 sla_tosmetric[1]; /* may repeat */
+ } un_sla;
+
+ /* AS external links advertisements */
+ struct {
+ struct in_addr asla_mask;
+ struct aslametric {
+ u_int32 asla_tosmetric;
+ struct in_addr asla_forward;
+ struct in_addr asla_tag;
+ } asla_metric[1]; /* may repeat */
+ } un_asla;
+
+ /* Multicast group membership */
+ struct mcla {
+ u_int32 mcla_vtype;
+ struct in_addr mcla_vid;
+ } un_mcla[1];
+ } lsa_un;
+} ;
+
+
+/*
+ * TOS metric struct (will be 0 or more in router links update)
+ */
+struct tos_metric {
+ u_char tos_type;
+ u_char tos_zero;
+ u_short tos_metric;
+} ;
+
+#define OSPF_AUTH_SIZE 8
+
+/*
+ * the main header
+ */
+struct ospfhdr {
+ u_char ospf_version;
+ u_char ospf_type;
+ u_short ospf_len;
+ struct in_addr ospf_routerid;
+ struct in_addr ospf_areaid;
+ u_short ospf_chksum;
+ u_short ospf_authtype;
+ u_char ospf_authdata[OSPF_AUTH_SIZE];
+ union {
+
+ /* Hello packet */
+ struct {
+ struct in_addr hello_mask;
+ u_short hello_helloint;
+ u_char hello_options;
+ u_char hello_priority;
+ u_int32 hello_deadint;
+ struct in_addr hello_dr;
+ struct in_addr hello_bdr;
+ struct in_addr hello_neighbor[1]; /* may repeat */
+ } un_hello;
+
+ /* Database Description packet */
+ struct {
+ u_char db_zero[2];
+ u_char db_options;
+ u_char db_flags;
+ u_int32 db_seq;
+ struct lsa_hdr db_lshdr[1]; /* may repeat */
+ } un_db;
+
+ /* Link State Request */
+ struct lsr {
+ u_int32 ls_type;
+ struct in_addr ls_stateid;
+ struct in_addr ls_router;
+ } un_lsr[1]; /* may repeat */
+
+ /* Link State Update */
+ struct {
+ u_int32 lsu_count;
+ struct lsa lsu_lsa[1]; /* may repeat */
+ } un_lsu;
+
+ /* Link State Acknowledment */
+ struct {
+ struct lsa_hdr lsa_lshdr[1]; /* may repeat */
+ } un_lsa ;
+ } ospf_un ;
+} ;
+
+#define ospf_hello ospf_un.un_hello
+#define ospf_db ospf_un.un_db
+#define ospf_lsr ospf_un.un_lsr
+#define ospf_lsu ospf_un.un_lsu
+#define ospf_lsa ospf_un.un_lsa
+
diff --git a/usr.sbin/tcpdump/packetdat.awk b/usr.sbin/tcpdump/packetdat.awk
new file mode 100644
index 00000000000..97746525f46
--- /dev/null
+++ b/usr.sbin/tcpdump/packetdat.awk
@@ -0,0 +1,63 @@
+# $NetBSD: packetdat.awk,v 1.2 1995/03/06 19:10:59 mycroft Exp $
+
+BEGIN {
+ # we need to know (usual) packet size to convert byte numbers
+ # to packet numbers
+ if (packetsize <= 0)
+ packetsize = 512
+ }
+$5 !~ /[SR]/ {
+ # print out per-packet data in the form:
+ # <packet #>
+ # <start sequence #>
+ # <1st send time>
+ # <last send time>
+ # <1st ack time>
+ # <last ack time>
+ # <# sends>
+ # <# acks>
+
+ n = split ($1,t,":")
+ tim = t[1]*3600 + t[2]*60 + t[3]
+ if ($6 != "ack") {
+ i = index($6,":")
+ strtSeq = substr($6,1,i-1)
+ id = 1.5 + (strtSeq - 1) / packetsize
+ id -= id % 1
+ if (maxId < id)
+ maxId = id
+ if (firstSend[id] == 0) {
+ firstSend[id] = tim
+ seqNo[id] = strtSeq
+ }
+ lastSend[id] = tim
+ timesSent[id]++
+ totalPackets++
+ } else {
+ id = 1 + ($7 - 2) / packetsize
+ id -= id % 1
+ timesAcked[id]++
+ if (firstAck[id] == 0)
+ firstAck[id] = tim
+ lastAck[id] = tim
+ totalAcks++
+ }
+ }
+END {
+ print "# " maxId " chunks. " totalPackets " packets sent. " \
+ totalAcks " acks."
+ # for packets that were implicitly acked, make the ack time
+ # be the ack time of next explicitly acked packet.
+ for (i = maxId-1; i > 0; --i)
+ while (i > 0 && firstAck[i] == 0) {
+ lastAck[i] = firstAck[i] = firstAck[i+1]
+ --i
+ }
+ tzero = firstSend[1]
+ for (i = 1; i <= maxId; i++)
+ printf "%d\t%d\t%.2f\t%.2f\t%.2f\t%.2f\t%d\t%d\n",\
+ i, seqNo[i], \
+ firstSend[i] - tzero, lastSend[i] - tzero,\
+ firstAck[i] - tzero, lastAck[i] - tzero,\
+ timesSent[i], timesAcked[i]
+ }
diff --git a/usr.sbin/tcpdump/parsenfsfh.c b/usr.sbin/tcpdump/parsenfsfh.c
new file mode 100644
index 00000000000..bff083088d9
--- /dev/null
+++ b/usr.sbin/tcpdump/parsenfsfh.c
@@ -0,0 +1,427 @@
+/* $NetBSD: parsenfsfh.c,v 1.2 1995/03/06 19:11:00 mycroft Exp $ */
+
+#ifndef lint
+static char *RCSid = "Header: parsenfsfh.c,v 1.5 94/01/13 19:06:41 leres Exp";
+#endif
+
+/*
+ * parsenfsfh.c - portable parser for NFS file handles
+ * uses all sorts of heuristics
+ *
+ * Jeffrey C. Mogul
+ * Digital Equipment Corporation
+ * Western Research Laboratory
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "interface.h"
+#include "nfsfh.h"
+
+/*
+ * Make sure that we use 32-bit integers when necessary. The "x"
+ * suffix is to avoid possible identifier conflicts.
+ */
+
+typedef int int32x;
+typedef unsigned int u_int32x;
+
+/*
+ * This routine attempts to parse a file handle (in network byte order),
+ * using heuristics to guess what kind of format it is in. See the
+ * file "fhandle_layouts" for a detailed description of the various
+ * patterns we know about.
+ *
+ * The file handle is parsed into our internal representation of a
+ * file-system id, and an internal representation of an inode-number.
+ */
+
+#define FHT_UNKNOWN 0
+#define FHT_AUSPEX 1
+#define FHT_DECOSF 2
+#define FHT_IRIX4 3
+#define FHT_IRIX5 4
+#define FHT_SUNOS3 5
+#define FHT_SUNOS4 6
+#define FHT_ULTRIX 7
+#define FHT_VMSUCX 8
+#define FHT_SUNOS5 9
+#define FHT_AIX32 10
+#define FHT_HPUX9 11
+
+#ifdef ultrix
+/* Nasty hack to keep the Ultrix C compiler from emitting bogus warnings */
+#define XFF(x) ((unsigned long)(x))
+#else
+#define XFF(x) (x)
+#endif
+
+#define make_uint32(msb,b,c,lsb)\
+ (XFF(lsb) + (XFF(c)<<8) + (XFF(b)<<16) + (XFF(msb)<<24))
+
+#define make_uint24(msb,b, lsb)\
+ (XFF(lsb) + (XFF(b)<<8) + (XFF(msb)<<16))
+
+#define make_uint16(msb,lsb)\
+ (XFF(lsb) + (XFF(msb)<<8))
+
+#ifdef __alpha
+ /* or other 64-bit systems */
+#define make_uint48(msb,b,c,d,e,lsb)\
+ ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24) + ((b)<<32) + ((msb)<<40))
+#else
+ /* on 32-bit systems ignore high-order bits */
+#define make_uint48(msb,b,c,d,e,lsb)\
+ ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24))
+#endif
+
+static int is_UCX(unsigned char *);
+
+void
+Parse_fh(fh, fsidp, inop, osnamep, fsnamep, ourself)
+register caddr_t *fh;
+my_fsid *fsidp;
+ino_t *inop;
+char **osnamep; /* if non-NULL, return OS name here */
+char **fsnamep; /* if non-NULL, return server fs name here (for VMS) */
+int ourself; /* true if file handle was generated on this host */
+{
+ register unsigned char *fhp = (unsigned char *)fh;
+ u_int32x temp;
+ int fhtype = FHT_UNKNOWN;
+
+ if (ourself) {
+ /* File handle generated on this host, no need for guessing */
+#if defined(IRIX40)
+ fhtype = FHT_IRIX4;
+#endif
+#if defined(IRIX50)
+ fhtype = FHT_IRIX5;
+#endif
+#if defined(IRIX51)
+ fhtype = FHT_IRIX5;
+#endif
+#if defined(SUNOS4)
+ fhtype = FHT_SUNOS4;
+#endif
+#if defined(SUNOS5)
+ fhtype = FHT_SUNOS5;
+#endif
+#if defined(ultrix)
+ fhtype = FHT_ULTRIX;
+#endif
+#if defined(__osf__)
+ fhtype = FHT_DECOSF;
+#endif
+ }
+ /*
+ * This is basically a big decision tree
+ */
+ else if ((fhp[0] == 0) && (fhp[1] == 0)) {
+ /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */
+ /* probably rules out HP-UX, AIX unless they allow major=0 */
+ if ((fhp[2] == 0) && (fhp[3] == 0)) {
+ /* bytes[2,3] == (0,0); must be Auspex */
+ /* XXX or could be Ultrix+MASSBUS "hp" disk? */
+ fhtype = FHT_AUSPEX;
+ }
+ else {
+ /*
+ * bytes[2,3] != (0,0); rules out Auspex, could be
+ * DECOSF, SUNOS4, or IRIX4
+ */
+ if ((fhp[4] != 0) && (fhp[5] == 0) &&
+ (fhp[8] == 12) && (fhp[9] == 0)) {
+ /* seems to be DECOSF, with minor == 0 */
+ fhtype = FHT_DECOSF;
+ }
+ else {
+ /* could be SUNOS4 or IRIX4 */
+ /* XXX the test of fhp[5] == 8 could be wrong */
+ if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) &&
+ (fhp[7] == 0)) {
+ /* looks like a length, not a file system typecode */
+ fhtype = FHT_IRIX4;
+ }
+ else {
+ /* by elimination */
+ fhtype = FHT_SUNOS4;
+ }
+ }
+ }
+ }
+ else {
+ /*
+ * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4
+ * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5
+ * could be AIX, HP-UX
+ */
+ if ((fhp[2] == 0) && (fhp[3] == 0)) {
+ /*
+ * bytes[2,3] == (0,0); rules out OSF, probably not UCX
+ * (unless the exported device name is just one letter!),
+ * could be Ultrix, IRIX5, AIX, or SUNOS5
+ * might be HP-UX (depends on their values for minor devs)
+ */
+ /*XXX we probably only need to test of these two bytes */
+ if ((fhp[21] == 0) && (fhp[23] == 0)) {
+ fhtype = FHT_ULTRIX;
+ }
+ else {
+ /* Could be SUNOS5/IRIX5, maybe AIX */
+ /* XXX no obvious difference between SUNOS5 and IRIX5 */
+ if (fhp[9] == 10)
+ fhtype = FHT_SUNOS5;
+ /* XXX what about AIX? */
+ }
+ }
+ else {
+ /*
+ * bytes[2,3] != (0,0); rules out Ultrix, could be
+ * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX
+ */
+ if ((fhp[8] == 12) && (fhp[9] == 0)) {
+ fhtype = FHT_DECOSF;
+ }
+ else if ((fhp[8] == 0) && (fhp[9] == 10)) {
+ /* could be SUNOS5/IRIX5, AIX, HP-UX */
+ if ((fhp[7] == 0) && (fhp[6] == 0) &&
+ (fhp[5] == 0) && (fhp[4] == 0)) {
+ /* XXX is this always true of HP-UX? */
+ fhtype = FHT_HPUX9;
+ }
+ else if (fhp[7] == 2) {
+ /* This would be MNT_NFS on AIX, which is impossible */
+ fhtype = FHT_SUNOS5; /* or maybe IRIX5 */
+ }
+ else {
+ /*
+ * XXX Could be SUNOS5/IRIX5 or AIX. I don't
+ * XXX see any way to disambiguate these, so
+ * XXX I'm going with the more likely guess.
+ * XXX Sorry, Big Blue.
+ */
+ fhtype = FHT_SUNOS5; /* or maybe IRIX5 */
+ }
+ }
+ else {
+ if (is_UCX(fhp)) {
+ fhtype = FHT_VMSUCX;
+ }
+ else {
+ fhtype = FHT_UNKNOWN;
+ }
+ }
+ }
+ }
+
+ /* XXX still needs to handle SUNOS3 */
+
+ switch (fhtype) {
+ case FHT_AUSPEX:
+ fsidp->fsid_dev.Minor = fhp[7];
+ fsidp->fsid_dev.Major = fhp[6];
+ fsidp->fsid_code = 0;
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "Auspex";
+ break;
+
+ case FHT_DECOSF:
+ fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]);
+ /* XXX could ignore 3 high-order bytes */
+
+ temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]);
+ fsidp->fsid_dev.Minor = temp & 0xFFFFF;
+ fsidp->fsid_dev.Major = (temp>>20) & 0xFFF;
+
+ temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]);
+ *inop = temp;
+ if (osnamep)
+ *osnamep = "OSF";
+ break;
+
+ case FHT_IRIX4:
+ fsidp->fsid_dev.Minor = fhp[3];
+ fsidp->fsid_dev.Major = fhp[2];
+ fsidp->fsid_code = 0;
+
+ temp = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "IRIX4";
+ break;
+
+ case FHT_IRIX5:
+ fsidp->fsid_dev.Minor = make_uint16(fhp[2], fhp[3]);
+ fsidp->fsid_dev.Major = make_uint16(fhp[0], fhp[1]);
+ fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "IRIX5";
+ break;
+
+ case FHT_SUNOS3:
+ if (osnamep)
+ *osnamep = "SUNOS3";
+ break;
+
+ case FHT_SUNOS4:
+ fsidp->fsid_dev.Minor = fhp[3];
+ fsidp->fsid_dev.Major = fhp[2];
+ fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "SUNOS4";
+ break;
+
+ case FHT_SUNOS5:
+ temp = make_uint16(fhp[0], fhp[1]);
+ fsidp->fsid_dev.Major = (temp>>2) & 0x3FFF;
+ temp = make_uint24(fhp[1], fhp[2], fhp[3]);
+ fsidp->fsid_dev.Minor = temp & 0x3FFFF;
+ fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "SUNOS5";
+ break;
+
+ case FHT_ULTRIX:
+ fsidp->fsid_code = 0;
+ fsidp->fsid_dev.Minor = fhp[0];
+ fsidp->fsid_dev.Major = fhp[1];
+
+ temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]);
+ *inop = temp;
+ if (osnamep)
+ *osnamep = "Ultrix";
+ break;
+
+ case FHT_VMSUCX:
+ /* No numeric file system ID, so hash on the device-name */
+ if (sizeof(*fsidp) >= 14) {
+ if (sizeof(*fsidp) > 14)
+ bzero((char *)fsidp, sizeof(*fsidp));
+ bcopy(fh, (char *)fsidp, 14); /* just use the whole thing */
+ }
+ else {
+ u_long tempa[4]; /* at least 16 bytes, maybe more */
+
+ bzero((char *)tempa, sizeof(tempa));
+ bcopy(fh, (char *)tempa, 14); /* ensure alignment */
+ fsidp->fsid_dev.Minor = tempa[0] + (tempa[1]<<1);
+ fsidp->fsid_dev.Major = tempa[2] + (tempa[3]<<1);
+ fsidp->fsid_code = 0;
+ }
+
+ /* VMS file ID is: (RVN, FidHi, FidLo) */
+ *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]);
+
+ /* Caller must save (and null-terminate?) this value */
+ if (fsnamep)
+ *fsnamep = (char *)&(fhp[1]);
+
+ if (osnamep)
+ *osnamep = "VMS";
+ break;
+
+ case FHT_AIX32:
+ fsidp->fsid_dev.Minor = make_uint16(fhp[2], fhp[3]);
+ fsidp->fsid_dev.Major = make_uint16(fhp[0], fhp[1]);
+ fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "AIX32";
+ break;
+
+ case FHT_HPUX9:
+ fsidp->fsid_dev.Major = fhp[0];
+ temp = make_uint24(fhp[1], fhp[2], fhp[3]);
+ fsidp->fsid_dev.Minor = temp;
+ fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "HPUX9";
+ break;
+
+ case FHT_UNKNOWN:
+#ifdef DEBUG
+ {
+ /* XXX debugging */
+ int i;
+ for (i=0; i<32;i++) fprintf(stderr, "%x.", fhp[i]);
+ fprintf(stderr, "\n");
+ }
+#endif
+ /* XXX for now, give "bogus" values to aid debugging */
+ fsidp->fsid_code = 0;
+ fsidp->fsid_dev.Minor = 257;
+ fsidp->fsid_dev.Major = 257;
+ *inop = 1;
+
+ /* display will show this string instead of (257,257) */
+ if (fsnamep)
+ *fsnamep = "Unknown";
+
+ if (osnamep)
+ *osnamep = "Unknown";
+ break;
+
+ }
+}
+
+/*
+ * Is this a VMS UCX file handle?
+ * Check for:
+ * (1) leading code byte [XXX not yet]
+ * (2) followed by string of printing chars & spaces
+ * (3) followed by string of nulls
+ */
+static int
+is_UCX(fhp)
+unsigned char *fhp;
+{
+ register int i;
+ int seen_null = 0;
+
+ for (i = 1; i < 14; i++) {
+ if (isprint(fhp[i])) {
+ if (seen_null)
+ return(0);
+ else
+ continue;
+ }
+ else if (fhp[i] == 0) {
+ seen_null = 1;
+ continue;
+ }
+ else
+ return(0);
+ }
+
+ return(1);
+}
diff --git a/usr.sbin/tcpdump/print-arp.c b/usr.sbin/tcpdump/print-arp.c
new file mode 100644
index 00000000000..f9636a66282
--- /dev/null
+++ b/usr.sbin/tcpdump/print-arp.c
@@ -0,0 +1,123 @@
+/* $NetBSD: print-arp.c,v 1.2 1995/03/06 19:11:02 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-arp.c,v 1.28 94/06/14 20:17:36 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+static u_char ezero[6];
+
+void
+arp_print(register const u_char *bp, int length, int caplen)
+{
+ register const struct ether_arp *ap;
+ register const struct ether_header *eh;
+ const u_char *p;
+ int pro, hrd, op;
+
+ ap = (struct ether_arp *)bp;
+ if ((u_char *)(ap + 1) > snapend) {
+ printf("[|arp]");
+ return;
+ }
+ if (length < sizeof(struct ether_arp)) {
+ (void)printf("truncated-arp");
+ default_print((u_char *)ap, length);
+ return;
+ }
+ /*
+ * Don't assume alignment.
+ */
+ p = (u_char*)&ap->arp_pro;
+ pro = (p[0] << 8) | p[1];
+ p = (u_char*)&ap->arp_hrd;
+ hrd = (p[0] << 8) | p[1];
+ p = (u_char*)&ap->arp_op;
+ op = (p[0] << 8) | p[1];
+
+ if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
+ || ap->arp_hln != sizeof(SHA(ap))
+ || ap->arp_pln != sizeof(SPA(ap))) {
+ (void)printf("arp-#%d for proto #%d (%d) hardware #%d (%d)",
+ op, pro, ap->arp_pln,
+ hrd, ap->arp_hln);
+ return;
+ }
+ if (pro == ETHERTYPE_TRAIL)
+ (void)printf("trailer-");
+ eh = (struct ether_header *)packetp;
+ switch (op) {
+
+ case ARPOP_REQUEST:
+ (void)printf("arp who-has %s", ipaddr_string(TPA(ap)));
+ if (bcmp((char *)ezero, (char *)THA(ap), 6) != 0)
+ (void)printf(" (%s)", etheraddr_string(THA(ap)));
+ (void)printf(" tell %s", ipaddr_string(SPA(ap)));
+ if (bcmp((char *)ESRC(eh), (char *)SHA(ap), 6) != 0)
+ (void)printf(" (%s)", etheraddr_string(SHA(ap)));
+ break;
+
+ case ARPOP_REPLY:
+ (void)printf("arp reply %s", ipaddr_string(SPA(ap)));
+ if (bcmp((char *)ESRC(eh), (char *)SHA(ap), 6) != 0)
+ (void)printf(" (%s)", etheraddr_string(SHA(ap)));
+ (void)printf(" is-at %s", etheraddr_string(SHA(ap)));
+ if (bcmp((char *)EDST(eh), (char *)THA(ap), 6) != 0)
+ (void)printf(" (%s)", etheraddr_string(THA(ap)));
+ break;
+
+ case REVARP_REQUEST:
+ (void)printf("rarp who-is %s tell %s",
+ etheraddr_string(THA(ap)),
+ etheraddr_string(SHA(ap)));
+ break;
+
+ case REVARP_REPLY:
+ (void)printf("rarp reply %s at %s",
+ etheraddr_string(THA(ap)),
+ ipaddr_string(TPA(ap)));
+ break;
+
+ default:
+ (void)printf("arp-#%d", op);
+ default_print((u_char *)ap, caplen);
+ return;
+ }
+ if (hrd != ARPHRD_ETHER)
+ printf(" hardware #%d", ap->arp_hrd);
+}
diff --git a/usr.sbin/tcpdump/print-atalk.c b/usr.sbin/tcpdump/print-atalk.c
new file mode 100644
index 00000000000..89807fa7257
--- /dev/null
+++ b/usr.sbin/tcpdump/print-atalk.c
@@ -0,0 +1,573 @@
+/* $NetBSD: print-atalk.c,v 1.3 1995/03/06 19:11:04 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print AppleTalk packets.
+ */
+#ifndef lint
+static char rcsid[] =
+ "@(#)Header: print-atalk.c,v 1.36 94/06/20 19:44:34 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "extract.h" /* must come after interface.h */
+#include "appletalk.h"
+
+static struct token type2str[] = {
+ { ddpRTMP, "rtmp" },
+ { ddpRTMPrequest, "rtmpReq" },
+ { ddpECHO, "echo" },
+ { ddpIP, "IP" },
+ { ddpARP, "ARP" },
+ { ddpKLAP, "KLAP" },
+ { 0, NULL }
+};
+
+struct aarp {
+ u_short htype, ptype;
+ u_char halen, palen;
+ u_short op;
+ u_char hsaddr[6];
+ u_char psaddr[4];
+ u_char hdaddr[6];
+ u_char pdaddr[4];
+};
+
+static char tstr[] = "[|atalk]";
+
+static void atp_print(const struct atATP *, int);
+static void atp_bitmap_print(u_char);
+static void nbp_print(const struct atNBP *, int, u_short, u_char, u_char);
+static const char *print_cstring(const char *, const u_char *);
+static const struct atNBPtuple *nbp_tuple_print(const struct atNBPtuple *,
+ const u_char *,
+ u_short, u_char, u_char);
+static const struct atNBPtuple *nbp_name_print(const struct atNBPtuple *,
+ const u_char *);
+static const char *ataddr_string(u_short, u_char);
+static void ddp_print(const u_char *, int, int, u_short, u_char, u_char);
+static const char *ddpskt_string(int);
+
+/*
+ * Print AppleTalk Datagram Delivery Protocol packets.
+ */
+void
+atalk_print(register const u_char *bp, int length)
+{
+ register const struct LAP *lp;
+ register const struct atDDP *dp;
+ register const struct atShortDDP *sdp;
+ u_short snet;
+
+ lp = (struct LAP *)bp;
+ bp += sizeof(*lp);
+ length -= sizeof(*lp);
+ switch (lp->type) {
+
+ case lapShortDDP:
+ if (length < ddpSSize) {
+ (void)printf(" [|sddp %d]", length);
+ return;
+ }
+ sdp = (const struct atShortDDP *)bp;
+ printf("%s.%s",
+ ataddr_string(0, lp->src), ddpskt_string(sdp->srcSkt));
+ printf(" > %s.%s:",
+ ataddr_string(0, lp->dst), ddpskt_string(sdp->dstSkt));
+ bp += ddpSSize;
+ length -= ddpSSize;
+ ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt);
+ break;
+
+ case lapDDP:
+ if (length < ddpSize) {
+ (void)printf(" [|ddp %d]", length);
+ return;
+ }
+ dp = (const struct atDDP *)bp;
+ snet = EXTRACT_SHORT(&dp->srcNet);
+ printf("%s.%s", ataddr_string(snet, dp->srcNode),
+ ddpskt_string(dp->srcSkt));
+ printf(" > %s.%s:",
+ ataddr_string(EXTRACT_SHORT(&dp->dstNet), dp->dstNode),
+ ddpskt_string(dp->dstSkt));
+ bp += ddpSize;
+ length -= ddpSize;
+ ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
+ break;
+
+#ifdef notdef
+ case lapKLAP:
+ klap_print(bp, length);
+ break;
+#endif
+
+ default:
+ printf("%d > %d at-lap#%d %d",
+ lp->src, lp->dst, lp->type, length);
+ break;
+ }
+}
+
+/* XXX should probably pass in the snap header and do checks like arp_print() */
+void
+aarp_print(register const u_char *bp, int length)
+{
+ register const struct aarp *ap;
+
+#define AT(member) ataddr_string((ap->member[1]<<8)|ap->member[2],ap->member[3])
+
+ printf("aarp ");
+ ap = (const struct aarp *)bp;
+ if (ap->htype == 1 && ap->ptype == ETHERTYPE_ATALK &&
+ ap->halen == 6 && ap->palen == 4 )
+ switch (ap->op) {
+
+ case 1: /* request */
+ (void)printf("who-has %s tell %s",
+ AT(pdaddr), AT(psaddr));
+ return;
+
+ case 2: /* response */
+ (void)printf("reply %s is-at %s",
+ AT(pdaddr), etheraddr_string(ap->hdaddr));
+ return;
+
+ case 3: /* probe (oy!) */
+ (void)printf("probe %s tell %s",
+ AT(pdaddr), AT(psaddr));
+ return;
+ }
+ (void)printf("len %d op %d htype %d ptype %#x halen %d palen %d",
+ length, ap->op, ap->htype, ap->ptype, ap->halen, ap->palen );
+}
+
+static void
+ddp_print(register const u_char *bp, register int length, register int t,
+ register u_short snet, register u_char snode, u_char skt)
+{
+
+ switch (t) {
+
+ case ddpNBP:
+ nbp_print((const struct atNBP *)bp, length, snet, snode, skt);
+ break;
+
+ case ddpATP:
+ atp_print((const struct atATP *)bp, length);
+ break;
+
+ default:
+ (void)printf(" at-%s %d", tok2str(type2str, NULL, t), length);
+ break;
+ }
+}
+
+static void
+atp_print(register const struct atATP *ap, int length)
+{
+ char c;
+ u_int32 data;
+
+ if ((const u_char *)(ap + 1) > snapend) {
+ /* Just bail if we don't have the whole chunk. */
+ fputs(tstr, stdout);
+ return;
+ }
+ length -= sizeof(*ap);
+ switch (ap->control & 0xc0) {
+
+ case atpReqCode:
+ (void)printf(" atp-req%s %d",
+ ap->control & atpXO? " " : "*",
+ EXTRACT_SHORT(&ap->transID));
+
+ atp_bitmap_print(ap->bitmap);
+
+ if (length != 0)
+ (void)printf(" [len=%d]", length);
+
+ switch (ap->control & (atpEOM|atpSTS)) {
+ case atpEOM:
+ (void)printf(" [EOM]");
+ break;
+ case atpSTS:
+ (void)printf(" [STS]");
+ break;
+ case atpEOM|atpSTS:
+ (void)printf(" [EOM,STS]");
+ break;
+ }
+ break;
+
+ case atpRspCode:
+ (void)printf(" atp-resp%s%d:%d (%d)",
+ ap->control & atpEOM? "*" : " ",
+ EXTRACT_SHORT(&ap->transID), ap->bitmap, length);
+ switch (ap->control & (atpXO|atpSTS)) {
+ case atpXO:
+ (void)printf(" [XO]");
+ break;
+ case atpSTS:
+ (void)printf(" [STS]");
+ break;
+ case atpXO|atpSTS:
+ (void)printf(" [XO,STS]");
+ break;
+ }
+ break;
+
+ case atpRelCode:
+ (void)printf(" atp-rel %d", EXTRACT_SHORT(&ap->transID));
+
+ atp_bitmap_print(ap->bitmap);
+
+ /* length should be zero */
+ if (length)
+ (void)printf(" [len=%d]", length);
+
+ /* there shouldn't be any control flags */
+ if (ap->control & (atpXO|atpEOM|atpSTS)) {
+ c = '[';
+ if (ap->control & atpXO) {
+ (void)printf("%cXO", c);
+ c = ',';
+ }
+ if (ap->control & atpEOM) {
+ (void)printf("%cEOM", c);
+ c = ',';
+ }
+ if (ap->control & atpSTS) {
+ (void)printf("%cSTS", c);
+ c = ',';
+ }
+ (void)printf("]");
+ }
+ break;
+
+ default:
+ (void)printf(" atp-0x%x %d (%d)", ap->control,
+ EXTRACT_SHORT(&ap->transID), length);
+ break;
+ }
+ data = EXTRACT_LONG(&ap->userData);
+ if (data != 0)
+ (void)printf(" 0x%x", data);
+}
+
+static void
+atp_bitmap_print(register u_char bm)
+{
+ register char c;
+ register int i;
+
+ /*
+ * The '& 0xff' below is needed for compilers that want to sign
+ * extend a u_char, which is the case with the Ultrix compiler.
+ * (gcc is smart enough to eliminate it, at least on the Sparc).
+ */
+ if ((bm + 1) & (bm & 0xff)) {
+ c = '<';
+ for (i = 0; bm; ++i) {
+ if (bm & 1) {
+ (void)printf("%c%d", c, i);
+ c = ',';
+ }
+ bm >>= 1;
+ }
+ (void)printf(">");
+ } else {
+ for (i = 0; bm; ++i)
+ bm >>= 1;
+ if (i > 1)
+ (void)printf("<0-%d>", i - 1);
+ else
+ (void)printf("<0>");
+ }
+}
+
+static void
+nbp_print(register const struct atNBP *np, int length, register u_short snet,
+ register u_char snode, register u_char skt)
+{
+ register const struct atNBPtuple *tp =
+ (struct atNBPtuple *)((u_char *)np + nbpHeaderSize);
+ int i = length;
+ const u_char *ep;
+
+ length -= nbpHeaderSize;
+ if (length < 8) {
+ /* must be room for at least one tuple */
+ (void)printf(" truncated-nbp %d", length + nbpHeaderSize);
+ return;
+ }
+ /* ep points to end of available data */
+ ep = snapend;
+ if ((const u_char *)tp > ep) {
+ fputs(tstr, stdout);
+ return;
+ }
+ switch (i = np->control & 0xf0) {
+
+ case nbpBrRq:
+ case nbpLkUp:
+ (void)printf(i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:",
+ np->id);
+ if ((const u_char *)(tp + 1) > ep) {
+ fputs(tstr, stdout);
+ return;
+ }
+ (void)nbp_name_print(tp, ep);
+ /*
+ * look for anomalies: the spec says there can only
+ * be one tuple, the address must match the source
+ * address and the enumerator should be zero.
+ */
+ if ((np->control & 0xf) != 1)
+ (void)printf(" [ntup=%d]", np->control & 0xf);
+ if (tp->enumerator)
+ (void)printf(" [enum=%d]", tp->enumerator);
+ if (EXTRACT_SHORT(&tp->net) != snet ||
+ tp->node != snode || tp->skt != skt)
+ (void)printf(" [addr=%s.%d]",
+ ataddr_string(EXTRACT_SHORT(&tp->net),
+ tp->node), tp->skt);
+ break;
+
+ case nbpLkUpReply:
+ (void)printf(" nbp-reply %d:", np->id);
+
+ /* print each of the tuples in the reply */
+ for (i = np->control & 0xf; --i >= 0 && tp; )
+ tp = nbp_tuple_print(tp, ep, snet, snode, skt);
+ break;
+
+ default:
+ (void)printf(" nbp-0x%x %d (%d)", np->control, np->id,
+ length);
+ break;
+ }
+}
+
+/* print a counted string */
+static const char *
+print_cstring(register const char *cp, register const u_char *ep)
+{
+ register int length;
+
+ if (cp >= (const char *)ep) {
+ fputs(tstr, stdout);
+ return (0);
+ }
+ length = *cp++;
+
+ /* Spec says string can be at most 32 bytes long */
+ if (length < 0 || length > 32) {
+ (void)printf("[len=%d]", length);
+ return (0);
+ }
+ while (--length >= 0) {
+ if (cp >= (char *)ep) {
+ fputs(tstr, stdout);
+ return (0);
+ }
+ putchar(*cp++);
+ }
+ return (cp);
+}
+
+static const struct atNBPtuple *
+nbp_tuple_print(register const struct atNBPtuple *tp,
+ register const u_char *ep,
+ register u_short snet, register u_char snode,
+ register u_char skt)
+{
+ register const struct atNBPtuple *tpn;
+
+ if ((const u_char *)(tp + 1) > ep) {
+ fputs(tstr, stdout);
+ return 0;
+ }
+ tpn = nbp_name_print(tp, ep);
+
+ /* if the enumerator isn't 1, print it */
+ if (tp->enumerator != 1)
+ (void)printf("(%d)", tp->enumerator);
+
+ /* if the socket doesn't match the src socket, print it */
+ if (tp->skt != skt)
+ (void)printf(" %d", tp->skt);
+
+ /* if the address doesn't match the src address, it's an anomaly */
+ if (EXTRACT_SHORT(&tp->net) != snet || tp->node != snode)
+ (void)printf(" [addr=%s]",
+ ataddr_string(EXTRACT_SHORT(&tp->net), tp->node));
+
+ return (tpn);
+}
+
+static const struct atNBPtuple *
+nbp_name_print(const struct atNBPtuple *tp, register const u_char *ep)
+{
+ register const char *cp = (const char *)tp + nbpTupleSize;
+
+ putchar(' ');
+
+ /* Object */
+ putchar('"');
+ if ((cp = print_cstring(cp, ep)) != NULL) {
+ /* Type */
+ putchar(':');
+ if ((cp = print_cstring(cp, ep)) != NULL) {
+ /* Zone */
+ putchar('@');
+ if ((cp = print_cstring(cp, ep)) != NULL)
+ putchar('"');
+ }
+ }
+ return ((const struct atNBPtuple *)cp);
+}
+
+
+#define HASHNAMESIZE 4096
+
+struct hnamemem {
+ int addr;
+ char *name;
+ struct hnamemem *nxt;
+};
+
+static struct hnamemem hnametable[HASHNAMESIZE];
+
+static const char *
+ataddr_string(u_short atnet, u_char athost)
+{
+ register struct hnamemem *tp, *tp2;
+ register int i = (atnet << 8) | athost;
+ char nambuf[256];
+ static int first = 1;
+ FILE *fp;
+
+ /*
+ * if this is the first call, see if there's an AppleTalk
+ * number to name map file.
+ */
+ if (first && (first = 0, !nflag)
+ && (fp = fopen("/etc/atalk.names", "r"))) {
+ char line[256];
+ int i1, i2, i3;
+
+ while (fgets(line, sizeof(line), fp)) {
+ if (line[0] == '\n' || line[0] == 0 || line[0] == '#')
+ continue;
+ if (sscanf(line, "%d.%d.%d %s", &i1, &i2, &i3,
+ nambuf) == 4)
+ /* got a hostname. */
+ i3 |= ((i1 << 8) | i2) << 8;
+ else if (sscanf(line, "%d.%d %s", &i1, &i2,
+ nambuf) == 3)
+ /* got a net name */
+ i3 = (((i1 << 8) | i2) << 8) | 255;
+ else
+ continue;
+
+ for (tp = &hnametable[i3 & (HASHNAMESIZE-1)];
+ tp->nxt; tp = tp->nxt)
+ ;
+ tp->addr = i3;
+ tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
+ tp->name = savestr(nambuf);
+ }
+ fclose(fp);
+ }
+
+ for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ /* didn't have the node name -- see if we've got the net name */
+ i |= 255;
+ for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt)
+ if (tp2->addr == i) {
+ tp->addr = (atnet << 8) | athost;
+ tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
+ (void)sprintf(nambuf, "%s.%d", tp2->name, athost);
+ tp->name = savestr(nambuf);
+ return (tp->name);
+ }
+
+ tp->addr = (atnet << 8) | athost;
+ tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
+ if (athost != 255)
+ (void)sprintf(nambuf, "%d.%d.%d",
+ atnet >> 8, atnet & 0xff, athost);
+ else
+ (void)sprintf(nambuf, "%d.%d", atnet >> 8, atnet & 0xff);
+ i = strlen(nambuf) + 1;
+ tp->name = strcpy(malloc((u_int) i), nambuf);
+
+ return (tp->name);
+}
+
+static struct token skt2str[] = {
+ { rtmpSkt, "rtmp" }, /* routing table maintenance */
+ { nbpSkt, "nis" }, /* name info socket */
+ { echoSkt, "echo" }, /* AppleTalk echo protocol */
+ { zipSkt, "zip" }, /* zone info protocol */
+ { 0, NULL }
+};
+
+static const char *
+ddpskt_string(register int skt)
+{
+ static char buf[8];
+
+ if (nflag) {
+ (void)sprintf(buf, "%d", skt);
+ return (buf);
+ }
+ return (tok2str(skt2str, "%d", skt));
+}
diff --git a/usr.sbin/tcpdump/print-bootp.c b/usr.sbin/tcpdump/print-bootp.c
new file mode 100644
index 00000000000..2e641419222
--- /dev/null
+++ b/usr.sbin/tcpdump/print-bootp.c
@@ -0,0 +1,359 @@
+/* $NetBSD: print-bootp.c,v 1.2 1995/03/06 19:11:05 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print bootp packets.
+ */
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-bootp.c,v 1.30 94/06/14 20:17:37 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <ctype.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "bootp.h"
+
+static void rfc1048_print(const u_char *, int);
+static void cmu_print(const u_char *, int);
+
+static char tstr[] = " [|bootp]";
+
+/*
+ * Print bootp requests
+ */
+void
+bootp_print(register const u_char *cp, int length,
+ u_short sport, u_short dport)
+{
+ register const struct bootp *bp;
+ static u_char vm_cmu[4] = VM_CMU;
+ static u_char vm_rfc1048[4] = VM_RFC1048;
+ const u_char *ep;
+
+#define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc
+
+ bp = (struct bootp *)cp;
+ /* 'ep' points to the end of avaible data. */
+ ep = snapend;
+
+ TCHECK(bp->bp_op, sizeof(bp->bp_op));
+ switch (bp->bp_op) {
+
+ case BOOTREQUEST:
+ /* Usually, a request goes from a client to a server */
+ if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS)
+ printf(" (request)");
+ break;
+
+ case BOOTREPLY:
+ /* Usually, a reply goes from a server to a client */
+ if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC)
+ printf(" (reply)");
+ break;
+
+ default:
+ printf(" bootp-#%d", bp->bp_op);
+ }
+
+ TCHECK(bp->bp_secs, sizeof(bp->bp_secs));
+
+ /* The usual hardware address type is 1 (10Mb Ethernet) */
+ if (bp->bp_htype != 1)
+ printf(" htype-#%d", bp->bp_htype);
+
+ /* The usual length for 10Mb Ethernet address is 6 bytes */
+ if (bp->bp_htype != 1 || bp->bp_hlen != 6)
+ printf(" hlen:%d", bp->bp_hlen);
+
+ /* Only print interesting fields */
+ if (bp->bp_hops)
+ printf(" hops:%d", bp->bp_hops);
+ if (bp->bp_xid)
+ printf(" xid:0x%x", ntohl(bp->bp_xid));
+ if (bp->bp_secs)
+ printf(" secs:%d", ntohs(bp->bp_secs));
+
+ /* Client's ip address */
+ TCHECK(bp->bp_ciaddr, sizeof(bp->bp_ciaddr));
+ if (bp->bp_ciaddr.s_addr)
+ printf(" C:%s", ipaddr_string(&bp->bp_ciaddr));
+
+ /* 'your' ip address (bootp client) */
+ TCHECK(bp->bp_yiaddr, sizeof(bp->bp_yiaddr));
+ if (bp->bp_yiaddr.s_addr)
+ printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr));
+
+ /* Server's ip address */
+ TCHECK(bp->bp_siaddr, sizeof(bp->bp_siaddr));
+ if (bp->bp_siaddr.s_addr)
+ printf(" S:%s", ipaddr_string(&bp->bp_siaddr));
+
+ /* Gateway's ip address */
+ TCHECK(bp->bp_giaddr, sizeof(bp->bp_giaddr));
+ if (bp->bp_giaddr.s_addr)
+ printf(" G:%s", ipaddr_string(&bp->bp_giaddr));
+
+ /* Client's Ethernet address */
+ if (bp->bp_htype == 1 && bp->bp_hlen == 6) {
+ register const struct ether_header *eh;
+ register const char *e;
+
+ TCHECK(bp->bp_chaddr[0], 6);
+ eh = (struct ether_header *)packetp;
+ if (bp->bp_op == BOOTREQUEST)
+ e = (const char *)ESRC(eh);
+ else if (bp->bp_op == BOOTREPLY)
+ e = (const char *)EDST(eh);
+ else
+ e = 0;
+ if (e == 0 || bcmp((char *)bp->bp_chaddr, e, 6) != 0)
+ printf(" ether %s", etheraddr_string(bp->bp_chaddr));
+ }
+
+ TCHECK(bp->bp_sname[0], 1); /* check first char only */
+ if (*bp->bp_sname) {
+ printf(" sname ");
+ if (fn_print(bp->bp_sname, ep)) {
+ fputs(tstr + 1, stdout);
+ return;
+ }
+ }
+ TCHECK(bp->bp_sname[0], 1); /* check first char only */
+ if (*bp->bp_file) {
+ printf(" file ");
+ if (fn_print(bp->bp_file, ep)) {
+ fputs(tstr + 1, stdout);
+ return;
+ }
+ }
+
+ /* Decode the vendor buffer */
+ TCHECK(bp->bp_vend[0], sizeof(bp->bp_vend));
+ length -= sizeof(*bp) - sizeof(bp->bp_vend);
+ if (bcmp((char *)bp->bp_vend, (char *)vm_rfc1048,
+ sizeof(u_int32)) == 0)
+ rfc1048_print(bp->bp_vend, length);
+ else if (bcmp((char *)bp->bp_vend, (char *)vm_cmu,
+ sizeof(u_int32)) == 0)
+ cmu_print(bp->bp_vend, length);
+ else {
+ u_int32 ul;
+
+ bcopy((char *)bp->bp_vend, (char *)&ul, sizeof(ul));
+ if (ul != 0)
+ printf("vend-#0x%x", ul);
+ }
+
+ return;
+trunc:
+ fputs(tstr, stdout);
+#undef TCHECK
+}
+
+/* The first character specifies the format to print */
+static struct token tag2str[] = {
+/* RFC1048 tags */
+ { TAG_PAD, " PAD" },
+ { TAG_SUBNET_MASK, "iSM" }, /* subnet mask (RFC950) */
+ { TAG_TIME_OFFSET, "lTZ" }, /* seconds from UTC */
+ { TAG_GATEWAY, "iDG" }, /* default gateway */
+ { TAG_TIME_SERVER, "iTS" }, /* time servers (RFC868) */
+ { TAG_NAME_SERVER, "iIEN" }, /* IEN name servers (IEN116) */
+ { TAG_DOMAIN_SERVER, "iNS" }, /* domain name (RFC1035) */
+ { TAG_LOG_SERVER, "iLOG" }, /* MIT log servers */
+ { TAG_COOKIE_SERVER, "iCS" }, /* cookie servers (RFC865) */
+ { TAG_LPR_SERVER, "iLPR" }, /* lpr server (RFC1179) */
+ { TAG_IMPRESS_SERVER, "iIM" }, /* impress servers (Imagen) */
+ { TAG_RLP_SERVER, "iRL" }, /* resource location (RFC887) */
+ { TAG_HOSTNAME, "aHN" }, /* ascii hostname */
+ { TAG_BOOTSIZE, "sBS" }, /* 512 byte blocks */
+ { TAG_END, " END" },
+/* RFC1497 tags */
+ { TAG_DUMPPATH, "aDP" },
+ { TAG_DOMAINNAME, "aDN" },
+ { TAG_SWAP_SERVER, "iSS" },
+ { TAG_ROOTPATH, "aRP" },
+ { TAG_EXTPATH, "aEP" },
+ { 0, NULL }
+};
+
+static void
+rfc1048_print(register const u_char *bp, register int length)
+{
+ register u_char tag;
+ register const u_char *ep;
+ register u_int len, size;
+ register const char *cp;
+ register char c;
+ int first;
+ u_int32 ul;
+ u_short us;
+
+ printf(" vend-rfc1048");
+
+ /* Setup end pointer */
+ ep = bp + length;
+
+ /* Step over magic cookie */
+ bp += sizeof(int32);
+
+ /* Loop while we there is a tag left in the buffer */
+ while (bp + 1 < ep) {
+ tag = *bp++;
+ if (tag == TAG_PAD)
+ continue;
+ if (tag == TAG_END)
+ return;
+ cp = tok2str(tag2str, "?T%d", tag);
+ c = *cp++;
+ printf(" %s:", cp);
+
+ /* Get the length; check for truncation */
+ if (bp + 1 >= ep) {
+ fputs(tstr, stdout);
+ return;
+ }
+ len = *bp++;
+ if (bp + len >= ep) {
+ fputs(tstr, stdout);
+ return;
+ }
+
+ /* Print data */
+ size = len;
+ if (c == '?') {
+ /* Base default formats for unknown tags on data size */
+ if (size & 1)
+ c = 'b';
+ else if (size & 2)
+ c = 's';
+ else
+ c = 'l';
+ }
+ first = 1;
+ switch (c) {
+
+ case 'a':
+ /* ascii strings */
+ (void)fn_printn(bp, size, NULL);
+ bp += size;
+ size = 0;
+ break;
+
+ case 'i':
+ case 'l':
+ /* ip addresses/32-bit words */
+ while (size >= sizeof(ul)) {
+ if (!first)
+ putchar(',');
+ bcopy((char *)bp, (char *)&ul, sizeof(ul));
+ if (c == 'i')
+ printf("%s", ipaddr_string(&ul));
+ else
+ printf("%lu", ul);
+ bp += sizeof(ul);
+ size -= sizeof(ul);
+ first = 0;
+ }
+ break;
+
+ case 's':
+ /* shorts */
+ while (size >= sizeof(us)) {
+ if (!first)
+ putchar(',');
+ bcopy((char *)bp, (char *)&us, sizeof(us));
+ printf("%d", us);
+ bp += sizeof(us);
+ size -= sizeof(us);
+ first = 0;
+ }
+ break;
+
+ case 'b':
+ default:
+ /* Bytes */
+ while (size > 0) {
+ if (!first)
+ putchar('.');
+ printf("%d", *bp);
+ ++bp;
+ --size;
+ first = 0;
+ }
+ break;
+ }
+ /* Data left over? */
+ if (size)
+ printf("[len %d]", len);
+ }
+}
+
+static void
+cmu_print(register const u_char *bp, register int length)
+{
+ register const struct cmu_vend *cmu;
+ register const u_char *ep;
+ char *fmt = " %s:%s";
+
+#define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc
+#define PRINTCMUADDR(m, s) { TCHECK(cmu->m, sizeof(cmu->m)); \
+ if (cmu->m.s_addr != 0) \
+ printf(fmt, s, ipaddr_string(&cmu->m.s_addr)); }
+
+ /* Setup end pointer */
+ ep = bp + length;
+
+ printf(" vend-cmu");
+ cmu = (struct cmu_vend *)bp;
+
+ /* Only print if there are unknown bits */
+ TCHECK(cmu->v_flags, sizeof(cmu->v_flags));
+ if ((cmu->v_flags & ~(VF_SMASK)) != 0)
+ printf(" F:0x%x", cmu->v_flags);
+ PRINTCMUADDR(v_dgate, "DG");
+ PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*");
+ PRINTCMUADDR(v_dns1, "NS1");
+ PRINTCMUADDR(v_dns2, "NS2");
+ PRINTCMUADDR(v_ins1, "IEN1");
+ PRINTCMUADDR(v_ins2, "IEN2");
+ PRINTCMUADDR(v_ts1, "TS1");
+ PRINTCMUADDR(v_ts2, "TS2");
+ return;
+
+trunc:
+ fputs(tstr, stdout);
+#undef TCHECK
+#undef PRINTCMUADDR
+}
diff --git a/usr.sbin/tcpdump/print-decnet.c b/usr.sbin/tcpdump/print-decnet.c
new file mode 100644
index 00000000000..2e0a419cea5
--- /dev/null
+++ b/usr.sbin/tcpdump/print-decnet.c
@@ -0,0 +1,765 @@
+/* $NetBSD: print-decnet.c,v 1.2 1995/03/06 19:11:07 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-decnet.c,v 1.15 94/06/20 19:44:38 leres Exp (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#ifdef DECNETLIB
+#include <netdnet/dnetdb.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <unistd.h>
+
+#include "decnet.h"
+#include "interface.h"
+#include "addrtoname.h"
+
+/* Forwards */
+static void print_decnet_ctlmsg(const union routehdr *, int);
+static void print_t_info(int);
+static void print_l1_routes(const char *, int);
+static void print_l2_routes(const char *, int);
+static void print_i_info(int);
+static void print_elist(const char *, int);
+static void print_nsp(const u_char *, int);
+static void print_reason(int);
+#ifdef PRINT_NSPDATA
+static void pdata(u_char *, int);
+#endif
+
+#ifdef DECNETLIB
+extern char *dnet_htoa(struct dn_naddr *);
+#endif
+
+void
+decnet_print(register const u_char *ap, register int length,
+ register int caplen)
+{
+ static union routehdr rhcopy;
+ register union routehdr *rhp = &rhcopy;
+ register int mflags;
+ int dst, src, hops;
+ int rhlen;
+ const u_char *nspp;
+ int nsplen;
+ int pktlen;
+
+ if (length < sizeof(struct shorthdr)) {
+ (void)printf("[|decnet]");
+ return;
+ }
+
+ pktlen = EXTRACT_16BITS(ap);
+
+ rhlen = min(length, caplen);
+ rhlen = min(rhlen, sizeof(*rhp));
+ bcopy(&(ap[sizeof(short)]), rhp, rhlen);
+
+ mflags = EXTRACT_8BITS(rhp->rh_short.sh_flags);
+
+ if (mflags & RMF_PAD) {
+ /* pad bytes of some sort in front of message */
+ int padlen = mflags & RMF_PADMASK;
+ if (vflag)
+ (void) printf("[pad:%d] ", padlen);
+ ap += padlen;
+ length -= padlen;
+ caplen -= padlen;
+ rhlen = min(length, caplen);
+ rhlen = min(rhlen, sizeof(*rhp));
+ bcopy(&(ap[sizeof(short)]), rhp, rhlen);
+ mflags = EXTRACT_8BITS(rhp->rh_short.sh_flags);
+ }
+
+ if (mflags & RMF_FVER) {
+ (void) printf("future-version-decnet");
+ default_print(ap, length);
+ return;
+ }
+
+ /* is it a control message? */
+ if (mflags & RMF_CTLMSG) {
+ print_decnet_ctlmsg(rhp, min(length, caplen));
+ return;
+ }
+
+ switch (mflags & RMF_MASK) {
+ case RMF_LONG:
+ dst = EXTRACT_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
+ src = EXTRACT_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
+ hops = EXTRACT_8BITS(rhp->rh_long.lg_visits);
+ nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
+ nsplen = min((length - sizeof(struct longhdr)),
+ (caplen - sizeof(struct longhdr)));
+ break;
+ case RMF_SHORT:
+ dst = EXTRACT_16BITS(rhp->rh_short.sh_dst);
+ src = EXTRACT_16BITS(rhp->rh_short.sh_src);
+ hops = (EXTRACT_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
+ nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
+ nsplen = min((length - sizeof(struct shorthdr)),
+ (caplen - sizeof(struct shorthdr)));
+ break;
+ default:
+ (void) printf("unknown message flags under mask");
+ default_print((u_char *)ap, length);
+ return;
+ }
+
+ (void)printf("%s > %s %d ",
+ dnaddr_string(src), dnaddr_string(dst), pktlen);
+ if (vflag) {
+ if (mflags & RMF_RQR)
+ (void)printf("RQR ");
+ if (mflags & RMF_RTS)
+ (void)printf("RTS ");
+ if (mflags & RMF_IE)
+ (void)printf("IE ");
+ (void)printf("%d hops ", hops);
+ }
+
+ print_nsp(nspp, nsplen);
+}
+
+static void
+print_decnet_ctlmsg(register const union routehdr *rhp, int length)
+{
+ int mflags = EXTRACT_8BITS(rhp->rh_short.sh_flags);
+ register union controlmsg *cmp = (union controlmsg *)rhp;
+ int src, dst, info, blksize, eco, ueco, hello, other, vers;
+ etheraddr srcea, rtea;
+ int priority;
+ char *rhpx = (char *)rhp;
+
+ switch (mflags & RMF_CTLMASK) {
+ case RMF_INIT:
+ (void)printf("init ");
+ src = EXTRACT_16BITS(cmp->cm_init.in_src);
+ info = EXTRACT_8BITS(cmp->cm_init.in_info);
+ blksize = EXTRACT_16BITS(cmp->cm_init.in_blksize);
+ vers = EXTRACT_8BITS(cmp->cm_init.in_vers);
+ eco = EXTRACT_8BITS(cmp->cm_init.in_eco);
+ ueco = EXTRACT_8BITS(cmp->cm_init.in_ueco);
+ hello = EXTRACT_16BITS(cmp->cm_init.in_hello);
+ print_t_info(info);
+ (void)printf(
+ "src %sblksize %d vers %d eco %d ueco %d hello %d",
+ dnaddr_string(src), blksize, vers, eco, ueco,
+ hello);
+ break;
+ case RMF_VER:
+ (void)printf("verification ");
+ src = EXTRACT_16BITS(cmp->cm_ver.ve_src);
+ other = EXTRACT_8BITS(cmp->cm_ver.ve_fcnval);
+ (void)printf("src %s fcnval %o", dnaddr_string(src), other);
+ break;
+ case RMF_TEST:
+ (void)printf("test ");
+ src = EXTRACT_16BITS(cmp->cm_test.te_src);
+ other = EXTRACT_8BITS(cmp->cm_test.te_data);
+ (void)printf("src %s data %o", dnaddr_string(src), other);
+ break;
+ case RMF_L1ROUT:
+ (void)printf("lev-1-routing ");
+ src = EXTRACT_16BITS(cmp->cm_l1rou.r1_src);
+ (void)printf("src %s ", dnaddr_string(src));
+ print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
+ length - sizeof(struct l1rout));
+ break;
+ case RMF_L2ROUT:
+ (void)printf("lev-2-routing ");
+ src = EXTRACT_16BITS(cmp->cm_l2rout.r2_src);
+ (void)printf("src %s ", dnaddr_string(src));
+ print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
+ length - sizeof(struct l2rout));
+ break;
+ case RMF_RHELLO:
+ (void)printf("router-hello ");
+ vers = EXTRACT_8BITS(cmp->cm_rhello.rh_vers);
+ eco = EXTRACT_8BITS(cmp->cm_rhello.rh_eco);
+ ueco = EXTRACT_8BITS(cmp->cm_rhello.rh_ueco);
+ bcopy(&(cmp->cm_rhello.rh_src), &srcea, sizeof(srcea));
+ src = EXTRACT_16BITS(srcea.dne_remote.dne_nodeaddr);
+ info = EXTRACT_8BITS(cmp->cm_rhello.rh_info);
+ blksize = EXTRACT_16BITS(cmp->cm_rhello.rh_blksize);
+ priority = EXTRACT_8BITS(cmp->cm_rhello.rh_priority);
+ hello = EXTRACT_16BITS(cmp->cm_rhello.rh_hello);
+ print_i_info(info);
+ (void)printf(
+ "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
+ vers, eco, ueco, dnaddr_string(src),
+ blksize, priority, hello);
+ print_elist(&(rhpx[sizeof(struct rhellomsg)]),
+ length - sizeof(struct rhellomsg));
+ break;
+ case RMF_EHELLO:
+ (void)printf("endnode-hello ");
+ vers = EXTRACT_8BITS(cmp->cm_ehello.eh_vers);
+ eco = EXTRACT_8BITS(cmp->cm_ehello.eh_eco);
+ ueco = EXTRACT_8BITS(cmp->cm_ehello.eh_ueco);
+ bcopy(&(cmp->cm_ehello.eh_src), &srcea, sizeof(srcea));
+ src = EXTRACT_16BITS(srcea.dne_remote.dne_nodeaddr);
+ info = EXTRACT_8BITS(cmp->cm_ehello.eh_info);
+ blksize = EXTRACT_16BITS(cmp->cm_ehello.eh_blksize);
+ /*seed*/
+ bcopy(&(cmp->cm_ehello.eh_router), &rtea, sizeof(rtea));
+ dst = EXTRACT_16BITS(rtea.dne_remote.dne_nodeaddr);
+ hello = EXTRACT_16BITS(cmp->cm_ehello.eh_hello);
+ other = EXTRACT_8BITS(cmp->cm_ehello.eh_data);
+ print_i_info(info);
+ (void)printf(
+ "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
+ vers, eco, ueco, dnaddr_string(src),
+ blksize, dnaddr_string(dst), hello, other);
+ break;
+
+ default:
+ (void)printf("unknown control message");
+ default_print((u_char *)rhp, length);
+ break;
+ }
+}
+
+static void
+print_t_info(int info)
+{
+ int ntype = info & 3;
+ switch (ntype) {
+ case 0: (void)printf("reserved-ntype? "); break;
+ case TI_L2ROUT: (void)printf("l2rout "); break;
+ case TI_L1ROUT: (void)printf("l1rout "); break;
+ case TI_ENDNODE: (void)printf("endnode "); break;
+ }
+ if (info & TI_VERIF)
+ (void)printf("verif ");
+ if (info & TI_BLOCK)
+ (void)printf("blo ");
+}
+
+static void
+print_l1_routes(const char *rp, int len)
+{
+ int count;
+ int id;
+ int info;
+
+ /* The last short is a checksum */
+ while (len > (3 * sizeof(short))) {
+ count = EXTRACT_16BITS(rp);
+ if (count > 1024)
+ return; /* seems to be bogus from here on */
+ rp += sizeof(short);
+ len -= sizeof(short);
+ id = EXTRACT_16BITS(rp);
+ rp += sizeof(short);
+ len -= sizeof(short);
+ info = EXTRACT_16BITS(rp);
+ rp += sizeof(short);
+ len -= sizeof(short);
+ (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
+ RI_COST(info), RI_HOPS(info));
+ }
+}
+
+static void
+print_l2_routes(const char *rp, int len)
+{
+ int count;
+ int area;
+ int info;
+
+ /* The last short is a checksum */
+ while (len > (3 * sizeof(short))) {
+ count = EXTRACT_16BITS(rp);
+ if (count > 1024)
+ return; /* seems to be bogus from here on */
+ rp += sizeof(short);
+ len -= sizeof(short);
+ area = EXTRACT_16BITS(rp);
+ rp += sizeof(short);
+ len -= sizeof(short);
+ info = EXTRACT_16BITS(rp);
+ rp += sizeof(short);
+ len -= sizeof(short);
+ (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
+ RI_COST(info), RI_HOPS(info));
+ }
+}
+
+static void
+print_i_info(int info)
+{
+ int ntype = info & II_TYPEMASK;
+ switch (ntype) {
+ case 0: (void)printf("reserved-ntype? "); break;
+ case II_L2ROUT: (void)printf("l2rout "); break;
+ case II_L1ROUT: (void)printf("l1rout "); break;
+ case II_ENDNODE: (void)printf("endnode "); break;
+ }
+ if (info & II_VERIF)
+ (void)printf("verif ");
+ if (info & II_NOMCAST)
+ (void)printf("nomcast ");
+ if (info & II_BLOCK)
+ (void)printf("blo ");
+}
+
+static void
+print_elist(const char *elp, int len)
+{
+ /* Not enough examples available for me to debug this */
+}
+
+static void
+print_nsp(const u_char *nspp, int nsplen)
+{
+ const struct nsphdr *nsphp = (struct nsphdr *)nspp;
+ int dst, src, flags;
+
+ flags = EXTRACT_8BITS(nsphp->nh_flags);
+ dst = EXTRACT_16BITS(nsphp->nh_dst);
+ src = EXTRACT_16BITS(nsphp->nh_src);
+
+ switch (flags & NSP_TYPEMASK) {
+ case MFT_DATA:
+ switch (flags & NSP_SUBMASK) {
+ case MFS_BOM:
+ case MFS_MOM:
+ case MFS_EOM:
+ case MFS_BOM+MFS_EOM:
+ printf("data %d>%d ", src, dst);
+ {
+ struct seghdr *shp = (struct seghdr *)nspp;
+ int ack;
+#ifdef PRINT_NSPDATA
+ u_char *dp;
+#endif
+ int data_off = sizeof(struct minseghdr);
+
+ ack = EXTRACT_16BITS(shp->sh_seq[0]);
+ if (ack & SGQ_ACK) { /* acknum field */
+ if ((ack & SGQ_NAK) == SGQ_NAK)
+ (void)printf("nak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ack %d ", ack & SGQ_MASK);
+ ack = EXTRACT_16BITS(shp->sh_seq[1]);
+ data_off += sizeof(short);
+ if (ack & SGQ_OACK) { /* ackoth field */
+ if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ (void)printf("onak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("oack %d ", ack & SGQ_MASK);
+ ack = EXTRACT_16BITS(shp->sh_seq[2]);
+ data_off += sizeof(short);
+ }
+ }
+ (void)printf("seg %d ", ack & SGQ_MASK);
+#ifdef PRINT_NSPDATA
+ dp = &(nspp[data_off]);
+ pdata(dp, 10);
+#endif
+ }
+ break;
+ case MFS_ILS+MFS_INT:
+ printf("intr ");
+ {
+ struct seghdr *shp = (struct seghdr *)nspp;
+ int ack;
+#ifdef PRINT_NSPDATA
+ u_char *dp;
+#endif
+ int data_off = sizeof(struct minseghdr);
+
+ ack = EXTRACT_16BITS(shp->sh_seq[0]);
+ if (ack & SGQ_ACK) { /* acknum field */
+ if ((ack & SGQ_NAK) == SGQ_NAK)
+ (void)printf("nak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ack %d ", ack & SGQ_MASK);
+ ack = EXTRACT_16BITS(shp->sh_seq[1]);
+ data_off += sizeof(short);
+ if (ack & SGQ_OACK) { /* ackdat field */
+ if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ (void)printf("nakdat %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ackdat %d ", ack & SGQ_MASK);
+ ack = EXTRACT_16BITS(shp->sh_seq[2]);
+ data_off += sizeof(short);
+ }
+ }
+ (void)printf("seg %d ", ack & SGQ_MASK);
+#ifdef PRINT_NSPDATA
+ dp = &(nspp[data_off]);
+ pdata(dp, 10);
+#endif
+ }
+ break;
+ case MFS_ILS:
+ (void)printf("link-service %d>%d ", src, dst);
+ {
+ struct seghdr *shp = (struct seghdr *)nspp;
+ struct lsmsg *lsmp =
+ (struct lsmsg *)&(nspp[sizeof(struct seghdr)]);
+ int ack;
+ int lsflags, fcval;
+
+ ack = EXTRACT_16BITS(shp->sh_seq[0]);
+ if (ack & SGQ_ACK) { /* acknum field */
+ if ((ack & SGQ_NAK) == SGQ_NAK)
+ (void)printf("nak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ack %d ", ack & SGQ_MASK);
+ ack = EXTRACT_16BITS(shp->sh_seq[1]);
+ if (ack & SGQ_OACK) { /* ackdat field */
+ if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ (void)printf("nakdat %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ackdat %d ", ack & SGQ_MASK);
+ ack = EXTRACT_16BITS(shp->sh_seq[2]);
+ }
+ }
+ (void)printf("seg %d ", ack & SGQ_MASK);
+ lsflags = EXTRACT_8BITS(lsmp->ls_lsflags);
+ fcval = EXTRACT_8BITS(lsmp->ls_fcval);
+ switch (lsflags & LSI_MASK) {
+ case LSI_DATA:
+ (void)printf("dat seg count %d ", fcval);
+ switch (lsflags & LSM_MASK) {
+ case LSM_NOCHANGE:
+ break;
+ case LSM_DONOTSEND:
+ (void)printf("donotsend-data ");
+ break;
+ case LSM_SEND:
+ (void)printf("send-data ");
+ break;
+ default:
+ (void)printf("reserved-fcmod? %x", lsflags);
+ break;
+ }
+ break;
+ case LSI_INTR:
+ (void)printf("intr req count %d ", fcval);
+ break;
+ default:
+ (void)printf("reserved-fcval-int? %x", lsflags);
+ break;
+ }
+ }
+ break;
+ default:
+ (void)printf("reserved-subtype? %x %d > %d", flags, src, dst);
+ break;
+ }
+ break;
+ case MFT_ACK:
+ switch (flags & NSP_SUBMASK) {
+ case MFS_DACK:
+ (void)printf("data-ack %d>%d ", src, dst);
+ {
+ struct ackmsg *amp = (struct ackmsg *)nspp;
+ int ack;
+
+ ack = EXTRACT_16BITS(amp->ak_acknum[0]);
+ if (ack & SGQ_ACK) { /* acknum field */
+ if ((ack & SGQ_NAK) == SGQ_NAK)
+ (void)printf("nak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ack %d ", ack & SGQ_MASK);
+ ack = EXTRACT_16BITS(amp->ak_acknum[1]);
+ if (ack & SGQ_OACK) { /* ackoth field */
+ if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ (void)printf("onak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("oack %d ", ack & SGQ_MASK);
+ }
+ }
+ }
+ break;
+ case MFS_IACK:
+ (void)printf("ils-ack %d>%d ", src, dst);
+ {
+ struct ackmsg *amp = (struct ackmsg *)nspp;
+ int ack;
+
+ ack = EXTRACT_16BITS(amp->ak_acknum[0]);
+ if (ack & SGQ_ACK) { /* acknum field */
+ if ((ack & SGQ_NAK) == SGQ_NAK)
+ (void)printf("nak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ack %d ", ack & SGQ_MASK);
+ ack = EXTRACT_16BITS(amp->ak_acknum[1]);
+ if (ack & SGQ_OACK) { /* ackdat field */
+ if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ (void)printf("nakdat %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ackdat %d ", ack & SGQ_MASK);
+ }
+ }
+ }
+ break;
+ case MFS_CACK:
+ (void)printf("conn-ack %d", dst);
+ break;
+ default:
+ (void)printf("reserved-acktype? %x %d > %d", flags, src, dst);
+ break;
+ }
+ break;
+ case MFT_CTL:
+ switch (flags & NSP_SUBMASK) {
+ case MFS_CI:
+ case MFS_RCI:
+ if ((flags & NSP_SUBMASK) == MFS_CI)
+ (void)printf("conn-initiate ");
+ else
+ (void)printf("retrans-conn-initiate ");
+ (void)printf("%d>%d ", src, dst);
+ {
+ struct cimsg *cimp = (struct cimsg *)nspp;
+ int services, info, segsize;
+#ifdef PRINT_NSPDATA
+ u_char *dp;
+#endif
+
+ services = EXTRACT_8BITS(cimp->ci_services);
+ info = EXTRACT_8BITS(cimp->ci_info);
+ segsize = EXTRACT_16BITS(cimp->ci_segsize);
+
+ switch (services & COS_MASK) {
+ case COS_NONE:
+ break;
+ case COS_SEGMENT:
+ (void)printf("seg ");
+ break;
+ case COS_MESSAGE:
+ (void)printf("msg ");
+ break;
+ case COS_CRYPTSER:
+ (void)printf("crypt ");
+ break;
+ }
+ switch (info & COI_MASK) {
+ case COI_32:
+ (void)printf("ver 3.2 ");
+ break;
+ case COI_31:
+ (void)printf("ver 3.1 ");
+ break;
+ case COI_40:
+ (void)printf("ver 4.0 ");
+ break;
+ case COI_41:
+ (void)printf("ver 4.1 ");
+ break;
+ }
+ (void)printf("segsize %d ", segsize);
+#ifdef PRINT_NSPDATA
+ dp = &(nspp[sizeof(struct cimsg)]);
+ pdata(dp, nsplen - sizeof(struct cimsg));
+#endif
+ }
+ break;
+ case MFS_CC:
+ (void)printf("conn-confirm %d>%d ", src, dst);
+ {
+ struct ccmsg *ccmp = (struct ccmsg *)nspp;
+ int services, info, segsize, optlen;
+#ifdef PRINT_NSPDATA
+ u_char *dp;
+#endif
+
+ services = EXTRACT_8BITS(ccmp->cc_services);
+ info = EXTRACT_8BITS(ccmp->cc_info);
+ segsize = EXTRACT_16BITS(ccmp->cc_segsize);
+ optlen = EXTRACT_8BITS(ccmp->cc_optlen);
+
+ switch (services & COS_MASK) {
+ case COS_NONE:
+ break;
+ case COS_SEGMENT:
+ (void)printf("seg ");
+ break;
+ case COS_MESSAGE:
+ (void)printf("msg ");
+ break;
+ case COS_CRYPTSER:
+ (void)printf("crypt ");
+ break;
+ }
+ switch (info & COI_MASK) {
+ case COI_32:
+ (void)printf("ver 3.2 ");
+ break;
+ case COI_31:
+ (void)printf("ver 3.1 ");
+ break;
+ case COI_40:
+ (void)printf("ver 4.0 ");
+ break;
+ case COI_41:
+ (void)printf("ver 4.1 ");
+ break;
+ }
+ (void)printf("segsize %d ", segsize);
+ if (optlen) {
+ (void)printf("optlen %d ", optlen);
+#ifdef PRINT_NSPDATA
+ optlen = min(optlen, nsplen - sizeof(struct ccmsg));
+ dp = &(nspp[sizeof(struct ccmsg)]);
+ pdata(dp, optlen);
+#endif
+ }
+ }
+ break;
+ case MFS_DI:
+ (void)printf("disconn-initiate %d>%d ", src, dst);
+ {
+ struct dimsg *dimp = (struct dimsg *)nspp;
+ int reason, optlen;
+#ifdef PRINT_NSPDATA
+ u_char *dp;
+#endif
+
+ reason = EXTRACT_16BITS(dimp->di_reason);
+ optlen = EXTRACT_8BITS(dimp->di_optlen);
+
+ print_reason(reason);
+ if (optlen) {
+ (void)printf("optlen %d ", optlen);
+#ifdef PRINT_NSPDATA
+ optlen = min(optlen, nsplen - sizeof(struct dimsg));
+ dp = &(nspp[sizeof(struct dimsg)]);
+ pdata(dp, optlen);
+#endif
+ }
+ }
+ break;
+ case MFS_DC:
+ (void)printf("disconn-confirm %d>%d ", src, dst);
+ {
+ struct dcmsg *dcmp = (struct dcmsg *)nspp;
+ int reason;
+
+ reason = EXTRACT_16BITS(dcmp->dc_reason);
+
+ print_reason(reason);
+ }
+ break;
+ default:
+ (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst);
+ break;
+ }
+ break;
+ default:
+ (void)printf("reserved-type? %x %d > %d", flags, src, dst);
+ break;
+ }
+}
+
+struct token reason2str[] = {
+ { UC_OBJREJECT, "object rejected connect" },
+ { UC_RESOURCES, "insufficient resources" },
+ { UC_NOSUCHNODE, "unrecognized node name" },
+ { DI_SHUT, "node is shutting down" },
+ { UC_NOSUCHOBJ, "unrecognized object" },
+ { UC_INVOBJFORMAT, "invalid object name format" },
+ { UC_OBJTOOBUSY, "object too busy" },
+ { DI_PROTOCOL, "protocol error discovered" },
+ { DI_TPA, "third party abort" },
+ { UC_USERABORT, "user abort" },
+ { UC_INVNODEFORMAT, "invalid node name format" },
+ { UC_LOCALSHUT, "local node shutting down" },
+ { DI_LOCALRESRC, "insufficient local resources" },
+ { DI_REMUSERRESRC, "insufficient remote user resources" },
+ { UC_ACCESSREJECT, "invalid access control information" },
+ { DI_BADACCNT, "bad ACCOUNT information" },
+ { UC_NORESPONSE, "no response from object" },
+ { UC_UNREACHABLE, "node unreachable" },
+ { DC_NOLINK, "no link terminate" },
+ { DC_COMPLETE, "disconnect complete" },
+ { DI_BADIMAGE, "bad image data in connect" },
+ { DI_SERVMISMATCH, "cryptographic service mismatch" },
+ { 0, NULL }
+};
+
+static void
+print_reason(register int reason)
+{
+ printf("%s ", tok2str(reason2str, "reason-%d", reason));
+}
+
+char *
+dnnum_string(u_short dnaddr)
+{
+ char *str;
+ int area = (dnaddr & AREAMASK) >> AREASHIFT;
+ int node = dnaddr & NODEMASK;
+
+ str = (char *)malloc(sizeof("00.0000"));
+ sprintf(str, "%d.%d", area, node);
+ return(str);
+}
+
+char *
+dnname_string(u_short dnaddr)
+{
+#ifdef DECNETLIB
+ struct dn_naddr dna;
+
+ dna.a_len = sizeof(short);
+ bcopy((char *)&dnaddr, dna.a_addr, sizeof(short));
+ return (savestr(dnet_htoa(&dna)));
+#else
+ return(dnnum_string(dnaddr)); /* punt */
+#endif
+}
+
+#ifdef PRINT_NSPDATA
+static void
+pdata(u_char *dp, int maxlen)
+{
+ char c;
+ int x = maxlen;
+
+ while (x-- > 0) {
+ c = *dp++;
+ if (isprint(c))
+ putchar(c);
+ else
+ printf("\\%o", c & 0xFF);
+ }
+}
+#endif
diff --git a/usr.sbin/tcpdump/print-domain.c b/usr.sbin/tcpdump/print-domain.c
new file mode 100644
index 00000000000..bc2cab3db3e
--- /dev/null
+++ b/usr.sbin/tcpdump/print-domain.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-domain.c,v 1.23 94/06/14 20:17:38 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#undef NOERROR /* Solaris sucks */
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+static char *ns_ops[] = {
+ "", " inv_q", " stat", " op3", " op4", " op5", " op6", " op7",
+ " op8", " updataA", " updateD", " updateDA",
+ " updateM", " updateMA", " zoneInit", " zoneRef",
+};
+
+static char *ns_resp[] = {
+ "", " FormErr", " ServFail", " NXDomain",
+ " NotImp", " Refused", " Resp6", " Resp7",
+ " Resp8", " Resp9", " Resp10", " Resp11",
+ " Resp12", " Resp13", " Resp14", " NoChange",
+};
+
+/* skip over a domain name */
+static const u_char *
+ns_nskip(register const u_char *cp)
+{
+ register u_char i;
+
+ if (((i = *cp++) & 0xc0) == 0xc0)
+ return (cp + 1);
+ while (i) {
+ cp += i;
+ i = *cp++;
+ }
+ return (cp);
+}
+
+/* print a domain name */
+static void
+ns_nprint(register const u_char *cp, register const u_char *bp,
+ register const u_char *ep)
+{
+ register u_int i;
+
+ putchar(' ');
+ if ((i = *cp++) != 0)
+ while (i && cp < ep) {
+ if ((i & 0xc0) == 0xc0) {
+ cp = bp + (((i << 8) | *cp) & 0x3fff);
+ i = *cp++;
+ continue;
+ }
+ do {
+ putchar(*cp++);
+ } while (--i);
+ putchar('.');
+ i = *cp++;
+ }
+ else
+ putchar('.');
+}
+
+static struct token type2str[] = {
+ { T_A, "A" },
+ { T_NS, "NS" },
+ { T_MD, "MD" },
+ { T_MF, "MF" },
+ { T_CNAME, "CNAME" },
+ { T_SOA, "SOA" },
+ { T_MB, "MB" },
+ { T_MG, "MG" },
+ { T_MR, "MR" },
+ { T_NULL, "NULL" },
+ { T_WKS, "WKS" },
+ { T_PTR, "PTR" },
+ { T_HINFO, "HINFO" },
+ { T_MINFO, "MINFO" },
+ { T_MX, "MX" },
+ { T_UINFO, "UINFO" },
+ { T_UID, "UID" },
+ { T_GID, "GID" },
+#ifdef T_UNSPEC
+ { T_UNSPEC, "UNSPEC" },
+#endif
+ { T_AXFR, "AXFR" },
+ { T_MAILB, "MAILB" },
+ { T_MAILA, "MAILA" },
+ { T_ANY, "ANY" },
+ { 0, NULL }
+};
+
+/* print a query */
+static void
+ns_qprint(register const u_char *cp, register const u_char *bp,
+ register const u_char *ep)
+{
+ const u_char *np = cp;
+ register u_int i;
+
+ cp = ns_nskip(cp);
+
+ if (cp + 4 > ep)
+ return;
+
+ /* print the qtype and qclass (if it's not IN) */
+ i = *cp++ << 8;
+ i |= *cp++;
+ printf(" %s", tok2str(type2str, "Type%d", i));
+ i = *cp++ << 8;
+ if ((i |= *cp++) != C_IN)
+ if (i == C_ANY)
+ printf("(c_any)");
+ else
+ printf("(Class %d)", i);
+
+ putchar('?');
+ ns_nprint(np, bp, ep);
+}
+
+
+/* print a reply */
+static void
+ns_rprint(register const u_char *cp, register const u_char *bp,
+ register const u_char *ep)
+{
+ register u_int i;
+ u_short typ;
+
+ cp = ns_nskip(cp);
+
+ if (cp + 10 > ep)
+ return;
+
+ /* print the type/qtype and class (if it's not IN) */
+ typ = *cp++ << 8;
+ typ |= *cp++;
+ i = *cp++ << 8;
+ if ((i |= *cp++) != C_IN)
+ if (i == C_ANY)
+ printf("(c_any)");
+ else
+ printf("(Class %d)", i);
+
+ /* ignore ttl & len */
+ cp += 6;
+ printf(" %s", tok2str(type2str, "Type%d", typ));
+ switch (typ) {
+
+ case T_A:
+ printf(" %s", ipaddr_string(cp));
+ break;
+
+ case T_NS:
+ case T_CNAME:
+ case T_PTR:
+ ns_nprint(cp, bp, ep);
+ break;
+
+ case T_MX:
+ ns_nprint(cp+2, bp, ep);
+#ifndef TCPDUMP_ALIGN
+ printf(" %d", *(short *)cp);
+#else
+ {
+ u_short x = *cp | cp[1] << 8;
+ printf(" %d", ntohs(x));
+ }
+#endif
+ break;
+ }
+}
+
+void
+ns_print(register const u_char *bp, int length)
+{
+ register const HEADER *np;
+ int qdcount, ancount, nscount, arcount;
+ const u_char *ep = snapend;
+
+ np = (const HEADER *)bp;
+ /* get the byte-order right */
+ qdcount = ntohs(np->qdcount);
+ ancount = ntohs(np->ancount);
+ nscount = ntohs(np->nscount);
+ arcount = ntohs(np->arcount);
+
+ if (np->qr) {
+ /* this is a response */
+ printf(" %d%s%s%s%s%s",
+ ntohs(np->id),
+ ns_ops[np->opcode],
+ ns_resp[np->rcode],
+ np->aa? "*" : "",
+ np->ra? "" : "-",
+ np->tc? "|" : "");
+ if (qdcount != 1)
+ printf(" [%dq]", qdcount);
+ printf(" %d/%d/%d", ancount, nscount, arcount);
+ if (ancount)
+ ns_rprint(ns_nskip((const u_char *)(np + 1)) + 4,
+ (const u_char *)np, ep);
+ }
+ else {
+ /* this is a request */
+ printf(" %d%s%s",
+ ntohs(np->id),
+ ns_ops[np->opcode],
+ np->rd? "+" : "");
+
+ /* any weirdness? */
+ if (*(((u_short *)np)+1) & htons(0x6ff))
+ printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1)));
+
+ if (np->opcode == IQUERY) {
+ if (qdcount)
+ printf(" [%dq]", qdcount);
+ if (ancount != 1)
+ printf(" [%da]", ancount);
+ }
+ else {
+ if (ancount)
+ printf(" [%da]", ancount);
+ if (qdcount != 1)
+ printf(" [%dq]", qdcount);
+ }
+ if (nscount)
+ printf(" [%dn]", nscount);
+ if (arcount)
+ printf(" [%dau]", arcount);
+
+ ns_qprint((const u_char *)(np + 1), (const u_char *)np, ep);
+ }
+ printf(" (%d)", length);
+}
diff --git a/usr.sbin/tcpdump/print-egp.c b/usr.sbin/tcpdump/print-egp.c
new file mode 100644
index 00000000000..97fc2c3818f
--- /dev/null
+++ b/usr.sbin/tcpdump/print-egp.c
@@ -0,0 +1,358 @@
+/* $NetBSD: print-egp.c,v 1.2 1995/03/06 19:11:09 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Lawrence Berkeley Laboratory,
+ * Berkeley, CA. The name of the University may not be used to
+ * endorse or promote products derived from this software without
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU).
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-egp.c,v 1.14 94/06/20 19:44:38 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <netdb.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+struct egp_packet {
+ u_char egp_version;
+#define EGP_VERSION 2
+ u_char egp_type;
+#define EGPT_ACQUIRE 3
+#define EGPT_REACH 5
+#define EGPT_POLL 2
+#define EGPT_UPDATE 1
+#define EGPT_ERROR 8
+ u_char egp_code;
+#define EGPC_REQUEST 0
+#define EGPC_CONFIRM 1
+#define EGPC_REFUSE 2
+#define EGPC_CEASE 3
+#define EGPC_CEASEACK 4
+#define EGPC_HELLO 0
+#define EGPC_HEARDU 1
+ u_char egp_status;
+#define EGPS_UNSPEC 0
+#define EGPS_ACTIVE 1
+#define EGPS_PASSIVE 2
+#define EGPS_NORES 3
+#define EGPS_ADMIN 4
+#define EGPS_GODOWN 5
+#define EGPS_PARAM 6
+#define EGPS_PROTO 7
+#define EGPS_INDET 0
+#define EGPS_UP 1
+#define EGPS_DOWN 2
+#define EGPS_UNSOL 0x80
+ u_short egp_checksum;
+ u_short egp_as;
+ u_short egp_sequence;
+ union {
+ u_short egpu_hello;
+ u_char egpu_gws[2];
+ u_short egpu_reason;
+#define EGPR_UNSPEC 0
+#define EGPR_BADHEAD 1
+#define EGPR_BADDATA 2
+#define EGPR_NOREACH 3
+#define EGPR_XSPOLL 4
+#define EGPR_NORESP 5
+#define EGPR_UVERSION 6
+ } egp_handg;
+#define egp_hello egp_handg.egpu_hello
+#define egp_intgw egp_handg.egpu_gws[0]
+#define egp_extgw egp_handg.egpu_gws[1]
+#define egp_reason egp_handg.egpu_reason
+ union {
+ u_short egpu_poll;
+ u_int32 egpu_sourcenet;
+ } egp_pands;
+#define egp_poll egp_pands.egpu_poll
+#define egp_sourcenet egp_pands.egpu_sourcenet
+};
+
+char *egp_acquire_codes[] = {
+ "request",
+ "confirm",
+ "refuse",
+ "cease",
+ "cease_ack"
+};
+
+char *egp_acquire_status[] = {
+ "unspecified",
+ "active_mode",
+ "passive_mode",
+ "insufficient_resources",
+ "administratively_prohibited",
+ "going_down",
+ "parameter_violation",
+ "protocol_violation"
+};
+
+char *egp_reach_codes[] = {
+ "hello",
+ "i-h-u"
+};
+
+char *egp_status_updown[] = {
+ "indeterminate",
+ "up",
+ "down"
+};
+
+char *egp_reasons[] = {
+ "unspecified",
+ "bad_EGP_header_format",
+ "bad_EGP_data_field_format",
+ "reachability_info_unavailable",
+ "excessive_polling_rate",
+ "no_response",
+ "unsupported_version"
+};
+
+static void
+egpnrprint(register const struct egp_packet *egp, register int length)
+{
+ register const u_char *cp, *ep;
+#define TCHECK(n) if (cp > ep - n) goto trunc
+ register u_int32 addr;
+ register u_int32 net;
+ register int netlen;
+ int gateways, distances, networks;
+ int t_gateways;
+ char *comma;
+
+ addr = egp->egp_sourcenet;
+ if (IN_CLASSA(addr)) {
+ net = addr & IN_CLASSA_NET;
+ netlen = 1;
+ } else if (IN_CLASSB(addr)) {
+ net = addr & IN_CLASSB_NET;
+ netlen = 2;
+ } else if (IN_CLASSC(addr)) {
+ net = addr & IN_CLASSC_NET;
+ netlen = 3;
+ } else {
+ net = 0;
+ netlen = 0;
+ }
+ cp = (u_char *)(egp + 1);
+ ep = snapend;
+
+ t_gateways = egp->egp_intgw + egp->egp_extgw;
+ for (gateways = 0; gateways < t_gateways; ++gateways) {
+ /* Pickup host part of gateway address */
+ addr = 0;
+ TCHECK(4 - netlen);
+ switch (netlen) {
+
+ case 1:
+ addr = *cp++;
+ /* fall through */
+ case 2:
+ addr = (addr << 8) | *cp++;
+ /* fall through */
+ case 3:
+ addr = (addr << 8) | *cp++;
+ }
+ addr |= net;
+ TCHECK(1);
+ distances = *cp++;
+ printf(" %s %s ",
+ gateways < egp->egp_intgw ? "int" : "ext",
+ intoa(addr));
+
+ comma = "";
+ putchar('(');
+ while (--distances >= 0) {
+ TCHECK(2);
+ printf("%sd%d:", comma, (int)*cp++);
+ comma = ", ";
+ networks = *cp++;
+ while (--networks >= 0) {
+ /* Pickup network number */
+ TCHECK(1);
+ addr = (u_int32)*cp++ << 24;
+ if (IN_CLASSB(addr)) {
+ TCHECK(1);
+ addr |= (u_int32)*cp++ << 16;
+ } else if (!IN_CLASSA(addr)) {
+ TCHECK(2);
+ addr |= (u_int32)*cp++ << 16;
+ addr |= (u_int32)*cp++ << 8;
+ }
+ printf(" %s", intoa(addr));
+ }
+ }
+ putchar(')');
+ }
+ return;
+trunc:
+ fputs("[|]", stdout);
+}
+
+void
+egp_print(register const u_char *bp, register int length,
+ register const u_char *bp2)
+{
+ register const struct egp_packet *egp;
+ register const struct ip *ip;
+ register int status;
+ register int code;
+ register int type;
+
+ egp = (struct egp_packet *)bp;
+ ip = (struct ip *)bp2;
+ (void)printf("%s > %s: egp: ",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+
+ if (egp->egp_version != EGP_VERSION) {
+ printf("[version %d]", egp->egp_version);
+ return;
+ }
+ printf("as:%d seq:%d", ntohs(egp->egp_as), ntohs(egp->egp_sequence));
+
+ type = egp->egp_type;
+ code = egp->egp_code;
+ status = egp->egp_status;
+
+ switch (type) {
+ case EGPT_ACQUIRE:
+ printf(" acquire");
+ switch (code) {
+ case EGPC_REQUEST:
+ case EGPC_CONFIRM:
+ printf(" %s", egp_acquire_codes[code]);
+ switch (status) {
+ case EGPS_UNSPEC:
+ case EGPS_ACTIVE:
+ case EGPS_PASSIVE:
+ printf(" %s", egp_acquire_status[status]);
+ break;
+
+ default:
+ printf(" [status %d]", status);
+ break;
+ }
+ printf(" hello:%d poll:%d",
+ ntohs(egp->egp_hello),
+ ntohs(egp->egp_poll));
+ break;
+
+ case EGPC_REFUSE:
+ case EGPC_CEASE:
+ case EGPC_CEASEACK:
+ printf(" %s", egp_acquire_codes[code]);
+ switch (status ) {
+ case EGPS_UNSPEC:
+ case EGPS_NORES:
+ case EGPS_ADMIN:
+ case EGPS_GODOWN:
+ case EGPS_PARAM:
+ case EGPS_PROTO:
+ printf(" %s", egp_acquire_status[status]);
+ break;
+
+ default:
+ printf("[status %d]", status);
+ break;
+ }
+ break;
+
+ default:
+ printf("[code %d]", code);
+ break;
+ }
+ break;
+
+ case EGPT_REACH:
+ switch (code) {
+
+ case EGPC_HELLO:
+ case EGPC_HEARDU:
+ printf(" %s", egp_reach_codes[code]);
+ if (status <= EGPS_DOWN)
+ printf(" state:%s", egp_status_updown[status]);
+ else
+ printf(" [status %d]", status);
+ break;
+
+ default:
+ printf("[reach code %d]", code);
+ break;
+ }
+ break;
+
+ case EGPT_POLL:
+ printf(" poll");
+ if (egp->egp_status <= EGPS_DOWN)
+ printf(" state:%s", egp_status_updown[status]);
+ else
+ printf(" [status %d]", status);
+ printf(" net:%s", intoa(egp->egp_sourcenet));
+ break;
+
+ case EGPT_UPDATE:
+ printf(" update");
+ if (status & EGPS_UNSOL) {
+ status &= ~EGPS_UNSOL;
+ printf(" unsolicited");
+ }
+ if (status <= EGPS_DOWN)
+ printf(" state:%s", egp_status_updown[status]);
+ else
+ printf(" [status %d]", status);
+ printf(" %s int %d ext %d",
+ intoa(egp->egp_sourcenet),
+ egp->egp_intgw,
+ egp->egp_extgw);
+ if (vflag)
+ egpnrprint(egp, length);
+ break;
+
+ case EGPT_ERROR:
+ printf(" error");
+ if (status <= EGPS_DOWN)
+ printf(" state:%s", egp_status_updown[status]);
+ else
+ printf(" [status %d]", status);
+
+ if (ntohs(egp->egp_reason) <= EGPR_UVERSION)
+ printf(" %s", egp_reasons[ntohs(egp->egp_reason)]);
+ else
+ printf(" [reason %d]", ntohs(egp->egp_reason));
+ break;
+
+ default:
+ printf("[type %d]", type);
+ break;
+ }
+}
diff --git a/usr.sbin/tcpdump/print-ether.c b/usr.sbin/tcpdump/print-ether.c
new file mode 100644
index 00000000000..d32ceca2213
--- /dev/null
+++ b/usr.sbin/tcpdump/print-ether.c
@@ -0,0 +1,194 @@
+/* $NetBSD: print-ether.c,v 1.3 1995/03/06 19:11:10 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-ether.c,v 1.37 94/06/10 17:01:29 mccanne Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+const u_char *packetp;
+const u_char *snapend;
+
+static inline void
+ether_print(register const u_char *bp, int length)
+{
+ register const struct ether_header *ep;
+
+ ep = (const struct ether_header *)bp;
+ if (qflag)
+ (void)printf("%s %s %d: ",
+ etheraddr_string(ESRC(ep)),
+ etheraddr_string(EDST(ep)),
+ length);
+ else
+ (void)printf("%s %s %s %d: ",
+ etheraddr_string(ESRC(ep)),
+ etheraddr_string(EDST(ep)),
+ etherproto_string(ep->ether_type),
+ length);
+}
+
+/*
+ * This is the top level routine of the printer. 'p' is the points
+ * to the ether header of the packet, 'tvp' is the timestamp,
+ * 'length' is the length of the packet off the wire, and 'caplen'
+ * is the number of bytes actually captured.
+ */
+void
+ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+ int caplen = h->caplen;
+ int length = h->len;
+ struct ether_header *ep;
+ u_short ether_type;
+ extern u_short extracted_ethertype;
+
+ ts_print(&h->ts);
+
+ if (caplen < sizeof(struct ether_header)) {
+ printf("[|ether]");
+ goto out;
+ }
+
+ if (eflag)
+ ether_print(p, length);
+
+ /*
+ * Some printers want to get back at the ethernet addresses,
+ * and/or check that they're not walking off the end of the packet.
+ * Rather than pass them all the way down, we set these globals.
+ */
+ packetp = p;
+ snapend = p + caplen;
+
+ length -= sizeof(struct ether_header);
+ caplen -= sizeof(struct ether_header);
+ ep = (struct ether_header *)p;
+ p += sizeof(struct ether_header);
+
+ ether_type = ntohs(ep->ether_type);
+
+ /*
+ * Is it (gag) an 802.3 encapsulation?
+ */
+ extracted_ethertype = 0;
+ if (ether_type < ETHERMTU) {
+ /* Try to print the LLC-layer header & higher layers */
+ if (llc_print(p, length, caplen, ESRC(ep), EDST(ep)) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!eflag)
+ ether_print((u_char *)ep, length);
+ if (extracted_ethertype) {
+ printf("(LLC %s) ",
+ etherproto_string(htons(extracted_ethertype)));
+ }
+ if (!xflag && !qflag)
+ default_print(p, caplen);
+ }
+ } else if (ether_encap_print(ether_type, p, length, caplen) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!eflag)
+ ether_print((u_char *)ep, length + sizeof(*ep));
+ if (!xflag && !qflag)
+ default_print(p, caplen);
+ }
+ if (xflag)
+ default_print(p, caplen);
+ out:
+ putchar('\n');
+}
+
+/*
+ * Prints the packet encapsulated in an Ethernet data segment
+ * (or an equivalent encapsulation), given the Ethernet type code.
+ *
+ * Returns non-zero if it can do so, zero if the ethertype is unknown.
+ *
+ * Stuffs the ether type into a global for the benefit of lower layers
+ * that might want to know what it is.
+ */
+
+u_short extracted_ethertype;
+
+int
+ether_encap_print(u_short ethertype, const u_char *p, int length, int caplen)
+{
+ extracted_ethertype = ethertype;
+
+ switch (ethertype) {
+
+ case ETHERTYPE_IP:
+ ip_print(p, length);
+ return (1);
+
+ case ETHERTYPE_ARP:
+ case ETHERTYPE_REVARP:
+ arp_print(p, length, caplen);
+ return (1);
+
+ case ETHERTYPE_DN:
+ decnet_print(p, length, caplen);
+ return (1);
+
+ case ETHERTYPE_ATALK:
+ if (vflag)
+ fputs("et1 ", stdout);
+ atalk_print(p, length);
+ return (1);
+
+ case ETHERTYPE_AARP:
+ aarp_print(p, length);
+ return (1);
+
+ case ETHERTYPE_LAT:
+ case ETHERTYPE_MOPRC:
+ case ETHERTYPE_MOPDL:
+ /* default_print for now */
+ default:
+ return (0);
+ }
+}
+
diff --git a/usr.sbin/tcpdump/print-fddi.c b/usr.sbin/tcpdump/print-fddi.c
new file mode 100644
index 00000000000..0d5c0501ccc
--- /dev/null
+++ b/usr.sbin/tcpdump/print-fddi.c
@@ -0,0 +1,353 @@
+/* $NetBSD: print-fddi.c,v 1.2 1995/03/06 19:11:12 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#)Header: print-fddi.c,v 1.21 94/06/10 17:01:29 mccanne Exp (LBL)";
+#endif
+
+#ifdef FDDI
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <pcap.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#include "fddi.h"
+
+int fddipad = FDDIPAD; /* for proper alignment of header */
+
+/*
+ * Some FDDI interfaces use bit-swapped addresses.
+ */
+#if defined(ultrix) || defined(__alpha)
+int fddi_bitswap = 0;
+#else
+int fddi_bitswap = 1;
+#endif
+
+/*
+ * FDDI support for tcpdump, by Jeffrey Mogul [DECWRL], June 1992
+ *
+ * Based in part on code by Van Jacobson, which bears this note:
+ *
+ * NOTE: This is a very preliminary hack for FDDI support.
+ * There are all sorts of wired in constants & nothing (yet)
+ * to print SMT packets as anything other than hex dumps.
+ * Most of the necessary changes are waiting on my redoing
+ * the "header" that a kernel fddi driver supplies to bpf: I
+ * want it to look like one byte of 'direction' (0 or 1
+ * depending on whether the packet was inbound or outbound),
+ * two bytes of system/driver dependent data (anything an
+ * implementor thinks would be useful to filter on and/or
+ * save per-packet, then the real 21-byte FDDI header.
+ * Steve McCanne & I have also talked about adding the
+ * 'direction' byte to all bpf headers (e.g., in the two
+ * bytes of padding on an ethernet header). It's not clear
+ * we could do this in a backwards compatible way & we hate
+ * the idea of an incompatible bpf change. Discussions are
+ * proceeding.
+ *
+ * Also, to really support FDDI (and better support 802.2
+ * over ethernet) we really need to re-think the rather simple
+ * minded assumptions about fixed length & fixed format link
+ * level headers made in gencode.c. One day...
+ *
+ * - vj
+ */
+
+#define FDDI_HDRLEN (sizeof(struct fddi_header))
+
+static u_char fddi_bit_swap[] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
+
+/*
+ * Print FDDI frame-control bits
+ */
+static inline void
+print_fddi_fc(u_char fc)
+{
+ switch (fc) {
+
+ case FDDIFC_VOID: /* Void frame */
+ printf("void ");
+ break;
+
+ case FDDIFC_NRT: /* Nonrestricted token */
+ printf("nrt ");
+ break;
+
+ case FDDIFC_RT: /* Restricted token */
+ printf("rt ");
+ break;
+
+ case FDDIFC_SMT_INFO: /* SMT Info */
+ printf("info ");
+ break;
+
+ case FDDIFC_SMT_NSA: /* SMT Next station adrs */
+ printf("nsa ");
+ break;
+
+ case FDDIFC_MAC_BEACON: /* MAC Beacon frame */
+ printf("beacon ");
+ break;
+
+ case FDDIFC_MAC_CLAIM: /* MAC Claim frame */
+ printf("claim ");
+ break;
+
+ default:
+ switch (fc & FDDIFC_CLFF) {
+
+ case FDDIFC_MAC:
+ printf("mac%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ case FDDIFC_SMT:
+ printf("smt%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ case FDDIFC_LLC_ASYNC:
+ printf("async%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ case FDDIFC_LLC_SYNC:
+ printf("sync%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ case FDDIFC_IMP_ASYNC:
+ printf("imp_async%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ case FDDIFC_IMP_SYNC:
+ printf("imp_sync%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ default:
+ printf("%02x ", fc);
+ break;
+ }
+ }
+}
+
+/* Extract src, dst addresses */
+static inline void
+extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst)
+{
+ register int i;
+
+ if (fddi_bitswap) {
+ /*
+ * bit-swap the fddi addresses (isn't the IEEE standards
+ * process wonderful!) then convert them to names.
+ */
+ for (i = 0; i < 6; ++i)
+ fdst[i] = fddi_bit_swap[fddip->fddi_dhost[i]];
+ for (i = 0; i < 6; ++i)
+ fsrc[i] = fddi_bit_swap[fddip->fddi_shost[i]];
+ }
+ else {
+ bcopy(fddip->fddi_dhost, fdst, 6);
+ bcopy(fddip->fddi_shost, fsrc, 6);
+ }
+}
+
+/*
+ * Print the FDDI MAC header
+ */
+static inline void
+fddi_print(register const struct fddi_header *fddip, register int length,
+ register const u_char *fsrc, register const u_char *fdst)
+{
+ char *srcname, *dstname;
+
+ srcname = etheraddr_string(fsrc);
+ dstname = etheraddr_string(fdst);
+
+ if (vflag)
+ (void) printf("%02x %s %s %d: ",
+ fddip->fddi_fc,
+ srcname, dstname,
+ length);
+ else if (qflag)
+ printf("%s %s %d: ", srcname, dstname, length);
+ else {
+ (void) print_fddi_fc(fddip->fddi_fc);
+ (void) printf("%s %s %d: ", srcname, dstname, length);
+ }
+}
+
+static inline void
+fddi_smt_print(const u_char *p, int length)
+{
+ printf("<SMT printer not yet implemented>");
+}
+
+/*
+ * This is the top level routine of the printer. 'sp' is the points
+ * to the FDDI header of the packet, 'tvp' is the timestamp,
+ * 'length' is the length of the packet off the wire, and 'caplen'
+ * is the number of bytes actually captured.
+ */
+void
+fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
+ register const u_char *p)
+{
+ int caplen = h->caplen;
+ int length = h->len;
+ const struct fddi_header *fddip = (struct fddi_header *)p;
+ extern u_short extracted_ethertype;
+ struct ether_header ehdr;
+
+ ts_print(&h->ts);
+
+ if (caplen < FDDI_HDRLEN) {
+ printf("[|fddi]");
+ goto out;
+ }
+ /*
+ * Get the FDDI addresses into a canonical form
+ */
+ extract_fddi_addrs(fddip, (char*)ESRC(&ehdr), (char*)EDST(&ehdr));
+ /*
+ * Some printers want to get back at the link level addresses,
+ * and/or check that they're not walking off the end of the packet.
+ * Rather than pass them all the way down, we set these globals.
+ */
+ snapend = p + caplen;
+ /*
+ * Actually, the only printer that uses packetp is print-bootp.c,
+ * and it assumes that packetp points to an Ethernet header. The
+ * right thing to do is to fix print-bootp.c to know which link
+ * type is in use when it excavates. XXX
+ */
+ packetp = (u_char *)&ehdr;
+
+ if (eflag)
+ fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));
+
+ /* Skip over FDDI MAC header */
+ length -= FDDI_HDRLEN;
+ p += FDDI_HDRLEN;
+ caplen -= FDDI_HDRLEN;
+
+ /* Frame Control field determines interpretation of packet */
+ extracted_ethertype = 0;
+ if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) {
+ /* Try to print the LLC-layer header & higher layers */
+ if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr))
+ == 0) {
+ /*
+ * Some kinds of LLC packet we cannot
+ * handle intelligently
+ */
+ if (!eflag)
+ fddi_print(fddip, length,
+ ESRC(&ehdr), EDST(&ehdr));
+ if (extracted_ethertype) {
+ printf("(LLC %s) ",
+ etherproto_string(htons(extracted_ethertype)));
+ }
+ if (!xflag && !qflag)
+ default_print(p, caplen);
+ }
+ } else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT)
+ fddi_smt_print(p, caplen);
+ else {
+ /* Some kinds of FDDI packet we cannot handle intelligently */
+ if (!eflag)
+ fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));
+ if (!xflag && !qflag)
+ default_print(p, caplen);
+ }
+ if (xflag)
+ default_print(p, caplen);
+out:
+ putchar('\n');
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+void
+fddi_if_print(u_char *pcap, struct pcap_pkthdr *h, register u_char *p)
+{
+
+ error("not configured for fddi");
+ /* NOTREACHED */
+}
+#endif
diff --git a/usr.sbin/tcpdump/print-icmp.c b/usr.sbin/tcpdump/print-icmp.c
new file mode 100644
index 00000000000..e4154315b4c
--- /dev/null
+++ b/usr.sbin/tcpdump/print-icmp.c
@@ -0,0 +1,217 @@
+/* $NetBSD: print-icmp.c,v 1.3 1995/03/06 19:11:13 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-icmp.c,v 1.20 94/06/14 20:17:39 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+void
+icmp_print(register const u_char *bp, register const u_char *bp2)
+{
+ register const struct icmp *dp;
+ register const struct ip *ip;
+ register const char *str;
+ register const struct ip *oip;
+ register const struct udphdr *ouh;
+ register int hlen, dport;
+ register const u_char *ep;
+ char buf[256];
+
+#define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc
+
+ dp = (struct icmp *)bp;
+ ip = (struct ip *)bp2;
+ str = buf;
+ /* 'ep' points to the end of avaible data. */
+ ep = snapend;
+
+ (void)printf("%s > %s: ",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+
+ TCHECK(dp->icmp_code, sizeof(dp->icmp_code));
+ switch (dp->icmp_type) {
+ case ICMP_ECHOREPLY:
+ str = "echo reply";
+ break;
+ case ICMP_UNREACH:
+ TCHECK(dp->icmp_ip.ip_dst, sizeof(dp->icmp_ip.ip_dst));
+ switch (dp->icmp_code) {
+ case ICMP_UNREACH_NET:
+ (void)sprintf(buf, "net %s unreachable",
+ ipaddr_string(&dp->icmp_ip.ip_dst));
+ break;
+ case ICMP_UNREACH_HOST:
+ (void)sprintf(buf, "host %s unreachable",
+ ipaddr_string(&dp->icmp_ip.ip_dst));
+ break;
+ case ICMP_UNREACH_PROTOCOL:
+ TCHECK(dp->icmp_ip.ip_p, sizeof(dp->icmp_ip.ip_p));
+ (void)sprintf(buf, "%s protocol %d unreachable",
+ ipaddr_string(&dp->icmp_ip.ip_dst),
+ dp->icmp_ip.ip_p);
+ break;
+ case ICMP_UNREACH_PORT:
+ TCHECK(dp->icmp_ip.ip_p, sizeof(dp->icmp_ip.ip_p));
+ oip = &dp->icmp_ip;
+ hlen = oip->ip_hl * 4;
+ ouh = (struct udphdr *)(((u_char *)oip) + hlen);
+ dport = ntohs(ouh->uh_dport);
+ switch (oip->ip_p) {
+ case IPPROTO_TCP:
+ (void)sprintf(buf,
+ "%s tcp port %s unreachable",
+ ipaddr_string(&oip->ip_dst),
+ tcpport_string(dport));
+ break;
+ case IPPROTO_UDP:
+ (void)sprintf(buf,
+ "%s udp port %s unreachable",
+ ipaddr_string(&oip->ip_dst),
+ udpport_string(dport));
+ break;
+ default:
+ (void)sprintf(buf,
+ "%s protocol %d port %d unreachable",
+ ipaddr_string(&oip->ip_dst),
+ oip->ip_p, dport);
+ break;
+ }
+ break;
+ case ICMP_UNREACH_NEEDFRAG:
+ (void)sprintf(buf, "%s unreachable - need to frag",
+ ipaddr_string(&dp->icmp_ip.ip_dst));
+ break;
+ case ICMP_UNREACH_SRCFAIL:
+ (void)sprintf(buf,
+ "%s unreachable - source route failed",
+ ipaddr_string(&dp->icmp_ip.ip_dst));
+ break;
+ }
+ break;
+ case ICMP_SOURCEQUENCH:
+ str = "source quench";
+ break;
+ case ICMP_REDIRECT:
+ TCHECK(dp->icmp_ip.ip_dst, sizeof(dp->icmp_ip.ip_dst));
+ switch (dp->icmp_code) {
+ case ICMP_REDIRECT_NET:
+ (void)sprintf(buf, "redirect %s to net %s",
+ ipaddr_string(&dp->icmp_ip.ip_dst),
+ ipaddr_string(&dp->icmp_gwaddr));
+ break;
+ case ICMP_REDIRECT_HOST:
+ (void)sprintf(buf, "redirect %s to host %s",
+ ipaddr_string(&dp->icmp_ip.ip_dst),
+ ipaddr_string(&dp->icmp_gwaddr));
+ break;
+ case ICMP_REDIRECT_TOSNET:
+ (void)sprintf(buf, "redirect-tos %s to net %s",
+ ipaddr_string(&dp->icmp_ip.ip_dst),
+ ipaddr_string(&dp->icmp_gwaddr));
+ break;
+ case ICMP_REDIRECT_TOSHOST:
+ (void)sprintf(buf, "redirect-tos %s to host %s",
+ ipaddr_string(&dp->icmp_ip.ip_dst),
+ ipaddr_string(&dp->icmp_gwaddr));
+ break;
+ }
+ break;
+ case ICMP_ECHO:
+ str = "echo request";
+ break;
+ case ICMP_TIMXCEED:
+ TCHECK(dp->icmp_ip.ip_dst, sizeof(dp->icmp_ip.ip_dst));
+ switch (dp->icmp_code) {
+ case ICMP_TIMXCEED_INTRANS:
+ str = "time exceeded in-transit";
+ break;
+ case ICMP_TIMXCEED_REASS:
+ str = "ip reassembly time exceeded";
+ break;
+ }
+ break;
+ case ICMP_PARAMPROB:
+ if (dp->icmp_code)
+ (void)sprintf(buf, "parameter problem - code %d",
+ dp->icmp_code);
+ else {
+ TCHECK(dp->icmp_pptr, sizeof(dp->icmp_pptr));
+ (void)sprintf(buf, "parameter problem - octet %d",
+ dp->icmp_pptr);
+ }
+ break;
+ case ICMP_TSTAMP:
+ str = "time stamp request";
+ break;
+ case ICMP_TSTAMPREPLY:
+ str = "time stamp reply";
+ break;
+ case ICMP_IREQ:
+ str = "information request";
+ break;
+ case ICMP_IREQREPLY:
+ str = "information reply";
+ break;
+ case ICMP_MASKREQ:
+ str = "address mask request";
+ break;
+ case ICMP_MASKREPLY:
+ TCHECK(dp->icmp_mask, sizeof(dp->icmp_mask));
+ (void)sprintf(buf, "address mask is 0x%08x",
+ ntohl(dp->icmp_mask));
+ break;
+ default:
+ (void)sprintf(buf, "type-#%d", dp->icmp_type);
+ break;
+ }
+ (void)printf("icmp: %s", str);
+ return;
+trunc:
+ fputs("[|icmp]", stdout);
+#undef TCHECK
+}
diff --git a/usr.sbin/tcpdump/print-ip.c b/usr.sbin/tcpdump/print-ip.c
new file mode 100644
index 00000000000..4c43bcf32fa
--- /dev/null
+++ b/usr.sbin/tcpdump/print-ip.c
@@ -0,0 +1,364 @@
+/* $NetBSD: print-ip.c,v 1.4 1995/04/24 13:27:43 cgd Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-ip.c,v 1.38 94/06/14 20:17:40 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <unistd.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+static void
+igmp_print(register const u_char *bp, register int len,
+ register const u_char *bp2)
+{
+ register const struct ip *ip;
+ register const u_char *ep;
+
+ ip = (const struct ip *)bp2;
+ ep = (const u_char *)snapend;
+ (void)printf("%s > %s: ",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+
+ if (bp + 7 > ep) {
+ (void)printf("[|igmp]");
+ return;
+ }
+ switch (bp[0] & 0xf) {
+ case 1:
+ (void)printf("igmp query");
+ if (*(int *)&bp[4])
+ (void)printf(" [gaddr %s]", ipaddr_string(&bp[4]));
+ if (len != 8)
+ (void)printf(" [len %d]", len);
+ break;
+ case 2:
+ (void)printf("igmp report %s", ipaddr_string(&bp[4]));
+ if (len != 8)
+ (void)printf(" [len %d]", len);
+ break;
+ case 3:
+ (void)printf("igmp dvmrp %s", ipaddr_string(&bp[4]));
+ if (len < 8)
+ (void)printf(" [len %d]", len);
+ break;
+ default:
+ (void)printf("igmp-%d", bp[0] & 0xf);
+ break;
+ }
+ if ((bp[0] >> 4) != 1)
+ (void)printf(" [v%d]", bp[0] >> 4);
+ if (bp[1])
+ (void)printf(" [b1=0x%x]", bp[1]);
+}
+
+/*
+ * print the recorded route in an IP RR, LSRR or SSRR option.
+ */
+static void
+ip_printroute(const char *type, register const u_char *cp, int length)
+{
+ int ptr = cp[2] - 1;
+ int len;
+
+ printf(" %s{", type);
+ if ((length + 1) & 3)
+ printf(" [bad length %d]", length);
+ if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
+ printf(" [bad ptr %d]", cp[2]);
+
+ type = "";
+ for (len = 3; len < length; len += 4) {
+ if (ptr == len)
+ type = "#";
+#ifdef TCPDUMP_ALIGN
+ {
+ struct in_addr addr;
+ bcopy((char *)&cp[len], (char *)&addr, sizeof(addr));
+ printf("%s%s", type, ipaddr_string(&addr));
+ }
+#else
+ printf("%s%s", type, ipaddr_string(&cp[len]));
+#endif
+ type = " ";
+ }
+ printf("%s}", ptr == len? "#" : "");
+}
+
+/*
+ * print IP options.
+ */
+static void
+ip_optprint(register const u_char *cp, int length)
+{
+ int len;
+
+ for (; length > 0; cp += len, length -= len) {
+ int tt = *cp;
+
+ len = (tt == IPOPT_NOP || tt == IPOPT_EOL) ? 1 : cp[1];
+ if (&cp[1] >= snapend || cp + len > snapend) {
+ printf("[|ip]");
+ return;
+ }
+ switch (tt) {
+
+ case IPOPT_EOL:
+ printf(" EOL");
+ if (length > 1)
+ printf("-%d", length - 1);
+ return;
+
+ case IPOPT_NOP:
+ printf(" NOP");
+ break;
+
+ case IPOPT_TS:
+ printf(" TS{%d}", len);
+ break;
+
+ case IPOPT_SECURITY:
+ printf(" SECURITY{%d}", len);
+ break;
+
+ case IPOPT_RR:
+ printf(" RR{%d}=", len);
+ ip_printroute("RR", cp, len);
+ break;
+
+ case IPOPT_SSRR:
+ ip_printroute("SSRR", cp, len);
+ break;
+
+ case IPOPT_LSRR:
+ ip_printroute("LSRR", cp, len);
+ break;
+
+ default:
+ printf(" IPOPT-%d{%d}", cp[0], len);
+ break;
+ }
+ }
+}
+
+/*
+ * compute an IP header checksum.
+ * don't modifiy the packet.
+ */
+static int
+in_cksum(const struct ip *ip)
+{
+ register const u_short *sp = (u_short *)ip;
+ register u_int32 sum = 0;
+ register int count;
+
+ /*
+ * No need for endian conversions.
+ */
+ for (count = ip->ip_hl * 2; --count >= 0; )
+ sum += *sp++;
+ while (sum > 0xffff)
+ sum = (sum & 0xffff) + (sum >> 16);
+ sum = ~sum & 0xffff;
+
+ return (sum);
+}
+
+/*
+ * print an IP datagram.
+ */
+void
+ip_print(register const u_char *bp, register int length)
+{
+ register const struct ip *ip;
+ register int hlen;
+ register int len;
+ register int off;
+ register const u_char *cp;
+
+ ip = (const struct ip *)bp;
+#ifdef TCPDUMP_ALIGN
+ /*
+ * The IP header is not word aligned, so copy into abuf.
+ * This will never happen with BPF. It does happen raw packet
+ * dumps from -r.
+ */
+ if ((long)ip & (sizeof(long)-1)) {
+ static u_char *abuf;
+
+ if (abuf == 0)
+ abuf = (u_char *)malloc(snaplen);
+ bcopy((char *)ip, (char *)abuf, min(length, snaplen));
+ snapend += abuf - (u_char *)ip;
+ packetp = abuf;
+ ip = (struct ip *)abuf;
+ }
+#endif
+ if ((u_char *)(ip + 1) > snapend) {
+ printf("[|ip]");
+ return;
+ }
+ if (length < sizeof (struct ip)) {
+ (void)printf("truncated-ip %d", length);
+ return;
+ }
+ hlen = ip->ip_hl * 4;
+
+ len = ntohs(ip->ip_len);
+ if (length < len)
+ (void)printf("truncated-ip - %d bytes missing!",
+ len - length);
+ len -= hlen;
+
+ /*
+ * If this is fragment zero, hand it to the next higher
+ * level protocol.
+ */
+ off = ntohs(ip->ip_off);
+ if ((off & 0x1fff) == 0) {
+ cp = (const u_char *)ip + hlen;
+ switch (ip->ip_p) {
+
+ case IPPROTO_TCP:
+ tcp_print(cp, len, (const u_char *)ip);
+ break;
+ case IPPROTO_UDP:
+ udp_print(cp, len, (const u_char *)ip);
+ break;
+ case IPPROTO_ICMP:
+ icmp_print(cp, (const u_char *)ip);
+ break;
+ case IPPROTO_ND:
+ (void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+ (void)printf(" nd %d", len);
+ break;
+ case IPPROTO_EGP:
+ egp_print(cp, len, (const u_char *)ip);
+ break;
+#ifndef IPPROTO_OSPF
+#define IPPROTO_OSPF 89
+#endif
+ case IPPROTO_OSPF:
+ ospf_print(cp, len, (const u_char *)ip);
+ break;
+#ifndef IPPROTO_IGMP
+#define IPPROTO_IGMP 2
+#endif
+ case IPPROTO_IGMP:
+ igmp_print(cp, len, (const u_char *)ip);
+ break;
+#ifndef IPPROTO_ENCAP
+#define IPPROTO_ENCAP 4
+#endif
+ case IPPROTO_ENCAP:
+ /* ip-in-ip encapsulation */
+ if (vflag)
+ (void)printf("%s > %s: ",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+ ip_print(cp, len);
+ if (! vflag) {
+ printf(" (encap)");
+ return;
+ }
+ break;
+ default:
+ (void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+ (void)printf(" ip-proto-%d %d", ip->ip_p, len);
+ break;
+ }
+ }
+ /*
+ * for fragmented datagrams, print id:size@offset. On all
+ * but the last stick a "+". For unfragmented datagrams, note
+ * the don't fragment flag.
+ */
+ if (off & 0x3fff) {
+ /*
+ * if this isn't the first frag, we're missing the
+ * next level protocol header. print the ip addr.
+ */
+ if (off & 0x1fff)
+ (void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+ (void)printf(" (frag %d:%d@%d%s)", ntohs(ip->ip_id), len,
+ (off & 0x1fff) * 8,
+ (off & IP_MF)? "+" : "");
+ } else if (off & IP_DF)
+ (void)printf(" (DF)");
+
+ if (ip->ip_tos)
+ (void)printf(" [tos 0x%x]", (int)ip->ip_tos);
+ if (ip->ip_ttl <= 1)
+ (void)printf(" [ttl %d]", (int)ip->ip_ttl);
+
+ if (vflag) {
+ int sum;
+ char *sep = "";
+
+ printf(" (");
+ if (ip->ip_ttl > 1) {
+ (void)printf("%sttl %d", sep, (int)ip->ip_ttl);
+ sep = ", ";
+ }
+ if ((off & 0x3fff) == 0) {
+ (void)printf("%sid %d", sep, (int)ntohs(ip->ip_id));
+ sep = ", ";
+ }
+ sum = in_cksum(ip);
+ if (sum != 0) {
+ (void)printf("%sbad cksum %x!", sep,
+ ntohs(ip->ip_sum));
+ sep = ", ";
+ }
+ if ((hlen -= sizeof(struct ip)) > 0) {
+ (void)printf("%soptlen=%d", sep, hlen);
+ ip_optprint((u_char *)(ip + 1), hlen);
+ }
+ printf(")");
+ }
+}
diff --git a/usr.sbin/tcpdump/print-ipx.c b/usr.sbin/tcpdump/print-ipx.c
new file mode 100644
index 00000000000..7872e6a6554
--- /dev/null
+++ b/usr.sbin/tcpdump/print-ipx.c
@@ -0,0 +1,214 @@
+/* $NetBSD: print-ipx.c,v 1.2 1995/03/06 19:11:16 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * Format and print Novell IPX packets.
+ * Contributed by Brad Parker (brad@fcr.com).
+ */
+#ifndef lint
+static char rcsid[] =
+ "@(#)Header: print-ipx.c,v 1.6 94/06/20 19:44:38 leres Exp";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ipx.h"
+#include "extract.h"
+
+
+static const char *ipxaddr_string(u_int32 net, const u_char *node);
+void ipx_decode(const struct ipxHdr *ipx, const u_char *datap, int length);
+void ipx_sap_print(const u_short *ipx, int length);
+void ipx_rip_print(const u_short *ipx, int length);
+
+/*
+ * Print IPX datagram packets.
+ */
+void
+ipx_print(const u_char *p, int length)
+{
+ const struct ipxHdr *ipx = (const struct ipxHdr *)p;
+
+ if (length < ipxSize) {
+ (void)printf(" truncated-ipx %d", length);
+ return;
+ }
+ (void)printf("%s.%x > ",
+ ipxaddr_string(EXTRACT_LONG(ipx->srcNet), ipx->srcNode),
+ EXTRACT_SHORT(&ipx->srcSkt));
+
+ (void)printf("%s.%x:",
+ ipxaddr_string(EXTRACT_LONG(ipx->dstNet), ipx->dstNode),
+ EXTRACT_SHORT(&ipx->dstSkt));
+
+ if ((u_char *)(ipx + 1) > snapend) {
+ printf(" [|ipx]");
+ return;
+ }
+
+ /* take length from ipx header */
+ length = EXTRACT_SHORT(&ipx->length);
+
+ ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize);
+}
+
+static const char *
+ipxaddr_string(u_int32 net, const u_char *node)
+{
+ static char line[256];
+
+ sprintf(line, "%lu.%02x:%02x:%02x:%02x:%02x:%02x",
+ net, node[0], node[1], node[2], node[3], node[4], node[5]);
+
+ return line;
+}
+
+void
+ipx_decode(const struct ipxHdr *ipx, const u_char *datap, int length)
+{
+ switch (EXTRACT_SHORT(&ipx->dstSkt)) {
+ case IPX_SKT_NCP:
+ (void)printf(" ipx-ncp %d", length);
+ break;
+ case IPX_SKT_SAP:
+ ipx_sap_print((u_short *)datap, length);
+ break;
+ case IPX_SKT_RIP:
+ ipx_rip_print((u_short *)datap, length);
+ break;
+ case IPX_SKT_NETBIOS:
+ (void)printf(" ipx-netbios %d", length);
+ break;
+ case IPX_SKT_DIAGNOSTICS:
+ (void)printf(" ipx-diags %d", length);
+ break;
+ default:
+ (void)printf(" ipx-#%x %d", ipx->dstSkt, length);
+ break;
+ }
+}
+
+void
+ipx_sap_print(const u_short *ipx, int length)
+{
+ int command, i;
+
+ if (length < 2) {
+ (void)printf(" truncated-sap %d", length);
+ return;
+ }
+
+ command = EXTRACT_SHORT(ipx);
+ ipx++;
+ length -= 2;
+
+ switch (command) {
+ case 1:
+ case 3:
+ if (command == 1)
+ (void)printf("ipx-sap-req");
+ else
+ (void)printf("ipx-sap-nearest-req");
+
+ if (length > 0)
+ (void)printf(" %x '%.48s'", EXTRACT_SHORT(&ipx[0]),
+ (char*)&ipx[1]);
+ break;
+
+ case 2:
+ case 4:
+ if (command == 2)
+ (void)printf("ipx-sap-resp");
+ else
+ (void)printf("ipx-sap-nearest-resp");
+
+ for (i = 0; i < 8 && length > 0; i++) {
+ (void)printf(" %x '%.48s' addr %s",
+ EXTRACT_SHORT(&ipx[0]), (char *)&ipx[1],
+ ipxaddr_string(EXTRACT_LONG(&ipx[25]),
+ (u_char *)&ipx[27]));
+ ipx += 32;
+ length -= 64;
+ }
+ break;
+ default:
+ (void)printf("ipx-sap-?%x", command);
+ break;
+ }
+}
+
+void
+ipx_rip_print(const u_short *ipx, int length)
+{
+ int command, i;
+
+ if (length < 2) {
+ (void)printf(" truncated-ipx %d", length);
+ return;
+ }
+
+ command = EXTRACT_SHORT(ipx);
+ ipx++;
+ length -= 2;
+
+ switch (command) {
+ case 1:
+ (void)printf("ipx-rip-req");
+ if (length > 0)
+ (void)printf(" %lu/%d.%d", EXTRACT_LONG(&ipx[0]),
+ EXTRACT_SHORT(&ipx[2]), EXTRACT_SHORT(&ipx[3]));
+ break;
+ case 2:
+ (void)printf("ipx-rip-resp");
+ for (i = 0; i < 50 && length > 0; i++) {
+ (void)printf(" %lu/%d.%d", EXTRACT_LONG(&ipx[0]),
+ EXTRACT_SHORT(&ipx[2]), EXTRACT_SHORT(&ipx[3]));
+
+ ipx += 4;
+ length -= 8;
+ }
+ break;
+ default:
+ (void)printf("ipx-rip-?%x", command);
+ }
+}
+
diff --git a/usr.sbin/tcpdump/print-isoclns.c b/usr.sbin/tcpdump/print-isoclns.c
new file mode 100644
index 00000000000..670ecaf7c72
--- /dev/null
+++ b/usr.sbin/tcpdump/print-isoclns.c
@@ -0,0 +1,317 @@
+/* $NetBSD: print-isoclns.c,v 1.2 1995/03/06 19:11:17 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * Original code by Matt Thomas, Digital Equipment Corporation
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-isoclns.c,v 1.9 94/06/14 20:18:44 leres Exp (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#define CLNS 129
+#define ESIS 130
+#define ISIS 131
+#define NULLNS 0
+
+static int osi_cksum(const u_char *, int, const u_char *, u_char *, u_char *);
+static void esis_print(const u_char *, int);
+
+void
+isoclns_print(const u_char *p, int length, int caplen,
+ const u_char *esrc, const u_char *edst)
+{
+ if (caplen < 1) {
+ printf("[|iso-clns] ");
+ if (!eflag)
+ printf("%s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ return;
+ }
+
+ switch (*p) {
+
+ case CLNS:
+ /* esis_print(&p, &length); */
+ printf("iso-clns");
+ if (!eflag)
+ (void)printf(" %s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ break;
+
+ case ESIS:
+ printf("iso-esis");
+ if (!eflag)
+ (void)printf(" %s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ esis_print(p, length);
+ return;
+
+ case ISIS:
+ printf("iso-isis");
+ if (!eflag)
+ (void)printf(" %s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ /* isis_print(&p, &length); */
+ (void)printf(" len=%d ", length);
+ if (caplen > 1)
+ default_print_unaligned(p, caplen);
+ break;
+
+ case NULLNS:
+ printf("iso-nullns");
+ if (!eflag)
+ (void)printf(" %s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ break;
+
+ default:
+ printf("iso-clns %02x", p[0]);
+ if (!eflag)
+ (void)printf(" %s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ (void)printf(" len=%d ", length);
+ if (caplen > 1)
+ default_print_unaligned(p, caplen);
+ break;
+ }
+}
+
+#define ESIS_REDIRECT 6
+#define ESIS_ESH 2
+#define ESIS_ISH 4
+
+struct esis_hdr {
+ u_char version;
+ u_char reserved;
+ u_char type;
+ u_char tmo[2];
+ u_char cksum[2];
+};
+
+static void
+esis_print(const u_char *p, int length)
+{
+ const u_char *ep;
+ int li = p[1];
+ const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
+ u_char cksum[2];
+ u_char off[2];
+
+ if (length == 2) {
+ if (qflag)
+ printf(" bad pkt!");
+ else
+ printf(" no header at all!");
+ return;
+ }
+ ep = p + li;
+ if (li > length) {
+ if (qflag)
+ printf(" bad pkt!");
+ else
+ printf(" LI(%d) > PDU size (%d)!", li, length);
+ return;
+ }
+ if (li < sizeof(struct esis_hdr) + 2) {
+ if (qflag)
+ printf(" bad pkt!");
+ else {
+ printf(" too short for esis header %d:", li);
+ while (--length >= 0)
+ printf("%02X", *p++);
+ }
+ return;
+ }
+ switch (eh->type & 0x1f) {
+
+ case ESIS_REDIRECT:
+ printf(" redirect");
+ break;
+
+ case ESIS_ESH:
+ printf(" esh");
+ break;
+
+ case ESIS_ISH:
+ printf(" ish");
+ break;
+
+ default:
+ printf(" type %d", eh->type & 0x1f);
+ break;
+ }
+ off[0] = eh->cksum[0];
+ off[1] = eh->cksum[1];
+ if (vflag && osi_cksum(p, li, eh->cksum, cksum, off)) {
+ printf(" bad cksum (got %02x%02x want %02x%02x)",
+ eh->cksum[1], eh->cksum[0], cksum[1], cksum[0]);
+ return;
+ }
+ if (eh->version != 1) {
+ printf(" unsupported version %d", eh->version);
+ return;
+ }
+ p += sizeof(*eh) + 2;
+ li -= sizeof(*eh) + 2; /* protoid * li */
+
+ switch (eh->type & 0x1f) {
+ case ESIS_REDIRECT: {
+ const u_char *dst, *snpa, *is;
+
+ dst = p; p += *p + 1;
+ if (p > snapend)
+ return;
+ printf(" %s", isonsap_string(dst));
+ snpa = p; p += *p + 1;
+ is = p; p += *p + 1;
+ if (p > snapend)
+ return;
+ if (p > ep) {
+ printf(" [bad li]");
+ return;
+ }
+ if (is[0] == 0)
+ printf(" > %s", etheraddr_string(&snpa[1]));
+ else
+ printf(" > %s", isonsap_string(is));
+ li = ep - p;
+ break;
+ }
+#if 0
+ case ESIS_ESH:
+ printf(" esh");
+ break;
+#endif
+ case ESIS_ISH: {
+ const u_char *is;
+
+ is = p; p += *p + 1;
+ if (p > ep) {
+ printf(" [bad li]");
+ return;
+ }
+ if (p > snapend)
+ return;
+ printf(" %s", isonsap_string(is));
+ li = ep - p;
+ break;
+ }
+
+ default:
+ (void)printf(" len=%d", length);
+ if (length && p < snapend) {
+ length = snapend - p;
+ default_print(p, length);
+ }
+ return;
+ }
+ if (vflag)
+ while (p < ep && li) {
+ int op, opli;
+ const u_char *q;
+
+ if (snapend - p < 2)
+ return;
+ if (li < 2) {
+ printf(" bad opts/li");
+ return;
+ }
+ op = *p++;
+ opli = *p++;
+ li -= 2;
+ if (opli > li) {
+ printf(" opt (%d) too long", op);
+ return;
+ }
+ li -= opli;
+ q = p;
+ p += opli;
+ if (snapend < p)
+ return;
+ if (op == 198 && opli == 2) {
+ printf(" tmo=%d", q[0] * 256 + q[1]);
+ continue;
+ }
+ printf (" %d:<", op);
+ while (--opli >= 0)
+ printf("%02x", *q++);
+ printf (">");
+ }
+}
+
+static int
+osi_cksum(register const u_char *p, register int len,
+ const u_char *toff, u_char *cksum, u_char *off)
+{
+ int x, y, f = (len - ((toff - p) + 1));
+ long c0 = 0, c1 = 0;
+
+ if ((cksum[0] = off[0]) == 0 && (cksum[1] = off[1]) == 0)
+ return 0;
+
+ off[0] = off[1] = 0;
+ while (--len >= 0) {
+ c0 += *p++;
+ c1 += c0;
+ c0 %= 255;
+ c1 %= 255;
+ }
+ x = (c0 * f - c1);
+ if (x < 0)
+ x = 255 - (-x % 255);
+ else
+ x %= 255;
+ y = -1 * (x + c0);
+ if (y < 0)
+ y = 255 - (-y % 255);
+ else
+ y %= 255;
+
+ off[0] = x;
+ off[1] = y;
+
+ return (off[0] != cksum[0] || off[1] != cksum[1]);
+}
diff --git a/usr.sbin/tcpdump/print-llc.c b/usr.sbin/tcpdump/print-llc.c
new file mode 100644
index 00000000000..a6c036620d2
--- /dev/null
+++ b/usr.sbin/tcpdump/print-llc.c
@@ -0,0 +1,198 @@
+/* $NetBSD: print-llc.c,v 1.2 1995/03/06 19:11:19 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * Code by Matt Thomas, Digital Equipment Corporation
+ * with an awful lot of hacking by Jeffrey Mogul, DECWRL
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#)Header: print-llc.c,v 1.13 94/06/14 20:18:45 leres Exp";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#include "llc.h"
+
+static struct token cmd2str[] = {
+ { LLC_UI, "ui" },
+ { LLC_TEST, "test" },
+ { LLC_XID, "xid" },
+ { LLC_UA, "ua" },
+ { LLC_DISC, "disc" },
+ { LLC_DM, "dm" },
+ { LLC_SABME, "sabme" },
+ { LLC_FRMR, "frmr" },
+ { 0, NULL }
+};
+
+/*
+ * Returns non-zero IFF it succeeds in printing the header
+ */
+int
+llc_print(const u_char *p, int length, int caplen,
+ const u_char *esrc, const u_char *edst)
+{
+ struct llc llc;
+ register u_short et;
+ register int ret;
+
+ if (caplen < 3) {
+ (void)printf("[|llc]");
+ default_print((u_char *)p, caplen);
+ return(0);
+ }
+
+ /* Watch out for possible alignment problems */
+ bcopy((char *)p, (char *)&llc, min(caplen, sizeof(llc)));
+
+ if (llc.ssap == LLCSAP_GLOBAL && llc.dsap == LLCSAP_GLOBAL) {
+ ipx_print(p, length);
+ return (1);
+ }
+#ifdef notyet
+ else if (p[0] == 0xf0 && p[1] == 0xf0)
+ netbios_print(p, length);
+#endif
+ if (llc.ssap == LLCSAP_ISONS && llc.dsap == LLCSAP_ISONS
+ && llc.llcui == LLC_UI) {
+ isoclns_print(p + 3, length - 3, caplen - 3, esrc, edst);
+ return (1);
+ }
+
+ if (llc.ssap == LLCSAP_SNAP && llc.dsap == LLCSAP_SNAP
+ && llc.llcui == LLC_UI) {
+ if (caplen < sizeof(llc)) {
+ (void)printf("[|llc-snap]");
+ default_print((u_char *)p, caplen);
+ return (0);
+ }
+ if (vflag)
+ (void)printf("snap %s ", protoid_string(llc.llcpi));
+
+ caplen -= sizeof(llc);
+ length -= sizeof(llc);
+ p += sizeof(llc);
+
+ /* This is an encapsulated Ethernet packet */
+ et = EXTRACT_SHORT(&llc.ethertype[0]);
+ ret = ether_encap_print(et, p, length, caplen);
+ if (ret)
+ return (ret);
+ }
+
+ if ((llc.ssap & ~LLC_GSAP) == llc.dsap) {
+ if (eflag)
+ (void)printf("%s ", llcsap_string(llc.dsap));
+ else
+ (void)printf("%s > %s %s ",
+ etheraddr_string(esrc),
+ etheraddr_string(edst),
+ llcsap_string(llc.dsap));
+ } else {
+ if (eflag)
+ (void)printf("%s > %s ",
+ llcsap_string(llc.ssap & ~LLC_GSAP),
+ llcsap_string(llc.dsap));
+ else
+ (void)printf("%s %s > %s %s ",
+ etheraddr_string(esrc),
+ llcsap_string(llc.ssap & ~LLC_GSAP),
+ etheraddr_string(edst),
+ llcsap_string(llc.dsap));
+ }
+
+ if ((llc.llcu & LLC_U_FMT) == LLC_U_FMT) {
+ const char *m;
+ char f;
+ m = tok2str(cmd2str, "%02x", LLC_U_CMD(llc.llcu));
+ switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
+ case 0: f = 'C'; break;
+ case LLC_GSAP: f = 'R'; break;
+ case LLC_U_POLL: f = 'P'; break;
+ case LLC_GSAP|LLC_U_POLL: f = 'F'; break;
+ default: f = '?'; break;
+ }
+
+ printf("%s/%c", m, f);
+
+ p += 3;
+ length -= 3;
+ caplen -= 3;
+
+ if ((llc.llcu & ~LLC_U_POLL) == LLC_XID) {
+ if (*p == LLC_XID_FI) {
+ printf(": %02x %02x", p[1], p[2]);
+ p += 3;
+ length -= 3;
+ caplen -= 3;
+ }
+ }
+ } else {
+ char f;
+ llc.llcis = ntohs(llc.llcis);
+ switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
+ case 0: f = 'C'; break;
+ case LLC_GSAP: f = 'R'; break;
+ case LLC_U_POLL: f = 'P'; break;
+ case LLC_GSAP|LLC_U_POLL: f = 'F'; break;
+ default: f = '?'; break;
+ }
+
+ if ((llc.llcu & LLC_S_FMT) == LLC_S_FMT) {
+ static char *llc_s[] = { "rr", "rej", "rnr", "03" };
+ (void)printf("%s (r=%d,%c)",
+ llc_s[LLC_S_CMD(llc.llcis)],
+ LLC_IS_NR(llc.llcis),
+ f);
+ } else {
+ (void)printf("I (s=%d,r=%d,%c)",
+ LLC_I_NS(llc.llcis),
+ LLC_IS_NR(llc.llcis),
+ f);
+ }
+ p += 4;
+ length -= 4;
+ caplen -= 4;
+ }
+ (void)printf(" len=%d", length);
+ if (caplen > 0) {
+ default_print_unaligned(p, caplen);
+ }
+ return(1);
+}
diff --git a/usr.sbin/tcpdump/print-nfs.c b/usr.sbin/tcpdump/print-nfs.c
new file mode 100644
index 00000000000..5ba11d9e989
--- /dev/null
+++ b/usr.sbin/tcpdump/print-nfs.c
@@ -0,0 +1,856 @@
+/* $NetBSD: print-nfs.c,v 1.4 1995/04/24 13:27:45 cgd Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-nfs.c,v 1.41 94/06/12 14:35:15 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#ifdef SOLARIS
+#include <tiuser.h>
+#endif
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#include "nfsv2.h"
+#include "nfsfh.h"
+
+static void nfs_printfh(const u_int32 *);
+static void xid_map_enter(const struct rpc_msg *, const struct ip *);
+static int32 xid_map_find(const struct rpc_msg *, const struct ip *);
+static void interp_reply(const struct rpc_msg *, u_int32, int);
+
+void
+nfsreply_print(register const u_char *bp, int length,
+ register const u_char *bp2)
+{
+ register const struct rpc_msg *rp;
+ register const struct ip *ip;
+ int32 proc;
+
+ rp = (const struct rpc_msg *)bp;
+ ip = (const struct ip *)bp2;
+
+ if (!nflag)
+ (void)printf("%s.nfs > %s.%x: reply %s %d",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst),
+ ntohl(rp->rm_xid),
+ ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED?
+ "ok":"ERR",
+ length);
+ else
+ (void)printf("%s.%x > %s.%x: reply %s %d",
+ ipaddr_string(&ip->ip_src),
+ NFS_PORT,
+ ipaddr_string(&ip->ip_dst),
+ ntohl(rp->rm_xid),
+ ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED?
+ "ok":"ERR",
+ length);
+
+ proc = xid_map_find(rp, ip);
+ if (proc >= 0)
+ interp_reply(rp, (u_int32)proc, length);
+}
+
+/*
+ * Return a pointer to the first file handle in the packet.
+ * If the packet was truncated, return 0.
+ */
+static const u_int32 *
+parsereq(register const struct rpc_msg *rp, register int length)
+{
+ register const u_int32 *dp = (u_int32 *)&rp->rm_call.cb_cred;
+ register const u_int32 *ep = (u_int32 *)snapend;
+ register u_int len;
+
+ if (&dp[2] >= ep)
+ return (0);
+ /*
+ * find the start of the req data (if we captured it)
+ */
+ len = ntohl(dp[1]);
+ if (dp < ep && len < length) {
+ dp += (len + (2 * sizeof(u_int32) + 3)) / sizeof(u_int32);
+ len = ntohl(dp[1]);
+ if ((dp < ep) && (len < length)) {
+ dp += (len + (2 * sizeof(u_int32) + 3)) /
+ sizeof(u_int32);
+ if (dp < ep)
+ return (dp);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Print out an NFS file handle and return a pointer to following word.
+ * If packet was truncated, return 0.
+ */
+static const u_int32 *
+parsefh(register const u_int32 *dp)
+{
+ if (dp + 8 <= (u_int32 *)snapend) {
+ nfs_printfh(dp);
+ return (dp + 8);
+ }
+ return (0);
+}
+
+/*
+ * Print out a file name and return pointer to 32-bit word past it.
+ * If packet was truncated, return 0.
+ */
+static const u_int32 *
+parsefn(register const u_int32 *dp)
+{
+ register u_int32 len;
+ register const u_char *cp;
+
+ /* Bail if we don't have the string length */
+ if ((u_char *)dp > snapend - sizeof(*dp))
+ return(0);
+
+ /* Fetch string length; convert to host order */
+ len = *dp++;
+ NTOHL(len);
+
+ cp = (u_char *)dp;
+ /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */
+ dp += ((len + 3) & ~3) / sizeof(*dp);
+ if ((u_char *)dp > snapend)
+ return (0);
+ /* XXX seems like we should be checking the length */
+ (void) fn_printn(cp, len, NULL);
+
+ return (dp);
+}
+
+/*
+ * Print out file handle and file name.
+ * Return pointer to 32-bit word past file name.
+ * If packet was truncated (or there was some other error), return 0.
+ */
+static const u_int32 *
+parsefhn(register const u_int32 *dp)
+{
+ dp = parsefh(dp);
+ if (dp == 0)
+ return (0);
+ putchar(' ');
+ return (parsefn(dp));
+}
+
+void
+nfsreq_print(register const u_char *bp, int length, register const u_char *bp2)
+{
+ register const struct rpc_msg *rp;
+ register const struct ip *ip;
+ register const u_int32 *dp;
+ register const u_char *ep;
+
+#define TCHECK(p, l) if ((u_char *)(p) > ep - l) break
+
+ rp = (const struct rpc_msg *)bp;
+ ip = (const struct ip *)bp2;
+ ep = snapend;
+ if (!nflag)
+ (void)printf("%s.%x > %s.nfs: %d",
+ ipaddr_string(&ip->ip_src),
+ ntohl(rp->rm_xid),
+ ipaddr_string(&ip->ip_dst),
+ length);
+ else
+ (void)printf("%s.%x > %s.%x: %d",
+ ipaddr_string(&ip->ip_src),
+ ntohl(rp->rm_xid),
+ ipaddr_string(&ip->ip_dst),
+ NFS_PORT,
+ length);
+
+ xid_map_enter(rp, ip); /* record proc number for later on */
+
+ switch (ntohl(rp->rm_call.cb_proc)) {
+#ifdef NFSPROC_NOOP
+ case NFSPROC_NOOP:
+ printf(" nop");
+ return;
+#else
+#define NFSPROC_NOOP -1
+#endif
+ case NFSPROC_NULL:
+ printf(" null");
+ return;
+
+ case NFSPROC_GETATTR:
+ printf(" getattr");
+ if ((dp = parsereq(rp, length)) != 0 && parsefh(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_SETATTR:
+ printf(" setattr");
+ if ((dp = parsereq(rp, length)) != 0 && parsefh(dp) != 0)
+ return;
+ break;
+
+#if NFSPROC_ROOT != NFSPROC_NOOP
+ case NFSPROC_ROOT:
+ printf(" root");
+ break;
+#endif
+ case NFSPROC_LOOKUP:
+ printf(" lookup");
+ if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_READLINK:
+ printf(" readlink");
+ if ((dp = parsereq(rp, length)) != 0 && parsefh(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_READ:
+ printf(" read");
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefh(dp)) != 0) {
+ TCHECK(dp, 3 * sizeof(*dp));
+ printf(" %lu bytes @ %lu",
+ ntohl(dp[1]), ntohl(dp[0]));
+ return;
+ }
+ break;
+
+#if NFSPROC_WRITECACHE != NFSPROC_NOOP
+ case NFSPROC_WRITECACHE:
+ printf(" writecache");
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefh(dp)) != 0) {
+ TCHECK(dp, 4 * sizeof(*dp));
+ printf(" %lu (%lu) bytes @ %lu (%lu)",
+ ntohl(dp[3]), ntohl(dp[2]),
+ ntohl(dp[1]), ntohl(dp[0]));
+ return;
+ }
+ break;
+#endif
+ case NFSPROC_WRITE:
+ printf(" write");
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefh(dp)) != 0) {
+ TCHECK(dp, 4 * sizeof(*dp));
+ printf(" %lu (%lu) bytes @ %lu (%lu)",
+ ntohl(dp[3]), ntohl(dp[2]),
+ ntohl(dp[1]), ntohl(dp[0]));
+ return;
+ }
+ break;
+
+ case NFSPROC_CREATE:
+ printf(" create");
+ if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_REMOVE:
+ printf(" remove");
+ if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_RENAME:
+ printf(" rename");
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefhn(dp)) != 0) {
+ fputs(" ->", stdout);
+ if (parsefhn(dp) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_LINK:
+ printf(" link");
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefh(dp)) != 0) {
+ fputs(" ->", stdout);
+ if (parsefhn(dp) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_SYMLINK:
+ printf(" symlink");
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefhn(dp)) != 0) {
+ fputs(" -> ", stdout);
+ if (parsefn(dp) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_MKDIR:
+ printf(" mkdir");
+ if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_RMDIR:
+ printf(" rmdir");
+ if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_READDIR:
+ printf(" readdir");
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefh(dp)) != 0) {
+ TCHECK(dp, 2 * sizeof(*dp));
+ /*
+ * Print the offset as signed, since -1 is common,
+ * but offsets > 2^31 aren't.
+ */
+ printf(" %lu bytes @ %ld", ntohl(dp[1]), ntohl(dp[0]));
+ return;
+ }
+ break;
+
+ case NFSPROC_STATFS:
+ printf(" statfs");
+ if ((dp = parsereq(rp, length)) != 0 && parsefh(dp) != 0)
+ return;
+ break;
+
+ default:
+ printf(" proc-%lu", ntohl(rp->rm_call.cb_proc));
+ return;
+ }
+ fputs(" [|nfs]", stdout);
+#undef TCHECK
+}
+
+/*
+ * Print out an NFS file handle.
+ * We assume packet was not truncated before the end of the
+ * file handle pointed to by dp.
+ *
+ * Note: new version (using portable file-handle parser) doesn't produce
+ * generation number. It probably could be made to do that, with some
+ * additional hacking on the parser code.
+ */
+static void
+nfs_printfh(register const u_int32 *dp)
+{
+ my_fsid fsid;
+ ino_t ino;
+ char *sfsname = NULL;
+
+ Parse_fh((caddr_t*)dp, &fsid, &ino, NULL, &sfsname, 0);
+
+ if (sfsname) {
+ /* file system ID is ASCII, not numeric, for this server OS */
+ static char temp[NFS_FHSIZE+1];
+
+ /* Make sure string is null-terminated */
+ strncpy(temp, sfsname, NFS_FHSIZE);
+ /* Remove trailing spaces */
+ sfsname = strchr(temp, ' ');
+ if (sfsname)
+ *sfsname = 0;
+
+ (void)printf(" fh %s/%ld", temp, ino);
+ }
+ else {
+ (void)printf(" fh %d,%d/%ld",
+ fsid.fsid_dev.Major, fsid.fsid_dev.Minor,
+ ino);
+ }
+}
+
+/*
+ * Maintain a small cache of recent client.XID.server/proc pairs, to allow
+ * us to match up replies with requests and thus to know how to parse
+ * the reply.
+ */
+
+struct xid_map_entry {
+ u_int32 xid; /* transaction ID (net order) */
+ struct in_addr client; /* client IP address (net order) */
+ struct in_addr server; /* server IP address (net order) */
+ u_int32 proc; /* call proc number (host order) */
+};
+
+/*
+ * Map entries are kept in an array that we manage as a ring;
+ * new entries are always added at the tail of the ring. Initially,
+ * all the entries are zero and hence don't match anything.
+ */
+
+#define XIDMAPSIZE 64
+
+struct xid_map_entry xid_map[XIDMAPSIZE];
+
+int xid_map_next = 0;
+int xid_map_hint = 0;
+
+static void
+xid_map_enter(const struct rpc_msg *rp, const struct ip *ip)
+{
+ struct xid_map_entry *xmep;
+
+ xmep = &xid_map[xid_map_next];
+
+ if (++xid_map_next >= XIDMAPSIZE)
+ xid_map_next = 0;
+
+ xmep->xid = rp->rm_xid;
+ xmep->client = ip->ip_src;
+ xmep->server = ip->ip_dst;
+ xmep->proc = ntohl(rp->rm_call.cb_proc);
+}
+
+/* Returns NFSPROC_xxx or -1 on failure */
+static int32
+xid_map_find(const struct rpc_msg *rp, const struct ip *ip)
+{
+ int i;
+ struct xid_map_entry *xmep;
+ u_int32 xid = rp->rm_xid;
+ u_int32 clip = ip->ip_dst.s_addr;
+ u_int32 sip = ip->ip_src.s_addr;
+
+ /* Start searching from where we last left off */
+ i = xid_map_hint;
+ do {
+ xmep = &xid_map[i];
+ if (xmep->xid == xid && xmep->client.s_addr == clip &&
+ xmep->server.s_addr == sip) {
+ /* match */
+ xid_map_hint = i;
+ return ((int32)xmep->proc);
+ }
+ if (++i >= XIDMAPSIZE)
+ i = 0;
+ } while (i != xid_map_hint);
+
+ /* search failed */
+ return(-1);
+}
+
+/*
+ * Routines for parsing reply packets
+ */
+
+/*
+ * Return a pointer to the beginning of the actual results.
+ * If the packet was truncated, return 0.
+ */
+static const u_int32 *
+parserep(register const struct rpc_msg *rp, register int length)
+{
+ register const u_int32 *dp;
+ register const u_int32 *ep = (const u_int32 *)snapend;
+ int len;
+ enum accept_stat astat;
+
+ /*
+ * Portability note:
+ * Here we find the address of the ar_verf credentials.
+ * Originally, this calculation was
+ * dp = (u_int32 *)&rp->rm_reply.rp_acpt.ar_verf
+ * On the wire, the rp_acpt field starts immediately after
+ * the (32 bit) rp_stat field. However, rp_acpt (which is a
+ * "struct accepted_reply") contains a "struct opaque_auth",
+ * whose internal representation contains a pointer, so on a
+ * 64-bit machine the compiler inserts 32 bits of padding
+ * before rp->rm_reply.rp_acpt.ar_verf. So, we cannot use
+ * the internal representation to parse the on-the-wire
+ * representation. Instead, we skip past the rp_stat field,
+ * which is an "enum" and so occupies one 32-bit word.
+ */
+ dp = ((const u_int32 *)&rp->rm_reply) + 1;
+ if (&dp[1] >= ep)
+ return(0);
+ len = ntohl(dp[1]);
+ if (len >= length)
+ return(0);
+ /*
+ * skip past the ar_verf credentials.
+ */
+ dp += (len + (2*sizeof(u_int32) + 3)) / sizeof(u_int32);
+ if (dp >= ep)
+ return(0);
+
+ /*
+ * now we can check the ar_stat field
+ */
+ astat = ntohl(*(enum accept_stat *)dp);
+ switch (astat) {
+
+ case SUCCESS:
+ break;
+
+ case PROG_UNAVAIL:
+ printf(" PROG_UNAVAIL");
+ return(0);
+
+ case PROG_MISMATCH:
+ printf(" PROG_MISMATCH");
+ return(0);
+
+ case PROC_UNAVAIL:
+ printf(" PROC_UNAVAIL");
+ return(0);
+
+ case GARBAGE_ARGS:
+ printf(" GARBAGE_ARGS");
+ return(0);
+
+ case SYSTEM_ERR:
+ printf(" SYSTEM_ERR");
+ return(0);
+
+ default:
+ printf(" ar_stat %d", astat);
+ return(0);
+ }
+ /* successful return */
+ if ((sizeof(astat) + ((char *)dp)) < (char *)ep)
+ return((u_int32 *) (sizeof(astat) + ((char *)dp)));
+
+ return (0);
+}
+
+#define T2CHECK(p, l) if ((u_char *)(p) > ((u_char *)snapend) - l) return(0)
+
+/*
+ * Not all systems have strerror().
+ */
+static char *
+strerr(int errno)
+{
+
+ return (strerror(errno));
+}
+
+static const u_int32 *
+parsestatus(const u_int32 *dp)
+{
+ int errno;
+ T2CHECK(dp, 4);
+
+ errno = ntohl(dp[0]);
+ if (errno != 0) {
+ char *errmsg;
+
+ if (qflag)
+ return(0);
+
+ errmsg = strerr(errno);
+ if (errmsg)
+ printf(" ERROR: %s", errmsg);
+ else
+ printf(" ERROR: %d", errno);
+ return(0);
+ }
+ return (dp + 1);
+}
+
+static struct token type2str[] = {
+ { NFNON, "NON" },
+ { NFREG, "REG" },
+ { NFDIR, "DIR" },
+ { NFBLK, "BLK" },
+ { NFCHR, "CHR" },
+ { NFLNK, "LNK" },
+ { 0, NULL }
+};
+
+static const u_int32 *
+parsefattr(const u_int32 *dp, int verbose)
+{
+ const struct nfsv2_fattr *fap;
+
+ T2CHECK(dp, 4);
+
+ fap = (const struct nfsv2_fattr *)dp;
+ if (verbose)
+ printf(" %s %o ids %d/%d sz %d ",
+ tok2str(type2str, "unk-ft %d ", ntohl(fap->fa_type)),
+ ntohl(fap->fa_mode), ntohl(fap->fa_uid),
+ ntohl(fap->fa_gid), ntohl(fap->fa_nfssize));
+ /* print lots more stuff */
+ if (verbose > 1) {
+ printf("nlink %d rdev %x fsid %x nodeid %x a/m/ctime ",
+ ntohl(fap->fa_nlink), ntohl(fap->fa_nfsrdev),
+ ntohl(fap->fa_nfsfsid), ntohl(fap->fa_nfsfileid));
+ printf("%d.%06d ",
+ ntohl(fap->fa_nfsatime.nfs_sec),
+ ntohl(fap->fa_nfsatime.nfs_usec));
+ printf("%d.%06d ",
+ ntohl(fap->fa_nfsmtime.nfs_sec),
+ ntohl(fap->fa_nfsmtime.nfs_usec));
+ printf("%d.%06d ",
+ ntohl(fap->fa_nfsctime.nfs_sec),
+ ntohl(fap->fa_nfsctime.nfs_usec));
+ }
+ return ((const u_int32 *)&fap[1]);
+}
+
+static int
+parseattrstat(const u_int32 *dp, int verbose)
+{
+ dp = parsestatus(dp);
+ if (dp == NULL)
+ return (0);
+
+ return ((long)parsefattr(dp, verbose));
+}
+
+static int
+parsediropres(const u_int32 *dp)
+{
+ dp = parsestatus(dp);
+ if (dp == NULL)
+ return (0);
+
+ dp = parsefh(dp);
+ if (dp == NULL)
+ return (0);
+
+ return (parsefattr(dp, vflag) != NULL);
+}
+
+static int
+parselinkres(const u_int32 *dp)
+{
+ dp = parsestatus(dp);
+ if (dp == NULL)
+ return(0);
+
+ putchar(' ');
+ return (parsefn(dp) != NULL);
+}
+
+static int
+parsestatfs(const u_int32 *dp)
+{
+ const struct nfsv2_statfs *sfsp;
+
+ dp = parsestatus(dp);
+ if (dp == NULL)
+ return(0);
+
+ if (qflag)
+ return(1);
+
+ T2CHECK(dp, 20);
+
+ sfsp = (const struct nfsv2_statfs *)dp;
+ printf(" tsize %d bsize %d blocks %d bfree %d bavail %d",
+ ntohl(sfsp->sf_tsize), ntohl(sfsp->sf_bsize),
+ ntohl(sfsp->sf_blocks), ntohl(sfsp->sf_bfree),
+ ntohl(sfsp->sf_bavail));
+
+ return (1);
+}
+
+static int
+parserddires(const u_int32 *dp)
+{
+ dp = parsestatus(dp);
+ if (dp == 0)
+ return (0);
+ if (qflag)
+ return (1);
+
+ T2CHECK(dp, 12);
+ printf(" offset %x size %d ", ntohl(dp[0]), ntohl(dp[1]));
+ if (dp[2] != 0)
+ printf("eof");
+
+ return (1);
+}
+
+static void
+interp_reply(const struct rpc_msg *rp, u_int32 proc, int length)
+{
+ register const u_int32 *dp;
+
+ switch (proc) {
+
+#ifdef NFSPROC_NOOP
+ case NFSPROC_NOOP:
+ printf(" nop");
+ return;
+#else
+#define NFSPROC_NOOP -1
+#endif
+ case NFSPROC_NULL:
+ printf(" null");
+ return;
+
+ case NFSPROC_GETATTR:
+ printf(" getattr");
+ dp = parserep(rp, length);
+ if (dp != 0 && parseattrstat(dp, !qflag) != 0)
+ return;
+ break;
+
+ case NFSPROC_SETATTR:
+ printf(" setattr");
+ dp = parserep(rp, length);
+ if (dp != 0 && parseattrstat(dp, !qflag) != 0)
+ return;
+ break;
+
+#if NFSPROC_ROOT != NFSPROC_NOOP
+ case NFSPROC_ROOT:
+ printf(" root");
+ break;
+#endif
+ case NFSPROC_LOOKUP:
+ printf(" lookup");
+ dp = parserep(rp, length);
+ if (dp != 0 && parsediropres(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_READLINK:
+ printf(" readlink");
+ dp = parserep(rp, length);
+ if (dp != 0 && parselinkres(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_READ:
+ printf(" read");
+ dp = parserep(rp, length);
+ if (dp != 0 && parseattrstat(dp, vflag) != 0)
+ return;
+ break;
+
+#if NFSPROC_WRITECACHE != NFSPROC_NOOP
+ case NFSPROC_WRITECACHE:
+ printf(" writecache");
+ break;
+#endif
+ case NFSPROC_WRITE:
+ printf(" write");
+ dp = parserep(rp, length);
+ if (dp != 0 && parseattrstat(dp, vflag) != 0)
+ return;
+ break;
+
+ case NFSPROC_CREATE:
+ printf(" create");
+ dp = parserep(rp, length);
+ if (dp != 0 && parsediropres(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_REMOVE:
+ printf(" remove");
+ dp = parserep(rp, length);
+ if (dp != 0 && parsestatus(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_RENAME:
+ printf(" rename");
+ dp = parserep(rp, length);
+ if (dp != 0 && parsestatus(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_LINK:
+ printf(" link");
+ dp = parserep(rp, length);
+ if (dp != 0 && parsestatus(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_SYMLINK:
+ printf(" symlink");
+ dp = parserep(rp, length);
+ if (dp != 0 && parsestatus(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_MKDIR:
+ printf(" mkdir");
+ dp = parserep(rp, length);
+ if (dp != 0 && parsediropres(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_RMDIR:
+ printf(" rmdir");
+ dp = parserep(rp, length);
+ if (dp != 0 && parsestatus(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_READDIR:
+ printf(" readdir");
+ dp = parserep(rp, length);
+ if (dp != 0 && parserddires(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_STATFS:
+ printf(" statfs");
+ dp = parserep(rp, length);
+ if (dp != 0 && parsestatfs(dp) != 0)
+ return;
+ break;
+
+ default:
+ printf(" proc-%lu", proc);
+ return;
+ }
+ fputs(" [|nfs]", stdout);
+}
diff --git a/usr.sbin/tcpdump/print-ntp.c b/usr.sbin/tcpdump/print-ntp.c
new file mode 100644
index 00000000000..ed92f695224
--- /dev/null
+++ b/usr.sbin/tcpdump/print-ntp.c
@@ -0,0 +1,287 @@
+/* $NetBSD: print-ntp.c,v 1.2 1995/03/06 19:11:22 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print ntp packets.
+ * By Jeffrey Mogul/DECWRL
+ * loosely based on print-bootp.c
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-ntp.c,v 1.14 94/06/14 20:18:46 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#undef MODEMASK /* Solaris sucks */
+#include "ntp.h"
+
+static void p_sfix(const struct s_fixedpt *);
+static void p_ntp_time(const struct l_fixedpt *);
+static void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *);
+
+/*
+ * Print ntp requests
+ */
+void
+ntp_print(register const u_char *cp, int length)
+{
+ register const struct ntpdata *bp;
+ register const u_char *ep;
+ int mode, version, leapind;
+ static char rclock[5];
+
+#define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc
+
+ bp = (struct ntpdata *)cp;
+ /* Note funny sized packets */
+ if (length != sizeof(struct ntpdata))
+ (void)printf(" [len=%d]", length);
+
+ /* 'ep' points to the end of avaible data. */
+ ep = snapend;
+
+ TCHECK(bp->status, sizeof(bp->status));
+
+ version = (bp->status & VERSIONMASK) >> 3;
+ printf(" v%d", version);
+
+ leapind = bp->status & LEAPMASK;
+ switch (leapind) {
+
+ case NO_WARNING:
+ break;
+
+ case PLUS_SEC:
+ fputs(" +1s", stdout);
+ break;
+
+ case MINUS_SEC:
+ fputs(" -1s", stdout);
+ break;
+ }
+
+ mode = bp->status & MODEMASK;
+ switch (mode) {
+
+ case MODE_UNSPEC: /* unspecified */
+ fputs(" unspec", stdout);
+ break;
+
+ case MODE_SYM_ACT: /* symmetric active */
+ fputs(" sym_act", stdout);
+ break;
+
+ case MODE_SYM_PAS: /* symmetric passive */
+ fputs(" sym_pas", stdout);
+ break;
+
+ case MODE_CLIENT: /* client */
+ fputs(" client", stdout);
+ break;
+
+ case MODE_SERVER: /* server */
+ fputs(" server", stdout);
+ break;
+
+ case MODE_BROADCAST: /* broadcast */
+ fputs(" bcast", stdout);
+ break;
+
+ case MODE_RES1: /* reserved */
+ fputs(" res1", stdout);
+ break;
+
+ case MODE_RES2: /* reserved */
+ fputs(" res2", stdout);
+ break;
+
+ }
+
+ TCHECK(bp->stratum, sizeof(bp->stratum));
+ printf(" strat %d", bp->stratum);
+
+ TCHECK(bp->ppoll, sizeof(bp->ppoll));
+ printf(" poll %d", bp->ppoll);
+
+ /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */
+ TCHECK(bp->distance, 0);
+ printf(" prec %d", bp->precision);
+
+ if (!vflag)
+ return;
+
+ TCHECK(bp->distance, sizeof(bp->distance));
+ fputs(" dist ", stdout);
+ p_sfix(&bp->distance);
+
+ TCHECK(bp->dispersion, sizeof(bp->dispersion));
+ fputs(" disp ", stdout);
+ p_sfix(&bp->dispersion);
+
+ TCHECK(bp->refid, sizeof(bp->refid));
+ fputs(" ref ", stdout);
+ /* Interpretation depends on stratum */
+ switch (bp->stratum) {
+
+ case UNSPECIFIED:
+ case PRIM_REF:
+ strncpy(rclock, (char *)&(bp->refid), 4);
+ rclock[4] = '\0';
+ fputs(rclock, stdout);
+ break;
+
+ case INFO_QUERY:
+ printf("%s INFO_QUERY", ipaddr_string(&(bp->refid)));
+ /* this doesn't have more content */
+ return;
+
+ case INFO_REPLY:
+ printf("%s INFO_REPLY", ipaddr_string(&(bp->refid)));
+ /* this is too complex to be worth printing */
+ return;
+
+ default:
+ printf("%s", ipaddr_string(&(bp->refid)));
+ break;
+ }
+
+ TCHECK(bp->reftime, sizeof(bp->reftime));
+ putchar('@');
+ p_ntp_time(&(bp->reftime));
+
+ TCHECK(bp->org, sizeof(bp->org));
+ fputs(" orig ", stdout);
+ p_ntp_time(&(bp->org));
+
+ TCHECK(bp->rec, sizeof(bp->rec));
+ fputs(" rec ", stdout);
+ p_ntp_delta(&(bp->org), &(bp->rec));
+
+ TCHECK(bp->xmt, sizeof(bp->xmt));
+ fputs(" xmt ", stdout);
+ p_ntp_delta(&(bp->org), &(bp->xmt));
+
+ return;
+
+trunc:
+ fputs(" [|ntp]", stdout);
+#undef TCHECK
+}
+
+static void
+p_sfix(register const struct s_fixedpt *sfp)
+{
+ register int i;
+ register int f;
+ register float ff;
+
+ i = ntohs(sfp->int_part);
+ f = ntohs(sfp->fraction);
+ ff = f / 65536.0; /* shift radix point by 16 bits */
+ f = ff * 1000000.0; /* Treat fraction as parts per million */
+ printf("%d.%06d", i, f);
+}
+
+#define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */
+
+static void
+p_ntp_time(register const struct l_fixedpt *lfp)
+{
+ register int32 i;
+ register u_int32 uf;
+ register u_int32 f;
+ register float ff;
+
+ i = ntohl(lfp->int_part);
+ uf = ntohl(lfp->fraction);
+ ff = uf;
+ if (ff < 0.0) /* some compilers are buggy */
+ ff += FMAXINT;
+ ff = ff / FMAXINT; /* shift radix point by 32 bits */
+ f = ff * 1000000000.0; /* treat fraction as parts per billion */
+ printf("%lu.%09d", i, f);
+}
+
+/* Prints time difference between *lfp and *olfp */
+static void
+p_ntp_delta(register const struct l_fixedpt *olfp,
+ register const struct l_fixedpt *lfp)
+{
+ register int32 i;
+ register u_int32 uf;
+ register u_int32 ouf;
+ register u_int32 f;
+ register float ff;
+ int signbit;
+
+ i = ntohl(lfp->int_part) - ntohl(olfp->int_part);
+
+ uf = ntohl(lfp->fraction);
+ ouf = ntohl(olfp->fraction);
+
+ if (i > 0) { /* new is definitely greater than old */
+ signbit = 0;
+ f = uf - ouf;
+ if (ouf > uf) /* must borrow from high-order bits */
+ i -= 1;
+ } else if (i < 0) { /* new is definitely less than old */
+ signbit = 1;
+ f = ouf - uf;
+ if (uf > ouf) /* must carry into the high-order bits */
+ i += 1;
+ i = -i;
+ } else { /* int_part is zero */
+ if (uf > ouf) {
+ signbit = 0;
+ f = uf - ouf;
+ } else {
+ signbit = 1;
+ f = ouf - uf;
+ }
+ }
+
+ ff = f;
+ if (ff < 0.0) /* some compilers are buggy */
+ ff += FMAXINT;
+ ff = ff / FMAXINT; /* shift radix point by 32 bits */
+ f = ff * 1000000000.0; /* treat fraction as parts per billion */
+ if (signbit)
+ putchar('-');
+ else
+ putchar('+');
+ printf("%d.%09d", i, f);
+}
diff --git a/usr.sbin/tcpdump/print-null.c b/usr.sbin/tcpdump/print-null.c
new file mode 100644
index 00000000000..69a34566897
--- /dev/null
+++ b/usr.sbin/tcpdump/print-null.c
@@ -0,0 +1,113 @@
+/* $NetBSD: print-null.c,v 1.3 1995/03/06 19:11:24 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#)Header: print-null.c,v 1.14 94/06/10 17:01:35 mccanne Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "pcap.h"
+
+#define NULL_HDRLEN 4
+
+static void
+null_print(const u_char *p, const struct ip *ip, int length)
+{
+ u_int family;
+
+ bcopy(p, &family, sizeof(family));
+
+ if (nflag) {
+ /* XXX just dump the header */
+ return;
+ }
+ switch (family) {
+
+ case AF_INET:
+ printf("ip: ");
+ break;
+
+ case AF_NS:
+ printf("ns: ");
+ break;
+
+ default:
+ printf("AF %d: ", family);
+ break;
+ }
+}
+
+void
+null_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+ int length = h->len;
+ int caplen = h->caplen;
+ const struct ip *ip;
+
+ ts_print(&h->ts);
+
+ /*
+ * Some printers want to get back at the link level addresses,
+ * and/or check that they're not walking off the end of the packet.
+ * Rather than pass them all the way down, we set these globals.
+ */
+ packetp = p;
+ snapend = p + caplen;
+
+ length -= NULL_HDRLEN;
+
+ ip = (struct ip *)(p + NULL_HDRLEN);
+
+ if (eflag)
+ null_print(p, ip, length);
+
+ ip_print((const u_char *)ip, length);
+
+ if (xflag)
+ default_print((const u_char *)ip, caplen - NULL_HDRLEN);
+ putchar('\n');
+}
+
diff --git a/usr.sbin/tcpdump/print-ospf.c b/usr.sbin/tcpdump/print-ospf.c
new file mode 100644
index 00000000000..90ffecf9dd7
--- /dev/null
+++ b/usr.sbin/tcpdump/print-ospf.c
@@ -0,0 +1,580 @@
+/* $NetBSD: print-ospf.c,v 1.3 1995/03/06 19:11:25 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-ospf.c,v 1.12 94/06/14 20:18:46 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <errno.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#include "ospf.h"
+
+#ifndef __GNUC__
+#define inline
+#endif
+
+struct bits {
+ u_int32 bit;
+ const char *str;
+};
+
+static const struct bits ospf_option_bits[] = {
+ { OSPF_OPTION_T, "T" },
+ { OSPF_OPTION_E, "E" },
+ { OSPF_OPTION_MC, "MC" },
+ { 0, NULL }
+};
+
+static const struct bits ospf_rla_flag_bits[] = {
+ { RLA_FLAG_B, "B" },
+ { RLA_FLAG_E, "E" },
+ { RLA_FLAG_W1, "W1" },
+ { RLA_FLAG_W2, "W2" },
+ { 0, NULL }
+};
+
+static const char *ospf_types[OSPF_TYPE_MAX] = {
+ (char *) 0,
+ "hello",
+ "dd",
+ "ls_req",
+ "ls_upd",
+ "ls_ack"
+};
+
+static inline void
+ospf_print_seqage(register u_int32 seq, register time_t us)
+{
+ register time_t sec = us % 60;
+ register time_t mins = (us / 60) % 60;
+ register time_t hour = us/3600;
+
+ printf(" S %X age ",
+ seq);
+ if (hour) {
+ printf("%d:%02d:%02d",
+ hour,
+ mins,
+ sec);
+ } else if (mins) {
+ printf("%d:%02d",
+ mins,
+ sec);
+ } else {
+ printf("%d",
+ sec);
+ }
+}
+
+
+static inline void
+ospf_print_bits(register const struct bits *bp, register u_char options)
+{
+ char sep = ' ';
+
+ do {
+ if (options & bp->bit) {
+ printf("%c%s",
+ sep,
+ bp->str);
+ sep = '/';
+ }
+ } while ((++bp)->bit) ;
+}
+
+
+#define LS_PRINT(lsp, type) switch (type) { \
+ case LS_TYPE_ROUTER: \
+ printf(" rtr %s ", ipaddr_string(&lsp->ls_router)); break; \
+ case LS_TYPE_NETWORK: \
+ printf(" net dr %s if %s", ipaddr_string(&lsp->ls_router), ipaddr_string(&lsp->ls_stateid)); break; \
+ case LS_TYPE_SUM_IP: \
+ printf(" sum %s abr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
+ case LS_TYPE_SUM_ABR: \
+ printf(" abr %s rtr %s", ipaddr_string(&lsp->ls_router), ipaddr_string(&lsp->ls_stateid)); break; \
+ case LS_TYPE_ASE: \
+ printf(" ase %s asbr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
+ case LS_TYPE_GROUP: \
+ printf(" group %s rtr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
+ }
+
+static int
+ospf_print_lshdr(register const struct lsa_hdr *lshp, const caddr_t end)
+{
+ if ((caddr_t) (lshp + 1) > end) {
+ return 1;
+ }
+
+ printf(" {"); /* } (ctags) */
+
+ if (!lshp->ls_type || lshp->ls_type >= LS_TYPE_MAX) {
+ printf(" ??LS type %d?? }", /* { (ctags) */
+ lshp->ls_type);
+ return 1;
+ }
+
+ ospf_print_bits(ospf_option_bits, lshp->ls_options);
+ ospf_print_seqage(ntohl(lshp->ls_seq),
+ ntohs(lshp->ls_age));
+
+ LS_PRINT(lshp, lshp->ls_type);
+
+ return 0;
+}
+
+
+/*
+ * Print a single link state advertisement. If truncated return 1, else 0.
+ */
+
+static int
+ospf_print_lsa(register const struct lsa *lsap, const caddr_t end)
+{
+ register const char *ls_end;
+ const struct rlalink *rlp;
+ const struct tos_metric *tosp;
+ const struct in_addr *ap;
+ const struct aslametric *almp;
+ const struct mcla *mcp;
+ const u_int32 *lp;
+ int j, k;
+
+ if (ospf_print_lshdr(&lsap->ls_hdr, end)) {
+ return 1;
+ }
+
+ ls_end = (caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length);
+
+ if (ls_end > end) {
+ printf(" }"); /* { (ctags) */
+ return 1;
+ }
+
+ switch (lsap->ls_hdr.ls_type) {
+ case LS_TYPE_ROUTER:
+ ospf_print_bits(ospf_rla_flag_bits, lsap->lsa_un.un_rla.rla_flags);
+
+ j = ntohs(lsap->lsa_un.un_rla.rla_count);
+ rlp = lsap->lsa_un.un_rla.rla_link;
+ while (j--) {
+ struct rlalink *rln = (struct rlalink *) ((caddr_t) (rlp + 1) + ((rlp->link_toscount) * sizeof (struct tos_metric)));
+
+ if ((caddr_t) rln > ls_end) {
+ break;
+ }
+ printf(" {"); /* } (ctags) */
+
+ switch (rlp->link_type) {
+ case RLA_TYPE_VIRTUAL:
+ printf(" virt");
+ /* Fall through */
+
+ case RLA_TYPE_ROUTER:
+ printf(" nbrid %s if %s",
+ ipaddr_string(&rlp->link_id),
+ ipaddr_string(&rlp->link_data));
+ break;
+
+ case RLA_TYPE_TRANSIT:
+ printf(" dr %s if %s",
+ ipaddr_string(&rlp->link_id),
+ ipaddr_string(&rlp->link_data));
+ break;
+
+ case RLA_TYPE_STUB:
+ printf(" net %s mask %s",
+ ipaddr_string(&rlp->link_id),
+ ipaddr_string(&rlp->link_data));
+ break;
+
+ default:
+ printf(" ??RouterLinksType %d?? }", /* { (ctags) */
+ rlp->link_type);
+ return 0;
+ }
+ printf(" tos 0 metric %d",
+ ntohs(rlp->link_tos0metric));
+ tosp = (struct tos_metric *) ((sizeof rlp->link_tos0metric) + (caddr_t) rlp);
+ for (k = 0; k < rlp->link_toscount; k++, tosp++) {
+ printf(" tos %d metric %d",
+ ntohs(tosp->tos_type),
+ ntohs(tosp->tos_metric));
+ }
+ printf(" }"); /* { (ctags) */
+ rlp = rln;
+ }
+ break;
+
+ case LS_TYPE_NETWORK:
+ printf(" mask %s rtrs",
+ ipaddr_string(&lsap->lsa_un.un_nla.nla_mask));
+ for (ap = lsap->lsa_un.un_nla.nla_router;
+ (caddr_t) (ap + 1) <= ls_end;
+ ap++) {
+ printf(" %s",
+ ipaddr_string(ap));
+ }
+ break;
+
+ case LS_TYPE_SUM_IP:
+ printf(" mask %s",
+ ipaddr_string(&lsap->lsa_un.un_sla.sla_mask));
+ /* Fall through */
+
+ case LS_TYPE_SUM_ABR:
+
+ for (lp = lsap->lsa_un.un_sla.sla_tosmetric;
+ (caddr_t) (lp + 1) <= ls_end;
+ lp++) {
+ u_int32 ul = ntohl(*lp);
+
+ printf(" tos %d metric %d",
+ (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
+ ul & SLA_MASK_METRIC);
+ }
+ break;
+
+ case LS_TYPE_ASE:
+ printf(" mask %s",
+ ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));
+
+ for (almp = lsap->lsa_un.un_asla.asla_metric;
+ (caddr_t) (almp + 1) <= ls_end;
+ almp++) {
+ u_int32 ul = ntohl(almp->asla_tosmetric);
+
+ printf(" type %d tos %d metric %d",
+ (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1,
+ (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS,
+ (ul & ASLA_MASK_METRIC));
+ if (almp->asla_forward.s_addr) {
+ printf(" forward %s",
+ ipaddr_string(&almp->asla_forward));
+ }
+ if (almp->asla_tag.s_addr) {
+ printf(" tag %s",
+ ipaddr_string(&almp->asla_tag));
+ }
+ }
+ break;
+
+ case LS_TYPE_GROUP:
+ /* Multicast extensions as of 23 July 1991 */
+ for (mcp = lsap->lsa_un.un_mcla;
+ (caddr_t) (mcp + 1) <= ls_end;
+ mcp++) {
+ switch (ntohl(mcp->mcla_vtype)) {
+ case MCLA_VERTEX_ROUTER:
+ printf(" rtr rtrid %s",
+ ipaddr_string(&mcp->mcla_vid));
+ break;
+
+ case MCLA_VERTEX_NETWORK:
+ printf(" net dr %s",
+ ipaddr_string(&mcp->mcla_vid));
+ break;
+
+ default:
+ printf(" ??VertexType %d??",
+ ntohl(mcp->mcla_vtype));
+ break;
+ }
+ }
+ }
+
+ printf(" }"); /* { (ctags) */
+ return 0;
+}
+
+
+void
+ospf_print(register const u_char *bp, register int length,
+ register const u_char *bp2)
+{
+ register const struct ospfhdr *op;
+ register const struct ip *ip;
+ register const caddr_t end = (caddr_t)snapend;
+ register const struct lsa *lsap;
+ register const struct lsa_hdr *lshp;
+ char sep;
+ int i, j;
+ const struct in_addr *ap;
+ const struct lsr *lsrp;
+
+ op = (struct ospfhdr *)bp;
+ ip = (struct ip *)bp2;
+ /* Print the source and destination address */
+ (void) printf("%s > %s:",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+
+ if ((caddr_t) (&op->ospf_len + 1) > end) {
+ goto trunc_test;
+ }
+
+ /* If the type is valid translate it, or just print the type */
+ /* value. If it's not valid, say so and return */
+ if (op->ospf_type || op->ospf_type < OSPF_TYPE_MAX) {
+ printf(" OSPFv%d-%s %d:",
+ op->ospf_version,
+ ospf_types[op->ospf_type],
+ length);
+ } else {
+ printf(" ospf-v%d-??type %d?? %d:",
+ op->ospf_version,
+ op->ospf_type,
+ length);
+ return;
+ }
+
+ if (length != ntohs(op->ospf_len)) {
+ printf(" ??len %d??",
+ ntohs(op->ospf_len));
+ goto trunc_test;
+ }
+
+ if ((caddr_t) (&op->ospf_routerid + 1) > end) {
+ goto trunc_test;
+ }
+
+ /* Print the routerid if it is not the same as the source */
+ if (ip->ip_src.s_addr != op->ospf_routerid.s_addr) {
+ printf(" rtrid %s",
+ ipaddr_string(&op->ospf_routerid));
+ }
+
+ if ((caddr_t) (&op->ospf_areaid + 1) > end) {
+ goto trunc_test;
+ }
+
+ if (op->ospf_areaid.s_addr) {
+ printf(" area %s",
+ ipaddr_string(&op->ospf_areaid));
+ } else {
+ printf(" backbone");
+ }
+
+ if ((caddr_t) (op->ospf_authdata + OSPF_AUTH_SIZE) > end) {
+ goto trunc_test;
+ }
+
+ if (vflag) {
+ /* Print authentication data (should we really do this?) */
+ switch (ntohs(op->ospf_authtype)) {
+ case OSPF_AUTH_NONE:
+ break;
+
+ case OSPF_AUTH_SIMPLE:
+ printf(" auth ");
+ j = 0;
+ for (i = 0; i < sizeof (op->ospf_authdata); i++) {
+ if (!isprint(op->ospf_authdata[i])) {
+ j = 1;
+ break;
+ }
+ }
+ if (j) {
+ /* Print the auth-data as a string of octets */
+ printf("%s.%s",
+ ipaddr_string((struct in_addr *) op->ospf_authdata),
+ ipaddr_string((struct in_addr *) &op->ospf_authdata[sizeof (struct in_addr)]));
+ } else {
+ /* Print the auth-data as a text string */
+ printf("'%.8s'",
+ op->ospf_authdata);
+ }
+ break;
+
+ default:
+ printf(" ??authtype-%d??",
+ ntohs(op->ospf_authtype));
+ return;
+ }
+ }
+
+
+ /* Do rest according to version. */
+ switch (op->ospf_version) {
+ case 2:
+ /* ospf version 2 */
+ switch (op->ospf_type) {
+ case OSPF_TYPE_UMD: /* Rob Coltun's special monitoring packets; do nothing */
+ break;
+
+ case OSPF_TYPE_HELLO:
+ if ((caddr_t) (&op->ospf_hello.hello_deadint + 1) > end) {
+ break;
+ }
+ if (vflag) {
+ ospf_print_bits(ospf_option_bits, op->ospf_hello.hello_options);
+ printf(" mask %s int %d pri %d dead %d",
+ ipaddr_string(&op->ospf_hello.hello_mask),
+ ntohs(op->ospf_hello.hello_helloint),
+ op->ospf_hello.hello_priority,
+ ntohl(op->ospf_hello.hello_deadint));
+ }
+
+ if ((caddr_t) (&op->ospf_hello.hello_dr + 1) > end) {
+ break;
+ }
+ if (op->ospf_hello.hello_dr.s_addr) {
+ printf(" dr %s",
+ ipaddr_string(&op->ospf_hello.hello_dr));
+ }
+
+ if ((caddr_t) (&op->ospf_hello.hello_bdr + 1) > end) {
+ break;
+ }
+ if (op->ospf_hello.hello_bdr.s_addr) {
+ printf(" bdr %s",
+ ipaddr_string(&op->ospf_hello.hello_bdr));
+ }
+
+ if (vflag) {
+ if ((caddr_t) (op->ospf_hello.hello_neighbor + 1) > end) {
+ break;
+ }
+ printf(" nbrs");
+ for (ap = op->ospf_hello.hello_neighbor;
+ (caddr_t) (ap + 1) <= end;
+ ap++) {
+ printf(" %s",
+ ipaddr_string(ap));
+ }
+ }
+ break; /* HELLO */
+
+ case OSPF_TYPE_DB:
+ if ((caddr_t) (&op->ospf_db.db_seq + 1) > end) {
+ break;
+ }
+ ospf_print_bits(ospf_option_bits, op->ospf_db.db_options);
+ sep = ' ';
+ if (op->ospf_db.db_flags & OSPF_DB_INIT) {
+ printf("%cI",
+ sep);
+ sep = '/';
+ }
+ if (op->ospf_db.db_flags & OSPF_DB_MORE) {
+ printf("%cM",
+ sep);
+ sep = '/';
+ }
+ if (op->ospf_db.db_flags & OSPF_DB_MASTER) {
+ printf("%cMS",
+ sep);
+ sep = '/';
+ }
+ printf(" S %X",
+ ntohl(op->ospf_db.db_seq));
+
+ if (vflag) {
+ /* Print all the LS adv's */
+ lshp = op->ospf_db.db_lshdr;
+
+ while (!ospf_print_lshdr(lshp, end)) {
+ printf(" }"); /* { (ctags) */
+ lshp++;
+ }
+ }
+ break;
+
+ case OSPF_TYPE_LSR:
+ if (vflag) {
+ for (lsrp = op->ospf_lsr; (caddr_t) (lsrp+1) <= end; lsrp++) {
+ int32 type;
+
+ if ((caddr_t) (lsrp + 1) > end) {
+ break;
+ }
+
+ printf(" {"); /* } (ctags) */
+ if (!(type = lsrp->ls_type) || type >= LS_TYPE_MAX) {
+ printf(" ??LinkStateType %d }", /* { (ctags) */
+ type);
+ printf(" }"); /* { (ctags) */
+ break;
+ }
+
+ LS_PRINT(lsrp, type);
+ printf(" }"); /* { (ctags) */
+ }
+ }
+ break;
+
+ case OSPF_TYPE_LSU:
+ if (vflag) {
+ lsap = op->ospf_lsu.lsu_lsa;
+ i = ntohl(op->ospf_lsu.lsu_count);
+
+ while (i-- &&
+ !ospf_print_lsa(lsap, end)) {
+ lsap = (struct lsa *) ((caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length));
+ }
+ }
+ break;
+
+
+ case OSPF_TYPE_LSA:
+ if (vflag) {
+ lshp = op->ospf_lsa.lsa_lshdr;
+
+ while (!ospf_print_lshdr(lshp, end)) {
+ printf(" }"); /* { (ctags) */
+ lshp++;
+ }
+ break;
+ }
+ } /* end switch on v2 packet type */
+ break;
+
+ default:
+ printf(" ospf [version %d]",
+ op->ospf_version);
+ break;
+ } /* end switch on version */
+
+ trunc_test:
+ if ((snapend - bp) < length) {
+ printf(" [|]");
+ }
+
+ return; /* from ospf_print */
+}
diff --git a/usr.sbin/tcpdump/print-ppp.c b/usr.sbin/tcpdump/print-ppp.c
new file mode 100644
index 00000000000..966e9f58782
--- /dev/null
+++ b/usr.sbin/tcpdump/print-ppp.c
@@ -0,0 +1,104 @@
+/* $NetBSD: print-ppp.c,v 1.3 1995/03/06 19:11:27 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#)Header: print-ppp.c,v 1.18 94/06/10 17:01:37 mccanne Exp (LBL)";
+#endif
+
+#ifdef PPP
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <pcap.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+/* XXX This goes somewhere else. */
+#define PPP_HDRLEN 4
+
+void
+ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
+ register const u_char *p)
+{
+ register int length = h->len;
+ register int caplen = h->caplen;
+ const struct ip *ip;
+
+ ts_print(&h->ts);
+
+ if (caplen < PPP_HDRLEN) {
+ printf("[|ppp]");
+ goto out;
+ }
+
+ /*
+ * Some printers want to get back at the link level addresses,
+ * and/or check that they're not walking off the end of the packet.
+ * Rather than pass them all the way down, we set these globals.
+ */
+ packetp = p;
+ snapend = p + caplen;
+
+ if (eflag)
+ printf("%c %4d %02x %04x: ", p[0] ? 'O' : 'I', length,
+ p[1], ntohs(*(u_short *)&p[2]));
+
+ length -= PPP_HDRLEN;
+ ip = (struct ip *)(p + PPP_HDRLEN);
+ ip_print((const u_char *)ip, length);
+
+ if (xflag)
+ default_print((const u_char *)ip, caplen - PPP_HDRLEN);
+out:
+ putchar('\n');
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+void
+ppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+ error("not configured for ppp");
+ /* NOTREACHED */
+}
+#endif
diff --git a/usr.sbin/tcpdump/print-rip.c b/usr.sbin/tcpdump/print-rip.c
new file mode 100644
index 00000000000..1be9c9dae12
--- /dev/null
+++ b/usr.sbin/tcpdump/print-rip.c
@@ -0,0 +1,117 @@
+/* $NetBSD: print-rip.c,v 1.4 1995/06/20 23:38:49 christos Exp $ */
+
+/*
+ * Copyright (c) 1989, 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-rip.c,v 1.20 94/06/14 20:18:47 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include <protocols/routed.h>
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+static void
+rip_entry_print(register const struct netinfo *ni)
+{
+ if (ntohs(ni->rip_family) != AF_INET) {
+ register int i;
+
+ printf(" [family %d:", ntohs(ni->rip_family));
+ printf(" %04x", ni->rip_dst);
+ printf("]");
+ } else {
+ struct sockaddr_in sin;
+ sin.sin_addr.s_addr = ni->rip_dst;
+ printf(" %s", ipaddr_string(&sin.sin_addr));
+ if (ni->rip_tag)
+ printf(" [port %d]", ni->rip_tag);
+ }
+ printf("(%d)", ntohl(ni->rip_metric));
+}
+
+void
+rip_print(const u_char *dat, int length)
+{
+ register const struct rip *rp = (struct rip *)dat;
+ register const struct netinfo *ni;
+ register int amt = snapend - dat;
+ register int i = min(length, amt) -
+ (sizeof(struct rip) - sizeof(struct netinfo));
+ int j;
+ int trunc;
+
+ if (i < 0)
+ return;
+
+ switch (rp->rip_cmd) {
+
+ case RIPCMD_REQUEST:
+ printf(" rip-req %d", length);
+ break;
+ case RIPCMD_RESPONSE:
+ j = length / sizeof(*ni);
+ if (j * sizeof(*ni) != length - 4)
+ printf(" rip-resp %d[%d]:", j, length);
+ else
+ printf(" rip-resp %d:", j);
+ trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
+ for (ni = rp->rip_nets; (i -= sizeof(*ni)) >= 0; ++ni)
+ rip_entry_print(ni);
+ if (trunc)
+ printf("[|rip]");
+ break;
+ case RIPCMD_TRACEON:
+ printf(" rip-traceon %d: \"%s\"", length, rp->rip_tracefile);
+ break;
+ case RIPCMD_TRACEOFF:
+ printf(" rip-traceoff %d", length);
+ break;
+ case RIPCMD_POLL:
+ printf(" rip-poll %d", length);
+ break;
+ case RIPCMD_POLLENTRY:
+ printf(" rip-pollentry %d", length);
+ break;
+ default:
+ printf(" rip-%d ?? %d", rp->rip_cmd, length);
+ break;
+ }
+ if (rp->rip_vers != RIP_VERSION_1)
+ printf(" [vers %d]", rp->rip_vers);
+}
diff --git a/usr.sbin/tcpdump/print-sl.c b/usr.sbin/tcpdump/print-sl.c
new file mode 100644
index 00000000000..582e9037021
--- /dev/null
+++ b/usr.sbin/tcpdump/print-sl.c
@@ -0,0 +1,245 @@
+/* $NetBSD: print-sl.c,v 1.5 1995/03/06 19:11:29 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1989, 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#)Header: print-sl.c,v 1.28 94/06/10 17:01:38 mccanne Exp (LBL)";
+#endif
+
+#ifdef CSLIP
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <net/slcompress.h>
+#include <net/slip.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <pcap.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+static int lastlen[2][256];
+static int lastconn = 255;
+
+static void sliplink_print(const u_char *, const struct ip *, int);
+static void compressed_sl_print(const u_char *, const struct ip *, int, int);
+
+void
+sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+ register int caplen = h->caplen;
+ register int length = h->len;
+ register const struct ip *ip;
+
+ ts_print(&h->ts);
+
+ if (caplen < SLIP_HDRLEN) {
+ printf("[|slip]");
+ goto out;
+ }
+ /*
+ * Some printers want to get back at the link level addresses,
+ * and/or check that they're not walking off the end of the packet.
+ * Rather than pass them all the way down, we set these globals.
+ */
+ packetp = p;
+ snapend = p + caplen;
+
+ length -= SLIP_HDRLEN;
+
+ ip = (struct ip *)(p + SLIP_HDRLEN);
+
+ if (eflag)
+ sliplink_print(p, ip, length);
+
+ ip_print((u_char *)ip, length);
+
+ if (xflag)
+ default_print((u_char *)ip, caplen - SLIP_HDRLEN);
+ out:
+ putchar('\n');
+}
+
+static void
+sliplink_print(register const u_char *p, register const struct ip *ip,
+ register int length)
+{
+ int dir;
+ int hlen;
+
+ dir = p[SLX_DIR];
+ putchar(dir == SLIPDIR_IN ? 'I' : 'O');
+ putchar(' ');
+
+ if (nflag) {
+ /* XXX just dump the header */
+ int i;
+
+ for (i = 0; i < 15; ++i)
+ printf("%02x.", p[SLX_CHDR + i]);
+ printf("%02x: ", p[SLX_CHDR + 15]);
+ return;
+ }
+ switch (p[SLX_CHDR] & 0xf0) {
+
+ case TYPE_IP:
+ printf("ip %d: ", length + SLIP_HDRLEN);
+ break;
+
+ case TYPE_UNCOMPRESSED_TCP:
+ /*
+ * The connection id is stode in the IP protcol field.
+ */
+ lastconn = ip->ip_p;
+ hlen = ip->ip_hl;
+ hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off;
+ lastlen[dir][lastconn] = length - (hlen << 2);
+ printf("utcp %d: ", lastconn);
+ break;
+
+ default:
+ if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
+ compressed_sl_print(&p[SLX_CHDR], ip,
+ length, dir);
+ printf(": ");
+ } else
+ printf("slip-%d!: ", p[SLX_CHDR]);
+ }
+}
+
+static const u_char *
+print_sl_change(const char *str, register const u_char *cp)
+{
+ register u_int i;
+
+ if ((i = *cp++) == 0) {
+ i = (cp[0] << 8) | cp[1];
+ cp += 2;
+ }
+ printf(" %s%d", str, i);
+ return (cp);
+}
+
+static const u_char *
+print_sl_winchange(register const u_char *cp)
+{
+ register short i;
+
+ if ((i = *cp++) == 0) {
+ i = (cp[0] << 8) | cp[1];
+ cp += 2;
+ }
+ if (i >= 0)
+ printf(" W+%d", i);
+ else
+ printf(" W%d", i);
+ return (cp);
+}
+
+static void
+compressed_sl_print(const u_char *chdr, const struct ip *ip,
+ int length, int dir)
+{
+ register const u_char *cp = chdr;
+ register u_int flags;
+ int hlen;
+
+ flags = *cp++;
+ if (flags & NEW_C) {
+ lastconn = *cp++;
+ printf("ctcp %d", lastconn);
+ } else
+ printf("ctcp *");
+
+ /* skip tcp checksum */
+ cp += 2;
+
+ switch (flags & SPECIALS_MASK) {
+ case SPECIAL_I:
+ printf(" *SA+%d", lastlen[dir][lastconn]);
+ break;
+
+ case SPECIAL_D:
+ printf(" *S+%d", lastlen[dir][lastconn]);
+ break;
+
+ default:
+ if (flags & NEW_U)
+ cp = print_sl_change("U=", cp);
+ if (flags & NEW_W)
+ cp = print_sl_winchange(cp);
+ if (flags & NEW_A)
+ cp = print_sl_change("A+", cp);
+ if (flags & NEW_S)
+ cp = print_sl_change("S+", cp);
+ break;
+ }
+ if (flags & NEW_I)
+ cp = print_sl_change("I+", cp);
+
+ /*
+ * 'hlen' is the length of the uncompressed TCP/IP header (in words).
+ * 'cp - chdr' is the length of the compressed header.
+ * 'length - hlen' is the amount of data in the packet.
+ */
+ hlen = ip->ip_hl;
+ hlen += ((struct tcphdr *)&((int32 *)ip)[hlen])->th_off;
+ lastlen[dir][lastconn] = length - (hlen << 2);
+ printf(" %d (%d)", lastlen[dir][lastconn], cp - chdr);
+}
+#else
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+void
+sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+
+ error("not configured for slip");
+ /* NOTREACHED */
+}
+#endif
diff --git a/usr.sbin/tcpdump/print-snmp.c b/usr.sbin/tcpdump/print-snmp.c
new file mode 100644
index 00000000000..87bda376ab3
--- /dev/null
+++ b/usr.sbin/tcpdump/print-snmp.c
@@ -0,0 +1,1034 @@
+/* $NetBSD: print-snmp.c,v 1.3 1995/03/06 19:11:30 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994
+ * John Robert LoVerso. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by John Robert LoVerso.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * This implementation has been influenced by the CMU SNMP release,
+ * by Steve Waldbusser. However, this shares no code with that system.
+ * Additional ASN.1 insight gained from Marshall T. Rose's _The_Open_Book_.
+ * Earlier forms of this implementation were derived and/or inspired by an
+ * awk script originally written by C. Philip Wood of LANL (but later
+ * heavily modified by John Robert LoVerso). The copyright notice for
+ * that work is preserved below, even though it may not rightly apply
+ * to this file.
+ *
+ * This started out as a very simple program, but the incremental decoding
+ * (into the BE structure) complicated things.
+ *
+ # Los Alamos National Laboratory
+ #
+ # Copyright, 1990. The Regents of the University of California.
+ # This software was produced under a U.S. Government contract
+ # (W-7405-ENG-36) by Los Alamos National Laboratory, which is
+ # operated by the University of California for the U.S. Department
+ # of Energy. The U.S. Government is licensed to use, reproduce,
+ # and distribute this software. Permission is granted to the
+ # public to copy and use this software without charge, provided
+ # that this Notice and any statement of authorship are reproduced
+ # on all copies. Neither the Government nor the University makes
+ # any warranty, express or implied, or assumes any liability or
+ # responsibility for the use of this software.
+ # @(#)snmp.awk.x 1.1 (LANL) 1/15/90
+ */
+#ifndef lint
+static char rcsid[] =
+ "@(#) Id: print-snmp.c,v 3.10 91/01/17 01:18:13 loverso Exp Locker: loverso (jlv)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+/*
+ * Universal ASN.1 types
+ * (we only care about the tag values for those allowed in the Internet SMI)
+ */
+char *Universal[] = {
+ "U-0",
+ "Boolean",
+ "Integer",
+#define INTEGER 2
+ "Bitstring",
+ "String",
+#define STRING 4
+ "Null",
+#define ASN_NULL 5
+ "ObjID",
+#define OBJECTID 6
+ "ObjectDes",
+ "U-8","U-9","U-10","U-11", /* 8-11 */
+ "U-12","U-13","U-14","U-15", /* 12-15 */
+ "Sequence",
+#define SEQUENCE 16
+ "Set"
+};
+
+/*
+ * Application-wide ASN.1 types from the Internet SMI and their tags
+ */
+char *Application[] = {
+ "IpAddress",
+#define IPADDR 0
+ "Counter",
+#define COUNTER 1
+ "Gauge",
+#define GAUGE 2
+ "TimeTicks",
+#define TIMETICKS 3
+ "Opaque"
+};
+
+/*
+ * Context-specific ASN.1 types for the SNMP PDUs and their tags
+ */
+char *Context[] = {
+ "GetRequest",
+#define GETREQ 0
+ "GetNextRequest",
+#define GETNEXTREQ 1
+ "GetResponse",
+#define GETRESP 2
+ "SetRequest",
+#define SETREQ 3
+ "Trap"
+#define TRAP 4
+};
+
+/*
+ * Private ASN.1 types
+ * The Internet SMI does not specify any
+ */
+char *Private[] = {
+ "P-0"
+};
+
+/*
+ * error-status values for any SNMP PDU
+ */
+char *ErrorStatus[] = {
+ "noError",
+ "tooBig",
+ "noSuchName",
+ "badValue",
+ "readOnly",
+ "genErr"
+};
+#define DECODE_ErrorStatus(e) \
+ ( e >= 0 && e <= sizeof(ErrorStatus)/sizeof(ErrorStatus[0]) \
+ ? ErrorStatus[e] : (sprintf(errbuf, "err=%d", e), errbuf))
+
+/*
+ * generic-trap values in the SNMP Trap-PDU
+ */
+char *GenericTrap[] = {
+ "coldStart",
+ "warmStart",
+ "linkDown",
+ "linkUp",
+ "authenticationFailure",
+ "egpNeighborLoss",
+ "enterpriseSpecific"
+#define GT_ENTERPRISE 7
+};
+#define DECODE_GenericTrap(t) \
+ ( t >= 0 && t <= sizeof(GenericTrap)/sizeof(GenericTrap[0]) \
+ ? GenericTrap[t] : (sprintf(buf, "gt=%d", t), buf))
+
+/*
+ * ASN.1 type class table
+ * Ties together the preceding Universal, Application, Context, and Private
+ * type definitions.
+ */
+#define defineCLASS(x) { "x", x, sizeof(x)/sizeof(x[0]) } /* not ANSI-C */
+struct {
+ char *name;
+ char **Id;
+ int numIDs;
+} Class[] = {
+ defineCLASS(Universal),
+#define UNIVERSAL 0
+ defineCLASS(Application),
+#define APPLICATION 1
+ defineCLASS(Context),
+#define CONTEXT 2
+ defineCLASS(Private),
+#define PRIVATE 3
+};
+
+/*
+ * defined forms for ASN.1 types
+ */
+char *Form[] = {
+ "Primitive",
+#define PRIMITIVE 0
+ "Constructed",
+#define CONSTRUCTED 1
+};
+
+/*
+ * A structure for the OID tree for the compiled-in MIB.
+ * This is stored as a general-order tree.
+ */
+struct obj {
+ char *desc; /* name of object */
+ u_char oid; /* sub-id following parent */
+ u_char type; /* object type (unused) */
+ struct obj *child, *next; /* child and next sibling pointers */
+} *objp = NULL;
+
+/*
+ * Include the compiled in SNMP MIB. "mib.h" is produced by feeding
+ * RFC-1156 format files into "makemib". "mib.h" MUST define at least
+ * a value for `mibroot'.
+ *
+ * In particular, this is gross, as this is including initialized structures,
+ * and by right shouldn't be an "include" file.
+ */
+#include "mib.h"
+
+/*
+ * This defines a list of OIDs which will be abbreviated on output.
+ * Currently, this includes the prefixes for the Internet MIB, the
+ * private enterprises tree, and the experimental tree.
+ */
+struct obj_abrev {
+ char *prefix; /* prefix for this abrev */
+ struct obj *node; /* pointer into object table */
+ char *oid; /* ASN.1 encoded OID */
+} obj_abrev_list[] = {
+#ifndef NO_ABREV_MIB
+ /* .iso.org.dod.internet.mgmt.mib */
+ { "", &_mib_obj, "\53\6\1\2\1" },
+#endif
+#ifndef NO_ABREV_ENTER
+ /* .iso.org.dod.internet.private.enterprises */
+ { "E:", &_enterprises_obj, "\53\6\1\4\1" },
+#endif
+#ifndef NO_ABREV_EXPERI
+ /* .iso.org.dod.internet.experimental */
+ { "X:", &_experimental_obj, "\53\6\1\3" },
+#endif
+ { 0,0,0 }
+};
+
+/*
+ * This is used in the OID print routine to walk down the object tree
+ * rooted at `mibroot'.
+ */
+#define OBJ_PRINT(o, suppressdot) \
+{ \
+ if (objp) { \
+ do { \
+ if ((o) == objp->oid) \
+ break; \
+ } while ((objp = objp->next) != NULL); \
+ } \
+ if (objp) { \
+ printf(suppressdot?"%s":".%s", objp->desc); \
+ objp = objp->child; \
+ } else \
+ printf(suppressdot?"%u":".%u", (o)); \
+}
+
+/*
+ * This is the definition for the Any-Data-Type storage used purely for
+ * temporary internal representation while decoding an ASN.1 data stream.
+ */
+struct be {
+ u_long asnlen;
+ union {
+ caddr_t raw;
+ long integer;
+ u_long uns;
+ const u_char *str;
+ } data;
+ u_char form, class, id; /* tag info */
+ u_char type;
+#define BE_ANY 255
+#define BE_NONE 0
+#define BE_NULL 1
+#define BE_OCTET 2
+#define BE_OID 3
+#define BE_INT 4
+#define BE_UNS 5
+#define BE_STR 6
+#define BE_SEQ 7
+#define BE_INETADDR 8
+#define BE_PDU 9
+};
+
+/*
+ * Defaults for SNMP PDU components
+ */
+#define DEF_COMMUNITY "public"
+#define DEF_VERSION 0
+
+/*
+ * constants for ASN.1 decoding
+ */
+#define OIDMUX 40
+#define ASNLEN_INETADDR 4
+#define ASN_SHIFT7 7
+#define ASN_SHIFT8 8
+#define ASN_BIT8 0x80
+#define ASN_LONGLEN 0x80
+
+#define ASN_ID_BITS 0x1f
+#define ASN_FORM_BITS 0x20
+#define ASN_FORM_SHIFT 5
+#define ASN_CLASS_BITS 0xc0
+#define ASN_CLASS_SHIFT 6
+
+#define ASN_ID_EXT 0x1f /* extension ID in tag field */
+
+/*
+ * truncated==1 means the packet was complete, but we don't have all of
+ * it to decode.
+ */
+static int truncated;
+#define ifNotTruncated if (truncated) fputs("[|snmp]", stdout); else
+
+/*
+ * This decodes the next ASN.1 object in the stream pointed to by "p"
+ * (and of real-length "len") and stores the intermediate data in the
+ * provided BE object.
+ *
+ * This returns -l if it fails (i.e., the ASN.1 stream is not valid).
+ * O/w, this returns the number of bytes parsed from "p".
+ */
+static int
+asn1_parse(register const u_char *p, int len, struct be *elem)
+{
+ u_char form, class, id;
+ int i, hdr;
+
+ elem->asnlen = 0;
+ elem->type = BE_ANY;
+ if (len < 1) {
+ ifNotTruncated puts("[nothing to parse], stdout");
+ return -1;
+ }
+
+ /*
+ * it would be nice to use a bit field, but you can't depend on them.
+ * +---+---+---+---+---+---+---+---+
+ * + class |frm| id |
+ * +---+---+---+---+---+---+---+---+
+ * 7 6 5 4 3 2 1 0
+ */
+ id = *p & ASN_ID_BITS; /* lower 5 bits, range 00-1f */
+#ifdef notdef
+ form = (*p & 0xe0) >> 5; /* move upper 3 bits to lower 3 */
+ class = form >> 1; /* bits 7&6 -> bits 1&0, range 0-3 */
+ form &= 0x1; /* bit 5 -> bit 0, range 0-1 */
+#else
+ form = (*p & ASN_FORM_BITS) >> ASN_FORM_SHIFT;
+ class = (*p & ASN_CLASS_BITS) >> ASN_CLASS_SHIFT;
+#endif
+ elem->form = form;
+ elem->class = class;
+ elem->id = id;
+ if (vflag)
+ printf("|%.2x", *p);
+ p++; len--; hdr = 1;
+ /* extended tag field */
+ if (id == ASN_ID_EXT) {
+ for (id = 0; *p & ASN_BIT8 && len > 0; len--, hdr++, p++) {
+ if (vflag)
+ printf("|%.2x", *p);
+ id += *p & ~ASN_BIT8;
+ }
+ if (len == 0 && *p & ASN_BIT8) {
+ ifNotTruncated fputs("[Xtagfield?]", stdout);
+ return -1;
+ }
+ }
+ if (len < 1) {
+ ifNotTruncated fputs("[no asnlen]", stdout);
+ return -1;
+ }
+ elem->asnlen = *p;
+ if (vflag)
+ printf("|%.2x", *p);
+ p++; len--; hdr++;
+ if (elem->asnlen & ASN_BIT8) {
+ int noct = elem->asnlen % ASN_BIT8;
+ elem->asnlen = 0;
+ if (len < noct) {
+ ifNotTruncated printf("[asnlen? %d<%d]", len, noct);
+ return -1;
+ }
+ for (; noct-- > 0; len--, hdr++) {
+ if (vflag)
+ printf("|%.2x", *p);
+ elem->asnlen = (elem->asnlen << ASN_SHIFT8) | *p++;
+ }
+ }
+ if (len < elem->asnlen) {
+ if (!truncated) {
+ printf("[len%d<asnlen%u]", len, elem->asnlen);
+ return -1;
+ }
+ /* maybe should check at least 4? */
+ elem->asnlen = len;
+ }
+ if (form >= sizeof(Form)/sizeof(Form[0])) {
+ ifNotTruncated printf("[form?%d]", form);
+ return -1;
+ }
+ if (class >= sizeof(Class)/sizeof(Class[0])) {
+ ifNotTruncated printf("[class?%c/%d]", *Form[form], class);
+ return -1;
+ }
+ if (id >= Class[class].numIDs) {
+ ifNotTruncated printf("[id?%c/%s/%d]", *Form[form],
+ Class[class].name, id);
+ return -1;
+ }
+
+ switch (form) {
+ case PRIMITIVE:
+ switch (class) {
+ case UNIVERSAL:
+ switch (id) {
+ case STRING:
+ elem->type = BE_STR;
+ elem->data.str = p;
+ break;
+
+ case INTEGER: {
+ register long data;
+ elem->type = BE_INT;
+ data = 0;
+
+ if (*p & ASN_BIT8) /* negative */
+ data = -1;
+ for (i = elem->asnlen; i-- > 0; p++)
+ data = (data << ASN_SHIFT8) | *p;
+ elem->data.integer = data;
+ break;
+ }
+
+ case OBJECTID:
+ elem->type = BE_OID;
+ elem->data.raw = (caddr_t)p;
+ break;
+
+ case ASN_NULL:
+ elem->type = BE_NULL;
+ elem->data.raw = NULL;
+ break;
+
+ default:
+ elem->type = BE_OCTET;
+ elem->data.raw = (caddr_t)p;
+ printf("[P/U/%s]",
+ Class[class].Id[id]);
+ break;
+ }
+ break;
+
+ case APPLICATION:
+ switch (id) {
+ case IPADDR:
+ elem->type = BE_INETADDR;
+ elem->data.raw = (caddr_t)p;
+ break;
+
+ case COUNTER:
+ case GAUGE:
+ case TIMETICKS: {
+ register u_long data;
+ elem->type = BE_UNS;
+ data = 0;
+ for (i = elem->asnlen; i-- > 0; p++)
+ data = (data << 8) + *p;
+ elem->data.uns = data;
+ break;
+ }
+
+ default:
+ elem->type = BE_OCTET;
+ elem->data.raw = (caddr_t)p;
+ printf("[P/A/%s]",
+ Class[class].Id[id]);
+ break;
+ }
+ break;
+
+ default:
+ elem->type = BE_OCTET;
+ elem->data.raw = (caddr_t)p;
+ printf("[P/%s/%s]",
+ Class[class].name, Class[class].Id[id]);
+ break;
+ }
+ break;
+
+ case CONSTRUCTED:
+ switch (class) {
+ case UNIVERSAL:
+ switch (id) {
+ case SEQUENCE:
+ elem->type = BE_SEQ;
+ elem->data.raw = (caddr_t)p;
+ break;
+
+ default:
+ elem->type = BE_OCTET;
+ elem->data.raw = (caddr_t)p;
+ printf("C/U/%s", Class[class].Id[id]);
+ break;
+ }
+ break;
+
+ case CONTEXT:
+ elem->type = BE_PDU;
+ elem->data.raw = (caddr_t)p;
+ break;
+
+ default:
+ elem->type = BE_OCTET;
+ elem->data.raw = (caddr_t)p;
+ printf("C/%s/%s",
+ Class[class].name, Class[class].Id[id]);
+ break;
+ }
+ break;
+ }
+ p += elem->asnlen;
+ len -= elem->asnlen;
+ return elem->asnlen + hdr;
+}
+
+/*
+ * Display the ASN.1 object represented by the BE object.
+ * This used to be an integral part of asn1_parse() before the intermediate
+ * BE form was added.
+ */
+static void
+asn1_print(struct be *elem)
+{
+ u_char *p = (u_char *)elem->data.raw;
+ u_long asnlen = elem->asnlen;
+ int i;
+
+ switch (elem->type) {
+
+ case BE_OCTET:
+ for (i = asnlen; i-- > 0; p++);
+ printf("_%.2x", *p);
+ break;
+
+ case BE_NULL:
+ break;
+
+ case BE_OID: {
+ int o = 0, first = -1, i = asnlen;
+
+ if (!nflag && asnlen > 2) {
+ struct obj_abrev *a = &obj_abrev_list[0];
+ for (; a->node; a++) {
+ if (!bcmp(a->oid, (char *)p, strlen(a->oid))) {
+ objp = a->node->child;
+ i -= strlen(a->oid);
+ p += strlen(a->oid);
+ fputs(a->prefix, stdout);
+ first = 1;
+ break;
+ }
+ }
+ }
+ for (; i-- > 0; p++) {
+ o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8);
+ if (*p & ASN_LONGLEN)
+ continue;
+
+ /*
+ * first subitem encodes two items with 1st*OIDMUX+2nd
+ */
+ if (first < 0) {
+ if (!nflag)
+ objp = mibroot;
+ first = 0;
+ OBJ_PRINT(o/OIDMUX, first);
+ o %= OIDMUX;
+ }
+ OBJ_PRINT(o, first);
+ if (--first < 0)
+ first = 0;
+ o = 0;
+ }
+ break;
+ }
+
+ case BE_INT:
+ printf("%ld", elem->data.integer);
+ break;
+
+ case BE_UNS:
+ printf("%ld", elem->data.uns);
+ break;
+
+ case BE_STR: {
+ register int printable = 1, first = 1;
+ const u_char *p = elem->data.str;
+ for (i = asnlen; printable && i-- > 0; p++)
+ printable = isprint(*p) || isspace(*p);
+ p = elem->data.str;
+ if (printable)
+ (void)fn_print(p, p + asnlen);
+ else
+ for (i = asnlen; i-- > 0; p++) {
+ printf(first ? "%.2x" : "_%.2x", *p);
+ first = 0;
+ }
+ break;
+ }
+
+ case BE_SEQ:
+ printf("Seq(%d)", elem->asnlen);
+ break;
+
+ case BE_INETADDR: {
+ char sep;
+ if (asnlen != ASNLEN_INETADDR)
+ printf("[inetaddr len!=%d]", ASNLEN_INETADDR);
+ sep='[';
+ for (i = asnlen; i-- > 0; p++) {
+ printf("%c%u", sep, *p);
+ sep='.';
+ }
+ putchar(']');
+ break;
+ }
+
+ case BE_PDU:
+ printf("%s(%d)",
+ Class[CONTEXT].Id[elem->id], elem->asnlen);
+ break;
+
+ case BE_ANY:
+ fputs("[BE_ANY!?]", stdout);
+ break;
+
+ default:
+ fputs("[be!?]", stdout);
+ break;
+ }
+}
+
+#ifdef notdef
+/*
+ * This is a brute force ASN.1 printer: recurses to dump an entire structure.
+ * This will work for any ASN.1 stream, not just an SNMP PDU.
+ *
+ * By adding newlines and spaces at the correct places, this would print in
+ * Rose-Normal-Form.
+ *
+ * This is not currently used.
+ */
+static void
+asn1_decode(u_char *p, int length)
+{
+ struct be elem;
+ int i = 0;
+
+ while (i >= 0 && length > 0) {
+ i = asn1_parse(p, length, &elem);
+ if (i >= 0) {
+ fputs(" ", stdout);
+ asn1_print(&elem);
+ if (elem.type == BE_SEQ || elem.type == BE_PDU) {
+ fputs(" {", stdout);
+ asn1_decode(elem.data.raw, elem.asnlen);
+ fputs(" }", stdout);
+ }
+ length -= i;
+ p += i;
+ }
+ }
+}
+#endif
+
+/*
+ * General SNMP header
+ * SEQUENCE {
+ * version INTEGER {version-1(0)},
+ * community OCTET STRING,
+ * data ANY -- PDUs
+ * }
+ * PDUs for all but Trap: (see rfc1157 from page 15 on)
+ * SEQUENCE {
+ * request-id INTEGER,
+ * error-status INTEGER,
+ * error-index INTEGER,
+ * varbindlist SEQUENCE OF
+ * SEQUENCE {
+ * name ObjectName,
+ * value ObjectValue
+ * }
+ * }
+ * PDU for Trap:
+ * SEQUENCE {
+ * enterprise OBJECT IDENTIFIER,
+ * agent-addr NetworkAddress,
+ * generic-trap INTEGER,
+ * specific-trap INTEGER,
+ * time-stamp TimeTicks,
+ * varbindlist SEQUENCE OF
+ * SEQUENCE {
+ * name ObjectName,
+ * value ObjectValue
+ * }
+ * }
+ */
+
+/*
+ * Decode SNMP varBind
+ */
+static void
+varbind_print(u_char pduid, const u_char *np, int length, int error)
+{
+ struct be elem;
+ int count = 0, ind;
+
+ /* Sequence of varBind */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_SEQ) {
+ fputs("[!SEQ of varbind]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (count < length)
+ printf("[%d extra after SEQ of varbind]", length - count);
+ /* descend */
+ length = elem.asnlen;
+ np = (u_char *)elem.data.raw;
+
+ for (ind = 1; length > 0; ind++) {
+ const u_char *vbend;
+ int vblength;
+
+ if (!error || ind == error)
+ fputs(" ", stdout);
+
+ /* Sequence */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_SEQ) {
+ fputs("[!varbind]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ vbend = np + count;
+ vblength = length - count;
+ /* descend */
+ length = elem.asnlen;
+ np = (u_char *)elem.data.raw;
+
+ /* objName (OID) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_OID) {
+ fputs("[objName!=OID]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (!error || ind == error)
+ asn1_print(&elem);
+ length -= count;
+ np += count;
+
+ if (pduid != GETREQ && pduid != GETNEXTREQ && !error)
+ fputs("=", stdout);
+
+ /* objVal (ANY) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (pduid == GETREQ || pduid == GETNEXTREQ) {
+ if (elem.type != BE_NULL) {
+ fputs("[objVal!=NULL]", stdout);
+ asn1_print(&elem);
+ }
+ } else
+ if (error && ind == error && elem.type != BE_NULL)
+ fputs("[err objVal!=NULL]", stdout);
+ if (!error || ind == error)
+ asn1_print(&elem);
+
+ length = vblength;
+ np = vbend;
+ }
+}
+
+/*
+ * Decode SNMP PDUs: GetRequest, GetNextRequest, GetResponse, and SetRequest
+ */
+static void
+snmppdu_print(u_char pduid, const u_char *np, int length)
+{
+ struct be elem;
+ int count = 0, error;
+
+ /* reqId (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[reqId!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ /* ignore the reqId */
+ length -= count;
+ np += count;
+
+ /* errorStatus (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[errorStatus!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ error = 0;
+ if ((pduid == GETREQ || pduid == GETNEXTREQ)
+ && elem.data.integer != 0) {
+ char errbuf[10];
+ printf("[errorStatus(%s)!=0]",
+ DECODE_ErrorStatus(elem.data.integer));
+ } else if (elem.data.integer != 0) {
+ char errbuf[10];
+ printf(" %s", DECODE_ErrorStatus(elem.data.integer));
+ error = elem.data.integer;
+ }
+ length -= count;
+ np += count;
+
+ /* errorIndex (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[errorIndex!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if ((pduid == GETREQ || pduid == GETNEXTREQ)
+ && elem.data.integer != 0)
+ printf("[errorIndex(%d)!=0]", elem.data.integer);
+ else if (elem.data.integer != 0) {
+ if (!error)
+ printf("[errorIndex(%d) w/o errorStatus]",
+ elem.data.integer);
+ else {
+ printf("@%d", elem.data.integer);
+ error = elem.data.integer;
+ }
+ } else if (error) {
+ fputs("[errorIndex==0]", stdout);
+ error = 0;
+ }
+ length -= count;
+ np += count;
+
+ varbind_print(pduid, np, length, error);
+ return;
+}
+
+/*
+ * Decode SNMP Trap PDU
+ */
+static void
+trap_print(const u_char *np, int length)
+{
+ struct be elem;
+ int count = 0, generic;
+
+ putchar(' ');
+
+ /* enterprise (oid) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_OID) {
+ fputs("[enterprise!=OID]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ asn1_print(&elem);
+ length -= count;
+ np += count;
+
+ putchar(' ');
+
+ /* agent-addr (inetaddr) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INETADDR) {
+ fputs("[agent-addr!=INETADDR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ asn1_print(&elem);
+ length -= count;
+ np += count;
+
+ /* generic-trap (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[generic-trap!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ generic = elem.data.integer;
+ {
+ char buf[10];
+ printf(" %s", DECODE_GenericTrap(generic));
+ }
+ length -= count;
+ np += count;
+
+ /* specific-trap (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[specific-trap!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (generic != GT_ENTERPRISE) {
+ if (elem.data.integer != 0)
+ printf("[specific-trap(%d)!=0]", elem.data.integer);
+ } else
+ printf(" s=%d", elem.data.integer);
+ length -= count;
+ np += count;
+
+ putchar(' ');
+
+ /* time-stamp (TimeTicks) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_UNS) { /* XXX */
+ fputs("[time-stamp!=TIMETICKS]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ asn1_print(&elem);
+ length -= count;
+ np += count;
+
+ varbind_print (TRAP, np, length, 0);
+ return;
+}
+
+/*
+ * Decode SNMP header and pass on to PDU printing routines
+ */
+void
+snmp_print(const u_char *np, int length)
+{
+ struct be elem, pdu;
+ int count = 0;
+
+ truncated = 0;
+
+ /* truncated packet? */
+ if (np + length > snapend) {
+ truncated = 1;
+ length = snapend - np;
+ }
+
+ putchar(' ');
+
+ /* initial Sequence */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_SEQ) {
+ fputs("[!init SEQ]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (count < length)
+ printf("[%d extra after iSEQ]", length - count);
+ /* descend */
+ length = elem.asnlen;
+ np = (u_char *)elem.data.raw;
+ /* Version (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[version!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ /* only handle version==0 */
+ if (elem.data.integer != DEF_VERSION) {
+ printf("[version(%d)!=0]", elem.data.integer);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ /* Community (String) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_STR) {
+ fputs("[comm!=STR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ /* default community */
+ if (strncmp((char *)elem.data.str, DEF_COMMUNITY,
+ sizeof(DEF_COMMUNITY) - 1))
+ /* ! "public" */
+ printf("C=%.*s ", (int)elem.asnlen, elem.data.str);
+ length -= count;
+ np += count;
+
+ /* PDU (Context) */
+ if ((count = asn1_parse(np, length, &pdu)) < 0)
+ return;
+ if (pdu.type != BE_PDU) {
+ fputs("[no PDU]", stdout);
+ return;
+ }
+ if (count < length)
+ printf("[%d extra after PDU]", length - count);
+ asn1_print(&pdu);
+ /* descend into PDU */
+ length = pdu.asnlen;
+ np = (u_char *)pdu.data.raw;
+
+ switch (pdu.id) {
+ case TRAP:
+ trap_print(np, length);
+ break;
+ case GETREQ:
+ case GETNEXTREQ:
+ case GETRESP:
+ case SETREQ:
+ snmppdu_print(pdu.id, np, length);
+ break;
+ }
+ return;
+}
diff --git a/usr.sbin/tcpdump/print-sunrpc.c b/usr.sbin/tcpdump/print-sunrpc.c
new file mode 100644
index 00000000000..d3e23a334c6
--- /dev/null
+++ b/usr.sbin/tcpdump/print-sunrpc.c
@@ -0,0 +1,114 @@
+/* $NetBSD: print-sunrpc.c,v 1.3 1995/03/06 19:11:32 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-sunrpc.c,v 1.12 94/06/14 20:18:48 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#ifdef SOLARIS
+#include <tiuser.h>
+#endif
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+static void bswap(u_int32 *, u_int);
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+/*
+ * Byte swap an array of n 32-bit words.
+ * Assume input is word-aligned.
+ * Check that buffer is bounded by "snapend".
+ */
+static void
+bswap(register u_int32 *bp, register u_int n)
+{
+ register int nwords = ((char *)snapend - (char *)bp) / sizeof(*bp);
+
+ if (nwords > n)
+ nwords = n;
+ for (; --nwords >= 0; ++bp)
+ *bp = ntohl(*bp);
+}
+#endif
+
+static struct token proc2str[] = {
+ { PMAPPROC_NULL, "null" },
+ { PMAPPROC_SET, "set" },
+ { PMAPPROC_UNSET, "unset" },
+ { PMAPPROC_GETPORT, "getport" },
+ { PMAPPROC_DUMP, "dump" },
+ { PMAPPROC_CALLIT, "call" },
+ { 0, NULL }
+};
+
+void
+sunrpcrequest_print(register const u_char *bp, register int length,
+ register const u_char *bp2)
+{
+ register const struct rpc_msg *rp;
+ register const struct ip *ip;
+
+ rp = (struct rpc_msg *)bp;
+ ip = (struct ip *)bp2;
+
+ if (!nflag)
+ (void)printf("%s.%x > %s.sunrpc: %d",
+ ipaddr_string(&ip->ip_src),
+ ntohl(rp->rm_xid),
+ ipaddr_string(&ip->ip_dst),
+ length);
+ else
+ (void)printf("%s.%x > %s.%x: %d",
+ ipaddr_string(&ip->ip_src),
+ ntohl(rp->rm_xid),
+ ipaddr_string(&ip->ip_dst),
+ PMAPPORT,
+ length);
+ printf(" %s", tok2str(proc2str, " proc #%d",
+ ntohl(rp->rm_call.cb_proc)));
+}
+
diff --git a/usr.sbin/tcpdump/print-tcp.c b/usr.sbin/tcpdump/print-tcp.c
new file mode 100644
index 00000000000..50545d19867
--- /dev/null
+++ b/usr.sbin/tcpdump/print-tcp.c
@@ -0,0 +1,278 @@
+/* $NetBSD: print-tcp.c,v 1.5 1995/03/06 19:11:33 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-tcp.c,v 1.28 94/06/16 01:26:40 mccanne Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <unistd.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#ifndef TCPOPT_WSCALE
+#define TCPOPT_WSCALE 3 /* window scale factor (rfc1072) */
+#endif
+#ifndef TCPOPT_SACKOK
+#define TCPOPT_SACKOK 4 /* selective ack ok (rfc1072) */
+#endif
+#ifndef TCPOPT_SACK
+#define TCPOPT_SACK 5 /* selective ack (rfc1072) */
+#endif
+#ifndef TCPOPT_ECHO
+#define TCPOPT_ECHO 6 /* echo (rfc1072) */
+#endif
+#ifndef TCPOPT_ECHOREPLY
+#define TCPOPT_ECHOREPLY 7 /* echo (rfc1072) */
+#endif
+#ifndef TCPOPT_TIMESTAMP
+#define TCPOPT_TIMESTAMP 8 /* timestamps (rfc1323) */
+#endif
+
+struct tha {
+ struct in_addr src;
+ struct in_addr dst;
+ u_int port;
+};
+
+struct tcp_seq_hash {
+ struct tcp_seq_hash *nxt;
+ struct tha addr;
+ tcp_seq seq;
+ tcp_seq ack;
+};
+
+#define TSEQ_HASHSIZE 919
+
+static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];
+
+
+void
+tcp_print(register const u_char *bp, register int length,
+ register const u_char *bp2)
+{
+ register const struct tcphdr *tp;
+ register const struct ip *ip;
+ register u_char flags;
+ register int hlen;
+ u_short sport, dport, win, urp;
+ tcp_seq seq, ack;
+
+ tp = (struct tcphdr *)bp;
+ ip = (struct ip *)bp2;
+ if ((const u_char *)(tp + 1) > snapend) {
+ printf("[|tcp]");
+ return;
+ }
+ if (length < sizeof(struct tcphdr)) {
+ (void)printf("truncated-tcp %d", length);
+ return;
+ }
+
+ sport = ntohs(tp->th_sport);
+ dport = ntohs(tp->th_dport);
+ seq = ntohl(tp->th_seq);
+ ack = ntohl(tp->th_ack);
+ win = ntohs(tp->th_win);
+ urp = ntohs(tp->th_urp);
+
+ (void)printf("%s.%s > %s.%s: ",
+ ipaddr_string(&ip->ip_src), tcpport_string(sport),
+ ipaddr_string(&ip->ip_dst), tcpport_string(dport));
+
+ if (qflag) {
+ (void)printf("tcp %d", length - tp->th_off * 4);
+ return;
+ }
+ if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH)) {
+ if (flags & TH_SYN)
+ putchar('S');
+ if (flags & TH_FIN)
+ putchar('F');
+ if (flags & TH_RST)
+ putchar('R');
+ if (flags & TH_PUSH)
+ putchar('P');
+ } else
+ putchar('.');
+
+ if (!Sflag && (flags & TH_ACK)) {
+ register struct tcp_seq_hash *th;
+ register int rev;
+ struct tha tha;
+ /*
+ * Find (or record) the initial sequence numbers for
+ * this conversation. (we pick an arbitrary
+ * collating order so there's only one entry for
+ * both directions).
+ */
+ if (sport < dport ||
+ (sport == dport &&
+ ip->ip_src.s_addr < ip->ip_dst.s_addr)) {
+ tha.src = ip->ip_src, tha.dst = ip->ip_dst;
+ tha.port = sport << 16 | dport;
+ rev = 0;
+ } else {
+ tha.src = ip->ip_dst, tha.dst = ip->ip_src;
+ tha.port = dport << 16 | sport;
+ rev = 1;
+ }
+
+ for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
+ th->nxt; th = th->nxt)
+ if (!bcmp((char *)&tha, (char *)&th->addr,
+ sizeof(th->addr)))
+ break;
+
+ if (!th->nxt || flags & TH_SYN) {
+ /* didn't find it or new conversation */
+ if (!th->nxt)
+ th->nxt = (struct tcp_seq_hash *)
+ calloc(1, sizeof (*th));
+ th->addr = tha;
+ if (rev)
+ th->ack = seq, th->seq = ack - 1;
+ else
+ th->seq = seq, th->ack = ack - 1;
+ } else {
+ if (rev)
+ seq -= th->ack, ack -= th->seq;
+ else
+ seq -= th->seq, ack -= th->ack;
+ }
+ }
+ hlen = tp->th_off * 4;
+ length -= hlen;
+ if (length > 0 || flags & (TH_SYN | TH_FIN | TH_RST))
+ (void)printf(" %lu:%lu(%d)", seq, seq + length, length);
+ if (flags & TH_ACK)
+ (void)printf(" ack %u", ack);
+
+ (void)printf(" win %d", win);
+
+ if (flags & TH_URG)
+ (void)printf(" urg %d", urp);
+ /*
+ * Handle any options.
+ */
+ if ((hlen -= sizeof(struct tcphdr)) > 0) {
+ register const u_char *cp = (const u_char *)tp + sizeof(*tp);
+ int i;
+ char ch = '<';
+
+ putchar(' ');
+ while (--hlen >= 0) {
+ putchar(ch);
+ switch (*cp++) {
+ case TCPOPT_MAXSEG:
+ {
+ (void)printf("mss %d", cp[1] << 8 | cp[2]);
+ if (*cp != 4)
+ (void)printf("[len %d]", *cp);
+ cp += 3;
+ hlen -= 3;
+ break;
+ }
+ case TCPOPT_EOL:
+ (void)printf("eol");
+ break;
+ case TCPOPT_NOP:
+ (void)printf("nop");
+ break;
+ case TCPOPT_WSCALE:
+ (void)printf("wscale %d", cp[1]);
+ if (*cp != 3)
+ (void)printf("[len %d]", *cp);
+ cp += 2;
+ hlen -= 2;
+ break;
+ case TCPOPT_SACKOK:
+ (void)printf("sackOK");
+ if (*cp != 2)
+ (void)printf("[len %d]", *cp);
+ cp += 1;
+ hlen -= 1;
+ break;
+ case TCPOPT_ECHO:
+ {
+ (void)printf("echo %u",
+ cp[1] << 24 | cp[2] << 16 |
+ cp[3] << 8 | cp[4]);
+ if (*cp != 6)
+ (void)printf("[len %d]", *cp);
+ cp += 5;
+ hlen -= 5;
+ break;
+ }
+ case TCPOPT_ECHOREPLY:
+ {
+ (void)printf("echoreply %u",
+ cp[1] << 24 | cp[2] << 16 |
+ cp[3] << 8 | cp[4]);
+ if (*cp != 6)
+ (void)printf("[len %d]", *cp);
+ cp += 5;
+ hlen -= 5;
+ break;
+ }
+ case TCPOPT_TIMESTAMP:
+ {
+ (void)printf("timestamp %lu %lu",
+ cp[1] << 24 | cp[2] << 16 |
+ cp[3] << 8 | cp[4],
+ cp[5] << 24 | cp[6] << 16 |
+ cp[7] << 8 | cp[8]);
+ if (*cp != 10)
+ (void)printf("[len %d]", *cp);
+ cp += 9;
+ hlen -= 9;
+ break;
+ }
+ default:
+ (void)printf("opt-%d:", cp[-1]);
+ for (i = *cp++ - 2, hlen -= i + 1; i > 0; --i)
+ (void)printf("%02x", *cp++);
+ break;
+ }
+ ch = ',';
+ }
+ putchar('>');
+ }
+}
+
diff --git a/usr.sbin/tcpdump/print-tftp.c b/usr.sbin/tcpdump/print-tftp.c
new file mode 100644
index 00000000000..a1938321728
--- /dev/null
+++ b/usr.sbin/tcpdump/print-tftp.c
@@ -0,0 +1,147 @@
+/* $NetBSD: print-tftp.c,v 1.2 1995/03/06 19:11:35 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print trivial file transfer protocol packets.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-tftp.c,v 1.20 94/06/14 20:18:49 leres Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <netinet/in.h>
+
+#include <arpa/tftp.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+/* op code to string mapping */
+static struct token op2str[] = {
+ { RRQ, "RRQ" }, /* read request */
+ { WRQ, "WRQ" }, /* write request */
+ { DATA, "DATA" }, /* data packet */
+ { ACK, "ACK" }, /* acknowledgement */
+ { ERROR, "ERROR" }, /* error code */
+ { 0, NULL }
+};
+
+/* error code to string mapping */
+static struct token err2str[] = {
+ { EUNDEF, "EUNDEF" }, /* not defined */
+ { ENOTFOUND, "ENOTFOUND" }, /* file not found */
+ { EACCESS, "EACCESS" }, /* access violation */
+ { ENOSPACE, "ENOSPACE" }, /* disk full or allocation exceeded */
+ { EBADOP, "EBADOP" }, /* illegal TFTP operation */
+ { EBADID, "EBADID" }, /* unknown transfer ID */
+ { EEXISTS, "EEXISTS" }, /* file already exists */
+ { ENOUSER, "ENOUSER" }, /* no such user */
+ { 0, NULL }
+};
+
+/*
+ * Print trivial file transfer program requests
+ */
+void
+tftp_print(register const u_char *bp, int length)
+{
+ register const struct tftphdr *tp;
+ register const char *cp;
+ register const u_char *ep, *p;
+ register int opcode;
+#define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc
+ static char tstr[] = " [|tftp]";
+
+ tp = (const struct tftphdr *)bp;
+ /* 'ep' points to the end of avaible data. */
+ ep = snapend;
+
+ /* Print length */
+ printf(" %d", length);
+
+ /* Print tftp request type */
+ TCHECK(tp->th_opcode, sizeof(tp->th_opcode));
+ opcode = ntohs(tp->th_opcode);
+ cp = tok2str(op2str, "tftp-#%d", opcode);
+ printf(" %s", cp);
+ /* Bail if bogus opcode */
+ if (*cp == 't')
+ return;
+
+ switch (opcode) {
+
+ case RRQ:
+ case WRQ:
+ putchar(' ');
+ /*
+ * XXX Not all arpa/tftp.h's specify th_stuff as any
+ * array; use address of th_block instead
+ */
+#ifdef notdef
+ p = (u_char *)tp->th_stuff;
+#else
+ p = (u_char *)&tp->th_block;
+#endif
+ if (fn_print(p, ep)) {
+ fputs(&tstr[1], stdout);
+ return;
+ }
+ break;
+
+ case DATA:
+ TCHECK(tp->th_block, sizeof(tp->th_block));
+ printf(" block %d", ntohs(tp->th_block));
+ break;
+
+ case ACK:
+ break;
+
+ case ERROR:
+ /* Print error code string */
+ TCHECK(tp->th_code, sizeof(tp->th_code));
+ printf(" %s ", tok2str(err2str, "tftp-err-#%d",
+ ntohs(tp->th_code)));
+ /* Print error message string */
+ if (fn_print((const u_char *)tp->th_data, ep)) {
+ fputs(&tstr[1], stdout);
+ return;
+ }
+ break;
+
+ default:
+ /* We shouldn't get here */
+ printf("(unknown #%d)", opcode);
+ break;
+ }
+ return;
+trunc:
+ fputs(tstr, stdout);
+#undef TCHECK
+}
diff --git a/usr.sbin/tcpdump/print-udp.c b/usr.sbin/tcpdump/print-udp.c
new file mode 100644
index 00000000000..4758c9da601
--- /dev/null
+++ b/usr.sbin/tcpdump/print-udp.c
@@ -0,0 +1,259 @@
+/* $NetBSD: print-udp.c,v 1.3 1995/03/06 19:11:36 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-udp.c,v 1.37 94/06/10 17:01:42 mccanne Exp (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#undef NOERROR /* Solaris sucks */
+#include <arpa/nameser.h>
+#include <arpa/tftp.h>
+
+#ifdef SOLARIS
+#include <tiuser.h>
+#endif
+#include <rpc/rpc.h>
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "appletalk.h"
+
+#include "nfsv2.h"
+#include "bootp.h"
+
+extern int packettype;
+
+static void
+vat_print(const void *hdr, int len, register const struct udphdr *up)
+{
+ /* vat/vt audio */
+ u_int ts = *(u_short *)hdr;
+ if ((ts & 0xf060) != 0) {
+ /* probably vt */
+ (void)printf(" udp/vt %d %d / %d",
+ ntohs(up->uh_ulen) - sizeof(*up),
+ ts & 0x3ff, ts >> 10);
+ } else {
+ /* probably vat */
+ u_int i0 = ((u_int *)hdr)[0];
+ u_int i1 = ((u_int *)hdr)[1];
+ printf(" udp/vat %d c%d %u%s",
+ ntohs(up->uh_ulen) - sizeof(*up) - 8,
+ i0 & 0xffff,
+ i1, i0 & 0x800000? "*" : "");
+ /* audio format */
+ if (i0 & 0x1f0000)
+ printf(" f%d", (i0 >> 16) & 0x1f);
+ if (i0 & 0x3f000000)
+ printf(" s%d", (i0 >> 24) & 0x3f);
+ }
+}
+
+static void
+rtp_print(const void *hdr, int len, register const struct udphdr *up)
+{
+ /* rtp v1 video */
+ u_int *ip = (u_int *)hdr;
+ u_int i0 = ((u_int *)hdr)[0];
+ u_int i1 = ((u_int *)hdr)[1];
+ u_int hasopt = i0 & 0x800000;
+ u_int contype = (i0 >> 16) & 0x3f;
+ printf(" udp/rtp %d c%d %s%s %d",
+ ntohs(up->uh_ulen) - sizeof(*up) - 8,
+ contype,
+ hasopt? "+" : "",
+ i0 & 0x400000? "*" : "",
+ i0 & 0xffff);
+ if (contype == 31) {
+ ip += 2;
+ len >>= 2;
+ len -= 2;
+ if (hasopt) {
+ u_int i2, optlen;
+ do {
+ i2 = ip[0];
+ optlen = (i2 >> 16) & 0xff;
+ if (optlen == 0 || optlen > len) {
+ printf(" !opt");
+ return;
+ }
+ ip += optlen;
+ } while ((int)i2 >= 0);
+ }
+ printf(" 0x%04x", ip[0] >> 16);
+ }
+ if (vflag)
+ printf(" %u", i1);
+}
+
+/* XXX probably should use getservbyname() and cache answers */
+#define TFTP_PORT 69 /*XXX*/
+#define SUNRPC_PORT 111 /*XXX*/
+#define SNMP_PORT 161 /*XXX*/
+#define NTP_PORT 123 /*XXX*/
+#define SNMPTRAP_PORT 162 /*XXX*/
+#define RIP_PORT 520 /*XXX*/
+
+void
+udp_print(register const u_char *bp, int length, register const u_char *bp2)
+{
+ register const struct udphdr *up;
+ register const struct ip *ip;
+ register const u_char *cp;
+ u_short sport, dport, ulen;
+
+ up = (struct udphdr *)bp;
+ ip = (struct ip *)bp2;
+ cp = (u_char *)(up + 1);
+ if (cp > snapend) {
+ printf("[|udp]");
+ return;
+ }
+ if (length < sizeof(struct udphdr)) {
+ (void)printf(" truncated-udp %d", length);
+ return;
+ }
+ length -= sizeof(struct udphdr);
+
+ sport = ntohs(up->uh_sport);
+ dport = ntohs(up->uh_dport);
+ ulen = ntohs(up->uh_ulen);
+ if (packettype) {
+ register struct rpc_msg *rp;
+ enum msg_type direction;
+
+ switch (packettype) {
+ case 1:
+ (void)printf("%s.%s > %s.%s:",
+ ipaddr_string(&ip->ip_src),
+ udpport_string(sport),
+ ipaddr_string(&ip->ip_dst),
+ udpport_string(dport));
+ vat_print((void *)(up + 1), length, up);
+ break;
+ case 2:
+ (void)printf("%s.%s > %s.%s:",
+ ipaddr_string(&ip->ip_src),
+ udpport_string(sport),
+ ipaddr_string(&ip->ip_dst),
+ udpport_string(dport));
+ wb_print((void *)(up + 1), length);
+ break;
+ case 3:
+ rp = (struct rpc_msg *)(up + 1);
+ direction = (enum msg_type)ntohl(rp->rm_direction);
+ if (direction == CALL)
+ sunrpcrequest_print((u_char *)rp, length,
+ (u_char *)ip);
+ else
+ nfsreply_print((u_char *)rp, length,
+ (u_char *)ip); /*XXX*/
+ break;
+ case 4:
+ (void)printf("%s.%s > %s.%s:",
+ ipaddr_string(&ip->ip_src),
+ udpport_string(sport),
+ ipaddr_string(&ip->ip_dst),
+ udpport_string(dport));
+ rtp_print((void *)(up + 1), length, up);
+ break;
+ }
+ return;
+ }
+
+ if (! qflag) {
+ register struct rpc_msg *rp;
+ enum msg_type direction;
+
+ rp = (struct rpc_msg *)(up + 1);
+ direction = (enum msg_type)ntohl(rp->rm_direction);
+ if (dport == NFS_PORT && direction == CALL) {
+ nfsreq_print((u_char *)rp, length, (u_char *)ip);
+ return;
+ }
+ else if (sport == NFS_PORT && direction == REPLY) {
+ nfsreply_print((u_char *)rp, length, (u_char *)ip);
+ return;
+ }
+#ifdef notdef
+ else if (dport == SUNRPC_PORT && direction == CALL) {
+ sunrpcrequest_print((u_char *)rp, length, (u_char *)ip);
+ return;
+ }
+#endif
+ else if (((struct LAP *)cp)->type == lapDDP &&
+ (atalk_port(sport) || atalk_port(dport))) {
+ if (vflag)
+ fputs("kip ", stdout);
+ atalk_print(cp, length);
+ return;
+ }
+ }
+ (void)printf("%s.%s > %s.%s:",
+ ipaddr_string(&ip->ip_src), udpport_string(sport),
+ ipaddr_string(&ip->ip_dst), udpport_string(dport));
+
+ if (!qflag) {
+#define ISPORT(p) (dport == (p) || sport == (p))
+ if (ISPORT(NAMESERVER_PORT))
+ ns_print((const u_char *)(up + 1), length);
+ else if (ISPORT(TFTP_PORT))
+ tftp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS))
+ bootp_print((const u_char *)(up + 1), length,
+ sport, dport);
+ else if (dport == RIP_PORT)
+ rip_print((const u_char *)(up + 1), length);
+ else if (ISPORT(SNMP_PORT) || ISPORT(SNMPTRAP_PORT))
+ snmp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(NTP_PORT))
+ ntp_print((const u_char *)(up + 1), length);
+ else if (dport == 3456)
+ vat_print((const void *)(up + 1), length, up);
+ /*
+ * Kludge in test for whiteboard packets.
+ */
+ else if (dport == 4567)
+ wb_print((const void *)(up + 1), length);
+ else
+ (void)printf(" udp %d", ulen - sizeof(*up));
+#undef ISPORT
+ } else
+ (void)printf(" udp %d", ulen - sizeof(*up));
+}
diff --git a/usr.sbin/tcpdump/print-wb.c b/usr.sbin/tcpdump/print-wb.c
new file mode 100644
index 00000000000..ac7d6823e1d
--- /dev/null
+++ b/usr.sbin/tcpdump/print-wb.c
@@ -0,0 +1,447 @@
+/* $NetBSD: print-wb.c,v 1.2 1995/03/06 19:11:37 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: print-wb.c,v 1.14 94/06/14 20:18:50 leres Exp (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+/* XXX need to add byte-swapping macros! */
+
+/*
+ * Largest packet size. Everything should fit within this space.
+ * For instance, multiline objects are sent piecewise.
+ */
+#define MAXFRAMESIZE 1024
+
+/*
+ * Multiple drawing ops can be sent in one packet. Each one starts on a
+ * an even multiple of DOP_ALIGN bytes, which must be a power of two.
+ */
+#define DOP_ALIGN 4
+#define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1))
+#define DOP_NEXT(d)\
+ ((struct dophdr*)((u_char *)(d) + \
+ DOP_ROUNDUP(ntohs((d)->dh_len) + sizeof(*(d)))))
+
+/*
+ * Format of the whiteboard packet header.
+ * The transport level header.
+ */
+struct pkt_hdr {
+ u_int32 ph_src; /* site id of source */
+ u_int32 ph_ts; /* time stamp (for skew computation) */
+ u_short ph_version; /* version number */
+ u_char ph_type; /* message type */
+ u_char ph_flags; /* message flags */
+};
+
+/* Packet types */
+#define PT_DRAWOP 0 /* drawing operation */
+#define PT_ID 1 /* announcement packet */
+#define PT_RREQ 2 /* repair request */
+#define PT_RREP 3 /* repair reply */
+#define PT_KILL 4 /* terminate participation */
+#define PT_PREQ 5 /* page vector request */
+#define PT_PREP 7 /* page vector reply */
+
+/* flags */
+#define PF_USER 0x01 /* hint that packet has interactive data */
+#define PF_VIS 0x02 /* only visible ops wanted */
+
+struct PageID {
+ u_int32 p_sid; /* session id of initiator */
+ u_int32 p_uid; /* page number */
+};
+
+struct dophdr {
+ u_int32 dh_ts; /* sender's timestamp */
+ u_short dh_len; /* body length */
+ u_char dh_flags;
+ u_char dh_type; /* body type */
+ /* body follows */
+};
+/*
+ * Drawing op sub-types.
+ */
+#define DT_RECT 2
+#define DT_LINE 3
+#define DT_ML 4
+#define DT_DEL 5
+#define DT_XFORM 6
+#define DT_ELL 7
+#define DT_CHAR 8
+#define DT_STR 9
+#define DT_NOP 10
+#define DT_PSCODE 11
+#define DT_PSCOMP 12
+#define DT_REF 13
+#define DT_SKIP 14
+#define DT_HOLE 15
+#define DT_MAXTYPE 15
+
+/*
+ * A drawing operation.
+ */
+struct pkt_dop {
+ struct PageID pd_page; /* page that operations apply to */
+ u_int32 pd_sseq; /* start sequence number */
+ u_int32 pd_eseq; /* end sequence number */
+ /* drawing ops follow */
+};
+
+/*
+ * A repair request.
+ */
+struct pkt_rreq {
+ u_int32 pr_id; /* source id of drawops to be repaired */
+ struct PageID pr_page; /* page of drawops */
+ u_int32 pr_sseq; /* start seqno */
+ u_int32 pr_eseq; /* end seqno*/
+};
+
+/*
+ * A repair reply.
+ */
+struct pkt_rrep {
+ u_int32 pr_id; /* original site id of ops */
+ struct pkt_dop pr_dop;
+ /* drawing ops follow */
+};
+
+struct id_off {
+ u_int32 id;
+ u_int32 off;
+};
+
+struct pgstate {
+ u_int32 slot;
+ struct PageID page;
+ u_short nid;
+ u_short rsvd;
+ /* seqptr's */
+};
+
+/*
+ * An announcement packet.
+ */
+struct pkt_id {
+ u_int32 pi_mslot;
+ struct PageID pi_mpage; /* current page */
+ struct pgstate pi_ps;
+ /* seqptr's */
+ /* null-terminated site name */
+};
+
+struct pkt_preq {
+ struct PageID pp_page;
+ u_int32 pp_low;
+ u_int32 pp_high;
+};
+
+struct pkt_prep {
+ u_int32 pp_n; /* size of pageid array */
+ /* pgstate's follow */
+};
+
+static int
+wb_id(const struct pkt_id *id, int len)
+{
+ int i;
+ const char *cp;
+ const struct id_off *io;
+ char c;
+ int nid;
+
+ len -= sizeof(*id);
+ if (len < 0) {
+ printf(" truncated-wb-id!");
+ return (0);
+ }
+ if ((u_char *)(id + 1) > snapend)
+ return (-1);
+ nid = ntohs(id->pi_ps.nid);
+ len -= sizeof(*io) * nid;
+ if (len < 0) {
+ printf(" truncated-wb-id!");
+ return (0);
+ }
+ io = (struct id_off *)(id + 1);
+ cp = (char *)(io + nid);
+ if ((u_char *)cp + len > snapend)
+ return (-1);
+
+ printf(" wb-id: %d/%s:%d (max %d/%s:%d) ",
+ ntohl(id->pi_ps.slot),
+ ipaddr_string(&id->pi_ps.page.p_sid),
+ ntohl(id->pi_ps.page.p_uid),
+ ntohl(id->pi_mslot),
+ ipaddr_string(&id->pi_mpage.p_sid),
+ ntohl(id->pi_mpage.p_uid));
+
+ if (cp[len - 1] != '\0')
+ printf("(unterm!) ");
+
+ fn_print((u_char *)cp, (u_char *)cp + len);
+
+ c = '<';
+ for (i = 0; i < nid; ++io, ++i) {
+ printf("%c%s:%d", c, ipaddr_string(&io->id), ntohl(io->off));
+ c = ',';
+ }
+ printf(">");
+ return (0);
+}
+
+static int
+wb_rreq(const struct pkt_rreq *rreq, int len)
+{
+ if (len < sizeof(*rreq)) {
+ printf(" truncated-wb-rreq!");
+ return (0);
+ }
+ if ((u_char *)(rreq + 1) > snapend)
+ return (-1);
+
+ printf(" wb-rreq: please repair %s %s:%ld<%ld:%ld>",
+ ipaddr_string(&rreq->pr_id),
+ ipaddr_string(&rreq->pr_page.p_sid), ntohl(rreq->pr_page.p_uid),
+ ntohl(rreq->pr_sseq), ntohl(rreq->pr_eseq));
+ return (0);
+}
+
+static int
+wb_preq(const struct pkt_preq *preq, int len)
+{
+ if (len < sizeof(*preq)) {
+ printf(" truncated-wb-preq!");
+ return (0);
+ }
+ if ((u_char *)(preq + 1) > snapend)
+ return (-1);
+
+ printf(" wb-preq: need %d/%s:%ld",
+ ntohl(preq->pp_low),
+ ipaddr_string(&preq->pp_page.p_sid),
+ ntohl(preq->pp_page.p_uid));
+ return (0);
+}
+
+static int
+wb_prep(const struct pkt_prep *prep, int len)
+{
+ int n;
+ const struct pgstate* ps;
+ const u_char* ep = snapend;
+
+ if (len < sizeof(*prep)) {
+ printf(" truncated-wb-prep!");
+ return (0);
+ }
+ printf(" wb-prep:");
+ n = ntohl(prep->pp_n);
+ ps = (const struct pgstate*)(prep + 1);
+ while (--n >= 0 && (u_char*)ps < ep) {
+ const struct id_off *io, *ie;
+ char c = '<';
+
+ printf(" %lu/%s:%lu", ntohl(ps->slot),
+ ipaddr_string(&ps->page.p_sid),
+ ntohl(ps->page.p_uid));
+ io = (struct id_off*)(ps + 1);
+ for (ie = io + ps->nid; io < ie && (u_char*)io < ep; ++io) {
+ printf("%c%s:%lu", c, ipaddr_string(&io->id),
+ ntohl(io->off));
+ c = ',';
+ }
+ printf(">");
+ ps = (struct pgstate*)io;
+ }
+ return ((u_char*)ps <= ep? 0 : -1);
+}
+
+
+char *dopstr[] = {
+ "dop-0!",
+ "dop-1!",
+ "RECT",
+ "LINE",
+ "ML",
+ "DEL",
+ "XFORM",
+ "ELL",
+ "CHAR",
+ "STR",
+ "NOP",
+ "PSCODE",
+ "PSCOMP",
+ "REF",
+ "SKIP",
+ "HOLE",
+};
+
+static int
+wb_dops(const struct dophdr *dh, u_int32 ss, u_int32 es)
+{
+ printf(" <");
+ for ( ; ss <= es; ++ss) {
+ register int t = dh->dh_type;
+
+ if (t > DT_MAXTYPE)
+ printf(" dop-%d!", t);
+ else {
+ printf(" %s", dopstr[t]);
+ if (t == DT_SKIP || t == DT_HOLE) {
+ int ts = ntohl(dh->dh_ts);
+ printf("%d", ts - ss + 1);
+ if (ss > ts || ts > es) {
+ printf("[|]");
+ if (ts < ss)
+ return (0);
+ }
+ ss = ts;
+ }
+ }
+ dh = DOP_NEXT(dh);
+ if ((u_char*)dh >= snapend) {
+ printf("[|wb]");
+ break;
+ }
+ }
+ printf(" >");
+ return (0);
+}
+
+static int
+wb_rrep(const struct pkt_rrep *rrep, int len)
+{
+ const struct pkt_dop *dop = &rrep->pr_dop;
+
+ len -= sizeof(*rrep);
+ if (len < 0) {
+ printf(" truncated-wb-rrep!");
+ return (0);
+ }
+ if ((u_char *)(rrep + 1) > snapend)
+ return (-1);
+
+ printf(" wb-rrep: for %s %s:%d<%ld:%ld>",
+ ipaddr_string(&rrep->pr_id),
+ ipaddr_string(&dop->pd_page.p_sid), ntohl(dop->pd_page.p_uid),
+ ntohl(dop->pd_sseq), ntohl(dop->pd_eseq));
+
+ return (wb_dops((const struct dophdr*)(dop + 1),
+ ntohl(dop->pd_sseq), ntohl(dop->pd_eseq)));
+}
+
+static int
+wb_drawop(const struct pkt_dop *dop, int len)
+{
+ len -= sizeof(*dop);
+ if (len < 0) {
+ printf(" truncated-wb-dop!");
+ return (0);
+ }
+ if ((u_char *)(dop + 1) > snapend)
+ return (-1);
+
+ printf(" wb-dop: %s:%d<%ld:%ld>",
+ ipaddr_string(&dop->pd_page.p_sid), ntohl(dop->pd_page.p_uid),
+ ntohl(dop->pd_sseq), ntohl(dop->pd_eseq));
+
+ return (wb_dops((const struct dophdr*)(dop + 1),
+ ntohl(dop->pd_sseq), ntohl(dop->pd_eseq)));
+}
+
+/*
+ * Print whiteboard multicast packets.
+ */
+void
+wb_print(register const void *hdr, register int len)
+{
+ register const struct pkt_hdr* ph;
+
+ ph = (const struct pkt_hdr*)hdr;
+ len -= sizeof(*ph);
+ if (len < 0) {
+ printf(" truncated-wb!");
+ return;
+ }
+ if ((u_char *)(ph + 1) > snapend) {
+ trunc:
+ printf("[|wb]");
+ return;
+ }
+ if (ph->ph_flags)
+ printf("*");
+ switch (ph->ph_type) {
+
+ case PT_KILL:
+ printf(" wb-kill");
+ break;
+
+ case PT_ID:
+ if (wb_id((struct pkt_id *)(ph + 1), len) < 0)
+ goto trunc;
+ break;
+
+ case PT_RREQ:
+ if (wb_rreq((struct pkt_rreq *)(ph + 1), len) < 0)
+ goto trunc;
+ break;
+
+ case PT_RREP:
+ if (wb_rrep((struct pkt_rrep *)(ph + 1), len) < 0)
+ goto trunc;
+ break;
+
+ case PT_DRAWOP:
+ if (wb_drawop((struct pkt_dop *)(ph + 1), len) < 0)
+ goto trunc;
+ break;
+
+ case PT_PREQ:
+ if (wb_preq((struct pkt_preq *)(ph + 1), len) < 0)
+ goto trunc;
+ break;
+
+ case PT_PREP:
+ if (wb_prep((struct pkt_prep *)(ph + 1), len) < 0)
+ goto trunc;
+ break;
+
+ default:
+ printf(" wb-%d!", ph->ph_type);
+ return;
+ }
+}
diff --git a/usr.sbin/tcpdump/send-ack.awk b/usr.sbin/tcpdump/send-ack.awk
new file mode 100644
index 00000000000..1f98e50322e
--- /dev/null
+++ b/usr.sbin/tcpdump/send-ack.awk
@@ -0,0 +1,70 @@
+# $NetBSD: send-ack.awk,v 1.2 1995/03/06 19:11:42 mycroft Exp $
+
+BEGIN {
+ # we need the number of bytes in a packet to do the output
+ # in packet numbers rather than byte numbers.
+ if (packetsize <= 0)
+ packetsize = 512
+ expectNext = 1
+ lastwin = -1
+ }
+ {
+ # convert tcp trace to send/ack form.
+ n = split ($1,t,":")
+ tim = t[1]*3600 + t[2]*60 + t[3]
+ if (NR <= 1) {
+ tzero = tim
+ ltim = tim
+ OFS = "\t"
+ }
+ if ($6 != "ack") {
+ # we have a data packet record:
+ # ignore guys with syn, fin or reset 'cause we
+ # can't handle their sequence numbers. Try to
+ # detect and add a flag character for 'anomalies':
+ # * -> re-sent packet
+ # - -> packet after hole (missing packet(s))
+ # # -> odd size packet
+ if ($5 !~ /[SFR]/) {
+ i = index($6,":")
+ j = index($6,"(")
+ strtSeq = substr($6,1,i-1)
+ endSeq = substr($6,i+1,j-i-1)
+ len = endSeq - strtSeq
+ id = endSeq
+ if (! timeOf[id])
+ timeOf[id] = tim
+ if (endSeq - expectNext < 0)
+ flag = "*"
+ else {
+ if (strtSeq - expectNext > 0)
+ flag = "-"
+ else if (len != packetsize)
+ flag = "#"
+ else
+ flag = " "
+ expectNext = endSeq
+ }
+ printf "%7.2f\t%7.2f\t%s send %s %d", tim-tzero, tim-ltim,\
+ flag, $5, strtSeq
+ if (++timesSent[id] > 1)
+ printf " (%.2f) [%d]", tim - timeOf[id], timesSent[id]
+ if (len != packetsize)
+ printf " <%d>", len
+ }
+ } else {
+ id = $7
+
+ printf "%7.2f\t%7.2f\t%s ack %s %d", tim-tzero, tim-ltim,\
+ flag, $5, id
+ if ($9 != lastwin) {
+ printf " win %d", $9
+ lastwin = $9
+ }
+ printf " (%.2f)", tim - timeOf[id]
+ if (++timesAcked[id] > 1)
+ printf " [%d]", timesAcked[id]
+ }
+ printf "\n"
+ ltim = tim
+ }
diff --git a/usr.sbin/tcpdump/stime.awk b/usr.sbin/tcpdump/stime.awk
new file mode 100644
index 00000000000..d57968ed932
--- /dev/null
+++ b/usr.sbin/tcpdump/stime.awk
@@ -0,0 +1,21 @@
+# $NetBSD: stime.awk,v 1.2 1995/03/06 19:11:43 mycroft Exp $
+
+$6 !~ /^ack/ && $5 !~ /[SFR]/ {
+ # given a tcpdump ftp trace, output one line for each send
+ # in the form
+ # <send time> <seq no>
+ # where <send time> is the time packet was sent (in seconds with
+ # zero at time of first packet) and <seq no> is the tcp sequence
+ # number of the packet divided by 1024 (i.e., Kbytes sent).
+ #
+ # convert time to seconds
+ n = split ($1,t,":")
+ tim = t[1]*3600 + t[2]*60 + t[3]
+ if (! tzero) {
+ tzero = tim
+ OFS = "\t"
+ }
+ # get packet sequence number
+ i = index($6,":")
+ printf "%7.2f\t%g\n", tim-tzero, substr($6,1,i-1)/1024
+ }
diff --git a/usr.sbin/tcpdump/tcpdump.8 b/usr.sbin/tcpdump/tcpdump.8
new file mode 100644
index 00000000000..01879d3b2ce
--- /dev/null
+++ b/usr.sbin/tcpdump/tcpdump.8
@@ -0,0 +1,1173 @@
+.\" $NetBSD: tcpdump.8,v 1.3 1995/03/06 19:11:46 mycroft Exp $
+.\"
+.\" @(#) Header: tcpdump.1,v 1.45 94/06/20 18:54:27 leres Exp (LBL)
+.\"
+.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that: (1) source code distributions
+.\" retain the above copyright notice and this paragraph in its entirety, (2)
+.\" distributions including binary code include the above copyright notice and
+.\" this paragraph in its entirety in the documentation or other materials
+.\" provided with the distribution, and (3) all advertising materials mentioning
+.\" features or use of this software display the following acknowledgement:
+.\" ``This product includes software developed by the University of California,
+.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+.\" the University nor the names of its contributors may be used to endorse
+.\" or promote products derived from this software without specific prior
+.\" written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.TH TCPDUMP 1 "20 Jun 1994"
+.SH NAME
+tcpdump \- dump traffic on a network
+.SH SYNOPSIS
+.na
+.B tcpdump
+[
+.B \-deflnNOpqStvx
+] [
+.B \-c
+.I count
+] [
+.B \-F
+.I file
+]
+.br
+.ti +8
+[
+.B \-i
+.I interface
+] [
+.B \-r
+.I file
+]
+[
+.B \-s
+.I snaplen
+]
+.br
+.ti +8
+[
+.B \-w
+.I file
+]
+.I expression
+.br
+.ad
+.SH DESCRIPTION
+.LP
+\fITcpdump\fP prints out the headers of packets on a network interface
+that match the boolean \fIexpression\fP.
+.B Under SunOS:
+You must be root to invoke \fItcpdump\fP or it must be installed
+setuid to root.
+.B Under Ultrix:
+Any user can invoke \fItcpdump\fP once the super-user has enabled
+promiscuous-mode operation using
+.IR pfconfig (8).
+.B Under BSD:
+Access is controlled by the permissions on
+.I /dev/bpf0,
+etc.
+.SH OPTIONS
+.TP
+.B \-c
+Exit after receiving \fIcount\fP packets.
+.TP
+.B \-d
+Dump the compiled packet-matching code to standard output and stop.
+.TP
+.B \-e
+Print the link-level header on each dump line.
+.TP
+.B \-f
+Print `foreign' internet addresses numerically rather than symbolically
+(this option is intended to get around serious brain damage in
+Sun's yp server \(em usually it hangs forever translating non-local
+internet numbers).
+.TP
+.B \-F
+Use \fIfile\fP as input for the filter expression.
+An additional expression given on the command line is ignored.
+.TP
+.B \-i
+Listen on \fIinterface\fP.
+If unspecified, \fItcpdump\fP searches the system interface list for the
+lowest numbered, configured up interface (excluding loopback).
+Ties are broken by choosing the earliest match.
+.TP
+.B \-l
+Make stdout line buffered. Useful if you want to see the data
+while capturing it. E.g.,
+.br
+``tcpdump\ \ \-l\ \ |\ \ tee dat'' or
+``tcpdump\ \ \-l \ \ > dat\ \ &\ \ tail\ \ \-f\ \ dat''.
+.TP
+.B \-n
+Don't convert addresses (i.e., host addresses, port numbers, etc.) to names.
+.TP
+.B \-N
+Don't print domain name qualification of host names. E.g.,
+if you give this flag then \fItcpdump\fP will print ``nic''
+instead of ``nic.ddn.mil''.
+.TP
+.B \-O
+Do not run the packet-matching code optimizer. This is useful only
+if you suspect a bug in the optimizer.
+.TP
+.B \-p
+\fIDon't\fP put the interface
+into promiscuous mode. Note that the interface might be in promiscuous
+for some other reason; hence, `-p' cannot be used as an abbreviation for
+`ether host {localhost} or broadcast'.
+.TP
+.B \-q
+Quick (quiet?) output. Print less protocol information so output
+lines are shorter.
+.TP
+.B \-r
+Read packets from \fIfile\fR (which was created with the -w option).
+Standard input is used if \fIfile\fR is ``-''.
+.TP
+.B \-s
+Snarf \fIsnaplen\fP bytes of data from each packet rather than the
+default of 68 (with NIT, the minimum is actually 96).
+68 bytes is adequate for IP, ICMP, TCP
+and UDP but may truncate protocol information from name server and NFS
+packets (see below). Packets truncated because of a limited snapshot
+are indicated in the output with ``[|\fIproto\fP]'', where \fIproto\fP
+is the name of the protocol level at which the truncation has occurred.
+Note that taking larger snapshots both increases
+the amount of time it takes to process packets and, effectively,
+decreases the amount of packet buffering. This may cause packets to be
+lost. You should limit \fIsnaplen\fP to the smallest number that will
+capture the protocol information you're interested in.
+.TP
+.B \-S
+Print absolute, rather than relative, TCP sequence numbers.
+.TP
+.B \-t
+\fIDon't\fP print a timestamp on each dump line.
+.TP
+.B \-tt
+Print an unformatted timestamp on each dump line.
+.TP
+.B \-v
+(Slightly more) verbose output. For example, the time to live
+and type of service information in an IP packet is printed.
+.TP
+.B \-vv
+Even more verbose output. For example, additional fields are
+printed from NFS reply packets.
+.TP
+.B \-w
+Write the raw packets to \fIfile\fR rather than parsing and printing
+them out. They can later be printed with the \-r option.
+Standard output is used if \fIfile\fR is ``-''.
+.TP
+.B \-x
+Print each packet (minus its link level header) in hex.
+The smaller of the entire packet or
+.I snaplen
+bytes will be printed.
+.IP "\fI expression\fP"
+.RS
+selects which packets will be dumped. If no \fIexpression\fP
+is given, all packets on the net will be dumped. Otherwise,
+only packets for which \fIexpression\fP is `true' will be dumped.
+.LP
+The \fIexpression\fP consists of one or more
+.I primitives.
+Primitives usually consist of an
+.I id
+(name or number) preceded by one or more qualifiers. There are three
+different kinds of qualifier:
+.IP \fItype\fP
+qualifiers say what kind of thing the id name or number refers to.
+Possible types are
+.BR host ,
+.B net
+and
+.BR port .
+E.g., `host foo', `net 128.3', `port 20'. If there is no type
+qualifier,
+.B host
+is assumed.
+.IP \fIdir\fP
+qualifiers specify a particular tranfer direction to and/or from
+.I id.
+Possible directions are
+.BR src ,
+.BR dst ,
+.B "src or dst"
+and
+.B "src and"
+.BR dst .
+E.g., `src foo', `dst net 128.3', `src or dst port ftp-data'. If
+there is no dir qualifier,
+.B "src or dst"
+is assumed.
+.IP \fIproto\fP
+qualifiers restrict the match to a particular protocol. Possible
+protos are:
+.BR ether ,
+.BR fddi ,
+.BR ip ,
+.BR arp ,
+.BR rarp ,
+.BR decnet ,
+.BR lat ,
+.BR moprc ,
+.BR mopdl ,
+.B tcp
+and
+.BR udp .
+E.g., `ether src foo', `arp net 128.3', `tcp port 21'. If there is
+no proto qualifier, all protocols consistent with the type are
+assumed. E.g., `src foo' means `(ip or arp or rarp) src foo'
+(except the latter is not legal syntax), `net bar' means `(ip or
+arp or rarp) net bar' and `port 53' means `(tcp or udp) port 53'.
+.LP
+[`fddi' is actually an alias for `ether'; the parser treats them
+identically as meaning ``the data link level used on the specified
+network interface.'' FDDI headers contain Ethernet-like source
+and destination addresses, and often contain Ethernet-like packet
+types, so you can filter on these FDDI fields just as with the
+analogous Ethernet fields. FDDI headers also contain other fields,
+but you cannot name them explicitly in a filter expression.]
+.LP
+In addition to the above, there are some special `primitive' keywords
+that don't follow the pattern:
+.BR gateway ,
+.BR broadcast ,
+.BR less ,
+.B greater
+and arithmetic expressions. All of these are described below.
+.LP
+More complex filter expressions are built up by using the words
+.BR and ,
+.B or
+and
+.B not
+to combine primitives. E.g., `host foo and not port ftp and not port ftp-data'.
+To save typing, identical qualifier lists can be omitted. E.g.,
+`tcp dst port ftp or ftp-data or domain' is exactly the same as
+`tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'.
+.LP
+Allowable primitives are:
+.IP "\fBdst host \fIhost\fR"
+True if the IP destination field of the packet is \fIhost\fP,
+which may be either an address or a name.
+.IP "\fBsrc host \fIhost\fR"
+True if the IP source field of the packet is \fIhost\fP.
+.IP "\fBhost \fIhost\fP
+True if either the IP source or destination of the packet is \fIhost\fP.
+Any of the above host expressions can be prepended with the keywords,
+\fBip\fP, \fBarp\fP, or \fBrarp\fP as in:
+.in +.5i
+.nf
+\fBip host \fIhost\fR
+.fi
+.in -.5i
+which is equivalent to:
+.in +.5i
+.nf
+\fBether proto \fI\\ip\fB and host \fIhost\fR
+.fi
+.in -.5i
+If \fIhost\fR is a name with multiple IP addresses, each address will
+be checked for a match.
+.IP "\fBether dst \fIehost\fP
+True if the ethernet destination address is \fIehost\fP. \fIEhost\fP
+may be either a name from /etc/ethers or a number (see
+.IR ethers (3N)
+for numeric format).
+.IP "\fBether src \fIehost\fP
+True if the ethernet source address is \fIehost\fP.
+.IP "\fBether host \fIehost\fP
+True if either the ethernet source or destination address is \fIehost\fP.
+.IP "\fBgateway\fP \fIhost\fP
+True if the packet used \fIhost\fP as a gateway. I.e., the ethernet
+source or destination address was \fIhost\fP but neither the IP source
+nor the IP destination was \fIhost\fP. \fIHost\fP must be a name and
+must be found in both /etc/hosts and /etc/ethers. (An equivalent
+expression is
+.in +.5i
+.nf
+\fBether host \fIehost \fBand not host \fIhost\fR
+.fi
+.in -.5i
+which can be used with either names or numbers for \fIhost / ehost\fP.)
+.IP "\fBdst net \fInet\fR"
+True if the IP destination address of the packet has a network
+number of \fInet\fP, which may be either an address or a name.
+.IP "\fBsrc net \fInet\fR"
+True if the IP source address of the packet has a network
+number of \fInet\fP.
+.IP "\fBnet \fInet\fR"
+True if either the IP source or destination address of the packet has a network
+number of \fInet\fP.
+.IP "\fBdst port \fIport\fR"
+True if the packet is ip/tcp or ip/udp and has a
+destination port value of \fIport\fP.
+The \fIport\fP can be a number or a name used in /etc/services (see
+.IR tcp (4P)
+and
+.IR udp (4P)).
+If a name is used, both the port
+number and protocol are checked. If a number or ambiguous name is used,
+only the port number is checked (e.g., \fBdst port 513\fR will print both
+tcp/login traffic and udp/who traffic, and \fBport domain\fR will print
+both tcp/domain and udp/domain traffic).
+.IP "\fBsrc port \fIport\fR"
+True if the packet has a source port value of \fIport\fP.
+.IP "\fBport \fIport\fR"
+True if either the source or destination port of the packet is \fIport\fP.
+Any of the above port expressions can be prepended with the keywords,
+\fBtcp\fP or \fBudp\fP, as in:
+.in +.5i
+.nf
+\fBtcp src port \fIport\fR
+.fi
+.in -.5i
+which matches only tcp packets.
+.IP "\fBless \fIlength\fR"
+True if the packet has a length less than or equal to \fIlength\fP.
+This is equivalent to:
+.in +.5i
+.nf
+\fBlen <= \fIlength\fP.
+.fi
+.in -.5i
+.IP "\fBgreater \fIlength\fR"
+True if the packet has a length greater than or equal to \fIlength\fP.
+This is equivalent to:
+.in +.5i
+.nf
+\fBlen >= \fIlength\fP.
+.fi
+.in -.5i
+.IP "\fBip proto \fIprotocol\fR"
+True if the packet is an ip packet (see
+.IR ip (4P))
+of protocol type \fIprotocol\fP.
+\fIProtocol\fP can be a number or one of the names
+\fIicmp\fP, \fIudp\fP, \fInd\fP, or \fItcp\fP.
+Note that the identifiers \fItcp\fP, \fIudp\fP, and \fIicmp\fP are also
+keywords and must be escaped via backslash (\\), which is \\\\ in the C-shell.
+.IP "\fBether broadcast\fR"
+True if the packet is an ethernet broadcast packet. The \fIether\fP
+keyword is optional.
+.IP "\fBip broadcast\fR"
+True if the packet is an IP broadcast packet. It checks for both
+the all-zeroes and all-ones broadcast conventions, and looks up
+the local subnet mask.
+.IP "\fBether multicast\fR"
+True if the packet is an ethernet multicast packet. The \fIether\fP
+keyword is optional.
+This is shorthand for `\fBether[0] & 1 != 0\fP'.
+.IP "\fBip multicast\fR"
+True if the packet is an IP multicast packet.
+.IP "\fBether proto \fIprotocol\fR"
+True if the packet is of ether type \fIprotocol\fR.
+\fIProtocol\fP can be a number or a name like
+\fIip\fP, \fIarp\fP, or \fIrarp\fP.
+Note these identifiers are also keywords
+and must be escaped via backslash (\\).
+[In the case of FDDI (e.g., `\fBfddi protocol arp\fR'), the
+protocol identification comes from the 802.2 Logical Link Control
+(LLC) header, which is usually layered on top of the FDDI header.
+\fItcpdump\fP assumes, when filtering on the protocol identifier,
+that all FDDI packets include an LLC header, and that the LLC header
+is in so-called SNAP format.]
+.IP "\fBdecnet src \fIhost\fR"
+True if the DECNET source address is
+.IR host ,
+which may be an address of the form ``10.123'', or a DECNET host
+name. [DECNET host name support is only available on Ultrix systems
+that are configured to run DECNET.]
+.IP "\fBdecnet dst \fIhost\fR"
+True if the DECNET destination address is
+.IR host .
+.IP "\fBdecnet host \fIhost\fR"
+True if either the DECNET source or destination address is
+.IR host .
+.IP "\fBip\fR, \fBarp\fR, \fBrarp\fR, \fBdecnet\fR"
+Abbreviations for:
+.in +.5i
+.nf
+\fBether proto \fIp\fR
+.fi
+.in -.5i
+where \fIp\fR is one of the above protocols.
+.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR"
+Abbreviations for:
+.in +.5i
+.nf
+\fBether proto \fIp\fR
+.fi
+.in -.5i
+where \fIp\fR is one of the above protocols.
+Note that
+\fItcpdump\fP does not currently know how to parse these protocols.
+.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
+Abbreviations for:
+.in +.5i
+.nf
+\fBip proto \fIp\fR
+.fi
+.in -.5i
+where \fIp\fR is one of the above protocols.
+.IP "\fIexpr relop expr\fR"
+True if the relation holds, where \fIrelop\fR is one of >, <, >=, <=, =, !=,
+and \fIexpr\fR is an arithmetic expression composed of integer constants
+(expressed in standard C syntax), the normal binary operators
+[+, -, *, /, &, |], a length operator, and special packet data accessors.
+To access
+data inside the packet, use the following syntax:
+.in +.5i
+.nf
+\fIproto\fB [ \fIexpr\fB : \fIsize\fB ]\fR
+.fi
+.in -.5i
+\fIProto\fR is one of \fBether, fddi,
+ip, arp, rarp, tcp, udp, \fRor \fBicmp\fR, and
+indicates the protocol layer for the index operation.
+The byte offset, relative to the indicated protocol layer, is
+given by \fIexpr\fR.
+\fISize\fR is optional and indicates the number of bytes in the
+field of interest; it can be either one, two, or four, and defaults to one.
+The length operator, indicated by the keyword \fBlen\fP, gives the
+length of the packet.
+
+For example, `\fBether[0] & 1 != 0\fP' catches all multicast traffic.
+The expression `\fBip[0] & 0xf != 5\fP'
+catches all IP packets with options. The expression
+`\fBip[6:2] & 0x1fff = 0\fP'
+catches only unfragmented datagrams and frag zero of fragmented datagrams.
+This check is implicitly applied to the \fBtcp\fP and \fBudp\fP
+index operations.
+For instance, \fBtcp[0]\fP always means the first
+byte of the TCP \fIheader\fP, and never means the first byte of an
+intervening fragment.
+.LP
+Primitives may be combined using:
+.IP
+A parenthesized group of primitives and operators
+(parentheses are special to the Shell and must be escaped).
+.IP
+Negation (`\fB!\fP' or `\fBnot\fP').
+.IP
+Concatenation (`\fB&&\fP' or `\fBand\fP').
+.IP
+Alternation (`\fB||\fP' or `\fBor\fP').
+.LP
+Negation has highest precedence.
+Alternation and concatenation have equal precedence and associate
+left to right. Note that explicit \fBand\fR tokens, not juxtaposition,
+are now required for concatenation.
+.LP
+If an identifier is given without a keyword, the most recent keyword
+is assumed.
+For example,
+.in +.5i
+.nf
+\fBnot host vs and ace\fR
+.fi
+.in -.5i
+is short for
+.in +.5i
+.nf
+\fBnot host vs and host ace\fR
+.fi
+.in -.5i
+which should not be confused with
+.in +.5i
+.nf
+\fBnot ( host vs or ace )\fR
+.fi
+.in -.5i
+.LP
+Expression arguments can be passed to tcpdump as either a single argument
+or as multiple arguments, whichever is more convenient.
+Generally, if the expression contains Shell metacharacters, it is
+easier to pass it as a single, quoted argument.
+Multiple arguments are concatenated with spaces before being parsed.
+.SH EXAMPLES
+.LP
+To print all packets arriving at or departing from \fIsundown\fP:
+.RS
+.nf
+\fBtcpdump host sundown\fP
+.fi
+.RE
+.LP
+To print traffic between \fIhelios\fR and either \fIhot\fR or \fIace\fR:
+.RS
+.nf
+\fBtcpdump host helios and \\( hot or ace \\)\fP
+.fi
+.RE
+.LP
+To print all IP packets between \fIace\fR and any host except \fIhelios\fR:
+.RS
+.nf
+\fBtcpdump ip host ace and not helios\fP
+.fi
+.RE
+.LP
+To print all traffic between local hosts and hosts at Berkeley:
+.RS
+.nf
+.B
+tcpdump net ucb-ether
+.fi
+.RE
+.LP
+To print all ftp traffic through internet gateway \fIsnup\fP:
+(note that the expression is quoted to prevent the shell from
+(mis-)interpreting the parentheses):
+.RS
+.nf
+.B
+tcpdump 'gateway snup and (port ftp or ftp-data)'
+.fi
+.RE
+.LP
+To print traffic neither sourced from nor destined for local hosts
+(if you gateway to one other net, this stuff should never make it
+onto your local net).
+.RS
+.nf
+.B
+tcpdump ip and not net \fIlocalnet\fP
+.fi
+.RE
+.LP
+To print the start and end packets (the SYN and FIN packets) of each
+TCP conversation that involves a non-local host.
+.RS
+.nf
+.B
+tcpdump 'tcp[13] & 3 != 0 and not src and dst net \fIlocalnet\fP'
+.fi
+.RE
+.LP
+To print IP packets longer than 576 bytes sent through gateway \fIsnup\fP:
+.RS
+.nf
+.B
+tcpdump 'gateway snup and ip[2:2] > 576'
+.fi
+.RE
+.LP
+To print IP broadcast or multicast packets that were
+.I not
+sent via ethernet broadcast or multicast:
+.RS
+.nf
+.B
+tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224'
+.fi
+.RE
+.LP
+To print all ICMP packets that are not echo requests/replies (i.e., not
+ping packets):
+.RS
+.nf
+.B
+tcpdump 'icmp[0] != 8 and icmp[0] != 0"
+.fi
+.RE
+.SH OUTPUT FORMAT
+.LP
+The output of \fItcpdump\fP is protocol dependent. The following
+gives a brief description and examples of most of the formats.
+.de HD
+.sp 1.5
+.B
+..
+.HD
+Link Level Headers
+.LP
+If the '-e' option is given, the link level header is printed out.
+On ethernets, the source and destination addresses, protocol,
+and packet length are printed.
+.LP
+On FDDI networks, the '-e' option causes \fItcpdump\fP to print
+the `frame control' field, the source and destination addresses,
+and the packet length. (The `frame control' field governs the
+interpretation of the rest of the packet. Normal packets (such
+as those containing IP datagrams) are `async' packets, with a priority
+value between 0 and 7; for example, `\fBasync4\fR'. Such packets
+are assumed to contain an 802.2 Logical Link Control (LLC) packet;
+the LLC header is printed if it is \fInot\fR an ISO datagram or a
+so-called SNAP packet.
+.LP
+\fI(N.B.: The following description assumes familiarity with
+the SLIP compression algorithm described in RFC-1144.)\fP
+.LP
+On SLIP links, a direction indicator (``I'' for inbound, ``O'' for outbound),
+packet type, and compression information are printed out.
+The packet type is printed first.
+The three types are \fIip\fP, \fIutcp\fP, and \fIctcp\fP.
+No further link information is printed for \fIip\fR packets.
+For TCP packets, the connection identifier is printed following the type.
+If the packet is compressed, its encoded header is printed out.
+The special cases are printed out as
+\fB*S+\fIn\fR and \fB*SA+\fIn\fR, where \fIn\fR is the amount by which
+the sequence number (or sequence number and ack) has changed.
+If it is not a special case,
+zero or more changes are printed.
+A change is indicated by U (urgent pointer), W (window), A (ack),
+S (sequence number), and I (packet ID), followed by a delta (+n or -n),
+or a new value (=n).
+Finally, the amount of data in the packet and compressed header length
+are printed.
+.LP
+For example, the following line shows an outbound compressed TCP packet,
+with an implicit connection identifier; the ack has changed by 6,
+the sequence number by 49, and the packet ID by 6; there are 3 bytes of
+data and 6 bytes of compressed header:
+.RS
+.nf
+\fBO ctcp * A+6 S+49 I+6 3 (6)\fP
+.fi
+.RE
+.HD
+ARP/RARP Packets
+.LP
+Arp/rarp output shows the type of request and its arguments. The
+format is intended to be self explanatory.
+Here is a short sample taken from the start of an `rlogin' from
+host \fIrtsg\fP to host \fIcsam\fP:
+.RS
+.nf
+.sp .5
+\f(CWarp who-has csam tell rtsg
+arp reply csam is-at CSAM\fP
+.sp .5
+.fi
+.RE
+The first line says that rtsg sent an arp packet asking
+for the ethernet address of internet host csam. Csam
+replies with its ethernet address (in this example, ethernet addresses
+are in caps and internet addresses in lower case).
+.LP
+This would look less redundant if we had done \fBtcpdump \-n\fP:
+.RS
+.nf
+.sp .5
+\f(CWarp who-has 128.3.254.6 tell 128.3.254.68
+arp reply 128.3.254.6 is-at 02:07:01:00:01:c4\fP
+.fi
+.RE
+.LP
+If we had done \fBtcpdump \-e\fP, the fact that the first packet is
+broadcast and the second is point-to-point would be visible:
+.RS
+.nf
+.sp .5
+\f(CWRTSG Broadcast 0806 64: arp who-has csam tell rtsg
+CSAM RTSG 0806 64: arp reply csam is-at CSAM\fP
+.sp .5
+.fi
+.RE
+For the first packet this says the ethernet source address is RTSG, the
+destination is the broadcast address, the type field
+contained hex 0806 (type ETHER_ARP) and the total length was 64 bytes.
+.HD
+TCP Packets
+.LP
+\fI(N.B.:The following description assumes familiarity with
+the TCP protocol described in RFC-793. If you are not familiar
+with the protocol, neither this description nor tcpdump will
+be of much use to you.)\fP
+.LP
+The general format of a tcp protocol line is:
+.RS
+.nf
+.sp .5
+\fIsrc > dst: flags data-seqno ack window urgent options\fP
+.sp .5
+.fi
+.RE
+\fISrc\fP and \fIdst\fP are the source and destination IP
+addresses and ports. \fIFlags\fP are some combination of S (SYN),
+F (FIN), P (PUSH) or R (RST) or a single `.' (no flags).
+\fIData-seqno\fP describes the portion of sequence space covered
+by the data in this packet (see example below).
+\fIAck\fP is sequence number of the next data expected the other
+direction on this connection.
+\fIWindow\fP is the number of bytes of receive buffer space available
+the other direction on this connection.
+\fIUrg\fP indicates there is `urgent' data in the packet.
+\fIOptions\fP are tcp options enclosed in angle brackets (e.g., <mss 1024>).
+.LP
+\fISrc, dst\fP and \fIflags\fP are always present. The other fields
+depend on the contents of the packet's tcp protocol header and
+are output only if appropriate.
+.LP
+Here is the opening portion of an rlogin from host \fIrtsg\fP to
+host \fIcsam\fP.
+.RS
+.nf
+.sp .5
+\s-2\f(CWrtsg.1023 > csam.login: S 768512:768512(0) win 4096 <mss 1024>
+csam.login > rtsg.1023: S 947648:947648(0) ack 768513 win 4096 <mss 1024>
+rtsg.1023 > csam.login: . ack 1 win 4096
+rtsg.1023 > csam.login: P 1:2(1) ack 1 win 4096
+csam.login > rtsg.1023: . ack 2 win 4096
+rtsg.1023 > csam.login: P 2:21(19) ack 1 win 4096
+csam.login > rtsg.1023: P 1:2(1) ack 21 win 4077
+csam.login > rtsg.1023: P 2:3(1) ack 21 win 4077 urg 1
+csam.login > rtsg.1023: P 3:4(1) ack 21 win 4077 urg 1\fP\s+2
+.sp .5
+.fi
+.RE
+The first line says that tcp port 1023 on rtsg sent a packet
+to port \fIlogin\fP
+on csam. The \fBS\fP indicates that the \fISYN\fP flag was set.
+The packet sequence number was 768512 and it contained no data.
+(The notation is `first:last(nbytes)' which means `sequence
+numbers \fIfirst\fP
+up to but not including \fIlast\fP which is \fInbytes\fP bytes of user data'.)
+There was no piggy-backed ack, the available receive window was 4096
+bytes and there was a max-segment-size option requesting an mss of
+1024 bytes.
+.LP
+Csam replies with a similar packet except it includes a piggy-backed
+ack for rtsg's SYN. Rtsg then acks csam's SYN. The `.' means no
+flags were set.
+The packet contained no data so there is no data sequence number.
+Note that the ack sequence
+number is a small integer (1). The first time \fBtcpdump\fP sees a
+tcp `conversation', it prints the sequence number from the packet.
+On subsequent packets of the conversation, the difference between
+the current packet's sequence number and this initial sequence number
+is printed. This means that sequence numbers after the
+first can be interpreted
+as relative byte positions in the conversation's data stream (with the
+first data byte each direction being `1'). `-S' will override this
+feature, causing the original sequence numbers to be output.
+.LP
+On the 6th line, rtsg sends csam 19 bytes of data (bytes 2 through 20
+in the rtsg \(-> csam side of the conversation).
+The PUSH flag is set in the packet.
+On the 7th line, csam says it's received data sent by rtsg up to
+but not including byte 21. Most of this data is apparently sitting in the
+socket buffer since csam's receive window has gotten 19 bytes smaller.
+Csam also sends one byte of data to rtsg in this packet.
+On the 8th and 9th lines,
+csam sends two bytes of urgent, pushed data to rtsg.
+.HD
+.B
+UDP Packets
+.LP
+UDP format is illustrated by this rwho packet:
+.RS
+.nf
+.sp .5
+\f(CWactinide.who > broadcast.who: udp 84\fP
+.sp .5
+.fi
+.RE
+This says that port \fIwho\fP on host \fIactinide\fP sent a udp
+datagram to port \fIwho\fP on host \fIbroadcast\fP, the Internet
+broadcast address. The packet contained 84 bytes of user data.
+.LP
+Some UDP services are recognized (from the source or destination
+port number) and the higher level protocol information printed.
+In particular, Domain Name service requests (RFC-1034/1035) and Sun
+RPC calls (RFC-1050) to NFS.
+.HD
+UDP Name Server Requests
+.LP
+\fI(N.B.:The following description assumes familiarity with
+the Domain Service protocol described in RFC-1035. If you are not familiar
+with the protocol, the following description will appear to be written
+in greek.)\fP
+.LP
+Name server requests are formatted as
+.RS
+.nf
+.sp .5
+\fIsrc > dst: id op? flags qtype qclass name (len)\fP
+.sp .5
+\f(CWh2opolo.1538 > helios.domain: 3+ A? ucbvax.berkeley.edu. (37)\fP
+.sp .5
+.fi
+.RE
+Host \fIh2opolo\fP asked the domain server on \fIhelios\fP for an
+address record (qtype=A) associated with the name \fIucbvax.berkeley.edu.\fP
+The query id was `3'. The `+' indicates the \fIrecursion desired\fP flag
+was set. The query length was 37 bytes, not including the UDP and
+IP protocol headers. The query operation was the normal one, \fIQuery\fP,
+so the op field was omitted. If the op had been anything else, it would
+have been printed between the `3' and the `+'.
+Similarly, the qclass was the normal one,
+\fIC_IN\fP, and omitted. Any other qclass would have been printed
+immediately after the `A'.
+.LP
+A few anomalies are checked and may result in extra fields enclosed in
+square brackets: If a query contains an answer, name server or
+authority section,
+.IR ancount ,
+.IR nscount ,
+or
+.I arcount
+are printed as `[\fIn\fPa]', `[\fIn\fPn]' or `[\fIn\fPau]' where \fIn\fP
+is the appropriate count.
+If any of the response bits are set (AA, RA or rcode) or any of the
+`must be zero' bits are set in bytes two and three, `[b2&3=\fIx\fP]'
+is printed, where \fIx\fP is the hex value of header bytes two and three.
+.HD
+UDP Name Server Responses
+.LP
+Name server responses are formatted as
+.RS
+.nf
+.sp .5
+\fIsrc > dst: id op rcode flags a/n/au type class data (len)\fP
+.sp .5
+\f(CWhelios.domain > h2opolo.1538: 3 3/3/7 A 128.32.137.3 (273)
+helios.domain > h2opolo.1537: 2 NXDomain* 0/1/0 (97)\fP
+.sp .5
+.fi
+.RE
+In the first example, \fIhelios\fP responds to query id 3 from \fIh2opolo\fP
+with 3 answer records, 3 name server records and 7 authority records.
+The first answer record is type A (address) and its data is internet
+address 128.32.137.3. The total size of the response was 273 bytes,
+excluding UDP and IP headers. The op (Query) and response code
+(NoError) were omitted, as was the class (C_IN) of the A record.
+.LP
+In the second example, \fIhelios\fP responds to query 2 with a
+response code of non-existent domain (NXDomain) with no answers,
+one name server and no authority records. The `*' indicates that
+the \fIauthoritative answer\fP bit was set. Since there were no
+answers, no type, class or data were printed.
+.LP
+Other flag characters that might appear are `\-' (recursion available,
+RA, \fInot\fP set) and `|' (truncated message, TC, set). If the
+`question' section doesn't contain exactly one entry, `[\fIn\fPq]'
+is printed.
+.LP
+Note that name server requests and responses tend to be large and the
+default \fIsnaplen\fP of 96 bytes may not capture enough of the packet
+to print. Use the \fB\-s\fP flag to increase the snaplen if you
+need to seriously investigate name server traffic. `\fB\-s 128\fP'
+has worked well for me.
+
+.HD
+NFS Requests and Replies
+.LP
+Sun NFS (Network File System) requests and replies are printed as:
+.RS
+.nf
+.sp .5
+\fIsrc.xid > dst.nfs: len op args\fP
+\fIsrc.nfs > dst.xid: reply stat len op results\fP
+.sp .5
+\f(CW
+sushi.6709 > wrl.nfs: 112 readlink fh 21,24/10.73165
+wrl.nfs > sushi.6709: reply ok 40 readlink "../var"
+sushi.201b > wrl.nfs:
+ 144 lookup fh 9,74/4096.6878 "xcolors"
+wrl.nfs > sushi.201b:
+ reply ok 128 lookup fh 9,74/4134.3150
+\fP
+.sp .5
+.fi
+.RE
+In the first line, host \fIsushi\fP sends a transaction with id \fI6709\fP
+to \fIwrl\fP (note that the number following the src host is a
+transaction id, \fInot\fP the source port). The request was 112 bytes,
+excluding the UDP and IP headers. The operation was a \fIreadlink\fP
+(read symbolic link) on file handle (\fIfh\fP) 21,24/10.731657119.
+(If one is lucky, as in this case, the file handle can be interpreted
+as a major,minor device number pair, followed by the inode number and
+generation number.)
+\fIWrl\fP replies `ok' with the contents of the link.
+.LP
+In the third line, \fIsushi\fP asks \fIwrl\fP to lookup the name
+`\fIxcolors\fP' in directory file 9,74/4096.6878. Note that the data printed
+depends on the operation type. The format is intended to be self
+explanatory if read in conjunction with
+an NFS protocol spec.
+.LP
+If the \-v (verbose) flag is given, additional information is printed.
+For example:
+.RS
+.nf
+.sp .5
+\f(CW
+sushi.1372a > wrl.nfs:
+ 148 read fh 21,11/12.195 8192 bytes @ 24576
+wrl.nfs > sushi.1372a:
+ reply ok 1472 read REG 100664 ids 417/0 sz 29388
+\fP
+.sp .5
+.fi
+.RE
+(\-v also prints the IP header TTL, ID, and fragmentation fields,
+which have been omitted from this example.) In the first line,
+\fIsushi\fP asks \fIwrl\fP to read 8192 bytes from file 21,11/12.195,
+at byte offset 24576. \fIWrl\fP replies `ok'; the packet shown on the
+second line is the first fragment of the reply, and hence is only 1472
+bytes long (the other bytes will follow in subsequent fragments, but
+these fragments do not have NFS or even UDP headers and so might not be
+printed, depending on the filter expression used). Because the \-v flag
+is given, some of the file attributes (which are returned in addition
+to the file data) are printed: the file type (``REG'', for regular file),
+the file mode (in octal), the uid and gid, and the file size.
+.LP
+If the \-v flag is given more than once, even more details are printed.
+.LP
+Note that NFS requests are very large and much of the detail won't be printed
+unless \fIsnaplen\fP is increased. Try using `\fB\-s 192\fP' to watch
+NFS traffic.
+.LP
+NFS reply packets do not explicitly identify the RPC operation. Instead,
+\fItcpdump\fP keeps track of ``recent'' requests, and matches them to the
+replies using the transaction ID. If a reply does not closely follow the
+corresponding request, it might not be parseble.
+.HD
+KIP Appletalk (DDP in UDP)
+.LP
+Appletalk DDP packets encapsulated in UDP datagrams are de-encapsulated
+and dumped as DDP packets (i.e., all the UDP header information is
+discarded). The file
+.I /etc/atalk.names
+is used to translate appletalk net and node numbers to names.
+Lines in this file have the form
+.RS
+.nf
+.sp .5
+\fInumber name\fP
+
+\f(CW1.254 ether
+16.1 icsd-net
+1.254.110 ace\fP
+.sp .5
+.fi
+.RE
+The first two lines give the names of appletalk networks. The third
+line gives the name of a particular host (a host is distinguished
+from a net by the 3rd octet in the number \-
+a net number \fImust\fP have two octets and a host number \fImust\fP
+have three octets.) The number and name should be separated by
+whitespace (blanks or tabs).
+The
+.I /etc/atalk.names
+file may contain blank lines or comment lines (lines starting with
+a `#').
+.LP
+Appletalk addresses are printed in the form
+.RS
+.nf
+.sp .5
+\fInet.host.port\fP
+
+\f(CW144.1.209.2 > icsd-net.112.220
+office.2 > icsd-net.112.220
+jssmag.149.235 > icsd-net.2\fP
+.sp .5
+.fi
+.RE
+(If the
+.I /etc/atalk.names
+doesn't exist or doesn't contain an entry for some appletalk
+host/net number, addresses are printed in numeric form.)
+In the first example, NBP (DDP port 2) on net 144.1 node 209
+is sending to whatever is listening on port 220 of net icsd node 112.
+The second line is the same except the full name of the source node
+is known (`office'). The third line is a send from port 235 on
+net jssmag node 149 to broadcast on the icsd-net NBP port (note that
+the broadcast address (255) is indicated by a net name with no host
+number \- for this reason it's a good idea to keep node names and
+net names distinct in /etc/atalk.names).
+.LP
+NBP (name binding protocol) and ATP (Appletalk transaction protocol)
+packets have their contents interpreted. Other protocols just dump
+the protocol name (or number if no name is registered for the
+protocol) and packet size.
+
+\fBNBP packets\fP are formatted like the following examples:
+.RS
+.nf
+.sp .5
+\s-2\f(CWicsd-net.112.220 > jssmag.2: nbp-lkup 190: "=:LaserWriter@*"
+jssmag.209.2 > icsd-net.112.220: nbp-reply 190: "RM1140:LaserWriter@*" 250
+techpit.2 > icsd-net.112.220: nbp-reply 190: "techpit:LaserWriter@*" 186\fP\s+2
+.sp .5
+.fi
+.RE
+The first line is a name lookup request for laserwriters sent by net icsd host
+112 and broadcast on net jssmag. The nbp id for the lookup is 190.
+The second line shows a reply for this request (note that it has the
+same id) from host jssmag.209 saying that it has a laserwriter
+resource named "RM1140" registered on port 250. The third line is
+another reply to the same request saying host techpit has laserwriter
+"techpit" registered on port 186.
+
+\fBATP packet\fP formatting is demonstrated by the following example:
+.RS
+.nf
+.sp .5
+\s-2\f(CWjssmag.209.165 > helios.132: atp-req 12266<0-7> 0xae030001
+helios.132 > jssmag.209.165: atp-resp 12266:0 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:1 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:2 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:4 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:6 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp*12266:7 (512) 0xae040000
+jssmag.209.165 > helios.132: atp-req 12266<3,5> 0xae030001
+helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000
+helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000
+jssmag.209.165 > helios.132: atp-rel 12266<0-7> 0xae030001
+jssmag.209.133 > helios.132: atp-req* 12267<0-7> 0xae030002\fP\s+2
+.sp .5
+.fi
+.RE
+Jssmag.209 initiates transaction id 12266 with host helios by requesting
+up to 8 packets (the `<0-7>'). The hex number at the end of the line
+is the value of the `userdata' field in the request.
+.LP
+Helios responds with 8 512-byte packets. The `:digit' following the
+transaction id gives the packet sequence number in the transaction
+and the number in parens is the amount of data in the packet,
+excluding the atp header. The `*' on packet 7 indicates that the
+EOM bit was set.
+.LP
+Jssmag.209 then requests that packets 3 & 5 be retransmitted. Helios
+resends them then jssmag.209 releases the transaction. Finally,
+jssmag.209 initiates the next request. The `*' on the request
+indicates that XO (`exactly once') was \fInot\fP set.
+
+.HD
+IP Fragmentation
+.LP
+Fragmented Internet datagrams are printed as
+.RS
+.nf
+.sp .5
+\fB(frag \fIid\fB:\fIsize\fB@\fIoffset\fB+)\fR
+\fB(frag \fIid\fB:\fIsize\fB@\fIoffset\fB)\fR
+.sp .5
+.fi
+.RE
+(The first form indicates there are more fragments. The second
+indicates this is the last fragment.)
+.LP
+\fIId\fP is the fragment id. \fISize\fP is the fragment
+size (in bytes) excluding the IP header. \fIOffset\fP is this
+fragment's offset (in bytes) in the original datagram.
+.LP
+The fragment information is output for each fragment. The first
+fragment contains the higher level protocol header and the frag
+info is printed after the protocol info. Fragments
+after the first contain no higher level protocol header and the
+frag info is printed after the source and destination addresses.
+For example, here is part of an ftp from arizona.edu to lbl-rtsg.arpa
+over a CSNET connection that doesn't appear to handle 576 byte datagrams:
+.RS
+.nf
+.sp .5
+\s-2\f(CWarizona.ftp-data > rtsg.1170: . 1024:1332(308) ack 1 win 4096 (frag 595a:328@0+)
+arizona > rtsg: (frag 595a:204@328)
+rtsg.1170 > arizona.ftp-data: . ack 1536 win 2560\fP\s+2
+.sp .5
+.fi
+.RE
+There are a couple of things to note here: First, addresses in the
+2nd line don't include port numbers. This is because the TCP
+protocol information is all in the first fragment and we have no idea
+what the port or sequence numbers are when we print the later fragments.
+Second, the tcp sequence information in the first line is printed as if there
+were 308 bytes of user data when, in fact, there are 512 bytes (308 in
+the first frag and 204 in the second). If you are looking for holes
+in the sequence space or trying to match up acks
+with packets, this can fool you.
+.LP
+A packet with the IP \fIdon't fragment\fP flag is marked with a
+trailing \fB(DF)\fP.
+.HD
+Timestamps
+.LP
+By default, all output lines are preceded by a timestamp. The timestamp
+is the current clock time in the form
+.RS
+.nf
+\fIhh:mm:ss.frac\fP
+.fi
+.RE
+and is as accurate as the kernel's clock (e.g., \(+-10ms on a Sun-3).
+The timestamp reflects the time the kernel first saw the packet. No attempt
+is made to account for the time lag between when the
+ethernet interface removed the packet from the wire and when the kernel
+serviced the `new packet' interrupt (of course,
+with Sun's lousy clock resolution this time lag is negligible.)
+.SH "SEE ALSO"
+traffic(1C), nit(4P), bpf(4)
+.SH AUTHORS
+Van Jacobson (van@helios.ee.lbl.gov),
+Craig Leres (leres@helios.ee.lbl.gov) and
+Steven McCanne (mccanne@helios.ee.lbl.gov), all of
+Lawrence Berkeley Laboratory, University of California, Berkeley, CA.
+.SH BUGS
+The clock resolution on most Suns is pathetic (20ms).
+If you want to use the timestamp to generate some of the important
+performance distributions (like packet interarrival time) it's best
+to watch something that generates packets slowly (like an Arpanet
+gateway or a MicroVax running VMS).
+.LP
+NIT doesn't let you watch your own outbound traffic, BPF will.
+We recommend that you use the latter.
+.LP
+\fItcpdump\fP for Ultrix requires Ultrix version 4.0 or later; the kernel
+has to have been built with the \fIpacketfilter\fP pseudo-device driver
+(see
+.IR packetfilter (4)).
+In order to watch either your own outbound or inbound traffic,
+you will need to use Ultrix version 4.2 or later, and you will have
+to have used the
+.IR pfconfig (8)
+command to enable ``copyall'' mode.
+.LP
+Under SunOS 4.1, the packet capture code (or Streams NIT) is not what
+you'd call efficient. Don't plan on doing much with your Sun while
+you're monitoring a busy network.
+.LP
+On Sun systems prior to release 3.2, NIT is very buggy.
+If run on an old system, tcpdump may crash the machine.
+.LP
+Some attempt should be made to reassemble IP fragments or, at least
+to compute the right length for the higher level protocol.
+.LP
+Name server inverse queries are not dumped correctly: The (empty)
+question section is printed rather than real query in the answer
+section. Some believe that inverse queries are themselves a bug and
+prefer to fix the program generating them rather than tcpdump.
+.LP
+Apple Ethertalk DDP packets could be dumped as easily as KIP DDP
+packets but aren't.
+Even if we were inclined to do anything to promote the use of
+Ethertalk (we aren't), LBL doesn't allow Ethertalk on any of its
+networks so we'd would have no way of testing this code.
+.LP
+A packet trace that crosses a daylight savings time change will give
+skewed time stamps (the time change is ignored).
+.LP
+Filters expressions that manipulate FDDI headers assume that all FDDI
+packets are encapsulated Ethernet packets. This is true for IP, ARP,
+and DECNET Phase IV, but is not true for protocols such as ISO CLNS.
+Therefore, the filter may inadvertently accept certain packets that
+do not properly match the filter expression.
diff --git a/usr.sbin/tcpdump/tcpdump.c b/usr.sbin/tcpdump/tcpdump.c
new file mode 100644
index 00000000000..fc6b153c80a
--- /dev/null
+++ b/usr.sbin/tcpdump/tcpdump.c
@@ -0,0 +1,413 @@
+/* $NetBSD: tcpdump.c,v 1.3 1995/04/24 13:27:48 cgd Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+char copyright[] =
+ "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994\nThe Regents of the University of California. All rights reserved.\n";
+static char rcsid[] =
+ "@(#)Header: tcpdump.c,v 1.93 94/06/10 17:01:44 mccanne Exp (LBL)";
+#endif
+
+/*
+ * tcpdump - monitor tcp/ip traffic on an ethernet.
+ *
+ * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory.
+ * Mercilessly hacked and occasionally improved since then via the
+ * combined efforts of Van, Steve McCanne and Craig Leres of LBL.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <pcap.h>
+#include <signal.h>
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <unistd.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+int fflag; /* don't translate "foreign" IP address */
+int nflag; /* leave addresses as numbers */
+int Nflag; /* remove domains from printed host names */
+int pflag; /* don't go promiscuous */
+int qflag; /* quick (shorter) output */
+int tflag = 1; /* print packet arrival time */
+int eflag; /* print ethernet header */
+int vflag; /* verbose */
+int xflag; /* print packet in hex */
+int Oflag = 1; /* run filter code optimizer */
+int Sflag; /* print raw TCP sequence numbers */
+int packettype;
+
+int dflag; /* print filter code */
+
+char *program_name;
+
+int thiszone;
+
+SIGRET cleanup(int);
+extern void bpf_dump(struct bpf_program *, int);
+
+/* Length of saved portion of packet. */
+int snaplen = DEFAULT_SNAPLEN;
+
+struct printer {
+ pcap_handler f;
+ int type;
+};
+
+static struct printer printers[] = {
+ { ether_if_print, DLT_EN10MB },
+ { sl_if_print, DLT_SLIP },
+ { ppp_if_print, DLT_PPP },
+ { fddi_if_print, DLT_FDDI },
+ { null_if_print, DLT_NULL },
+ { NULL, 0 },
+};
+
+static pcap_handler
+lookup_printer(int type)
+{
+ struct printer *p;
+
+ for (p = printers; p->f; ++p)
+ if (type == p->type)
+ return p->f;
+
+ error("unknown data link type 0x%x", type);
+ /* NOTREACHED */
+}
+
+static pcap_t *pd;
+
+#ifdef __osf__
+#include <sys/sysinfo.h>
+#include <sys/proc.h>
+void
+abort_on_misalignment()
+{
+ int buf[2];
+
+ buf[0] = SSIN_UACPROC;
+ buf[1] = UAC_SIGBUS;
+ if (setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0) < 0) {
+ perror("setsysinfo");
+ exit(1);
+ }
+}
+
+#endif
+
+int
+main(int argc, char **argv)
+{
+ register int cnt, op;
+ u_long localnet, netmask;
+ register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;
+ pcap_handler printer;
+ struct bpf_program fcode;
+ u_char *pcap_userdata;
+ char errbuf[PCAP_ERRBUF_SIZE];
+
+ extern char *optarg;
+ extern int optind, opterr;
+
+#ifdef __osf__
+ abort_on_misalignment();
+#endif
+
+ cnt = -1;
+ device = NULL;
+ infile = NULL;
+ RFileName = NULL;
+ WFileName = NULL;
+ if ((cp = strrchr(argv[0], '/')) != NULL)
+ program_name = cp + 1;
+ else
+ program_name = argv[0];
+
+ opterr = 0;
+ while ((op = getopt(argc, argv, "c:defF:i:lnNOpqr:s:StT:vw:xY")) != EOF)
+ switch (op) {
+ case 'c':
+ cnt = atoi(optarg);
+ break;
+
+ case 'd':
+ ++dflag;
+ break;
+
+ case 'e':
+ ++eflag;
+ break;
+
+ case 'f':
+ ++fflag;
+ break;
+
+ case 'F':
+ infile = optarg;
+ break;
+
+ case 'i':
+ device = optarg;
+ break;
+
+ case 'l':
+ setlinebuf(stdout);
+ break;
+
+ case 'n':
+ ++nflag;
+ break;
+
+ case 'N':
+ ++Nflag;
+ break;
+
+ case 'O':
+ Oflag = 0;
+ break;
+
+ case 'p':
+ ++pflag;
+ break;
+
+ case 'q':
+ ++qflag;
+ break;
+
+ case 'r':
+ RFileName = optarg;
+ break;
+
+ case 's':
+ snaplen = atoi(optarg);
+ break;
+
+ case 'S':
+ ++Sflag;
+ break;
+
+ case 't':
+ --tflag;
+ break;
+
+ case 'T':
+ if (strcasecmp(optarg, "vat") == 0)
+ packettype = 1;
+ else if (strcasecmp(optarg, "wb") == 0)
+ packettype = 2;
+ else if (strcasecmp(optarg, "rpc") == 0)
+ packettype = 3;
+ else if (strcasecmp(optarg, "rtp") == 0)
+ packettype = 4;
+ else
+ error("unknown packet type `%s'", optarg);
+ break;
+
+ case 'v':
+ ++vflag;
+ break;
+
+ case 'w':
+ WFileName = optarg;
+ break;
+#ifdef YYDEBUG
+ case 'Y':
+ {
+ extern int yydebug;
+ yydebug = 1;
+ }
+ break;
+#endif
+ case 'x':
+ ++xflag;
+ break;
+
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+
+ if (tflag > 0)
+ thiszone = gmt2local();
+
+ if (RFileName != NULL) {
+ /*
+ * We don't need network access, so set it back to the user id.
+ * Also, this prevents the user from reading anyone's
+ * trace file.
+ */
+ setuid(getuid());
+
+ pd = pcap_open_offline(RFileName, errbuf);
+ if (pd == NULL)
+ error(errbuf);
+ localnet = 0;
+ netmask = 0;
+ if (fflag != 0)
+ error("-f and -r options are incompatible");
+ } else {
+ if (device == NULL) {
+ device = pcap_lookupdev(errbuf);
+ if (device == NULL)
+ error(errbuf);
+ }
+ pd = pcap_open_live(device, snaplen, !pflag, 1000, errbuf);
+ if (pd == NULL)
+ error(errbuf);
+ if (pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0)
+ error(errbuf);
+ /*
+ * Let user own process after socket has been opened.
+ */
+ setuid(getuid());
+ }
+ if (infile)
+ cmdbuf = read_infile(infile);
+ else
+ cmdbuf = copy_argv(&argv[optind]);
+
+ if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
+ error(pcap_geterr(pd));
+ if (dflag) {
+ bpf_dump(&fcode, dflag);
+ exit(0);
+ }
+ init_addrtoname(fflag, localnet, netmask);
+
+ (void)signal(SIGTERM, cleanup);
+ (void)signal(SIGINT, cleanup);
+ (void)signal(SIGHUP, cleanup);
+
+ if (pcap_setfilter(pd, &fcode) < 0)
+ error(pcap_geterr(pd));
+ if (WFileName) {
+ pcap_dumper_t *p = pcap_dump_open(pd, WFileName);
+ if (p == NULL)
+ error(pcap_geterr(pd));
+ printer = pcap_dump;
+ pcap_userdata = (u_char *)p;
+ } else {
+ printer = lookup_printer(pcap_datalink(pd));
+ pcap_userdata = 0;
+ }
+ if (RFileName == NULL) {
+ fprintf(stderr, "%s: listening on %s\n", program_name, device);
+ fflush(stderr);
+ }
+ pcap_loop(pd, cnt, printer, pcap_userdata);
+ pcap_close(pd);
+ exit(0);
+}
+
+/* make a clean exit on interrupts */
+SIGRET
+cleanup(int signo)
+{
+ struct pcap_stat stat;
+
+ /* Can't print the summary if reading from a savefile */
+ if (pd != NULL && pcap_file(pd) == NULL) {
+ (void)fflush(stdout);
+ putc('\n', stderr);
+ if (pcap_stats(pd, &stat) < 0)
+ (void)fprintf(stderr, "pcap_stats: %s\n",
+ pcap_geterr(pd));
+ else {
+ (void)fprintf(stderr, "%d packets received by filter\n",
+ stat.ps_recv);
+ (void)fprintf(stderr, "%d packets dropped by kernel\n",
+ stat.ps_drop);
+ }
+ }
+ exit(0);
+}
+
+/* Like default_print() but data need not be aligned */
+void
+default_print_unaligned(register const u_char *cp, register int length)
+{
+ register u_int i, s;
+ register int nshorts;
+
+ nshorts = (u_int) length / sizeof(u_short);
+ i = 0;
+ while (--nshorts >= 0) {
+ if ((i++ % 8) == 0)
+ (void)printf("\n\t\t\t");
+ s = *cp++;
+ (void)printf(" %02x%02x", s, *cp++);
+ }
+ if (length & 1) {
+ if ((i % 8) == 0)
+ (void)printf("\n\t\t\t");
+ (void)printf(" %02x", *cp);
+ }
+}
+
+void
+default_print(register const u_char *bp, register int length)
+{
+ register const u_short *sp;
+ register u_int i;
+ register int nshorts;
+
+ if ((long)bp & 1) {
+ default_print_unaligned(bp, length);
+ return;
+ }
+ sp = (u_short *)bp;
+ nshorts = (u_int) length / sizeof(u_short);
+ i = 0;
+ while (--nshorts >= 0) {
+ if ((i++ % 8) == 0)
+ (void)printf("\n\t\t\t");
+ (void)printf(" %04x", ntohs(*sp++));
+ }
+ if (length & 1) {
+ if ((i % 8) == 0)
+ (void)printf("\n\t\t\t");
+ (void)printf(" %02x", *(u_char *)sp);
+ }
+}
+
+void
+usage()
+{
+ extern char version[];
+
+ (void)fprintf(stderr, "Version %s\n", version);
+ (void)fprintf(stderr,
+"Usage: tcpdump [-deflnOpqtvx] [-c count] [-i interface]\n");
+ (void)fprintf(stderr,
+"\t\t[-r filename] [-w filename] [expr]\n");
+ exit(-1);
+}
diff --git a/usr.sbin/tcpdump/util.c b/usr.sbin/tcpdump/util.c
new file mode 100644
index 00000000000..2c456a85e27
--- /dev/null
+++ b/usr.sbin/tcpdump/util.c
@@ -0,0 +1,337 @@
+/* $NetBSD: util.c,v 1.3 1995/03/06 19:11:53 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) Header: util.c,v 1.28 94/06/12 14:30:31 leres Exp (LBL)";
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#ifdef SOLARIS
+#include <fcntl.h>
+#endif
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <string.h>
+#include <unistd.h>
+
+#include "interface.h"
+
+/*
+ * Print out a filename (or other ascii string).
+ * If ep is NULL, assume no truncation check is needed.
+ * Return true if truncated.
+ */
+int
+fn_print(register const u_char *s, register const u_char *ep)
+{
+ register int ret;
+ register u_char c;
+
+ ret = 1; /* assume truncated */
+ putchar('"');
+ while (ep == NULL || s < ep) {
+ c = *s++;
+ if (c == '\0') {
+ ret = 0;
+ break;
+ }
+ if (!isascii(c)) {
+ c = toascii(c);
+ putchar('M');
+ putchar('-');
+ }
+ if (!isprint(c)) {
+ c ^= 0x40; /* DEL to ?, others to alpha */
+ putchar('^');
+ }
+ putchar(c);
+ }
+ putchar('"');
+ return(ret);
+}
+
+/*
+ * Print out a counted filename (or other ascii string).
+ * If ep is NULL, assume no truncation check is needed.
+ * Return true if truncated.
+ */
+int
+fn_printn(register const u_char *s, register u_int n,
+ register const u_char *ep)
+{
+ register int ret;
+ register u_char c;
+
+ ret = 1; /* assume truncated */
+ putchar('"');
+ while (ep == NULL || s < ep) {
+ if (n-- <= 0) {
+ ret = 0;
+ break;
+ }
+ c = *s++;
+ if (!isascii(c)) {
+ c = toascii(c);
+ putchar('M');
+ putchar('-');
+ }
+ if (!isprint(c)) {
+ c ^= 0x40; /* DEL to ?, others to alpha */
+ putchar('^');
+ }
+ putchar(c);
+ }
+ putchar('"');
+ return(ret);
+}
+
+/*
+ * Print the timestamp
+ */
+void
+ts_print(register const struct timeval *tvp)
+{
+ register int s;
+ extern int32 thiszone;
+
+ if (tflag > 0) {
+ /* Default */
+ s = (tvp->tv_sec + thiszone) % 86400;
+ (void)printf("%02d:%02d:%02d.%06d ",
+ s / 3600, (s % 3600) / 60, s % 60, tvp->tv_usec);
+ } else if (tflag < 0) {
+ /* Unix timeval style */
+ (void)printf("%d.%06d ", tvp->tv_sec, tvp->tv_usec);
+ }
+}
+
+/*
+ * Convert a token value to a string; use "fmt" if not found.
+ */
+const char *
+tok2str(register const struct token *lp, register const char *fmt,
+ register int v)
+{
+ static char buf[128];
+
+ while (lp->s != NULL) {
+ if (lp->v == v)
+ return (lp->s);
+ ++lp;
+ }
+ if (fmt == NULL)
+ fmt = "#%d";
+ (void)sprintf(buf, fmt, v);
+ return (buf);
+}
+
+/* A replacement for strdup() that cuts down on malloc() overhead */
+char *
+savestr(register const char *str)
+{
+ register u_int size;
+ register char *p;
+ static char *strptr = NULL;
+ static u_int strsize = 0;
+
+ size = strlen(str) + 1;
+ if (size > strsize) {
+ strsize = 1024;
+ if (strsize < size)
+ strsize = size;
+ strptr = malloc(strsize);
+ if (strptr == NULL)
+ error("savestr: malloc");
+ }
+ (void)strcpy(strptr, str);
+ p = strptr;
+ strptr += size;
+ strsize -= size;
+ return (p);
+}
+
+#ifdef NOVFPRINTF
+/*
+ * Stock 4.3 doesn't have vfprintf.
+ * This routine is due to Chris Torek.
+ */
+vfprintf(f, fmt, args)
+ FILE *f;
+ char *fmt;
+ va_list args;
+{
+ int ret;
+
+ if ((f->_flag & _IOWRT) == 0) {
+ if (f->_flag & _IORW)
+ f->_flag |= _IOWRT;
+ else
+ return EOF;
+ }
+ ret = _doprnt(fmt, args, f);
+ return ferror(f) ? EOF : ret;
+}
+#endif
+
+/* VARARGS */
+__dead void
+#if __STDC__ || defined(SOLARIS)
+error(char *fmt, ...)
+#else
+error(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+
+ (void)fprintf(stderr, "%s: ", program_name);
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ if (*fmt) {
+ fmt += strlen(fmt);
+ if (fmt[-1] != '\n')
+ (void)fputc('\n', stderr);
+ }
+ exit(1);
+ /* NOTREACHED */
+}
+
+/* VARARGS */
+void
+#if __STDC__ || defined(SOLARIS)
+warning(char *fmt, ...)
+#else
+warning(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+
+ (void)fprintf(stderr, "%s: warning: ", program_name);
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ if (*fmt) {
+ fmt += strlen(fmt);
+ if (fmt[-1] != '\n')
+ (void)fputc('\n', stderr);
+ }
+}
+
+/*
+ * Copy arg vector into a new buffer, concatenating arguments with spaces.
+ */
+char *
+copy_argv(register char **argv)
+{
+ register char **p;
+ register int len = 0;
+ char *buf;
+ char *src, *dst;
+
+ p = argv;
+ if (*p == 0)
+ return 0;
+
+ while (*p)
+ len += strlen(*p++) + 1;
+
+ buf = malloc(len);
+
+ p = argv;
+ dst = buf;
+ while ((src = *p++) != NULL) {
+ while ((*dst++ = *src++) != '\0')
+ ;
+ dst[-1] = ' ';
+ }
+ dst[-1] = '\0';
+
+ return buf;
+}
+
+char *
+read_infile(char *fname)
+{
+ struct stat buf;
+ int fd;
+ char *p;
+
+ fd = open(fname, O_RDONLY);
+ if (fd < 0)
+ error("can't open '%s'", fname);
+
+ if (fstat(fd, &buf) < 0)
+ error("can't state '%s'", fname);
+
+ p = malloc((u_int)buf.st_size);
+ if (read(fd, p, (int)buf.st_size) != buf.st_size)
+ error("problem reading '%s'", fname);
+
+ return p;
+}
+
+int
+gmt2local()
+{
+#ifndef SOLARIS
+ struct timeval now;
+ struct timezone tz;
+ long t;
+
+ if (gettimeofday(&now, &tz) < 0)
+ error("gettimeofday");
+ t = tz.tz_minuteswest * -60;
+ if (localtime((time_t *)&now.tv_sec)->tm_isdst)
+ t += 3600;
+ return (t);
+#else
+ tzset();
+ return (-altzone);
+#endif
+}
diff --git a/usr.sbin/tcpdump/version.c b/usr.sbin/tcpdump/version.c
new file mode 100644
index 00000000000..33cc7ff833a
--- /dev/null
+++ b/usr.sbin/tcpdump/version.c
@@ -0,0 +1,3 @@
+/* $NetBSD: version.c,v 1.2 1995/03/06 19:11:56 mycroft Exp $ */
+
+char version[] = "3.0";