diff options
author | olah <olah@FreeBSD.org> | 1995-03-08 12:53:42 +0000 |
---|---|---|
committer | olah <olah@FreeBSD.org> | 1995-03-08 12:53:42 +0000 |
commit | 48fc7bedf7186fa650bf61612b46dacd1522a4a2 (patch) | |
tree | 40baaef0054aa886e0bb8efd90c3b1689af336ff /usr.sbin/tcpdump | |
parent | 98f80a48617e9bb96ab3c38cccdb647282371f06 (diff) | |
download | FreeBSD-src-48fc7bedf7186fa650bf61612b46dacd1522a4a2.zip FreeBSD-src-48fc7bedf7186fa650bf61612b46dacd1522a4a2.tar.gz |
Upgrade tcpdump and tcpslice to version 3.0
Obtained from: ftp.ee.lbl.gov and Vern Paxson <vern@ee.lbl.gov>
Diffstat (limited to 'usr.sbin/tcpdump')
58 files changed, 6956 insertions, 2253 deletions
diff --git a/usr.sbin/tcpdump/tcpdump/Makefile b/usr.sbin/tcpdump/tcpdump/Makefile index d276179..806f23e 100644 --- a/usr.sbin/tcpdump/tcpdump/Makefile +++ b/usr.sbin/tcpdump/tcpdump/Makefile @@ -1,26 +1,22 @@ # @(#)Makefile 0.1 (RWGrimes) 3/24/93 PROG= tcpdump -CFLAGS+=-DCSLIP -DPPP -I. -I${.CURDIR}/../../mrouted +CFLAGS+=-DCSLIP -DPPP -DFDDI MAN1= tcpdump.1 -SRCS= version.c addrtoname.c bpf_dump.c bpf_filter.c bpf_image.c etherent.c \ - gencode.c inet.c md.c nametoaddr.c optimize.c os.c pcap.c \ - print-arp.c print-atalk.c print-bootp.c print-domain.c \ +SRCS= version.c addrtoname.c bpf_dump.c parsenfsfh.c \ + print-arp.c print-atalk.c print-bootp.c print-decnet.c print-domain.c \ print-egp.c print-ether.c print-fddi.c print-icmp.c print-ip.c \ + print-ipx.c print-isoclns.c print-llc.c \ print-nfs.c print-ntp.c print-null.c print-ospf.c print-ppp.c \ print-rip.c print-sl.c print-snmp.c print-sunrpc.c print-tcp.c \ - print-tftp.c print-udp.c savefile.c tcpdump.c tcpgram.c \ - tcplex.c util.c -.PATH: ${.CURDIR}/../../../sys/net -CLEANFILES+= tcpgram.c tcplex.c y.tab.h y.tab.c version.c version.h -DPADD+= ${LIBL} -LDADD+= -ll + print-tftp.c print-udp.c print-wb.c tcpdump.c \ + util.c +CLEANFILES+= version.c +DPADD+= ${LIBL} ${LIBPCAP} +LDADD+= -ll -lpcap -version.c version.h: VERSION +version.c: VERSION rm -f version.c ; \ sed 's/.*/char version[] = "&";/' $(.CURDIR)/VERSION > version.c - set `sed 's/\([0-9]*\)\.\([0-9]*\).*/\1 \2/' $(.CURDIR)/VERSION` ; \ - { echo '#define VERSION_MAJOR' $$1 ; \ - echo '#define VERSION_MINOR' $$2 ; } > version.h .include <bsd.prog.mk> diff --git a/usr.sbin/tcpdump/tcpdump/VERSION b/usr.sbin/tcpdump/tcpdump/VERSION index c043eea..9f55b2c 100644 --- a/usr.sbin/tcpdump/tcpdump/VERSION +++ b/usr.sbin/tcpdump/tcpdump/VERSION @@ -1 +1 @@ -2.2.1 +3.0 diff --git a/usr.sbin/tcpdump/tcpdump/addrtoname.c b/usr.sbin/tcpdump/tcpdump/addrtoname.c index 5c70865..11a1098 100644 --- a/usr.sbin/tcpdump/tcpdump/addrtoname.c +++ b/usr.sbin/tcpdump/tcpdump/addrtoname.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988, 1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -23,25 +23,41 @@ */ #ifndef lint static char rcsid[] = - "@(#) $Header: addrtoname.c,v 1.14 92/05/25 14:29:07 mccanne Exp $ (LBL)"; + "@(#) $Header: addrtoname.c,v 1.37 94/06/16 00:42:28 mccanne Exp $ (LBL)"; #endif -#include <stdio.h> -#include <strings.h> -#include <ctype.h> #include <sys/types.h> #include <sys/socket.h> +#include <sys/time.h> + #include <net/if.h> -#include <netdb.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 "nametoaddr.h" -#include "etherent.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 @@ -50,7 +66,7 @@ static char rcsid[] = #define HASHNAMESIZE 4096 struct hnamemem { - u_long addr; + u_int32 addr; char *name; struct hnamemem *nxt; }; @@ -59,24 +75,35 @@ 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(addr) - u_long addr; +intoa(u_int32 addr) { register char *cp; register u_int byte; @@ -105,9 +132,9 @@ intoa(addr) return cp + 1; } -static u_long f_netmask; -static u_long f_localnet; -static u_long netmask; +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 @@ -117,8 +144,8 @@ static u_long netmask; jmp_buf getname_env; -static void -nohostname() +static SIGRET +nohostname(int signo) { longjmp(getname_env, 1); } @@ -128,16 +155,15 @@ nohostname() * is assumed to be in network byte order. */ char * -getname(ap) - u_char *ap; +getname(const u_char *ap) { - register struct hnamemem *p; register struct hostent *hp; register char *cp; - u_long addr; + u_int32 addr; + static struct hnamemem *p; /* static for longjmp() */ #ifndef TCPDUMP_ALIGN - addr = *(u_long *)ap; + addr = *(const u_int32 *)ap; #else /* * Deal with alignment. @@ -145,35 +171,35 @@ getname(ap) switch ((int)ap & 3) { case 0: - addr = *(u_long *)ap; + addr = *(u_int32 *)ap; break; case 2: #if BYTE_ORDER == LITTLE_ENDIAN - addr = ((u_long)*(u_short *)(ap + 2) << 16) | - (u_long)*(u_short *)ap; + addr = ((u_int32)*(u_short *)(ap + 2) << 16) | + (u_int32)*(u_short *)ap; #else - addr = ((u_long)*(u_short *)ap << 16) | - (u_long)*(u_short *)(ap + 2); + addr = ((u_int32)*(u_short *)ap << 16) | + (u_int32)*(u_short *)(ap + 2); #endif break; default: #if BYTE_ORDER == LITTLE_ENDIAN - addr = ((u_long)ap[0] << 24) | - ((u_long)ap[1] << 16) | - ((u_long)ap[2] << 8) | - (u_long)ap[3]; + addr = ((u_int32)ap[0] << 24) | + ((u_int32)ap[1] << 16) | + ((u_int32)ap[2] << 8) | + (u_int32)ap[3]; #else - addr = ((u_long)ap[3] << 24) | - ((u_long)ap[2] << 16) | - ((u_long)ap[1] << 8) | - (u_long)ap[0]; + 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)]; + p = &hnametable[addr & (HASHNAMESIZE-1)]; for (; p->nxt; p = p->nxt) { if (p->addr == addr) return (p->name); @@ -183,8 +209,8 @@ getname(ap) /* * Only print names when: - * (1) -n was not given. - * (2) Address is foreign and -f was given. If -f was not + * (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). @@ -198,14 +224,12 @@ getname(ap) hp = gethostbyaddr((char *)&addr, 4, AF_INET); (void)alarm(0); if (hp) { - char *index(); - char *dotp; - u_int len = strlen(hp->h_name) + 1; - p->name = (char *)malloc(len); - (void)strcpy(p->name, hp->h_name); + char *dotp; + + p->name = savestr(hp->h_name); if (Nflag) { /* Remove domain qualifications */ - dotp = index(p->name, '.'); + dotp = strchr(p->name, '.'); if (dotp) *dotp = 0; } @@ -214,8 +238,7 @@ getname(ap) } } cp = intoa(addr); - p->name = (char *)malloc((unsigned)(strlen(cp) + 1)); - (void)strcpy(p->name, cp); + p->name = savestr(cp); return (p->name); } @@ -225,8 +248,7 @@ static char hex[] = "0123456789abcdef"; /* Find the hash node that corresponds the ether address 'ep'. */ static inline struct enamemem * -lookup_emem(ep) - u_char *ep; +lookup_emem(const u_char *ep) { register u_int i, j, k; struct enamemem *tp; @@ -251,9 +273,73 @@ lookup_emem(ep) 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(ep) - register u_char *ep; +etheraddr_string(register const u_char *ep) { register u_int i, j; register char *cp; @@ -261,25 +347,24 @@ etheraddr_string(ep) tp = lookup_emem(ep); if (tp->e_name) - return tp->e_name; - + return (tp->e_name); #ifdef ETHER_SERVICE if (!nflag) { - cp = ETHER_ntohost(ep); - if (cp) { - tp->e_name = cp; - return cp; + char buf[128]; + if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) { + tp->e_name = savestr(buf); + return (buf); } } -#endif +#endif tp->e_name = cp = (char *)malloc(sizeof("00:00:00:00:00:00")); - if (j = *ep >> 4) + if ((j = *ep >> 4) != 0) *cp++ = hex[j]; *cp++ = hex[*ep++ & 0xf]; for (i = 5; (int)--i >= 0;) { *cp++ = ':'; - if (j = *ep >> 4) + if ((j = *ep >> 4) != 0) *cp++ = hex[j]; *cp++ = hex[*ep++ & 0xf]; } @@ -288,8 +373,7 @@ etheraddr_string(ep) } char * -etherproto_string(port) - u_short port; +etherproto_string(u_short port) { register char *cp; register struct hnamemem *tp; @@ -313,11 +397,82 @@ etherproto_string(port) } char * -tcpport_string(port) - u_short port; +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 int i = port; + register u_long i = port; for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) if (tp->addr == i) @@ -332,11 +487,10 @@ tcpport_string(port) } char * -udpport_string(port) - register u_short port; +udpport_string(register u_short port) { register struct hnamemem *tp; - register int i = port; + register u_long i = port; for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) if (tp->addr == i) @@ -352,15 +506,15 @@ udpport_string(port) } static void -init_servarray() +init_servarray(void) { struct servent *sv; register struct hnamemem *table; register int i; - while (sv = getservent()) { - NTOHS(sv->s_port); - i = sv->s_port & (HASHNAMESIZE-1); + 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) @@ -373,45 +527,24 @@ init_servarray() if (nflag) { char buf[32]; - (void)sprintf(buf, "%d", sv->s_port); - table->name = (char *)malloc((unsigned)strlen(buf)+1); - (void)strcpy(table->name, buf); - } else { - table->name = - (char *)malloc((unsigned)strlen(sv->s_name)+1); - (void)strcpy(table->name, sv->s_name); - } - table->addr = sv->s_port; + (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(); } -#include "etherproto.h" - -/* Static data base of ether protocol types. */ -struct eproto eproto_db[] = { - { "pup", ETHERTYPE_PUP }, - { "xns", ETHERTYPE_NS }, - { "ip", ETHERTYPE_IP }, - { "arp", ETHERTYPE_ARP }, - { "rarp", ETHERTYPE_REVARP }, - { "sprite", ETHERTYPE_SPRITE }, - { "mopdl", ETHERTYPE_MOPDL }, - { "moprc", ETHERTYPE_MOPRC }, - { "decnet", ETHERTYPE_DN }, - { "lat", ETHERTYPE_LAT }, - { "lanbridge", ETHERTYPE_LANBRIDGE }, - { "vexp", ETHERTYPE_VEXP }, - { "vprod", ETHERTYPE_VPROD }, - { "atalk", ETHERTYPE_ATALK }, - { "atalkarp", ETHERTYPE_AARP }, - { "loopback", ETHERTYPE_LOOPBACK }, - { (char *)0, 0 } -}; +/*XXX from libbpfc.a */ +extern struct eproto { + char *s; + u_short p; +} eproto_db[]; static void -init_eprotoarray() +init_eprotoarray(void) { register int i; register struct hnamemem *table; @@ -427,26 +560,118 @@ init_eprotoarray() } } +/* + * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet + * types. + */ static void -init_etherarray() +init_protoidarray(void) { -#ifndef ETHER_SERVICE - FILE *fp; - struct etherent *ep; - struct enamemem *tp; + register int i; + register struct protoidmem *tp; + u_char protoid[5]; - fp = fopen(ETHERS_FILE, "r"); - if (fp == 0) - /* No data base; will have to settle for - numeric addresses. */ - return; + 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); + } +} - while (ep = next_etherent(fp)) { - tp = lookup_emem(ep->addr); - tp->e_name = (char *)malloc((unsigned)strlen(ep->name)+1); - strcpy(tp->e_name, ep->name); +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)); + } } /* @@ -456,10 +681,7 @@ init_etherarray() * of the local network. mask is its subnet mask. */ void -init_addrtoname(fflag, localnet, mask) - int fflag; - u_long localnet; - u_long mask; +init_addrtoname(int fflag, u_int32 localnet, u_int32 mask) { netmask = mask; if (fflag) { @@ -475,4 +697,26 @@ init_addrtoname(fflag, localnet, mask) 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/tcpdump/addrtoname.h b/usr.sbin/tcpdump/tcpdump/addrtoname.h index 6dc6979..f52825b 100644 --- a/usr.sbin/tcpdump/tcpdump/addrtoname.h +++ b/usr.sbin/tcpdump/tcpdump/addrtoname.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988, 1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -18,19 +18,18 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: addrtoname.h,v 1.5 92/03/17 13:41:37 mccanne Exp $ (LBL) + * @(#) $Header: addrtoname.h,v 1.11 94/06/14 20:11:41 leres Exp $ (LBL) */ /* Name to address translation routines. */ -extern char *etheraddr_string(); -extern char *etherproto_string(); -extern char *tcpport_string(); -extern char *udpport_string(); -extern char *getname(); -extern char *intoa(); +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(); -extern void no_foreign_names(); +extern void init_addrtoname(int, u_int32, u_int32); -#define ipaddr_string(p) getname((u_char *)(p)) +#define ipaddr_string(p) getname((const u_char *)(p)) diff --git a/usr.sbin/tcpdump/tcpdump/appletalk.h b/usr.sbin/tcpdump/tcpdump/appletalk.h index 90c8c80..6a21f1d 100644 --- a/usr.sbin/tcpdump/tcpdump/appletalk.h +++ b/usr.sbin/tcpdump/tcpdump/appletalk.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988 The Regents of the University of California. - * All rights reserved. + * 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 @@ -20,9 +20,18 @@ * * AppleTalk protocol formats (courtesy Bill Croft of Stanford/SUMEX). * - * @(#) $Header: appletalk.h,v 1.6 90/10/03 22:14:26 leres Exp $ (LBL) + * @(#) $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 { @@ -67,7 +76,7 @@ struct atATP { u_char control; u_char bitmap; u_short transID; - long userData; + int32 userData; }; #define atpReqCode 0x40 @@ -117,7 +126,9 @@ struct atNBPtuple { #define nbpTupleMax 15 #define nbpHeaderSize 2 -#define nbpTupleSize 5; +#define nbpTupleSize 5 + +#define nbpSkt 2 /* NIS */ /* Routing Table Maint. Protocol */ diff --git a/usr.sbin/tcpdump/tcpdump/bootp.h b/usr.sbin/tcpdump/tcpdump/bootp.h index ab474cf..19844ca 100644 --- a/usr.sbin/tcpdump/tcpdump/bootp.h +++ b/usr.sbin/tcpdump/tcpdump/bootp.h @@ -1,4 +1,4 @@ -/* @(#) $Header: bootp.h,v 1.2 90/05/29 21:29:16 leres Exp $ (LBL) */ +/* @(#) $Header: bootp.h,v 1.6 94/01/13 19:06:29 leres Exp $ (LBL) */ /* * Bootstrap Protocol (BOOTP). RFC951 and RFC1048. * @@ -25,7 +25,7 @@ struct bootp { unsigned char bp_htype; /* hardware addr type */ unsigned char bp_hlen; /* hardware addr length */ unsigned char bp_hops; /* gateway hops */ - unsigned long bp_xid; /* transaction ID */ + 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 */ @@ -80,6 +80,12 @@ struct bootp { #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) @@ -89,13 +95,13 @@ struct bootp { struct cmu_vend { unsigned char v_magic[4]; /* magic number */ - unsigned long v_flags; /* flags/opcodes, etc. */ - struct in_addr v_smask; /* Subnet mask */ - struct in_addr v_dgate; /* Default gateway */ + 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[25]; /* currently unused */ + unsigned char v_unused[24]; /* currently unused */ }; diff --git a/usr.sbin/tcpdump/tcpdump/bpf_dump.c b/usr.sbin/tcpdump/tcpdump/bpf_dump.c index fab9596..547041a 100644 --- a/usr.sbin/tcpdump/tcpdump/bpf_dump.c +++ b/usr.sbin/tcpdump/tcpdump/bpf_dump.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -20,17 +20,21 @@ */ #ifndef lint static char rcsid[] = - "@(#) $Header: bpf_dump.c,v 1.1 92/01/29 13:25:30 mccanne Exp $ (LBL)"; + "@(#) $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 <net/bpf.h> + +#include <pcap.h> +#include <stdio.h> + +#include "interface.h" + +extern void bpf_dump(struct bpf_program *, int); void -bpf_dump(p, option) - struct bpf_program *p; - int option; +bpf_dump(struct bpf_program *p, int option) { struct bpf_insn *insn; int i; @@ -47,7 +51,7 @@ bpf_dump(p, option) } if (option > 1) { for (i = 0; i < n; ++insn, ++i) - printf("{ 0x%x, %d, %d, 0x%08x },\n", + printf("{ 0x%x, %d, %d, 0x%08x },\n", insn->code, insn->jt, insn->jf, insn->k); return; } diff --git a/usr.sbin/tcpdump/tcpdump/decnet.h b/usr.sbin/tcpdump/tcpdump/decnet.h new file mode 100644 index 0000000..83e7e0e --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/decnet.h @@ -0,0 +1,480 @@ +/* + * 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/tcpdump/ethertype.h b/usr.sbin/tcpdump/tcpdump/ethertype.h new file mode 100644 index 0000000..6fa6e40 --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/ethertype.h @@ -0,0 +1,70 @@ +/* + * 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/tcpdump/extract.h b/usr.sbin/tcpdump/tcpdump/extract.h index bd45c59..4e10275 100644 --- a/usr.sbin/tcpdump/tcpdump/extract.h +++ b/usr.sbin/tcpdump/tcpdump/extract.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: extract.h,v 1.4 92/05/25 14:28:36 mccanne Exp $ (LBL) + * @(#) $Header: extract.h,v 1.7 94/06/14 20:11:45 leres Exp $ (LBL) */ #ifdef TCPDUMP_ALIGN @@ -28,22 +28,22 @@ ((u_short)*((u_char *)p+1)<<8|\ (u_short)*((u_char *)p+0)<<0)) #define EXTRACT_LONG(p)\ - ((u_long)*((u_char *)p+3)<<24|\ - (u_long)*((u_char *)p+2)<<16|\ - (u_long)*((u_char *)p+1)<<8|\ - (u_long)*((u_char *)p+0)<<0) + ((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_long)*((u_char *)p+0)<<24|\ - (u_long)*((u_char *)p+1)<<16|\ - (u_long)*((u_char *)p+2)<<8|\ - (u_long)*((u_char *)p+3)<<0) + ((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_long *)p)) +#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p)) #endif diff --git a/usr.sbin/tcpdump/tcpdump/fddi.h b/usr.sbin/tcpdump/tcpdump/fddi.h new file mode 100644 index 0000000..a6c2711 --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/fddi.h @@ -0,0 +1,76 @@ +/* + * 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/tcpdump/interface.h b/usr.sbin/tcpdump/tcpdump/interface.h index 1ff89ff..146ca6a 100644 --- a/usr.sbin/tcpdump/tcpdump/interface.h +++ b/usr.sbin/tcpdump/tcpdump/interface.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -18,25 +18,31 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /a/cvs/386BSD/src/contrib/tcpdump/tcpdump/interface.h,v 1.1.1.1 1993/06/12 14:42:12 rgrimes Exp $ (LBL) + * @(#) $Header: interface.h,v 1.66 94/06/14 20:21:37 leres Exp $ (LBL) */ #ifdef __GNUC__ -#ifndef inline #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 __STDC__ -extern char *malloc(); -extern char *calloc(); +#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 */ @@ -51,55 +57,86 @@ 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 unsigned char *packetp; -extern unsigned char *snapend; +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; -extern long thiszone; /* gmt to local correction */ +typedef void (*printfunc)(u_char *, struct timeval *, int, int); -extern void ts_print(); -extern int clock_sigfigs(); +extern void ts_print(const struct timeval *); +extern int clock_sigfigs(void); +int gmt2local(void); -extern char *lookup_device(); +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 void error(); -extern void warning(); +extern int initdevice(char *, int, int *); +extern void wrapup(int); -extern char *read_infile(); -extern char *copy_argv(); +extern __dead void error(char *, ...); +extern void warning(char *, ...); -extern void usage(); -extern void show_code(); -extern void init_addrtoname(); +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. */ -extern void ether_if_print(); -extern void arp_print(); -extern void ip_print(); -extern void tcp_print(); -extern void udp_print(); -extern void icmp_print(); -extern void default_print(); - -extern void ntp_print(); -extern void nfsreq_print(); -extern void nfsreply_print(); -extern void ns_print(); -extern void ddp_print(); -extern void rip_print(); -extern void tftp_print(); -extern void bootp_print(); -extern void snmp_print(); -extern void sl_if_print(); -extern void ppp_if_print(); -extern void fddi_if_print(); -extern void null_if_print(); -extern void egp_print(); +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 diff --git a/usr.sbin/tcpdump/tcpdump/ipx.h b/usr.sbin/tcpdump/tcpdump/ipx.h new file mode 100644 index 0000000..0a70724 --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/ipx.h @@ -0,0 +1,29 @@ +/* + * 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/tcpdump/llc.h b/usr.sbin/tcpdump/tcpdump/llc.h new file mode 100644 index 0000000..89c10d5 --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/llc.h @@ -0,0 +1,120 @@ +/* + * 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/tcpdump/md.h b/usr.sbin/tcpdump/tcpdump/md.h index f83d81f..9df5e9b 100644 --- a/usr.sbin/tcpdump/tcpdump/md.h +++ b/usr.sbin/tcpdump/tcpdump/md.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -18,23 +18,16 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: md-vax.h,v 1.2 90/09/21 02:23:16 mccanne Exp $ (LBL) + * @(#) $Header: md-i386.h,v 1.5 94/06/14 20:14:40 leres Exp $ (LBL) */ -#ifndef BYTE_ORDER -#define BYTE_ORDER LITTLE_ENDIAN -#endif +#define TCPDUMP_ALIGN -/* These should be fixed to be real macros, for speed */ +#include <machine/endian.h> -#ifndef NTOHL -#define NTOHL(x) (x) = ntohl(x) -#define NTOHS(x) (x) = ntohs(x) -#define HTONL(x) (x) = htonl(x) -#define HTONS(x) (x) = htons(x) +/* 32-bit data types */ +/* N.B.: this doesn't address printf()'s %d vs. %ld formats */ +typedef long int32; /* signed 32-bit integer */ +#ifndef AUTH_UNIX +typedef u_long u_int32; /* unsigned 32-bit integer */ #endif - -#ifndef vax -/* Some Ultrix header files may need this */ -#define vax 1 -#endif vax diff --git a/usr.sbin/tcpdump/tcpdump/mib.h b/usr.sbin/tcpdump/tcpdump/mib.h index a81897c..48ead9b 100644 --- a/usr.sbin/tcpdump/tcpdump/mib.h +++ b/usr.sbin/tcpdump/tcpdump/mib.h @@ -2,7 +2,7 @@ * 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 + * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer }; */ diff --git a/usr.sbin/tcpdump/tcpdump/nfsfh.h b/usr.sbin/tcpdump/tcpdump/nfsfh.h new file mode 100644 index 0000000..36296c3 --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/nfsfh.h @@ -0,0 +1,34 @@ +/* + * $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/tcpdump/nfsv2.h b/usr.sbin/tcpdump/tcpdump/nfsv2.h new file mode 100644 index 0000000..ff55d31 --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/nfsv2.h @@ -0,0 +1,260 @@ +/* + * 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/tcpdump/ntp.h b/usr.sbin/tcpdump/tcpdump/ntp.h index 493686d..2a626fd 100644 --- a/usr.sbin/tcpdump/tcpdump/ntp.h +++ b/usr.sbin/tcpdump/tcpdump/ntp.h @@ -1,4 +1,4 @@ -/* $Header: ntp.h,v 1.1 90/08/07 11:08:27 mogul 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 @@ -28,8 +28,8 @@ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct l_fixedpt { - u_long int_part; - u_long fraction; + u_int32 int_part; + u_int32 fraction; }; struct s_fixedpt { @@ -74,7 +74,7 @@ struct ntpdata { int precision:8; struct s_fixedpt distance; struct s_fixedpt dispersion; - u_long refid; + u_int32 refid; struct l_fixedpt reftime; struct l_fixedpt org; struct l_fixedpt rec; diff --git a/usr.sbin/tcpdump/tcpdump/os.h b/usr.sbin/tcpdump/tcpdump/os.h index e0d01cf..1bd9d5c 100644 --- a/usr.sbin/tcpdump/tcpdump/os.h +++ b/usr.sbin/tcpdump/tcpdump/os.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: os-bsd.h,v 1.15 91/05/05 23:59:11 mccanne Exp $ (LBL) + * @(#) $Header: os-bsd.h,v 1.18 94/06/14 20:15:17 leres Exp $ (LBL) */ #include <sys/param.h> @@ -58,28 +58,3 @@ #ifndef RIPCMD_POLLENTRY #define RIPCMD_POLLENTRY 6 #endif - -/* - * Map BSD names to SunOS names. - */ -#if BSD >= 199006 -#define RFS_NULL NFSPROC_NULL -#define RFS_GETATTR NFSPROC_GETATTR -#define RFS_SETATTR NFSPROC_SETATTR -#define RFS_ROOT NFSPROC_ROOT -#define RFS_LOOKUP NFSPROC_LOOKUP -#define RFS_READLINK NFSPROC_READLINK -#define RFS_READ NFSPROC_READ -#define RFS_WRITECACHE NFSPROC_WRITECACHE -#define RFS_WRITE NFSPROC_WRITE -#define RFS_CREATE NFSPROC_CREATE -#define RFS_REMOVE NFSPROC_REMOVE -#define RFS_RENAME NFSPROC_RENAME -#define RFS_LINK NFSPROC_LINK -#define RFS_SYMLINK NFSPROC_SYMLINK -#define RFS_MKDIR NFSPROC_MKDIR -#define RFS_RMDIR NFSPROC_RMDIR -#define RFS_READDIR NFSPROC_READDIR -#define RFS_STATFS NFSPROC_STATFS -#define RFS_NPROC NFSPROC_NPROC -#endif diff --git a/usr.sbin/tcpdump/tcpdump/ospf.h b/usr.sbin/tcpdump/tcpdump/ospf.h index e3a3a6d..252c399 100644 --- a/usr.sbin/tcpdump/tcpdump/ospf.h +++ b/usr.sbin/tcpdump/tcpdump/ospf.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 1991 The Regents of the University of California. - * All rights reserved. + * 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 @@ -38,7 +38,7 @@ #define OSPF_AUTH_SIMPLE 1 /* Simple password */ /* db_flags */ -#define OSPF_DB_INIT 0x04 /* */ +#define OSPF_DB_INIT 0x04 /* */ #define OSPF_DB_MORE 0x02 #define OSPF_DB_MASTER 0x01 @@ -57,7 +57,7 @@ * is the above a bug in the documentation? * *************************************************/ - + /* rla_link.link_type */ #define RLA_TYPE_ROUTER 1 /* point-to-point to another router */ @@ -93,7 +93,7 @@ struct lsa_hdr { u_char ls_type; struct in_addr ls_stateid; struct in_addr ls_router; - u_long ls_seq; + u_int32 ls_seq; u_short ls_chksum; u_short ls_length; } ; @@ -127,14 +127,14 @@ struct lsa { /* Summary links advertisements */ struct { struct in_addr sla_mask; - u_long sla_tosmetric[1]; /* may repeat */ + u_int32 sla_tosmetric[1]; /* may repeat */ } un_sla; /* AS external links advertisements */ struct { struct in_addr asla_mask; struct aslametric { - u_long asla_tosmetric; + u_int32 asla_tosmetric; struct in_addr asla_forward; struct in_addr asla_tag; } asla_metric[1]; /* may repeat */ @@ -142,7 +142,7 @@ struct lsa { /* Multicast group membership */ struct mcla { - u_long mcla_vtype; + u_int32 mcla_vtype; struct in_addr mcla_vid; } un_mcla[1]; } lsa_un; @@ -180,7 +180,7 @@ struct ospfhdr { u_short hello_helloint; u_char hello_options; u_char hello_priority; - u_long hello_deadint; + u_int32 hello_deadint; struct in_addr hello_dr; struct in_addr hello_bdr; struct in_addr hello_neighbor[1]; /* may repeat */ @@ -191,20 +191,20 @@ struct ospfhdr { u_char db_zero[2]; u_char db_options; u_char db_flags; - u_long db_seq; + u_int32 db_seq; struct lsa_hdr db_lshdr[1]; /* may repeat */ } un_db; /* Link State Request */ struct lsr { - u_long ls_type; + u_int32 ls_type; struct in_addr ls_stateid; struct in_addr ls_router; } un_lsr[1]; /* may repeat */ /* Link State Update */ struct { - u_long lsu_count; + u_int32 lsu_count; struct lsa lsu_lsa[1]; /* may repeat */ } un_lsu; diff --git a/usr.sbin/tcpdump/tcpdump/parsenfsfh.c b/usr.sbin/tcpdump/tcpdump/parsenfsfh.c new file mode 100644 index 0000000..4acb82b --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/parsenfsfh.c @@ -0,0 +1,425 @@ +#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/tcpdump/print-arp.c b/usr.sbin/tcpdump/tcpdump/print-arp.c index 3f0671a..92fce66 100644 --- a/usr.sbin/tcpdump/tcpdump/print-arp.c +++ b/usr.sbin/tcpdump/tcpdump/print-arp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,63 +21,82 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: print-arp.c,v 1.16 91/04/19 10:45:56 mccanne Exp $ (LBL)"; + "@(#) $Header: print-arp.c,v 1.28 94/06/14 20:17:36 leres Exp $ (LBL)"; #endif #include <sys/param.h> -#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" +static u_char ezero[6]; + void -arp_print(ap, length, caplen) - register struct ether_arp *ap; - int length; - int caplen; +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_short *)ap, length); + 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]; - NTOHS(ap->arp_hrd); - NTOHS(ap->arp_pro); - NTOHS(ap->arp_op); - - if (ap->arp_hrd != ARPHRD_ETHER - || (ap->arp_pro != ETHERTYPE_IP - && ap->arp_pro != ETHERTYPE_TRAIL) + if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || ap->arp_hln != sizeof(SHA(ap)) || ap->arp_pln != sizeof(SPA(ap))) { - (void)printf("arp-req #%d for proto #%d (%d) hardware %d (%d)", - ap->arp_op, ap->arp_pro, ap->arp_pln, - ap->arp_hrd, ap->arp_hln); + (void)printf("arp-#%d for proto #%d (%d) hardware #%d (%d)", + op, pro, ap->arp_pln, + hrd, ap->arp_hln); return; } - if (ap->arp_pro == ETHERTYPE_TRAIL) - (void)printf("trailer"); - switch (ap->arp_op) { + if (pro == ETHERTYPE_TRAIL) + (void)printf("trailer-"); + eh = (struct ether_header *)packetp; + switch (op) { case ARPOP_REQUEST: - (void)printf("arp who-has %s tell %s", - ipaddr_string(TPA(ap)), - ipaddr_string(SPA(ap))); + (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 is-at %s", - ipaddr_string(SPA(ap)), - etheraddr_string(SHA(ap))); + (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: @@ -93,8 +112,10 @@ arp_print(ap, length, caplen) break; default: - (void)printf("arp-%d", ap->arp_op); - default_print((u_short *)ap, caplen); - break; + (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/tcpdump/print-atalk.c b/usr.sbin/tcpdump/tcpdump/print-atalk.c index 203585e..a6dceea 100644 --- a/usr.sbin/tcpdump/tcpdump/print-atalk.c +++ b/usr.sbin/tcpdump/tcpdump/print-atalk.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -22,111 +22,197 @@ */ #ifndef lint static char rcsid[] = - "@(#)$Header: print-atalk.c,v 1.22 92/03/26 14:15:34 mccanne Exp $ (LBL)"; + "@(#)$Header: print-atalk.c,v 1.36 94/06/20 19:44:34 leres Exp $ (LBL)"; #endif -#ifdef __STDC__ -#include <stdlib.h> -#endif -#include <stdio.h> - #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" -#include <strings.h> -#include "extract.h" -static char *ataddr_string(); -static struct atNBPtuple *nbp_tuple_print(); -static struct atNBPtuple *nbp_name_print(); -static void atp_print(); -static void nbp_print(); -static void atp_bitmap_print(); +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 -ddp_print(dp, length) - register struct atDDP *dp; - int length; +atalk_print(register const u_char *bp, int length) { - if (length < ddpSize) { - (void)printf(" truncated-ddp %d", length); - return; - } - (void)printf("%s.%d > %s.%d:", - ataddr_string(EXTRACT_SHORT(&dp->srcNet), dp->srcNode), - dp->srcSkt, - ataddr_string(EXTRACT_SHORT(&dp->dstNet), dp->dstNode), - dp->dstSkt); - - /* 'type' is the last field of 'dp' so we need the whole thing. - If we cannot determine the type, bail out. (This last byte - happens to be *one* byte past the end of tcpdump's minimum - snapshot length.) */ - if ((u_char *)(dp + 1) > snapend) { - printf(" [|atalk]"); - return; - } + 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; - length -= ddpSize; - switch (dp->type) { + 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; - case ddpRTMP: - (void)printf(" at-rtmp %d", length); +#ifdef notdef + case lapKLAP: + klap_print(bp, length); break; - case ddpRTMPrequest: - (void)printf(" at-rtmpReq %d", length); +#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((struct atNBP *)((u_char *)dp + ddpSize), - length, dp); + nbp_print((const struct atNBP *)bp, length, snet, snode, skt); break; + case ddpATP: - atp_print((struct atATP *)((u_char *)dp + ddpSize), length); - break; - case ddpECHO: - (void)printf(" at-echo %d", length); - break; - case ddpIP: - (void)printf(" at-IP %d", length); - break; - case ddpARP: - (void)printf(" at-ARP %d", length); - break; - case ddpKLAP: - (void)printf(" at-KLAP %d", length); + atp_print((const struct atATP *)bp, length); break; + default: - (void)printf(" at-#%d %d", length); + (void)printf(" at-%s %d", tok2str(type2str, NULL, t), length); break; } } static void -atp_print(ap, length) - register struct atATP *ap; - int length; +atp_print(register const struct atATP *ap, int length) { char c; - long data; + u_int32 data; - if ((u_char *)(ap + 1) > snapend) { + if ((const u_char *)(ap + 1) > snapend) { /* Just bail if we don't have the whole chunk. */ - printf(" [|atalk]"); + fputs(tstr, stdout); return; } length -= sizeof(*ap); @@ -201,7 +287,7 @@ atp_print(ap, length) break; default: - (void)printf(" atp-0x%x %d (%d)", ap->control, + (void)printf(" atp-0x%x %d (%d)", ap->control, EXTRACT_SHORT(&ap->transID), length); break; } @@ -211,13 +297,12 @@ atp_print(ap, length) } static void -atp_bitmap_print(bm) - register u_char bm; +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). @@ -243,15 +328,13 @@ atp_bitmap_print(bm) } static void -nbp_print(np, length, dp) - register struct atNBP *np; - int length; - register struct atDDP *dp; +nbp_print(register const struct atNBP *np, int length, register u_short snet, + register u_char snode, register u_char skt) { - register struct atNBPtuple *tp = + register const struct atNBPtuple *tp = (struct atNBPtuple *)((u_char *)np + nbpHeaderSize); int i = length; - u_char *ep; + const u_char *ep; length -= nbpHeaderSize; if (length < 8) { @@ -261,8 +344,8 @@ nbp_print(np, length, dp) } /* ep points to end of available data */ ep = snapend; - if ((u_char *)tp > ep) { - printf(" [|atalk]"); + if ((const u_char *)tp > ep) { + fputs(tstr, stdout); return; } switch (i = np->control & 0xf0) { @@ -271,8 +354,8 @@ nbp_print(np, length, dp) case nbpLkUp: (void)printf(i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:", np->id); - if ((u_char *)(tp + 1) > ep) { - printf(" [|atalk]"); + if ((const u_char *)(tp + 1) > ep) { + fputs(tstr, stdout); return; } (void)nbp_name_print(tp, ep); @@ -285,12 +368,11 @@ nbp_print(np, length, dp) (void)printf(" [ntup=%d]", np->control & 0xf); if (tp->enumerator) (void)printf(" [enum=%d]", tp->enumerator); - if (EXTRACT_SHORT(&tp->net) != EXTRACT_SHORT(&dp->srcNet) || - tp->node != dp->srcNode || tp->skt != dp->srcSkt) + 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); + ataddr_string(EXTRACT_SHORT(&tp->net), + tp->node), tp->skt); break; case nbpLkUpReply: @@ -298,7 +380,7 @@ nbp_print(np, length, dp) /* print each of the tuples in the reply */ for (i = np->control & 0xf; --i >= 0 && tp; ) - tp = nbp_tuple_print(tp, ep, dp); + tp = nbp_tuple_print(tp, ep, snet, snode, skt); break; default: @@ -309,15 +391,13 @@ nbp_print(np, length, dp) } /* print a counted string */ -static char * -print_cstring(cp, ep) - register char *cp; - register u_char *ep; +static const char * +print_cstring(register const char *cp, register const u_char *ep) { register int length; - if (cp >= (char *)ep) { - (void)printf("[|atalk]"); + if (cp >= (const char *)ep) { + fputs(tstr, stdout); return (0); } length = *cp++; @@ -329,7 +409,7 @@ print_cstring(cp, ep) } while (--length >= 0) { if (cp >= (char *)ep) { - (void)printf("[|atalk]"); + fputs(tstr, stdout); return (0); } putchar(*cp++); @@ -337,16 +417,16 @@ print_cstring(cp, ep) return (cp); } -static struct atNBPtuple * -nbp_tuple_print(tp, ep, dp) - register struct atNBPtuple *tp; - register u_char *ep; - register struct atDDP *dp; +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 struct atNBPtuple *tpn; + register const struct atNBPtuple *tpn; - if ((u_char *)(tp + 1) > ep) { - printf(" [|atalk]"); + if ((const u_char *)(tp + 1) > ep) { + fputs(tstr, stdout); return 0; } tpn = nbp_name_print(tp, ep); @@ -356,40 +436,37 @@ nbp_tuple_print(tp, ep, dp) (void)printf("(%d)", tp->enumerator); /* if the socket doesn't match the src socket, print it */ - if (tp->skt != dp->srcSkt) + 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) != EXTRACT_SHORT(&dp->srcNet) || - tp->node != dp->srcNode) + if (EXTRACT_SHORT(&tp->net) != snet || tp->node != snode) (void)printf(" [addr=%s]", - ataddr_string(EXTRACT_SHORT(&tp->net), tp->node)); + ataddr_string(EXTRACT_SHORT(&tp->net), tp->node)); return (tpn); } -static struct atNBPtuple * -nbp_name_print(tp, ep) - struct atNBPtuple *tp; - register u_char *ep; +static const struct atNBPtuple * +nbp_name_print(const struct atNBPtuple *tp, register const u_char *ep) { - register char *cp = (char *)tp + nbpTupleSize; + register const char *cp = (const char *)tp + nbpTupleSize; putchar(' '); /* Object */ putchar('"'); - if (cp = print_cstring(cp, ep)) { + if ((cp = print_cstring(cp, ep)) != NULL) { /* Type */ putchar(':'); - if (cp = print_cstring(cp, ep)) { + if ((cp = print_cstring(cp, ep)) != NULL) { /* Zone */ putchar('@'); - if (cp = print_cstring(cp, ep)) + if ((cp = print_cstring(cp, ep)) != NULL) putchar('"'); } } - return ((struct atNBPtuple *)cp); + return ((const struct atNBPtuple *)cp); } @@ -403,10 +480,8 @@ struct hnamemem { static struct hnamemem hnametable[HASHNAMESIZE]; -static char * -ataddr_string(atnet, athost) - u_short atnet; - u_char athost; +static const char * +ataddr_string(u_short atnet, u_char athost) { register struct hnamemem *tp, *tp2; register int i = (atnet << 8) | athost; @@ -442,8 +517,7 @@ ataddr_string(atnet, athost) ; tp->addr = i3; tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp)); - i3 = strlen(nambuf) + 1; - tp->name = strcpy(malloc((unsigned) i3), nambuf); + tp->name = savestr(nambuf); } fclose(fp); } @@ -459,8 +533,7 @@ ataddr_string(atnet, athost) tp->addr = (atnet << 8) | athost; tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp)); (void)sprintf(nambuf, "%s.%d", tp2->name, athost); - i = strlen(nambuf) + 1; - tp->name = strcpy(malloc((unsigned) i), nambuf); + tp->name = savestr(nambuf); return (tp->name); } @@ -472,7 +545,27 @@ ataddr_string(atnet, athost) else (void)sprintf(nambuf, "%d.%d", atnet >> 8, atnet & 0xff); i = strlen(nambuf) + 1; - tp->name = strcpy(malloc((unsigned) i), nambuf); + 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/tcpdump/print-bootp.c b/usr.sbin/tcpdump/tcpdump/print-bootp.c index 0641d82..9e3f8ca 100644 --- a/usr.sbin/tcpdump/tcpdump/print-bootp.c +++ b/usr.sbin/tcpdump/tcpdump/print-bootp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -22,50 +22,50 @@ */ #ifndef lint static char rcsid[] = - "@(#) $Header: print-bootp.c,v 1.17 91/11/14 22:21:34 leres Exp $ (LBL)"; + "@(#) $Header: print-bootp.c,v 1.30 94/06/14 20:17:37 leres Exp $ (LBL)"; #endif -#include <stdio.h> - #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 <strings.h> + #include <ctype.h> +#include <stdio.h> #include "interface.h" #include "addrtoname.h" #include "bootp.h" -void rfc1048_print(); -void cmu_print(); +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(bp, length, sport, dport) - register struct bootp *bp; - int length; - u_short sport, dport; +bootp_print(register const u_char *cp, int length, + u_short sport, u_short dport) { - static char tstr[] = " [|bootp]"; - static unsigned char vm_cmu[4] = VM_CMU; - static unsigned char vm_rfc1048[4] = VM_RFC1048; - u_char *ep; + 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 - /* Note funny sized packets */ - if (length != sizeof(struct bootp)) - (void)printf(" [len=%d]", length); - + bp = (struct bootp *)cp; /* 'ep' points to the end of avaible data. */ - ep = (u_char *)snapend; + ep = snapend; + TCHECK(bp->bp_op, sizeof(bp->bp_op)); switch (bp->bp_op) { case BOOTREQUEST: @@ -84,8 +84,7 @@ bootp_print(bp, length, sport, dport) printf(" bootp-#%d", bp->bp_op); } - NTOHL(bp->bp_xid); - NTOHS(bp->bp_secs); + TCHECK(bp->bp_secs, sizeof(bp->bp_secs)); /* The usual hardware address type is 1 (10Mb Ethernet) */ if (bp->bp_htype != 1) @@ -99,9 +98,9 @@ bootp_print(bp, length, sport, dport) if (bp->bp_hops) printf(" hops:%d", bp->bp_hops); if (bp->bp_xid) - printf(" xid:0x%x", bp->bp_xid); + printf(" xid:0x%x", ntohl(bp->bp_xid)); if (bp->bp_secs) - printf(" secs:%d", bp->bp_secs); + printf(" secs:%d", ntohs(bp->bp_secs)); /* Client's ip address */ TCHECK(bp->bp_ciaddr, sizeof(bp->bp_ciaddr)); @@ -125,53 +124,53 @@ bootp_print(bp, length, sport, dport) /* Client's Ethernet address */ if (bp->bp_htype == 1 && bp->bp_hlen == 6) { - register struct ether_header *eh; - register char *e; + 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 = (char *)ESRC(eh); + e = (const char *)ESRC(eh); else if (bp->bp_op == BOOTREPLY) - e = (char *)EDST(eh); + 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], sizeof(bp->bp_sname)); + TCHECK(bp->bp_sname[0], 1); /* check first char only */ if (*bp->bp_sname) { printf(" sname "); - if (printfn(bp->bp_sname, ep)) { + if (fn_print(bp->bp_sname, ep)) { fputs(tstr + 1, stdout); return; } } - TCHECK(bp->bp_file[0], sizeof(bp->bp_file)); + TCHECK(bp->bp_sname[0], 1); /* check first char only */ if (*bp->bp_file) { printf(" file "); - if (printfn(bp->bp_file, ep)) { + if (fn_print(bp->bp_file, ep)) { fputs(tstr + 1, stdout); return; } } - /* Don't try to decode the vendor buffer unless we're verbose */ - if (vflag <= 0) - return; - + /* Decode the vendor buffer */ TCHECK(bp->bp_vend[0], sizeof(bp->bp_vend)); - printf(" vend"); - if (bcmp(bp->bp_vend, vm_rfc1048, sizeof(u_long)) == 0) - rfc1048_print(bp->bp_vend, sizeof(bp->bp_vend)); - else if (bcmp(bp->bp_vend, vm_cmu, sizeof(u_long)) == 0) - cmu_print(bp->bp_vend, 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_long ul; + u_int32 ul; bcopy((char *)bp->bp_vend, (char *)&ul, sizeof(ul)); - printf("-#0x%x", ul); + if (ul != 0) + printf("vend-#0x%x", ul); } return; @@ -180,84 +179,179 @@ trunc: #undef TCHECK } -void -rfc1048_print(bp, length) - register u_char *bp; - int length; +/* 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) { - u_char tag; - u_char *ep; - register int i; - u_long ul; + 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("-rfc1048"); - - /* Step over magic cookie */ - bp += sizeof(long); + printf(" vend-rfc1048"); /* Setup end pointer */ ep = bp + length; - while (bp < ep) { - tag = *bp++; - i = *bp++; - switch (tag) { + /* Step over magic cookie */ + bp += sizeof(int32); - case TAG_PAD: - /* no-op */ - break; + /* 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); - case TAG_SUBNET_MASK: - ul = 0; - bcopy((char *)bp, (char *)&ul, i); - printf(" SM:%s", ipaddr_string(&ul)); - break; + /* Get the length; check for truncation */ + if (bp + 1 >= ep) { + fputs(tstr, stdout); + return; + } + len = *bp++; + if (bp + len >= ep) { + fputs(tstr, stdout); + return; + } - case TAG_TIME_SERVER: - ul = 0; - bcopy((char *)bp, (char *)&ul, i); - printf(" TS:%s", ipaddr_string(&ul)); + /* 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 TAG_GATEWAY: - ul = 0; - bcopy((char *)bp, (char *)&ul, i); - printf(" G:%s", ipaddr_string(&ul)); + 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 TAG_TIME_OFFSET: - case TAG_NAME_SERVER: - case TAG_DOMAIN_SERVER: - case TAG_LOG_SERVER: - case TAG_COOKIE_SERVER: - case TAG_LPR_SERVER: - case TAG_IMPRESS_SERVER: - case TAG_RLP_SERVER: - case TAG_HOSTNAME: - case TAG_BOOTSIZE: - printf(" tag-#%d", tag); - if (i == sizeof(long)) { - bcopy((char *)bp, (char *)&ul, sizeof(long)); - printf(":0x%x", ul); - } else - printf(":?"); + 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 TAG_END: - return; - + case 'b': default: - printf("[tag-#%d]", tag); - return; + /* Bytes */ + while (size > 0) { + if (!first) + putchar('.'); + printf("%d", *bp); + ++bp; + --size; + first = 0; + } + break; } + /* Data left over? */ + if (size) + printf("[len %d]", len); } } -void -cmu_print(bp, length) - register u_char *bp; - int length; +static void +cmu_print(register const u_char *bp, register int length) { - /* XXX not really implemented */ - printf("-cmu [...]"); + 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/tcpdump/print-decnet.c b/usr.sbin/tcpdump/tcpdump/print-decnet.c new file mode 100644 index 0000000..91794d8 --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/print-decnet.c @@ -0,0 +1,763 @@ +/* + * 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/tcpdump/print-domain.c b/usr.sbin/tcpdump/tcpdump/print-domain.c index 04cf5aa..2ed1edf 100644 --- a/usr.sbin/tcpdump/tcpdump/print-domain.c +++ b/usr.sbin/tcpdump/tcpdump/print-domain.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,13 +21,16 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: print-domain.c,v 1.16 92/05/25 14:28:59 mccanne Exp $ (LBL)"; + "@(#) $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> @@ -37,8 +40,12 @@ static char rcsid[] = #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" @@ -55,11 +62,9 @@ static char *ns_resp[] = { " Resp12", " Resp13", " Resp14", " NoChange", }; - /* skip over a domain name */ -static u_char * -ns_nskip(cp) - register u_char *cp; +static const u_char * +ns_nskip(register const u_char *cp) { register u_char i; @@ -74,15 +79,13 @@ ns_nskip(cp) /* print a domain name */ static void -ns_nprint(cp, bp, ep) - register u_char *cp; - register u_char *bp; - register u_char *ep; +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++) + if ((i = *cp++) != 0) while (i && cp < ep) { if ((i & 0xc0) == 0xc0) { cp = bp + (((i << 8) | *cp) & 0x3fff); @@ -99,15 +102,41 @@ ns_nprint(cp, bp, ep) 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(cp, bp, ep) - register u_char *cp; - register u_char *bp; - register u_char *ep; +ns_qprint(register const u_char *cp, register const u_char *bp, + register const u_char *ep) { - u_char *np = cp; + const u_char *np = cp; register u_int i; cp = ns_nskip(cp); @@ -117,34 +146,8 @@ ns_qprint(cp, bp, ep) /* print the qtype and qclass (if it's not IN) */ i = *cp++ << 8; - switch (i |= *cp++) { - case T_A: printf(" A"); break; - case T_NS: printf(" NS"); break; - case T_MD: printf(" MD"); break; - case T_MF: printf(" MF"); break; - case T_CNAME: printf(" CNAME"); break; - case T_SOA: printf(" SOA"); break; - case T_MB: printf(" MB"); break; - case T_MG: printf(" MG"); break; - case T_MR: printf(" MR"); break; - case T_NULL: printf(" NULL"); break; - case T_WKS: printf(" WKS"); break; - case T_PTR: printf(" PTR"); break; - case T_HINFO: printf(" HINFO"); break; - case T_MINFO: printf(" MINFO"); break; - case T_MX: printf(" MX"); break; - case T_UINFO: printf(" UINFO"); break; - case T_UID: printf(" UID"); break; - case T_GID: printf(" GID"); break; -#ifdef T_UNSPEC - case T_UNSPEC: printf(" UNSPEC"); break; -#endif - case T_AXFR: printf(" AXFR"); break; - case T_MAILB: printf(" MAILB"); break; - case T_MAILA: printf(" MAILA"); break; - case T_ANY: printf(" ANY"); break; - default: printf(" Type%d", i); break; - } + i |= *cp++; + printf(" %s", tok2str(type2str, "Type%d", i)); i = *cp++ << 8; if ((i |= *cp++) != C_IN) if (i == C_ANY) @@ -159,10 +162,8 @@ ns_qprint(cp, bp, ep) /* print a reply */ static void -ns_rprint(cp, bp, ep) - register u_char *cp; - register u_char *bp; - register u_char *ep; +ns_rprint(register const u_char *cp, register const u_char *bp, + register const u_char *ep) { register u_int i; u_short typ; @@ -184,104 +185,92 @@ ns_rprint(cp, bp, ep) /* ignore ttl & len */ cp += 6; + printf(" %s", tok2str(type2str, "Type%d", typ)); switch (typ) { - case T_A: printf(" A %s", ipaddr_string(cp)); break; - case T_NS: printf(" NS"); ns_nprint(cp, bp, ep); break; - case T_MD: printf(" MD"); break; - case T_MF: printf(" MF"); break; - case T_CNAME: printf(" CNAME"); ns_nprint(cp, bp, ep); break; - case T_SOA: printf(" SOA"); break; - case T_MB: printf(" MB"); break; - case T_MG: printf(" MG"); break; - case T_MR: printf(" MR"); break; - case T_NULL: printf(" NULL"); break; - case T_WKS: printf(" WKS"); break; - case T_PTR: printf(" PTR"); ns_nprint(cp, bp, ep); break; - case T_HINFO: printf(" HINFO"); break; - case T_MINFO: printf(" MINFO"); break; - case T_MX: printf(" MX"); ns_nprint(cp+2, bp, ep); + + 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); + printf(" %d", *(short *)cp); #else - { - u_short x = *cp | cp[1] << 8; - printf(" %d", ntohs(x)); - } -#endif - break; - case T_UINFO: printf(" UINFO"); break; - case T_UID: printf(" UID"); break; - case T_GID: printf(" GID"); break; -#ifdef T_UNSPEC - case T_UNSPEC: printf(" UNSPEC"); break; + { + u_short x = *cp | cp[1] << 8; + printf(" %d", ntohs(x)); + } #endif - case T_AXFR: printf(" AXFR"); break; - case T_MAILB: printf(" MAILB"); break; - case T_MAILA: printf(" MAILA"); break; - case T_ANY: printf(" ANY"); break; - default: printf(" Type%d", typ); break; + break; } } void -ns_print(np, length) - register HEADER *np; - int length; +ns_print(register const u_char *bp, int length) { - u_char *ep = (u_char *)snapend; + register const HEADER *np; + int qdcount, ancount, nscount, arcount; + const u_char *ep = snapend; + np = (const HEADER *)bp; /* get the byte-order right */ - NTOHS(np->id); - NTOHS(np->qdcount); - NTOHS(np->ancount); - NTOHS(np->nscount); - NTOHS(np->arcount); + 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", - np->id, + ntohs(np->id), ns_ops[np->opcode], ns_resp[np->rcode], np->aa? "*" : "", np->ra? "" : "-", np->tc? "|" : ""); - if (np->qdcount != 1) - printf(" [%dq]", np->qdcount); - printf(" %d/%d/%d", np->ancount, np->nscount, np->arcount); - if (np->ancount) - ns_rprint(ns_nskip((u_char *)(np + 1)) + 4, - (u_char *)np, ep); + 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", - np->id, + 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 (*(((u_short *)np)+1) & htons(0x6ff)) + printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1))); if (np->opcode == IQUERY) { - if (np->qdcount) - printf(" [%dq]", np->qdcount); - if (np->ancount != 1) - printf(" [%da]", np->ancount); + if (qdcount) + printf(" [%dq]", qdcount); + if (ancount != 1) + printf(" [%da]", ancount); } else { - if (np->ancount) - printf(" [%da]", np->ancount); - if (np->qdcount != 1) - printf(" [%dq]", np->qdcount); + if (ancount) + printf(" [%da]", ancount); + if (qdcount != 1) + printf(" [%dq]", qdcount); } - if (np->nscount) - printf(" [%dn]", np->nscount); - if (np->arcount) - printf(" [%dau]", np->arcount); + if (nscount) + printf(" [%dn]", nscount); + if (arcount) + printf(" [%dau]", arcount); - ns_qprint((u_char *)(np + 1), (u_char *)np, ep); + ns_qprint((const u_char *)(np + 1), (const u_char *)np, ep); } printf(" (%d)", length); } diff --git a/usr.sbin/tcpdump/tcpdump/print-egp.c b/usr.sbin/tcpdump/tcpdump/print-egp.c index a88a683..876118d 100644 --- a/usr.sbin/tcpdump/tcpdump/print-egp.c +++ b/usr.sbin/tcpdump/tcpdump/print-egp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1991 Regents of the University of California. - * All rights reserved. + * 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 @@ -17,14 +17,23 @@ * * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU). */ -#include <stdio.h> + +#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" @@ -80,7 +89,7 @@ struct egp_packet { #define egp_reason egp_handg.egpu_reason union { u_short egpu_poll; - u_long egpu_sourcenet; + u_int32 egpu_sourcenet; } egp_pands; #define egp_poll egp_pands.egpu_poll #define egp_sourcenet egp_pands.egpu_sourcenet @@ -127,14 +136,12 @@ char *egp_reasons[] = { }; static void -egpnrprint(egp, length) - register struct egp_packet *egp; - register int length; +egpnrprint(register const struct egp_packet *egp, register int length) { - register u_char *cp, *ep; + register const u_char *cp, *ep; #define TCHECK(n) if (cp > ep - n) goto trunc - register u_long addr; - register u_long net; + register u_int32 addr; + register u_int32 net; register int netlen; int gateways, distances, networks; int t_gateways; @@ -177,9 +184,9 @@ egpnrprint(egp, length) TCHECK(1); distances = *cp++; printf(" %s %s ", - gateways < egp->egp_intgw ? "int" : "ext", + gateways < egp->egp_intgw ? "int" : "ext", intoa(addr)); - + comma = ""; putchar('('); while (--distances >= 0) { @@ -190,14 +197,14 @@ egpnrprint(egp, length) while (--networks >= 0) { /* Pickup network number */ TCHECK(1); - addr = (u_long)*cp++ << 24; + addr = (u_int32)*cp++ << 24; if (IN_CLASSB(addr)) { TCHECK(1); - addr |= (u_long)*cp++ << 16; + addr |= (u_int32)*cp++ << 16; } else if (!IN_CLASSA(addr)) { TCHECK(2); - addr |= (u_long)*cp++ << 16; - addr |= (u_long)*cp++ << 8; + addr |= (u_int32)*cp++ << 16; + addr |= (u_int32)*cp++ << 8; } printf(" %s", intoa(addr)); } @@ -210,15 +217,17 @@ trunc: } void -egp_print(egp, length, ip) - register struct egp_packet *egp; - register int length; - register struct ip *ip; +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)); @@ -228,7 +237,7 @@ egp_print(egp, length, ip) 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; @@ -246,7 +255,7 @@ egp_print(egp, length, ip) case EGPS_PASSIVE: printf(" %s", egp_acquire_status[status]); break; - + default: printf(" [status %d]", status); break; @@ -255,7 +264,7 @@ egp_print(egp, length, ip) ntohs(egp->egp_hello), ntohs(egp->egp_poll)); break; - + case EGPC_REFUSE: case EGPC_CEASE: case EGPC_CEASEACK: @@ -269,19 +278,19 @@ egp_print(egp, length, ip) case EGPS_PROTO: printf(" %s", egp_acquire_status[status]); break; - + default: - printf("[status %d], status"); + printf("[status %d]", status); break; } break; - + default: printf("[code %d]", code); break; } break; - + case EGPT_REACH: switch (code) { @@ -291,15 +300,15 @@ egp_print(egp, length, ip) if (status <= EGPS_DOWN) printf(" state:%s", egp_status_updown[status]); else - printf(" [status %d], status"); + printf(" [status %d]", status); break; - + default: - printf("[reach code %d], code"); + printf("[reach code %d]", code); break; } break; - + case EGPT_POLL: printf(" poll"); if (egp->egp_status <= EGPS_DOWN) @@ -308,12 +317,12 @@ egp_print(egp, length, ip) 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(" unsolicitied"); + printf(" unsolicited"); } if (status <= EGPS_DOWN) printf(" state:%s", egp_status_updown[status]); @@ -326,20 +335,20 @@ egp_print(egp, length, ip) 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]", status); + printf(" [status %d]", status); if (ntohs(egp->egp_reason) <= EGPR_UVERSION) printf(" %s", egp_reasons[ntohs(egp->egp_reason)]); else - printf(" [reason]", ntohs(egp->egp_reason)); + printf(" [reason %d]", ntohs(egp->egp_reason)); break; - + default: printf("[type %d]", type); break; diff --git a/usr.sbin/tcpdump/tcpdump/print-ether.c b/usr.sbin/tcpdump/tcpdump/print-ether.c index 563a506..713fc09 100644 --- a/usr.sbin/tcpdump/tcpdump/print-ether.c +++ b/usr.sbin/tcpdump/tcpdump/print-ether.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -20,14 +20,16 @@ */ #ifndef lint static char rcsid[] = - "@(#) $Header: /home/ncvs/src/usr.sbin/tcpdump/tcpdump/print-ether.c,v 1.1.1.1 1993/06/12 14:42:09 rgrimes Exp $ (LBL)"; + "@(#) $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 <net/if_llc.h> + #include <netinet/in.h> #include <netinet/if_ether.h> #include <netinet/in_systm.h> @@ -38,18 +40,22 @@ static char rcsid[] = #include <netinet/tcp.h> #include <netinet/tcpip.h> +#include <stdio.h> +#include <pcap.h> + #include "interface.h" #include "addrtoname.h" -#include "appletalk.h" +#include "ethertype.h" -u_char *packetp; -u_char *snapend; +const u_char *packetp; +const u_char *snapend; static inline void -ether_print(ep, length) - register struct ether_header *ep; - int length; +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)), @@ -59,144 +65,26 @@ ether_print(ep, length) (void)printf("%s %s %s %d: ", etheraddr_string(ESRC(ep)), etheraddr_string(EDST(ep)), - etherproto_string(ep->ether_type), + etherproto_string(ep->ether_type), length); } -static inline void -eight02_print(ep, lp, length) - register struct ether_header *ep; - struct llc *lp; - int length; -{ - if(eflag || length < LLC_UFRAMELEN) { - (void)printf("%s %s %d: ", - etheraddr_string(ESRC(ep)), - etheraddr_string(EDST(ep)), - length); - } - - if(length < LLC_UFRAMELEN) { - printf("[|llc]"); - return; - } - - if(eflag && lp->llc_dsap != LLC_SNAP_LSAP) { - switch(lp->llc_control) { - case LLC_UI: printf("ui "); break; - case LLC_UI_P: printf("ui-p "); break; - case LLC_DISC: printf("disc "); break; - case LLC_DISC_P: printf("disc-p "); break; - case LLC_UA: printf("ua "); break; - case LLC_UA_P: printf("ua-p "); break; - case LLC_TEST: printf("test "); break; - case LLC_TEST_P: printf("test-p "); break; - case LLC_FRMR: printf("frmr "); break; - case LLC_FRMR_P: printf("frmr-p "); break; - case LLC_DM: printf("dm "); break; - case LLC_DM_P: printf("dm-p "); break; - case LLC_XID: printf("xid "); break; - case LLC_XID_P: printf("xid-p "); break; - case LLC_SABME: printf("sabme "); break; - case LLC_SABME_P: printf("sabme-p "); break; - case LLC_RR: printf("rr "); break; - case LLC_RNR: printf("rnr "); break; - case LLC_REJ: printf("rej "); break; - case LLC_INFO: printf("info "); break; - - default: - printf("[control %d] ", lp->llc_control); - break; - } - } - switch(lp->llc_dsap) { - case LLC_SNAP_LSAP: - if(length < 6) { - printf(" [|snap]"); - return; - } - -#define llc_snap_oui llc_un.type_snap.org_code -#define llc_snap_type llc_un.type_snap.ether_type - if(lp->llc_snap_oui[0] == 0x08 - && lp->llc_snap_oui[1] == 0x00 - && lp->llc_snap_oui[2] == 0x07) { - printf("[ethertalk] "); - ddp_print((struct atDDP *)((char *)lp + 6), - length - 6); - } else { - if(!eflag) { - (void)printf("%s %s %d: ", - etheraddr_string(ESRC(ep)), - etheraddr_string(EDST(ep)), - length); - } - printf("snap %02x-%02x-%02x type %04x ", - lp->llc_snap_oui[0], lp->llc_snap_oui[1], - lp->llc_snap_oui[2], lp->llc_snap_type); - } - break; - - default: - if(!eflag) { - (void)printf("%s %s %d: ", - etheraddr_string(ESRC(ep)), - etheraddr_string(EDST(ep)), - length); - switch(lp->llc_control) { - case LLC_UI: printf("ui "); break; - case LLC_UI_P: printf("ui-p "); break; - case LLC_DISC: printf("disc "); break; - case LLC_DISC_P: printf("disc-p "); break; - case LLC_UA: printf("ua "); break; - case LLC_UA_P: printf("ua-p "); break; - case LLC_TEST: printf("test "); break; - case LLC_TEST_P: printf("test-p "); break; - case LLC_FRMR: printf("frmr "); break; - case LLC_FRMR_P: printf("frmr-p "); break; - case LLC_DM: printf("dm "); break; - case LLC_DM_P: printf("dm-p "); break; - case LLC_XID: printf("xid "); break; - case LLC_XID_P: printf("xid-p "); break; - case LLC_SABME: printf("sabme "); break; - case LLC_SABME_P: printf("sabme-p "); break; - case LLC_RR: printf("rr "); break; - case LLC_RNR: printf("rnr "); break; - case LLC_REJ: printf("rej "); break; - case LLC_INFO: printf("info "); break; - - default: - printf("[control %d] ", lp->llc_control); - break; - } - } - - printf("[dsap %d] [ssap %d] ", - lp->llc_dsap, lp->llc_ssap); - break; - } - - if (xflag) - default_print((u_short *)lp, 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, + * 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(p, tvp, length, caplen) - u_char *p; - struct timeval *tvp; - int length; - int caplen; +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; - register int i; + u_short ether_type; + extern u_short extracted_ethertype; - ts_print(tvp); + ts_print(&h->ts); if (caplen < sizeof(struct ether_header)) { printf("[|ether]"); @@ -204,7 +92,7 @@ ether_if_print(p, tvp, length, caplen) } if (eflag) - ether_print((struct ether_header *)p, length); + ether_print(p, length); /* * Some printers want to get back at the ethernet addresses, @@ -213,36 +101,92 @@ ether_if_print(p, tvp, length, caplen) */ 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); - switch (ntohs(ep->ether_type)) { - - case ETHERTYPE_IP: - ip_print((struct ip *)p, length); - break; - case ETHERTYPE_ARP: - case ETHERTYPE_REVARP: - arp_print((struct ether_arp *)p, length, caplen - sizeof(*ep)); - break; + ether_type = ntohs(ep->ether_type); - default: - if (ntohs(ep->ether_type) < 1500) { - eight02_print(ep, (struct llc *)p, - caplen - sizeof(*ep)); - goto out; + /* + * 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(ep, length); - + ether_print((u_char *)ep, length + sizeof(*ep)); if (!xflag && !qflag) - default_print((u_short *)p, caplen - sizeof(*ep)); - break; + default_print(p, caplen); } if (xflag) - default_print((u_short *)p, caplen - sizeof(*ep)); + 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/tcpdump/print-fddi.c b/usr.sbin/tcpdump/tcpdump/print-fddi.c index 7783112..8052825 100644 --- a/usr.sbin/tcpdump/tcpdump/print-fddi.c +++ b/usr.sbin/tcpdump/tcpdump/print-fddi.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,36 +21,52 @@ #ifndef lint static char rcsid[] = - "@(#)$Header: print-fddi.c,v 1.4 92/02/03 16:04:02 van Exp $ (LBL)"; + "@(#)$Header: print-fddi.c,v 1.21 94/06/10 17:01:29 mccanne Exp $ (LBL)"; #endif #ifdef FDDI -#include <stdio.h> -#include <netdb.h> -#include <ctype.h> -#include <signal.h> -#include <errno.h> #include <sys/param.h> -#include <sys/types.h> #include <sys/time.h> -#include <sys/timeb.h> #include <sys/socket.h> #include <sys/file.h> -#include <sys/mbuf.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 <net/bpf.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. @@ -76,8 +92,7 @@ static char rcsid[] = * - vj */ -/* XXX This goes somewhere else. */ -#define FDDI_HDRLEN 21 +#define FDDI_HDRLEN (sizeof(struct fddi_header)) static u_char fddi_bit_swap[] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, @@ -114,121 +129,221 @@ static u_char fddi_bit_swap[] = { 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, }; +/* + * Print FDDI frame-control bits + */ static inline void -fddi_print(p, length) - u_char *p; - int length; +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) { - u_char fsrc[6], fdst[6]; - register char *srcname, *dstname; register int i; - /* - * bit-swap the fddi addresses (isn't the IEEE standards - * process wonderful!) then convert them to names. - */ - - for (i = 0; i < sizeof(fdst); ++i) - fdst[i] = fddi_bit_swap[p[i+1]]; - for (i = 0; i < sizeof(fsrc); ++i) - fsrc[i] = fddi_bit_swap[p[i+7]]; - dstname = etheraddr_string(fdst); + 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) - printf("%s %s %02x %02x %02x %02x %02x%02x%02x %s %d: ", - dstname, srcname, - p[0], - p[13], p[14], p[15], - p[16], p[17], p[18], - etherproto_string((p[19] << 8) | p[20]), + (void) printf("%02x %s %s %d: ", + fddip->fddi_fc, + srcname, dstname, length); else if (qflag) - printf("%s %s %d: ", dstname, srcname, length); - else - printf("%s %s %02x %s %d: ", - dstname, srcname, - p[0], - etherproto_string((p[19] << 8) | p[20]), - length); + 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(p, tvp, length, caplen) - u_char *p; - struct timeval *tvp; - int length; - int caplen; +fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, + register const u_char *p) { - struct ip *ip; - u_short type; + 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(tvp); + 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. */ - packetp = (u_char *)p; - snapend = (u_char *)p + caplen; - + snapend = p + caplen; /* - * If the frame is not an LLC frame or is not an LLC/UI frame - * or doesn't have SNAP as a dest NSAP, use the default printer. - * (XXX - should interpret SMT packets here.) + * 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 */ - if ((p[0] & 0xf8) != 0x50) - /* not LLC frame -- use default printer */ - type = 0; - else if ((p[15] &~ 0x10) != 0x03) - /* not UI frame -- use default printer */ - type = 0; - else if (p[13] != 170) - /* DSAP not SNAP -- use default printer */ - type = 0; - else - type = (p[19] << 8) | p[20]; + packetp = (u_char *)&ehdr; + if (eflag) - fddi_print(p, length); + fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); + /* Skip over FDDI MAC header */ length -= FDDI_HDRLEN; p += FDDI_HDRLEN; + caplen -= FDDI_HDRLEN; - switch (ntohs(type)) { - - case ETHERTYPE_IP: - ip_print((struct ip *)p, length); - break; - - case ETHERTYPE_ARP: - case ETHERTYPE_REVARP: - arp_print((struct ether_arp *)p, length, caplen - FDDI_HDRLEN); - break; - - default: + /* 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(p, length); + fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); if (!xflag && !qflag) - default_print((u_short *)p, caplen - FDDI_HDRLEN); - break; + default_print(p, caplen); } if (xflag) - default_print((u_short *)p, caplen - sizeof(FDDI_HDRLEN)); + 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() +fddi_if_print(u_char *pcap, struct pcap_pkthdr *h, register u_char *p) { - void error(); error("not configured for fddi"); /* NOTREACHED */ diff --git a/usr.sbin/tcpdump/tcpdump/print-icmp.c b/usr.sbin/tcpdump/tcpdump/print-icmp.c index 928d866..ccd3156 100644 --- a/usr.sbin/tcpdump/tcpdump/print-icmp.c +++ b/usr.sbin/tcpdump/tcpdump/print-icmp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,51 +21,55 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: print-icmp.c,v 1.11 91/03/27 17:42:58 leres Exp $ (LBL)"; + "@(#) $Header: print-icmp.c,v 1.20 94/06/14 20:17:39 leres Exp $ (LBL)"; #endif -#include <stdio.h> - #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 <netinet/ip_icmp.h> +#include <stdio.h> #include "interface.h" #include "addrtoname.h" void -icmp_print(dp, ip) - register struct icmp *dp; - register struct ip *ip; +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]; - register char *str = buf; - register struct ip *oip; - register struct udphdr *ouh; - register int hlen; - u_char *ep; #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 = (u_char *)snapend; + ep = snapend; (void)printf("%s > %s: ", ipaddr_string(&ip->ip_src), ipaddr_string(&ip->ip_dst)); - strcpy(str, "[?]"); TCHECK(dp->icmp_code, sizeof(dp->icmp_code)); switch (dp->icmp_type) { @@ -94,25 +98,25 @@ icmp_print(dp, ip) oip = &dp->icmp_ip; hlen = oip->ip_hl * 4; ouh = (struct udphdr *)(((u_char *)oip) + hlen); - NTOHS(ouh->uh_dport); + 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(ouh->uh_dport)); + tcpport_string(dport)); break; case IPPROTO_UDP: (void)sprintf(buf, "%s udp port %s unreachable", ipaddr_string(&oip->ip_dst), - udpport_string(ouh->uh_dport)); + udpport_string(dport)); break; default: (void)sprintf(buf, "%s protocol %d port %d unreachable", ipaddr_string(&oip->ip_dst), - oip->ip_p, ouh->uh_dport); + oip->ip_p, dport); break; } break; @@ -196,7 +200,11 @@ icmp_print(dp, ip) break; case ICMP_MASKREPLY: TCHECK(dp->icmp_mask, sizeof(dp->icmp_mask)); - (void)sprintf(buf, "address mask is 0x%08x", 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); diff --git a/usr.sbin/tcpdump/tcpdump/print-ip.c b/usr.sbin/tcpdump/tcpdump/print-ip.c index a67b29a..c7397f0 100644 --- a/usr.sbin/tcpdump/tcpdump/print-ip.c +++ b/usr.sbin/tcpdump/tcpdump/print-ip.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,12 +21,14 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: /home/ncvs/src/usr.sbin/tcpdump/tcpdump/print-ip.c,v 1.2 1994/09/08 02:29:12 wollman Exp $ (LBL)"; + "@(#) $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> @@ -35,134 +37,66 @@ static char rcsid[] = #include <netinet/udp_var.h> #include <netinet/tcp.h> #include <netinet/tcpip.h> -#include <netinet/igmp.h> + +#include <stdio.h> +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include <unistd.h> #include "interface.h" #include "addrtoname.h" -#include "dvmrp.h" /* in mrouted directory */ -void -igmp_print(cp, len, ip) - register u_char *cp; - register int len; - register struct ip *ip; +static void +igmp_print(register const u_char *bp, register int len, + register const u_char *bp2) { - register u_char *ep = (u_char *)snapend; - struct igmp *igmp = (struct igmp *)cp; + 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 (cp + 7 > ep) { + if (bp + 7 > ep) { (void)printf("[|igmp]"); return; } - switch (igmp->igmp_type) { - case IGMP_HOST_MEMBERSHIP_QUERY: + switch (bp[0] & 0xf) { + case 1: (void)printf("igmp query"); - if (igmp->igmp_code) - printf(" max delay %d", igmp->igmp_code); - - if (igmp->igmp_group.s_addr) - (void)printf(" [gaddr %s]", - ipaddr_string(&igmp->igmp_group)); - if (len != IGMP_MINLEN) + if (*(int *)&bp[4]) + (void)printf(" [gaddr %s]", ipaddr_string(&bp[4])); + if (len != 8) (void)printf(" [len %d]", len); break; - case IGMP_HOST_MEMBERSHIP_REPORT: - (void)printf("igmp report %s", ipaddr_string(&igmp->igmp_group)); - if (igmp->igmp_code) - printf(" [code %d]", igmp->igmp_code); - if (len != IGMP_MINLEN) + case 2: + (void)printf("igmp report %s", ipaddr_string(&bp[4])); + if (len != 8) (void)printf(" [len %d]", len); break; - case IGMP_HOST_NEW_MEMBERSHIP_REPORT: - printf("igmp new report %s", ipaddr_string(&igmp->igmp_group)); - if (igmp->igmp_code) - printf(" [code %d]", igmp->igmp_code); - if (len != IGMP_MINLEN) - (void)printf(" [len %d]", len); - break; - - case IGMP_HOST_LEAVE_MESSAGE: - printf("igmp leave %s", ipaddr_string(&igmp->igmp_group)); - if (igmp->igmp_code) - printf(" [code %d]", igmp->igmp_code); - if (len != IGMP_MINLEN) - (void)printf(" [len %d]", len); - break; - - case IGMP_DVMRP: - (void)printf("igmp dvmrp"); - switch(igmp->igmp_code) { - case DVMRP_PROBE: - printf(" probe"); - break; - case DVMRP_REPORT: - printf(" report"); - break; - case DVMRP_ASK_NEIGHBORS: - printf(" neighbor list request"); - break; - case DVMRP_NEIGHBORS: - printf(" neighbor list reply"); - break; - case DVMRP_ASK_NEIGHBORS2: - printf(" neighbor list request v2"); - break; - case DVMRP_NEIGHBORS2: - printf(" neighbor list reply v2"); - break; - case DVMRP_PRUNE: - printf(" prune"); - break; - case DVMRP_GRAFT: - printf(" graft"); - break; - case DVMRP_GRAFT_ACK: - printf(" graft ack"); - break; - default: - printf("-%d", igmp->igmp_code); - break; - } - - if (len != IGMP_MINLEN) - (void)printf(" [len %d]", len); - break; - case IGMP_MTRACE: - (void)printf("igmp traceroute %s", - ipaddr_string(&igmp->igmp_group)); - if (igmp->igmp_code) - printf(" [code %d]", igmp->igmp_code); - if (len != IGMP_MINLEN) - (void)printf(" [len %d]", len); - break; - case IGMP_MTRACE_RESP: - (void)printf("igmp traceroute resp %s", - ipaddr_string(&igmp->igmp_group)); - if (igmp->igmp_code) - printf(" [code %d]", igmp->igmp_code); - if (len != IGMP_MINLEN) + case 3: + (void)printf("igmp dvmrp %s", ipaddr_string(&bp[4])); + if (len < 8) (void)printf(" [len %d]", len); break; default: - (void)printf("igmp-%x", igmp->igmp_type); - if (igmp->igmp_code) - printf(" [code %d]", igmp->igmp_code); + (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(type, cp, length) - char *type; - register u_char *cp; - int length; +ip_printroute(const char *type, register const u_char *cp, int length) { int ptr = cp[2] - 1; int len; @@ -195,9 +129,7 @@ ip_printroute(type, cp, length) * print IP options. */ static void -ip_optprint(cp, length) - register u_char *cp; - int length; +ip_optprint(register const u_char *cp, int length) { int len; @@ -250,25 +182,50 @@ ip_optprint(cp, length) } /* + * 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(ip, length) - register struct ip *ip; - register int length; +ip_print(register const u_char *bp, register int length) { + register const struct ip *ip; register int hlen; register int len; - register unsigned char *cp; + register int off; + register const u_char *cp; + ip = (const struct ip *)bp; #ifdef TCPDUMP_ALIGN - static u_char *abuf; /* * 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 ((int)ip & (sizeof(long)-1)) { + static u_char *abuf; + if (abuf == 0) abuf = (u_char *)malloc(snaplen); bcopy((char *)ip, (char *)abuf, min(length, snaplen)); @@ -286,41 +243,30 @@ ip_print(ip, length) return; } hlen = ip->ip_hl * 4; - if (hlen < sizeof (struct ip)) { - printf("invalid ip header length %d", hlen); - return; - } - - if (ip->ip_v != 4) { - printf("unknown ip version %d", ip->ip_v); - return; - } - - NTOHS(ip->ip_len); - NTOHS(ip->ip_off); - NTOHS(ip->ip_id); - len = ip->ip_len - hlen; - if (length < ip->ip_len) + len = ntohs(ip->ip_len); + if (length < len) (void)printf("truncated-ip - %d bytes missing!", - ip->ip_len - length); + len - length); + len -= hlen; /* * If this is fragment zero, hand it to the next higher * level protocol. */ - if ((ip->ip_off & 0x1fff) == 0) { - cp = (unsigned char *)ip + hlen; + off = ntohs(ip->ip_off); + if ((off & 0x1fff) == 0) { + cp = (const u_char *)ip + hlen; switch (ip->ip_p) { case IPPROTO_TCP: - tcp_print((struct tcphdr *)cp, len, ip); + tcp_print(cp, len, (const u_char *)ip); break; case IPPROTO_UDP: - udp_print((struct udphdr *)cp, len, ip); + udp_print(cp, len, (const u_char *)ip); break; case IPPROTO_ICMP: - icmp_print((struct icmp *)cp, ip); + icmp_print(cp, (const u_char *)ip); break; case IPPROTO_ND: (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), @@ -328,19 +274,34 @@ ip_print(ip, length) (void)printf(" nd %d", len); break; case IPPROTO_EGP: - egp_print((struct egp_packet *)cp, len, ip); + egp_print(cp, len, (const u_char *)ip); break; #ifndef IPPROTO_OSPF #define IPPROTO_OSPF 89 #endif case IPPROTO_OSPF: - ospf_print((struct ospfhdr *)cp, len, ip); + ospf_print(cp, len, (const u_char *)ip); break; #ifndef IPPROTO_IGMP #define IPPROTO_IGMP 2 #endif case IPPROTO_IGMP: - igmp_print(cp, len, ip); + 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), @@ -354,18 +315,18 @@ ip_print(ip, length) * but the last stick a "+". For unfragmented datagrams, note * the don't fragment flag. */ - if (ip->ip_off & 0x3fff) { + if (off & 0x3fff) { /* * if this isn't the first frag, we're missing the * next level protocol header. print the ip addr. */ - if (ip->ip_off & 0x1fff) + if (off & 0x1fff) (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), ipaddr_string(&ip->ip_dst)); - (void)printf(" (frag %d:%d@%d%s)", ip->ip_id, len, - (ip->ip_off & 0x1fff) * 8, - (ip->ip_off & IP_MF)? "+" : ""); - } else if (ip->ip_off & IP_DF) + (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) @@ -374,6 +335,7 @@ ip_print(ip, length) (void)printf(" [ttl %d]", (int)ip->ip_ttl); if (vflag) { + int sum; char *sep = ""; printf(" ("); @@ -381,8 +343,14 @@ ip_print(ip, length) (void)printf("%sttl %d", sep, (int)ip->ip_ttl); sep = ", "; } - if ((ip->ip_off & 0x3fff) == 0) { - (void)printf("%sid %d", sep, (int)ip->ip_id); + 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) { diff --git a/usr.sbin/tcpdump/tcpdump/print-ipx.c b/usr.sbin/tcpdump/tcpdump/print-ipx.c new file mode 100644 index 0000000..5040068 --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/print-ipx.c @@ -0,0 +1,212 @@ +/* + * 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/tcpdump/print-isoclns.c b/usr.sbin/tcpdump/tcpdump/print-isoclns.c new file mode 100644 index 0000000..5f86d56 --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/print-isoclns.c @@ -0,0 +1,315 @@ +/* + * 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/tcpdump/print-llc.c b/usr.sbin/tcpdump/tcpdump/print-llc.c new file mode 100644 index 0000000..cff51b7 --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/print-llc.c @@ -0,0 +1,196 @@ +/* + * 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/tcpdump/print-nfs.c b/usr.sbin/tcpdump/tcpdump/print-nfs.c index 593e334..e5e4361 100644 --- a/usr.sbin/tcpdump/tcpdump/print-nfs.c +++ b/usr.sbin/tcpdump/tcpdump/print-nfs.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990, 1991, 1992 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,107 +21,106 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: /a/cvs/386BSD/src/contrib/tcpdump/tcpdump/print-nfs.c,v 1.1.1.1 1993/06/12 14:42:08 rgrimes Exp $ (LBL)"; + "@(#) $Header: print-nfs.c,v 1.41 94/06/12 14:35:15 leres Exp $ (LBL)"; #endif -#include <stdio.h> #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 <sys/time.h> -#include <errno.h> -#include <rpc/rpc.h> +#ifdef SOLARIS +#include <tiuser.h> +#endif +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#include <rpc/auth_unix.h> +#include <rpc/svc.h> +#include <rpc/rpc_msg.h> #include <ctype.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> #include "interface.h" -/* These must come after interface.h for BSD. */ -#if BSD >= 199006 -#include <sys/ucred.h> -#include <nfs/nfsv2.h> -#endif -#include <nfs/nfs.h> - #include "addrtoname.h" -#include "extract.h" - -static void nfs_printfh(); -static void nfs_printfn(); +#include "extract.h" /* must come after interface.h */ -#if BYTE_ORDER == LITTLE_ENDIAN -/* - * Byte swap an array of n words. - * Assume input is word-aligned. - * Check that buffer is bounded by "snapend". - */ -static void -bswap(bp, n) - register u_long *bp; - register u_int n; -{ - register int nwords = ((char *)snapend - (char *)bp) / sizeof(*bp); +#include "nfsv2.h" +#include "nfsfh.h" - if (nwords > n) - nwords = n; - for (; --nwords >= 0; ++bp) - *bp = ntohl(*bp); -} -#endif +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(rp, length, ip) - register struct rpc_msg *rp; - int length; - register struct ip *ip; +nfsreply_print(register const u_char *bp, int length, + register const u_char *bp2) { -#if BYTE_ORDER == LITTLE_ENDIAN - bswap((u_long *)rp, sizeof(*rp) / sizeof(u_long)); -#endif + 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), - rp->rm_xid, - rp->rm_reply.rp_stat == MSG_ACCEPTED? "ok":"ERR", + 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), - rp->rm_xid, - rp->rm_reply.rp_stat == MSG_ACCEPTED? "ok":"ERR", + 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 u_long * -parsereq(rp, length) - register struct rpc_msg *rp; - register int length; +static const u_int32 * +parsereq(register const struct rpc_msg *rp, register int length) { - register u_long *dp = (u_long *)&rp->rm_call.cb_cred; - register u_long *ep = (u_long *)snapend; + register const u_int32 *dp = (u_int32 *)&rp->rm_call.cb_cred; + register const u_int32 *ep = (u_int32 *)snapend; + register u_int len; - /* - * find the start of the req data (if we captured it) - * note that dp[1] was already byte swapped by bswap() + if (&dp[2] >= ep) + return (0); + /* + * find the start of the req data (if we captured it) */ - if (dp < ep && dp[1] < length) { - dp += (dp[1] + (2*sizeof(u_long) + 3)) / sizeof(u_long); - if ((dp < ep) && (dp[1] < length)) { - dp += (dp[1] + (2*sizeof(u_long) + 3)) / - sizeof(u_long); + 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); } @@ -133,11 +132,10 @@ parsereq(rp, length) * Print out an NFS file handle and return a pointer to following word. * If packet was truncated, return 0. */ -static u_long * -parsefh(dp) - register u_long *dp; +static const u_int32 * +parsefh(register const u_int32 *dp) { - if (dp + 8 <= (u_long *)snapend) { + if (dp + 8 <= (u_int32 *)snapend) { nfs_printfh(dp); return (dp + 8); } @@ -145,15 +143,14 @@ parsefh(dp) } /* - * Print out a file name and return pointer to longword past it. + * Print out a file name and return pointer to 32-bit word past it. * If packet was truncated, return 0. */ -static u_long * -parsefn(dp) - register u_long *dp; +static const u_int32 * +parsefn(register const u_int32 *dp) { - register int len; - register u_char *cp; + 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)) @@ -164,23 +161,23 @@ parsefn(dp) NTOHL(len); cp = (u_char *)dp; - /* Update long pointer (NFS filenames are padded to long) */ + /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */ dp += ((len + 3) & ~3) / sizeof(*dp); if ((u_char *)dp > snapend) return (0); - nfs_printfn(cp, len); + /* 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 longword past file name. + * Return pointer to 32-bit word past file name. * If packet was truncated (or there was some other error), return 0. */ -static u_long * -parsefhn(dp) - register u_long *dp; +static const u_int32 * +parsefhn(register const u_int32 *dp) { dp = parsefh(dp); if (dp == 0) @@ -190,34 +187,35 @@ parsefhn(dp) } void -nfsreq_print(rp, length, ip) - register struct rpc_msg *rp; - int length; - register struct ip *ip; +nfsreq_print(register const u_char *bp, int length, register const u_char *bp2) { - register u_long *dp; - register u_char *ep = snapend; -#define TCHECK(p, l) if ((u_char *)(p) > ep - l) break + register const struct rpc_msg *rp; + register const struct ip *ip; + register const u_int32 *dp; + register const u_char *ep; -#if BYTE_ORDER == LITTLE_ENDIAN - bswap((u_long *)rp, sizeof(*rp) / sizeof(u_long)); -#endif +#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), - rp->rm_xid, + ntohl(rp->rm_xid), ipaddr_string(&ip->ip_dst), length); else (void)printf("%s.%x > %s.%x: %d", ipaddr_string(&ip->ip_src), - rp->rm_xid, + ntohl(rp->rm_xid), ipaddr_string(&ip->ip_dst), NFS_PORT, length); - switch (rp->rm_call.cb_proc) { + 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"); @@ -225,52 +223,52 @@ nfsreq_print(rp, length, ip) #else #define NFSPROC_NOOP -1 #endif - case RFS_NULL: + case NFSPROC_NULL: printf(" null"); return; - case RFS_GETATTR: + case NFSPROC_GETATTR: printf(" getattr"); if ((dp = parsereq(rp, length)) != 0 && parsefh(dp) != 0) return; break; - case RFS_SETATTR: + case NFSPROC_SETATTR: printf(" setattr"); if ((dp = parsereq(rp, length)) != 0 && parsefh(dp) != 0) return; break; -#if RFS_ROOT != NFSPROC_NOOP - case RFS_ROOT: +#if NFSPROC_ROOT != NFSPROC_NOOP + case NFSPROC_ROOT: printf(" root"); break; #endif - case RFS_LOOKUP: + case NFSPROC_LOOKUP: printf(" lookup"); if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp) != 0) return; break; - case RFS_READLINK: + case NFSPROC_READLINK: printf(" readlink"); if ((dp = parsereq(rp, length)) != 0 && parsefh(dp) != 0) return; break; - case RFS_READ: + case NFSPROC_READ: printf(" read"); if ((dp = parsereq(rp, length)) != 0 && (dp = parsefh(dp)) != 0) { TCHECK(dp, 3 * sizeof(*dp)); - printf(" %lu (%lu) bytes @ %lu", - ntohl(dp[1]), ntohl(dp[2]), ntohl(dp[0])); + printf(" %lu bytes @ %lu", + ntohl(dp[1]), ntohl(dp[0])); return; } break; -#if RFS_WRITECACHE != NFSPROC_NOOP - case RFS_WRITECACHE: +#if NFSPROC_WRITECACHE != NFSPROC_NOOP + case NFSPROC_WRITECACHE: printf(" writecache"); if ((dp = parsereq(rp, length)) != 0 && (dp = parsefh(dp)) != 0) { @@ -282,7 +280,7 @@ nfsreq_print(rp, length, ip) } break; #endif - case RFS_WRITE: + case NFSPROC_WRITE: printf(" write"); if ((dp = parsereq(rp, length)) != 0 && (dp = parsefh(dp)) != 0) { @@ -294,21 +292,21 @@ nfsreq_print(rp, length, ip) } break; - case RFS_CREATE: + case NFSPROC_CREATE: printf(" create"); if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp) != 0) return; break; - case RFS_REMOVE: + case NFSPROC_REMOVE: printf(" remove"); if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp) != 0) return; break; - case RFS_RENAME: + case NFSPROC_RENAME: printf(" rename"); - if ((dp = parsereq(rp, length)) != 0 && + if ((dp = parsereq(rp, length)) != 0 && (dp = parsefhn(dp)) != 0) { fputs(" ->", stdout); if (parsefhn(dp) != 0) @@ -316,7 +314,7 @@ nfsreq_print(rp, length, ip) } break; - case RFS_LINK: + case NFSPROC_LINK: printf(" link"); if ((dp = parsereq(rp, length)) != 0 && (dp = parsefh(dp)) != 0) { @@ -326,7 +324,7 @@ nfsreq_print(rp, length, ip) } break; - case RFS_SYMLINK: + case NFSPROC_SYMLINK: printf(" symlink"); if ((dp = parsereq(rp, length)) != 0 && (dp = parsefhn(dp)) != 0) { @@ -336,36 +334,40 @@ nfsreq_print(rp, length, ip) } break; - case RFS_MKDIR: + case NFSPROC_MKDIR: printf(" mkdir"); if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp) != 0) return; break; - case RFS_RMDIR: + case NFSPROC_RMDIR: printf(" rmdir"); if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp) != 0) return; break; - case RFS_READDIR: + case NFSPROC_READDIR: printf(" readdir"); if ((dp = parsereq(rp, length)) != 0 && (dp = parsefh(dp)) != 0) { TCHECK(dp, 2 * sizeof(*dp)); - printf(" %lu bytes @ %lu", ntohl(dp[1]), ntohl(dp[0])); + /* + * 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 RFS_STATFS: + case NFSPROC_STATFS: printf(" statfs"); if ((dp = parsereq(rp, length)) != 0 && parsefh(dp) != 0) return; break; default: - printf(" proc-%lu", rp->rm_call.cb_proc); + printf(" proc-%lu", ntohl(rp->rm_call.cb_proc)); return; } fputs(" [|nfs]", stdout); @@ -376,86 +378,488 @@ nfsreq_print(rp, length, ip) * 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(dp) - register u_long *dp; +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; + /* - * take a wild guess at the structure of file handles. - * On sun 3s, there are 2 longs of fsid, a short - * len == 8, a long of inode & a long of generation number. - * On sun 4s, the len == 10 & there are 2 bytes of - * padding immediately following it. + * 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. */ - if (dp[2] == 0xa0000) { - if (dp[1]) - (void) printf(" fh %ld.%ld.%lu", dp[0], dp[1], dp[3]); - else - (void) printf(" fh %ld.%ld", dp[0], dp[3]); - } else if ((dp[2] >> 16) == 8) - /* - * 'dp' is longword aligned, so we must use the extract - * macros below for dp+10 which cannot possibly be aligned. - */ - if (dp[1]) - (void) printf(" fh %ld.%ld.%lu", dp[0], dp[1], - EXTRACT_LONG((u_char *)dp + 10)); - else - (void) printf(" fh %ld.%ld", dp[0], - EXTRACT_LONG((u_char *)dp + 10)); - /* On Ultrix pre-4.0, three longs: fsid, fno, fgen and then zeros */ - else if (dp[3] == 0) { - (void)printf(" fh %d,%d/%ld.%ld", major(dp[0]), minor(dp[0]), - dp[1], dp[2]); - } + dp = ((const u_int32 *)&rp->rm_reply) + 1; + if (&dp[1] >= ep) + return(0); + len = ntohl(dp[1]); + if (len >= length) + return(0); /* - * On Ultrix 4.0, - * five longs: fsid, fno, fgen, eno, egen and then zeros + * skip past the ar_verf credentials. */ - else if (dp[5] == 0) { - (void)printf(" fh %d,%d/%ld.%ld", major(dp[0]), minor(dp[0]), - dp[1], dp[2]); - if (vflag) { - /* print additional info */ - (void)printf("[%ld.%ld]", dp[3], dp[4]); - } + 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); } - else - (void) printf(" fh %lu.%lu.%lu.%lu", - dp[0], dp[1], dp[2], dp[3]); + /* 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) + /* - * Print out an NFS filename. - * Assumes that len bytes from cp are present in packet. + * Not all systems have strerror(). */ +static char * +strerr(int errno) +{ + extern int sys_nerr; +#ifndef __FreeBSD__ + /* Conflicts with declaration in <stdio.h> */ + extern char *sys_errlist[]; +#endif + + if (errno < sys_nerr) + return (sys_errlist[errno]); + return (0); +} + +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 ((int)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 -nfs_printfn(cp, len) - register u_char *cp; - register int len; +interp_reply(const struct rpc_msg *rp, u_int32 proc, int length) { - register char c; + register const u_int32 *dp; + + switch (proc) { - /* Sanity */ - if (len >= 64) { - fputs("[\">]", stdout); +#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; } - /* Print out the filename */ - putchar('"'); - while (--len >= 0) { - c = toascii(*cp++); - if (!isascii(c)) { - c = toascii(c); - putchar('M'); - putchar('-'); - } - if (!isprint(c)) { - c ^= 0x40; /* DEL to ?, others to alpha */ - putchar('^'); - } - putchar(c); - } - putchar('"'); + fputs(" [|nfs]", stdout); } diff --git a/usr.sbin/tcpdump/tcpdump/print-ntp.c b/usr.sbin/tcpdump/tcpdump/print-ntp.c index 86f6ba7..c4fadf1 100644 --- a/usr.sbin/tcpdump/tcpdump/print-ntp.c +++ b/usr.sbin/tcpdump/tcpdump/print-ntp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -25,44 +25,52 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: print-ntp.c,v 1.7 92/01/04 01:45:16 leres Exp $ (LBL)"; + "@(#) $Header: print-ntp.c,v 1.14 94/06/14 20:18:46 leres Exp $ (LBL)"; #endif -#include <stdio.h> - #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 <strings.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(bp, length) - register struct ntpdata *bp; - int length; +ntp_print(register const u_char *cp, int length) { - u_char *ep; + 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 = (u_char *)snapend; + ep = snapend; TCHECK(bp->status, sizeof(bp->status)); @@ -192,8 +200,8 @@ trunc: #undef TCHECK } -p_sfix(sfp) - register struct s_fixedpt *sfp; +static void +p_sfix(register const struct s_fixedpt *sfp) { register int i; register int f; @@ -208,12 +216,12 @@ p_sfix(sfp) #define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */ -p_ntp_time(lfp) - register struct l_fixedpt *lfp; +static void +p_ntp_time(register const struct l_fixedpt *lfp) { - register long i; - register unsigned long uf; - register unsigned long f; + register int32 i; + register u_int32 uf; + register u_int32 f; register float ff; i = ntohl(lfp->int_part); @@ -227,14 +235,14 @@ p_ntp_time(lfp) } /* Prints time difference between *lfp and *olfp */ -p_ntp_delta(olfp, lfp) - register struct l_fixedpt *olfp; - register struct l_fixedpt *lfp; +static void +p_ntp_delta(register const struct l_fixedpt *olfp, + register const struct l_fixedpt *lfp) { - register long i; - register unsigned long uf; - register unsigned long ouf; - register unsigned long f; + register int32 i; + register u_int32 uf; + register u_int32 ouf; + register u_int32 f; register float ff; int signbit; diff --git a/usr.sbin/tcpdump/tcpdump/print-null.c b/usr.sbin/tcpdump/tcpdump/print-null.c index b186068..8e7f3b7 100644 --- a/usr.sbin/tcpdump/tcpdump/print-null.c +++ b/usr.sbin/tcpdump/tcpdump/print-null.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,20 +21,17 @@ #ifndef lint static char rcsid[] = - "@(#)$Header: print-null.c,v 1.3 91/10/07 20:19:11 leres Exp $ (LBL)"; + "@(#)$Header: print-null.c,v 1.14 94/06/10 17:01:35 mccanne Exp $ (LBL)"; #endif -#include <stdio.h> -#include <sys/types.h> #include <sys/param.h> #include <sys/time.h> -#include <sys/timeb.h> #include <sys/socket.h> #include <sys/file.h> -#include <sys/mbuf.h> #include <sys/ioctl.h> #include <net/if.h> + #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> @@ -45,20 +42,19 @@ static char rcsid[] = #include <netinet/tcp.h> #include <netinet/tcpip.h> -#include <net/bpf.h> + +#include <stdio.h> #include "interface.h" #include "addrtoname.h" +#include "pcap.h" #define NULL_HDRLEN 4 static void -null_print(p, ip, length) - u_char *p; - struct ip *ip; - int length; +null_print(const u_char *p, const struct ip *ip, int length) { - u_int family; + u_int family; bcopy(p, &family, sizeof(family)); @@ -83,23 +79,21 @@ null_print(p, ip, length) } void -null_if_print(p, tvp, length, caplen) - u_char *p; - struct timeval *tvp; - int length; - int caplen; +null_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) { - struct ip *ip; + int length = h->len; + int caplen = h->caplen; + const struct ip *ip; - ts_print(tvp); + 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 = (u_char *)p; - snapend = (u_char *)p + caplen; + packetp = p; + snapend = p + caplen; length -= NULL_HDRLEN; @@ -108,10 +102,10 @@ null_if_print(p, tvp, length, caplen) if (eflag) null_print(p, ip, length); - ip_print(ip, length); + ip_print((const u_char *)ip, length); if (xflag) - default_print((u_short *)ip, caplen - NULL_HDRLEN); + default_print((const u_char *)ip, caplen - NULL_HDRLEN); putchar('\n'); } diff --git a/usr.sbin/tcpdump/tcpdump/print-ospf.c b/usr.sbin/tcpdump/tcpdump/print-ospf.c index 90daf94..4cae135 100644 --- a/usr.sbin/tcpdump/tcpdump/print-ospf.c +++ b/usr.sbin/tcpdump/tcpdump/print-ospf.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1991 The Regents of the University of California. - * All rights reserved. + * 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 @@ -20,13 +20,16 @@ * * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) */ + #ifndef lint static char rcsid[] = - "@(#) $Header: print-ospf.c,v 1.1 92/01/29 12:44:17 mccanne Exp $ (LBL)"; + "@(#) $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> @@ -34,37 +37,35 @@ static char rcsid[] = #include <errno.h> #include <ctype.h> +#include <stdio.h> -#include "ospf.h" #include "interface.h" #include "addrtoname.h" +#include "ospf.h" + #ifndef __GNUC__ #define inline #endif -#if !defined(__STDC__) && !defined(const) -#define const -#endif /* !defined(__STDC__) && !defined(const) */ - struct bits { - u_long bit; + 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, (char *) 0 + { 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, (char *) 0 + { 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] = { @@ -77,9 +78,7 @@ static const char *ospf_types[OSPF_TYPE_MAX] = { }; static inline void -ospf_print_seqage(seq, us) -register u_long seq; -register time_t us; +ospf_print_seqage(register u_int32 seq, register time_t us) { register time_t sec = us % 60; register time_t mins = (us / 60) % 60; @@ -104,9 +103,7 @@ register time_t us; static inline void -ospf_print_bits(bp, options) -register struct bits *bp; -register u_char options; +ospf_print_bits(register const struct bits *bp, register u_char options) { char sep = ' '; @@ -137,18 +134,16 @@ register u_char options; } static int -ospf_print_lshdr(lshp, end) -register struct lsa_hdr *lshp; -caddr_t end; +ospf_print_lshdr(register const struct lsa_hdr *lshp, const caddr_t end) { if ((caddr_t) (lshp + 1) > end) { return 1; } - - printf(" {"); + + printf(" {"); /* } (ctags) */ if (!lshp->ls_type || lshp->ls_type >= LS_TYPE_MAX) { - printf(" ??LS type %d?? }", + printf(" ??LS type %d?? }", /* { (ctags) */ lshp->ls_type); return 1; } @@ -168,17 +163,15 @@ caddr_t end; */ static int -ospf_print_lsa(lsap, end) -register struct lsa *lsap; -caddr_t end; +ospf_print_lsa(register const struct lsa *lsap, const caddr_t end) { - register caddr_t ls_end; - struct rlalink *rlp; - struct tos_metric *tosp; - struct in_addr *ap; - struct aslametric *almp; - struct mcla *mcp; - u_long *lp; + 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)) { @@ -186,9 +179,9 @@ caddr_t end; } ls_end = (caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length); - + if (ls_end > end) { - printf(" }"); + printf(" }"); /* { (ctags) */ return 1; } @@ -204,13 +197,13 @@ caddr_t end; if ((caddr_t) rln > ls_end) { break; } - printf(" {"); + 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), @@ -230,7 +223,7 @@ caddr_t end; break; default: - printf(" ??RouterLinksType %d?? }", + printf(" ??RouterLinksType %d?? }", /* { (ctags) */ rlp->link_type); return 0; } @@ -242,12 +235,12 @@ caddr_t end; ntohs(tosp->tos_type), ntohs(tosp->tos_metric)); } - printf(" }"); + printf(" }"); /* { (ctags) */ rlp = rln; } - break; + break; - case LS_TYPE_NETWORK: + 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; @@ -256,9 +249,9 @@ caddr_t end; printf(" %s", ipaddr_string(ap)); } - break; + break; - case LS_TYPE_SUM_IP: + case LS_TYPE_SUM_IP: printf(" mask %s", ipaddr_string(&lsap->lsa_un.un_sla.sla_mask)); /* Fall through */ @@ -268,7 +261,7 @@ caddr_t end; for (lp = lsap->lsa_un.un_sla.sla_tosmetric; (caddr_t) (lp + 1) <= ls_end; lp++) { - u_long ul = ntohl(*lp); + u_int32 ul = ntohl(*lp); printf(" tos %d metric %d", (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS, @@ -283,7 +276,7 @@ caddr_t end; for (almp = lsap->lsa_un.un_asla.asla_metric; (caddr_t) (almp + 1) <= ls_end; almp++) { - u_long ul = ntohl(almp->asla_tosmetric); + u_int32 ul = ntohl(almp->asla_tosmetric); printf(" type %d tos %d metric %d", (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1, @@ -324,28 +317,29 @@ caddr_t end; } } - printf(" }"); + printf(" }"); /* { (ctags) */ return 0; } void -ospf_print(dat, length, ip) -u_char *dat; -int length; -struct ip *ip; +ospf_print(register const u_char *bp, register int length, + register const u_char *bp2) { - register struct ospfhdr *op = (struct ospfhdr *) dat; - register caddr_t end = (caddr_t)snapend; - register struct lsa *lsap; - register struct lsa_hdr *lshp; + 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; - struct in_addr *ap; - struct lsr *lsrp; + 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:", + (void) printf("%s > %s:", ipaddr_string(&ip->ip_src), ipaddr_string(&ip->ip_dst)); @@ -373,11 +367,11 @@ struct ip *ip; 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", @@ -514,7 +508,7 @@ struct ip *ip; lshp = op->ospf_db.db_lshdr; while (!ospf_print_lshdr(lshp, end)) { - printf(" }"); + printf(" }"); /* { (ctags) */ lshp++; } } @@ -523,22 +517,22 @@ struct ip *ip; case OSPF_TYPE_LSR: if (vflag) { for (lsrp = op->ospf_lsr; (caddr_t) (lsrp+1) <= end; lsrp++) { - long type; + int32 type; if ((caddr_t) (lsrp + 1) > end) { break; } - printf(" {"); + printf(" {"); /* } (ctags) */ if (!(type = lsrp->ls_type) || type >= LS_TYPE_MAX) { - printf(" ??LinkStateType %d }", + printf(" ??LinkStateType %d }", /* { (ctags) */ type); - printf(" }"); + printf(" }"); /* { (ctags) */ break; } LS_PRINT(lsrp, type); - printf(" }"); + printf(" }"); /* { (ctags) */ } } break; @@ -561,7 +555,7 @@ struct ip *ip; lshp = op->ospf_lsa.lsa_lshdr; while (!ospf_print_lshdr(lshp, end)) { - printf(" }"); + printf(" }"); /* { (ctags) */ lshp++; } break; @@ -576,11 +570,9 @@ struct ip *ip; } /* end switch on version */ trunc_test: - if ((snapend - dat) < length) { + if ((snapend - bp) < length) { printf(" [|]"); } return; /* from ospf_print */ } - - diff --git a/usr.sbin/tcpdump/tcpdump/print-ppp.c b/usr.sbin/tcpdump/tcpdump/print-ppp.c index c83cc7d..806f05f 100644 --- a/usr.sbin/tcpdump/tcpdump/print-ppp.c +++ b/usr.sbin/tcpdump/tcpdump/print-ppp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,30 +21,28 @@ #ifndef lint static char rcsid[] = - "@(#)$Header: print-ppp.c,v 1.7 91/10/07 20:18:33 leres Exp $ (LBL)"; + "@(#)$Header: print-ppp.c,v 1.18 94/06/10 17:01:37 mccanne Exp $ (LBL)"; #endif #ifdef PPP -#include <stdio.h> -#include <netdb.h> -#include <ctype.h> -#include <signal.h> -#include <errno.h> #include <sys/param.h> -#include <sys/types.h> #include <sys/time.h> -#include <sys/timeb.h> #include <sys/socket.h> #include <sys/file.h> -#include <sys/mbuf.h> #include <sys/ioctl.h> #include <net/if.h> + #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> -#include <net/bpf.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" @@ -53,15 +51,14 @@ static char rcsid[] = #define PPP_HDRLEN 4 void -ppp_if_print(p, tvp, length, caplen) - u_char *p; - struct timeval *tvp; - int length; - int caplen; +ppp_if_print(u_char *user, const struct pcap_pkthdr *h, + register const u_char *p) { - struct ip *ip; + register int length = h->len; + register int caplen = h->caplen; + const struct ip *ip; - ts_print(tvp); + ts_print(&h->ts); if (caplen < PPP_HDRLEN) { printf("[|ppp]"); @@ -73,8 +70,8 @@ ppp_if_print(p, tvp, length, caplen) * 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 = (u_char *)p; - snapend = (u_char *)p + caplen; + packetp = p; + snapend = p + caplen; if (eflag) printf("%c %4d %02x %04x: ", p[0] ? 'O' : 'I', length, @@ -82,20 +79,23 @@ ppp_if_print(p, tvp, length, caplen) length -= PPP_HDRLEN; ip = (struct ip *)(p + PPP_HDRLEN); - ip_print(ip, length); + ip_print((const u_char *)ip, length); if (xflag) - default_print((u_short *)ip, caplen - PPP_HDRLEN); + 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() +ppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) { - void error(); - error("not configured for ppp"); /* NOTREACHED */ } diff --git a/usr.sbin/tcpdump/tcpdump/print-rip.c b/usr.sbin/tcpdump/tcpdump/print-rip.c index 4e06594..f305cb0 100644 --- a/usr.sbin/tcpdump/tcpdump/print-rip.c +++ b/usr.sbin/tcpdump/tcpdump/print-rip.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,12 +21,14 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: /a/cvs/386BSD/src/contrib/tcpdump/tcpdump/print-rip.c,v 1.2 1994/02/10 09:17:57 davidg Exp $ (LBL)"; + "@(#) $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> @@ -34,41 +36,16 @@ static char rcsid[] = #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" -#define RIPVERSION 1 - -struct netinfo { - struct osockaddr rip_dst; /* destination net/host */ - int rip_metric; /* cost of route */ -}; - -struct rip { - u_char rip_cmd; /* request/response */ - u_char rip_vers; /* protocol version # */ - u_char rip_res1[2]; /* pad to 32-bit boundary */ - union { - struct netinfo ru_nets[1]; /* variable length... */ - char ru_tracefile[1]; /* ditto ... */ - } ripun; -#define rip_nets ripun.ru_nets -#define rip_tracefile ripun.ru_tracefile -}; - -/* - * Packet types. - */ -#define RIPCMD_REQUEST 1 /* want info */ -#define RIPCMD_RESPONSE 2 /* responding to request */ -#define RIPCMD_TRACEON 3 /* turn tracing on */ -#define RIPCMD_TRACEOFF 4 /* turn it off */ - static void -rip_entry_print(ni) - register struct netinfo *ni; +rip_entry_print(register const struct netinfo *ni) { if (ntohs(ni->rip_dst.sa_family) != AF_INET) { register int i; @@ -79,7 +56,7 @@ rip_entry_print(ni) (u_char)ni->rip_dst.sa_data[i+1]); printf("]"); } else { - register struct sockaddr_in *sin = + register struct sockaddr_in *sin = (struct sockaddr_in *)&ni->rip_dst; printf(" %s", ipaddr_string(&sin->sin_addr)); if (sin->sin_port) @@ -89,18 +66,16 @@ rip_entry_print(ni) } void -rip_print(dat, length) - u_char *dat; - int length; +rip_print(const u_char *dat, int length) { - register struct rip *rp = (struct rip *)dat; - register struct netinfo *ni; - register int amt = (u_char *)snapend - dat; + 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; diff --git a/usr.sbin/tcpdump/tcpdump/print-sl.c b/usr.sbin/tcpdump/tcpdump/print-sl.c index 2c89b42..3c2b8ea 100644 --- a/usr.sbin/tcpdump/tcpdump/print-sl.c +++ b/usr.sbin/tcpdump/tcpdump/print-sl.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,23 +21,17 @@ #ifndef lint static char rcsid[] = - "@(#)$Header: print-sl.c,v 1.17 91/10/07 20:18:35 leres Exp $ (LBL)"; + "@(#)$Header: print-sl.c,v 1.28 94/06/10 17:01:38 mccanne Exp $ (LBL)"; #endif #ifdef CSLIP -#include <stdio.h> -#include <netdb.h> -#include <ctype.h> -#include <signal.h> -#include <errno.h> #include <sys/param.h> -#include <sys/types.h> #include <sys/time.h> #include <sys/timeb.h> -#include <sys/socket.h> #include <sys/file.h> -#include <sys/mbuf.h> #include <sys/ioctl.h> +#include <sys/mbuf.h> +#include <sys/socket.h> #include <net/if.h> #include <netinet/in.h> @@ -52,7 +46,13 @@ static char rcsid[] = #include <net/slcompress.h> #include <net/slip.h> -#include <net/bpf.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" @@ -60,18 +60,17 @@ static char rcsid[] = static int lastlen[2][256]; static int lastconn = 255; -static void compressed_sl_print(); +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(p, tvp, length, caplen) - u_char *p; - struct timeval *tvp; - int length; - int caplen; +sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) { - struct ip *ip; + register int caplen = h->caplen; + register int length = h->len; + register const struct ip *ip; - ts_print(tvp); + ts_print(&h->ts); if (caplen < SLIP_HDRLEN) { printf("[|slip]"); @@ -82,8 +81,8 @@ sl_if_print(p, tvp, length, caplen) * 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 = (u_char *)p; - snapend = (u_char *)p + caplen; + packetp = p; + snapend = p + caplen; length -= SLIP_HDRLEN; @@ -92,18 +91,17 @@ sl_if_print(p, tvp, length, caplen) if (eflag) sliplink_print(p, ip, length); - ip_print(ip, length); + ip_print((u_char *)ip, length); if (xflag) - default_print((u_short *)ip, caplen - SLIP_HDRLEN); + default_print((u_char *)ip, caplen - SLIP_HDRLEN); out: putchar('\n'); } -sliplink_print(p, ip, length) - u_char *p; - struct ip *ip; - int length; +static void +sliplink_print(register const u_char *p, register const struct ip *ip, + register int length) { int dir; int hlen; @@ -140,17 +138,16 @@ sliplink_print(p, ip, length) default: if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) { - compressed_sl_print(&p[SLX_CHDR], ip, length, dir); + compressed_sl_print(&p[SLX_CHDR], ip, + length, dir); printf(": "); } else printf("slip-%d!: ", p[SLX_CHDR]); } } -static u_char * -print_sl_change(str, cp) - char *str; - register u_char *cp; +static const u_char * +print_sl_change(const char *str, register const u_char *cp) { register u_int i; @@ -162,9 +159,8 @@ print_sl_change(str, cp) return (cp); } -static u_char * -print_sl_winchange(cp) - register u_char *cp; +static const u_char * +print_sl_winchange(register const u_char *cp) { register short i; @@ -180,16 +176,13 @@ print_sl_winchange(cp) } static void -compressed_sl_print(chdr, ip, length, dir) - u_char *chdr; - int length; - struct ip *ip; - int dir; +compressed_sl_print(const u_char *chdr, const struct ip *ip, + int length, int dir) { - register u_char *cp = chdr; + register const u_char *cp = chdr; register u_int flags; int hlen; - + flags = *cp++; if (flags & NEW_C) { lastconn = *cp++; @@ -224,21 +217,25 @@ compressed_sl_print(chdr, ip, length, dir) cp = print_sl_change("I+", cp); /* - * 'hlen' is the length of the uncompressed TCP/IP header (in longs). + * '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 *)&((long *)ip)[hlen])->th_off; + 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() +sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) { - void error(); error("not configured for slip"); /* NOTREACHED */ diff --git a/usr.sbin/tcpdump/tcpdump/print-snmp.c b/usr.sbin/tcpdump/tcpdump/print-snmp.c index d1996c0..0a6cb58 100644 --- a/usr.sbin/tcpdump/tcpdump/print-snmp.c +++ b/usr.sbin/tcpdump/tcpdump/print-snmp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990, by John Robert LoVerso. - * All rights reserved. + * 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 @@ -12,10 +12,10 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * This implementaion has been influenced by the CMU SNMP release, + * 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 implemention were derived and/or inspired by an + * 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 @@ -45,9 +45,12 @@ static char rcsid[] = #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" @@ -194,13 +197,13 @@ struct obj { * RFC-1156 format files into "makemib". "mib.h" MUST define at least * a value for `mibroot'. * - * In particluar, this is gross, as this is including initialized structures, + * 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 abreviated on output. + * 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. */ @@ -211,7 +214,7 @@ struct obj_abrev { } obj_abrev_list[] = { #ifndef NO_ABREV_MIB /* .iso.org.dod.internet.mgmt.mib */ - { "", &_mib_obj, "\53\6\1\2\1" }, + { "", &_mib_obj, "\53\6\1\2\1" }, #endif #ifndef NO_ABREV_ENTER /* .iso.org.dod.internet.private.enterprises */ @@ -234,7 +237,7 @@ struct obj_abrev { do { \ if ((o) == objp->oid) \ break; \ - } while (objp = objp->next); \ + } while ((objp = objp->next) != NULL); \ } \ if (objp) { \ printf(suppressdot?"%s":".%s", objp->desc); \ @@ -248,14 +251,14 @@ struct obj_abrev { * temporary internal representation while decoding an ASN.1 data stream. */ struct be { - unsigned long asnlen; + u_long asnlen; union { caddr_t raw; long integer; - unsigned long uns; - unsigned char *str; + u_long uns; + const u_char *str; } data; - unsigned char form, class, id; /* tag info */ + u_char form, class, id; /* tag info */ u_char type; #define BE_ANY 255 #define BE_NONE 0 @@ -309,15 +312,11 @@ static int truncated; * 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". */ -int -asn1_parse(p, len, elem) - register u_char *p; - int len; - struct be *elem; +static int +asn1_parse(register const u_char *p, int len, struct be *elem) { - unsigned char form, class, id; - int indent=0, i, hdr; - char *classstr; + u_char form, class, id; + int i, hdr; elem->asnlen = 0; elem->type = BE_ANY; @@ -455,7 +454,7 @@ asn1_parse(p, len, elem) case COUNTER: case GAUGE: case TIMETICKS: { - register unsigned long data; + register u_long data; elem->type = BE_UNS; data = 0; for (i = elem->asnlen; i-- > 0; p++) @@ -523,9 +522,8 @@ asn1_parse(p, len, elem) * This used to be an integral part of asn1_parse() before the intermediate * BE form was added. */ -void -asn1_print(elem) - struct be *elem; +static void +asn1_print(struct be *elem) { u_char *p = (u_char *)elem->data.raw; u_long asnlen = elem->asnlen; @@ -547,7 +545,7 @@ asn1_print(elem) if (!nflag && asnlen > 2) { struct obj_abrev *a = &obj_abrev_list[0]; for (; a->node; a++) { - if (!memcmp(a->oid, p, strlen(a->oid))) { + if (!bcmp(a->oid, (char *)p, strlen(a->oid))) { objp = a->node->child; i -= strlen(a->oid); p += strlen(a->oid); @@ -590,12 +588,12 @@ asn1_print(elem) case BE_STR: { register int printable = 1, first = 1; - u_char *p = elem->data.str; + 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)printfn(p, p+asnlen); + (void)fn_print(p, p + asnlen); else for (i = asnlen; i-- > 0; p++) { printf(first ? "%.2x" : "_%.2x", *p); @@ -646,10 +644,8 @@ asn1_print(elem) * * This is not currently used. */ -void -asn1_decode(p, length) - u_char *p; - int length; +static void +asn1_decode(u_char *p, int length) { struct be elem; int i = 0; @@ -676,7 +672,7 @@ asn1_decode(p, length) * SEQUENCE { * version INTEGER {version-1(0)}, * community OCTET STRING, - * data ANY -- PDUs + * data ANY -- PDUs * } * PDUs for all but Trap: (see rfc1157 from page 15 on) * SEQUENCE { @@ -707,13 +703,11 @@ asn1_decode(p, length) /* * Decode SNMP varBind */ -void -varbind_print (pduid, np, length, error) - u_char pduid, *np; - int length, error; +static void +varbind_print(u_char pduid, const u_char *np, int length, int error) { struct be elem; - int count = 0, index; + int count = 0, ind; /* Sequence of varBind */ if ((count = asn1_parse(np, length, &elem)) < 0) @@ -729,11 +723,11 @@ varbind_print (pduid, np, length, error) length = elem.asnlen; np = (u_char *)elem.data.raw; - for (index = 1; length > 0; index++) { - u_char *vbend; + for (ind = 1; length > 0; ind++) { + const u_char *vbend; int vblength; - if (!error || index == error) + if (!error || ind == error) fputs(" ", stdout); /* Sequence */ @@ -758,7 +752,7 @@ varbind_print (pduid, np, length, error) asn1_print(&elem); return; } - if (!error || index == error) + if (!error || ind == error) asn1_print(&elem); length -= count; np += count; @@ -775,9 +769,9 @@ varbind_print (pduid, np, length, error) asn1_print(&elem); } } else - if (error && index == error && elem.type != BE_NULL) + if (error && ind == error && elem.type != BE_NULL) fputs("[err objVal!=NULL]", stdout); - if (!error || index == error) + if (!error || ind == error) asn1_print(&elem); length = vblength; @@ -788,10 +782,8 @@ varbind_print (pduid, np, length, error) /* * Decode SNMP PDUs: GetRequest, GetNextRequest, GetResponse, and SetRequest */ -void -snmppdu_print (pduid, np, length) - u_char pduid, *np; - int length; +static void +snmppdu_print(u_char pduid, const u_char *np, int length) { struct be elem; int count = 0, error; @@ -820,7 +812,7 @@ snmppdu_print (pduid, np, length) if ((pduid == GETREQ || pduid == GETNEXTREQ) && elem.data.integer != 0) { char errbuf[10]; - printf("[errorStatus(%s)!=0]", + printf("[errorStatus(%s)!=0]", DECODE_ErrorStatus(elem.data.integer)); } else if (elem.data.integer != 0) { char errbuf[10]; @@ -863,10 +855,8 @@ snmppdu_print (pduid, np, length) /* * Decode SNMP Trap PDU */ -void -trap_print (np, length) - u_char *np; - int length; +static void +trap_print(const u_char *np, int length) { struct be elem; int count = 0, generic; @@ -953,9 +943,7 @@ trap_print (np, length) * Decode SNMP header and pass on to PDU printing routines */ void -snmp_print (np, length) - u_char *np; - int length; +snmp_print(const u_char *np, int length) { struct be elem, pdu; int count = 0; @@ -1008,9 +996,10 @@ snmp_print (np, length) return; } /* default community */ - if (strncmp(elem.data.str, DEF_COMMUNITY, sizeof(DEF_COMMUNITY)-1)) + if (strncmp((char *)elem.data.str, DEF_COMMUNITY, + sizeof(DEF_COMMUNITY) - 1)) /* ! "public" */ - printf("C=%.*s ", elem.asnlen, elem.data.str); + printf("C=%.*s ", (int)elem.asnlen, elem.data.str); length -= count; np += count; diff --git a/usr.sbin/tcpdump/tcpdump/print-sunrpc.c b/usr.sbin/tcpdump/tcpdump/print-sunrpc.c index e7e74be..938d4b0 100644 --- a/usr.sbin/tcpdump/tcpdump/print-sunrpc.c +++ b/usr.sbin/tcpdump/tcpdump/print-sunrpc.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1992 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,42 +21,53 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: /a/cvs/386BSD/src/contrib/tcpdump/tcpdump/print-sunrpc.c,v 1.1.1.1 1993/06/12 14:42:07 rgrimes Exp $ (LBL)"; + "@(#) $Header: print-sunrpc.c,v 1.12 94/06/14 20:18:48 leres Exp $ (LBL)"; #endif -#include <stdio.h> #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 <sys/time.h> -#include <errno.h> -#include <rpc/rpc.h> +#ifdef SOLARIS +#include <tiuser.h> +#endif +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#include <rpc/auth_unix.h> +#include <rpc/svc.h> +#include <rpc/rpc_msg.h> #include <rpc/pmap_prot.h> #include <ctype.h> +#include <errno.h> +#include <stdio.h> #include "interface.h" - #include "addrtoname.h" -#include "extract.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 words. + * Byte swap an array of n 32-bit words. * Assume input is word-aligned. * Check that buffer is bounded by "snapend". */ static void -bswap(bp, n) - register u_long *bp; - register u_int n; +bswap(register u_int32 *bp, register u_int n) { register int nwords = ((char *)snapend - (char *)bp) / sizeof(*bp); @@ -67,64 +78,40 @@ bswap(bp, n) } #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(rp, length, ip) - register struct rpc_msg *rp; - int length; - register struct ip *ip; +sunrpcrequest_print(register const u_char *bp, register int length, + register const u_char *bp2) { - register u_long *dp; - register u_char *ep = snapend; -#define TCHECK(p, l) if ((u_char *)(p) > ep - l) break + register const struct rpc_msg *rp; + register const struct ip *ip; -#if BYTE_ORDER == LITTLE_ENDIAN - bswap((u_long *)rp, sizeof(*rp) / sizeof(u_long)); -#endif + rp = (struct rpc_msg *)bp; + ip = (struct ip *)bp2; if (!nflag) (void)printf("%s.%x > %s.sunrpc: %d", ipaddr_string(&ip->ip_src), - rp->rm_xid, + ntohl(rp->rm_xid), ipaddr_string(&ip->ip_dst), length); else (void)printf("%s.%x > %s.%x: %d", ipaddr_string(&ip->ip_src), - rp->rm_xid, + ntohl(rp->rm_xid), ipaddr_string(&ip->ip_dst), PMAPPORT, length); - - switch (rp->rm_call.cb_proc) { - - case PMAPPROC_NULL: - printf(" null"); - break; - - case PMAPPROC_SET: - printf(" set"); - break; - - case PMAPPROC_UNSET: - printf(" unset"); - break; - - case PMAPPROC_GETPORT: - printf(" getport"); - break; - - case PMAPPROC_DUMP: - printf(" dump"); - break; - - case PMAPPROC_CALLIT: - printf(" callit"); - break; - - default: - printf(" proc #%d", rp->rm_call.cb_proc); - } - printf(" prog #%d", rp->rm_call.cb_prog); - putchar('\n'); + printf(" %s", tok2str(proc2str, " proc #%d", + ntohl(rp->rm_call.cb_proc))); } diff --git a/usr.sbin/tcpdump/tcpdump/print-tcp.c b/usr.sbin/tcpdump/tcpdump/print-tcp.c index 9974b3c..6e1e58d 100644 --- a/usr.sbin/tcpdump/tcpdump/print-tcp.c +++ b/usr.sbin/tcpdump/tcpdump/print-tcp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,11 +21,13 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: print-tcp.c,v 1.18 92/05/25 14:29:04 mccanne Exp $ (LBL)"; + "@(#) $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> @@ -33,10 +35,11 @@ static char rcsid[] = #include <netinet/tcp.h> #include <netinet/tcpip.h> -#ifdef X10 -#include <X/X.h> -#include <X/Xproto.h> +#include <stdio.h> +#ifdef __STDC__ +#include <stdlib.h> #endif +#include <unistd.h> #include "interface.h" #include "addrtoname.h" @@ -56,6 +59,9 @@ static char rcsid[] = #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; @@ -76,15 +82,19 @@ static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE]; void -tcp_print(tp, length, ip) - register struct tcphdr *tp; - register int length; - register struct ip *ip; +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; + u_int32 seq, ack; - if ((u_char *)(tp + 1) > snapend) { + tp = (struct tcphdr *)bp; + ip = (struct ip *)bp2; + if ((const u_char *)(tp + 1) > snapend) { printf("[|tcp]"); return; } @@ -93,32 +103,16 @@ tcp_print(tp, length, ip) return; } - NTOHS(tp->th_sport); - NTOHS(tp->th_dport); - NTOHL(tp->th_seq); - NTOHL(tp->th_ack); - NTOHS(tp->th_win); - NTOHS(tp->th_urp); + 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(tp->th_sport), - ipaddr_string(&ip->ip_dst), tcpport_string(tp->th_dport)); - - if (!qflag) { -#ifdef X10 - register int be; - - if ((be = (tp->th_sport == X_TCP_BI_PORT || - tp->th_dport == X_TCP_BI_PORT)) || - tp->th_sport == X_TCP_LI_PORT || - tp->th_dport == X_TCP_LI_PORT) { - register XReq *xp = (XReq *)(tp + 1); - - x10_print(xp, length - sizeof(struct tcphdr), be); - return; - } -#endif - } + 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); @@ -146,15 +140,15 @@ tcp_print(tp, length, ip) * collating order so there's only one entry for * both directions). */ - if (tp->th_sport < tp->th_dport || - (tp->th_sport == tp->th_dport && + 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 = tp->th_sport << 16 | tp->th_dport; + tha.port = sport << 16 | dport; rev = 0; } else { tha.src = ip->ip_dst, tha.dst = ip->ip_src; - tha.port = tp->th_dport << 16 | tp->th_sport; + tha.port = dport << 16 | sport; rev = 1; } @@ -171,33 +165,32 @@ tcp_print(tp, length, ip) calloc(1, sizeof (*th)); th->addr = tha; if (rev) - th->ack = tp->th_seq, th->seq = tp->th_ack - 1; + th->ack = seq, th->seq = ack - 1; else - th->seq = tp->th_seq, th->ack = tp->th_ack - 1; + th->seq = seq, th->ack = ack - 1; } else { if (rev) - tp->th_seq -= th->ack, tp->th_ack -= th->seq; + seq -= th->ack, ack -= th->seq; else - tp->th_seq -= th->seq, tp->th_ack -= th->ack; + 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)", tp->th_seq, tp->th_seq + length, - length); + (void)printf(" %u:%u(%d)", seq, seq + length, length); if (flags & TH_ACK) - (void)printf(" ack %lu", tp->th_ack); + (void)printf(" ack %u", ack); - (void)printf(" win %d", tp->th_win); + (void)printf(" win %d", win); if (flags & TH_URG) - (void)printf(" urg %d", tp->th_urp); + (void)printf(" urg %d", urp); /* * Handle any options. */ if ((hlen -= sizeof(struct tcphdr)) > 0) { - register u_char *cp = (u_char *)tp + sizeof(struct tcphdr); + register const u_char *cp = (const u_char *)tp + sizeof(*tp); int i; char ch = '<'; @@ -207,14 +200,7 @@ tcp_print(tp, length, ip) switch (*cp++) { case TCPOPT_MAXSEG: { - u_short mss; -#ifdef TCPDUMP_ALIGN - bcopy((char *)cp + 1, (char *)&mss, - sizeof(mss)); -#else - mss = *(u_short *)(cp + 1); -#endif - (void)printf("mss %d", ntohs(mss)); + (void)printf("mss %d", cp[1] << 8 | cp[2]); if (*cp != 4) (void)printf("[len %d]", *cp); cp += 3; @@ -243,14 +229,9 @@ tcp_print(tp, length, ip) break; case TCPOPT_ECHO: { - u_long v; -#ifdef TCPDUMP_ALIGN - bcopy((char *)cp + 1, (char *)&v, - sizeof(v)); -#else - v = *(u_long *)(cp + 1); -#endif - (void)printf("echo %lu", v); + (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; @@ -259,20 +240,28 @@ tcp_print(tp, length, ip) } case TCPOPT_ECHOREPLY: { - u_long v; -#ifdef TCPDUMP_ALIGN - bcopy((char *)cp + 1, (char *)&v, - sizeof(v)); -#else - v = *(u_long *)(cp + 1); -#endif - (void)printf("echoreply %lu", v); + (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) diff --git a/usr.sbin/tcpdump/tcpdump/print-tftp.c b/usr.sbin/tcpdump/tcpdump/print-tftp.c index 3f8f079..8771cbf 100644 --- a/usr.sbin/tcpdump/tcpdump/print-tftp.c +++ b/usr.sbin/tcpdump/tcpdump/print-tftp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -20,88 +20,94 @@ * * Format and print trivial file transfer protocol packets. */ + #ifndef lint static char rcsid[] = - "@(#) $Header: print-tftp.c,v 1.13 91/04/19 10:46:57 mccanne Exp $ (LBL)"; + "@(#) $Header: print-tftp.c,v 1.20 94/06/14 20:18:49 leres Exp $ (LBL)"; #endif -#include <stdio.h> #include <sys/param.h> +#include <sys/time.h> #include <sys/types.h> + +#include <netinet/in.h> + #include <arpa/tftp.h> -#include "interface.h" -#include <strings.h> #include <ctype.h> +#include <stdio.h> +#include <string.h> -struct int2str { - int code; - char *str; -}; +#include "interface.h" +#include "addrtoname.h" /* op code to string mapping */ -static struct int2str op2str[] = { - RRQ, "RRQ", /* read request */ - WRQ, "WRQ", /* write request */ - DATA, "DATA", /* data packet */ - ACK, "ACK", /* acknowledgement */ - ERROR, "ERROR", /* error code */ - 0, 0 +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 int2str 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, 0 +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(tp, length) - register struct tftphdr *tp; - int length; +tftp_print(register const u_char *bp, int length) { - register struct int2str *ts; - register u_char *ep; + 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 = (u_char *)snapend; + ep = snapend; /* Print length */ printf(" %d", length); /* Print tftp request type */ TCHECK(tp->th_opcode, sizeof(tp->th_opcode)); - NTOHS(tp->th_opcode); - putchar(' '); - for (ts = op2str; ts->str; ++ts) - if (ts->code == tp->th_opcode) { - fputs(ts->str, stdout); - break; - } - if (ts->str == 0) { - /* Bail if bogus opcode */ - printf("tftp-#%d", 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 (tp->th_opcode) { + switch (opcode) { case RRQ: case WRQ: putchar(' '); - if (printfn((u_char *)tp->th_stuff, ep)) { + /* + * 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; } @@ -109,8 +115,7 @@ tftp_print(tp, length) case DATA: TCHECK(tp->th_block, sizeof(tp->th_block)); - NTOHS(tp->th_block); - printf(" block %d", tp->th_block); + printf(" block %d", ntohs(tp->th_block)); break; case ACK: @@ -119,19 +124,10 @@ tftp_print(tp, length) case ERROR: /* Print error code string */ TCHECK(tp->th_code, sizeof(tp->th_code)); - NTOHS(tp->th_code); - putchar(' '); - for (ts = err2str; ts->str; ++ts) - if (ts->code == tp->th_code) { - fputs(ts->str, stdout); - break; - } - if (ts->str == 0) - printf("tftp-err-#%d", tp->th_code); - + printf(" %s ", tok2str(err2str, "tftp-err-#%d", + ntohs(tp->th_code))); /* Print error message string */ - putchar(' '); - if (printfn((u_char *)tp->th_data, ep)) { + if (fn_print((const u_char *)tp->th_data, ep)) { fputs(&tstr[1], stdout); return; } @@ -139,7 +135,7 @@ tftp_print(tp, length) default: /* We shouldn't get here */ - printf("(unknown #%d)", tp->th_opcode); + printf("(unknown #%d)", opcode); break; } return; diff --git a/usr.sbin/tcpdump/tcpdump/print-udp.c b/usr.sbin/tcpdump/tcpdump/print-udp.c index 14c22da..9c6b59f 100644 --- a/usr.sbin/tcpdump/tcpdump/print-udp.c +++ b/usr.sbin/tcpdump/tcpdump/print-udp.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,12 +21,14 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: /a/cvs/386BSD/src/contrib/tcpdump/tcpdump/print-udp.c,v 1.1.1.1 1993/06/12 14:42:06 rgrimes Exp $ (LBL)"; + "@(#) $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> @@ -34,25 +36,95 @@ static char rcsid[] = #include <netinet/udp.h> #include <netinet/udp_var.h> +#undef NOERROR /* Solaris sucks */ #include <arpa/nameser.h> #include <arpa/tftp.h> -#include <errno.h> -#include <sys/time.h> -#include <rpc/rpc.h> -#include "interface.h" -/* These must come after interface.h for BSD. */ -#if BSD >= 199006 -#include <sys/ucred.h> -#include <nfs/nfsv2.h> +#ifdef SOLARIS +#include <tiuser.h> #endif -#include <nfs/nfs.h> +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#include <rpc/auth_unix.h> +#include <rpc/svc.h> +#include <rpc/rpc_msg.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*/ @@ -62,13 +134,16 @@ static char rcsid[] = #define RIP_PORT 520 /*XXX*/ void -udp_print(up, length, ip) - register struct udphdr *up; - int length; - register struct ip *ip; +udp_print(register const u_char *bp, int length, register const u_char *bp2) { - register u_char *cp = (u_char *)(up + 1); + 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; @@ -79,9 +154,51 @@ udp_print(up, length, ip) } length -= sizeof(struct udphdr); - NTOHS(up->uh_sport); - NTOHS(up->uh_dport); - NTOHS(up->uh_ulen); + 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; @@ -89,48 +206,57 @@ udp_print(up, length, ip) rp = (struct rpc_msg *)(up + 1); direction = (enum msg_type)ntohl(rp->rm_direction); - if (up->uh_dport == NFS_PORT && direction == CALL) { - nfsreq_print(rp, length, ip); + if (dport == NFS_PORT && direction == CALL) { + nfsreq_print((u_char *)rp, length, (u_char *)ip); return; } - else if (up->uh_sport == NFS_PORT && direction == REPLY) { - nfsreply_print(rp, length, ip); + else if (sport == NFS_PORT && direction == REPLY) { + nfsreply_print((u_char *)rp, length, (u_char *)ip); return; } #ifdef notdef - else if (up->uh_dport == SUNRPC_PORT && direction == CALL) { - sunrpcrequest_print(rp, length, ip); + else if (dport == SUNRPC_PORT && direction == CALL) { + sunrpcrequest_print((u_char *)rp, length, (u_char *)ip); return; } #endif - else if (cp[2] == 2 && (atalk_port(up->uh_sport) || - atalk_port(up->uh_dport))) { - ddp_print((struct atDDP *)(&cp[3]), length - 3); + 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(up->uh_sport), - ipaddr_string(&ip->ip_dst), udpport_string(up->uh_dport)); + ipaddr_string(&ip->ip_src), udpport_string(sport), + ipaddr_string(&ip->ip_dst), udpport_string(dport)); if (!qflag) { -#define ISPORT(p) (up->uh_dport == (p) || up->uh_sport == (p)) +#define ISPORT(p) (dport == (p) || sport == (p)) if (ISPORT(NAMESERVER_PORT)) - ns_print((HEADER *)(up + 1), length); + ns_print((const u_char *)(up + 1), length); else if (ISPORT(TFTP_PORT)) - tftp_print((struct tftphdr *)(up + 1), length); + tftp_print((const u_char *)(up + 1), length); else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS)) - bootp_print((struct bootp *)(up + 1), length, - up->uh_sport, up->uh_dport); - else if (up->uh_dport == RIP_PORT) - rip_print((u_char *)(up + 1), length); + 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((u_char *)(up + 1), length); + snmp_print((const u_char *)(up + 1), length); else if (ISPORT(NTP_PORT)) - ntp_print((struct ntpdata *)(up + 1), length); + 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", up->uh_ulen - sizeof(*up)); + (void)printf(" udp %d", ulen - sizeof(*up)); #undef ISPORT } else - (void)printf(" udp %d", up->uh_ulen - sizeof(*up)); + (void)printf(" udp %d", ulen - sizeof(*up)); } diff --git a/usr.sbin/tcpdump/tcpdump/print-wb.c b/usr.sbin/tcpdump/tcpdump/print-wb.c new file mode 100644 index 0000000..a9322dd --- /dev/null +++ b/usr.sbin/tcpdump/tcpdump/print-wb.c @@ -0,0 +1,445 @@ +/* + * 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/tcpdump/tcpdump.1 b/usr.sbin/tcpdump/tcpdump/tcpdump.1 index 7ba0fb9..2bb5c9f 100644 --- a/usr.sbin/tcpdump/tcpdump/tcpdump.1 +++ b/usr.sbin/tcpdump/tcpdump/tcpdump.1 @@ -1,7 +1,7 @@ -.\" @(#) $Header: /home/cvs/386BSD/src/contrib/tcpdump/tcpdump/tcpdump.1,v 1.1.1.1 1993/06/12 14:42:05 rgrimes Exp $ (LBL) +.\" @(#) $Header: tcpdump.1,v 1.45 94/06/20 18:54:27 leres Exp $ (LBL) .\" -.\" Copyright (c) 1988, 1989, 1990, 1991, 1992 -.\" The Regents of the University of California. +.\" 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 @@ -20,7 +20,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH TCPDUMP 1 "4 Jan 1992" +.TH TCPDUMP 1 "20 Jun 1994" .SH NAME tcpdump \- dump traffic on a network .SH SYNOPSIS @@ -159,6 +159,10 @@ Print an unformatted timestamp on each dump line. (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. @@ -200,7 +204,8 @@ Possible directions are .BR dst , .B "src or dst" and -.BR "src and dst" . +.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" @@ -209,9 +214,14 @@ is assumed. 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 . @@ -221,6 +231,14 @@ 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 , @@ -359,7 +377,25 @@ True if the packet is of ether type \fIprotocol\fR. \fIip\fP, \fIarp\fP, or \fIrarp\fP. Note these identifiers are also keywords and must be escaped via backslash (\\). -.IP "\fBip\fR, \fBarp\fR, \fBrarp\fR" +[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 @@ -367,6 +403,16 @@ Abbreviations for: .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 @@ -387,7 +433,8 @@ data inside the packet, use the following syntax: \fIproto\fB [ \fIexpr\fB : \fIsize\fB ]\fR .fi .in -.5i -\fIProto\fR is one of \fBether, ip, arp, rarp, tcp, udp, \fRor \fBicmp\fR, and +\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. @@ -399,10 +446,10 @@ 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[2:2] & 0x1fff = 0\fP' +`\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 opertations. +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. @@ -414,9 +461,9 @@ A parenthesized group of primitives and operators .IP Negation (`\fB!\fP' or `\fBnot\fP'). .IP -Concatenation (`\fBand\fP'). +Concatenation (`\fB&&\fP' or `\fBand\fP'). .IP -Alternation (`\fBor\fP'). +Alternation (`\fB||\fP' or `\fBor\fP'). .LP Negation has highest precedence. Alternation and concatenation have equal precedence and associate @@ -550,6 +597,16 @@ 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 @@ -806,40 +863,78 @@ need to seriously investigate name server traffic. `\fB\-s 128\fP' has worked well for me. .HD -NFS Requests +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\fP +\fIsrc.nfs > dst.xid: reply stat len op results\fP .sp .5 -\f(CWvs.e2766 > helios.nfs: 136 readdir fh 6.5197 8192 bytes @ 0 -helios.nfs > vs.e2766: reply ok 384 -vs.e2767 > helios.nfs: 136 lookup fh 6.5197 `RCS'\fP +\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 \fIvs\fP sends a transaction with id \fIe2766\fP -to \fIhelios\fP (note that the number following the src host is a -transaction id, \fInot\fP the source port). The request was 136 bytes, -excluding the UDP and IP headers. The operation was a \fIreaddir\fP -(read directory) on file handle (\fIfh\fP) 6.5197. 8192 bytes are -read, starting at offset 0. \fIHelios\fP replies `ok' with 384 -bytes of data. (The design of Sun's RPC protocol makes it difficult to -interpret replies. I don't bother.) -.LP -In the third line, \fIvs\fP asks \fIhelios\fP to lookup the name -`\fIRCS\fP' in directory file 6.5197. Note that the data printed +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 (at least, to me) if read in conjunction with +explanatory if read in conjunction with an NFS protocol spec. .LP -Note that NFS requests are very large and the above won't be printed -unless \fIsnaplen\fP is increased. I use `\fB\-s 192\fP' to watch +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 @@ -1039,8 +1134,11 @@ We recommend that you use the latter. has to have been built with the \fIpacketfilter\fP pseudo-device driver (see .IR packetfilter (4)). -As of this writing, Ultrix does not let you -watch either your own outbound or inbound traffic. +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 @@ -1065,3 +1163,9 @@ 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/tcpdump.c b/usr.sbin/tcpdump/tcpdump/tcpdump.c index 9a0ccc4..64b9150 100644 --- a/usr.sbin/tcpdump/tcpdump/tcpdump.c +++ b/usr.sbin/tcpdump/tcpdump/tcpdump.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1987-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -20,9 +20,9 @@ */ #ifndef lint char copyright[] = - "@(#) Copyright (c) 1987-1990 The Regents of the University of California.\nAll rights reserved.\n"; + "@(#) 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.68 92/06/02 17:57:41 mccanne Exp $ (LBL)"; + "@(#)$Header: tcpdump.c,v 1.93 94/06/10 17:01:44 mccanne Exp $ (LBL)"; #endif /* @@ -33,17 +33,21 @@ static char rcsid[] = * combined efforts of Van, Steve McCanne and Craig Leres of LBL. */ -#include <stdio.h> -#include <signal.h> #include <sys/types.h> #include <sys/time.h> -#include <sys/timeb.h> + #include <netinet/in.h> -#include <net/bpf.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 "savefile.h" #include "addrtoname.h" int fflag; /* don't translate "foreign" IP address */ @@ -57,37 +61,36 @@ 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; -long thiszone; /* gmt to local correction */ +int thiszone; -static void cleanup(); +SIGRET cleanup(int); +extern void bpf_dump(struct bpf_program *, int); /* Length of saved portion of packet. */ int snaplen = DEFAULT_SNAPLEN; -static int if_fd = -1; - struct printer { - void (*f)(); + 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 }, - { 0, 0 }, + { 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 }, }; -void -(*lookup_printer(type))() - int type; +static pcap_handler +lookup_printer(int type) { struct printer *p; @@ -99,40 +102,56 @@ void /* NOTREACHED */ } +static pcap_t *pd; + +#ifdef __osf__ +#include <sys/sysinfo.h> +#include <sys/proc.h> void -main(argc, argv) - int argc; - char **argv; +abort_on_misalignment() { - struct bpf_program *parse(); - void bpf_dump(); - - int cnt = -1, i; - struct timeb zt; - struct bpf_program *fcode; - int op; - void (*printit)(); - char *infile = 0; - char *cmdbuf; - int linktype; - int err; - u_long localnet; - u_long netmask; - - char *RFileName = 0; /* -r argument */ - char *WFileName = 0; /* -w argument */ + int buf[2]; + + buf[0] = SSIN_UACPROC; + buf[1] = UAC_SIGBUS; + if (setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0) < 0) { + perror("setsysinfo"); + exit(1); + } +} - char *device = 0; +#endif - int precision = clock_sigfigs(); +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; - program_name = argv[0]; +#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:Stvw:xY")) != EOF) + while ((op = getopt(argc, argv, "c:defF:i:lnNOpqr:s:StT:vw:xY")) != EOF) switch (op) { case 'c': cnt = atoi(optarg); @@ -183,8 +202,8 @@ main(argc, argv) break; case 'r': - RFileName = optarg; - break; + RFileName = optarg; + break; case 's': snaplen = atoi(optarg); @@ -198,13 +217,26 @@ main(argc, argv) --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; + WFileName = optarg; + break; #ifdef YYDEBUG case 'Y': { @@ -222,20 +254,10 @@ main(argc, argv) /* NOTREACHED */ } - if (tflag > 0) { - struct timeval now; - struct timezone tz; - - if (gettimeofday(&now, &tz) < 0) { - perror("tcpdump: gettimeofday"); - exit(1); - } - thiszone = tz.tz_minuteswest * -60; - if (localtime((time_t *)&now.tv_sec)->tm_isdst) - thiszone += 3600; - } + if (tflag > 0) + thiszone = gmt2local(); - if (RFileName) { + 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 @@ -243,36 +265,40 @@ main(argc, argv) */ setuid(getuid()); - err = sf_read_init(RFileName, &linktype, &thiszone, &snaplen, - &precision); - if (err) - sf_err(err); + pd = pcap_open_offline(RFileName, errbuf); + if (pd == NULL) + error(errbuf); + /* use the snaplen stored in the file */ + snaplen = pcap_snapshot(pd); localnet = 0; netmask = 0; if (fflag != 0) error("-f and -r options are incompatible"); } else { - if (device == 0) { - device = lookup_device(); - if (device == 0) - error("can't find any interfaces"); + if (device == NULL) { + device = pcap_lookupdev(errbuf); + if (device == NULL) + error(errbuf); } - if_fd = initdevice(device, pflag, &linktype); - lookup_net(device, &localnet, &netmask); + 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) + if (infile) cmdbuf = read_infile(infile); else cmdbuf = copy_argv(&argv[optind]); - fcode = parse(cmdbuf, Oflag, linktype, netmask); + if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) + error(pcap_geterr(pd)); if (dflag) { - bpf_dump(fcode, dflag); + bpf_dump(&fcode, dflag); exit(0); } init_addrtoname(fflag, localnet, netmask); @@ -281,45 +307,85 @@ main(argc, argv) (void)signal(SIGINT, cleanup); (void)signal(SIGHUP, cleanup); - printit = lookup_printer(linktype); - + if (pcap_setfilter(pd, &fcode) < 0) + error(pcap_geterr(pd)); if (WFileName) { - sf_write_init(WFileName, linktype, thiszone, snaplen, - precision); - printit = sf_write; - } - if (RFileName) { - err = sf_read(fcode, cnt, snaplen, printit); - if (err) - sf_err(err); + 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); - readloop(cnt, if_fd, fcode, printit); } + pcap_loop(pd, cnt, printer, pcap_userdata); + pcap_close(pd); exit(0); } /* make a clean exit on interrupts */ -static void -cleanup() +SIGRET +cleanup(int signo) { - if (if_fd >= 0) { + 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); - wrapup(if_fd); + 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(sp, length) - register u_short *sp; - register int length; +default_print(register const u_char *bp, register int length) { + register const u_short *sp; register u_int i; register int nshorts; - nshorts = (unsigned) length / sizeof(u_short); + if ((int)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) diff --git a/usr.sbin/tcpdump/tcpdump/util.c b/usr.sbin/tcpdump/tcpdump/util.c index ec58c3f..2a44176 100644 --- a/usr.sbin/tcpdump/tcpdump/util.c +++ b/usr.sbin/tcpdump/tcpdump/util.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1988-1990 The Regents of the University of California. - * All rights reserved. + * 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 @@ -21,77 +21,87 @@ #ifndef lint static char rcsid[] = - "@(#) $Header: util.c,v 1.12 91/10/28 22:09:31 mccanne Exp $ (LBL)"; + "@(#) $Header: util.c,v 1.28 94/06/12 14:30:31 leres Exp $ (LBL)"; #endif -#include <stdio.h> -#ifdef __STDC__ #include <stdlib.h> -#endif #include <sys/types.h> #include <sys/time.h> -#include <ctype.h> -#include <varargs.h> #include <sys/file.h> #include <sys/stat.h> -#include "interface.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> -/* Hex digit to integer. */ -static inline int -xdtoi(c) -{ - if (isdigit(c)) - return c - '0'; - else if (islower(c)) - return c - 'a' + 10; - else - return c - 'A' + 10; -} +#include "interface.h" /* - * Convert string to integer. Just like atoi(), but checks for - * preceding 0x or 0 and uses hex or octal instead of decimal. + * Print out a filename (or other ascii string). + * If ep is NULL, assume no truncation check is needed. + * Return true if truncated. */ int -stoi(s) - char *s; +fn_print(register const u_char *s, register const u_char *ep) { - int base = 10; - int n = 0; + register int ret; + register u_char c; - if (*s == '0') { - if (s[1] == 'x' || s[1] == 'X') { - s += 2; - base = 16; + 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('-'); } - else { - base = 8; - s += 1; + if (!isprint(c)) { + c ^= 0x40; /* DEL to ?, others to alpha */ + putchar('^'); } + putchar(c); } - while (*s) - n = n * base + xdtoi(*s++); - - return n; + putchar('"'); + return(ret); } /* - * Print out a filename (or other ascii string). + * Print out a counted filename (or other ascii string). + * If ep is NULL, assume no truncation check is needed. * Return true if truncated. */ int -printfn(s, ep) - register u_char *s, *ep; +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 (c = *s++) { - if (s > ep) { - putchar('"'); - return(1); + while (ep == NULL || s < ep) { + if (n-- <= 0) { + ret = 0; + break; } + c = *s++; if (!isascii(c)) { c = toascii(c); putchar('M'); @@ -104,32 +114,77 @@ printfn(s, ep) putchar(c); } putchar('"'); - return(0); + return(ret); } /* * Print the timestamp */ void -ts_print(tvp) - register struct timeval *tvp; +ts_print(register const struct timeval *tvp) { - register int i; + register int s; + extern int32 thiszone; if (tflag > 0) { /* Default */ - i = (tvp->tv_sec + thiszone) % 86400; + s = (tvp->tv_sec + thiszone) % 86400; (void)printf("%02d:%02d:%02d.%06d ", - i / 3600, (i % 3600) / 60, i % 60, tvp->tv_usec); + 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. + * Stock 4.3 doesn't have vfprintf. * This routine is due to Chris Torek. */ vfprintf(f, fmt, args) @@ -150,34 +205,29 @@ vfprintf(f, fmt, args) } #endif -static char * -stripdir(s) - register char *s; -{ - register char *cp; - char *rindex(); - - cp = rindex(s, '/'); - return (cp != 0) ? cp + 1 : s; -} - /* VARARGS */ -void -error(va_alist) +__dead void +#if __STDC__ || defined(SOLARIS) +error(char *fmt, ...) +#else +error(fmt, va_alist) + char *fmt; va_dcl +#endif { - register char *cp; va_list ap; - (void)fprintf(stderr, "%s: ", stripdir(program_name)); - + (void)fprintf(stderr, "%s: ", program_name); +#if __STDC__ + va_start(ap, fmt); +#else va_start(ap); - cp = va_arg(ap, char *); - (void)vfprintf(stderr, cp, ap); +#endif + (void)vfprintf(stderr, fmt, ap); va_end(ap); - if (*cp) { - cp += strlen(cp); - if (cp[-1] != '\n') + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') (void)fputc('\n', stderr); } exit(1); @@ -186,32 +236,36 @@ error(va_alist) /* VARARGS */ void -warning(va_alist) +#if __STDC__ || defined(SOLARIS) +warning(char *fmt, ...) +#else +warning(fmt, va_alist) + char *fmt; va_dcl +#endif { - register char *cp; va_list ap; - (void)fprintf(stderr, "%s: warning: ", stripdir(program_name)); - + (void)fprintf(stderr, "%s: warning: ", program_name); +#if __STDC__ + va_start(ap, fmt); +#else va_start(ap); - cp = va_arg(ap, char *); - (void)vfprintf(stderr, cp, ap); +#endif + (void)vfprintf(stderr, fmt, ap); va_end(ap); - if (*cp) { - cp += strlen(cp); - if (cp[-1] != '\n') + 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(argv) - register char **argv; +copy_argv(register char **argv) { register char **p; register int len = 0; @@ -229,8 +283,8 @@ copy_argv(argv) p = argv; dst = buf; - while (src = *p++) { - while (*dst++ = *src++) + while ((src = *p++) != NULL) { + while ((*dst++ = *src++) != '\0') ; dst[-1] = ' '; } @@ -240,8 +294,7 @@ copy_argv(argv) } char * -read_infile(fname) - char *fname; +read_infile(char *fname) { struct stat buf; int fd; @@ -254,25 +307,29 @@ read_infile(fname) if (fstat(fd, &buf) < 0) error("can't state '%s'", fname); - p = malloc((unsigned)buf.st_size); + 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; } -/* - * Left justify 'addr' and return its resulting network mask. - */ -u_long -net_mask(addr) - u_long *addr; +int +gmt2local() { - register u_long m = 0xffffffff; - - if (*addr) - while ((*addr & 0xff000000) == 0) - *addr <<= 8, m <<= 8; - - return m; +#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/tcpslice/Makefile b/usr.sbin/tcpdump/tcpslice/Makefile index 48e0053..d559c06 100644 --- a/usr.sbin/tcpdump/tcpslice/Makefile +++ b/usr.sbin/tcpdump/tcpslice/Makefile @@ -1,12 +1,12 @@ # @(#)Makefile 0.1 (RWGrimes) 3/24/93 PROG= tcpslice -CFLAGS+=-DCSLIP -I. -I$(.CURDIR)/../tcpdump +CFLAGS+=-Wall MAN1= tcpslice.1 -SRCS= version.c tcpslice.c gwtm2secs.c search.c \ - savefile.c bpf_filter.c md.c util.c -.PATH: ${.CURDIR}/../tcpdump ${.CURDIR}/../../../sys/net +SRCS= version.c tcpslice.c gwtm2secs.c search.c util.c CLEANFILES+= version.c version.h +DPADD+= ${LIBPCAP} +LDADD+= -lpcap version.c version.h: $(.CURDIR)/../tcpdump/VERSION rm -f version.c ; \ diff --git a/usr.sbin/tcpdump/tcpslice/gwtm2secs.c b/usr.sbin/tcpdump/tcpslice/gwtm2secs.c index aeb377f..797c1fc 100644 --- a/usr.sbin/tcpdump/tcpslice/gwtm2secs.c +++ b/usr.sbin/tcpdump/tcpslice/gwtm2secs.c @@ -20,16 +20,14 @@ */ #ifndef lint static char rcsid[] = - "@(#)$Header: gwtm2secs.c,v 1.1 92/06/02 11:35:19 mccanne Exp $ (LBL)"; + "@(#)$Header: gwtm2secs.c,v 1.2 93/11/18 13:11:30 vern Exp $ (LBL)"; #endif /* * gwtm2secs.c - convert "tm" structs for Greenwich time to Unix timestamp */ -#include <stdio.h> -#include <sys/types.h> -#include <time.h> +#include "tcpslice.h" static int days_in_month[] = /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ @@ -38,8 +36,7 @@ static int days_in_month[] = #define IS_LEAP_YEAR(year) \ (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) -time_t gwtm2secs( tm ) -struct tm *tm; +time_t gwtm2secs( struct tm *tm ) { int i, days, year; diff --git a/usr.sbin/tcpdump/tcpslice/search.c b/usr.sbin/tcpdump/tcpslice/search.c index 8bea0d2..b6f75e0 100644 --- a/usr.sbin/tcpdump/tcpslice/search.c +++ b/usr.sbin/tcpdump/tcpslice/search.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1990, 1991, 1992, 1993 + * 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 @@ -20,19 +20,14 @@ */ #ifndef lint static char rcsid[] = - "@(#)$Header: search.c,v 1.3 92/05/01 15:14:45 vern Exp $ (LBL)"; + "@(#)$Header: search.c,v 1.8 93/11/18 13:11:51 vern Exp $ (LBL)"; #endif /* * search.c - supports fast searching through tcpdump files for timestamps */ -#include <stdio.h> -#include <sys/types.h> -#include <sys/time.h> - -#include "interface.h" -#include "savefile.h" +#include "tcpslice.h" /* Maximum number of seconds that we can conceive of a dump file spanning. */ @@ -44,7 +39,9 @@ static char rcsid[] = /* Size of a packet header in bytes; easier than typing the sizeof() all * the time ... */ -#define PACKET_HDR_LEN (sizeof( struct packet_header )) +#define PACKET_HDR_LEN (sizeof( struct pcap_pkthdr )) + +extern int snaplen; /* The maximum size of a packet, including its header. */ #define MAX_PACKET_SIZE (PACKET_HDR_LEN + snaplen) @@ -71,18 +68,12 @@ static char rcsid[] = */ #define STRAIGHT_SCAN_THRESHOLD (100 * MAX_PACKET_SIZE) -/* Extracts a long integer from a possibly unaligned buffer containing - * unsigned characters. - */ -#define EXTRACT_LONG(buf) (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) - /* Given a header and an acceptable first and last time stamp, returns non-zero * if the header looks reasonable and zero otherwise. */ -static int reasonable_header( hdr, first_time, last_time ) -struct packet_header *hdr; -long first_time, last_time; +static int +reasonable_header( struct pcap_pkthdr *hdr, long first_time, long last_time ) { if ( last_time == 0 ) last_time = first_time + MAX_REASONABLE_FILE_SPAN; @@ -96,27 +87,41 @@ long first_time, last_time; } +#define SWAPLONG(y) \ +((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) +#define SWAPSHORT(y) \ + ( (((y)&0xff)<<8) | (((y)&0xff00)>>8) ) + /* Given a buffer, extracts a (properly aligned) packet header from it. */ -static void extract_header( buf, hdr ) -u_char *buf; -struct packet_header *hdr; +static void +extract_header( pcap_t *p, u_char *buf, struct pcap_pkthdr *hdr ) { - hdr->ts.tv_sec = EXTRACT_LONG(buf); - buf += sizeof( long ); - hdr->ts.tv_usec = EXTRACT_LONG(buf); - buf += sizeof( long ); - hdr->len = EXTRACT_LONG(buf); - buf += sizeof( long ); - hdr->caplen = EXTRACT_LONG(buf); - - if ( sf_swapped ) + bcopy((char *) buf, (char *) hdr, sizeof(struct pcap_pkthdr)); + + if ( pcap_is_swapped( p ) ) { hdr->ts.tv_sec = SWAPLONG(hdr->ts.tv_sec); hdr->ts.tv_usec = SWAPLONG(hdr->ts.tv_usec); hdr->len = SWAPLONG(hdr->len); hdr->caplen = SWAPLONG(hdr->caplen); } + + /* + * From bpf/libpcap/savefile.c: + * + * We interchanged the caplen and len fields at version 2.3, + * in order to match the bpf header layout. But unfortunately + * some files were written with version 2.3 in their headers + * but without the interchanged fields. + */ + if ( pcap_minor_version( p ) < 3 || + (pcap_minor_version( p ) == 3 && hdr->caplen > hdr->len) ) + { + int t = hdr->caplen; + hdr->caplen = hdr->len; + hdr->len = t; + } } @@ -152,16 +157,13 @@ struct packet_header *hdr; #define HEADER_PERHAPS 2 #define HEADER_DEFINITELY 3 -static int find_header( buf, buf_len, first_time, last_time, - hdrpos_addr, return_hdr ) -u_char *buf; -unsigned buf_len; -long first_time, last_time; -u_char **hdrpos_addr; -struct packet_header *return_hdr; +static int +find_header( pcap_t *p, u_char *buf, int buf_len, + long first_time, long last_time, + u_char **hdrpos_addr, struct pcap_pkthdr *return_hdr ) { u_char *bufptr, *bufend, *last_pos_to_try; - struct packet_header hdr, hdr2; + struct pcap_pkthdr hdr, hdr2; int status = HEADER_NONE; int saw_PERHAPS_clash = 0; @@ -175,7 +177,7 @@ struct packet_header *return_hdr; for ( bufptr = buf; bufptr < last_pos_to_try; ++bufptr ) { - extract_header( bufptr, &hdr ); + extract_header( p, bufptr, &hdr ); if ( reasonable_header( &hdr, first_time, last_time ) ) { @@ -183,9 +185,9 @@ struct packet_header *return_hdr; if ( next_header + PACKET_HDR_LEN < bufend ) { /* check for another good header */ - extract_header( next_header, &hdr2 ); + extract_header( p, next_header, &hdr2 ); - if ( reasonable_header( &hdr2, hdr.ts.tv_sec, + if ( reasonable_header( &hdr2, hdr.ts.tv_sec, hdr.ts.tv_sec + MAX_REASONABLE_HDR_SEPARATION ) ) { /* a confirmed header */ switch ( status ) @@ -262,15 +264,15 @@ struct packet_header *return_hdr; * order to give sf_find_packet() an upper bound on the timestamps * present in the dump file. */ -int sf_find_end( first_timestamp, last_timestamp ) -struct timeval *first_timestamp; -struct timeval *last_timestamp; +int +sf_find_end( pcap_t *p, struct timeval *first_timestamp, + struct timeval *last_timestamp ) { long first_time = first_timestamp->tv_sec; - unsigned num_bytes; + u_int num_bytes; u_char *buf, *bufpos, *bufend; u_char *hdrpos; - struct packet_header hdr, successor_hdr; + struct pcap_pkthdr hdr, successor_hdr; int status; /* Allow enough room for at least two full (untruncated) packets, @@ -279,10 +281,10 @@ struct timeval *last_timestamp; * end of the file. */ num_bytes = MAX_BYTES_FOR_DEFINITE_HEADER; - if ( fseek( sf_readfile, (long) -num_bytes, 2 ) < 0 ) + if ( fseek( pcap_file( p ), (long) -num_bytes, 2 ) < 0 ) return 0; - buf = (u_char *)malloc((unsigned) num_bytes); + buf = (u_char *)malloc((u_int) num_bytes); if ( ! buf ) return 0; @@ -290,11 +292,11 @@ struct timeval *last_timestamp; bufpos = buf; bufend = buf + num_bytes; - if ( fread( (char *) bufpos, num_bytes, 1, sf_readfile ) != 1 ) + if ( fread( (char *) bufpos, num_bytes, 1, pcap_file( p ) ) != 1 ) goto done; - if ( find_header( bufpos, num_bytes, first_time, 0L, &hdrpos, &hdr ) != - HEADER_DEFINITELY ) + if ( find_header( p, bufpos, num_bytes, + first_time, 0L, &hdrpos, &hdr ) != HEADER_DEFINITELY ) goto done; /* Okay, we have a definite header in our hands. Follow its @@ -313,7 +315,7 @@ struct timeval *last_timestamp; /* not enough room for another header */ break; - extract_header( bufpos, &successor_hdr ); + extract_header( p, bufpos, &successor_hdr ); first_time = hdr.ts.tv_sec; if ( ! reasonable_header( &successor_hdr, first_time, 0L ) ) @@ -344,7 +346,7 @@ struct timeval *last_timestamp; status = 1; /* Seek so that the next read will start at last valid packet. */ - if ( fseek( sf_readfile, (long) -(bufend - hdrpos), 2 ) < 0 ) + if ( fseek( pcap_file( p ), (long) -(bufend - hdrpos), 2 ) < 0 ) error( "final fseek() failed in sf_find_end()" ); done: @@ -356,8 +358,8 @@ struct timeval *last_timestamp; /* Takes two timeval's and returns the difference, tv2 - tv1, as a double. */ -static double timeval_diff( tv1, tv2 ) -struct timeval *tv1, *tv2; +static double +timeval_diff( struct timeval *tv1, struct timeval *tv2 ) { double result = (tv2->tv_sec - tv1->tv_sec); result += (tv2->tv_usec - tv1->tv_usec) / 1000000.0; @@ -368,8 +370,8 @@ struct timeval *tv1, *tv2; /* Returns true if timestamp t1 is chronologically less than timestamp t2. */ -int sf_timestamp_less_than( t1, t2 ) -struct timeval *t1, *t2; +int +sf_timestamp_less_than( struct timeval *t1, struct timeval *t2 ) { return t1->tv_sec < t2->tv_sec || (t1->tv_sec == t2->tv_sec && @@ -382,10 +384,10 @@ struct timeval *t1, *t2; * negative value if the desired_time is outside the given range. */ -static -long interpolated_position( min_time, min_pos, max_time, max_pos, desired_time ) -struct timeval *min_time, *max_time, *desired_time; -long min_pos, max_pos; +static long +interpolated_position( struct timeval *min_time, long min_pos, + struct timeval *max_time, long max_pos, + struct timeval *desired_time ) { double full_span = timeval_diff( max_time, min_time ); double desired_span = timeval_diff( desired_time, min_time ); @@ -405,46 +407,46 @@ long min_pos, max_pos; * first encountered. */ -static int read_up_to( desired_time ) -struct timeval *desired_time; +static int +read_up_to( pcap_t *p, struct timeval *desired_time ) { - int status = 1; - struct packet_header hdr; - u_char *buf; + struct pcap_pkthdr hdr; + const u_char *buf; long pos; - - buf = (u_char *) malloc( (unsigned) snaplen ); + int status; for ( ; ; ) { struct timeval *timestamp; - pos = ftell( sf_readfile ); - status = sf_next_packet( &hdr, buf, snaplen ); + pos = ftell( pcap_file( p ) ); + buf = pcap_next( p, &hdr ); - if ( status ) + if ( buf == 0 ) { - if ( status == SFERR_EOF ) + if ( feof( pcap_file( p ) ) ) { status = 0; + clearerr( pcap_file( p ) ); break; } - error( "bad status %d in read_up_to()", status ); + error( "bad status in read_up_to()" ); } timestamp = &hdr.ts; if ( ! sf_timestamp_less_than( timestamp, desired_time ) ) + { + status = 1; break; + } } - if ( fseek( sf_readfile, pos, 0 ) < 0 ) + if ( fseek( pcap_file( p ), pos, 0 ) < 0 ) error( "fseek() failed in read_up_to()" ); - free( (char *) buf ); - - return status; + return (status); } @@ -462,18 +464,19 @@ struct timeval *desired_time; * a valid packet. */ -int sf_find_packet( min_time, min_pos, max_time, max_pos, desired_time ) -struct timeval *min_time, *max_time; -long min_pos, max_pos; -struct timeval *desired_time; +int +sf_find_packet( pcap_t *p, + struct timeval *min_time, long min_pos, + struct timeval *max_time, long max_pos, + struct timeval *desired_time ) { int status = 1; struct timeval min_time_copy, max_time_copy; - unsigned num_bytes = MAX_BYTES_FOR_DEFINITE_HEADER; + u_int num_bytes = MAX_BYTES_FOR_DEFINITE_HEADER; int num_bytes_read; long desired_pos, present_pos; u_char *buf, *hdrpos; - struct packet_header hdr; + struct pcap_pkthdr hdr; buf = (u_char *) malloc( num_bytes ); if ( ! buf ) @@ -498,12 +501,12 @@ struct timeval *desired_time; break; } - present_pos = ftell( sf_readfile ); + present_pos = ftell( pcap_file( p ) ); if ( present_pos <= desired_pos && desired_pos - present_pos < STRAIGHT_SCAN_THRESHOLD ) { /* we're close enough to just blindly read ahead */ - status = read_up_to( desired_time ); + status = read_up_to( p, desired_time ); break; } @@ -514,11 +517,11 @@ struct timeval *desired_time; if ( desired_pos < min_pos ) desired_pos = min_pos; - if ( fseek( sf_readfile, desired_pos, 0 ) < 0 ) + if ( fseek( pcap_file( p ), desired_pos, 0 ) < 0 ) error( "fseek() failed in sf_find_packet()" ); num_bytes_read = - fread( (char *) buf, 1, num_bytes, sf_readfile ); + fread( (char *) buf, 1, num_bytes, pcap_file( p ) ); if ( num_bytes_read == 0 ) /* This shouldn't ever happen because we try to @@ -527,7 +530,7 @@ struct timeval *desired_time; */ error( "fread() failed in sf_find_packet()" ); - if ( find_header( buf, num_bytes, min_time->tv_sec, + if ( find_header( p, buf, num_bytes, min_time->tv_sec, max_time->tv_sec, &hdrpos, &hdr ) != HEADER_DEFINITELY ) error( "can't find header at position %ld in dump file", @@ -537,7 +540,7 @@ struct timeval *desired_time; desired_pos += (hdrpos - buf); /* Seek to the beginning of the header. */ - if ( fseek( sf_readfile, desired_pos, 0 ) < 0 ) + if ( fseek( pcap_file( p ), desired_pos, 0 ) < 0 ) error( "fseek() failed in sf_find_packet()" ); if ( sf_timestamp_less_than( &hdr.ts, desired_time ) ) diff --git a/usr.sbin/tcpdump/tcpslice/tcpslice.1 b/usr.sbin/tcpdump/tcpslice/tcpslice.1 index 42fb30b..b130f2c 100644 --- a/usr.sbin/tcpdump/tcpslice/tcpslice.1 +++ b/usr.sbin/tcpdump/tcpslice/tcpslice.1 @@ -1,4 +1,4 @@ -.\" @(#) $Header: /home/ncvs/src/usr.sbin/tcpdump/tcpslice/tcpslice.1,v 1.1.1.1 1993/06/12 14:42:16 rgrimes Exp $ (LBL) +.\" @(#) $Header: tcpslice.1,v 1.2 91/10/16 11:42:46 vern Exp $ (LBL) .\" .\" Copyright (c) 1988-1990 The Regents of the University of California. .\" All rights reserved. @@ -45,7 +45,7 @@ tcpslice \- extract pieces of and/or glue together tcpdump files .LP .I Tcpslice is a program for extracting portions of packet-trace files generated using -\fItcpdump(1)\fP's +\fItcpdump(l)\fP's .B \-w flag. It can also be used to glue together several such files, as discussed @@ -222,7 +222,7 @@ format discussed above. .B \-w Direct the output to \fIfile\fR rather than \fIstdout\fP. .SH "SEE ALSO" -tcpdump(1) +tcpdump(l) .SH AUTHOR Vern Paxson (vern@ee.lbl.gov), of Lawrence Berkeley Laboratory, University of California, Berkeley, CA. diff --git a/usr.sbin/tcpdump/tcpslice/tcpslice.c b/usr.sbin/tcpdump/tcpslice/tcpslice.c index b5b6eea..5be4b87 100644 --- a/usr.sbin/tcpdump/tcpslice/tcpslice.c +++ b/usr.sbin/tcpdump/tcpslice/tcpslice.c @@ -22,43 +22,20 @@ char copyright[] = "@(#) Copyright (c) 1987-1990 The Regents of the University of California.\nAll rights reserved.\n"; static char rcsid[] = - "@(#)$Header: tcpslice.c,v 1.10 92/06/02 17:57:44 mccanne Exp $ (LBL)"; + "@(#)$Header: tcpslice.c,v 1.13 93/11/18 13:12:02 vern Exp $ (LBL)"; #endif /* * tcpslice - extract pieces of and/or glue together tcpdump files */ -#include <stdio.h> -#include <ctype.h> -#include <string.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/timeb.h> -#include <netinet/in.h> -#include <varargs.h> - -#include "savefile.h" -#include "version.h" - +#include "tcpslice.h" int tflag = 0; /* global that util routines are sensitive to */ +int fddipad; /* XXX: libpcap needs this global */ char *program_name; -long thiszone; /* gmt to local correction in trace file */ - -/* Length of saved portion of packet. */ -int snaplen; - -/* Length of saved portion of data past link level protocol. */ -int snapdlen; - -/* Precision of clock used to generate trace file. */ -int precision; - -static int linkinfo; - /* Style in which to print timestamps; RAW is "secs.usecs"; READABLE is * ala the Unix "date" tool; and PARSEABLE is tcpslice's custom format, * designed to be easy to parse. The default is RAW. @@ -66,25 +43,28 @@ static int linkinfo; enum stamp_styles { TIMESTAMP_RAW, TIMESTAMP_READABLE, TIMESTAMP_PARSEABLE }; enum stamp_styles timestamp_style = TIMESTAMP_RAW; +#ifndef __FreeBSD__ +extern int getopt( int argc, char **argv, char *optstring ); +#endif -time_t gwtm2secs( /* struct tm *tmp */ ); - +int is_timestamp( char *str ); +long local_time_zone(long timestamp); +struct timeval parse_time(char *time_string, struct timeval base_time); +void fill_tm(char *time_string, int is_delta, struct tm *t, time_t *usecs_addr); +void get_file_range( char filename[], pcap_t **p, + struct timeval *first_time, struct timeval *last_time ); +struct timeval first_packet_time(char filename[], pcap_t **p_addr); +void extract_slice(char filename[], char write_file_name[], + struct timeval *start_time, struct timeval *stop_time); +char *timestamp_to_string(struct timeval *timestamp); +void dump_times(pcap_t **p, char filename[]); +void usage(void); -long local_time_zone( /* timestamp */ ); -struct timeval parse_time(/* time_string, base_time*/); -void fill_tm(/* time_string, is_delta, t, usecs_addr */); -void get_file_range( /* filename, first_time, last_time */ ); -struct timeval first_packet_time(/* filename */); -void extract_slice(/* filename, start_time, stop_time */); -char *timestamp_to_string( /* timestamp */ ); -void dump_times(/* filename */); -void usage(); +pcap_dumper_t *dumper = 0; int -main(argc, argv) - int argc; - char **argv; +main(int argc, char **argv) { int op; int dump_flag = 0; @@ -93,6 +73,7 @@ main(argc, argv) char *stop_time_string = 0; char *write_file_name = "-"; /* default is stdout */ struct timeval first_time, start_time, stop_time; + pcap_t *pcap; extern char *optarg; extern int optind, opterr; @@ -151,8 +132,8 @@ main(argc, argv) error("at least one input file must be given"); - first_time = first_packet_time(argv[optind]); - fclose( sf_readfile ); + first_time = first_packet_time(argv[optind], &pcap); + pcap_close(pcap); if (start_time_string) @@ -172,9 +153,9 @@ main(argc, argv) if (report_times) { for (; optind < argc; ++optind) - dump_times(argv[optind]); + dump_times(&pcap, argv[optind]); } - + if (dump_flag) { printf( "start\t%s\nstop\t%s\n", timestamp_to_string( &start_time ), @@ -186,13 +167,9 @@ main(argc, argv) isatty( fileno(stdout) ) ) error("stdout is a terminal; redirect or use -w"); - sf_write_init(write_file_name, linkinfo, thiszone, snaplen, - precision); - for (; optind < argc; ++optind) - extract_slice(argv[optind], &start_time, &stop_time); - - fclose( sf_writefile ); + extract_slice(argv[optind], write_file_name, + &start_time, &stop_time); } return 0; @@ -202,8 +179,7 @@ main(argc, argv) /* Returns non-zero if a string matches the format for a timestamp, * 0 otherwise. */ -int is_timestamp( str ) -char *str; +int is_timestamp( char *str ) { while ( isdigit(*str) || *str == '.' ) ++str; @@ -215,8 +191,7 @@ char *str; /* Return the correction in seconds for the local time zone with respect * to Greenwich time. */ -long local_time_zone(timestamp) -long timestamp; +long local_time_zone(long timestamp) { struct timeval now; struct timezone tz; @@ -240,9 +215,7 @@ long timestamp; */ struct timeval -parse_time(time_string, base_time) - char *time_string; - struct timeval base_time; +parse_time(char *time_string, struct timeval base_time) { struct tm *bt = localtime((time_t *) &base_time.tv_sec); struct tm t; @@ -351,11 +324,7 @@ parse_time(time_string, base_time) * of microseconds, if any. */ void -fill_tm(time_string, is_delta, t, usecs_addr) - char *time_string; - int is_delta; /* if true, add times in instead of replacing */ - struct tm *t; /* tm struct to be filled from time_string */ - time_t *usecs_addr; +fill_tm(char *time_string, int is_delta, struct tm *t, time_t *usecs_addr) { char *t_start, *t_stop, format_ch; int val; @@ -433,17 +402,16 @@ fill_tm(time_string, is_delta, t, usecs_addr) * last packets in the given file. */ void -get_file_range( filename, first_time, last_time ) - char filename[]; - struct timeval *first_time; - struct timeval *last_time; +get_file_range( char filename[], pcap_t **p, + struct timeval *first_time, struct timeval *last_time ) { - *first_time = first_packet_time( filename ); + *first_time = first_packet_time( filename, p ); - if ( ! sf_find_end( first_time, last_time ) ) + if ( ! sf_find_end( *p, first_time, last_time ) ) error( "couldn't find final packet in file %s", filename ); } +int snaplen; /* Returns the timestamp of the first packet in the given tcpdump save * file, which as a side-effect is initialized for further save-file @@ -451,66 +419,70 @@ get_file_range( filename, first_time, last_time ) */ struct timeval -first_packet_time(filename) - char filename[]; +first_packet_time(char filename[], pcap_t **p_addr) { - struct packet_header hdr; - u_char *buf; + struct pcap_pkthdr hdr; + pcap_t *p; + char errbuf[PCAP_ERRBUF_SIZE]; - if (sf_read_init(filename, &linkinfo, &thiszone, &snaplen, &precision)) - error( "bad tcpdump file %s", filename ); + p = *p_addr = pcap_open_offline(filename, errbuf); + if (! p) + error( "bad tcpdump file %s: %s", filename, errbuf ); - buf = (u_char *)malloc((unsigned)snaplen); + snaplen = pcap_snapshot( p ); - if (sf_next_packet(&hdr, buf, snaplen)) + if (pcap_next(p, &hdr) == 0) error( "bad status reading first packet in %s", filename ); - free((char *)buf); - return hdr.ts; } /* Extract from the given file all packets with timestamps between * the two time values given (inclusive). These packets are written - * to the save file output set up by a previous call to sf_write_init(). + * to the save file given by write_file_name. + * * Upon return, start_time is adjusted to reflect a time just after * that of the last packet written to the output. */ void -extract_slice(filename, start_time, stop_time) - char filename[]; - struct timeval *start_time; - struct timeval *stop_time; +extract_slice(char filename[], char write_file_name[], + struct timeval *start_time, struct timeval *stop_time) { long start_pos, stop_pos; struct timeval file_start_time, file_stop_time; - int status; - struct packet_header hdr; - u_char *buf; - - - if (sf_read_init(filename, &linkinfo, &thiszone, &snaplen, &precision)) - error( "bad tcpdump file %s", filename ); + struct pcap_pkthdr hdr; + pcap_t *p; + char errbuf[PCAP_ERRBUF_SIZE]; - buf = (u_char *)malloc((unsigned)snaplen); + p = pcap_open_offline(filename, errbuf); + if (! p) + error( "bad tcpdump file %s: %s", filename, errbuf ); - start_pos = ftell( sf_readfile ); + snaplen = pcap_snapshot( p ); + start_pos = ftell( pcap_file( p ) ); + if ( ! dumper ) + { + dumper = pcap_dump_open(p, write_file_name); + if ( ! dumper ) + error( "error creating output file %s: ", + write_file_name, pcap_geterr( p ) ); + } - if ( (status = sf_next_packet( &hdr, buf, snaplen )) ) - error( "bad status %d reading packet in %s", - status, filename ); + if (pcap_next(p, &hdr) == 0) + error( "error reading packet in %s: ", + filename, pcap_geterr( p ) ); file_start_time = hdr.ts; - if ( ! sf_find_end( &file_start_time, &file_stop_time ) ) + if ( ! sf_find_end( p, &file_start_time, &file_stop_time ) ) error( "problems finding end packet of file %s", filename ); - stop_pos = ftell( sf_readfile ); + stop_pos = ftell( pcap_file( p ) ); /* sf_find_packet() requires that the time it's passed as its last @@ -524,20 +496,23 @@ extract_slice(filename, start_time, stop_time) return; /* there aren't any packets of interest in the file */ - sf_find_packet( &file_start_time, start_pos, + sf_find_packet( p, &file_start_time, start_pos, &file_stop_time, stop_pos, start_time ); for ( ; ; ) { struct timeval *timestamp; - status = sf_next_packet( &hdr, buf, snaplen ); + const u_char *pkt = pcap_next( p, &hdr ); - if ( status ) + if ( pkt == 0 ) { +#ifdef notdef + int status; if ( status != SFERR_EOF ) error( "bad status %d reading packet in %s", status, filename ); +#endif break; } @@ -551,8 +526,8 @@ extract_slice(filename, start_time, stop_time) */ break; - sf_write( buf, timestamp, (int) hdr.len, - (int) hdr.caplen ); + pcap_dump((u_char *) dumper, &hdr, pkt); + *start_time = *timestamp; /* We know that each packet is guaranteed to have @@ -564,8 +539,7 @@ extract_slice(filename, start_time, stop_time) } } - fclose( sf_readfile ); - free( (char *) buf ); + pcap_close( p ); } @@ -578,8 +552,7 @@ extract_slice(filename, start_time, stop_time) */ char * -timestamp_to_string(timestamp) - struct timeval *timestamp; +timestamp_to_string(struct timeval *timestamp) { struct tm *t; #define NUM_BUFFERS 2 @@ -593,7 +566,7 @@ timestamp_to_string(timestamp) switch ( timestamp_style ) { case TIMESTAMP_RAW: - sprintf( buf, "%d.%d", timestamp->tv_sec, timestamp->tv_usec ); + sprintf(buf, "%ld.%ld", timestamp->tv_sec, timestamp->tv_usec); break; case TIMESTAMP_READABLE: @@ -604,7 +577,7 @@ timestamp_to_string(timestamp) case TIMESTAMP_PARSEABLE: t = localtime((time_t *) ×tamp->tv_sec); - sprintf( buf, "%02dy%02dm%02dd%02dh%02dm%02ds%06du", + sprintf( buf, "%02dy%02dm%02dd%02dh%02dm%02ds%06ldu", t->tm_year, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, timestamp->tv_usec ); break; @@ -620,12 +593,11 @@ timestamp_to_string(timestamp) */ void -dump_times(filename) - char filename[]; +dump_times(pcap_t **p, char filename[]) { struct timeval first_time, last_time; - get_file_range( filename, &first_time, &last_time ); + get_file_range( filename, p, &first_time, &last_time ); printf( "%s\t%s\t%s\n", filename, @@ -634,7 +606,7 @@ dump_times(filename) } void -usage() +usage(void) { (void)fprintf(stderr, "tcpslice for tcpdump version %d.%d\n", VERSION_MAJOR, VERSION_MINOR); @@ -643,3 +615,4 @@ usage() exit(-1); } + diff --git a/usr.sbin/tcpdump/tcpslice/tcpslice.h b/usr.sbin/tcpdump/tcpslice/tcpslice.h new file mode 100644 index 0000000..14c69a7 --- /dev/null +++ b/usr.sbin/tcpdump/tcpslice/tcpslice.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1987-1990 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. + */ + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/file.h> +#include <sys/stat.h> + +#include <net/bpf.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 "pcap.h" +#include "version.h" + + +time_t gwtm2secs( struct tm *tm ); + +int sf_find_end( struct pcap *p, struct timeval *first_timestamp, + struct timeval *last_timestamp ); +int sf_timestamp_less_than( struct timeval *t1, struct timeval *t2 ); +int sf_find_packet( struct pcap *p, + struct timeval *min_time, long min_pos, + struct timeval *max_time, long max_pos, + struct timeval *desired_time ); + +void error(const char *fmt, ...); diff --git a/usr.sbin/tcpdump/tcpslice/util.c b/usr.sbin/tcpdump/tcpslice/util.c new file mode 100644 index 0000000..3e7cb49 --- /dev/null +++ b/usr.sbin/tcpdump/tcpslice/util.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1988-1990 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.2 93/11/18 13:11:07 vern Exp $ (LBL)"; +#endif + +#include "tcpslice.h" + +/* VARARGS */ +void +#if __STDC__ +error(const char *fmt, ...) +#else +error(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; + + (void)fprintf(stderr, "tcpslice: "); +#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 */ +} |