aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorBill Fenner <fenner@FreeBSD.org>2001-04-03 07:50:46 +0000
committerBill Fenner <fenner@FreeBSD.org>2001-04-03 07:50:46 +0000
commit943ee2b15a8e008b2087495c2986bac507caef79 (patch)
tree862679b25d0bf745e54c1775c59b1fb4e25e8e6e /contrib
parent4df395f42edf94a848c3a2ef908b406d888207d6 (diff)
downloadsrc-943ee2b15a8e008b2087495c2986bac507caef79.tar.gz
src-943ee2b15a8e008b2087495c2986bac507caef79.zip
Merge tcpdump 3.6.2
Notes
Notes: svn path=/head/; revision=75118
Diffstat (limited to 'contrib')
-rw-r--r--contrib/tcpdump/addrtoname.c24
-rw-r--r--contrib/tcpdump/ethertype.h28
-rw-r--r--contrib/tcpdump/interface.h95
-rw-r--r--contrib/tcpdump/nfs.h4
-rw-r--r--contrib/tcpdump/nfsfh.h3
-rw-r--r--contrib/tcpdump/parsenfsfh.c23
-rw-r--r--contrib/tcpdump/ppp.h11
-rw-r--r--contrib/tcpdump/print-arp.c83
-rw-r--r--contrib/tcpdump/print-atalk.c92
-rw-r--r--contrib/tcpdump/print-atm.c29
-rw-r--r--contrib/tcpdump/print-bootp.c101
-rw-r--r--contrib/tcpdump/print-domain.c407
-rw-r--r--contrib/tcpdump/print-ether.c74
-rw-r--r--contrib/tcpdump/print-fddi.c31
-rw-r--r--contrib/tcpdump/print-icmp.c244
-rw-r--r--contrib/tcpdump/print-ip.c235
-rw-r--r--contrib/tcpdump/print-ip6.c65
-rw-r--r--contrib/tcpdump/print-ipx.c14
-rw-r--r--contrib/tcpdump/print-isoclns.c43
-rw-r--r--contrib/tcpdump/print-llc.c90
-rw-r--r--contrib/tcpdump/print-nfs.c815
-rw-r--r--contrib/tcpdump/print-ntp.c9
-rw-r--r--contrib/tcpdump/print-null.c100
-rw-r--r--contrib/tcpdump/print-pim.c18
-rw-r--r--contrib/tcpdump/print-ppp.c1299
-rw-r--r--contrib/tcpdump/print-sl.c76
-rw-r--r--contrib/tcpdump/print-sunrpc.c72
-rw-r--r--contrib/tcpdump/print-token.c2
-rw-r--r--contrib/tcpdump/print-udp.c241
-rw-r--r--contrib/tcpdump/tcpdump.1410
-rw-r--r--contrib/tcpdump/tcpdump.c121
31 files changed, 3253 insertions, 1606 deletions
diff --git a/contrib/tcpdump/addrtoname.c b/contrib/tcpdump/addrtoname.c
index c1f220821c08..e53f41ee09fe 100644
--- a/contrib/tcpdump/addrtoname.c
+++ b/contrib/tcpdump/addrtoname.c
@@ -25,7 +25,7 @@
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.64 1999/11/21 09:36:44 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.69.2.1 2001/01/17 18:29:58 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -36,17 +36,13 @@ static const char rcsid[] =
#include <sys/socket.h>
#include <sys/time.h>
-#if __STDC__
struct mbuf;
struct rtentry;
-#endif
#include <net/if.h>
#include <netinet/in.h>
-#include <net/ethernet.h>
-
-#ifdef INET6
-#include <netinet/ip6.h>
+#ifdef HAVE_NETINET_IF_ETHER_H
+#include <netinet/if_ether.h>
#endif
#include <arpa/inet.h>
@@ -55,12 +51,6 @@ struct rtentry;
#include <netdb.h>
#include <pcap.h>
#include <pcap-namedb.h>
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
#include <signal.h>
#include <stdio.h>
#include <string.h>
@@ -497,7 +487,6 @@ protoid_string(register const u_char *pi)
char *
llcsap_string(u_char sap)
{
- register char *cp;
register struct hnamemem *tp;
register u_int32_t i = sap;
char buf[sizeof("sap 00")];
@@ -509,12 +498,7 @@ llcsap_string(u_char sap)
tp->addr = i;
tp->nxt = newhnamemem();
- cp = buf;
- (void)strcpy(cp, "sap ");
- cp += strlen(cp);
- *cp++ = hex[sap >> 4 & 0xf];
- *cp++ = hex[sap & 0xf];
- *cp++ = '\0';
+ snprintf(buf, sizeof(buf), "sap %02x", sap & 0xff);
tp->name = savestr(buf);
return (tp->name);
}
diff --git a/contrib/tcpdump/ethertype.h b/contrib/tcpdump/ethertype.h
index 56bfa3c69ed1..4211ba9cd797 100644
--- a/contrib/tcpdump/ethertype.h
+++ b/contrib/tcpdump/ethertype.h
@@ -18,12 +18,34 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.7.2.1 2000/01/29 22:00:12 fenner Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.12 2000/09/23 08:03:30 guy Exp $ (LBL)
* $FreeBSD$
*/
-/* Types missing from some systems */
+/*
+ * Ethernet types.
+ *
+ * We wrap the declarations with #ifdef, so that if a file includes
+ * <netinet/if_ether.h>, which may declare some of these, we don't
+ * get a bunch of complaints from the C compiler about redefinitions
+ * of these values.
+ *
+ * We declare all of them here so that no file has to include
+ * <netinet/if_ether.h> if all it needs are ETHERTYPE_ values.
+ */
+#ifndef ETHERTYPE_PUP
+#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
+#endif
+#ifndef ETHERTYPE_IP
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#endif
+#ifndef ETHERTYPE_ARP
+#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
+#endif
+#ifndef ETHERTYPE_REVARP
+#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
+#endif
#ifndef ETHERTYPE_NS
#define ETHERTYPE_NS 0x0600
#endif
@@ -76,7 +98,7 @@
#define ETHERTYPE_8021Q 0x8100
#endif
#ifndef ETHERTYPE_IPX
-#define ETHERTYPE_IPX 0x8137
+#define ETHERTYPE_IPX 0x8137
#endif
#ifndef ETHERTYPE_IPV6
#define ETHERTYPE_IPV6 0x86dd
diff --git a/contrib/tcpdump/interface.h b/contrib/tcpdump/interface.h
index f9081bb7f896..2459764d7b69 100644
--- a/contrib/tcpdump/interface.h
+++ b/contrib/tcpdump/interface.h
@@ -18,17 +18,43 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.118 1999/12/22 15:44:09 itojun Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.149 2001/01/02 22:47:06 guy Exp $ (LBL)
* $FreeBSD$
*/
#ifndef tcpdump_interface_h
#define tcpdump_interface_h
-#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
+#endif
+
+/* snprintf et al */
+
+#include <stdarg.h>
+
+#if !defined(HAVE_SNPRINTF)
+int snprintf (char *str, size_t sz, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+#endif
+
+#if !defined(HAVE_VSNPRINTF)
+int vsnprintf (char *str, size_t sz, const char *format, va_list ap)
+ __attribute__((format (printf, 3, 0)));
+#endif
+
+#ifndef HAVE_STRLCAT
+extern size_t strlcat (char *, const char *, size_t);
+#endif
+#ifndef HAVE_STRLCPY
+extern size_t strlcpy (char *, const char *, size_t);
+#endif
struct tok {
int v; /* value */
@@ -46,11 +72,11 @@ extern int Rflag; /* print sequence # field in AH/ESP*/
extern int sflag; /* use the libsmi to translate OIDs */
extern int Sflag; /* print raw TCP sequence numbers */
extern int tflag; /* print packet arrival time */
+extern int uflag; /* Print undecoded NFS handles */
extern int vflag; /* verbose */
extern int xflag; /* print packet in hex */
extern int Xflag; /* print packet in hex/ascii */
-extern char *ahsecret;
extern char *espsecret;
extern int packettype; /* as specified by -T */
@@ -60,6 +86,7 @@ extern int packettype; /* as specified by -T */
#define PT_RTP 4 /* Real-Time Applications protocol */
#define PT_RTCP 5 /* Real-Time Applications control protocol */
#define PT_SNMP 6 /* Simple Network Management Protocol */
+#define PT_CNFP 7 /* Cisco NetFlow protocol */
#ifndef min
#define min(a,b) ((a)>(b)?(b):(a))
@@ -85,30 +112,8 @@ extern int packettype; /* as specified by -T */
#define LITTLE_ENDIAN 1234
#endif
-#ifdef ETHER_HEADER_HAS_EA
-#define ESRC(ep) ((ep)->ether_shost.ether_addr_octet)
-#define EDST(ep) ((ep)->ether_dhost.ether_addr_octet)
-#else
#define ESRC(ep) ((ep)->ether_shost)
#define EDST(ep) ((ep)->ether_dhost)
-#endif
-
-#ifdef ETHER_ARP_HAS_X
-#define SHA(ap) ((ap)->arp_xsha)
-#define THA(ap) ((ap)->arp_xtha)
-#define SPA(ap) ((ap)->arp_xspa)
-#define TPA(ap) ((ap)->arp_xtpa)
-#else
-#ifdef ETHER_ARP_HAS_EA
-#define SHA(ap) ((ap)->arp_sha.ether_addr_octet)
-#define THA(ap) ((ap)->arp_tha.ether_addr_octet)
-#else
-#define SHA(ap) ((ap)->arp_sha)
-#define THA(ap) ((ap)->arp_tha)
-#endif
-#define SPA(ap) ((ap)->arp_spa)
-#define TPA(ap) ((ap)->arp_tpa)
-#endif
#ifndef NTOHL
#define NTOHL(x) (x) = ntohl(x)
@@ -139,9 +144,7 @@ extern const u_char *snapend;
/* Bail if "var" was not captured */
#define TCHECK(var) TCHECK2(var, sizeof(var))
-#ifdef __STDC__
struct timeval;
-#endif
extern void ts_print(const struct timeval *);
extern void relts_print(int);
@@ -153,15 +156,16 @@ extern char *dnaddr_string(u_short);
extern void wrapup(int);
-#if __STDC__
-extern __dead void error(const char *, ...)
- __attribute__((volatile, format (printf, 1, 2)));
+extern void error(const char *, ...)
+ __attribute__((noreturn, format (printf, 1, 2)));
extern void warning(const char *, ...) __attribute__ ((format (printf, 1, 2)));
-#endif
extern char *read_infile(char *);
extern char *copy_argv(char **);
+extern void safeputchar(int);
+extern void safeputs(const char *);
+
extern char *isonsap_string(const u_char *);
extern char *llcsap_string(u_char);
extern char *protoid_string(const u_char *);
@@ -170,24 +174,24 @@ extern char *dnnum_string(u_short);
/* The printer routines. */
-#ifdef __STDC__
struct pcap_pkthdr;
-#endif
extern void ascii_print_with_offset(const u_char *, u_int, u_int);
extern void ascii_print(const u_char *, u_int);
extern void hex_print_with_offset(const u_char *, u_int, u_int);
extern void telnet_print(const u_char *, u_int);
extern void hex_print(const u_char *, u_int);
-extern int ether_encap_print(u_short, const u_char *, u_int, u_int);
+extern int ether_encap_print(u_short, const u_char *, u_int, u_int, u_short *);
extern int llc_print(const u_char *, u_int, u_int, const u_char *,
- const u_char *);
+ const u_char *, u_short *);
extern void aarp_print(const u_char *, u_int);
extern void arp_print(const u_char *, u_int, u_int);
extern void atalk_print(const u_char *, u_int);
extern void atm_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
extern void bootp_print(const u_char *, u_int, u_short, u_short);
extern void bgp_print(const u_char *, int);
+extern void bxxp_print(const u_char *, u_int);
+extern void cnfp_print(const u_char *cp, u_int len, const u_char *bp);
extern void decnet_print(const u_char *, u_int, u_int);
extern void default_print(const u_char *, u_int);
extern void default_print_unaligned(const u_char *, u_int);
@@ -200,12 +204,15 @@ extern void token_if_print(u_char *, const struct pcap_pkthdr *,
extern void fddi_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
extern void gre_print(const u_char *, u_int);
extern void icmp_print(const u_char *, u_int, const u_char *);
+extern void igmp_print(const u_char *, u_int, const u_char *);
extern void igrp_print(const u_char *, u_int, const u_char *);
extern void ip_print(const u_char *, u_int);
+extern void ipN_print(const u_char *, u_int);
extern void ipx_print(const u_char *, u_int);
extern void isoclns_print(const u_char *, u_int, u_int, const u_char *,
const u_char *);
extern void krb_print(const u_char *, u_int);
+extern void llap_print(const u_char *, u_int);
extern void nfsreply_print(const u_char *, u_int, const u_char *);
extern void nfsreq_print(const u_char *, u_int, const u_char *);
extern void ns_print(const u_char *, u_int);
@@ -217,7 +224,10 @@ extern void cisco_autorp_print(const u_char *, u_int);
extern void mobile_print(const u_char *, u_int);
extern void pim_print(const u_char *, u_int);
extern void pppoe_print(const u_char *, u_int);
+extern void ppp_print(register const u_char *, u_int);
extern void ppp_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern void ppp_hdlc_if_print(u_char *, const struct pcap_pkthdr *,
+ const u_char *);
extern void ppp_bsdos_if_print(u_char *, const struct pcap_pkthdr *,
const u_char *);
extern int vjc_print(register const char *, register u_int, u_short);
@@ -230,18 +240,20 @@ extern void sl_bsdos_if_print(u_char *, const struct pcap_pkthdr *,
const u_char *);
extern void chdlc_if_print(u_char *, const struct pcap_pkthdr *,
const u_char *);
+extern void sll_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
extern void snmp_print(const u_char *, u_int);
extern void sunrpcrequest_print(const u_char *, u_int, const u_char *);
-extern void tcp_print(const u_char *, u_int, const u_char *);
+extern void tcp_print(const u_char *, u_int, const u_char *, int);
extern void tftp_print(const u_char *, u_int);
-extern void udp_print(const u_char *, u_int, const u_char *);
+extern void timed_print(const u_char *, u_int);
+extern void udp_print(const u_char *, u_int, const u_char *, int);
extern void wb_print(const void *, u_int);
extern int ah_print(register const u_char *, register const u_char *);
extern int esp_print(register const u_char *, register const u_char *, int *);
extern void isakmp_print(const u_char *, u_int, const u_char *);
extern int ipcomp_print(register const u_char *, register const u_char *, int *);
extern void rx_print(register const u_char *, int, int, int, u_char *);
-extern void netbeui_print(const u_char *, const u_char *);
+extern void netbeui_print(u_short, const u_char *, const u_char *);
extern void ipx_netbios_print(const u_char *, const u_char *);
extern void nbt_tcp_print(const u_char *, int);
extern void nbt_udp137_print(const u_char *data, int);
@@ -250,6 +262,11 @@ extern char *smb_errstr(int, int);
extern void print_data(const unsigned char *, int);
extern void l2tp_print(const u_char *, u_int);
extern void lcp_print(const u_char *, u_int);
+extern void vrrp_print(const u_char *bp, u_int len, int ttl);
+extern void cdp_print(const u_char *p, u_int length, u_int caplen,
+ const u_char *esrc, const u_char *edst);
+extern void stp_print(const u_char *p, u_int length);
+extern void radius_print(const u_char *, u_int);
#ifdef INET6
extern void ip6_print(const u_char *, int);
@@ -261,6 +278,6 @@ extern void icmp6_print(const u_char *, const u_char *);
extern void ripng_print(const u_char *, int);
extern int rt6_print(const u_char *, const u_char *);
extern void ospf6_print(const u_char *, u_int);
-extern void dhcp6_print(const u_char *, u_int, u_short, u_short);
+extern void dhcp6_print(const u_char *, u_int, u_int16_t, u_int16_t);
#endif /*INET6*/
extern u_short in_cksum(const u_short *addr, register int len, u_short csum);
diff --git a/contrib/tcpdump/nfs.h b/contrib/tcpdump/nfs.h
index 0887148dad13..074d5ee86b7a 100644
--- a/contrib/tcpdump/nfs.h
+++ b/contrib/tcpdump/nfs.h
@@ -246,7 +246,7 @@
/* File types */
typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5,
- NFSOCK=6, NFFIFO=7 } nfstype;
+ NFSOCK=6, NFFIFO=7 } nfs_type;
/* Structs for common parts of the rpc's */
/*
@@ -295,7 +295,7 @@ typedef struct nfs_uquad nfsuint64;
*/
union nfs_quadconvert {
u_int32_t lval[2];
- u_quad_t qval;
+ u_int64_t qval;
};
typedef union nfs_quadconvert nfsquad_t;
diff --git a/contrib/tcpdump/nfsfh.h b/contrib/tcpdump/nfsfh.h
index 8a4541ecdc6f..97e56c137043 100644
--- a/contrib/tcpdump/nfsfh.h
+++ b/contrib/tcpdump/nfsfh.h
@@ -1,5 +1,5 @@
/*
- * $Header: /tcpdump/master/tcpdump/nfsfh.h,v 1.8 1999/12/15 06:49:05 fenner Exp $
+ * $Header: /tcpdump/master/tcpdump/nfsfh.h,v 1.9 2000/06/01 01:16:36 assar Exp $
*
* nfsfh.h - NFS file handle definitions (for portable use)
*
@@ -26,6 +26,7 @@ typedef struct {
*/
typedef struct {
my_devt Fsid_dev; /* XXX avoid name conflict with AIX */
+ char Opaque_Handle[2 * 32 + 1];
u_int32_t fsid_code;
} my_fsid;
diff --git a/contrib/tcpdump/parsenfsfh.c b/contrib/tcpdump/parsenfsfh.c
index c59ad6aa317a..6712e49f87e8 100644
--- a/contrib/tcpdump/parsenfsfh.c
+++ b/contrib/tcpdump/parsenfsfh.c
@@ -11,7 +11,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/parsenfsfh.c,v 1.16 1999/11/21 09:36:47 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/parsenfsfh.c,v 1.18 2000/07/01 03:39:00 assar Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -22,9 +22,6 @@ static const char rcsid[] =
#include <sys/time.h>
#include <ctype.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
#include <stdio.h>
#include <string.h>
@@ -95,6 +92,7 @@ int ourself; /* true if file handle was generated on this host */
register unsigned char *fhp = (unsigned char *)fh;
u_int32_t temp;
int fhtype = FHT_UNKNOWN;
+ int i;
if (ourself) {
/* File handle generated on this host, no need for guessing */
@@ -372,15 +370,18 @@ int ourself; /* true if file handle was generated on this host */
case FHT_UNKNOWN:
#ifdef DEBUG
- {
- /* XXX debugging */
- int i;
- for (i = 0; i < 32; i++)
- (void)fprintf(stderr, "%x.", fhp[i]);
- (void)fprintf(stderr, "\n");
- }
+ /* XXX debugging */
+ int i;
+ for (i = 0; i < 32; i++)
+ (void)fprintf(stderr, "%x.", fhp[i]);
+ (void)fprintf(stderr, "\n");
#endif
/* XXX for now, give "bogus" values to aid debugging */
+
+ /* Save the actual handle, so it can be display with -u */
+ for (i = 0; i < 32; i++)
+ (void)sprintf(&(fsidp->Opaque_Handle[i*2]), "%.2X", fhp[i]);
+
fsidp->fsid_code = 0;
fsidp->Fsid_dev.Minor = 257;
fsidp->Fsid_dev.Major = 257;
diff --git a/contrib/tcpdump/ppp.h b/contrib/tcpdump/ppp.h
index da79154c7dc7..d55d6ae56d1b 100644
--- a/contrib/tcpdump/ppp.h
+++ b/contrib/tcpdump/ppp.h
@@ -1,4 +1,4 @@
-/* @(#) $Header: /tcpdump/master/tcpdump/ppp.h,v 1.8 1999/11/21 03:43:56 assar Exp $ (LBL) */
+/* @(#) $Header: /tcpdump/master/tcpdump/ppp.h,v 1.11 2000/10/09 01:53:19 guy Exp $ (LBL) */
/*
* Point to Point Protocol (PPP) RFC1331
*
@@ -17,6 +17,8 @@
*
* $FreeBSD$
*/
+#define PPP_HDRLEN 4 /* length of PPP header */
+
#undef PPP_ADDRESS
#define PPP_ADDRESS 0xff /* The address byte value */
#undef PPP_CONTROL
@@ -38,6 +40,7 @@
#define PPP_BRPDU 0x0031 /* Bridging PDU */
#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */
#define PPP_VINES 0x0035 /* Banyan Vines */
+#define PPP_IPV6 0x0057 /* IPv6 */
#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */
#define PPP_LUXCOM 0x0231 /* Luxcom */
@@ -51,9 +54,15 @@
#define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */
#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */
#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */
+#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
+#define PPP_CCP 0x80fd /* Compress Control Protocol */
#define PPP_LCP 0xc021 /* Link Control Protocol */
#define PPP_PAP 0xc023 /* Password Authentication Protocol */
#define PPP_LQM 0xc025 /* Link Quality Monitoring */
#define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */
+#define PPP_BACP 0xc02b /* Bandwidth Allocation Control Protocol */
+#define PPP_BAP 0xc02d /* BAP */
+#define PPP_MP 0xc03d /* Multi-Link */
+
extern struct tok ppptype2str[];
diff --git a/contrib/tcpdump/print-arp.c b/contrib/tcpdump/print-arp.c
index 2af4bc1093e7..ccb93bff8a6c 100644
--- a/contrib/tcpdump/print-arp.c
+++ b/contrib/tcpdump/print-arp.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.44 1999/11/21 09:36:48 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.49 2000/10/10 05:05:07 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -32,29 +32,84 @@ static const char rcsid[] =
#include <sys/param.h>
#include <sys/time.h>
-#include <sys/socket.h>
-
-#if __STDC__
-struct mbuf;
-struct rtentry;
-#endif
-#include <net/if.h>
-#include <net/if_var.h>
#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
#include <stdio.h>
#include <string.h>
#include "interface.h"
#include "addrtoname.h"
+#include "ether.h"
#include "ethertype.h"
#include "extract.h" /* must come after interface.h */
+/*
+ * Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. ARP packets are variable
+ * in size; the arphdr structure defines the fixed-length portion.
+ * Protocol type values are the same as those for 10 Mb/s Ethernet.
+ * It is followed by the variable-sized fields ar_sha, arp_spa,
+ * arp_tha and arp_tpa in that order, according to the lengths
+ * specified. Field names used correspond to RFC 826.
+ */
+struct arphdr {
+ u_short ar_hrd; /* format of hardware address */
+#define ARPHRD_ETHER 1 /* ethernet hardware format */
+#define ARPHRD_IEEE802 6 /* token-ring hardware format */
+#define ARPHRD_FRELAY 15 /* frame relay hardware format */
+ u_short ar_pro; /* format of protocol address */
+ u_char ar_hln; /* length of hardware address */
+ u_char ar_pln; /* length of protocol address */
+ u_short ar_op; /* one of: */
+#define ARPOP_REQUEST 1 /* request to resolve address */
+#define ARPOP_REPLY 2 /* response to previous request */
+#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */
+#define ARPOP_REVREPLY 4 /* response giving protocol address */
+#define ARPOP_INVREQUEST 8 /* request to identify peer */
+#define ARPOP_INVREPLY 9 /* response identifying peer */
+/*
+ * The remaining fields are variable in size,
+ * according to the sizes above.
+ */
+#ifdef COMMENT_ONLY
+ u_char ar_sha[]; /* sender hardware address */
+ u_char ar_spa[]; /* sender protocol address */
+ u_char ar_tha[]; /* target hardware address */
+ u_char ar_tpa[]; /* target protocol address */
+#endif
+};
+
+#define ARP_HDRLEN 8
+
+/*
+ * Ethernet Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. Structure below is adapted
+ * to resolving internet addresses. Field names used correspond to
+ * RFC 826.
+ */
+struct ether_arp {
+ struct arphdr ea_hdr; /* fixed-size header */
+ u_char arp_sha[6]; /* sender hardware address */
+ u_char arp_spa[4]; /* sender protocol address */
+ u_char arp_tha[6]; /* target hardware address */
+ u_char arp_tpa[4]; /* target protocol address */
+};
+#define arp_hrd ea_hdr.ar_hrd
+#define arp_pro ea_hdr.ar_pro
+#define arp_hln ea_hdr.ar_hln
+#define arp_pln ea_hdr.ar_pln
+#define arp_op ea_hdr.ar_op
+
+#define ETHER_ARP_HDRLEN (ARP_HDRLEN + 6 + 4 + 6 + 4)
+
+#define SHA(ap) ((ap)->arp_sha)
+#define THA(ap) ((ap)->arp_tha)
+#define SPA(ap) ((ap)->arp_spa)
+#define TPA(ap) ((ap)->arp_tpa)
+
/* Compatibility */
#ifndef REVARP_REQUEST
#define REVARP_REQUEST 3
@@ -77,7 +132,7 @@ arp_print(register const u_char *bp, u_int length, u_int caplen)
printf("[|arp]");
return;
}
- if (length < sizeof(struct ether_arp)) {
+ if (length < ETHER_ARP_HDRLEN) {
(void)printf("truncated-arp");
default_print((u_char *)ap, length);
return;
diff --git a/contrib/tcpdump/print-atalk.c b/contrib/tcpdump/print-atalk.c
index 2b77ecd35579..195638b114ea 100644
--- a/contrib/tcpdump/print-atalk.c
+++ b/contrib/tcpdump/print-atalk.c
@@ -25,7 +25,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.51 1999/11/21 09:36:48 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.64 2000/10/30 06:22:14 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -36,24 +36,12 @@ static const char rcsid[] =
#include <sys/time.h>
#include <sys/socket.h>
-#if __STDC__
-struct mbuf;
-struct rtentry;
-#endif
-#include <net/if.h>
-
#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <net/ethernet.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
-#include <netinet/tcp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <netdb.h> /* for MAXHOSTNAMELEN on some platforms */
#include "interface.h"
#include "addrtoname.h"
@@ -73,13 +61,13 @@ static struct tok type2str[] = {
};
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];
+ u_int16_t htype, ptype;
+ u_int8_t halen, palen;
+ u_int16_t op;
+ u_int8_t hsaddr[6];
+ u_int8_t psaddr[4];
+ u_int8_t hdaddr[6];
+ u_int8_t pdaddr[4];
};
static char tstr[] = "[|atalk]";
@@ -98,10 +86,10 @@ static void ddp_print(const u_char *, u_int, int, u_short, u_char, u_char);
static const char *ddpskt_string(int);
/*
- * Print AppleTalk Datagram Delivery Protocol packets.
+ * Print AppleTalk LLAP packets.
*/
void
-atalk_print(register const u_char *bp, u_int length)
+llap_print(register const u_char *bp, u_int length)
{
register const struct LAP *lp;
register const struct atDDP *dp;
@@ -165,6 +153,33 @@ atalk_print(register const u_char *bp, u_int length)
}
}
+/*
+ * Print EtherTalk/TokenTalk packets (or FDDITalk, or whatever it's called
+ * when it runs over FDDI; yes, I've seen FDDI captures with AppleTalk
+ * packets in them).
+ */
+void
+atalk_print(register const u_char *bp, u_int length)
+{
+ register const struct atDDP *dp;
+ u_short snet;
+
+ if (length < ddpSize) {
+ (void)printf(" [|ddp %d]", length);
+ return;
+ }
+ dp = (const struct atDDP *)bp;
+ snet = EXTRACT_16BITS(&dp->srcNet);
+ printf("%s.%s", ataddr_string(snet, dp->srcNode),
+ ddpskt_string(dp->srcSkt));
+ printf(" > %s.%s:",
+ ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
+ ddpskt_string(dp->dstSkt));
+ bp += ddpSize;
+ length -= ddpSize;
+ ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
+}
+
/* XXX should probably pass in the snap header and do checks like arp_print() */
void
aarp_print(register const u_char *bp, u_int length)
@@ -194,10 +209,14 @@ aarp_print(register const u_char *bp, u_int length)
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 );
+ (void)printf("len %u op %u htype %u ptype %#x halen %u palen %u",
+ length, ntohs(ap->op), ntohs(ap->htype), ntohs(ap->ptype),
+ ap->halen, ap->palen);
}
+/*
+ * Print AppleTalk Datagram Delivery Protocol packets.
+ */
static void
ddp_print(register const u_char *bp, register u_int length, register int t,
register u_short snet, register u_char snode, u_char skt)
@@ -511,17 +530,19 @@ ataddr_string(u_short atnet, u_char athost)
if (first && (first = 0, !nflag)
&& (fp = fopen("/etc/atalk.names", "r"))) {
char line[256];
- int i1, i2;
+ int i1, i2, i3;
while (fgets(line, sizeof(line), fp)) {
if (line[0] == '\n' || line[0] == 0 || line[0] == '#')
continue;
- if (sscanf(line, "%d.%d %s", &i1, &i2, nambuf) == 3)
+ if (sscanf(line, "%d.%d.%d %256s", &i1, &i2, &i3,
+ nambuf) == 4)
/* got a hostname. */
- i2 |= (i1 << 8);
- else if (sscanf(line, "%d %s", &i1, nambuf) == 2)
+ i3 |= ((i1 << 8) | i2) << 8;
+ else if (sscanf(line, "%d.%d %256s", &i1, &i2,
+ nambuf) == 3)
/* got a net name */
- i2 = (i1 << 8) | 255;
+ i3 = (((i1 << 8) | i2) << 8) | 255;
else
continue;
@@ -545,7 +566,8 @@ ataddr_string(u_short atnet, u_char athost)
if (tp2->addr == i) {
tp->addr = (atnet << 8) | athost;
tp->nxt = newhnamemem();
- (void)snprintf(nambuf, sizeof(nambuf), "%s.%d", tp2->name, athost);
+ (void)snprintf(nambuf, sizeof(nambuf), "%s.%d",
+ tp2->name, athost);
tp->name = savestr(nambuf);
return (tp->name);
}
@@ -553,9 +575,11 @@ ataddr_string(u_short atnet, u_char athost)
tp->addr = (atnet << 8) | athost;
tp->nxt = newhnamemem();
if (athost != 255)
- (void)sprintf(nambuf, "%d.%d", atnet, athost);
+ (void)snprintf(nambuf, sizeof(nambuf), "%d.%d.%d",
+ atnet >> 8, atnet & 0xff, athost);
else
- (void)sprintf(nambuf, "%d", atnet);
+ (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet >> 8,
+ atnet & 0xff);
tp->name = savestr(nambuf);
return (tp->name);
@@ -575,7 +599,7 @@ ddpskt_string(register int skt)
static char buf[8];
if (nflag) {
- (void)sprintf(buf, "%d", skt);
+ (void)snprintf(buf, sizeof(buf), "%d", skt);
return (buf);
}
return (tok2str(skt2str, "%d", skt));
diff --git a/contrib/tcpdump/print-atm.c b/contrib/tcpdump/print-atm.c
index 8fb95e786dc0..95f24b2f61bc 100644
--- a/contrib/tcpdump/print-atm.c
+++ b/contrib/tcpdump/print-atm.c
@@ -22,7 +22,7 @@
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.12 1999/11/21 09:36:48 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.20 2000/12/22 22:45:09 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -33,22 +33,7 @@ static const char rcsid[] =
#include <sys/time.h>
#include <sys/socket.h>
-#if __STDC__
-struct mbuf;
-struct rtentry;
-#endif
-
-#include <net/if.h>
-#include <net/if_var.h>
-
#include <netinet/in.h>
-#include <net/ethernet.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 <stdio.h>
#include <pcap.h>
@@ -68,7 +53,7 @@ atm_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
u_int caplen = h->caplen;
u_int length = h->len;
- u_short ethertype;
+ u_short ethertype, extracted_ethertype;
ts_print(&h->ts);
@@ -159,12 +144,14 @@ atm_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
/* ether_type not known, forward it to llc_print */
if (!eflag)
printf("%02x %02x %02x %02x-%02x-%02x %04x: ",
- p[0], p[1], p[2], /* dsap/ssap/ctrl */
- p[3], p[4], p[5], /* manufacturer's code */
+ packetp[0], packetp[1], packetp[2], /* dsap/ssap/ctrl */
+ packetp[3], packetp[4], packetp[5], /* manufacturer's code */
ethertype);
- if (!xflag && !qflag)
+ if (!xflag && !qflag) {
+ extracted_ethertype = 0;
/* default_print(p, caplen); */
- llc_print(p-8,length+8,caplen+8,"000000","000000");
+ llc_print(p-8,length+8,caplen+8,"000000","000000", &extracted_ethertype);
+ }
}
if (xflag)
default_print(p, caplen);
diff --git a/contrib/tcpdump/print-bootp.c b/contrib/tcpdump/print-bootp.c
index 7e15815dfc45..400539898caf 100644
--- a/contrib/tcpdump/print-bootp.c
+++ b/contrib/tcpdump/print-bootp.c
@@ -24,7 +24,7 @@
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.48 1999/11/21 09:36:49 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.56 2000/12/04 00:00:08 fenner Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -35,24 +35,19 @@ static const char rcsid[] =
#include <sys/time.h>
#include <sys/socket.h>
-#if __STDC__
struct mbuf;
struct rtentry;
-#endif
-#include <net/if.h>
#include <netinet/in.h>
-#include <net/ethernet.h>
#include <ctype.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
#include <stdio.h>
#include <string.h>
#include "interface.h"
#include "addrtoname.h"
+#include "extract.h"
+#include "ether.h"
#include "bootp.h"
static void rfc1048_print(const u_char *, u_int);
@@ -181,7 +176,7 @@ bootp_print(register const u_char *cp, u_int length,
else {
u_int32_t ul;
- memcpy((char *)&ul, (char *)bp->bp_vend, sizeof(ul));
+ ul = EXTRACT_32BITS(&bp->bp_vend);
if (ul != 0)
printf("vend-#0x%x", ul);
}
@@ -196,7 +191,7 @@ static struct tok tag2str[] = {
/* RFC1048 tags */
{ TAG_PAD, " PAD" },
{ TAG_SUBNET_MASK, "iSM" }, /* subnet mask (RFC950) */
- { TAG_TIME_OFFSET, "lTZ" }, /* seconds from UTC */
+ { 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) */
@@ -271,7 +266,46 @@ static struct tok tag2str[] = {
{ TAG_RENEWAL_TIME, "lRN" },
{ TAG_REBIND_TIME, "lRB" },
{ TAG_VENDOR_CLASS, "bVC" },
- { TAG_CLIENT_ID, "bCID" },
+ { TAG_CLIENT_ID, "xCID" },
+/* RFC 2485 */
+ { TAG_OPEN_GROUP_UAP, "aUAP" },
+/* RFC 2563 */
+ { TAG_DISABLE_AUTOCONF, "BNOAUTO" },
+/* RFC 2610 */
+ { TAG_SLP_DA, "bSLP-DA" }, /*"b" is a little wrong */
+ { TAG_SLP_SCOPE, "bSLP-SCOPE" }, /*"b" is a little wrong */
+/* RFC 2937 */
+ { TAG_NS_SEARCH, "sNSSEARCH" }, /* XXX 's' */
+/* RFC 3011 */
+ { TAG_IP4_SUBNET_SELECT, "iSUBNET" },
+/* ftp://ftp.isi.edu/.../assignments/bootp-dhcp-extensions */
+ { TAG_USER_CLASS, "aCLASS" },
+ { TAG_SLP_NAMING_AUTH, "aSLP-NA" },
+ { TAG_CLIENT_FQDN, "bFQDN" }, /* XXX 'b' */
+ { TAG_AGENT_CIRCUIT, "bACKT" },
+ { TAG_AGENT_REMOTE, "bARMT" },
+ { TAG_AGENT_MASK, "bAMSK" },
+ { TAG_TZ_STRING, "aTZSTR" },
+ { TAG_FQDN_OPTION, "bFQDNS" }, /* XXX 'b' */
+ { TAG_AUTH, "bAUTH" }, /* XXX 'b' */
+ { TAG_VINES_SERVERS, "iVINES" },
+ { TAG_SERVER_RANK, "sRANK" },
+ { TAG_CLIENT_ARCH, "sARCH" },
+ { TAG_CLIENT_NDI, "bNDI" }, /* XXX 'b' */
+ { TAG_CLIENT_GUID, "bGUID" }, /* XXX 'b' */
+ { TAG_LDAP_URL, "aLDAP" },
+ { TAG_6OVER4, "i6o4" },
+ { TAG_PRINTER_NAME, "aPRTR" },
+ { TAG_MDHCP_SERVER, "bMDHCP" }, /* XXX 'b' */
+ { TAG_IPX_COMPAT, "bIPX" }, /* XXX 'b' */
+ { TAG_NETINFO_PARENT, "iNI" },
+ { TAG_NETINFO_PARENT_TAG, "aNITAG" },
+ { TAG_URL, "aURL" },
+ { TAG_FAILOVER, "bFAIL" }, /* XXX 'b' */
+ { 0, NULL }
+};
+/* 2-byte extended tags */
+static struct tok xtag2str[] = {
{ 0, NULL }
};
@@ -298,7 +332,16 @@ rfc1048_print(register const u_char *bp, register u_int length)
continue;
if (tag == TAG_END)
return;
- cp = tok2str(tag2str, "?T%d", tag);
+ if (tag == TAG_EXTENDED_OPTION) {
+ TCHECK2(*(bp + 1), 2);
+ tag = EXTRACT_16BITS(bp + 1);
+ /* XXX we don't know yet if the IANA will
+ * preclude overlap of 1-byte and 2-byte spaces.
+ * If not, we need to offset tag after this step.
+ */
+ cp = tok2str(xtag2str, "?xT%d", tag);
+ } else
+ cp = tok2str(tag2str, "?T%d", tag);
c = *cp++;
printf(" %s:", cp);
@@ -333,7 +376,21 @@ rfc1048_print(register const u_char *bp, register u_int length)
first = 1;
while (len-- > 0) {
c = *bp++;
- cp = tok2str(tag2str, "?%d", c);
+ cp = tok2str(tag2str, "?T%d", c);
+ if (!first)
+ putchar('+');
+ printf("%s", cp + 1);
+ first = 0;
+ }
+ continue;
+ }
+ if (tag == TAG_EXTENDED_REQUEST) {
+ first = 1;
+ while (len > 1) {
+ len -= 2;
+ c = EXTRACT_16BITS(bp);
+ bp += 2;
+ cp = tok2str(xtag2str, "?xT%d", c);
if (!first)
putchar('+');
printf("%s", cp + 1);
@@ -367,13 +424,17 @@ rfc1048_print(register const u_char *bp, register u_int length)
case 'i':
case 'l':
+ case 'L':
/* ip addresses/32-bit words */
while (size >= sizeof(ul)) {
if (!first)
putchar(',');
- memcpy((char *)&ul, (char *)bp, sizeof(ul));
- if (c == 'i')
+ ul = EXTRACT_32BITS(bp);
+ if (c == 'i') {
+ ul = htonl(ul);
printf("%s", ipaddr_string(&ul));
+ } else if (c == 'L')
+ printf("%d", ul);
else
printf("%u", ul);
bp += sizeof(ul);
@@ -403,7 +464,7 @@ rfc1048_print(register const u_char *bp, register u_int length)
while (size >= sizeof(us)) {
if (!first)
putchar(',');
- memcpy((char *)&us, (char *)bp, sizeof(us));
+ us = EXTRACT_16BITS(bp);
printf("%d", us);
bp += sizeof(us);
size -= sizeof(us);
@@ -434,12 +495,13 @@ rfc1048_print(register const u_char *bp, register u_int length)
break;
case 'b':
+ case 'x':
default:
/* Bytes */
while (size > 0) {
if (!first)
- putchar('.');
- printf("%d", *bp);
+ putchar (c == 'x' ? ':' : '.');
+ printf (c == 'x' ? "%02x" : "%d", *bp);
++bp;
--size;
first = 0;
@@ -450,6 +512,9 @@ rfc1048_print(register const u_char *bp, register u_int length)
if (size)
printf("[len %d]", len);
}
+ return;
+trunc:
+ printf("|[rfc1048]");
}
static void
diff --git a/contrib/tcpdump/print-domain.c b/contrib/tcpdump/print-domain.c
index 50f2ce2b63b5..91fc3f69e6a7 100644
--- a/contrib/tcpdump/print-domain.c
+++ b/contrib/tcpdump/print-domain.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.42 1999/11/21 09:36:50 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.64 2001/01/02 23:24:51 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -32,22 +32,8 @@ static const char rcsid[] =
#include <sys/param.h>
#include <sys/time.h>
-#include <sys/socket.h>
-
-#if __STDC__
-struct mbuf;
-struct rtentry;
-#endif
-#include <net/if.h>
#include <netinet/in.h>
-#include <net/ethernet.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>
#ifdef NOERROR
#undef NOERROR /* Solaris sucks */
@@ -55,7 +41,7 @@ struct rtentry;
#ifdef NOERROR
#undef T_UNSPEC /* SINIX does too */
#endif
-#include <arpa/nameser.h>
+#include "nameser.h"
#include <stdio.h>
#include <string.h>
@@ -126,7 +112,14 @@ struct rtentry;
#define T_NAPTR 35 /* Naming Authority PoinTeR */
#endif
#ifndef T_A6
-#define T_A6 38 /* IP6 address (ipngwg-dns-lookups) */
+#define T_A6 38 /* IP6 address */
+#endif
+#ifndef T_DNAME
+#define T_DNAME 39 /* non-terminal redirection */
+#endif
+
+#ifndef T_OPT
+#define T_OPT 41 /* EDNS0 option (meta-RR) */
#endif
#ifndef T_UNSPEC
@@ -164,8 +157,22 @@ ns_nskip(register const u_char *cp, register const u_char *bp)
if (((i = *cp++) & INDIR_MASK) == INDIR_MASK)
return (cp + 1);
+ if (cp >= snapend)
+ return(NULL);
while (i && cp < snapend) {
- cp += i;
+ if ((i & INDIR_MASK) == EDNS0_MASK) {
+ int bitlen, bytelen;
+
+ if ((i & ~INDIR_MASK) != EDNS0_ELT_BITLABEL)
+ return(NULL); /* unknown ELT */
+ if ((bitlen = *cp++) == 0)
+ bitlen = 256;
+ bytelen = (bitlen + 7) / 8;
+ cp += bytelen;
+ } else
+ cp += i;
+ if (cp >= snapend)
+ return(NULL);
i = *cp++;
}
return (cp);
@@ -173,33 +180,135 @@ ns_nskip(register const u_char *cp, register const u_char *bp)
/* print a <domain-name> */
static const u_char *
-ns_nprint(register const u_char *cp, register const u_char *bp)
+blabel_print(const u_char *cp)
+{
+ int bitlen, slen, b;
+ int truncated = 0;
+ const u_char *bitp, *lim;
+ char tc;
+
+ if (cp >= snapend)
+ return(NULL);
+ if ((bitlen = *cp) == 0)
+ bitlen = 256;
+ slen = (bitlen + 3) / 4;
+ if ((lim = cp + 1 + slen) > snapend) {
+ truncated = 1;
+ lim = snapend;
+ }
+
+ /* print the bit string as a hex string */
+ printf("\\[x");
+ for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++)
+ printf("%02x", *bitp);
+ if (bitp == lim)
+ printf("...");
+ else if (b > 4) {
+ tc = *bitp++;
+ printf("%02x", tc & (0xff << (8 - b)));
+ } else if (b > 0) {
+ tc = *bitp++;
+ printf("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b)));
+ }
+ printf("/%d]", bitlen);
+
+ return(truncated ? NULL : lim);
+}
+
+static int
+labellen(const u_char *cp)
{
register u_int i;
- register const u_char *rp;
- register int compress;
- i = *cp++;
- rp = cp + i;
- if ((i & INDIR_MASK) == INDIR_MASK) {
- rp = cp + 1;
- compress = 1;
+ if (cp >= snapend)
+ return(-1);
+ i = *cp;
+ if ((i & INDIR_MASK) == EDNS0_MASK) {
+ int bitlen, elt;
+
+ if ((elt = (i & ~INDIR_MASK)) != EDNS0_ELT_BITLABEL)
+ return(-1);
+ if (cp + 1 >= snapend)
+ return(-1);
+ if ((bitlen = *(cp + 1)) == 0)
+ bitlen = 256;
+ return(((bitlen + 7) / 8) + 1);
} else
+ return(i);
+}
+
+static const u_char *
+ns_nprint(register const u_char *cp, register const u_char *bp)
+{
+ register u_int i, l;
+ register const u_char *rp = NULL;
+ register int compress = 0;
+ int chars_processed;
+ int elt;
+ int data_size = snapend - bp;
+
+ if ((l = labellen(cp)) < 0)
+ return(NULL);
+ if (cp >= snapend)
+ return(NULL);
+ chars_processed = 1;
+ if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) {
compress = 0;
+ rp = cp + l;
+ }
+
if (i != 0)
while (i && cp < snapend) {
if ((i & INDIR_MASK) == INDIR_MASK) {
+ if (!compress) {
+ rp = cp + 1;
+ compress = 1;
+ }
cp = bp + (((i << 8) | *cp) & 0x3fff);
+ if (cp >= snapend)
+ return(NULL);
+ if ((l = labellen(cp)) < 0)
+ return(NULL);
i = *cp++;
+ chars_processed++;
+
+ /*
+ * If we've looked at every character in
+ * the message, this pointer will make
+ * us look at some character again,
+ * which means we're looping.
+ */
+ if (chars_processed >= data_size) {
+ printf("<LOOP>");
+ return (NULL);
+ }
continue;
}
- if (fn_printn(cp, i, snapend))
- break;
- cp += i;
+ if ((i & INDIR_MASK) == EDNS0_MASK) {
+ elt = (i & ~INDIR_MASK);
+ switch(elt) {
+ case EDNS0_ELT_BITLABEL:
+ blabel_print(cp);
+ break;
+ default:
+ /* unknown ELT */
+ printf("<ELT %d>", elt);
+ return(NULL);
+ }
+ } else {
+ if (fn_printn(cp, l, snapend))
+ break;
+ }
+
+ cp += l;
+ chars_processed += l;
putchar('.');
+ if (cp >= snapend || (l = labellen(cp)) < 0)
+ return(NULL);
i = *cp++;
+ chars_processed++;
if (!compress)
- rp += i + 1;
+ rp += l + 1;
}
else
putchar('.');
@@ -212,6 +321,8 @@ ns_cprint(register const u_char *cp, register const u_char *bp)
{
register u_int i;
+ if (cp >= snapend)
+ return NULL;
i = *cp++;
(void)fn_printn(cp, i, snapend);
return (cp + i);
@@ -254,17 +365,10 @@ static struct tok type2str[] = {
{ T_ATMA, "ATMA " },
{ T_NAPTR, "NAPTR " },
{ T_A6, "A6 " },
-#ifndef T_UINFO
-#define T_UINFO 100
-#endif
+ { T_DNAME, "DNAME " },
+ { T_OPT, "OPT " },
{ T_UINFO, "UINFO" },
-#ifndef T_UID
-#define T_UID 101
-#endif
{ T_UID, "UID" },
-#ifndef T_GID
-#define T_GID 102
-#endif
{ T_GID, "GID" },
{ T_UNSPEC, "UNSPEC" },
{ T_UNSPECA, "UNSPECA" },
@@ -284,7 +388,7 @@ static struct tok class2str[] = {
};
/* print a query */
-static void
+static const u_char *
ns_qprint(register const u_char *cp, register const u_char *bp)
{
register const u_char *np = cp;
@@ -292,8 +396,8 @@ ns_qprint(register const u_char *cp, register const u_char *bp)
cp = ns_nskip(cp, bp);
- if (cp + 4 > snapend)
- return;
+ if (cp + 4 > snapend || cp == NULL)
+ return(NULL);
/* print the qtype and qclass (if it's not IN) */
i = *cp++ << 8;
@@ -305,33 +409,35 @@ ns_qprint(register const u_char *cp, register const u_char *bp)
printf(" %s", tok2str(class2str, "(Class %d)", i));
fputs("? ", stdout);
- ns_nprint(np, bp);
+ cp = ns_nprint(np, bp);
+ return(cp ? cp + 4 : NULL);
}
/* print a reply */
static const u_char *
ns_rprint(register const u_char *cp, register const u_char *bp)
{
- register u_int i;
+ register u_int class;
register u_short typ, len;
register const u_char *rp;
if (vflag) {
putchar(' ');
- cp = ns_nprint(cp, bp);
+ if ((cp = ns_nprint(cp, bp)) == NULL)
+ return NULL;
} else
cp = ns_nskip(cp, bp);
- if (cp + 10 > snapend)
+ if (cp + 10 > snapend || cp == NULL)
return (snapend);
/* print the type/qtype and class (if it's not IN) */
typ = *cp++ << 8;
typ |= *cp++;
- i = *cp++ << 8;
- i |= *cp++;
- if (i != C_IN)
- printf(" %s", tok2str(class2str, "(Class %d)", i));
+ class = *cp++ << 8;
+ class |= *cp++;
+ if (class != C_IN && typ != T_OPT)
+ printf(" %s", tok2str(class2str, "(Class %d)", class));
/* ignore ttl */
cp += 4;
@@ -342,9 +448,13 @@ ns_rprint(register const u_char *cp, register const u_char *bp)
rp = cp + len;
printf(" %s", tok2str(type2str, "Type%d", typ));
- switch (typ) {
+ if (rp > snapend)
+ return(NULL);
+ switch (typ) {
case T_A:
+ if (cp + sizeof(struct in_addr) > snapend)
+ return(NULL);
printf(" %s", ipaddr_string(cp));
break;
@@ -352,15 +462,41 @@ ns_rprint(register const u_char *cp, register const u_char *bp)
case T_CNAME:
case T_PTR:
#ifdef T_DNAME
- case T_DNAME: /*XXX not checked as there's no server support yet*/
+ case T_DNAME:
#endif
putchar(' ');
- (void)ns_nprint(cp, bp);
+ if (ns_nprint(cp, bp) == NULL)
+ return(NULL);
break;
+ case T_SOA:
+ if (!vflag)
+ break;
+ putchar(' ');
+ if ((cp = ns_nprint(cp, bp)) == NULL)
+ return(NULL);
+ putchar(' ');
+ if ((cp = ns_nprint(cp, bp)) == NULL)
+ return(NULL);
+ if (cp + 5 * 4 > snapend)
+ return(NULL);
+ printf(" %u", EXTRACT_32BITS(cp));
+ cp += 4;
+ printf(" %u", EXTRACT_32BITS(cp));
+ cp += 4;
+ printf(" %u", EXTRACT_32BITS(cp));
+ cp += 4;
+ printf(" %u", EXTRACT_32BITS(cp));
+ cp += 4;
+ printf(" %u", EXTRACT_32BITS(cp));
+ cp += 4;
+ break;
case T_MX:
putchar(' ');
- (void)ns_nprint(cp + 2, bp);
+ if (cp + 2 > snapend)
+ return(NULL);
+ if (ns_nprint(cp + 2, bp) == NULL)
+ return(NULL);
printf(" %d", EXTRACT_16BITS(cp));
break;
@@ -371,25 +507,43 @@ ns_rprint(register const u_char *cp, register const u_char *bp)
#ifdef INET6
case T_AAAA:
+ if (cp + sizeof(struct in6_addr) > snapend)
+ return(NULL);
printf(" %s", ip6addr_string(cp));
break;
- case T_A6: /*XXX not checked as there's no server support yet*/
+ case T_A6:
{
struct in6_addr a;
- int pbyte;
-
- pbyte = (*cp + 7) / 8;
- memset(&a, 0, sizeof(a));
- memcpy(&a, cp + 1, pbyte);
- printf(" %u %s ", *cp, ip6addr_string(&a));
- (void)ns_nprint(cp + 1 + pbyte, bp);
+ int pbit, pbyte;
+
+ pbit = *cp;
+ pbyte = (pbit & ~7) / 8;
+ if (pbit > 128) {
+ printf(" %u(bad plen)", pbit);
+ break;
+ } else if (pbit < 128) {
+ memset(&a, 0, sizeof(a));
+ memcpy(&a.s6_addr[pbyte], cp + 1, sizeof(a) - pbyte);
+ printf(" %u %s", pbit, ip6addr_string(&a));
+ }
+ if (pbit > 0) {
+ putchar(' ');
+ if (ns_nprint(cp + 1 + sizeof(a) - pbyte, bp) == NULL)
+ return(NULL);
+ }
break;
}
#endif /*INET6*/
+ case T_OPT:
+ printf(" UDPsize=%u", class);
+ break;
+
case T_UNSPECA: /* One long string */
- printf(" %.*s", len, cp);
+ if (cp + len > snapend)
+ return(NULL);
+ fn_printn(cp, len, snapend);
break;
}
return (rp); /* XXX This isn't always right */
@@ -400,7 +554,7 @@ ns_print(register const u_char *bp, u_int length)
{
register const HEADER *np;
register int qdcount, ancount, nscount, arcount;
- register const u_char *cp;
+ register const u_char *cp = NULL;
np = (const HEADER *)bp;
/* get the byte-order right */
@@ -409,44 +563,76 @@ ns_print(register const u_char *bp, u_int length)
nscount = ntohs(np->nscount);
arcount = ntohs(np->arcount);
- if (np->qr) {
+ if (DNS_QR(np)) {
/* this is a response */
- printf(" %d%s%s%s%s%s",
+ printf(" %d%s%s%s%s%s%s",
ntohs(np->id),
- ns_ops[np->opcode],
- ns_resp[np->rcode],
- np->aa? "*" : "",
- np->ra? "" : "-",
- np->tc? "|" : "");
+ ns_ops[DNS_OPCODE(np)],
+ ns_resp[DNS_RCODE(np)],
+ DNS_AA(np)? "*" : "",
+ DNS_RA(np)? "" : "-",
+ DNS_TC(np)? "|" : "",
+ DNS_CD(np)? "%" : "");
+
if (qdcount != 1)
printf(" [%dq]", qdcount);
/* Print QUESTION section on -vv */
if (vflag > 1) {
- fputs(" q: ", stdout);
- cp = ns_nprint((const u_char *)(np + 1), bp);
- } else
- cp = ns_nskip((const u_char *)(np + 1), bp);
+ fputs(" q:", stdout);
+ if ((cp = ns_qprint((const u_char *)(np + 1), bp))
+ == NULL)
+ goto trunc;
+ } else {
+ if ((cp = ns_nskip((const u_char *)(np + 1), bp))
+ == NULL)
+ goto trunc;
+ cp += 4;
+ }
printf(" %d/%d/%d", ancount, nscount, arcount);
if (ancount--) {
- cp = ns_rprint(cp + 4, bp);
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
while (ancount-- && cp < snapend) {
putchar(',');
- cp = ns_rprint(cp, bp);
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ }
+ }
+ /* Print NS and AR sections on -vv */
+ if (vflag > 1) {
+ if (nscount-- && cp < snapend) {
+ fputs(" ns:", stdout);
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ while (nscount-- && cp < snapend) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ }
+ }
+ if (arcount-- && cp < snapend) {
+ fputs(" ar:", stdout);
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ while (arcount-- && cp < snapend) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ }
}
}
}
else {
/* this is a request */
- printf(" %d%s%s",
- ntohs(np->id),
- ns_ops[np->opcode],
- np->rd? "+" : "");
+ printf(" %d%s%s%s", ntohs(np->id), ns_ops[DNS_OPCODE(np)],
+ DNS_RD(np) ? "+" : "",
+ DNS_AD(np) ? "$" : "");
/* any weirdness? */
- if (*(((u_short *)np)+1) & htons(0x6ff))
+ if (*(((u_short *)np)+1) & htons(0x6cf))
printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1)));
- if (np->opcode == IQUERY) {
+ if (DNS_OPCODE(np) == IQUERY) {
if (qdcount)
printf(" [%dq]", qdcount);
if (ancount != 1)
@@ -463,7 +649,60 @@ ns_print(register const u_char *bp, u_int length)
if (arcount)
printf(" [%dau]", arcount);
- ns_qprint((const u_char *)(np + 1), (const u_char *)np);
+ if (qdcount--) {
+ cp = ns_qprint((const u_char *)(np + 1),
+ (const u_char *)np);
+ if (!cp)
+ goto trunc;
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ while (qdcount-- && cp < snapend) {
+ cp = ns_qprint((const u_char *)cp,
+ (const u_char *)np);
+ if (!cp)
+ goto trunc;
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ }
+ }
+
+ /* Print remaining sections on -vv */
+ if (vflag > 1) {
+ if (ancount--) {
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ while (ancount-- && cp < snapend) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ }
+ }
+ if (nscount-- && cp < snapend) {
+ fputs(" ns:", stdout);
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ while (nscount-- && cp < snapend) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ }
+ }
+ if (arcount-- && cp < snapend) {
+ fputs(" ar:", stdout);
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ while (arcount-- && cp < snapend) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp)) == NULL)
+ goto trunc;
+ }
+ }
+ }
}
printf(" (%d)", length);
+ return;
+
+ trunc:
+ printf("[|domain]");
+ return;
}
diff --git a/contrib/tcpdump/print-ether.c b/contrib/tcpdump/print-ether.c
index d33028d6fecf..723853f0eec9 100644
--- a/contrib/tcpdump/print-ether.c
+++ b/contrib/tcpdump/print-ether.c
@@ -22,7 +22,7 @@
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.48 1999/11/21 09:36:51 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.61 2000/12/22 22:45:10 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -33,32 +33,20 @@ static const char rcsid[] =
#include <sys/time.h>
#include <sys/socket.h>
-#if __STDC__
struct mbuf;
struct rtentry;
-#endif
-#include <net/if.h>
#include <netinet/in.h>
-#include <net/ethernet.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 <stdio.h>
#include <pcap.h>
-#ifdef INET6
-#include <netinet/ip6.h>
-#endif
-
#include "interface.h"
#include "addrtoname.h"
#include "ethertype.h"
+#include "ether.h"
+
const u_char *packetp;
const u_char *snapend;
@@ -81,8 +69,6 @@ ether_print(register const u_char *bp, u_int length)
length);
}
-static u_short extracted_ethertype;
-
/*
* This is the top level routine of the printer. 'p' is the points
* to the ether header of the packet, 'h->tv' is the timestamp,
@@ -96,10 +82,11 @@ ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
u_int length = h->len;
struct ether_header *ep;
u_short ether_type;
+ u_short extracted_ethertype;
ts_print(&h->ts);
- if (caplen < sizeof(struct ether_header)) {
+ if (caplen < ETHER_HDRLEN) {
printf("[|ether]");
goto out;
}
@@ -115,10 +102,10 @@ ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
packetp = p;
snapend = p + caplen;
- length -= sizeof(struct ether_header);
- caplen -= sizeof(struct ether_header);
+ length -= ETHER_HDRLEN;
+ caplen -= ETHER_HDRLEN;
ep = (struct ether_header *)p;
- p += sizeof(struct ether_header);
+ p += ETHER_HDRLEN;
ether_type = ntohs(ep->ether_type);
@@ -128,10 +115,11 @@ ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
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) {
+ if (llc_print(p, length, caplen, ESRC(ep), EDST(ep),
+ &extracted_ethertype) == 0) {
/* ether_type not known, print raw packet */
if (!eflag)
- ether_print((u_char *)ep, length);
+ ether_print((u_char *)ep, length + ETHER_HDRLEN);
if (extracted_ethertype) {
printf("(LLC %s) ",
etherproto_string(htons(extracted_ethertype)));
@@ -139,10 +127,11 @@ ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
if (!xflag && !qflag)
default_print(p, caplen);
}
- } else if (ether_encap_print(ether_type, p, length, caplen) == 0) {
+ } else if (ether_encap_print(ether_type, p, length, caplen,
+ &extracted_ethertype) == 0) {
/* ether_type not known, print raw packet */
if (!eflag)
- ether_print((u_char *)ep, length + sizeof(*ep));
+ ether_print((u_char *)ep, length + ETHER_HDRLEN);
if (!xflag && !qflag)
default_print(p, caplen);
}
@@ -158,16 +147,18 @@ ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
*
* 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.
+ * The Ethernet type code is passed through a pointer; if it was
+ * ETHERTYPE_8021Q, it gets updated to be the Ethernet type of
+ * the 802.1Q payload, for the benefit of lower layers that might
+ * want to know what it is.
*/
int
ether_encap_print(u_short ethertype, const u_char *p,
- u_int length, u_int caplen)
+ u_int length, u_int caplen, u_short *extracted_ethertype)
{
recurse:
- extracted_ethertype = ethertype;
+ *extracted_ethertype = ethertype;
switch (ethertype) {
@@ -205,29 +196,30 @@ ether_encap_print(u_short ethertype, const u_char *p,
return (1);
case ETHERTYPE_8021Q:
- printf("802.1Q vlan#%d P%d%s",
- ntohs(*(unsigned short*)p)&0xFFF,
- ntohs(*(unsigned short*)p)>>13,
- (ntohs(*(unsigned short*)p)&0x1000) ? " CFI" : "");
- ethertype = ntohs(*(unsigned short*)(p+2));
+ printf("802.1Q vlan#%d P%d%s ",
+ ntohs(*(u_int16_t *)p) & 0xfff,
+ ntohs(*(u_int16_t *)p) >> 13,
+ (ntohs(*(u_int16_t *)p) & 0x1000) ? " CFI" : "");
+ ethertype = ntohs(*(u_int16_t *)(p + 2));
p += 4;
length -= 4;
caplen -= 4;
- if (ethertype > ETHERMTU)
+ if (ethertype > ETHERMTU)
goto recurse;
- extracted_ethertype = 0;
+ *extracted_ethertype = 0;
- if (llc_print(p, length, caplen, p-18, p-12) == 0) {
+ if (llc_print(p, length, caplen, p - 18, p - 12,
+ extracted_ethertype) == 0) {
/* ether_type not known, print raw packet */
if (!eflag)
- ether_print(p-18, length+4);
- if (extracted_ethertype) {
+ ether_print(p - 18, length + 4);
+ if (*extracted_ethertype) {
printf("(LLC %s) ",
- etherproto_string(htons(extracted_ethertype)));
+ etherproto_string(htons(*extracted_ethertype)));
}
if (!xflag && !qflag)
- default_print(p-18, caplen+4);
+ default_print(p - 18, caplen + 4);
}
return (1);
diff --git a/contrib/tcpdump/print-fddi.c b/contrib/tcpdump/print-fddi.c
index d2526fa7814d..68717371fc9c 100644
--- a/contrib/tcpdump/print-fddi.c
+++ b/contrib/tcpdump/print-fddi.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.40 1999/12/14 16:49:02 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.50 2000/12/23 20:48:13 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -36,16 +36,7 @@ static const char rcsid[] =
#include <sys/file.h>
#include <sys/ioctl.h>
-#if __STDC__
-struct mbuf;
-struct rtentry;
-#endif
-#include <net/if.h>
-
#include <netinet/in.h>
-#include <net/ethernet.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
#include <ctype.h>
#include <netdb.h>
@@ -57,6 +48,7 @@ struct rtentry;
#include "addrtoname.h"
#include "ethertype.h"
+#include "ether.h"
#include "fddi.h"
/*
@@ -98,8 +90,6 @@ int fddi_bitswap = 1;
* - vj
*/
-#define FDDI_HDRLEN (sizeof(struct fddi_header))
-
static u_char fddi_bit_swap[] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
@@ -291,10 +281,10 @@ fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
*/
snapend = p + caplen;
/*
- * Actually, the only printer that uses packetp is print-bootp.c,
- * and it assumes that packetp points to an Ethernet header. The
- * right thing to do is to fix print-bootp.c to know which link
- * type is in use when it excavates. XXX
+ * Actually, the only printers that use packetp are print-arp.c
+ * and print-bootp.c, and they assume that packetp points to an
+ * Ethernet header. The right thing to do is to fix them to know
+ * which link type is in use when they excavate. XXX
*/
packetp = (u_char *)&ehdr;
@@ -310,14 +300,14 @@ fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
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) {
+ if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr),
+ &extracted_ethertype) == 0) {
/*
* Some kinds of LLC packet we cannot
* handle intelligently
*/
if (!eflag)
- fddi_print(fddip, length,
+ fddi_print(fddip, length + FDDI_HDRLEN,
ESRC(&ehdr), EDST(&ehdr));
if (extracted_ethertype) {
printf("(LLC %s) ",
@@ -331,7 +321,8 @@ fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h,
else {
/* Some kinds of FDDI packet we cannot handle intelligently */
if (!eflag)
- fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));
+ fddi_print(fddip, length + FDDI_HDRLEN, ESRC(&ehdr),
+ EDST(&ehdr));
if (!xflag && !qflag)
default_print(p, caplen);
}
diff --git a/contrib/tcpdump/print-icmp.c b/contrib/tcpdump/print-icmp.c
index a4b3dd6206df..40d0d89e4cd6 100644
--- a/contrib/tcpdump/print-icmp.c
+++ b/contrib/tcpdump/print-icmp.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.43 1999/11/22 04:28:21 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.57 2000/10/10 05:03:32 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -34,29 +34,139 @@ static const char rcsid[] =
#include <sys/time.h>
#include <sys/socket.h>
-#if __STDC__
struct mbuf;
struct rtentry;
-#endif
-#include <net/if.h>
#include <netinet/in.h>
-#include <net/ethernet.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 <stdio.h>
#include <string.h>
+#include <netdb.h> /* for MAXHOSTNAMELEN on some platforms */
#include "interface.h"
#include "addrtoname.h"
#include "extract.h" /* must come after interface.h */
+#include "ip.h"
+#include "udp.h"
+
+/*
+ * Interface Control Message Protocol Definitions.
+ * Per RFC 792, September 1981.
+ */
+
+/*
+ * Structure of an icmp header.
+ */
+struct icmp {
+ u_int8_t icmp_type; /* type of message, see below */
+ u_int8_t icmp_code; /* type sub code */
+ u_int16_t icmp_cksum; /* ones complement cksum of struct */
+ union {
+ u_int8_t ih_pptr; /* ICMP_PARAMPROB */
+ struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
+ struct ih_idseq {
+ u_int16_t icd_id;
+ u_int16_t icd_seq;
+ } ih_idseq;
+ u_int32_t ih_void;
+
+ /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
+ struct ih_pmtu {
+ u_int16_t ipm_void;
+ u_int16_t ipm_nextmtu;
+ } ih_pmtu;
+ } icmp_hun;
+#define icmp_pptr icmp_hun.ih_pptr
+#define icmp_gwaddr icmp_hun.ih_gwaddr
+#define icmp_id icmp_hun.ih_idseq.icd_id
+#define icmp_seq icmp_hun.ih_idseq.icd_seq
+#define icmp_void icmp_hun.ih_void
+#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
+#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
+ union {
+ struct id_ts {
+ u_int32_t its_otime;
+ u_int32_t its_rtime;
+ u_int32_t its_ttime;
+ } id_ts;
+ struct id_ip {
+ struct ip idi_ip;
+ /* options and then 64 bits of data */
+ } id_ip;
+ u_int32_t id_mask;
+ u_int8_t id_data[1];
+ } icmp_dun;
+#define icmp_otime icmp_dun.id_ts.its_otime
+#define icmp_rtime icmp_dun.id_ts.its_rtime
+#define icmp_ttime icmp_dun.id_ts.its_ttime
+#define icmp_ip icmp_dun.id_ip.idi_ip
+#define icmp_mask icmp_dun.id_mask
+#define icmp_data icmp_dun.id_data
+};
+
+/*
+ * Lower bounds on packet lengths for various types.
+ * For the error advice packets must first insure that the
+ * packet is large enought to contain the returned ip header.
+ * Only then can we do the check to see if 64 bits of packet
+ * data have been returned, since we need to check the returned
+ * ip header length.
+ */
+#define ICMP_MINLEN 8 /* abs minimum */
+#define ICMP_TSLEN (8 + 3 * sizeof (u_int32_t)) /* timestamp */
+#define ICMP_MASKLEN 12 /* address mask */
+#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
+#define ICMP_ADVLEN(p) (8 + (IP_HL(&(p)->icmp_ip) << 2) + 8)
+ /* N.B.: must separately check that ip_hl >= 5 */
+
+/*
+ * Definition of type and code field values.
+ */
+#define ICMP_ECHOREPLY 0 /* echo reply */
+#define ICMP_UNREACH 3 /* dest unreachable, codes: */
+#define ICMP_UNREACH_NET 0 /* bad net */
+#define ICMP_UNREACH_HOST 1 /* bad host */
+#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
+#define ICMP_UNREACH_PORT 3 /* bad port */
+#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
+#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
+#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
+#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
+#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
+#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */
+#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */
+#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
+#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
+#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
+#define ICMP_REDIRECT 5 /* shorter route, codes: */
+#define ICMP_REDIRECT_NET 0 /* for network */
+#define ICMP_REDIRECT_HOST 1 /* for host */
+#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
+#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
+#define ICMP_ECHO 8 /* echo service */
+#define ICMP_ROUTERADVERT 9 /* router advertisement */
+#define ICMP_ROUTERSOLICIT 10 /* router solicitation */
+#define ICMP_TIMXCEED 11 /* time exceeded, code: */
+#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
+#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
+#define ICMP_PARAMPROB 12 /* ip header bad */
+#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */
+#define ICMP_TSTAMP 13 /* timestamp request */
+#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
+#define ICMP_IREQ 15 /* information request */
+#define ICMP_IREQREPLY 16 /* information reply */
+#define ICMP_MASKREQ 17 /* address mask request */
+#define ICMP_MASKREPLY 18 /* address mask reply */
+
+#define ICMP_MAXTYPE 18
+
+#define ICMP_INFOTYPE(type) \
+ ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
+ (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
+ (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+ (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
+ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
/* rfc1700 */
#ifndef ICMP_UNREACH_NET_UNKNOWN
#define ICMP_UNREACH_NET_UNKNOWN 6 /* destination net unknown */
@@ -91,14 +201,6 @@ struct rtentry;
#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */
#endif
-/* rfc1256 */
-#ifndef ICMP_ROUTERADVERT
-#define ICMP_ROUTERADVERT 9 /* router advertisement */
-#endif
-#ifndef ICMP_ROUTERSOLICIT
-#define ICMP_ROUTERSOLICIT 10 /* router solicitation */
-#endif
-
/* Most of the icmp types */
static struct tok icmp2str[] = {
{ ICMP_ECHOREPLY, "echo reply" },
@@ -151,15 +253,15 @@ static struct tok type2str[] = {
/* rfc1191 */
struct mtu_discovery {
- short unused;
- short nexthopmtu;
+ u_int16_t unused;
+ u_int16_t nexthopmtu;
};
/* rfc1256 */
struct ih_rdiscovery {
- u_char ird_addrnum;
- u_char ird_addrsiz;
- u_short ird_lifetime;
+ u_int8_t ird_addrnum;
+ u_int8_t ird_addrsiz;
+ u_int16_t ird_lifetime;
};
struct id_rdiscovery {
@@ -198,15 +300,16 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
case ICMP_UNREACH_PROTOCOL:
TCHECK(dp->icmp_ip.ip_p);
- (void)snprintf(buf, sizeof(buf), "%s protocol %d unreachable",
- ipaddr_string(&dp->icmp_ip.ip_dst),
- dp->icmp_ip.ip_p);
+ (void)snprintf(buf, sizeof(buf),
+ "%s protocol %d unreachable",
+ ipaddr_string(&dp->icmp_ip.ip_dst),
+ dp->icmp_ip.ip_p);
break;
case ICMP_UNREACH_PORT:
TCHECK(dp->icmp_ip.ip_p);
oip = &dp->icmp_ip;
- hlen = oip->ip_hl * 4;
+ hlen = IP_HL(oip) * 4;
ouh = (struct udphdr *)(((u_char *)oip) + hlen);
dport = ntohs(ouh->uh_dport);
switch (oip->ip_p) {
@@ -235,20 +338,20 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
break;
case ICMP_UNREACH_NEEDFRAG:
- {
+ {
register const struct mtu_discovery *mp;
-
mp = (struct mtu_discovery *)&dp->icmp_void;
mtu = EXTRACT_16BITS(&mp->nexthopmtu);
- if (mtu)
- (void)snprintf(buf, sizeof(buf),
- "%s unreachable - need to frag (mtu %d)",
- ipaddr_string(&dp->icmp_ip.ip_dst), mtu);
- else
- (void)snprintf(buf, sizeof(buf),
- "%s unreachable - need to frag",
- ipaddr_string(&dp->icmp_ip.ip_dst));
+ if (mtu) {
+ (void)snprintf(buf, sizeof(buf),
+ "%s unreachable - need to frag (mtu %d)",
+ ipaddr_string(&dp->icmp_ip.ip_dst), mtu);
+ } else {
+ (void)snprintf(buf, sizeof(buf),
+ "%s unreachable - need to frag",
+ ipaddr_string(&dp->icmp_ip.ip_dst));
}
+ }
break;
default:
@@ -270,49 +373,54 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
break;
case ICMP_ROUTERADVERT:
- {
+ {
register const struct ih_rdiscovery *ihp;
register const struct id_rdiscovery *idp;
u_int lifetime, num, size;
- (void)strcpy(buf, "router advertisement");
+ (void)snprintf(buf, sizeof(buf), "router advertisement");
cp = buf + strlen(buf);
ihp = (struct ih_rdiscovery *)&dp->icmp_void;
TCHECK(*ihp);
- (void)strcpy(cp, " lifetime ");
+ (void)strncpy(cp, " lifetime ", sizeof(buf) - (cp - buf));
cp = buf + strlen(buf);
lifetime = EXTRACT_16BITS(&ihp->ird_lifetime);
- if (lifetime < 60)
- (void)snprintf(cp, sizeof(buf) - strlen(buf), "%u", lifetime);
- else if (lifetime < 60 * 60)
- (void)snprintf(cp, sizeof(buf) - strlen(buf), "%u:%02u",
+ if (lifetime < 60) {
+ (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u",
+ lifetime);
+ } else if (lifetime < 60 * 60) {
+ (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u:%02u",
lifetime / 60, lifetime % 60);
- else
- (void)snprintf(cp, sizeof(buf) - strlen(buf), "%u:%02u:%02u",
+ } else {
+ (void)snprintf(cp, sizeof(buf) - (cp - buf),
+ "%u:%02u:%02u",
lifetime / 3600,
(lifetime % 3600) / 60,
lifetime % 60);
+ }
cp = buf + strlen(buf);
num = ihp->ird_addrnum;
- (void)snprintf(cp, sizeof(buf) - strlen(buf), " %d:", num);
+ (void)snprintf(cp, sizeof(buf) - (cp - buf), " %d:", num);
cp = buf + strlen(buf);
size = ihp->ird_addrsiz;
if (size != 2) {
- (void)snprintf(cp, sizeof(buf) - strlen(buf), " [size %d]", size);
+ (void)snprintf(cp, sizeof(buf) - (cp - buf),
+ " [size %d]", size);
break;
}
idp = (struct id_rdiscovery *)&dp->icmp_data;
while (num-- > 0) {
TCHECK(*idp);
- (void)snprintf(cp, sizeof(buf) - strlen(buf), " {%s %u}",
+ (void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}",
ipaddr_string(&idp->ird_addr),
EXTRACT_32BITS(&idp->ird_pref));
cp = buf + strlen(buf);
+ ++idp;
}
- }
+ }
break;
case ICMP_TIMXCEED:
@@ -328,26 +436,46 @@ icmp_print(register const u_char *bp, u_int plen, register const u_char *bp2)
break;
default:
- (void)snprintf(buf, sizeof(buf), "time exceeded-#%d", dp->icmp_code);
+ (void)snprintf(buf, sizeof(buf), "time exceeded-#%d",
+ dp->icmp_code);
break;
}
break;
case ICMP_PARAMPROB:
if (dp->icmp_code)
- (void)snprintf(buf, sizeof(buf), "parameter problem - code %d",
- dp->icmp_code);
+ (void)snprintf(buf, sizeof(buf),
+ "parameter problem - code %d", dp->icmp_code);
else {
TCHECK(dp->icmp_pptr);
- (void)snprintf(buf, sizeof(buf), "parameter problem - octet %d",
- dp->icmp_pptr);
+ (void)snprintf(buf, sizeof(buf),
+ "parameter problem - octet %d", dp->icmp_pptr);
}
break;
case ICMP_MASKREPLY:
TCHECK(dp->icmp_mask);
(void)snprintf(buf, sizeof(buf), "address mask is 0x%08x",
- (u_int32_t)ntohl(dp->icmp_mask));
+ (unsigned)ntohl(dp->icmp_mask));
+ break;
+
+ case ICMP_TSTAMP:
+ TCHECK(dp->icmp_seq);
+ (void)snprintf(buf, sizeof(buf),
+ "time stamp query id %u seq %u",
+ (unsigned)ntohs(dp->icmp_id),
+ (unsigned)ntohs(dp->icmp_seq));
+ break;
+
+ case ICMP_TSTAMPREPLY:
+ TCHECK(dp->icmp_ttime);
+ (void)snprintf(buf, sizeof(buf),
+ "time stamp reply id %u seq %u : org 0x%lx recv 0x%lx xmit 0x%lx",
+ (unsigned)ntohs(dp->icmp_id),
+ (unsigned)ntohs(dp->icmp_seq),
+ (unsigned long)ntohl(dp->icmp_otime),
+ (unsigned long)ntohl(dp->icmp_rtime),
+ (unsigned long)ntohl(dp->icmp_ttime));
break;
default:
diff --git a/contrib/tcpdump/print-ip.c b/contrib/tcpdump/print-ip.c
index fe06efd48ee9..8e88d6ea5716 100644
--- a/contrib/tcpdump/print-ip.c
+++ b/contrib/tcpdump/print-ip.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.79 1999/12/22 06:27:21 itojun Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.92 2001/01/02 23:00:01 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -35,16 +35,7 @@ static const char rcsid[] =
#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>
-
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -54,172 +45,13 @@ static const char rcsid[] =
#include "interface.h"
#include "extract.h" /* must come after interface.h */
+#include "ip.h"
+
/* Compatibility */
#ifndef IPPROTO_ND
#define IPPROTO_ND 77
#endif
-#ifndef IN_CLASSD
-#define IN_CLASSD(i) (((int32_t)(i) & 0xf0000000) == 0xe0000000)
-#endif
-
-/* (following from ipmulti/mrouted/prune.h) */
-
-/*
- * The packet format for a traceroute request.
- */
-struct tr_query {
- u_int tr_src; /* traceroute source */
- u_int tr_dst; /* traceroute destination */
- u_int tr_raddr; /* traceroute response address */
- u_int tr_rttlqid; /* response ttl and qid */
-};
-
-#define TR_GETTTL(x) (int)(((x) >> 24) & 0xff)
-#define TR_GETQID(x) ((x) & 0x00ffffff)
-
-/*
- * Traceroute response format. A traceroute response has a tr_query at the
- * beginning, followed by one tr_resp for each hop taken.
- */
-struct tr_resp {
- u_int tr_qarr; /* query arrival time */
- u_int tr_inaddr; /* incoming interface address */
- u_int tr_outaddr; /* outgoing interface address */
- u_int tr_rmtaddr; /* parent address in source tree */
- u_int tr_vifin; /* input packet count on interface */
- u_int tr_vifout; /* output packet count on interface */
- u_int tr_pktcnt; /* total incoming packets for src-grp */
- u_char tr_rproto; /* routing proto deployed on router */
- u_char tr_fttl; /* ttl required to forward on outvif */
- u_char tr_smask; /* subnet mask for src addr */
- u_char tr_rflags; /* forwarding error codes */
-};
-
-/* defs within mtrace */
-#define TR_QUERY 1
-#define TR_RESP 2
-
-/* fields for tr_rflags (forwarding error codes) */
-#define TR_NO_ERR 0
-#define TR_WRONG_IF 1
-#define TR_PRUNED 2
-#define TR_OPRUNED 3
-#define TR_SCOPED 4
-#define TR_NO_RTE 5
-#define TR_NO_FWD 7
-#define TR_NO_SPACE 0x81
-#define TR_OLD_ROUTER 0x82
-
-/* fields for tr_rproto (routing protocol) */
-#define TR_PROTO_DVMRP 1
-#define TR_PROTO_MOSPF 2
-#define TR_PROTO_PIM 3
-#define TR_PROTO_CBT 4
-
-static void print_mtrace(register const u_char *bp, register u_int len)
-{
- register struct tr_query *tr = (struct tr_query *)(bp + 8);
-
- printf("mtrace %lu: %s to %s reply-to %s",
- (u_long)TR_GETQID(ntohl(tr->tr_rttlqid)),
- ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst),
- ipaddr_string(&tr->tr_raddr));
- if (IN_CLASSD(ntohl(tr->tr_raddr)))
- printf(" with-ttl %d", TR_GETTTL(ntohl(tr->tr_rttlqid)));
-}
-
-static void print_mresp(register const u_char *bp, register u_int len)
-{
- register struct tr_query *tr = (struct tr_query *)(bp + 8);
-
- printf("mresp %lu: %s to %s reply-to %s",
- (u_long)TR_GETQID(ntohl(tr->tr_rttlqid)),
- ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst),
- ipaddr_string(&tr->tr_raddr));
- if (IN_CLASSD(ntohl(tr->tr_raddr)))
- printf(" with-ttl %d", TR_GETTTL(ntohl(tr->tr_rttlqid)));
-}
-
-static void
-igmp_print(register const u_char *bp, register u_int len,
- register const u_char *bp2)
-{
- register const struct ip *ip;
-
- ip = (const struct ip *)bp2;
- (void)printf("%s > %s: ",
- ipaddr_string(&ip->ip_src),
- ipaddr_string(&ip->ip_dst));
-
- if (qflag) {
- (void)printf("igmp");
- return;
- }
-
- TCHECK2(bp[0], 8);
- switch (bp[0]) {
- case 0x11:
- (void)printf("igmp %s query", bp[1] ? "v2" : "v1");
- if (bp[1] && bp[1] != 100)
- (void)printf(" [intvl %d]", bp[1]);
- (void)printf("igmp query");
- if (EXTRACT_32BITS(&bp[4]))
- (void)printf(" [gaddr %s]", ipaddr_string(&bp[4]));
- if (len != 8)
- (void)printf(" [len %d]", len);
- break;
- case 0x12:
- case 0x16:
- (void)printf("igmp %s report %s",
- (bp[0] & 0x0f) == 6 ? "v2" : "v1",
- ipaddr_string(&bp[4]));
- if (len != 8)
- (void)printf(" [len %d]", len);
- if (bp[1])
- (void)printf(" [b1=0x%x]", bp[1]);
- break;
- case 0x17:
- (void)printf("igmp leave %s", ipaddr_string(&bp[4]));
- if (len != 8)
- (void)printf(" [len %d]", len);
- if (bp[1])
- (void)printf(" [b1=0x%x]", bp[1]);
- break;
- case 0x13:
- (void)printf("igmp dvmrp");
- if (len < 8)
- (void)printf(" [len %d]", len);
- else
- dvmrp_print(bp, len);
- break;
- case 0x14:
- (void)printf("igmp pimv1");
- pimv1_print(bp, len);
- break;
- case 0x1e:
- print_mresp(bp, len);
- break;
- case 0x1f:
- print_mtrace(bp, len);
- break;
- default:
- (void)printf("igmp-%d", bp[0] & 0xf);
- if (bp[1])
- (void)printf(" [b1=0x%02x]", bp[1]);
- break;
- }
-
- if (vflag && TTEST2(bp[0], len)) {
- /* Check the IGMP checksum */
- if (in_cksum((const u_short*)bp, len, 0))
- printf(" bad igmp cksum %x!", EXTRACT_16BITS(&bp[2]));
- }
- return;
-trunc:
- fputs("[|igmp]", stdout);
-}
-
/*
* print the recorded route in an IP RR, LSRR or SSRR option.
*/
@@ -312,7 +144,15 @@ ip_optprint(register const u_char *cp, u_int length)
for (; length > 0; cp += len, length -= len) {
int tt = *cp;
- len = (tt == IPOPT_NOP || tt == IPOPT_EOL) ? 1 : cp[1];
+ if (tt == IPOPT_NOP || tt == IPOPT_EOL)
+ len = 1;
+ else {
+ if (&cp[1] >= snapend) {
+ printf("[|ip]");
+ return;
+ }
+ len = cp[1];
+ }
if (len <= 0) {
printf("[|ip op len %d]", len);
return;
@@ -455,7 +295,11 @@ ip_print(register const u_char *bp, register u_int length)
(void)printf("truncated-ip %d", length);
return;
}
- hlen = ip->ip_hl * 4;
+ hlen = IP_HL(ip) * 4;
+ if (hlen < sizeof (struct ip)) {
+ (void)printf("bad-hlen %d", hlen);
+ return;
+ }
len = ntohs(ip->ip_len);
if (length < len)
@@ -521,11 +365,11 @@ again:
}
case IPPROTO_TCP:
- tcp_print(cp, len, (const u_char *)ip);
+ tcp_print(cp, len, (const u_char *)ip, (off &~ 0x6000));
break;
case IPPROTO_UDP:
- udp_print(cp, len, (const u_char *)ip);
+ udp_print(cp, len, (const u_char *)ip, (off &~ 0x6000));
break;
case IPPROTO_ICMP:
@@ -639,6 +483,17 @@ again:
pim_print(cp, len);
break;
+#ifndef IPPROTO_VRRP
+#define IPPROTO_VRRP 112
+#endif
+ case IPPROTO_VRRP:
+ if (vflag)
+ (void)printf("vrrp %s > %s: ",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+ vrrp_print(cp, len, ip->ip_ttl);
+ break;
+
default:
#if 0
(void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
@@ -708,6 +563,8 @@ again:
(void)printf("%sid %d", sep, (int)ntohs(ip->ip_id));
sep = ", ";
}
+ (void)printf("%slen %d", sep, (int)ntohs(ip->ip_len));
+ sep = ", ";
if ((u_char *)ip + hlen <= snapend) {
sum = in_cksum((const u_short *)ip, hlen, 0);
if (sum != 0) {
@@ -723,3 +580,29 @@ again:
printf(")");
}
}
+
+void
+ipN_print(register const u_char *bp, register u_int length)
+{
+ struct ip *ip, hdr;
+
+ ip = (struct ip *)bp;
+ if (length < 4) {
+ (void)printf("truncated-ip %d", length);
+ return;
+ }
+ memcpy (&hdr, (char *)ip, 4);
+ switch (IP_V(&hdr)) {
+ case 4:
+ ip_print (bp, length);
+ return;
+#ifdef INET6
+ case 6:
+ ip6_print (bp, length);
+ return;
+#endif
+ default:
+ (void)printf("unknown ip %d", IP_V(&hdr));
+ return;
+ }
+}
diff --git a/contrib/tcpdump/print-ip6.c b/contrib/tcpdump/print-ip6.c
index 04dee43a350b..9eee4de7cd6b 100644
--- a/contrib/tcpdump/print-ip6.c
+++ b/contrib/tcpdump/print-ip6.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.2.2.1 2000/01/11 06:58:25 fenner Exp $";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.16 2000/11/17 19:08:15 itojun Exp $";
#endif
#ifdef HAVE_CONFIG_H
@@ -38,23 +38,16 @@ static const char rcsid[] =
#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 <stdio.h>
-#ifdef __STDC__
#include <stdlib.h>
-#endif
#include <unistd.h>
+#include <string.h>
#include "interface.h"
#include "addrtoname.h"
-#include <netinet/ip6.h>
+#include "ip6.h"
/*
* print an IP6 datagram.
@@ -63,29 +56,30 @@ void
ip6_print(register const u_char *bp, register int length)
{
register const struct ip6_hdr *ip6;
- register int hlen;
+ register int advance;
register int len;
register const u_char *cp;
int nh;
+ int fragmented = 0;
u_int flow;
ip6 = (const struct ip6_hdr *)bp;
-#ifdef TCPDUMP_ALIGN
+#ifdef LBL_ALIGN
/*
- * The IP header is not word aligned, so copy into abuf.
+ * The IP6 header is not 16-byte 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)) {
+ if ((u_long)ip6 & 15) {
static u_char *abuf;
- if (abuf == 0)
- abuf = (u_char *)malloc(snaplen);
- bcopy((char *)ip, (char *)abuf, min(length, snaplen));
- snapend += abuf - (u_char *)ip;
+ if (abuf == NULL)
+ abuf = malloc(snaplen);
+ memcpy(abuf, ip6, min(length, snaplen));
+ snapend += abuf - (u_char *)ip6;
packetp = abuf;
- ip = (struct ip6_hdr *)abuf;
+ ip6 = (struct ip6_hdr *)abuf;
}
#endif
if ((u_char *)(ip6 + 1) > snapend) {
@@ -96,17 +90,17 @@ ip6_print(register const u_char *bp, register int length)
(void)printf("truncated-ip6 %d", length);
return;
}
- hlen = sizeof(struct ip6_hdr);
+ advance = sizeof(struct ip6_hdr);
len = ntohs(ip6->ip6_plen);
- if (length < len + hlen)
+ if (length < len + advance)
(void)printf("truncated-ip6 - %d bytes missing!",
- len + hlen - length);
+ len + advance - length);
cp = (const u_char *)ip6;
nh = ip6->ip6_nxt;
while (cp < snapend) {
- cp += hlen;
+ cp += advance;
if (cp == (u_char *)(ip6 + 1)
&& nh != IPPROTO_TCP && nh != IPPROTO_UDP) {
@@ -116,42 +110,43 @@ ip6_print(register const u_char *bp, register int length)
switch (nh) {
case IPPROTO_HOPOPTS:
- hlen = hbhopt_print(cp);
+ advance = hbhopt_print(cp);
nh = *cp;
break;
case IPPROTO_DSTOPTS:
- hlen = dstopt_print(cp);
+ advance = dstopt_print(cp);
nh = *cp;
break;
case IPPROTO_FRAGMENT:
- hlen = frag6_print(cp, (const u_char *)ip6);
- if (snapend <= cp + hlen)
+ advance = frag6_print(cp, (const u_char *)ip6);
+ if (snapend <= cp + advance)
goto end;
nh = *cp;
+ fragmented = 1;
break;
case IPPROTO_ROUTING:
- hlen = rt6_print(cp, (const u_char *)ip6);
+ advance = rt6_print(cp, (const u_char *)ip6);
nh = *cp;
break;
case IPPROTO_TCP:
tcp_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp),
- (const u_char *)ip6);
+ (const u_char *)ip6, fragmented);
goto end;
case IPPROTO_UDP:
udp_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp),
- (const u_char *)ip6);
+ (const u_char *)ip6, fragmented);
goto end;
case IPPROTO_ICMPV6:
icmp6_print(cp, (const u_char *)ip6);
goto end;
case IPPROTO_AH:
- hlen = ah_print(cp, (const u_char *)ip6);
+ advance = ah_print(cp, (const u_char *)ip6);
nh = *cp;
break;
case IPPROTO_ESP:
{
int enh;
- cp += esp_print(cp, (const u_char *)ip6, &enh);
+ advance = esp_print(cp, (const u_char *)ip6, &enh);
if (enh < 0)
goto end;
nh = enh & 0xff;
@@ -163,12 +158,16 @@ ip6_print(register const u_char *bp, register int length)
case IPPROTO_IPCOMP:
{
int enh;
- cp += ipcomp_print(cp, (const u_char *)ip6, &enh);
+ advance = ipcomp_print(cp, (const u_char *)ip6, &enh);
if (enh < 0)
goto end;
nh = enh & 0xff;
break;
}
+
+#ifndef IPPROTO_PIM
+#define IPPROTO_PIM 103
+#endif
case IPPROTO_PIM:
pim_print(cp, len);
goto end;
diff --git a/contrib/tcpdump/print-ipx.c b/contrib/tcpdump/print-ipx.c
index c17812387848..867634c4ebff 100644
--- a/contrib/tcpdump/print-ipx.c
+++ b/contrib/tcpdump/print-ipx.c
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ipx.c,v 1.22 1999/11/21 09:36:54 fenner Exp $";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ipx.c,v 1.27 2000/09/29 04:58:41 guy Exp $";
#endif
#ifdef HAVE_CONFIG_H
@@ -38,16 +38,8 @@ static const char rcsid[] =
#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>
-
-#ifdef __STDC__
+
#include <stdlib.h>
-#endif
#include <stdio.h>
#include <string.h>
@@ -94,7 +86,7 @@ ipxaddr_string(u_int32_t net, const u_char *node)
{
static char line[256];
- sprintf(line, "%x.%02x:%02x:%02x:%02x:%02x:%02x",
+ snprintf(line, sizeof(line), "%x.%02x:%02x:%02x:%02x:%02x:%02x",
net, node[0], node[1], node[2], node[3], node[4], node[5]);
return line;
diff --git a/contrib/tcpdump/print-isoclns.c b/contrib/tcpdump/print-isoclns.c
index 399ec8b81d99..ed020fa65d64 100644
--- a/contrib/tcpdump/print-isoclns.c
+++ b/contrib/tcpdump/print-isoclns.c
@@ -25,7 +25,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.16 1999/11/21 09:36:55 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.22 2000/10/11 04:04:33 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -36,20 +36,14 @@ static const char rcsid[] =
#include <sys/time.h>
#include <sys/socket.h>
-#if __STDC__
-struct mbuf;
-struct rtentry;
-#endif
-#include <net/if.h>
-
#include <netinet/in.h>
-#include <net/ethernet.h>
#include <stdio.h>
#include "interface.h"
#include "addrtoname.h"
#include "ethertype.h"
+#include "ether.h"
#include "extract.h"
#define NLPID_CLNS 129 /* 0x81 */
@@ -62,7 +56,7 @@ struct rtentry;
* IS-IS is defined in ISO 10589. Look there for protocol definitions.
*/
-#define SYSTEM_ID_LEN sizeof(struct ether_addr)
+#define SYSTEM_ID_LEN ETHER_ADDR_LEN
#define ISIS_VERSION 1
#define PDU_TYPE_MASK 0x1F
#define PRIORITY_MASK 0x7F
@@ -117,9 +111,9 @@ struct isis_ptp_adjancey_values {
};
static struct isis_ptp_adjancey_values isis_ptp_adjancey_values[] = {
- ISIS_PTP_ADJ_UP, "UP",
- ISIS_PTP_ADJ_INIT, "INIT",
- ISIS_PTP_ADJ_DOWN, "DOWN"
+ { ISIS_PTP_ADJ_UP, "UP" },
+ { ISIS_PTP_ADJ_INIT, "INIT" },
+ { ISIS_PTP_ADJ_DOWN, "DOWN" }
};
struct isis_common_header {
@@ -266,7 +260,6 @@ esis_print(const u_char *p, u_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) {
@@ -418,7 +411,7 @@ esis_print(const u_char *p, u_int length)
* Print out an NSAP.
*/
-void
+static void
print_nsap (register const u_char *cp, register int length)
{
int i;
@@ -444,11 +437,13 @@ isis_print (const u_char *p, u_int length)
{
struct isis_header *header;
struct isis_ptp_header *header_ptp;
- u_char pdu_type, max_area, priority, *pptr, type, len, *tptr, tmp, alen;
+ u_char pdu_type, max_area, priority, type, len, tmp, alen;
+ const u_char *pptr, *tptr;
u_short packet_len, holding_time;
int i;
- header_ptp = (struct isis_ptp_header *)header = (struct isis_header *)p;
+ header = (struct isis_header *)p;
+ header_ptp = (struct isis_ptp_header *)header;
printf("\n\t\t\t");
/*
@@ -474,7 +469,7 @@ isis_print (const u_char *p, u_int length)
(header->fixed_len != ISIS_PTP_HEADER_SIZE) &&
(header->fixed_len != L1_LS_PDU_HEADER_SIZE) &&
(header-> fixed_len != L1_COMPLETE_SEQ_PDU_HEADER_SIZE) ) {
- printf(" bogus fixed header length",
+ printf(" bogus fixed header length %u",
header->fixed_len);
return(0);
}
@@ -485,12 +480,12 @@ isis_print (const u_char *p, u_int length)
(pdu_type != L1_COMPLETE_SEQ_PDU) &&
(pdu_type != L2_COMPLETE_SEQ_PDU) ) {
printf(" PDU type (%d) not supported", pdu_type);
- return;
+ return(0);
}
if (header->pkt_version != ISIS_VERSION) {
printf(" version %d packet not supported", header->pkt_version);
- return;
+ return(0);
}
max_area = header->enc_max_area;
@@ -581,10 +576,10 @@ isis_print (const u_char *p, u_int length)
*/
if(pdu_type==PTP_IIH) {
packet_len -= ISIS_PTP_HEADER_SIZE;
- pptr = (char *)p + ISIS_PTP_HEADER_SIZE;
+ pptr = p + ISIS_PTP_HEADER_SIZE;
} else {
packet_len -= ISIS_HEADER_SIZE;
- pptr = (char *)p + ISIS_HEADER_SIZE;
+ pptr = p + ISIS_HEADER_SIZE;
}
while (packet_len >= 2) {
if (pptr >= snapend) {
@@ -617,10 +612,10 @@ isis_print (const u_char *p, u_int length)
printf("\n\t\t\t neighbor addresses");
tmp = len;
tptr = pptr;
- while (tmp >= sizeof(struct ether_addr)) {
+ while (tmp >= ETHER_ADDR_LEN) {
printf("\n\t\t\t %s", etheraddr_string(tptr));
- tmp -= sizeof(struct ether_addr);
- tptr += sizeof(struct ether_addr);
+ tmp -= ETHER_ADDR_LEN;
+ tptr += ETHER_ADDR_LEN;
}
break;
case TLV_PADDING:
diff --git a/contrib/tcpdump/print-llc.c b/contrib/tcpdump/print-llc.c
index 3216f4d6c148..a31d6ad2290d 100644
--- a/contrib/tcpdump/print-llc.c
+++ b/contrib/tcpdump/print-llc.c
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.27 1999/12/22 06:27:21 itojun Exp $";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.32 2000/12/18 07:55:36 guy Exp $";
#endif
#ifdef HAVE_CONFIG_H
@@ -66,10 +66,11 @@ static struct tok cmd2str[] = {
*/
int
llc_print(const u_char *p, u_int length, u_int caplen,
- const u_char *esrc, const u_char *edst)
+ const u_char *esrc, const u_char *edst, u_short *extracted_ethertype)
{
struct llc llc;
register u_short et;
+ u_int16_t control;
register int ret;
if (caplen < 3) {
@@ -85,13 +86,61 @@ llc_print(const u_char *p, u_int length, u_int caplen,
ipx_print(p, length);
return (1);
}
- if (llc.ssap == 0xf0 && llc.dsap == 0xf0) {
+
+ /* Cisco Discovery Protocol - SNAP & ether type 0x2000 */
+ if(llc.ssap == LLCSAP_SNAP && llc.dsap == LLCSAP_SNAP &&
+ llc.llcui == LLC_UI &&
+ llc.ethertype[0] == 0x20 && llc.ethertype[1] == 0x00 ) {
+ cdp_print( p, length, caplen, esrc, edst);
+ return (1);
+ }
+
+ if (llc.ssap == LLCSAP_8021D && llc.dsap == LLCSAP_8021D) {
+ stp_print(p, length);
+ return (1);
+ }
+ if (llc.ssap == 0xf0 && llc.dsap == 0xf0
+ && (!(llc.llcu & LLC_S_FMT) || llc.llcu == LLC_U_FMT)) {
/*
* we don't actually have a full netbeui parser yet, but the
* smb parser can handle many smb-in-netbeui packets, which
* is very useful, so we call that
+ *
+ * We don't call it for S frames, however, just I frames
+ * (which are frames that don't have the low-order bit,
+ * LLC_S_FMT, set in the first byte of the control field)
+ * and UI frames (whose control field is just 3, LLC_U_FMT).
+ */
+
+ /*
+ * Skip the DSAP and LSAP.
+ */
+ p += 2;
+ length -= 2;
+ caplen -= 2;
+
+ /*
+ * OK, what type of LLC frame is this? The length
+ * of the control field depends on that - I frames
+ * have a two-byte control field, and U frames have
+ * a one-byte control field.
*/
- netbeui_print(p + 2, p + min(caplen, length));
+ if (llc.llcu == LLC_U_FMT) {
+ control = llc.llcu;
+ p += 1;
+ length -= 1;
+ caplen -= 1;
+ } else {
+ /*
+ * The control field in I and S frames is
+ * little-endian.
+ */
+ control = EXTRACT_LE_16BITS(&llc.llcu);
+ p += 2;
+ length -= 2;
+ caplen -= 2;
+ }
+ netbeui_print(control, p, p + min(caplen, length));
return (1);
}
if (llc.ssap == LLCSAP_ISONS && llc.dsap == LLCSAP_ISONS
@@ -116,7 +165,8 @@ llc_print(const u_char *p, u_int length, u_int caplen,
/* This is an encapsulated Ethernet packet */
et = EXTRACT_16BITS(&llc.ethertype[0]);
- ret = ether_encap_print(et, p, length, caplen);
+ ret = ether_encap_print(et, p, length, caplen,
+ extracted_ethertype);
if (ret)
return (ret);
}
@@ -143,9 +193,12 @@ llc_print(const u_char *p, u_int length, u_int caplen,
}
if ((llc.llcu & LLC_U_FMT) == LLC_U_FMT) {
+ u_int16_t cmd;
const char *m;
char f;
- m = tok2str(cmd2str, "%02x", LLC_U_CMD(llc.llcu));
+
+ cmd = LLC_U_CMD(llc.llcu);
+ m = tok2str(cmd2str, "%02x", cmd);
switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
case 0: f = 'C'; break;
case LLC_GSAP: f = 'R'; break;
@@ -169,35 +222,38 @@ llc_print(const u_char *p, u_int length, u_int caplen,
}
}
- if (!strcmp(m,"ui") && f=='C') {
+ if (cmd == LLC_UI && f == 'C') {
/*
* we don't have a proper ipx decoder yet, but there
* is a partial one in the smb code
*/
ipx_netbios_print(p,p+min(caplen,length));
}
-
} else {
char f;
- llc.llcis = ntohs(llc.llcis);
- switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
+
+ /*
+ * The control field in I and S frames is little-endian.
+ */
+ control = EXTRACT_LE_16BITS(&llc.llcu);
+ switch ((llc.ssap & LLC_GSAP) | (control & LLC_IS_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;
+ case LLC_IS_POLL: f = 'P'; break;
+ case LLC_GSAP|LLC_IS_POLL: f = 'F'; break;
default: f = '?'; break;
}
- if ((llc.llcu & LLC_S_FMT) == LLC_S_FMT) {
+ if ((control & 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),
+ llc_s[LLC_S_CMD(control)],
+ LLC_IS_NR(control),
f);
} else {
(void)printf("I (s=%d,r=%d,%c)",
- LLC_I_NS(llc.llcis),
- LLC_IS_NR(llc.llcis),
+ LLC_I_NS(control),
+ LLC_IS_NR(control),
f);
}
p += 4;
diff --git a/contrib/tcpdump/print-nfs.c b/contrib/tcpdump/print-nfs.c
index bfaf4387d2a1..289535e30b9e 100644
--- a/contrib/tcpdump/print-nfs.c
+++ b/contrib/tcpdump/print-nfs.c
@@ -17,24 +17,27 @@
* 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.
+ *
+ * $FreeBSD$
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: print-nfs.c,v 1.65 97/08/17 13:24:22 leres Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.87 2000/10/07 05:53:12 itojun Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
#endif
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
-#include <net/if.h>
+struct mbuf;
+struct rtentry;
#include <netinet/in.h>
-#include <net/ethernet.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
#include <rpc/rpc.h>
@@ -45,19 +48,24 @@ static const char rcsid[] =
#include "interface.h"
#include "addrtoname.h"
-#include "extract.h" /* must come after interface.h */
#include "nfs.h"
#include "nfsfh.h"
-static void nfs_printfh(const u_int32_t *, const int);
-static void xid_map_enter(const struct rpc_msg *, const struct ip *);
-static int32_t xid_map_find(const struct rpc_msg *, const struct ip *, u_int32_t *,
- u_int32_t *);
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+
+static void nfs_printfh(const u_int32_t *, const u_int);
+static void xid_map_enter(const struct rpc_msg *, const u_char *);
+static int32_t xid_map_find(const struct rpc_msg *, const u_char *,
+ u_int32_t *, u_int32_t *);
static void interp_reply(const struct rpc_msg *, u_int32_t, u_int32_t, int);
static const u_int32_t *parse_post_op_attr(const u_int32_t *, int);
-
-static int nfserr; /* true if we error rather than trunc */
+static void print_sattr3(const struct nfsv3_sattr *sa3, int verbose);
+static int print_int64(const u_int32_t *dp, int how);
+static void print_nfsaddr(const u_char *, const char *, const char *);
/*
* Mapping of old NFS Version 2 RPC numbers to generic numbers.
@@ -91,10 +99,60 @@ u_int32_t nfsv3_procid[NFS_NPROCS] = {
NFSPROC_NOOP
};
-const char *nfsv3_writemodes[NFSV3WRITE_NMODES] = {
- "unstable",
- "datasync",
- "filesync"
+/*
+ * NFS V2 and V3 status values.
+ *
+ * Some of these come from the RFCs for NFS V2 and V3, with the message
+ * strings taken from the FreeBSD C library "errlst.c".
+ *
+ * Others are errors that are not in the RFC but that I suspect some
+ * NFS servers could return; the values are FreeBSD errno values, as
+ * the first NFS server was the SunOS 2.0 one, and until 5.0 SunOS
+ * was primarily BSD-derived.
+ */
+static struct tok status2str[] = {
+ { 1, "Operation not permitted" }, /* EPERM */
+ { 2, "No such file or directory" }, /* ENOENT */
+ { 5, "Input/output error" }, /* EIO */
+ { 6, "Device not configured" }, /* ENXIO */
+ { 11, "Resource deadlock avoided" }, /* EDEADLK */
+ { 12, "Cannot allocate memory" }, /* ENOMEM */
+ { 13, "Permission denied" }, /* EACCES */
+ { 17, "File exists" }, /* EEXIST */
+ { 18, "Cross-device link" }, /* EXDEV */
+ { 19, "Operation not supported by device" }, /* ENODEV */
+ { 20, "Not a directory" }, /* ENOTDIR */
+ { 21, "Is a directory" }, /* EISDIR */
+ { 22, "Invalid argument" }, /* EINVAL */
+ { 26, "Text file busy" }, /* ETXTBSY */
+ { 27, "File too large" }, /* EFBIG */
+ { 28, "No space left on device" }, /* ENOSPC */
+ { 30, "Read-only file system" }, /* EROFS */
+ { 31, "Too many links" }, /* EMLINK */
+ { 45, "Operation not supported" }, /* EOPNOTSUPP */
+ { 62, "Too many levels of symbolic links" }, /* ELOOP */
+ { 63, "File name too long" }, /* ENAMETOOLONG */
+ { 66, "Directory not empty" }, /* ENOTEMPTY */
+ { 69, "Disc quota exceeded" }, /* EDQUOT */
+ { 70, "Stale NFS file handle" }, /* ESTALE */
+ { 71, "Too many levels of remote in path" }, /* EREMOTE */
+ { 99, "Write cache flushed to disk" }, /* NFSERR_WFLUSH (not used) */
+ { 10001, "Illegal NFS file handle" }, /* NFS3ERR_BADHANDLE */
+ { 10002, "Update synchronization mismatch" }, /* NFS3ERR_NOT_SYNC */
+ { 10003, "READDIR/READDIRPLUS cookie is stale" }, /* NFS3ERR_BAD_COOKIE */
+ { 10004, "Operation not supported" }, /* NFS3ERR_NOTSUPP */
+ { 10005, "Buffer or request is too small" }, /* NFS3ERR_TOOSMALL */
+ { 10006, "Unspecified error on server" }, /* NFS3ERR_SERVERFAULT */
+ { 10007, "Object of that type not supported" }, /* NFS3ERR_BADTYPE */
+ { 10008, "Request couldn't be completed in time" }, /* NFS3ERR_JUKEBOX */
+ { 0, NULL }
+};
+
+static struct tok nfsv3_writemodes[] = {
+ { 0, "unstable" },
+ { 1, "datasync" },
+ { 2, "filesync" },
+ { 0, NULL }
};
static struct tok type2str[] = {
@@ -121,11 +179,7 @@ static struct tok type2str[] = {
#define SIGNED 1
#define HEX 2
-#define INT64_FORMAT "%qd"
-#define U_INT64_FORMAT "%qu"
-#define HEX_INT64_FORMAT "%qx"
-
-int print_int64(const u_int32_t *dp, int how)
+static int print_int64(const u_int32_t *dp, int how)
{
#ifdef INT64_FORMAT
u_int64_t res;
@@ -145,77 +199,108 @@ int print_int64(const u_int32_t *dp, int how)
return (0);
}
#else
- /*
- * XXX - throw upper 32 bits away.
- * Could also go for hex: printf("0x%x%x", dp[0], dp[1]);
- */
- if (how == SIGNED)
- printf("%ld", (int)dp[1]);
- else
- printf("%lu", (unsigned int)dp[1]);
+ switch (how) {
+ case SIGNED:
+ case UNSIGNED:
+ case HEX:
+ printf("0x%x%08x", (u_int32_t)ntohl(dp[0]),
+ (u_int32_t)ntohl(dp[1]));
+ break;
+ default:
+ return (0);
+ }
#endif
return 1;
}
+static void
+print_nfsaddr(const u_char *bp, const char *s, const char *d)
+{
+ struct ip *ip;
+#ifdef INET6
+ struct ip6_hdr *ip6;
+ char srcaddr[INET6_ADDRSTRLEN], dstaddr[INET6_ADDRSTRLEN];
+#else
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+ char srcaddr[INET_ADDRSTRLEN], dstaddr[INET_ADDRSTRLEN];
+#endif
+
+ srcaddr[0] = dstaddr[0] = '\0';
+ switch (IP_V((struct ip *)bp)) {
+ case 4:
+ ip = (struct ip *)bp;
+ strlcpy(srcaddr, ipaddr_string(&ip->ip_src), sizeof(srcaddr));
+ strlcpy(dstaddr, ipaddr_string(&ip->ip_dst), sizeof(dstaddr));
+ break;
+#ifdef INET6
+ case 6:
+ ip6 = (struct ip6_hdr *)bp;
+ strlcpy(srcaddr, ip6addr_string(&ip6->ip6_src),
+ sizeof(srcaddr));
+ strlcpy(dstaddr, ip6addr_string(&ip6->ip6_dst),
+ sizeof(dstaddr));
+ break;
+#endif
+ default:
+ strlcpy(srcaddr, "?", sizeof(srcaddr));
+ strlcpy(dstaddr, "?", sizeof(dstaddr));
+ break;
+ }
+
+ (void)printf("%s.%s > %s.%s: ", srcaddr, s, dstaddr, d);
+}
+
static const u_int32_t *
parse_sattr3(const u_int32_t *dp, struct nfsv3_sattr *sa3)
{
- register const u_int32_t *ep = (u_int32_t *)snapend;
-
- if (dp + 1 > ep)
- return (NULL);
+ TCHECK(dp[0]);
if ((sa3->sa_modeset = ntohl(*dp++))) {
- if (dp + 1 > ep)
- return (NULL);
+ TCHECK(dp[0]);
sa3->sa_mode = ntohl(*dp++);
}
- if (dp + 1 > ep)
- return (NULL);
+ TCHECK(dp[0]);
if ((sa3->sa_uidset = ntohl(*dp++))) {
- if (dp + 1 > ep)
- return (NULL);
+ TCHECK(dp[0]);
sa3->sa_uid = ntohl(*dp++);
}
- if (dp + 1 > ep)
- return (NULL);
+ TCHECK(dp[0]);
if ((sa3->sa_gidset = ntohl(*dp++))) {
- if (dp + 1 > ep)
- return (NULL);
+ TCHECK(dp[0]);
sa3->sa_gid = ntohl(*dp++);
}
- if (dp + 1 > ep)
- return (NULL);
+ TCHECK(dp[0]);
if ((sa3->sa_sizeset = ntohl(*dp++))) {
- if (dp + 1 > ep)
- return (NULL);
+ TCHECK(dp[0]);
sa3->sa_size = ntohl(*dp++);
}
- if (dp + 1 > ep)
- return (NULL);
+ TCHECK(dp[0]);
if ((sa3->sa_atimetype = ntohl(*dp++)) == NFSV3SATTRTIME_TOCLIENT) {
- if (dp + 2 > ep)
- return (NULL);
+ TCHECK(dp[1]);
sa3->sa_atime.nfsv3_sec = ntohl(*dp++);
sa3->sa_atime.nfsv3_nsec = ntohl(*dp++);
}
- if (dp + 1 > ep)
- return (NULL);
+ TCHECK(dp[0]);
if ((sa3->sa_mtimetype = ntohl(*dp++)) == NFSV3SATTRTIME_TOCLIENT) {
- if (dp + 2 > ep)
- return (NULL);
+ TCHECK(dp[1]);
sa3->sa_mtime.nfsv3_sec = ntohl(*dp++);
sa3->sa_mtime.nfsv3_nsec = ntohl(*dp++);
}
return dp;
+trunc:
+ return NULL;
}
-void
+static int nfserr; /* true if we error rather than trunc */
+
+static void
print_sattr3(const struct nfsv3_sattr *sa3, int verbose)
{
if (sa3->sa_modeset)
@@ -239,41 +324,37 @@ nfsreply_print(register const u_char *bp, u_int length,
register const u_char *bp2)
{
register const struct rpc_msg *rp;
- register const struct ip *ip;
u_int32_t proc, vers;
+ char srcid[20], dstid[20]; /*fits 32bit*/
nfserr = 0; /* assume no error */
rp = (const struct rpc_msg *)bp;
- ip = (const struct ip *)bp2;
-
- if (!nflag)
- (void)printf("%s.nfs > %s.%u: reply %s %d",
- ipaddr_string(&ip->ip_src),
- ipaddr_string(&ip->ip_dst),
- (u_int32_t)ntohl(rp->rm_xid),
- ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED?
- "ok":"ERR",
- length);
- else
- (void)printf("%s.%u > %s.%u: reply %s %d",
- ipaddr_string(&ip->ip_src),
- NFS_PORT,
- ipaddr_string(&ip->ip_dst),
- (u_int32_t)ntohl(rp->rm_xid),
- ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED?
- "ok":"ERR",
+
+ if (!nflag) {
+ strlcpy(srcid, "nfs", sizeof(srcid));
+ snprintf(dstid, sizeof(dstid), "%u",
+ (u_int32_t)ntohl(rp->rm_xid));
+ } else {
+ snprintf(srcid, sizeof(srcid), "%u", NFS_PORT);
+ snprintf(dstid, sizeof(dstid), "%u",
+ (u_int32_t)ntohl(rp->rm_xid));
+ }
+ print_nfsaddr(bp2, srcid, dstid);
+ (void)printf("reply %s %d",
+ ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED?
+ "ok":"ERR",
length);
- if (xid_map_find(rp, ip, &proc, &vers) >= 0)
+ if (xid_map_find(rp, bp2, &proc, &vers) >= 0)
interp_reply(rp, proc, vers, length);
}
/*
* Return a pointer to the first file handle in the packet.
- * If the packet was truncated, return NULL.
+ * If the packet was truncated, return 0.
*/
static const u_int32_t *
-parsereq(register const struct rpc_msg *rp, register int length)
+parsereq(register const struct rpc_msg *rp, register u_int length)
{
register const u_int32_t *dp;
register u_int len;
@@ -300,7 +381,7 @@ trunc:
/*
* Print out an NFS file handle and return a pointer to following word.
- * If packet was truncated, return NULL.
+ * If packet was truncated, return 0.
*/
static const u_int32_t *
parsefh(register const u_int32_t *dp, int v3)
@@ -324,7 +405,7 @@ trunc:
/*
* Print out a file name and return pointer to 32-bit word past it.
- * If packet was truncated, return NULL.
+ * If packet was truncated, return 0.
*/
static const u_int32_t *
parsefn(register const u_int32_t *dp)
@@ -333,30 +414,31 @@ parsefn(register const u_int32_t *dp)
register const u_char *cp;
/* Bail if we don't have the string length */
- if ((u_char *)dp > snapend - sizeof(*dp))
- return (NULL);
+ TCHECK(*dp);
/* Fetch string length; convert to host order */
len = *dp++;
NTOHL(len);
+ TCHECK2(*dp, ((len + 3) & ~3));
+
cp = (u_char *)dp;
/* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */
dp += ((len + 3) & ~3) / sizeof(*dp);
- if ((u_char *)dp > snapend)
- return (NULL);
/* XXX seems like we should be checking the length */
putchar('"');
(void) fn_printn(cp, len, NULL);
putchar('"');
return (dp);
+trunc:
+ return NULL;
}
/*
* Print out file handle and file name.
* Return pointer to 32-bit word past file name.
- * If packet was truncated (or there was some other error), return NULL.
+ * If packet was truncated (or there was some other error), return 0.
*/
static const u_int32_t *
parsefhn(register const u_int32_t *dp, int v3)
@@ -373,30 +455,28 @@ nfsreq_print(register const u_char *bp, u_int length,
register const u_char *bp2)
{
register const struct rpc_msg *rp;
- register const struct ip *ip;
register const u_int32_t *dp;
- nfstype type;
- int proc, v3;
+ nfs_type type;
+ int v3;
+ u_int32_t proc;
struct nfsv3_sattr sa3;
+ char srcid[20], dstid[20]; /*fits 32bit*/
nfserr = 0; /* assume no error */
rp = (const struct rpc_msg *)bp;
- ip = (const struct ip *)bp2;
- if (!nflag)
- (void)printf("%s.%u > %s.nfs: %d",
- ipaddr_string(&ip->ip_src),
- (u_int32_t)ntohl(rp->rm_xid),
- ipaddr_string(&ip->ip_dst),
- length);
- else
- (void)printf("%s.%u > %s.%u: %d",
- ipaddr_string(&ip->ip_src),
- (u_int32_t)ntohl(rp->rm_xid),
- ipaddr_string(&ip->ip_dst),
- NFS_PORT,
- length);
+ if (!nflag) {
+ snprintf(srcid, sizeof(srcid), "%u",
+ (u_int32_t)ntohl(rp->rm_xid));
+ strlcpy(dstid, "nfs", sizeof(dstid));
+ } else {
+ snprintf(srcid, sizeof(srcid), "%u",
+ (u_int32_t)ntohl(rp->rm_xid));
+ snprintf(dstid, sizeof(dstid), "%u", NFS_PORT);
+ }
+ print_nfsaddr(bp2, srcid, dstid);
+ (void)printf("%d", length);
- xid_map_enter(rp, ip); /* record proc number for later on */
+ xid_map_enter(rp, bp2); /* record proc number for later on */
v3 = (ntohl(rp->rm_call.cb_vers) == NFS_VER3);
proc = ntohl(rp->rm_call.cb_proc);
@@ -414,19 +494,22 @@ nfsreq_print(register const u_char *bp, u_int length,
case NFSPROC_GETATTR:
printf(" getattr");
- if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL)
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefh(dp, v3) != NULL)
return;
break;
case NFSPROC_SETATTR:
printf(" setattr");
- if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL)
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefh(dp, v3) != NULL)
return;
break;
case NFSPROC_LOOKUP:
printf(" lookup");
- if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL)
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefhn(dp, v3) != NULL)
return;
break;
@@ -434,15 +517,16 @@ nfsreq_print(register const u_char *bp, u_int length,
printf(" access");
if ((dp = parsereq(rp, length)) != NULL &&
(dp = parsefh(dp, v3)) != NULL) {
- TCHECK(*dp);
- printf(" %04lx", ntohl(dp[0]));
+ TCHECK(dp[0]);
+ printf(" %04x", (u_int32_t)ntohl(dp[0]));
return;
}
break;
case NFSPROC_READLINK:
printf(" readlink");
- if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL)
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefh(dp, v3) != NULL)
return;
break;
@@ -451,13 +535,15 @@ nfsreq_print(register const u_char *bp, u_int length,
if ((dp = parsereq(rp, length)) != NULL &&
(dp = parsefh(dp, v3)) != NULL) {
if (v3) {
- TCHECK2(*dp, 3 * sizeof(*dp));
- printf(" %lu bytes @ ", ntohl(dp[2]));
+ TCHECK(dp[2]);
+ printf(" %u bytes @ ",
+ (u_int32_t) ntohl(dp[2]));
print_int64(dp, UNSIGNED);
} else {
- TCHECK2(*dp, 2 * sizeof(*dp));
- printf(" %lu bytes @ %lu",
- ntohl(dp[1]), ntohl(dp[0]));
+ TCHECK(dp[1]);
+ printf(" %u bytes @ %u",
+ (u_int32_t)ntohl(dp[1]),
+ (u_int32_t)ntohl(dp[0]));
}
return;
}
@@ -468,20 +554,24 @@ nfsreq_print(register const u_char *bp, u_int length,
if ((dp = parsereq(rp, length)) != NULL &&
(dp = parsefh(dp, v3)) != NULL) {
if (v3) {
- TCHECK2(*dp, 3 * sizeof(*dp));
- printf(" %lu bytes @ ", ntohl(dp[4]));
+ TCHECK(dp[4]);
+ printf(" %u bytes @ ",
+ (u_int32_t) ntohl(dp[4]));
print_int64(dp, UNSIGNED);
if (vflag) {
dp += 3;
- TCHECK2(*dp, sizeof(*dp));
+ TCHECK(dp[0]);
printf(" <%s>",
- nfsv3_writemodes[ntohl(*dp)]);
+ tok2str(nfsv3_writemodes,
+ NULL, ntohl(*dp)));
}
} else {
- TCHECK2(*dp, 4 * sizeof(*dp));
- printf(" %lu (%lu) bytes @ %lu (%lu)",
- ntohl(dp[3]), ntohl(dp[2]),
- ntohl(dp[1]), ntohl(dp[0]));
+ TCHECK(dp[3]);
+ printf(" %u (%u) bytes @ %u (%u)",
+ (u_int32_t)ntohl(dp[3]),
+ (u_int32_t)ntohl(dp[2]),
+ (u_int32_t)ntohl(dp[1]),
+ (u_int32_t)ntohl(dp[0]));
}
return;
}
@@ -489,24 +579,25 @@ nfsreq_print(register const u_char *bp, u_int length,
case NFSPROC_CREATE:
printf(" create");
- if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL)
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefhn(dp, v3) != NULL)
return;
break;
case NFSPROC_MKDIR:
printf(" mkdir");
- if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL)
+ if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp, v3) != 0)
return;
break;
case NFSPROC_SYMLINK:
printf(" symlink");
- if ((dp = parsereq(rp, length)) != NULL &&
- (dp = parsefhn(dp, v3)) != NULL) {
- fputs(" -> ", stdout);
- if (v3 && (dp = parse_sattr3(dp, &sa3)) == NULL)
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefhn(dp, v3)) != 0) {
+ fputs(" ->", stdout);
+ if (v3 && (dp = parse_sattr3(dp, &sa3)) == 0)
break;
- if (parsefn(dp) == NULL)
+ if (parsefn(dp) == 0)
break;
if (v3 && vflag)
print_sattr3(&sa3, vflag);
@@ -516,18 +607,18 @@ nfsreq_print(register const u_char *bp, u_int length,
case NFSPROC_MKNOD:
printf(" mknod");
- if ((dp = parsereq(rp, length)) != NULL &&
- (dp = parsefhn(dp, v3)) != NULL) {
- if (dp + 1 > (u_int32_t *)snapend)
- break;
- type = (nfstype)ntohl(*dp++);
- if ((dp = parse_sattr3(dp, &sa3)) == NULL)
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefhn(dp, v3)) != 0) {
+ TCHECK(*dp);
+ type = (nfs_type)ntohl(*dp++);
+ if ((dp = parse_sattr3(dp, &sa3)) == 0)
break;
printf(" %s", tok2str(type2str, "unk-ft %d", type));
if (vflag && (type == NFCHR || type == NFBLK)) {
- if (dp + 2 > (u_int32_t *)snapend)
- break;
- printf(" %lu/%lu", ntohl(dp[0]), ntohl(dp[1]));
+ TCHECK(dp[1]);
+ printf(" %u/%u",
+ (u_int32_t)ntohl(dp[0]),
+ (u_int32_t)ntohl(dp[1]));
dp += 2;
}
if (vflag)
@@ -538,13 +629,15 @@ nfsreq_print(register const u_char *bp, u_int length,
case NFSPROC_REMOVE:
printf(" remove");
- if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL)
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefhn(dp, v3) != NULL)
return;
break;
case NFSPROC_RMDIR:
printf(" rmdir");
- if ((dp = parsereq(rp, length)) != NULL && parsefhn(dp, v3) != NULL)
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefhn(dp, v3) != NULL)
return;
break;
@@ -573,24 +666,26 @@ nfsreq_print(register const u_char *bp, u_int length,
if ((dp = parsereq(rp, length)) != NULL &&
(dp = parsefh(dp, v3)) != NULL) {
if (v3) {
- TCHECK2(*dp, 20);
+ TCHECK(dp[4]);
/*
* We shouldn't really try to interpret the
* offset cookie here.
*/
- printf(" %lu bytes @ ", ntohl(dp[4]));
+ printf(" %u bytes @ ",
+ (u_int32_t) ntohl(dp[4]));
print_int64(dp, SIGNED);
if (vflag)
printf(" verf %08x%08x", dp[2],
dp[3]);
} else {
- TCHECK2(*dp, 2 * sizeof(*dp));
+ TCHECK(dp[1]);
/*
* 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]));
+ printf(" %u bytes @ %d",
+ (u_int32_t)ntohl(dp[1]),
+ (u_int32_t)ntohl(dp[0]));
}
return;
}
@@ -600,23 +695,24 @@ nfsreq_print(register const u_char *bp, u_int length,
printf(" readdirplus");
if ((dp = parsereq(rp, length)) != NULL &&
(dp = parsefh(dp, v3)) != NULL) {
- TCHECK2(*dp, 20);
+ TCHECK(dp[4]);
/*
* We don't try to interpret the offset
* cookie here.
*/
- printf(" %lu bytes @ ", ntohl(dp[4]));
+ printf(" %u bytes @ ", (u_int32_t) ntohl(dp[4]));
print_int64(dp, SIGNED);
if (vflag)
- printf(" max %lu verf %08x%08x",
- ntohl(dp[5]), dp[2], dp[3]);
+ printf(" max %u verf %08x%08x",
+ (u_int32_t) ntohl(dp[5]), dp[2], dp[3]);
return;
}
break;
case NFSPROC_FSSTAT:
printf(" fsstat");
- if ((dp = parsereq(rp, length)) != NULL && parsefh(dp, v3) != NULL)
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefh(dp, v3) != NULL)
return;
break;
@@ -632,16 +728,17 @@ nfsreq_print(register const u_char *bp, u_int length,
printf(" commit");
if ((dp = parsereq(rp, length)) != NULL &&
(dp = parsefh(dp, v3)) != NULL) {
- printf(" %lu bytes @ ", ntohl(dp[2]));
+ printf(" %u bytes @ ", (u_int32_t) ntohl(dp[2]));
print_int64(dp, UNSIGNED);
return;
}
break;
default:
- printf(" proc-%lu", ntohl(rp->rm_call.cb_proc));
+ printf(" proc-%u", (u_int32_t)ntohl(rp->rm_call.cb_proc));
return;
}
+
trunc:
if (!nfserr)
fputs(" [|nfs]", stdout);
@@ -657,13 +754,13 @@ trunc:
* additional hacking on the parser code.
*/
static void
-nfs_printfh(register const u_int32_t *dp, const int len)
+nfs_printfh(register const u_int32_t *dp, const u_int len)
{
my_fsid fsid;
ino_t ino;
char *sfsname = NULL;
- Parse_fh((caddr_t *)dp, len, &fsid, &ino, NULL, &sfsname, 0);
+ Parse_fh((caddr_t*)dp, len, &fsid, &ino, NULL, &sfsname, 0);
if (sfsname) {
/* file system ID is ASCII, not numeric, for this server OS */
@@ -671,16 +768,23 @@ nfs_printfh(register const u_int32_t *dp, const int len)
/* Make sure string is null-terminated */
strncpy(temp, sfsname, NFSX_V3FHMAX);
+ temp[sizeof(temp) - 1] = '\0';
/* Remove trailing spaces */
sfsname = strchr(temp, ' ');
if (sfsname)
*sfsname = 0;
- (void)printf(" fh %s/%u", temp, (u_int32_t)ino);
+ (void)printf(" fh %s/", temp);
} else {
- (void)printf(" fh %u,%u/%u",
- fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor, (u_int32_t)ino);
+ (void)printf(" fh %d,%d/",
+ fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor);
}
+
+ if(fsid.Fsid_dev.Minor == 257 && uflag)
+ /* Print the undecoded handle */
+ (void)printf("%s", fsid.Opaque_Handle);
+ else
+ (void)printf("%ld", (long) ino);
}
/*
@@ -690,11 +794,17 @@ nfs_printfh(register const u_int32_t *dp, const int len)
*/
struct xid_map_entry {
- u_int32_t xid; /* transaction ID (net order) */
+ u_int32_t xid; /* transaction ID (net order) */
+ int ipver; /* IP version (4 or 6) */
+#ifdef INET6
+ struct in6_addr client; /* client IP address (net order) */
+ struct in6_addr server; /* server IP address (net order) */
+#else
struct in_addr client; /* client IP address (net order) */
struct in_addr server; /* server IP address (net order) */
- u_int32_t proc; /* call proc number (host order) */
- u_int32_t vers; /* program version (host order) */
+#endif
+ u_int32_t proc; /* call proc number (host order) */
+ u_int32_t vers; /* program version (host order) */
};
/*
@@ -711,18 +821,45 @@ int xid_map_next = 0;
int xid_map_hint = 0;
static void
-xid_map_enter(const struct rpc_msg *rp, const struct ip *ip)
+xid_map_enter(const struct rpc_msg *rp, const u_char *bp)
{
+ struct ip *ip = NULL;
+#ifdef INET6
+ struct ip6_hdr *ip6 = NULL;
+#endif
struct xid_map_entry *xmep;
+ switch (IP_V((struct ip *)bp)) {
+ case 4:
+ ip = (struct ip *)bp;
+ break;
+#ifdef INET6
+ case 6:
+ ip6 = (struct ip6_hdr *)bp;
+ break;
+#endif
+ default:
+ return;
+ }
+
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;
+ if (ip) {
+ xmep->ipver = 4;
+ memcpy(&xmep->client, &ip->ip_src, sizeof(ip->ip_src));
+ memcpy(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst));
+ }
+#ifdef INET6
+ else if (ip6) {
+ xmep->ipver = 6;
+ memcpy(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src));
+ memcpy(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
+ }
+#endif
xmep->proc = ntohl(rp->rm_call.cb_proc);
xmep->vers = ntohl(rp->rm_call.cb_vers);
}
@@ -732,33 +869,62 @@ xid_map_enter(const struct rpc_msg *rp, const struct ip *ip)
* version in vers return, or returns -1 on failure
*/
static int
-xid_map_find(const struct rpc_msg *rp, const struct ip *ip, u_int32_t *proc,
+xid_map_find(const struct rpc_msg *rp, const u_char *bp, u_int32_t *proc,
u_int32_t *vers)
{
int i;
struct xid_map_entry *xmep;
u_int32_t xid = rp->rm_xid;
- u_int32_t clip = ip->ip_dst.s_addr;
- u_int32_t sip = ip->ip_src.s_addr;
+ struct ip *ip = (struct ip *)bp;
+#ifdef INET6
+ struct ip6_hdr *ip6 = (struct ip6_hdr *)bp;
+#endif
+ int cmp;
/* Start searching from where we last left off */
- i = xid_map_hint;
+ i = xid_map_hint;
do {
xmep = &xid_map[i];
- if (xmep->xid == xid && xmep->client.s_addr == clip &&
- xmep->server.s_addr == sip) {
+ cmp = 1;
+ if (xmep->ipver != IP_V(ip) || xmep->xid != xid)
+ goto nextitem;
+ switch (xmep->ipver) {
+ case 4:
+ if (memcmp(&ip->ip_src, &xmep->server,
+ sizeof(ip->ip_src)) != 0 ||
+ memcmp(&ip->ip_dst, &xmep->client,
+ sizeof(ip->ip_dst)) != 0) {
+ cmp = 0;
+ }
+ break;
+#ifdef INET6
+ case 6:
+ if (memcmp(&ip6->ip6_src, &xmep->server,
+ sizeof(ip6->ip6_src)) != 0 ||
+ memcmp(&ip6->ip6_dst, &xmep->client,
+ sizeof(ip6->ip6_dst)) != 0) {
+ cmp = 0;
+ }
+ break;
+#endif
+ default:
+ cmp = 0;
+ break;
+ }
+ if (cmp) {
/* match */
xid_map_hint = i;
*proc = xmep->proc;
*vers = xmep->vers;
return 0;
}
+ nextitem:
if (++i >= XIDMAPSIZE)
i = 0;
} while (i != xid_map_hint);
/* search failed */
- return (0);
+ return (-1);
}
/*
@@ -767,13 +933,13 @@ xid_map_find(const struct rpc_msg *rp, const struct ip *ip, u_int32_t *proc,
/*
* Return a pointer to the beginning of the actual results.
- * If the packet was truncated, return NULL.
+ * If the packet was truncated, return 0.
*/
static const u_int32_t *
-parserep(register const struct rpc_msg *rp, register int length)
+parserep(register const struct rpc_msg *rp, register u_int length)
{
register const u_int32_t *dp;
- int len;
+ u_int len;
enum accept_stat astat;
/*
@@ -792,7 +958,7 @@ parserep(register const struct rpc_msg *rp, register int length)
* which is an "enum" and so occupies one 32-bit word.
*/
dp = ((const u_int32_t *)&rp->rm_reply) + 1;
- TCHECK2(dp[0], 1);
+ TCHECK(dp[1]);
len = ntohl(dp[1]);
if (len >= length)
return (NULL);
@@ -842,32 +1008,32 @@ parserep(register const struct rpc_msg *rp, register int length)
return (NULL);
}
/* successful return */
- if ((sizeof(astat) + ((u_char *)dp)) < snapend)
- return ((u_int32_t *) (sizeof(astat) + ((char *)dp)));
-
+ TCHECK2(*dp, sizeof(astat));
+ return ((u_int32_t *) (sizeof(astat) + ((char *)dp)));
trunc:
- return (NULL);
+ return (0);
}
-
static const u_int32_t *
parsestatus(const u_int32_t *dp, int *er)
{
- register int errnum;
+ int errnum;
TCHECK(dp[0]);
+
errnum = ntohl(dp[0]);
if (er)
*er = errnum;
if (errnum != 0) {
if (!qflag)
- printf(" ERROR: %s", pcap_strerror(errnum));
+ printf(" ERROR: %s",
+ tok2str(status2str, "unk %d", errnum));
nfserr = 1;
return (NULL);
}
return (dp + 1);
trunc:
- return (NULL);
+ return NULL;
}
static const u_int32_t *
@@ -878,10 +1044,12 @@ parsefattr(const u_int32_t *dp, int verbose, int v3)
fap = (const struct nfs_fattr *)dp;
TCHECK(fap->fa_gid);
if (verbose) {
- printf(" %s %lo ids %ld/%ld",
- tok2str(type2str, "unk-ft %d ", ntohl(fap->fa_type)),
- ntohl(fap->fa_mode), ntohl(fap->fa_uid),
- ntohl(fap->fa_gid));
+ printf(" %s %o ids %d/%d",
+ tok2str(type2str, "unk-ft %d ",
+ (u_int32_t)ntohl(fap->fa_type)),
+ (u_int32_t)ntohl(fap->fa_mode),
+ (u_int32_t)ntohl(fap->fa_uid),
+ (u_int32_t) ntohl(fap->fa_gid));
if (v3) {
TCHECK(fap->fa3_size);
printf(" sz ");
@@ -889,44 +1057,46 @@ parsefattr(const u_int32_t *dp, int verbose, int v3)
putchar(' ');
} else {
TCHECK(fap->fa2_size);
- printf(" sz %ld ", ntohl(fap->fa2_size));
+ printf(" sz %d ", (u_int32_t) ntohl(fap->fa2_size));
}
}
/* print lots more stuff */
if (verbose > 1) {
if (v3) {
TCHECK(fap->fa3_ctime);
- printf("nlink %ld rdev %ld/%ld ",
- ntohl(fap->fa_nlink),
- ntohl(fap->fa3_rdev.specdata1),
- ntohl(fap->fa3_rdev.specdata2));
+ printf("nlink %d rdev %d/%d ",
+ (u_int32_t)ntohl(fap->fa_nlink),
+ (u_int32_t) ntohl(fap->fa3_rdev.specdata1),
+ (u_int32_t) ntohl(fap->fa3_rdev.specdata2));
printf("fsid ");
print_int64((u_int32_t *)&fap->fa2_fsid, HEX);
printf(" nodeid ");
print_int64((u_int32_t *)&fap->fa2_fileid, HEX);
- printf(" a/m/ctime %lu.%06lu ",
- ntohl(fap->fa3_atime.nfsv3_sec),
- ntohl(fap->fa3_atime.nfsv3_nsec));
- printf("%lu.%06lu ",
- ntohl(fap->fa3_mtime.nfsv3_sec),
- ntohl(fap->fa3_mtime.nfsv3_nsec));
- printf("%lu.%06lu ",
- ntohl(fap->fa3_ctime.nfsv3_sec),
- ntohl(fap->fa3_ctime.nfsv3_nsec));
+ printf(" a/m/ctime %u.%06u ",
+ (u_int32_t) ntohl(fap->fa3_atime.nfsv3_sec),
+ (u_int32_t) ntohl(fap->fa3_atime.nfsv3_nsec));
+ printf("%u.%06u ",
+ (u_int32_t) ntohl(fap->fa3_mtime.nfsv3_sec),
+ (u_int32_t) ntohl(fap->fa3_mtime.nfsv3_nsec));
+ printf("%u.%06u ",
+ (u_int32_t) ntohl(fap->fa3_ctime.nfsv3_sec),
+ (u_int32_t) ntohl(fap->fa3_ctime.nfsv3_nsec));
} else {
TCHECK(fap->fa2_ctime);
- printf("nlink %ld rdev %lx fsid %lx nodeid %lx a/m/ctime ",
- ntohl(fap->fa_nlink), ntohl(fap->fa2_rdev),
- ntohl(fap->fa2_fsid), ntohl(fap->fa2_fileid));
- printf("%lu.%06lu ",
- ntohl(fap->fa2_atime.nfsv2_sec),
- ntohl(fap->fa2_atime.nfsv2_usec));
- printf("%lu.%06lu ",
- ntohl(fap->fa2_mtime.nfsv2_sec),
- ntohl(fap->fa2_mtime.nfsv2_usec));
- printf("%lu.%06lu ",
- ntohl(fap->fa2_ctime.nfsv2_sec),
- ntohl(fap->fa2_ctime.nfsv2_usec));
+ printf("nlink %d rdev %x fsid %x nodeid %x a/m/ctime ",
+ (u_int32_t) ntohl(fap->fa_nlink),
+ (u_int32_t) ntohl(fap->fa2_rdev),
+ (u_int32_t) ntohl(fap->fa2_fsid),
+ (u_int32_t) ntohl(fap->fa2_fileid));
+ printf("%u.%06u ",
+ (u_int32_t) ntohl(fap->fa2_atime.nfsv2_sec),
+ (u_int32_t) ntohl(fap->fa2_atime.nfsv2_usec));
+ printf("%u.%06u ",
+ (u_int32_t) ntohl(fap->fa2_mtime.nfsv2_sec),
+ (u_int32_t) ntohl(fap->fa2_mtime.nfsv2_usec));
+ printf("%u.%06u ",
+ (u_int32_t) ntohl(fap->fa2_ctime.nfsv2_sec),
+ (u_int32_t) ntohl(fap->fa2_ctime.nfsv2_usec));
}
}
return ((const u_int32_t *)((unsigned char *)dp +
@@ -952,8 +1122,7 @@ parsediropres(const u_int32_t *dp)
{
int er;
- dp = parsestatus(dp, &er);
- if (dp == NULL || er)
+ if (!(dp = parsestatus(dp, &er)) || er)
return (0);
dp = parsefh(dp, 0);
@@ -971,10 +1140,8 @@ parselinkres(const u_int32_t *dp, int v3)
dp = parsestatus(dp, &er);
if (dp == NULL || er)
return(0);
-
- if (v3 && ((dp = parse_post_op_attr(dp, vflag)) != NULL))
+ if (v3 && !(dp = parse_post_op_attr(dp, vflag)))
return (0);
-
putchar(' ');
return (parsefn(dp) != NULL);
}
@@ -987,7 +1154,7 @@ parsestatfs(const u_int32_t *dp, int v3)
dp = parsestatus(dp, &er);
if (dp == NULL || (!v3 && er))
- return(0);
+ return (0);
if (qflag)
return(1);
@@ -995,7 +1162,7 @@ parsestatfs(const u_int32_t *dp, int v3)
if (v3) {
if (vflag)
printf(" POST:");
- if ((dp = parse_post_op_attr(dp, vflag)) == NULL)
+ if (!(dp = parse_post_op_attr(dp, vflag)))
return (0);
}
@@ -1017,13 +1184,16 @@ parsestatfs(const u_int32_t *dp, int v3)
print_int64((u_int32_t *)&sfsp->sf_ffiles, UNSIGNED);
printf(" afiles ");
print_int64((u_int32_t *)&sfsp->sf_afiles, UNSIGNED);
- printf(" invar %lu", ntohl(sfsp->sf_invarsec));
+ printf(" invar %u",
+ (u_int32_t) ntohl(sfsp->sf_invarsec));
}
} else {
- printf(" tsize %ld bsize %ld blocks %ld bfree %ld bavail %ld",
- ntohl(sfsp->sf_tsize), ntohl(sfsp->sf_bsize),
- ntohl(sfsp->sf_blocks), ntohl(sfsp->sf_bfree),
- ntohl(sfsp->sf_bavail));
+ printf(" tsize %d bsize %d blocks %d bfree %d bavail %d",
+ (u_int32_t)ntohl(sfsp->sf_tsize),
+ (u_int32_t)ntohl(sfsp->sf_bsize),
+ (u_int32_t)ntohl(sfsp->sf_blocks),
+ (u_int32_t)ntohl(sfsp->sf_bfree),
+ (u_int32_t)ntohl(sfsp->sf_bavail));
}
return (1);
@@ -1037,15 +1207,16 @@ parserddires(const u_int32_t *dp)
int er;
dp = parsestatus(dp, &er);
- if (dp == NULL || er)
+ if (dp == 0 || er)
return (0);
if (qflag)
return (1);
TCHECK(dp[2]);
- printf(" offset %lx size %ld ", ntohl(dp[0]), ntohl(dp[1]));
+ printf(" offset %x size %d ",
+ (u_int32_t)ntohl(dp[0]), (u_int32_t)ntohl(dp[1]));
if (dp[2] != 0)
- printf("eof");
+ printf(" eof");
return (1);
trunc:
@@ -1057,8 +1228,9 @@ parse_wcc_attr(const u_int32_t *dp)
{
printf(" sz ");
print_int64(dp, UNSIGNED);
- printf(" mtime %lu.%06lu ctime %lu.%06lu", ntohl(dp[2]), ntohl(dp[3]),
- ntohl(dp[4]), ntohl(dp[5]));
+ printf(" mtime %u.%06u ctime %u.%06u",
+ (u_int32_t)ntohl(dp[2]), (u_int32_t)ntohl(dp[3]),
+ (u_int32_t)ntohl(dp[4]), (u_int32_t)ntohl(dp[5]));
return (dp + 6);
}
@@ -1106,8 +1278,8 @@ parse_wcc_data(const u_int32_t *dp, int verbose)
{
if (verbose > 1)
printf(" PRE:");
- if ((dp = parse_pre_op_attr(dp, verbose)) == NULL)
- return (NULL);
+ if (!(dp = parse_pre_op_attr(dp, verbose)))
+ return (0);
if (verbose)
printf(" POST:");
@@ -1119,8 +1291,8 @@ parsecreateopres(const u_int32_t *dp, int verbose)
{
int er;
- if ((dp = parsestatus(dp, &er)) == NULL)
- return (NULL);
+ if (!(dp = parsestatus(dp, &er)))
+ return (0);
if (er)
dp = parse_wcc_data(dp, verbose);
else {
@@ -1128,11 +1300,11 @@ parsecreateopres(const u_int32_t *dp, int verbose)
if (!ntohl(dp[0]))
return (dp + 1);
dp++;
- if ((dp = parsefh(dp, 1)) == NULL)
- return (NULL);
+ if (!(dp = parsefh(dp, 1)))
+ return (0);
if (verbose) {
- if ((dp = parse_post_op_attr(dp, verbose)) == NULL)
- return (NULL);
+ if (!(dp = parse_post_op_attr(dp, verbose)))
+ return (0);
if (vflag > 1) {
printf("dir attr:");
dp = parse_wcc_data(dp, verbose);
@@ -1149,9 +1321,9 @@ parsewccres(const u_int32_t *dp, int verbose)
{
int er;
- if ((dp = parsestatus(dp, &er)) == NULL)
+ if (!(dp = parsestatus(dp, &er)))
return (0);
- return parse_wcc_data(dp, verbose) != NULL;
+ return parse_wcc_data(dp, verbose) != 0;
}
static const u_int32_t *
@@ -1159,12 +1331,12 @@ parsev3rddirres(const u_int32_t *dp, int verbose)
{
int er;
- if ((dp = parsestatus(dp, &er)) == NULL)
- return (NULL);
+ if (!(dp = parsestatus(dp, &er)))
+ return (0);
if (vflag)
printf(" POST:");
- if ((dp = parse_post_op_attr(dp, verbose)) == NULL)
- return (NULL);
+ if (!(dp = parse_post_op_attr(dp, verbose)))
+ return (0);
if (er)
return dp;
if (vflag) {
@@ -1183,31 +1355,35 @@ parsefsinfo(const u_int32_t *dp)
struct nfsv3_fsinfo *sfp;
int er;
- if ((dp = parsestatus(dp, &er)) == NULL)
+ if (!(dp = parsestatus(dp, &er)))
return (0);
if (vflag)
printf(" POST:");
- if ((dp = parse_post_op_attr(dp, vflag)) == NULL)
+ if (!(dp = parse_post_op_attr(dp, vflag)))
return (0);
if (er)
return (1);
sfp = (struct nfsv3_fsinfo *)dp;
TCHECK(*sfp);
- printf(" rtmax %lu rtpref %lu wtmax %lu wtpref %lu dtpref %lu",
- ntohl(sfp->fs_rtmax), ntohl(sfp->fs_rtpref),
- ntohl(sfp->fs_wtmax), ntohl(sfp->fs_wtpref),
- ntohl(sfp->fs_dtpref));
+ printf(" rtmax %u rtpref %u wtmax %u wtpref %u dtpref %u",
+ (u_int32_t) ntohl(sfp->fs_rtmax),
+ (u_int32_t) ntohl(sfp->fs_rtpref),
+ (u_int32_t) ntohl(sfp->fs_wtmax),
+ (u_int32_t) ntohl(sfp->fs_wtpref),
+ (u_int32_t) ntohl(sfp->fs_dtpref));
if (vflag) {
- printf(" rtmult %lu wtmult %lu maxfsz ",
- ntohl(sfp->fs_rtmult), ntohl(sfp->fs_wtmult));
+ printf(" rtmult %u wtmult %u maxfsz ",
+ (u_int32_t) ntohl(sfp->fs_rtmult),
+ (u_int32_t) ntohl(sfp->fs_wtmult));
print_int64((u_int32_t *)&sfp->fs_maxfilesize, UNSIGNED);
- printf(" delta %lu.%06lu ", ntohl(sfp->fs_timedelta.nfsv3_sec),
- ntohl(sfp->fs_timedelta.nfsv3_nsec));
+ printf(" delta %u.%06u ",
+ (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_sec),
+ (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_nsec));
}
- return (1);
-trunc:
return (0);
+trunc:
+ return (1);
}
static int
@@ -1216,11 +1392,11 @@ parsepathconf(const u_int32_t *dp)
int er;
struct nfsv3_pathconf *spp;
- if ((dp = parsestatus(dp, &er)) == NULL)
+ if (!(dp = parsestatus(dp, &er)))
return (0);
if (vflag)
printf(" POST:");
- if ((dp = parse_post_op_attr(dp, vflag)) == NULL)
+ if (!(dp = parse_post_op_attr(dp, vflag)))
return (0);
if (er)
return (1);
@@ -1228,24 +1404,23 @@ parsepathconf(const u_int32_t *dp)
spp = (struct nfsv3_pathconf *)dp;
TCHECK(*spp);
- printf(" linkmax %lu namemax %lu %s %s %s %s",
- ntohl(spp->pc_linkmax),
- ntohl(spp->pc_namemax),
+ printf(" linkmax %u namemax %u %s %s %s %s",
+ (u_int32_t) ntohl(spp->pc_linkmax),
+ (u_int32_t) ntohl(spp->pc_namemax),
ntohl(spp->pc_notrunc) ? "notrunc" : "",
ntohl(spp->pc_chownrestricted) ? "chownres" : "",
ntohl(spp->pc_caseinsensitive) ? "igncase" : "",
ntohl(spp->pc_casepreserving) ? "keepcase" : "");
- return (1);
-trunc:
return (0);
+trunc:
+ return (1);
}
-
+
static void
interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int length)
{
register const u_int32_t *dp;
register int v3;
-
int er;
v3 = (vers == NFS_VER3);
@@ -1272,10 +1447,10 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
case NFSPROC_SETATTR:
printf(" setattr");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
return;
if (v3) {
- if (parsewccres(dp, vflag) != 0)
+ if (parsewccres(dp, vflag))
return;
} else {
if (parseattrstat(dp, !qflag, 0) != 0)
@@ -1285,10 +1460,10 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
case NFSPROC_LOOKUP:
printf(" lookup");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if ((dp = parsestatus(dp, &er)) == NULL)
+ if (!(dp = parsestatus(dp, &er)))
break;
if (er) {
if (vflag > 1) {
@@ -1296,15 +1471,15 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
dp = parse_post_op_attr(dp, vflag);
}
} else {
- if ((dp = parsefh(dp, v3)) == NULL)
+ if (!(dp = parsefh(dp, v3)))
break;
- if (((dp = parse_post_op_attr(dp, vflag)) != NULL) &&
- (vflag > 1)) {
+ if ((dp = parse_post_op_attr(dp, vflag)) &&
+ vflag > 1) {
printf(" post dattr:");
dp = parse_post_op_attr(dp, vflag);
}
}
- if (dp != NULL)
+ if (dp)
return;
} else {
if (parsediropres(dp) != 0)
@@ -1315,14 +1490,14 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
case NFSPROC_ACCESS:
printf(" access");
dp = parserep(rp, length);
- if ((dp = parsestatus(dp, &er)) == NULL)
+ if (!(dp = parsestatus(dp, &er)))
break;
if (vflag)
printf(" attr:");
- if ((dp = parse_post_op_attr(dp, vflag)) == NULL)
+ if (!(dp = parse_post_op_attr(dp, vflag)))
break;
if (!er)
- printf(" c %04lx", ntohl(dp[0]));
+ printf(" c %04x", (u_int32_t)ntohl(dp[0]));
return;
case NFSPROC_READLINK:
@@ -1334,18 +1509,18 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
case NFSPROC_READ:
printf(" read");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if ((dp = parsestatus(dp, &er)) == NULL)
+ if (!(dp = parsestatus(dp, &er)))
break;
- if ((dp = parse_post_op_attr(dp, vflag)) == NULL)
+ if (!(dp = parse_post_op_attr(dp, vflag)))
break;
if (er)
return;
if (vflag) {
- TCHECK2(*dp, 8);
- printf("%lu bytes", ntohl(dp[0]));
+ TCHECK(dp[1]);
+ printf("%u bytes", (u_int32_t) ntohl(dp[0]));
if (ntohl(dp[1]))
printf(" EOF");
}
@@ -1358,22 +1533,23 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
case NFSPROC_WRITE:
printf(" write");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if ((dp = parsestatus(dp, &er)) == NULL)
+ if (!(dp = parsestatus(dp, &er)))
break;
- if ((dp = parse_wcc_data(dp, vflag)) == NULL)
+ if (!(dp = parse_wcc_data(dp, vflag)))
break;
if (er)
return;
if (vflag) {
- TCHECK2(*dp, 4);
- printf("%lu bytes", ntohl(dp[0]));
+ TCHECK(dp[0]);
+ printf("%u bytes", (u_int32_t) ntohl(dp[0]));
if (vflag > 1) {
- TCHECK2(*dp, 4);
+ TCHECK(dp[1]);
printf(" <%s>",
- nfsv3_writemodes[ntohl(dp[1])]);
+ tok2str(nfsv3_writemodes,
+ NULL, ntohl(dp[1])));
}
return;
}
@@ -1385,10 +1561,10 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
case NFSPROC_CREATE:
printf(" create");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if (parsecreateopres(dp, vflag) != NULL)
+ if (parsecreateopres(dp, vflag) != 0)
return;
} else {
if (parsediropres(dp) != 0)
@@ -1398,10 +1574,10 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
case NFSPROC_MKDIR:
printf(" mkdir");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if (parsecreateopres(dp, vflag) != NULL)
+ if (parsecreateopres(dp, vflag) != 0)
return;
} else {
if (parsediropres(dp) != 0)
@@ -1411,101 +1587,101 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
case NFSPROC_SYMLINK:
printf(" symlink");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if (parsecreateopres(dp, vflag) != NULL)
+ if (parsecreateopres(dp, vflag) != 0)
return;
} else {
- if (parsestatus(dp, &er) != NULL)
+ if (parsestatus(dp, &er) != 0)
return;
}
break;
case NFSPROC_MKNOD:
printf(" mknod");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
- if (parsecreateopres(dp, vflag) != NULL)
+ if (parsecreateopres(dp, vflag) != 0)
return;
break;
case NFSPROC_REMOVE:
printf(" remove");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if (parsewccres(dp, vflag) != 0)
+ if (parsewccres(dp, vflag))
return;
} else {
- if (parsestatus(dp, &er) != NULL)
+ if (parsestatus(dp, &er) != 0)
return;
}
break;
case NFSPROC_RMDIR:
printf(" rmdir");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if (parsewccres(dp, vflag) != 0)
+ if (parsewccres(dp, vflag))
return;
} else {
- if (parsestatus(dp, &er) != NULL)
+ if (parsestatus(dp, &er) != 0)
return;
}
break;
case NFSPROC_RENAME:
printf(" rename");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if ((dp = parsestatus(dp, &er)) == NULL)
+ if (!(dp = parsestatus(dp, &er)))
break;
if (vflag) {
printf(" from:");
- if ((dp = parse_wcc_data(dp, vflag)) == NULL)
+ if (!(dp = parse_wcc_data(dp, vflag)))
break;
printf(" to:");
- if ((dp = parse_wcc_data(dp, vflag)) == NULL)
+ if (!(dp = parse_wcc_data(dp, vflag)))
break;
}
return;
} else {
- if (parsestatus(dp, &er) != NULL)
+ if (parsestatus(dp, &er) != 0)
return;
}
break;
case NFSPROC_LINK:
printf(" link");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if ((dp = parsestatus(dp, &er)) == NULL)
+ if (!(dp = parsestatus(dp, &er)))
break;
if (vflag) {
printf(" file POST:");
- if ((dp = parse_post_op_attr(dp, vflag)) == NULL)
+ if (!(dp = parse_post_op_attr(dp, vflag)))
break;
printf(" dir:");
- if ((dp = parse_wcc_data(dp, vflag)) == NULL)
+ if (!(dp = parse_wcc_data(dp, vflag)))
break;
return;
}
} else {
- if (parsestatus(dp, &er) != NULL)
+ if (parsestatus(dp, &er) != 0)
return;
}
break;
case NFSPROC_READDIR:
printf(" readdir");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
if (v3) {
- if (parsev3rddirres(dp, vflag) != NULL)
+ if (parsev3rddirres(dp, vflag))
return;
} else {
if (parserddires(dp) != 0)
@@ -1515,23 +1691,23 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
case NFSPROC_READDIRPLUS:
printf(" readdirplus");
- if ((dp = parserep(rp, length)) == NULL)
+ if (!(dp = parserep(rp, length)))
break;
- if (parsev3rddirres(dp, vflag) != NULL)
+ if (parsev3rddirres(dp, vflag))
return;
break;
case NFSPROC_FSSTAT:
printf(" fsstat");
dp = parserep(rp, length);
- if (dp != NULL && parsestatfs(dp, v3) != NULL)
+ if (dp != NULL && parsestatfs(dp, v3) != 0)
return;
break;
case NFSPROC_FSINFO:
printf(" fsinfo");
dp = parserep(rp, length);
- if (dp != NULL && parsefsinfo(dp) != NULL)
+ if (dp != NULL && parsefsinfo(dp) != 0)
return;
break;
@@ -1553,7 +1729,6 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt
printf(" proc-%u", proc);
return;
}
-
trunc:
if (!nfserr)
fputs(" [|nfs]", stdout);
diff --git a/contrib/tcpdump/print-ntp.c b/contrib/tcpdump/print-ntp.c
index 1009872ed4b0..0e0961247403 100644
--- a/contrib/tcpdump/print-ntp.c
+++ b/contrib/tcpdump/print-ntp.c
@@ -27,7 +27,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.27 1999/11/21 09:36:57 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.31 2000/10/06 04:23:13 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -38,14 +38,7 @@ static const char rcsid[] =
#include <sys/time.h>
#include <sys/socket.h>
-#if __STDC__
-struct mbuf;
-struct rtentry;
-#endif
-#include <net/if.h>
-
#include <netinet/in.h>
-#include <net/ethernet.h>
#include <ctype.h>
#include <stdio.h>
diff --git a/contrib/tcpdump/print-null.c b/contrib/tcpdump/print-null.c
index 64c7df340c05..8da9a95c037c 100644
--- a/contrib/tcpdump/print-null.c
+++ b/contrib/tcpdump/print-null.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.30 1999/12/22 06:27:21 itojun Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.40 2000/12/16 22:00:50 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -36,84 +36,100 @@ static const char rcsid[] =
#include <sys/file.h>
#include <sys/ioctl.h>
-#if __STDC__
struct mbuf;
struct rtentry;
-#endif
-#include <net/if.h>
#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <net/ethernet.h>
-#include <netinet/ip_var.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
-#include <netinet/tcp.h>
#include <pcap.h>
#include <stdio.h>
#include <string.h>
-#ifdef INET6
-#include <netinet/ip6.h>
-#endif
-
#include "interface.h"
#include "addrtoname.h"
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+
#ifndef AF_NS
#define AF_NS 6 /* XEROX NS protocols */
#endif
/*
- * The DLT_NULL packet header is 4 bytes long. It contains a network
- * order 32 bit integer that specifies the family, e.g. AF_INET
+ * The DLT_NULL packet header is 4 bytes long. It contains a host-byte-order
+ * 32-bit integer that specifies the family, e.g. AF_INET.
+ *
+ * Note here that "host" refers to the host on which the packets were
+ * captured; that isn't necessarily *this* host.
+ *
+ * The OpenBSD DLT_LOOP packet header is the same, except that the integer
+ * is in network byte order.
*/
#define NULL_HDRLEN 4
static void
-null_print(const u_char *p, const struct ip *ip, u_int length)
+null_print(u_int family, u_int length)
{
- u_int family;
-
- memcpy((char *)&family, (char *)p, sizeof(family));
-
- if (nflag) {
- /* XXX just dump the header */
- return;
- }
- switch (family) {
+ if (nflag)
+ printf("AF %u ", family);
+ else {
+ switch (family) {
- case AF_INET:
- printf("ip: ");
- break;
+ case AF_INET:
+ printf("ip ");
+ break;
#ifdef INET6
- case AF_INET6:
- printf("ip6: ");
- break;
+ case AF_INET6:
+ printf("ip6 ");
+ break;
#endif
- case AF_NS:
- printf("ns: ");
- break;
+ case AF_NS:
+ printf("ns ");
+ break;
- default:
- printf("AF %d: ", family);
- break;
+ default:
+ printf("AF %u ", family);
+ break;
+ }
}
+ printf("%d: ", length);
}
+/*
+ * Byte-swap a 32-bit number.
+ * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on
+ * big-endian platforms.)
+ */
+#define SWAPLONG(y) \
+((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
+
void
null_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
u_int length = h->len;
u_int caplen = h->caplen;
const struct ip *ip;
+ u_int family;
ts_print(&h->ts);
+ memcpy((char *)&family, (char *)p, sizeof(family));
+
+ /*
+ * This isn't necessarily in our host byte order; if this is
+ * a DLT_LOOP capture, it's in network byte order, and if
+ * this is a DLT_NULL capture from a machine with the opposite
+ * byte-order, it's in the opposite byte order from ours.
+ *
+ * If the upper 16 bits aren't all zero, assume it's byte-swapped.
+ */
+ if ((family & 0xFFFF0000) != 0)
+ family = SWAPLONG(family);
+
/*
* 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.
@@ -127,9 +143,9 @@ null_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
ip = (struct ip *)(p + NULL_HDRLEN);
if (eflag)
- null_print(p, ip, length);
+ null_print(family, length);
- switch (ip->ip_v) {
+ switch (IP_V(ip)) {
case 4:
ip_print((const u_char *)ip, length);
break;
@@ -139,7 +155,7 @@ null_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
break;
#endif /* INET6 */
default:
- printf("ip v%d", ip->ip_v);
+ printf("ip v%d", IP_V(ip));
break;
}
diff --git a/contrib/tcpdump/print-pim.c b/contrib/tcpdump/print-pim.c
index 96bf6830ed76..2e6ff7266991 100644
--- a/contrib/tcpdump/print-pim.c
+++ b/contrib/tcpdump/print-pim.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.15.2.1 2000/01/25 18:29:05 itojun Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.23 2000/10/03 02:55:00 itojun Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -35,8 +35,6 @@ static const char rcsid[] =
#include <sys/socket.h>
#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
/*
* XXX: We consider a case where IPv6 is not ready yet for portability,
@@ -66,6 +64,8 @@ struct pim {
#include "addrtoname.h"
#include "extract.h"
+#include "ip.h"
+
static void pimv2_print(register const u_char *bp, register u_int len);
static void
@@ -318,7 +318,7 @@ cisco_autorp_print(register const u_char *bp, register u_int len)
TCHECK2(bp[0], 4);
(void)printf(" RP %s", ipaddr_string(bp));
TCHECK(bp[4]);
- switch(bp[4] & 0x3) {
+ switch (bp[4] & 0x3) {
case 0: printf(" PIMv?");
break;
case 1: printf(" PIMv1");
@@ -360,7 +360,7 @@ pim_print(register const u_char *bp, register u_int len)
TCHECK(pim->pim_rsv);
#endif
- switch(PIM_VER(pim->pim_typever)) {
+ switch (PIM_VER(pim->pim_typever)) {
case 2: /* avoid hardcoding? */
(void)printf("pim v2");
pimv2_print(bp, len);
@@ -636,7 +636,7 @@ pimv2_print(register const u_char *bp, register u_int len)
if (bp >= ep)
break;
ip = (struct ip *)bp;
- switch(ip->ip_v) {
+ switch (IP_V(ip)) {
case 4: /* IPv4 */
printf(" ");
ip_print(bp, len);
@@ -648,7 +648,7 @@ pimv2_print(register const u_char *bp, register u_int len)
break;
#endif
default:
- (void)printf(" IP ver %d", ip->ip_v);
+ (void)printf(" IP ver %d", IP_V(ip));
break;
}
break;
@@ -801,12 +801,12 @@ pimv2_print(register const u_char *bp, register u_int len)
(void)printf("...)");
goto bs_done;
}
- (void)printf(" RPcnt=%d", frpcnt = bp[0]);
+ (void)printf(" RPcnt=%d", bp[0]);
if (bp + 1 >= ep) {
(void)printf("...)");
goto bs_done;
}
- (void)printf(" FRPcnt=%d", bp[1]);
+ (void)printf(" FRPcnt=%d", frpcnt = bp[1]);
bp += 4;
for (j = 0; j < frpcnt && bp < ep; j++) {
diff --git a/contrib/tcpdump/print-ppp.c b/contrib/tcpdump/print-ppp.c
index 3c831d372e1b..ebd1ec17911d 100644
--- a/contrib/tcpdump/print-ppp.c
+++ b/contrib/tcpdump/print-ppp.c
@@ -18,12 +18,22 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
+ * Extensively modified by Motonori Shindo (mshindo@mshindo.net) for more
+ * complete PPP support.
+ *
* $FreeBSD$
*/
+/*
+ * TODO:
+ * o resolve XXX as much as possible
+ * o MP support
+ * o BAP support
+ */
+
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.33.2.1 2000/01/29 07:31:17 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.58 2000/12/27 11:09:08 itojun Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -32,96 +42,77 @@ static const char rcsid[] =
#include <sys/param.h>
#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#if __STDC__
-struct mbuf;
-struct rtentry;
+#ifdef __bsdi__
+#include <net/slcompress.h>
+#include <net/if_ppp.h>
#endif
-#include <net/if.h>
#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
#include <ctype.h>
#include <netdb.h>
#include <pcap.h>
#include <stdio.h>
-#ifdef __bsdi__
-#include <net/slcompress.h>
-#include <net/if_ppp.h>
-#endif
-
-#include <net/ethernet.h>
-#include "ethertype.h"
-#include <net/ppp_defs.h>
#include "interface.h"
#include "extract.h"
#include "addrtoname.h"
#include "ppp.h"
+#include "chdlc.h"
+#include "ethertype.h"
-struct protonames {
- u_short protocol;
- char *name;
-};
+/*
+ * The following constatns are defined by IANA. Please refer to
+ * http://www.isi.edu/in-notes/iana/assignments/ppp-numbers
+ * for the up-to-date information.
+ */
-static struct protonames protonames[] = {
+/* Control Protocols (LCP/IPCP/CCP etc.) Codes */
+
+#define CPCODES_VEXT 0 /* Vendor-Specific (RFC2153) */
+#define CPCODES_CONF_REQ 1 /* Configure-Request */
+#define CPCODES_CONF_ACK 2 /* Configure-Ack */
+#define CPCODES_CONF_NAK 3 /* Configure-Nak */
+#define CPCODES_CONF_REJ 4 /* Configure-Reject */
+#define CPCODES_TERM_REQ 5 /* Terminate-Request */
+#define CPCODES_TERM_ACK 6 /* Terminate-Ack */
+#define CPCODES_CODE_REJ 7 /* Code-Reject */
+#define CPCODES_PROT_REJ 8 /* Protocol-Reject (LCP only) */
+#define CPCODES_ECHO_REQ 9 /* Echo-Request (LCP only) */
+#define CPCODES_ECHO_RPL 10 /* Echo-Reply (LCP only) */
+#define CPCODES_DISC_REQ 11 /* Discard-Request (LCP only) */
+#define CPCODES_ID 12 /* Identification (LCP only) */
+#define CPCODES_TIME_REM 13 /* Time-Remaining (LCP only) */
+#define CPCODES_RESET_REQ 14 /* Reset-Request (CCP only) */
+#define CPCODES_RESET_REP 15 /* Reset-Reply (CCP only) */
+
+#define CPCODES_MIN CPCODES_VEXT
+#define CPCODES_MAX CPCODES_RESET_REP
+
+static const char *cpcodes[] = {
/*
- * Protocol field values.
+ * Control Protocol code values (RFC1661)
*/
- PPP_IP, "IP", /* Internet Protocol */
- PPP_XNS, "XNS", /* Xerox NS */
- PPP_IPX, "IPX", /* IPX Datagram (RFC1552) */
- PPP_VJC_COMP, "VJC_UNCOMP", /* VJ compressed TCP */
- PPP_VJC_UNCOMP, "VJC_UNCOMP", /* VJ uncompressed TCP */
- PPP_COMP, "COMP", /* compressed packet */
- PPP_IPCP, "IPCP", /* IP Control Protocol */
- PPP_IPXCP, "IPXCP", /* IPX Control Protocol (RFC1552) */
- PPP_CCP, "CCP", /* Compression Control Protocol */
- PPP_LCP, "LCP", /* Link Control Protocol */
- PPP_PAP, "PAP", /* Password Authentication Protocol */
- PPP_LQR, "LQR", /* Link Quality Report protocol */
- PPP_CHAP, "CHAP", /* Cryptographic Handshake Auth. Proto*/
+ "Vend-Ext", /* (0) RFC2153 */
+ "Conf-Req", /* (1) */
+ "Conf-Ack", /* (2) */
+ "Conf-Nak", /* (3) */
+ "Conf-Rej", /* (4) */
+ "Term-Req", /* (5) */
+ "Term-Ack", /* (6) */
+ "Code-Rej", /* (7) */
+ "Prot-Rej", /* (8) */
+ "Echo-Req", /* (9) */
+ "Echo-Rep", /* (10) */
+ "Disc-Req", /* (11) */
+ "Ident", /* (12) RFC1570 */
+ "Time-Rem", /* (13) RFC1570 */
+ "Reset-Req", /* (14) RFC1962 */
+ "Reset-Ack", /* (15) RFC1962 */
};
-/* LCP */
-
-#define LCP_CONF_REQ 1
-#define LCP_CONF_ACK 2
-#define LCP_CONF_NAK 3
-#define LCP_CONF_REJ 4
-#define LCP_TERM_REQ 5
-#define LCP_TERM_ACK 6
-#define LCP_CODE_REJ 7
-#define LCP_PROT_REJ 8
-#define LCP_ECHO_REQ 9
-#define LCP_ECHO_RPL 10
-#define LCP_DISC_REQ 11
-
-#define LCP_MIN LCP_CONF_REQ
-#define LCP_MAX LCP_DISC_REQ
-
-static char *lcpcodes[] = {
- /*
- * LCP code values (RFC1661, pp26)
- */
- "Configure-Request",
- "Configure-Ack",
- "Configure-Nak",
- "Configure-Reject",
- "Terminate-Request",
- "Terminate-Ack",
- "Code-Reject",
- "Protocol-Reject",
- "Echo-Request",
- "Echo-Reply",
- "Discard-Request",
-};
+/* LCP Config Options */
#define LCPOPT_VEXT 0
#define LCPOPT_MRU 1
@@ -129,40 +120,175 @@ static char *lcpcodes[] = {
#define LCPOPT_AP 3
#define LCPOPT_QP 4
#define LCPOPT_MN 5
+#define LCPOPT_DEP6 6
#define LCPOPT_PFC 7
#define LCPOPT_ACFC 8
+#define LCPOPT_FCSALT 9
+#define LCPOPT_SDP 10
+#define LCPOPT_NUMMODE 11
+#define LCPOPT_DEP12 12
+#define LCPOPT_CBACK 13
+#define LCPOPT_DEP14 14
+#define LCPOPT_DEP15 15
+#define LCPOPT_DEP16 16
+#define LCPOPT_MLMRRU 17
+#define LCPOPT_MLSSNHF 18
+#define LCPOPT_MLED 19
+#define LCPOPT_PROP 20
+#define LCPOPT_DCEID 21
+#define LCPOPT_MPP 22
+#define LCPOPT_LD 23
+#define LCPOPT_LCPAOPT 24
+#define LCPOPT_COBS 25
+#define LCPOPT_PE 26
+#define LCPOPT_MLHF 27
+#define LCPOPT_I18N 28
+#define LCPOPT_SDLOS 29
+#define LCPOPT_PPPMUX 30
+
+#define LCPOPT_MIN LCPOPT_VEXT
+#define LCPOPT_MAX LCPOPT_PPPMUX
+
+static const char *lcpconfopts[] = {
+ "Vend-Ext", /* (0) */
+ "MRU", /* (1) */
+ "ACCM", /* (2) */
+ "Auth-Prot", /* (3) */
+ "Qual-Prot", /* (4) */
+ "Magic-Num", /* (5) */
+ "deprecated(6)", /* used to be a Quality Protocol */
+ "PFC", /* (7) */
+ "ACFC", /* (8) */
+ "FCS-Alt", /* (9) */
+ "SDP", /* (10) */
+ "Num-Mode", /* (11) */
+ "deprecated(12)", /* used to be a Multi-Link-Procedure*/
+ "Call-Back", /* (13) */
+ "deprecated(14)", /* used to be a Connect-Time */
+ "deprecated(15)", /* used to be a Compund-Frames */
+ "deprecated(16)", /* used to be a Nominal-Data-Encap */
+ "MRRU", /* (17) */
+ "SSNHF", /* (18) */
+ "End-Disc", /* (19) */
+ "Proprietary", /* (20) */
+ "DCE-Id", /* (21) */
+ "MP+", /* (22) */
+ "Link-Disc", /* (23) */
+ "LCP-Auth-Opt", /* (24) */
+ "COBS", /* (25) */
+ "Prefix-elision", /* (26) */
+ "Multilink-header-Form",/* (27) */
+ "I18N", /* (28) */
+ "SDL-over-SONET/SDH", /* (29) */
+ "PPP-Muxing", /* (30) */
+};
-#define LCPOPT_MIN 0
-#define LCPOPT_MAX 24
-
-static char *lcpconfopts[] = {
- "Vendor-Ext",
- "Max-Rx-Unit",
- "Async-Ctrl-Char-Map",
- "Auth-Prot",
- "Quality-Prot",
- "Magic-Number",
- "unassigned (6)",
- "Prot-Field-Compr",
- "Add-Ctrl-Field-Compr",
- "FCS-Alternatives",
- "Self-Describing-Pad",
- "Numbered-Mode",
- "Multi-Link-Procedure",
- "Call-Back",
- "Connect-Time",
- "Compund-Frames",
- "Nominal-Data-Encap",
- "Multilink-MRRU",
- "Multilink-SSNHF",
- "Multilink-ED",
- "Proprietary",
- "DCE-Identifier",
- "Multilink-Plus-Proc",
- "Link-Discriminator",
- "LCP-Auth-Option",
+/* IPV6CP - to be supported */
+/* ECP - to be supported */
+
+/* CCP Config Options */
+
+#define CCPOPT_OUI 0 /* RFC1962 */
+#define CCPOPT_PRED1 1 /* RFC1962 */
+#define CCPOPT_PRED2 2 /* RFC1962 */
+#define CCPOPT_PJUMP 3 /* RFC1962 */
+/* 4-15 unassigned */
+#define CCPOPT_HPPPC 16 /* RFC1962 */
+#define CCPOPT_STACLZS 17 /* RFC1974 */
+#define CCPOPT_MPPC 18 /* RFC2118 */
+#define CCPOPT_GFZA 19 /* RFC1962 */
+#define CCPOPT_V42BIS 20 /* RFC1962 */
+#define CCPOPT_BSDCOMP 21 /* RFC1977 */
+/* 22 unassigned */
+#define CCPOPT_LZSDCP 23 /* RFC1967 */
+#define CCPOPT_MVRCA 24 /* RFC1975 */
+#define CCPOPT_DEC 25 /* RFC1976 */
+#define CCPOPT_DEFLATE 26 /* RFC1979 */
+/* 27-254 unassigned */
+#define CCPOPT_RESV 255 /* RFC1962 */
+
+#define CCPOPT_MIN CCPOPT_OUI
+#define CCPOPT_MAX CCPOPT_DEFLATE /* XXX: should be CCPOPT_RESV but... */
+
+static const char *ccpconfopts[] = {
+ "OUI", /* (0) */
+ "Pred-1", /* (1) */
+ "Pred-2", /* (2) */
+ "Puddle", /* (3) */
+ "unassigned(4)", /* (4) */
+ "unassigned(5)", /* (5) */
+ "unassigned(6)", /* (6) */
+ "unassigned(7)", /* (7) */
+ "unassigned(8)", /* (8) */
+ "unassigned(9)", /* (9) */
+ "unassigned(10)", /* (10) */
+ "unassigned(11)", /* (11) */
+ "unassigned(12)", /* (12) */
+ "unassigned(13)", /* (13) */
+ "unassigned(14)", /* (14) */
+ "unassigned(15)", /* (15) */
+ "HP-PPC", /* (16) */
+ "Stac-LZS", /* (17) */
+ "MPPC", /* (18) */
+ "Gand-FZA", /* (19) */
+ "V.42bis", /* (20) */
+ "BSD-Comp", /* (21) */
+ "unassigned(22)", /* (22) */
+ "LZS-DCP", /* (23) */
+ "MVRCA", /* (24) */
+ "DEC", /* (25) */
+ "Deflate", /* (26) */
};
+/* BACP Config Options */
+
+#define BACPOPT_FPEER 1 /* RFC2125 */
+
+/* SDCP - to be supported */
+
+/* IPCP Config Options */
+
+#define IPCPOPT_2ADDR 1 /* RFC1172, RFC1332 (deprecated) */
+#define IPCPOPT_IPCOMP 2 /* RFC1332 */
+#define IPCPOPT_ADDR 3 /* RFC1332 */
+#define IPCPOPT_MOBILE4 4 /* RFC2290 */
+
+#define IPCPOPT_PRIDNS 129 /* RFC1877 */
+#define IPCPOPT_PRINBNS 130 /* RFC1877 */
+#define IPCPOPT_SECDNS 131 /* RFC1877 */
+#define IPCPOPT_SECNBNS 132 /* RFC1877 */
+
+/* ATCP - to be supported */
+/* OSINLCP - to be supported */
+/* BVCP - to be supported */
+/* BCP - to be supported */
+/* IPXCP - to be supported */
+
+/* Auth Algorithms */
+
+/* 0-4 Reserved (RFC1994) */
+#define AUTHALG_CHAPMD5 5 /* RFC1994 */
+#define AUTHALG_MSCHAP1 128 /* RFC2433 */
+#define AUTHALG_MSCHAP2 129 /* RFC2795 */
+
+/* FCS Alternatives - to be supported */
+
+/* Multilink Endpoint Discriminator (RFC1717) */
+#define MEDCLASS_NULL 0 /* Null Class */
+#define MEDCLASS_LOCAL 1 /* Locally Assigned */
+#define MEDCLASS_IPV4 2 /* Internet Protocol (IPv4) */
+#define MEDCLASS_MAC 3 /* IEEE 802.1 global MAC address */
+#define MEDCLASS_MNB 4 /* PPP Magic Number Block */
+#define MEDCLASS_PSNDN 5 /* Public Switched Network Director Number */
+
+/* PPP LCP Callback */
+#define CALLBACK_AUTH 0 /* Location determined by user auth */
+#define CALLBACK_DSTR 1 /* Dialing string */
+#define CALLBACK_LID 2 /* Location identifier */
+#define CALLBACK_E164 3 /* E.164 number */
+#define CALLBACK_X500 4 /* X.500 distinguished name */
+#define CALLBACK_CBCP 6 /* Location is determined during CBCP nego */
+
/* CHAP */
#define CHAP_CHAL 1
@@ -170,14 +296,14 @@ static char *lcpconfopts[] = {
#define CHAP_SUCC 3
#define CHAP_FAIL 4
-#define CHAP_CODEMIN 1
-#define CHAP_CODEMAX 4
+#define CHAP_CODEMIN CHAP_CHAL
+#define CHAP_CODEMAX CHAP_FAIL
-static char *chapcode[] = {
- "Challenge",
- "Response",
- "Success",
- "Failure",
+static const char *chapcode[] = {
+ "Chal", /* (1) */
+ "Resp", /* (2) */
+ "Succ", /* (3) */
+ "Fail", /* (4) */
};
/* PAP */
@@ -186,129 +312,223 @@ static char *chapcode[] = {
#define PAP_AACK 2
#define PAP_ANAK 3
-#define PAP_CODEMIN 1
-#define PAP_CODEMAX 3
+#define PAP_CODEMIN PAP_AREQ
+#define PAP_CODEMAX PAP_ANAK
-static char *papcode[] = {
- "Authenticate-Request",
- "Authenticate-Ack",
- "Authenticate-Nak",
+static const char *papcode[] = {
+ "Auth-Req", /* (1) */
+ "Auth-Ack", /* (2) */
+ "Auth-Nak", /* (3) */
};
-/* IPCP */
-
-#define IPCP_2ADDR 1
-#define IPCP_CP 2
-#define IPCP_ADDR 3
-
-static void do_ppp_print __P((const u_char *, u_int, u_int));
-static void handle_lcp __P((const u_char *p, int length));
-static int print_lcp_config_options __P((const u_char *p));
-static void handle_chap __P((const u_char *p, int length));
-static void handle_ipcp __P((const u_char *p, int length));
-static void handle_pap __P((const u_char *p, int length));
-
-void
-ppp_hdlc_print(const u_char *p, int length)
+/* BAP */
+#define BAP_CALLREQ 1
+#define BAP_CALLRES 2
+#define BAP_CBREQ 3
+#define BAP_CBRES 4
+#define BAP_LDQREQ 5
+#define BAP_LDQRES 6
+#define BAP_CSIND 7
+#define BAP_CSRES 8
+
+static const char *ppp_protoname (u_int proto);
+static void handle_ctrl_proto (u_int proto,const u_char *p, int length);
+static void handle_chap (const u_char *p, int length);
+static void handle_pap (const u_char *p, int length);
+static void handle_bap (const u_char *p, int length);
+static int print_lcp_config_options (const u_char *p, int);
+static int print_ipcp_config_options (const u_char *p, int);
+static int print_ccp_config_options (const u_char *p, int);
+static int print_bacp_config_options (const u_char *p, int);
+static void handle_ppp (u_int proto, const u_char *p, int length);
+
+static const char *
+ppp_protoname(u_int proto)
{
- int proto = PPP_PROTOCOL(p);
- int i, j, x;
- u_char *ptr;
-
- printf("ID-%03d ", *(p+5));
-
- for (i = (sizeof(protonames) / sizeof(protonames[0])) - 1; i >= 0; --i)
- {
- if (proto == protonames[i].protocol)
- {
- printf("%s: ", protonames[i].name);
-
- switch(proto)
- {
- case PPP_LCP:
- handle_lcp(p, length);
- break;
- case PPP_CHAP:
- handle_chap(p, length);
- break;
- case PPP_PAP:
- handle_pap(p, length);
- break;
- case PPP_IPCP:
- handle_ipcp(p, length);
- break;
- }
- break;
- }
- }
- if (i < 0)
- {
- printf("%04x: ", proto);
+ static char buf[20];
+
+ switch (proto) {
+ case PPP_IP: return "IP";
+ case PPP_IPV6: return "IPv6";
+#ifdef PPP_XNS
+ case PPP_XNS: return "XNS";
+#endif
+ case PPP_IPX: return "IPX";
+ case PPP_VJC: return "VJC";
+ case PPP_VJNC: return "VJNC";
+#ifdef PPP_COMP
+ case PPP_COMP: return "COMP";
+#endif
+ case PPP_IPCP: return "IPCP";
+ case PPP_IPV6CP: return "IPv6CP";
+ case PPP_IPXCP: return "IPXCP";
+ case PPP_CCP: return "CCP";
+ case PPP_LCP: return "LCP";
+ case PPP_PAP: return "PAP";
+#ifdef PPP_LQR
+ case PPP_LQR: return "LQR";
+#endif
+ case PPP_CHAP: return "CHAP";
+ case PPP_BACP: return "BACP";
+ case PPP_BAP: return "BAP";
+ default:
+ snprintf(buf, sizeof(buf), "unknown-0x%04x", proto);
+ return buf;
}
}
-/* print LCP frame */
+/* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */
static void
-handle_lcp(const u_char *p, int length)
+handle_ctrl_proto(u_int proto, const u_char *p, int length)
{
+ u_int code, len;
+ int (*pfunc)(const u_char *, int);
int x, j;
- const u_char *ptr;
- x = p[4];
+ if (length < 1) {
+ printf("[|%s]", ppp_protoname(proto));
+ return;
+ } else if (length < 4) {
+ printf("[|%s 0x%02x]", ppp_protoname(proto), *p);
+ return;
+ }
- if ((x >= LCP_MIN) && (x <= LCP_MAX))
- printf("%s", lcpcodes[x - 1]);
+ code = *p;
+ if ((code >= CPCODES_MIN) && (code <= CPCODES_MAX))
+ printf("%s", cpcodes[code]);
else {
- printf("0x%02x", x);
+ printf("0x%02x", code);
return;
}
+ p++;
+
+ printf("(%u)", *p); /* ID */
+ p++;
+
+ len = EXTRACT_16BITS(p);
+ p += 2;
- length -= 4;
-
- switch (x) {
- case LCP_CONF_REQ:
- case LCP_CONF_ACK:
- case LCP_CONF_NAK:
- case LCP_CONF_REJ:
- x = length;
- ptr = p + 8;
+ if (length <= 4)
+ return; /* there may be a NULL confreq etc. */
+
+ switch (code) {
+ case CPCODES_VEXT:
+ if (length < 11)
+ break;
+ printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
+ p += 4;
+ printf(" OUI=%02x%02x%02x", p[0], p[1], p[2]);
+ /* XXX: need to decode Kind and Value(s)? */
+ break;
+ case CPCODES_CONF_REQ:
+ case CPCODES_CONF_ACK:
+ case CPCODES_CONF_NAK:
+ case CPCODES_CONF_REJ:
+ x = len - 4; /* Code(1), Identifier(1) and Length(2) */
do {
- if ((j = print_lcp_config_options(ptr)) == 0)
+ switch (proto) {
+ case PPP_LCP:
+ pfunc = print_lcp_config_options;
+ break;
+ case PPP_IPCP:
+ pfunc = print_ipcp_config_options;
+ break;
+ case PPP_CCP:
+ pfunc = print_ccp_config_options;
+ break;
+ case PPP_BACP:
+ pfunc = print_bacp_config_options;
+ break;
+ default:
+ /*
+ * This should never happen, but we set
+ * "pfunc" to squelch uninitialized
+ * variable warnings from compilers.
+ */
+ pfunc = NULL;
+ break;
+ }
+ if ((j = (*pfunc)(p, len)) == 0)
break;
x -= j;
- ptr += j;
+ p += j;
} while (x > 0);
break;
- case LCP_ECHO_REQ:
- case LCP_ECHO_RPL:
- printf(", Magic-Number=%u",
- EXTRACT_32BITS(p+8));
+ case CPCODES_TERM_REQ:
+ case CPCODES_TERM_ACK:
+ /* XXX: need to decode Data? */
+ break;
+ case CPCODES_CODE_REJ:
+ /* XXX: need to decode Rejected-Packet? */
+ break;
+ case CPCODES_PROT_REJ:
+ if (length < 6)
+ break;
+ printf(", Rejected-Protocol=%04x", EXTRACT_16BITS(p));
+ /* XXX: need to decode Rejected-Information? */
+ break;
+ case CPCODES_ECHO_REQ:
+ case CPCODES_ECHO_RPL:
+ case CPCODES_DISC_REQ:
+ case CPCODES_ID:
+ if (length < 8)
+ break;
+ printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
+ /* XXX: need to decode Data? */
+ break;
+ case CPCODES_TIME_REM:
+ if (length < 12)
+ break;
+ printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
+ printf(" Seconds-Remaining=%u", EXTRACT_32BITS(p + 4));
+ /* XXX: need to decode Message? */
break;
- case LCP_TERM_REQ:
- case LCP_TERM_ACK:
- case LCP_CODE_REJ:
- case LCP_PROT_REJ:
- case LCP_DISC_REQ:
default:
+ printf(", unknown-Codes-0x%02x", code);
break;
}
}
/* LCP config options */
static int
-print_lcp_config_options(const u_char *p)
+print_lcp_config_options(const u_char *p, int length)
{
- int len = p[1];
- int opt = p[0];
-
+ int len, opt;
+
+ if (length < 2)
+ return 0;
+ len = p[1];
+ opt = p[0];
+ if (length < len)
+ return 0;
if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
printf(", %s", lcpconfopts[opt]);
+ else {
+ printf(", unknwhown-%d", opt);
+ return len;
+ }
switch (opt) {
+ case LCPOPT_VEXT:
+ if (len >= 6) {
+ printf(" OUI=%02x%02x%02x", p[2], p[3], p[4]);
+#if 0
+ printf(" kind=%02x", p[5]);
+ printf(" val=")
+ for (i = 0; i < len - 6; i++) {
+ printf("%02x", p[6 + i]);
+ }
+#endif
+ }
+ break;
case LCPOPT_MRU:
if (len == 4)
- printf("=%d", (*(p+2) << 8) + *(p+3));
+ printf("=%u", EXTRACT_16BITS(p + 2));
+ break;
+ case LCPOPT_ACCM:
+ if (len == 6)
+ printf("=%08x", EXTRACT_32BITS(p + 2));
break;
case LCPOPT_AP:
if (len >= 4) {
@@ -320,11 +540,14 @@ print_lcp_config_options(const u_char *p)
default:
printf("unknown-algorithm-%u", p[4]);
break;
- case 5:
+ case AUTHALG_CHAPMD5:
printf("MD5");
break;
- case 0x80:
- printf("Microsoft");
+ case AUTHALG_MSCHAP1:
+ printf("MSCHAPv1");
+ break;
+ case AUTHALG_MSCHAP2:
+ printf("MSCHAPv2");
break;
}
}
@@ -348,14 +571,100 @@ print_lcp_config_options(const u_char *p)
break;
case LCPOPT_MN:
if (len == 6)
- printf("=%u", EXTRACT_32BITS(p+2));
+ printf("=%08x", EXTRACT_32BITS(p + 2));
break;
case LCPOPT_PFC:
- printf(" PFC");
break;
case LCPOPT_ACFC:
- printf(" ACFC");
break;
+ case LCPOPT_LD:
+ if (len == 4)
+ printf("=%04x", EXTRACT_16BITS(p + 2));
+ break;
+ case LCPOPT_CBACK:
+ if (len < 3)
+ break;
+ switch (p[2]) { /* Operation */
+ case CALLBACK_AUTH:
+ printf(" UserAuth");
+ break;
+ case CALLBACK_DSTR:
+ printf(" DialString");
+ break;
+ case CALLBACK_LID:
+ printf(" LocalID");
+ break;
+ case CALLBACK_E164:
+ printf(" E.164");
+ break;
+ case CALLBACK_X500:
+ printf(" X.500");
+ break;
+ case CALLBACK_CBCP:
+ printf(" CBCP");
+ break;
+ default:
+ printf(" unknown-operation=%u", p[2]);
+ break;
+ }
+ break;
+ case LCPOPT_MLMRRU:
+ if (len == 4)
+ printf("=%u", EXTRACT_16BITS(p + 2));
+ break;
+ case LCPOPT_MLED:
+ if (len < 3)
+ break;
+ switch (p[2]) { /* class */
+ case MEDCLASS_NULL:
+ printf(" Null");
+ break;
+ case MEDCLASS_LOCAL:
+ printf(" Local"); /* XXX */
+ break;
+ case MEDCLASS_IPV4:
+ if (len != 7)
+ break;
+ printf(" IPv4=%s", ipaddr_string(p + 3));
+ break;
+ case MEDCLASS_MAC:
+ if (len != 9)
+ break;
+ printf(" MAC=%02x:%02x:%02x:%02x:%02x:%02x",
+ p[3], p[4], p[5], p[6], p[7], p[8]);
+ break;
+ case MEDCLASS_MNB:
+ printf(" Magic-Num-Block"); /* XXX */
+ break;
+ case MEDCLASS_PSNDN:
+ printf(" PSNDN"); /* XXX */
+ break;
+ }
+ break;
+
+/* XXX: to be supported */
+#if 0
+ case LCPOPT_DEP6:
+ case LCPOPT_FCSALT:
+ case LCPOPT_SDP:
+ case LCPOPT_NUMMODE:
+ case LCPOPT_DEP12:
+ case LCPOPT_DEP14:
+ case LCPOPT_DEP15:
+ case LCPOPT_DEP16:
+ case LCPOPT_MLSSNHF:
+ case LCPOPT_PROP:
+ case LCPOPT_DCEID:
+ case LCPOPT_MPP:
+ case LCPOPT_LCPAOPT:
+ case LCPOPT_COBS:
+ case LCPOPT_PE:
+ case LCPOPT_MLHF:
+ case LCPOPT_I18N:
+ case LCPOPT_SDLOS:
+ case LCPOPT_PPPMUX:
+ break;
+#endif
}
return len;
}
@@ -364,183 +673,514 @@ print_lcp_config_options(const u_char *p)
static void
handle_chap(const u_char *p, int length)
{
- int x;
- const u_char *ptr;
+ u_int code, len;
+ int val_size, name_size, msg_size;
+ const u_char *p0;
+ int i;
- x = p[4];
+ p0 = p;
+ if (length < 1) {
+ printf("[|chap]");
+ return;
+ } else if (length < 4) {
+ printf("[|chap 0x%02x]", *p);
+ return;
+ }
- if ((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX))
- printf("%s", chapcode[x - 1]);
+ code = *p;
+ if ((code >= CHAP_CODEMIN) && (code <= CHAP_CODEMAX))
+ printf("%s", chapcode[code - 1]);
else {
- printf("0x%02x", x);
+ printf("0x%02x", code);
return;
}
+ p++;
+
+ printf("(%u)", *p); /* ID */
+ p++;
- length -= 4;
-
- switch (p[4]) {
+ len = EXTRACT_16BITS(p);
+ p += 2;
+
+ /*
+ * Note that this is a generic CHAP decoding routine. Since we
+ * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1,
+ * MS-CHAPv2) is used at this point, we can't decode packet
+ * specifically to each algorithms. Instead, we simply decode
+ * the GCD (Gratest Common Denominator) for all algorithms.
+ */
+ switch (code) {
case CHAP_CHAL:
case CHAP_RESP:
+ if (length - (p - p0) < 1)
+ return;
+ val_size = *p; /* value size */
+ p++;
+ if (length - (p - p0) < val_size)
+ return;
printf(", Value=");
- x = p[8]; /* value size */
- ptr = p + 9;
- while (--x >= 0)
- printf("%02x", *ptr++);
- x = length - p[8] - 1;
+ for (i = 0; i < val_size; i++)
+ printf("%02x", *p++);
+ name_size = len - (p - p0);
printf(", Name=");
- while (--x >= 0) {
- if (isprint(*ptr))
- printf("%c", *ptr);
- else
- printf("\\%03o", *ptr);
- ptr++;
- }
+ for (i = 0; i < name_size; i++)
+ safeputchar(*p++);
+ break;
+ case CHAP_SUCC:
+ case CHAP_FAIL:
+ msg_size = len - (p - p0);
+ printf(", Msg=");
+ for (i = 0; i< msg_size; i++)
+ safeputchar(*p++);
break;
}
}
-/* PAP */
+/* PAP (see RFC 1334) */
static void
handle_pap(const u_char *p, int length)
{
- int x;
- const u_char *ptr;
+ u_int code, len;
+ int peerid_len, passwd_len, msg_len;
+ const u_char *p0;
+ int i;
- x = p[4];
+ p0 = p;
+ if (length < 1) {
+ printf("[|pap]");
+ return;
+ } else if (length < 4) {
+ printf("[|pap 0x%02x]", *p);
+ return;
+ }
- if ((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX))
- printf("%s", papcode[x - 1]);
+ code = *p;
+ if ((code >= PAP_CODEMIN) && (code <= PAP_CODEMAX))
+ printf("%s", papcode[code - 1]);
else {
- printf("0x%02x", x);
+ printf("0x%02x", code);
return;
}
+ p++;
+
+ printf("(%u)", *p); /* ID */
+ p++;
+
+ len = EXTRACT_16BITS(p);
+ p += 2;
- length -= 4;
-
- switch (x) {
+ switch (code) {
case PAP_AREQ:
- printf(", Peer-Id=");
- x = p[8]; /* peerid size */
- ptr = p + 9;
- while (--x >= 0) {
- if (isprint(*ptr))
- printf("%c", *ptr);
- else
- printf("\\%03o", *ptr);
- ptr++;
- }
- x = *ptr++;
- printf(", Passwd=");
- while (--x >= 0) {
- if (isprint(*ptr))
- printf("%c", *ptr);
- else
- printf("\\%03o", *ptr);
- ptr++;
- }
+ if (length - (p - p0) < 1)
+ return;
+ peerid_len = *p; /* Peer-ID Length */
+ p++;
+ if (length - (p - p0) < peerid_len)
+ return;
+ printf(", Peer=");
+ for (i = 0; i < peerid_len; i++)
+ safeputchar(*p++);
+
+ if (length - (p - p0) < 1)
+ return;
+ passwd_len = *p; /* Password Length */
+ p++;
+ if (length - (p - p0) < passwd_len)
+ return;
+ printf(", Name=");
+ for (i = 0; i < passwd_len; i++)
+ safeputchar(*p++);
break;
case PAP_AACK:
case PAP_ANAK:
+ if (length - (p - p0) < 1)
+ return;
+ msg_len = *p; /* Msg-Length */
+ p++;
+ if (length - (p - p0) < msg_len)
+ return;
+ printf(", Msg=");
+ for (i = 0; i< msg_len; i++)
+ safeputchar(*p++);
break;
}
+ return;
}
-/* IPCP */
+/* BAP */
static void
-handle_ipcp(const u_char *p, int length)
+handle_bap(const u_char *p, int length)
+{
+ /* XXX: to be supported!! */
+}
+
+
+/* IPCP config options */
+static int
+print_ipcp_config_options(const u_char *p, int length)
{
- length -= 4;
-
- switch (p[8]) {
- case IPCP_2ADDR:
- printf("IP-Addresses");
- printf(", src=%s", ipaddr_string(p + 10));
- printf(", drc=%s", ipaddr_string(p + 14));
+ int len, opt;
+
+ if (length < 2)
+ return 0;
+ len = p[1];
+ opt = p[0];
+ if (length < len)
+ return 0;
+ switch (opt) {
+ case IPCPOPT_2ADDR: /* deprecated */
+ if (len != 10)
+ goto invlen;
+ printf(", IP-Addrs src=%s dst=%s",
+ ipaddr_string(p + 2),
+ ipaddr_string(p + 6));
+ break;
+ case IPCPOPT_IPCOMP:
+ if (len < 4)
+ goto invlen;
+ printf(", IP-Comp");
+ if (EXTRACT_16BITS(p + 2) == PPP_VJC) {
+ printf(" VJ-Comp");
+ /* XXX: VJ-Comp parameters should be decoded */
+ } else
+ printf(" unknown-comp-proto=%04x", EXTRACT_16BITS(p + 2));
+ break;
+ case IPCPOPT_ADDR:
+ if (len != 6)
+ goto invlen;
+ printf(", IP-Addr=%s", ipaddr_string(p + 2));
+ break;
+ case IPCPOPT_MOBILE4:
+ if (len != 6)
+ goto invlen;
+ printf(", Home-Addr=%s", ipaddr_string(p + 2));
+ break;
+ case IPCPOPT_PRIDNS:
+ if (len != 6)
+ goto invlen;
+ printf(", Pri-DNS=%s", ipaddr_string(p + 2));
break;
-
- case IPCP_CP:
- printf("IP-Compression-Protocol");
+ case IPCPOPT_PRINBNS:
+ if (len != 6)
+ goto invlen;
+ printf(", Pri-NBNS=%s", ipaddr_string(p + 2));
break;
+ case IPCPOPT_SECDNS:
+ if (len != 6)
+ goto invlen;
+ printf(", Sec-DNS=%s", ipaddr_string(p + 2));
+ break;
+ case IPCPOPT_SECNBNS:
+ if (len != 6)
+ goto invlen;
+ printf(", Sec-NBNS=%s", ipaddr_string(p + 2));
+ break;
+ default:
+ printf(", unknown-%d", opt);
+ break;
+ }
+ return len;
+
+invlen:
+ printf(", invalid-length-%d", opt);
+ return 0;
+}
- case IPCP_ADDR:
- printf("IP-Address=%s", ipaddr_string(p + 10));
+/* CCP config options */
+static int
+print_ccp_config_options(const u_char *p, int length)
+{
+ int len, opt;
+
+ if (length < 2)
+ return 0;
+ len = p[1];
+ opt = p[0];
+ if (length < len)
+ return 0;
+ if ((opt >= CCPOPT_MIN) && (opt <= CCPOPT_MAX))
+ printf(", %s", ccpconfopts[opt]);
+#if 0 /* XXX */
+ switch (opt) {
+ case CCPOPT_OUI:
+ case CCPOPT_PRED1:
+ case CCPOPT_PRED2:
+ case CCPOPT_PJUMP:
+ case CCPOPT_HPPPC:
+ case CCPOPT_STACLZS:
+ case CCPOPT_MPPC:
+ case CCPOPT_GFZA:
+ case CCPOPT_V42BIS:
+ case CCPOPT_BSDCOMP:
+ case CCPOPT_LZSDCP:
+ case CCPOPT_MVRCA:
+ case CCPOPT_DEC:
+ case CCPOPT_DEFLATE:
+ case CCPOPT_RESV:
+ break;
+
+ default:
+ printf(", unknown-%d", opt);
break;
}
+#endif
+ return len;
+}
+
+/* BACP config options */
+static int
+print_bacp_config_options(const u_char *p, int length)
+{
+ int len, opt;
+
+ if (length < 2)
+ return 0;
+ len = p[1];
+ opt = p[0];
+ if (length < len)
+ return 0;
+ if (opt == BACPOPT_FPEER) {
+ printf(", Favored-Peer");
+ printf(" Magic-Num=%08x", EXTRACT_32BITS(p + 2));
+ } else {
+ printf(", unknown-option-%d", opt);
+ }
+ return len;
}
-
+
+
+/* PPP */
+static void
+handle_ppp(u_int proto, const u_char *p, int length)
+{
+ switch (proto) {
+ case PPP_LCP:
+ case PPP_IPCP:
+ case PPP_CCP:
+ case PPP_BACP:
+ handle_ctrl_proto(proto, p, length);
+ break;
+ case PPP_CHAP:
+ handle_chap(p, length);
+ break;
+ case PPP_PAP:
+ handle_pap(p, length);
+ break;
+ case PPP_BAP: /* XXX: not yet completed */
+ handle_bap(p, length);
+ break;
+ case ETHERTYPE_IP: /*XXX*/
+ case PPP_IP:
+ ip_print(p, length);
+ break;
+#ifdef INET6
+ case ETHERTYPE_IPV6: /*XXX*/
+ case PPP_IPV6:
+ ip6_print(p, length);
+ break;
+#endif
+ case ETHERTYPE_IPX: /*XXX*/
+ case PPP_IPX:
+ ipx_print(p, length);
+ break;
+ }
+}
+
/* Standard PPP printer */
void
+ppp_print(register const u_char *p, u_int length)
+{
+ u_int proto;
+ u_int full_length = length;
+
+ /*
+ * Here, we assume that p points to the Address and Control
+ * field (if they present).
+ */
+ if (length < 2)
+ goto trunc;
+ if (*p == PPP_ADDRESS && *(p + 1) == PPP_CONTROL) {
+ p += 2; /* ACFC not used */
+ length -= 2;
+ }
+
+ if (length < 2)
+ goto trunc;
+ if (*p % 2) {
+ proto = *p; /* PFC is used */
+ p++;
+ length--;
+ } else {
+ proto = EXTRACT_16BITS(p);
+ p += 2;
+ length -= 2;
+ }
+
+ printf("%s %d: ", ppp_protoname(proto), full_length);
+
+ handle_ppp(proto, p, length);
+ return;
+trunc:
+ printf("[|ppp]");
+}
+
+
+/* PPP I/F printer */
+void
ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
register const u_char *p)
{
register u_int length = h->len;
register u_int caplen = h->caplen;
- const struct ip *ip;
- u_int proto;
ts_print(&h->ts);
if (caplen < PPP_HDRLEN) {
- puts("[|ppp]");
- return;
+ printf("[|ppp]");
+ goto out;
}
/*
* Some printers want to get back at the link level addresses,
* and/or check that they're not walking off the end of the packet.
- * Rather than pass them all the way down, we set these globals.
- */
- proto = ntohs(*(u_short *)&p[2]);
+ * Rather than pass them all the way down, we set these globals. */
+
packetp = p;
snapend = p + caplen;
- do_ppp_print(p, length, caplen);
+#if 0
+ /*
+ * XXX: seems to assume that there are 2 octets prepended to an
+ * actual PPP frame. The 1st octet looks like Input/Output flag
+ * while 2nd octet is unknown, at least to me
+ * (mshindo@mshindo.net).
+ *
+ * That was what the original tcpdump code did.
+ *
+ * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound
+ * packets and 0 for inbound packets - but only if the
+ * protocol field has the 0x8000 bit set (i.e., it's a network
+ * control protocol); it does so before running the packet through
+ * "bpf_filter" to see if it should be discarded, and to see
+ * if we should update the time we sent the most recent packet...
+ *
+ * ...but it puts the original address field back after doing
+ * so.
+ *
+ * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion.
+ *
+ * I don't know if any PPP implementation handed up to a BPF
+ * device packets with the first octet being 1 for outbound and
+ * 0 for inbound packets, so I (guy@alum.mit.edu) don't know
+ * whether that ever needs to be checked or not.
+ *
+ * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP,
+ * and its tcpdump appears to assume that the frame always
+ * begins with an address field and a control field, and that
+ * the address field might be 0x0f or 0x8f, for Cisco
+ * point-to-point with HDLC framing as per section 4.3.1 of RFC
+ * 1547, as well as 0xff, for PPP in HDLC-like framing as per
+ * RFC 1662.
+ *
+ * (Is the Cisco framing in question what DLT_C_HDLC, in
+ * BSD/OS, is?)
+ */
+ if (eflag)
+ printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]);
+#endif
+
+ ppp_print(p, length);
+
+ if (xflag)
+ default_print(p, caplen);
+out:
+ putchar('\n');
}
/*
- * Actually do the job
+ * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like
+ * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547,
+ * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL,
+ * discard them *if* those are the first two octets, and parse the remaining
+ * packet as a PPP packet, as "ppp_print()" does).
+ *
+ * This handles, for example, DLT_PPP_SERIAL in NetBSD.
*/
-static void
-do_ppp_print(const u_char *p, u_int length, u_int caplen)
+void
+ppp_hdlc_if_print(u_char *user, const struct pcap_pkthdr *h,
+ register const u_char *p)
{
- if (eflag)
- ppp_hdlc_print(p, length);
+ register u_int length = h->len;
+ register u_int caplen = h->caplen;
+ u_int proto;
- length -= PPP_HDRLEN;
+ if (caplen < 2) {
+ printf("[|ppp]");
+ goto out;
+ }
- switch(PPP_PROTOCOL(p)) {
- case PPP_IP:
- case ETHERTYPE_IP:
- ip_print((const u_char *)(p + PPP_HDRLEN), length);
- break;
- case PPP_IPX:
- case ETHERTYPE_IPX:
- ipx_print((const u_char *)(p + PPP_HDRLEN), length);
- break;
-#ifdef INET6
- case ETHERTYPE_IPV6: /*XXX*/
-#ifdef PPP_IPV6
- case PPP_IPV6:
-#endif
- ip6_print((const u_char *)(p + PPP_HDRLEN), length);
+ /*
+ * Some printers want to get back at the link level addresses,
+ * and/or check that they're not walking off the end of the packet.
+ * Rather than pass them all the way down, we set these globals.
+ */
+ packetp = p;
+ snapend = p + caplen;
+
+ switch (p[0]) {
+
+ case PPP_ADDRESS:
+ if (caplen < 4) {
+ printf("[|ppp]");
+ goto out;
+ }
+
+ ts_print(&h->ts);
+ if (eflag)
+ printf("%02x %02x %d ", p[0], p[1], length);
+ p += 2;
+ length -= 2;
+
+ proto = EXTRACT_16BITS(p);
+ p += 2;
+ length -= 2;
+ printf("%s: ", ppp_protoname(proto));
+
+ handle_ppp(proto, p, length);
break;
-#endif
+
+ case CHDLC_UNICAST:
+ case CHDLC_BCAST:
+ /*
+ * Have the Cisco HDLC print routine do all the work.
+ */
+ chdlc_if_print(user, h, p);
+ return;
default:
- if(!eflag)
- ppp_hdlc_print(p, length);
- if(!xflag)
- default_print((const u_char *)(p + PPP_HDRLEN),
- caplen - PPP_HDRLEN);
+ ts_print(&h->ts);
+ if (eflag)
+ printf("%02x %02x %d ", p[0], p[1], length);
+ p += 2;
+ length -= 2;
+
+ /*
+ * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats
+ * the next two octets as an Ethernet type; does that
+ * ever happen?
+ */
+ printf("unknown addr %02x; ctrl %02x", p[0], p[1]);
+ break;
}
if (xflag)
- default_print((const u_char *)(p + PPP_HDRLEN),
- caplen - PPP_HDRLEN);
+ default_print(p, caplen);
out:
putchar('\n');
}
+
+
struct tok ppptype2str[] = {
{ PPP_IP, "IP" },
{ PPP_OSI, "OSI" },
@@ -561,15 +1201,18 @@ struct tok ppptype2str[] = {
{ PPP_OSICP, "OSICP" },
{ PPP_NSCP, "NSCP" },
{ PPP_DECNETCP, "DECNETCP" },
- { PPP_APPLECP, "APPLECP" },
+ { PPP_APPLECP, "APPLECP" },
{ PPP_IPXCP, "IPXCP" },
{ PPP_STIICP, "STIICP" },
- { PPP_VINESCP, "VINESCP" },
+ { PPP_VINESCP, "VINESCP" },
{ PPP_LCP, "LCP" },
{ PPP_PAP, "PAP" },
{ PPP_LQM, "LQM" },
{ PPP_CHAP, "CHAP" },
+ { PPP_BACP, "BACP" },
+ { PPP_BAP, "BAP" },
+ { PPP_MP, "MP" },
{ 0, NULL }
};
@@ -584,7 +1227,7 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
register u_int length = h->len;
register u_int caplen = h->caplen;
register int hdrlength;
- u_short ptype;
+ u_int16_t ptype;
const u_char *q;
int i;
@@ -606,26 +1249,26 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
#if 0
if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
- if (eflag)
+ if (eflag)
printf("%02x %02x ", p[0], p[1]);
p += 2;
hdrlength = 2;
}
- if (eflag)
+ if (eflag)
printf("%d ", length);
/* Retrieve the protocol type */
if (*p & 01) {
/* Compressed protocol field */
ptype = *p;
- if (eflag)
+ if (eflag)
printf("%02x ", ptype);
p++;
hdrlength += 1;
} else {
/* Un-compressed protocol field */
- ptype = ntohs(*(u_short *)p);
- if (eflag)
+ ptype = ntohs(*(u_int16_t *)p);
+ if (eflag)
printf("%04x ", ptype);
p += 2;
hdrlength += 2;
@@ -642,7 +1285,7 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
ph = (struct ppp_header *)q;
if (ph->phdr_addr == PPP_ADDRESS
&& ph->phdr_ctl == PPP_CONTROL) {
- if (eflag)
+ if (eflag)
printf("%02x %02x ", q[0], q[1]);
ptype = ntohs(ph->phdr_type);
if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
@@ -657,9 +1300,9 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
printf("] ");
}
}
- if (eflag)
- printf("%d ", length);
}
+ if (eflag)
+ printf("%d ", length);
if (p[SLC_CHL]) {
q = p + SLC_BPFHDRLEN + p[SLC_LLHL];
@@ -668,15 +1311,31 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
ptype = vjc_print(q, length - (q - p), ptype);
hdrlength = PPP_BSDI_HDRLEN;
p += hdrlength;
- if (ptype == PPP_IP)
+ switch (ptype) {
+ case PPP_IP:
ip_print(p, length);
+ break;
+#ifdef INET6
+ case PPP_IPV6:
+ ip6_print(p, length);
+ break;
+#endif
+ }
goto printx;
case PPP_VJNC:
ptype = vjc_print(q, length - (q - p), ptype);
hdrlength = PPP_BSDI_HDRLEN;
p += hdrlength;
- if (ptype == PPP_IP)
+ switch (ptype) {
+ case PPP_IP:
ip_print(p, length);
+ break;
+#ifdef INET6
+ case PPP_IPV6:
+ ip6_print(p, length);
+ break;
+#endif
+ }
goto printx;
default:
if (eflag) {
@@ -695,10 +1354,18 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
length -= hdrlength;
p += hdrlength;
- if (ptype == PPP_IP)
+ switch (ptype) {
+ case PPP_IP:
ip_print(p, length);
- else
+ break;
+#ifdef INET6
+ case PPP_IPV6:
+ ip6_print(p, length);
+ break;
+#endif
+ default:
printf("%s ", tok2str(ppptype2str, "proto-#%d", ptype));
+ }
printx:
if (xflag)
diff --git a/contrib/tcpdump/print-sl.c b/contrib/tcpdump/print-sl.c
index c2f622bde0aa..ed6948a1630f 100644
--- a/contrib/tcpdump/print-sl.c
+++ b/contrib/tcpdump/print-sl.c
@@ -23,37 +23,17 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.46 1999/11/21 12:38:24 itojun Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.56 2000/10/10 05:06:10 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#ifdef HAVE_NET_SLIP_H
#include <sys/param.h>
#include <sys/time.h>
-#include <sys/timeb.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-
-#if __STDC__
-struct rtentry;
-#endif
-#include <net/if.h>
#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <net/ethernet.h>
-#include <netinet/ip_var.h>
-#include <netinet/udp.h>
-#include <netinet/tcp.h>
-
-#include <net/slcompress.h>
-#include <net/slip.h>
#include <ctype.h>
#include <netdb.h>
@@ -64,22 +44,17 @@ struct rtentry;
#include "addrtoname.h"
#include "extract.h" /* must come after interface.h */
+#include "ip.h"
+#include "tcp.h"
+#include "slip.h"
+#include "slcompress.h"
+
static u_int lastlen[2][256];
static u_int lastconn = 255;
static void sliplink_print(const u_char *, const struct ip *, u_int);
static void compressed_sl_print(const u_char *, const struct ip *, u_int, int);
-/* XXX BSD/OS 2.1 compatibility */
-#if !defined(SLIP_HDRLEN) && defined(SLC_BPFHDR)
-#define SLIP_HDRLEN SLC_BPFHDR
-#define SLX_DIR 0
-#define SLX_CHDR (SLC_BPFHDRLEN - 1)
-#define CHDR_LEN (SLC_BPFHDR - SLC_BPFHDRLEN)
-#endif
-
-/* XXX needs more hacking to work right */
-
void
sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
@@ -108,7 +83,7 @@ sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
if (eflag)
sliplink_print(p, ip, length);
- switch (ip->ip_v) {
+ switch (IP_V(ip)) {
case 4:
ip_print((u_char *)ip, length);
break;
@@ -118,7 +93,7 @@ sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
break;
#endif
default:
- printf ("ip v%d", ip->ip_v);
+ printf ("ip v%d", IP_V(ip));
}
if (xflag)
@@ -199,8 +174,8 @@ sliplink_print(register const u_char *p, register const struct ip *ip,
* has restored the IP header copy to IPPROTO_TCP.
*/
lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p;
- hlen = ip->ip_hl;
- hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off;
+ hlen = IP_HL(ip);
+ hlen += TH_OFF((struct tcphdr *)&((int *)ip)[hlen]);
lastlen[dir][lastconn] = length - (hlen << 2);
printf("utcp %d: ", lastconn);
break;
@@ -289,33 +264,8 @@ compressed_sl_print(const u_char *chdr, const struct ip *ip,
* 'cp - chdr' is the length of the compressed header.
* 'length - hlen' is the amount of data in the packet.
*/
- hlen = ip->ip_hl;
- hlen += ((struct tcphdr *)&((int32_t *)ip)[hlen])->th_off;
+ hlen = IP_HL(ip);
+ hlen += TH_OFF((struct tcphdr *)&((int32_t *)ip)[hlen]);
lastlen[dir][lastconn] = length - (hlen << 2);
- printf(" %d (%d)", lastlen[dir][lastconn], cp - chdr);
+ printf(" %d (%ld)", lastlen[dir][lastconn], (long)(cp - chdr));
}
-#else
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <pcap.h>
-#include <stdio.h>
-
-#include "interface.h"
-
-void
-sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
-{
-
- error("not configured for slip");
- /* NOTREACHED */
-}
-
-void
-sl_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
-{
-
- error("not configured for slip");
- /* NOTREACHED */
-}
-#endif
diff --git a/contrib/tcpdump/print-sunrpc.c b/contrib/tcpdump/print-sunrpc.c
index ddac9138321e..600af6e9ff08 100644
--- a/contrib/tcpdump/print-sunrpc.c
+++ b/contrib/tcpdump/print-sunrpc.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-sunrpc.c,v 1.29 1999/11/21 09:37:02 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-sunrpc.c,v 1.39 2000/10/07 05:53:13 itojun Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -34,17 +34,10 @@ static const char rcsid[] =
#include <sys/time.h>
#include <sys/socket.h>
-#if __STDC__
struct mbuf;
struct rtentry;
-#endif
-#include <net/if.h>
#include <netinet/in.h>
-#include <net/ethernet.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
#include <rpc/rpc.h>
#ifdef HAVE_RPC_RPCENT_H
@@ -60,6 +53,11 @@ struct rtentry;
#include "interface.h"
#include "addrtoname.h"
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+
static struct tok proc2str[] = {
{ PMAPPROC_NULL, "null" },
{ PMAPPROC_SET, "set" },
@@ -79,24 +77,44 @@ sunrpcrequest_print(register const u_char *bp, register u_int length,
{
register const struct rpc_msg *rp;
register const struct ip *ip;
+#ifdef INET6
+ register const struct ip6_hdr *ip6;
+#endif
u_int32_t x;
+ char srcid[20], dstid[20]; /*fits 32bit*/
rp = (struct rpc_msg *)bp;
- ip = (struct ip *)bp2;
-
- if (!nflag)
- (void)printf("%s.%x > %s.sunrpc: %d",
- ipaddr_string(&ip->ip_src),
- (u_int32_t)ntohl(rp->rm_xid),
- ipaddr_string(&ip->ip_dst),
- length);
- else
- (void)printf("%s.%x > %s.%x: %d",
- ipaddr_string(&ip->ip_src),
- (u_int32_t)ntohl(rp->rm_xid),
- ipaddr_string(&ip->ip_dst),
- PMAPPORT,
- length);
+
+ if (!nflag) {
+ snprintf(srcid, sizeof(srcid), "0x%x",
+ (u_int32_t)ntohl(rp->rm_xid));
+ strlcpy(dstid, "sunrpc", sizeof(dstid));
+ } else {
+ snprintf(srcid, sizeof(srcid), "0x%x",
+ (u_int32_t)ntohl(rp->rm_xid));
+ snprintf(dstid, sizeof(dstid), "0x%x", PMAPPORT);
+ }
+
+ switch (IP_V((struct ip *)bp2)) {
+ case 4:
+ ip = (struct ip *)bp2;
+ printf("%s.%s > %s.%s: %d",
+ ipaddr_string(&ip->ip_src), srcid,
+ ipaddr_string(&ip->ip_dst), dstid, length);
+ break;
+#ifdef INET6
+ case 6:
+ ip6 = (struct ip6_hdr *)bp2;
+ printf("%s.%s > %s.%s: %d",
+ ip6addr_string(&ip6->ip6_src), srcid,
+ ip6addr_string(&ip6->ip6_dst), dstid, length);
+ break;
+#endif
+ default:
+ printf("%s.%s > %s.%s: %d", "?", srcid, "?", dstid, length);
+ break;
+ }
+
printf(" %s", tok2str(proc2str, " proc #%u",
(u_int32_t)ntohl(rp->rm_call.cb_proc)));
x = ntohl(rp->rm_call.cb_rpcvers);
@@ -131,10 +149,8 @@ progstr(prog)
return (buf);
rp = getrpcbynumber(prog);
if (rp == NULL)
- (void) sprintf(buf, "#%u", prog);
- else {
- strncpy(buf, rp->r_name, sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
- }
+ (void) snprintf(buf, sizeof(buf), "#%u", prog);
+ else
+ strlcpy(buf, rp->r_name, sizeof(buf));
return (buf);
}
diff --git a/contrib/tcpdump/print-token.c b/contrib/tcpdump/print-token.c
index 0edbf2f0f75a..158d86a5178f 100644
--- a/contrib/tcpdump/print-token.c
+++ b/contrib/tcpdump/print-token.c
@@ -171,7 +171,7 @@ token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
extracted_ethertype = 0;
/* Try to print the LLC-layer header & higher layers */
- if (llc_print(p, length, caplen, ESRC(tp), EDST(tp)) == 0) {
+ if (llc_print(p, length, caplen, ESRC(tp), EDST(tp), &extracted_ethertype) == 0) {
/* ether_type not known, print raw packet */
if (!eflag)
token_print((u_char *)tp, length);
diff --git a/contrib/tcpdump/print-udp.c b/contrib/tcpdump/print-udp.c
index 9a64fb3da376..2e703bb96992 100644
--- a/contrib/tcpdump/print-udp.c
+++ b/contrib/tcpdump/print-udp.c
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.70 1999/12/22 06:27:23 itojun Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.90 2000/12/23 20:55:22 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -32,22 +32,9 @@ static const char rcsid[] =
#include <sys/param.h>
#include <sys/time.h>
-#include <sys/socket.h>
#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
-#ifdef NOERROR
-#undef NOERROR /* Solaris sucks */
-#endif
-#ifdef T_UNSPEC
-#undef T_UNSPEC /* SINIX does too */
-#endif
-#include <arpa/nameser.h>
#ifdef SEGSIZE
#undef SEGSIZE
#endif
@@ -56,27 +43,38 @@ static const char rcsid[] =
#include <rpc/rpc.h>
#include <stdio.h>
-
-#ifdef INET6
-#include <netinet/ip6.h>
-#endif
+#include <string.h>
#include "interface.h"
#include "addrtoname.h"
#include "appletalk.h"
+#include "udp.h"
+
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+
+#ifdef NOERROR
+#undef NOERROR /* Solaris sucks */
+#endif
+#ifdef T_UNSPEC
+#undef T_UNSPEC /* SINIX does too */
+#endif
+#include "nameser.h"
#include "nfs.h"
#include "bootp.h"
struct rtcphdr {
- u_short rh_flags; /* T:2 P:1 CNT:5 PT:8 */
- u_short rh_len; /* length of message (in words) */
- u_int rh_ssrc; /* synchronization src id */
+ u_int16_t rh_flags; /* T:2 P:1 CNT:5 PT:8 */
+ u_int16_t rh_len; /* length of message (in words) */
+ u_int32_t rh_ssrc; /* synchronization src id */
};
typedef struct {
- u_int upper; /* more significant 32 bits */
- u_int lower; /* less significant 32 bits */
+ u_int32_t upper; /* more significant 32 bits */
+ u_int32_t lower; /* less significant 32 bits */
} ntp64;
/*
@@ -84,9 +82,9 @@ typedef struct {
*/
struct rtcp_sr {
ntp64 sr_ntp; /* 64-bit ntp timestamp */
- u_int sr_ts; /* reference media timestamp */
- u_int sr_np; /* no. packets sent */
- u_int sr_nb; /* no. bytes sent */
+ u_int32_t sr_ts; /* reference media timestamp */
+ u_int32_t sr_np; /* no. packets sent */
+ u_int32_t sr_nb; /* no. bytes sent */
};
/*
@@ -94,12 +92,12 @@ struct rtcp_sr {
* Time stamps are middle 32-bits of ntp timestamp.
*/
struct rtcp_rr {
- u_int rr_srcid; /* sender being reported */
- u_int rr_nl; /* no. packets lost */
- u_int rr_ls; /* extended last seq number received */
- u_int rr_dv; /* jitter (delay variance) */
- u_int rr_lsr; /* orig. ts from last rr from this src */
- u_int rr_dlsr; /* time from recpt of last rr to xmit time */
+ u_int32_t rr_srcid; /* sender being reported */
+ u_int32_t rr_nl; /* no. packets lost */
+ u_int32_t rr_ls; /* extended last seq number received */
+ u_int32_t rr_dv; /* jitter (delay variance) */
+ u_int32_t rr_lsr; /* orig. ts from last rr from this src */
+ u_int32_t rr_dlsr; /* time from recpt of last rr to xmit time */
};
/*XXX*/
@@ -121,7 +119,7 @@ static void
vat_print(const void *hdr, u_int len, register const struct udphdr *up)
{
/* vat/vt audio */
- u_int ts = *(u_short *)hdr;
+ u_int ts = *(u_int16_t *)hdr;
if ((ts & 0xf060) != 0) {
/* probably vt */
(void)printf(" udp/vt %u %d / %d",
@@ -129,8 +127,8 @@ vat_print(const void *hdr, u_int len, register const struct udphdr *up)
ts & 0x3ff, ts >> 10);
} else {
/* probably vat */
- u_int i0 = ntohl(((u_int *)hdr)[0]);
- u_int i1 = ntohl(((u_int *)hdr)[1]);
+ u_int32_t i0 = (u_int32_t)ntohl(((u_int *)hdr)[0]);
+ u_int32_t i1 = (u_int32_t)ntohl(((u_int *)hdr)[1]);
printf(" udp/vat %u c%d %u%s",
(u_int32_t)(ntohs(up->uh_ulen) - sizeof(*up) - 8),
i0 & 0xffff,
@@ -149,8 +147,8 @@ rtp_print(const void *hdr, u_int len, register const struct udphdr *up)
/* rtp v1 or v2 */
u_int *ip = (u_int *)hdr;
u_int hasopt, hasext, contype, hasmarker;
- u_int i0 = ntohl(((u_int *)hdr)[0]);
- u_int i1 = ntohl(((u_int *)hdr)[1]);
+ u_int32_t i0 = (u_int32_t)ntohl(((u_int *)hdr)[0]);
+ u_int32_t i1 = (u_int32_t)ntohl(((u_int *)hdr)[1]);
u_int dlen = ntohs(up->uh_ulen) - sizeof(*up) - 8;
const char * ptype;
@@ -184,7 +182,7 @@ rtp_print(const void *hdr, u_int len, register const struct udphdr *up)
i0 & 0xffff,
i1);
if (vflag) {
- printf(" %u", i1);
+ printf(" %u", (u_int32_t)ntohl(((u_int *)hdr)[2]));
if (hasopt) {
u_int i2, optlen;
do {
@@ -221,7 +219,7 @@ rtcp_print(const u_char *hdr, const u_char *ep)
struct rtcp_sr *sr;
struct rtcphdr *rh = (struct rtcphdr *)hdr;
u_int len;
- u_short flags;
+ u_int16_t flags;
int cnt;
double ts, dts;
if ((u_char *)(rh + 1) > ep) {
@@ -238,7 +236,7 @@ rtcp_print(const u_char *hdr, const u_char *ep)
if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh))
printf(" [%d]", len);
if (vflag)
- printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
+ printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
if ((u_char *)(sr + 1) > ep) {
printf(" [|rtcp]");
return (ep);
@@ -256,18 +254,18 @@ rtcp_print(const u_char *hdr, const u_char *ep)
printf(" [%d]", len);
rr = (struct rtcp_rr *)(rh + 1);
if (vflag)
- printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
+ printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
break;
case RTCP_PT_SDES:
printf(" sdes %d", len);
if (vflag)
- printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
+ printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
cnt = 0;
break;
case RTCP_PT_BYE:
printf(" bye %d", len);
if (vflag)
- printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
+ printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc));
cnt = 0;
break;
default:
@@ -294,6 +292,100 @@ rtcp_print(const u_char *hdr, const u_char *ep)
return (hdr + len);
}
+static int udp_cksum(register const struct ip *ip,
+ register const struct udphdr *up,
+ register int len)
+{
+ int i, tlen;
+ union phu {
+ struct phdr {
+ u_int32_t src;
+ u_int32_t dst;
+ u_char mbz;
+ u_char proto;
+ u_int16_t len;
+ } ph;
+ u_int16_t pa[6];
+ } phu;
+ register const u_int16_t *sp;
+ u_int32_t sum;
+ tlen = ntohs(ip->ip_len) - ((const char *)up-(const char*)ip);
+
+ /* pseudo-header.. */
+ phu.ph.len = htons(tlen);
+ phu.ph.mbz = 0;
+ phu.ph.proto = IPPROTO_UDP;
+ memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
+ memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t));
+
+ sp = &phu.pa[0];
+ sum = sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5];
+
+ sp = (const u_int16_t *)up;
+
+ for (i=0; i<(tlen&~1); i+= 2)
+ sum += *sp++;
+
+ if (tlen & 1) {
+ sum += htons( (*(const u_int8_t *)sp) << 8);
+ }
+
+ while (sum > 0xffff)
+ sum = (sum & 0xffff) + (sum >> 16);
+ sum = ~sum & 0xffff;
+
+ return (sum);
+}
+
+#ifdef INET6
+static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up,
+ int len)
+{
+ int i, tlen;
+ register const u_int16_t *sp;
+ u_int32_t sum;
+ union {
+ struct {
+ struct in6_addr ph_src;
+ struct in6_addr ph_dst;
+ u_int32_t ph_len;
+ u_int8_t ph_zero[3];
+ u_int8_t ph_nxt;
+ } ph;
+ u_int16_t pa[20];
+ } phu;
+
+ tlen = ntohs(ip6->ip6_plen) + sizeof(struct ip6_hdr) -
+ ((const char *)up - (const char*)ip6);
+
+ /* pseudo-header */
+ memset(&phu, 0, sizeof(phu));
+ phu.ph.ph_src = ip6->ip6_src;
+ phu.ph.ph_dst = ip6->ip6_dst;
+ phu.ph.ph_len = htonl(tlen);
+ phu.ph.ph_nxt = IPPROTO_UDP;
+
+ sum = 0;
+ for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
+ sum += phu.pa[i];
+
+ sp = (const u_int16_t *)up;
+
+ for (i = 0; i < (tlen & ~1); i += 2)
+ sum += *sp++;
+
+ if (tlen & 1)
+ sum += htons((*(const u_int8_t *)sp) << 8);
+
+ while (sum > 0xffff)
+ sum = (sum & 0xffff) + (sum >> 16);
+ sum = ~sum & 0xffff;
+
+ return (sum);
+}
+#endif
+
+
/* XXX probably should use getservbyname() and cache answers */
#define TFTP_PORT 69 /*XXX*/
#define KERBEROS_PORT 88 /*XXX*/
@@ -302,6 +394,7 @@ rtcp_print(const u_char *hdr, const u_char *ep)
#define NTP_PORT 123 /*XXX*/
#define SNMPTRAP_PORT 162 /*XXX*/
#define ISAKMP_PORT 500 /*XXX*/
+#define TIMED_PORT 525 /*XXX*/
#define RIP_PORT 520 /*XXX*/
#define KERBEROS_SEC_PORT 750 /*XXX*/
#define L2TP_PORT 1701 /*XXX*/
@@ -312,6 +405,10 @@ rtcp_print(const u_char *hdr, const u_char *ep)
#define NETBIOS_NS_PORT 137
#define NETBIOS_DGRAM_PORT 138
#define CISCO_AUTORP_PORT 496 /*XXX*/
+#define RADIUS_PORT 1645
+#define RADIUS_NEW_PORT 1812
+#define RADIUS_ACCOUNTING_PORT 1646
+#define RADIUS_NEW_ACCOUNTING_PORT 1813
#ifdef INET6
#define RIPNG_PORT 521 /*XXX*/
@@ -320,13 +417,14 @@ rtcp_print(const u_char *hdr, const u_char *ep)
#endif
void
-udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
+udp_print(register const u_char *bp, u_int length,
+ register const u_char *bp2, int fragmented)
{
register const struct udphdr *up;
register const struct ip *ip;
register const u_char *cp;
register const u_char *ep = bp + length;
- u_short sport, dport, ulen;
+ u_int16_t sport, dport, ulen;
#ifdef INET6
register const struct ip6_hdr *ip6;
#endif
@@ -336,7 +434,7 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
up = (struct udphdr *)bp;
ip = (struct ip *)bp2;
#ifdef INET6
- if (ip->ip_v == 6)
+ if (IP_V(ip) == 6)
ip6 = (struct ip6_hdr *)bp2;
else
ip6 = NULL;
@@ -358,6 +456,13 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
sport = ntohs(up->uh_sport);
dport = ntohs(up->uh_dport);
ulen = ntohs(up->uh_ulen);
+ if (ulen < 8) {
+ (void)printf("%s > %s: truncated-udplength %d",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst),
+ ulen);
+ return;
+ }
if (packettype) {
register struct rpc_msg *rp;
enum msg_type direction;
@@ -420,6 +525,15 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
udpport_string(dport));
snmp_print((const u_char *)(up + 1), length);
break;
+
+ case PT_CNFP:
+ (void)printf("%s.%s > %s.%s:",
+ ipaddr_string(&ip->ip_src),
+ udpport_string(sport),
+ ipaddr_string(&ip->ip_dst),
+ udpport_string(dport));
+ cnfp_print(cp, length, (const u_char *)ip);
+ break;
}
return;
}
@@ -453,7 +567,7 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
(atalk_port(sport) || atalk_port(dport))) {
if (vflag)
fputs("kip ", stdout);
- atalk_print(cp, length);
+ llap_print(cp, length);
return;
}
}
@@ -490,10 +604,38 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
}
#endif
+ if (IP_V(ip) == 4 && vflag && !fragmented) {
+ int sum = up->uh_sum;
+ if (sum == 0) {
+ (void)printf(" [no cksum]");
+ } else if (TTEST2(cp[0], length)) {
+ sum = udp_cksum(ip, up, length);
+ if (sum != 0)
+ (void)printf(" [bad udp cksum %x!]", sum);
+ else
+ (void)printf(" [udp sum ok]");
+ }
+ }
+#ifdef INET6
+ if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !fragmented) {
+ int sum = up->uh_sum;
+ /* for IPv6, UDP checksum is mandatory */
+ if (TTEST2(cp[0], length)) {
+ sum = udp6_cksum(ip6, up, length);
+ if (sum != 0)
+ (void)printf(" [bad udp cksum %x!]", sum);
+ else
+ (void)printf(" [udp sum ok]");
+ }
+ }
+#endif
+
if (!qflag) {
#define ISPORT(p) (dport == (p) || sport == (p))
if (ISPORT(NAMESERVER_PORT))
ns_print((const u_char *)(up + 1), length);
+ else if (ISPORT(TIMED_PORT))
+ timed_print((const u_char *)(up + 1), length);
else if (ISPORT(TFTP_PORT))
tftp_print((const u_char *)(up + 1), length);
else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS))
@@ -546,6 +688,11 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2)
wb_print((const void *)(up + 1), length);
else if (ISPORT(CISCO_AUTORP_PORT))
cisco_autorp_print((const void *)(up + 1), length);
+ else if (ISPORT(RADIUS_PORT) ||
+ ISPORT(RADIUS_NEW_PORT) ||
+ ISPORT(RADIUS_ACCOUNTING_PORT) ||
+ ISPORT(RADIUS_NEW_ACCOUNTING_PORT) )
+ radius_print((const u_char *)(up+1), length);
else
(void)printf(" udp %u",
(u_int32_t)(ulen - sizeof(*up)));
diff --git a/contrib/tcpdump/tcpdump.1 b/contrib/tcpdump/tcpdump.1
index 500bb000c206..785bfbc63081 100644
--- a/contrib/tcpdump/tcpdump.1
+++ b/contrib/tcpdump/tcpdump.1
@@ -1,4 +1,4 @@
-.\" @(#) $Header: /tcpdump/master/tcpdump/tcpdump.1,v 1.72.2.2 2000/01/29 16:42:03 itojun Exp $ (LBL)
+.\" @(#) $Header: /tcpdump/master/tcpdump/tcpdump.1,v 1.92.2.2 2001/01/18 04:38:31 guy Exp $ (LBL)
.\"
.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
@@ -22,7 +22,7 @@
.\"
.\" $FreeBSD$
.\"
-.TH TCPDUMP 1 "30 June 1997"
+.TH TCPDUMP 1 "3 January 2001"
.SH NAME
tcpdump \- dump traffic on a network
.SH SYNOPSIS
@@ -68,6 +68,10 @@ tcpdump \- dump traffic on a network
.br
.ti +8
[
+.B \-E
+.I algo:secret
+]
+[
.I expression
]
.br
@@ -85,7 +89,7 @@ you must have read access to
or
.IR /dev/bpf* .
.B Under Solaris with dlpi:
-You must have read access to the network pseudo device, e.g.
+You must have read/write access to the network pseudo device, e.g.
.IR /dev/le .
.B Under HP-UX with dlpi:
You must be root or it must be installed setuid to root.
@@ -124,6 +128,27 @@ Dump packet-matching code as decimal numbers (preceded with a count).
.B \-e
Print the link-level header on each dump line.
.TP
+.B \-E
+Use \fIalgo:secret\fP for decrypting IPsec ESP packets. Algorithms may be
+\fBdes-cbc\fP,
+\fB3des-cbc\fP,
+\fBblowfish-cbc\fP,
+\fBrc3-cbc\fP,
+\fBcast128-cbc\fP, or
+\fBnone\fP.
+The default is \fBdes-cbc\fP.
+The ability to decrypt packets is only present if \fItcpdump\fP was compiled
+with cryptography enabled.
+\fIsecret\fP the ascii text for ESP secret key.
+We cannot take arbitrary binary value at this moment.
+The option assumes RFC2406 ESP, not RFC1827 ESP.
+The option is only for debugging purposes, and
+the use of this option with truly `secret' key is discouraged.
+By presenting IPsec secret key onto command line
+you make it visible to others, via
+.IR ps (1)
+and other occasions.
+.TP
.B \-f
Print `foreign' internet addresses numerically rather than symbolically
(this option is intended to get around serious brain damage in
@@ -139,6 +164,12 @@ Listen on \fIinterface\fP.
If unspecified, \fItcpdump\fP searches the system interface list for the
lowest numbered, configured up interface (excluding loopback).
Ties are broken by choosing the earliest match.
+.IP
+On Linux systems with 2.2 or later kernels, an
+.I interface
+argument of ``any'' can be used to capture packets from all interfaces.
+Note that captures on the ``any'' device will not be done in promiscuous
+mode.
.TP
.B \-l
Make stdout line buffered. Useful if you want to see the data
@@ -157,7 +188,7 @@ instead of ``nic.ddn.mil''.
.TP
.B \-m
Load SMI MIB module definitions from file \fImodule\fR. This option
-can be used several times to load several MIB modules into tcpdump.
+can be used several times to load several MIB modules into \fItcpdump\fP.
.TP
.B \-O
Do not run the packet-matching code optimizer. This is useful only
@@ -189,11 +220,13 @@ Note that taking larger snapshots both increases
the amount of time it takes to process packets and, effectively,
decreases the amount of packet buffering. This may cause packets to be
lost. You should limit \fIsnaplen\fP to the smallest number that will
-capture the protocol information you're interested in.
+capture the protocol information you're interested in. Setting
+\fIsnaplen\fP to 0 means use the required length to catch whole packets.
.TP
.B \-T
Force packets selected by "\fIexpression\fP" to be interpreted the
specified \fItype\fR. Currently known types are
+\fBcnfp\fR (Cisco NetFlow protocol),
\fBrpc\fR (Remote Procedure Call),
\fBrtp\fR (Real-Time Applications protocol),
\fBrtcp\fR (Real-Time Applications control protocol),
@@ -218,8 +251,10 @@ Print absolute, rather than relative, TCP sequence numbers.
Print an unformatted timestamp on each dump line.
.TP
.B \-v
-(Slightly more) verbose output. For example, the time to live
-and type of service information in an IP packet is printed.
+(Slightly more) verbose output. For example, the time to live,
+identification, total length and options in an IP packet are printed.
+Also enables additional packet integrity checks such as verifying the
+IP and ICMP header checksum.
.TP
.B \-vv
Even more verbose output. For example, additional fields are
@@ -277,7 +312,7 @@ qualifier,
is assumed.
.IP \fIdir\fP
qualifiers specify a particular transfer direction to and/or from
-.I id.
+.IR id .
Possible directions are
.BR src ,
.BR dst ,
@@ -299,6 +334,7 @@ qualifiers restrict the match to a particular protocol. Possible
protos are:
.BR ether ,
.BR fddi ,
+.BR tr ,
.BR ip ,
.BR ip6 ,
.BR arp ,
@@ -328,7 +364,10 @@ 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.]
+but you cannot name them explicitly in a filter expression.
+.LP
+Similarly, `tr' is an alias for `ether'; the previous paragraph's
+statements about FDDI headers also apply to Token Ring headers.]
.LP
In addition to the above, there are some special `primitive' keywords
that don't follow the pattern:
@@ -451,11 +490,12 @@ This is equivalent to:
.fi
.in -.5i
.IP "\fBip proto \fIprotocol\fR"
-True if the packet is an ip packet (see
+True if the packet is an IP packet (see
.IR ip (4P))
of protocol type \fIprotocol\fP.
\fIProtocol\fP can be a number or one of the names
-\fIicmp\fP, \fIigrp\fP, \fIudp\fP, \fInd\fP, or \fItcp\fP.
+\fIicmp\fP, \fIicmp6\fP, \fIigmp\fP, \fIigrp\fP, \fIpim\fP, \fIah\fP,
+\fIesp\fP, \fIudp\fP, or \fItcp\fP.
Note that the identifiers \fItcp\fP, \fIudp\fP, and \fIicmp\fP are also
keywords and must be escaped via backslash (\\), which is \\\\ in the C-shell.
Note that this primitive does not chase protocol header chain.
@@ -498,8 +538,10 @@ True if the packet is an IP multicast packet.
True if the packet is an IPv6 multicast packet.
.IP "\fBether proto \fIprotocol\fR"
True if the packet is of ether type \fIprotocol\fR.
-\fIProtocol\fP can be a number or a name like
-\fIip\fP, \fIip6\fP, \fIarp\fP, or \fIrarp\fP.
+\fIProtocol\fP can be a number or one of the names
+\fIip\fP, \fIip6\fP, \fIarp\fP, \fIrarp\fP, \fIatalk\fP, \fIaarp\fP,
+\fIdecnet\fP, \fIsca\fP, \fIlat\fP, \fImopdl\fP, \fImoprc\fP, or
+\fIiso\fP.
Note these identifiers are also keywords
and must be escaped via backslash (\\).
[In the case of FDDI (e.g., `\fBfddi protocol arp\fR'), the
@@ -507,7 +549,7 @@ 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.]
+is in so-called SNAP format. The same applies to Token Ring.]
.IP "\fBdecnet src \fIhost\fR"
True if the DECNET source address is
.IR host ,
@@ -520,7 +562,7 @@ True if the DECNET destination address is
.IP "\fBdecnet host \fIhost\fR"
True if either the DECNET source or destination address is
.IR host .
-.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBdecnet\fR, \fBiso\fR"
+.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR"
Abbreviations for:
.in +.5i
.nf
@@ -538,6 +580,13 @@ Abbreviations for:
where \fIp\fR is one of the above protocols.
Note that
\fItcpdump\fP does not currently know how to parse these protocols.
+.IP "\fBvlan \fI[vlan_id]\fR"
+True if the packet is an IEEE 802.1Q VLAN packet.
+If \fI[vlan_id]\fR is specified, only true is the packet has the specified
+\fIvlan_id\fR.
+Note that the first \fBvlan\fR keyword encountered in \fIexpression\fR
+changes the decoding offsets for the remainder of \fIexpression\fR
+on the assumption that the packet is a VLAN packet.
.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
Abbreviations for:
.in +.5i
@@ -546,7 +595,11 @@ Abbreviations for:
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
-.IP "\fBesis\fR, \fBisis\fR"
+.IP "\fBiso proto \fIprotocol\fR"
+True if the packet is an OSI packet of protocol type \fIprotocol\fP.
+\fIProtocol\fP can be a number or one of the names
+\fIclnp\fP, \fIesis\fP, or \fIisis\fP.
+.IP "\fBclnp\fR, \fBesis\fR, \fBisis\fR"
Abbreviations for:
.in +.5i
.nf
@@ -567,7 +620,7 @@ data inside the packet, use the following syntax:
\fIproto\fB [ \fIexpr\fB : \fIsize\fB ]\fR
.fi
.in -.5i
-\fIProto\fR is one of \fBether, fddi,
+\fIProto\fR is one of \fBether, fddi, tr,
ip, arp, rarp, tcp, udp, icmp\fR or \fBip6\fR, and
indicates the protocol layer for the index operation.
Note that \fItcp, udp\fR and other upper-layer protocol types only
@@ -627,8 +680,8 @@ which should not be confused with
.fi
.in -.5i
.LP
-Expression arguments can be passed to tcpdump as either a single argument
-or as multiple arguments, whichever is more convenient.
+Expression arguments can be passed to \fItcpdump\fP as either a single
+argument or as multiple arguments, whichever is more convenient.
Generally, if the expression contains Shell metacharacters, it is
easier to pass it as a single, quoted argument.
Multiple arguments are concatenated with spaces before being parsed.
@@ -743,6 +796,13 @@ 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
+On Token Ring networks, the '-e' option causes \fItcpdump\fP to print
+the `access control' and `frame control' fields, the source and
+destination addresses, and the packet length. As on FDDI networks,
+packets are assumed to contain an LLC packet. Regardless of whether
+the '-e' option is specified or not, the source routing information is
+printed for source-routed packets.
+.LP
\fI(N.B.: The following description assumes familiarity with
the SLIP compression algorithm described in RFC-1144.)\fP
.LP
@@ -784,7 +844,7 @@ host \fIrtsg\fP to host \fIcsam\fP:
.nf
.sp .5
\f(CWarp who-has csam tell rtsg
-arp reply csam is-at CSAM\fP
+arp reply csam is-at CSAM\fR
.sp .5
.fi
.RE
@@ -808,7 +868,7 @@ broadcast and the second is point-to-point would be visible:
.nf
.sp .5
\f(CWRTSG Broadcast 0806 64: arp who-has csam tell rtsg
-CSAM RTSG 0806 64: arp reply csam is-at CSAM\fP
+CSAM RTSG 0806 64: arp reply csam is-at CSAM\fR
.sp .5
.fi
.RE
@@ -820,7 +880,7 @@ TCP Packets
.LP
\fI(N.B.:The following description assumes familiarity with
the TCP protocol described in RFC-793. If you are not familiar
-with the protocol, neither this description nor tcpdump will
+with the protocol, neither this description nor \fItcpdump\fP will
be of much use to you.)\fP
.LP
The general format of a tcp protocol line is:
@@ -860,7 +920,7 @@ csam.login > rtsg.1023: . ack 2 win 4096
rtsg.1023 > csam.login: P 2:21(19) ack 1 win 4096
csam.login > rtsg.1023: P 1:2(1) ack 21 win 4077
csam.login > rtsg.1023: P 2:3(1) ack 21 win 4077 urg 1
-csam.login > rtsg.1023: P 3:4(1) ack 21 win 4077 urg 1\fP\s+2
+csam.login > rtsg.1023: P 3:4(1) ack 21 win 4077 urg 1\fR\s+2
.sp .5
.fi
.RE
@@ -880,7 +940,7 @@ ack for rtsg's SYN. Rtsg then acks csam's SYN. The `.' means no
flags were set.
The packet contained no data so there is no data sequence number.
Note that the ack sequence
-number is a small integer (1). The first time \fBtcpdump\fP sees a
+number is a small integer (1). The first time \fItcpdump\fP sees a
tcp `conversation', it prints the sequence number from the packet.
On subsequent packets of the conversation, the difference between
the current packet's sequence number and this initial sequence number
@@ -900,15 +960,201 @@ Csam also sends one byte of data to rtsg in this packet.
On the 8th and 9th lines,
csam sends two bytes of urgent, pushed data to rtsg.
.LP
-If the snapshot was small enough that \fBtcpdump\fP didn't capture
+If the snapshot was small enough that \fItcpdump\fP didn't capture
the full TCP header, it interprets as much of the header as it can
and then reports ``[|\fItcp\fP]'' to indicate the remainder could not
be interpreted. If the header contains a bogus option (one with a length
-that's either too small or beyond the end of the header), tcpdump reports
-it as ``[\fIbad opt\fP]'' and does not interpret any further options (since
-it's impossible to tell where they start). If the header length indicates
-options are present but the IP datagram length is not long enough for the
-options to actually be there, tcpdump reports it as ``[\fIbad hdr length\fP]''.
+that's either too small or beyond the end of the header), \fItcpdump\fP
+reports it as ``[\fIbad opt\fP]'' and does not interpret any further
+options (since it's impossible to tell where they start). If the header
+length indicates options are present but the IP datagram length is not
+long enough for the options to actually be there, \fItcpdump\fP reports
+it as ``[\fIbad hdr length\fP]''.
+.HD
+.B Capturing TCP packets with particular flag combinations (SYN-ACK, URG-ACK, etc.)
+.PP
+There are 6 bits in the control bits section of the TCP header:
+.IP
+.I URG | ACK | PSH | RST | SYN | FIN
+.PP
+Let's assume that we want to watch packets used in establishing
+a TCP connection. Recall that TCP uses a 3-way handshake protocol
+when it initializes a new connection; the connection sequence with
+regard to the TCP control bits is
+.PP
+.RS
+1) Caller sends SYN
+.RE
+.RS
+2) Recipient responds with SYN, ACK
+.RE
+.RS
+3) Caller sends ACK
+.RE
+.PP
+Now we're interested in capturing packets that have only the
+SYN bit set (Step 1). Note that we don't want packets from step 2
+(SYN-ACK), just a plain initial SYN. What we need is a correct filter
+expression for \fItcpdump\fP.
+.PP
+Recall the structure of a TCP header without options:
+.PP
+.nf
+ 0 15 31
+-----------------------------------------------------------------
+| source port | destination port |
+-----------------------------------------------------------------
+| sequence number |
+-----------------------------------------------------------------
+| acknowledgment number |
+-----------------------------------------------------------------
+| HL | reserved |U|A|P|R|S|F| window size |
+-----------------------------------------------------------------
+| TCP checksum | urgent pointer |
+-----------------------------------------------------------------
+.fi
+.PP
+A TCP header usually holds 20 octets of data, unless options are
+present. The fist line of the graph contains octets 0 - 3, the
+second line shows octets 4 - 7 etc.
+.PP
+Starting to count with 0, the relevant TCP control bits are contained
+in octet 13:
+.PP
+.nf
+ 0 7| 15| 23| 31
+----------------|---------------|---------------|----------------
+| HL | reserved |U|A|P|R|S|F| window size |
+----------------|---------------|---------------|----------------
+| | 13th octet | | |
+.fi
+.PP
+Let's have a closer look at octet no. 13:
+.PP
+.nf
+ | |
+ |---------------|
+ | |U|A|P|R|S|F|
+ |---------------|
+ |7 5 3 0|
+.fi
+.PP
+We see that this octet contains 2 bytes from the reserved field.
+According to RFC 793 this field is reserved for future use and must
+be 0. The remaining 6 bits are the TCP control bits we are interested
+in. We have numbered the bits in this octet from 0 to 7, right to
+left, so the PSH bit is bit number 3, while the URG bit is number 5.
+.PP
+Recall that we want to capture packets with only SYN set.
+Let's see what happens to octet 13 if a TCP datagram arrives
+with the SYN bit set in its header:
+.PP
+.nf
+ | |U|A|P|R|S|F|
+ |---------------|
+ |0 0 0 0 0 0 1 0|
+ |---------------|
+ |7 6 5 4 3 2 1 0|
+.fi
+.PP
+We already mentioned that bits number 7 and 6 belong to the
+reserved field, so they must must be 0. Looking at the
+control bits section we see that only bit number 1 (SYN) is set.
+.PP
+Assuming that octet number 13 is an 8-bit unsigned integer in
+network byte order, the binary value of this octet is
+.IP
+00000010
+.PP
+and its decimal representation is
+.PP
+.nf
+ 7 6 5 4 3 2 1 0
+0*2 + 0*2 + 0*2 + 0*2 + 0*2 + 0*2 + 1*2 + 0*2 = 2
+.fi
+.PP
+We're almost done, because now we know that if only SYN is set,
+the value of the 13th octet in the TCP header, when interpreted
+as a 8-bit unsigned integer in network byte order, must be exactly 2.
+.PP
+This relationship can be expressed as
+.RS
+.B
+tcp[13] == 2
+.RE
+.PP
+We can use this expression as the filter for \fItcpdump\fP in order
+to watch packets which have only SYN set:
+.RS
+.B
+tcpdump -i xl0 tcp[13] == 2
+.RE
+.PP
+The expression says "let the 13th octet of a TCP datagram have
+the decimal value 2", which is exactly what we want.
+.PP
+Now, let's assume that we need to capture SYN packets, but we
+don't care if ACK or any other TCP control bit is set at the
+same time. Let's see what happens to octet 13 when a TCP datagram
+with SYN-ACK set arrives:
+.PP
+.nf
+ | |U|A|P|R|S|F|
+ |---------------|
+ |0 0 0 1 0 0 1 0|
+ |---------------|
+ |7 6 5 4 3 2 1 0|
+.fi
+.PP
+Now bits 1 and 4 are set in the 13th octet. The binary value of
+octet 13 is
+.IP
+ 00010010
+.PP
+which translates to decimal
+.PP
+.nf
+ 7 6 5 4 3 2 1 0
+0*2 + 0*2 + 0*2 + 1*2 + 0*2 + 0*2 + 1*2 + 0*2 = 18
+.fi
+.PP
+Now we can't just use 'tcp[13] == 18' in the \fItcpdump\fP filter
+expression, because that would select only those packets that have
+SYN-ACK set, but not those with only SYN set. Remember that we don't care
+if ACK or any other control bit is set as long as SYN is set.
+.PP
+In order to achieve our goal, we need to logically AND the
+binary value of octet 13 with some other value to preserve
+the SYN bit. We know that we want SYN to be set in any case,
+so we'll logically AND the value in the 13th octet with
+the binary value of a SYN:
+.PP
+.nf
+
+ 00010010 SYN-ACK 00000010 SYN
+ AND 00000010 (we want SYN) AND 00000010 (we want SYN)
+ -------- --------
+ = 00000010 = 00000010
+.fi
+.PP
+We see that this AND operation delivers the same result
+regardless whether ACK or another TCP control bit is set.
+The decimal representation of the AND value as well as
+the result of this operation is 2 (binary 00000010),
+so we know that for packets with SYN set the following
+relation must hold true:
+.IP
+( ( value of octet 13 ) AND ( 2 ) ) == ( 2 )
+.PP
+This points us to the \fItcpdump\fP filter expression
+.RS
+.B
+ tcpdump -i xl0 'tcp[13] & 2 == 2'
+.RE
+.PP
+Note that you should use single quotes or a backslash
+in the expression to hide the AND ('&') special character
+from the shell.
.HD
.B
UDP Packets
@@ -943,7 +1189,7 @@ Name server requests are formatted as
.sp .5
\fIsrc > dst: id op? flags qtype qclass name (len)\fP
.sp .5
-\f(CWh2opolo.1538 > helios.domain: 3+ A? ucbvax.berkeley.edu. (37)\fP
+\f(CWh2opolo.1538 > helios.domain: 3+ A? ucbvax.berkeley.edu. (37)\fR
.sp .5
.fi
.RE
@@ -980,7 +1226,7 @@ Name server responses are formatted as
\fIsrc > dst: id op rcode flags a/n/au type class data (len)\fP
.sp .5
\f(CWhelios.domain > h2opolo.1538: 3 3/3/7 A 128.32.137.3 (273)
-helios.domain > h2opolo.1537: 2 NXDomain* 0/1/0 (97)\fP
+helios.domain > h2opolo.1537: 2 NXDomain* 0/1/0 (97)\fR
.sp .5
.fi
.RE
@@ -1011,7 +1257,7 @@ has worked well for me.
.HD
SMB/CIFS decoding
.LP
-tcpdump now includes fairly extensive SMB/CIFS/NBT decoding for data
+\fItcpdump\fP now includes fairly extensive SMB/CIFS/NBT decoding for data
on UDP/137, UDP/138 and TCP/139. Some primitive decoding of IPX and
NetBEUI SMB data is also done.
@@ -1046,7 +1292,7 @@ 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
+\fR
.sp .5
.fi
.RE
@@ -1080,7 +1326,7 @@ wrl.nfs > sushi.1372a:
.sp .5
.fi
.RE
-(\-v also prints the IP header TTL, ID, and fragmentation fields,
+(\-v also prints the IP header TTL, ID, length, 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
@@ -1103,7 +1349,7 @@ NFS reply packets do not explicitly identify the RPC operation. Instead,
replies using the transaction ID. If a reply does not closely follow the
corresponding request, it might not be parsable.
.HD
-AFS Request and Replies
+AFS Requests and Replies
.LP
Transarc AFS (Andrew File System) requests and replies are printed
as:
@@ -1120,7 +1366,7 @@ elvis.7001 > pike.afsfs:
rx data fs call rename old fid 536876964/1/1 ".newsrc.new"
new fid 536876964/1/1 ".newsrc"
pike.afsfs > elvis.7001: rx data fs reply rename
-\fP
+\fR
.sp .5
.fi
.RE
@@ -1140,11 +1386,16 @@ The format is intended to be self-describing, but it will probably
not be useful to people who are not familiar with the workings of
AFS and RX.
.LP
-If the -v (verbose) flag is given twice, additional information is printed,
-such as the the RX call ID, call number, sequence number, serial number,
-and the RX packet flags.
+If the -v (verbose) flag is given twice, acknowledgement packets and
+additional header information is printed, such as the the RX call ID,
+call number, sequence number, serial number, and the RX packet flags.
.LP
-If the -v flag is given again, the security index and service id are printed.
+If the -v flag is given twice, additional information is printed,
+such as the the RX call ID, serial number, and the RX packet flags.
+The MTU negotiation information is also printed from RX ack packets.
+.LP
+If the -v flag is given three times, the security index and service id
+are printed.
.LP
Error codes are printed for abort packets, with the exception of Ubik
beacon packets (because abort packets are used to signify a yes vote
@@ -1176,7 +1427,7 @@ Lines in this file have the form
\f(CW1.254 ether
16.1 icsd-net
-1.254.110 ace\fP
+1.254.110 ace\fR
.sp .5
.fi
.RE
@@ -1199,7 +1450,7 @@ Appletalk addresses are printed in the form
\f(CW144.1.209.2 > icsd-net.112.220
office.2 > icsd-net.112.220
-jssmag.149.235 > icsd-net.2\fP
+jssmag.149.235 > icsd-net.2\fR
.sp .5
.fi
.RE
@@ -1227,7 +1478,7 @@ protocol) and packet size.
.sp .5
\s-2\f(CWicsd-net.112.220 > jssmag.2: nbp-lkup 190: "=:LaserWriter@*"
jssmag.209.2 > icsd-net.112.220: nbp-reply 190: "RM1140:LaserWriter@*" 250
-techpit.2 > icsd-net.112.220: nbp-reply 190: "techpit:LaserWriter@*" 186\fP\s+2
+techpit.2 > icsd-net.112.220: nbp-reply 190: "techpit:LaserWriter@*" 186\fR\s+2
.sp .5
.fi
.RE
@@ -1256,7 +1507,7 @@ jssmag.209.165 > helios.132: atp-req 12266<3,5> 0xae030001
helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000
helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000
jssmag.209.165 > helios.132: atp-rel 12266<0-7> 0xae030001
-jssmag.209.133 > helios.132: atp-req* 12267<0-7> 0xae030002\fP\s+2
+jssmag.209.133 > helios.132: atp-req* 12267<0-7> 0xae030002\fR\s+2
.sp .5
.fi
.RE
@@ -1340,12 +1591,22 @@ serviced the `new packet' interrupt.
.SH "SEE ALSO"
bpf(4), pcap(3)
.SH AUTHORS
+The original authors are:
+.LP
Van Jacobson,
Craig Leres and
Steven McCanne, all of the
Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
.LP
-The current version is available via anonymous ftp:
+It is currently being maintained by tcpdump.org.
+.LP
+The current version is available via http:
+.LP
+.RS
+.I http://www.tcpdump.org/
+.RE
+.LP
+The original distribution is available via anonymous ftp:
.LP
.RS
.I ftp://ftp.ee.lbl.gov/tcpdump.tar.Z
@@ -1354,40 +1615,61 @@ The current version is available via anonymous ftp:
IPv6/IPsec support is added by WIDE/KAME project.
This program uses Eric Young's SSLeay library, under specific configuration.
.SH BUGS
-Please send bug reports to tcpdump@ee.lbl.gov.
+Please send problems, bugs, questions, desirable enhancements, etc. to:
+.LP
+.RS
+tcpdump-workers@tcpdump.org
+.RE
+.LP
+Please send source code contributions, etc. to:
+.LP
+.RS
+patches@tcpdump.org
+.RE
.LP
NIT doesn't let you watch your own outbound traffic, BPF will.
We recommend that you use the latter.
.LP
+On Linux systems with 2.0[.x] kernels:
+.IP
+packets on the loopback device will be seen twice;
+.IP
+packet filtering cannot be done in the kernel, so that all packets must
+be copied from the kernel in order to be filtered in user mode;
+.IP
+all of a packet, not just the part that's within the snapshot length,
+will be copied from the kernel (the 2.0[.x] packet capture mechanism, if
+asked to copy only part of a packet to userland, will not report the
+true length of the packet; this would cause most IP packets to get an
+error from
+.BR tcpdump ).
+.LP
+We recommend that you upgrade to a 2.2 or later kernel.
+.LP
Some attempt should be made to reassemble IP fragments or, at least
to compute the right length for the higher level protocol.
.LP
-Name server inverse queries are not dumped correctly: The (empty)
+Name server inverse queries are not dumped correctly: the (empty)
question section is printed rather than real query in the answer
section. Some believe that inverse queries are themselves a bug and
-prefer to fix the program generating them rather than tcpdump.
-.LP
-Apple Ethertalk DDP packets could be dumped as easily as KIP DDP
-packets but aren't.
-Even if we were inclined to do anything to promote the use of
-Ethertalk (we aren't), LBL doesn't allow Ethertalk on any of its
-networks so we'd would have no way of testing this code.
+prefer to fix the program generating them rather than \fItcpdump\fP.
.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.
+Filter expressions that manipulate FDDI or Token Ring headers assume
+that all FDDI and Token Ring packets are SNAP-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.
+.LP
+Filter expressions on fields other than those that manipulate Token Ring
+headers will not correctly handle source-routed Token Ring packets.
.LP
.BR "ip6 proto"
should chase header chain, but at this moment it does not.
-.BR tcp
-or
-.BR udp
-should chase header chain too.
+.BR "ip6 protochain"
+is supplied for this behavior.
.LP
Arithmetic expression against transport layer headers, like \fBtcp[0]\fP,
does not work against IPv6 packets.
diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c
index daf95fe28950..423a8e7edb35 100644
--- a/contrib/tcpdump/tcpdump.c
+++ b/contrib/tcpdump/tcpdump.c
@@ -24,7 +24,7 @@ static const char copyright[] =
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.138.2.1 2000/01/11 07:34:00 fenner Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.158 2000/12/21 10:43:24 guy Exp $ (LBL)";
#endif
/* $FreeBSD$ */
@@ -54,8 +54,6 @@ static const char rcsid[] =
#include <unistd.h>
#include <ctype.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
#include "interface.h"
#include "addrtoname.h"
@@ -76,11 +74,11 @@ int Rflag = 1; /* print sequence # field in AH/ESP*/
int sflag = 0; /* use the libsmi to translate OIDs */
int Sflag; /* print raw TCP sequence numbers */
int tflag = 1; /* print packet arrival time */
+int uflag = 0; /* Print undecoded NFS handles */
int vflag; /* verbose */
int xflag; /* print packet in hex */
int Xflag; /* print packet in ascii as well as hex */
-char *ahsecret = NULL; /* AH secret key */
char *espsecret = NULL; /* ESP secret key */
int packettype;
@@ -90,12 +88,9 @@ char *program_name;
int32_t thiszone; /* seconds offset from gmt to local time */
-/* Externs */
-extern void bpf_dump(struct bpf_program *, int);
-
/* Forwards */
-RETSIGTYPE cleanup(int);
-extern __dead void usage(void) __attribute__((volatile));
+static RETSIGTYPE cleanup(int);
+static void usage(void) __attribute__((noreturn));
/* Length of saved portion of packet. */
int snaplen = DEFAULT_SNAPLEN;
@@ -114,16 +109,28 @@ static struct printer printers[] = {
#ifdef DLT_CIP
{ cip_if_print, DLT_CIP },
#endif
+#ifdef DLT_ATM_CLIP
+ { cip_if_print, DLT_ATM_CLIP },
+#endif
{ sl_if_print, DLT_SLIP },
{ sl_bsdos_if_print, DLT_SLIP_BSDOS },
{ ppp_if_print, DLT_PPP },
{ ppp_bsdos_if_print, DLT_PPP_BSDOS },
{ fddi_if_print, DLT_FDDI },
{ null_if_print, DLT_NULL },
+#ifdef DLT_LOOP
+ { null_if_print, DLT_LOOP },
+#endif
{ raw_if_print, DLT_RAW },
{ atm_if_print, DLT_ATM_RFC1483 },
-#ifdef DLT_CHDLC
- { chdlc_if_print, DLT_CHDLC },
+#ifdef DLT_C_HDLC
+ { chdlc_if_print, DLT_C_HDLC },
+#endif
+#ifdef DLT_PPP_SERIAL
+ { ppp_hdlc_if_print, DLT_PPP_SERIAL },
+#endif
+#ifdef DLT_LINUX_SLL
+ { sll_if_print, DLT_LINUX_SLL },
#endif
{ NULL, 0 },
};
@@ -137,7 +144,7 @@ lookup_printer(int type)
if (type == p->type)
return p->f;
- error("unknown data link type 0x%x", type);
+ error("unknown data link type %d", type);
/* NOTREACHED */
}
@@ -169,7 +176,7 @@ main(int argc, char **argv)
else
program_name = argv[0];
- if (abort_on_misalignment(ebuf) < 0)
+ if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0)
error("%s", ebuf);
#ifdef LIBSMI
@@ -178,22 +185,13 @@ main(int argc, char **argv)
opterr = 0;
while (
- (op = getopt(argc, argv, "ac:deE:fF:i:lnNm:Opqr:Rs:StT:vw:xXY")) != EOF)
+ (op = getopt(argc, argv, "ac:deE:fF:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1)
switch (op) {
case 'a':
++aflag;
break;
-#if 0
- case 'A':
-#ifndef CRYPTO
- warning("crypto code not compiled in");
-#endif
- ahsecret = optarg;
- break;
-#endif
-
case 'c':
cnt = atoi(optarg);
if (cnt <= 0)
@@ -209,7 +207,7 @@ main(int argc, char **argv)
break;
case 'E':
-#ifndef CRYPTO
+#ifndef HAVE_LIBCRYPTO
warning("crypto code not compiled in");
#endif
espsecret = optarg;
@@ -275,11 +273,17 @@ main(int argc, char **argv)
Rflag = 0;
break;
- case 's':
- snaplen = atoi(optarg);
- if (snaplen <= 0)
+ case 's': {
+ char *end;
+
+ snaplen = strtol(optarg, &end, 0);
+ if (optarg == end || *end != '\0'
+ || snaplen < 0 || snaplen > 65535)
error("invalid snaplen %s", optarg);
+ else if (snaplen == 0)
+ snaplen = 65535;
break;
+ }
case 'S':
++Sflag;
@@ -302,10 +306,16 @@ main(int argc, char **argv)
packettype = PT_RTCP;
else if (strcasecmp(optarg, "snmp") == 0)
packettype = PT_SNMP;
+ else if (strcasecmp(optarg, "cnfp") == 0)
+ packettype = PT_CNFP;
else
error("unknown packet type `%s'", optarg);
break;
+ case 'u':
+ ++uflag;
+ break;
+
case 'v':
++vflag;
break;
@@ -319,7 +329,7 @@ main(int argc, char **argv)
break;
case 'X':
- ++xflag;
+ ++xflag;
++Xflag;
break;
@@ -428,7 +438,7 @@ main(int argc, char **argv)
}
/* make a clean exit on interrupts */
-RETSIGTYPE
+static RETSIGTYPE
cleanup(int signo)
{
struct pcap_stat stat;
@@ -450,55 +460,6 @@ cleanup(int signo)
exit(0);
}
-/* dump the buffer in `emacs-hexl' style */
-void
-default_print_hexl(const u_char *cp, unsigned int length, unsigned int offset)
-{
- unsigned int i, j, jm;
- int c;
- char ln[128];
-
- printf("\n");
- for (i = 0; i < length; i += 0x10) {
- snprintf(ln,
- sizeof(ln),
- " %04x: ", (unsigned int)(i + offset));
- jm = length - i;
- jm = jm > 16 ? 16 : jm;
-
- for (j = 0; j < jm; j++) {
- if ((j % 2) == 1)
- snprintf(ln + strlen(ln),
- sizeof(ln) - strlen(ln),
- "%02x ", (unsigned int)cp[i+j]);
- else
- snprintf(ln + strlen(ln),
- sizeof(ln) - strlen(ln),
- "%02x", (unsigned int)cp[i+j]);
- }
- for (; j < 16; j++) {
- if ((j % 2) == 1)
- snprintf(ln + strlen(ln),
- sizeof(ln) - strlen(ln),
- " ");
- else
- snprintf(ln + strlen(ln),
- sizeof(ln) - strlen(ln),
- " ");
- }
-
- snprintf(ln + strlen(ln), sizeof(ln) - strlen(ln), " ");
- for (j = 0; j < jm; j++) {
- c = cp[i+j];
- c = isprint(c) ? c : '.';
- snprintf(ln + strlen(ln),
- sizeof(ln) - strlen(ln),
- "%c", c);
- }
- printf("%s\n", ln);
- }
-}
-
/* Like default_print() but data need not be aligned */
void
default_print_unaligned(register const u_char *cp, register u_int length)
@@ -534,7 +495,7 @@ default_print(register const u_char *bp, register u_int length)
default_print_unaligned(bp, length);
}
-__dead void
+static void
usage(void)
{
extern char version[];
@@ -543,7 +504,7 @@ usage(void)
(void)fprintf(stderr, "%s version %s\n", program_name, version);
(void)fprintf(stderr, "libpcap version %s\n", pcap_version);
(void)fprintf(stderr,
-"Usage: %s [-adeflnNOpqStvxX] [-c count] [ -F file ]\n", program_name);
+"Usage: %s [-adeflnNOpqStuvxX] [-c count] [ -F file ]\n", program_name);
(void)fprintf(stderr,
"\t\t[ -i interface ] [ -r file ] [ -s snaplen ]\n");
(void)fprintf(stderr,