tcpdump-4.5.1/0000755000026300017510000000000012243146376010626 5ustar mcrtcpdump-4.5.1/nfsfh.h0000644000026300017510000000524512237020316012075 0ustar mcr/* @(#) $Header: /tcpdump/master/tcpdump/nfsfh.h,v 1.13 2002-04-24 06:27:05 guy Exp $ (LBL) */ /* * Copyright (c) 1993, 1994 Jeffrey C. Mogul, Digital Equipment Corporation, * Western Research Laboratory. All rights reserved. * Copyright (c) 2001 Compaq Computer Corporation. All rights reserved. * * Permission to use, copy, and modify this software and its * documentation is hereby granted only under the following terms and * conditions. Both the above copyright notice and this permission * notice must appear in all copies of the software, derivative works * or modified versions, and any portions thereof, and both notices * must appear in supporting documentation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THE SOFTWARE IS PROVIDED "AS IS" AND COMPAQ COMPUTER CORPORATION * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL COMPAQ COMPUTER CORPORATION BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* * nfsfh.h - NFS file handle definitions (for portable use) * * Jeffrey C. Mogul * Digital Equipment Corporation * Western Research Laboratory */ /* * Internal representation of dev_t, because different NFS servers * that we might be spying upon use different external representations. */ typedef struct { u_int32_t Minor; /* upper case to avoid clashing with macro names */ u_int32_t Major; } my_devt; #define dev_eq(a,b) ((a.Minor == b.Minor) && (a.Major == b.Major)) /* * Many file servers now use a large file system ID. This is * our internal representation of that. */ typedef struct { my_devt Fsid_dev; /* XXX avoid name conflict with AIX */ char Opaque_Handle[2 * 32 + 1]; u_int32_t fsid_code; } my_fsid; #define fsid_eq(a,b) ((a.fsid_code == b.fsid_code) &&\ dev_eq(a.Fsid_dev, b.Fsid_dev)) extern void Parse_fh(const unsigned char *, int, my_fsid *, u_int32_t *, const char **, const char **, int); tcpdump-4.5.1/llc.h0000644000026300017510000000747712237020316011554 0ustar mcr/* * Copyright (c) 1993, 1994, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header: /tcpdump/master/tcpdump/llc.h,v 1.23 2007-04-13 09:43:11 hannes Exp $ (LBL) */ /* * Definitions for information in the LLC header. */ #define LLC_U_FMT 3 #define LLC_GSAP 1 #define LLC_IG 1 /* Individual / Group */ #define LLC_S_FMT 1 #define LLC_U_POLL 0x10 #define LLC_IS_POLL 0x0100 #define LLC_XID_FI 0x81 #define LLC_U_CMD(u) ((u) & 0xef) #define LLC_UI 0x03 #define LLC_UA 0x63 #define LLC_DISC 0x43 #define LLC_DM 0x0f #define LLC_SABME 0x6f #define LLC_TEST 0xe3 #define LLC_XID 0xaf #define LLC_FRMR 0x87 #define LLC_S_CMD(is) (((is) >> 2) & 0x03) #define LLC_RR 0x0001 #define LLC_RNR 0x0005 #define LLC_REJ 0x0009 #define LLC_IS_NR(is) (((is) >> 9) & 0x7f) #define LLC_I_NS(is) (((is) >> 1) & 0x7f) #ifndef LLCSAP_NULL #define LLCSAP_NULL 0x00 #endif #ifndef LLCSAP_GLOBAL #define LLCSAP_GLOBAL 0xff #endif #ifndef LLCSAP_8021B_I #define LLCSAP_8021B_I 0x02 #endif #ifndef LLCSAP_8021B_G #define LLCSAP_8021B_G 0x03 #endif #ifndef LLCSAP_SNA #define LLCSAP_SNA 0x04 #endif #ifndef LLCSAP_IP #define LLCSAP_IP 0x06 #endif #ifndef LLCSAP_PROWAYNM #define LLCSAP_PROWAYNM 0x0e #endif #ifndef LLCSAP_8021D #define LLCSAP_8021D 0x42 #endif #ifndef LLCSAP_RS511 #define LLCSAP_RS511 0x4e #endif #ifndef LLCSAP_ISO8208 #define LLCSAP_ISO8208 0x7e #endif #ifndef LLCSAP_PROWAY #define LLCSAP_PROWAY 0x8e #endif #ifndef LLCSAP_SNAP #define LLCSAP_SNAP 0xaa #endif #ifndef LLCSAP_IPX #define LLCSAP_IPX 0xe0 #endif #ifndef LLCSAP_NETBEUI #define LLCSAP_NETBEUI 0xf0 #endif #ifndef LLCSAP_ISONS #define LLCSAP_ISONS 0xfe #endif /* * PIDs for use with OUI_CISCO. */ #define PID_CISCO_CDP 0x2000 /* Cisco Discovery Protocol */ #define PID_CISCO_VTP 0x2003 /* Cisco VLAN Trunk Protocol */ #define PID_CISCO_DTP 0x2004 /* Cisco Dynamic Trunk Protocol */ #define PID_CISCO_UDLD 0x0111 /* Unidirectional Link Detection */ #define PID_CISCO_PVST 0x010b /* Per VLAN Spanning Tree+ and RPVST+ */ #define PID_CISCO_VLANBRIDGE 0x010c /* "VLAN Bridge", according to Wireshark */ /* * PIDs for use with OUI_RFC2684. */ #define PID_RFC2684_ETH_FCS 0x0001 /* Ethernet, with FCS */ #define PID_RFC2684_ETH_NOFCS 0x0007 /* Ethernet, without FCS */ #define PID_RFC2684_802_4_FCS 0x0002 /* 802.4, with FCS */ #define PID_RFC2684_802_4_NOFCS 0x0008 /* 802.4, without FCS */ #define PID_RFC2684_802_5_FCS 0x0003 /* 802.5, with FCS */ #define PID_RFC2684_802_5_NOFCS 0x0009 /* 802.5, without FCS */ #define PID_RFC2684_FDDI_FCS 0x0004 /* FDDI, with FCS */ #define PID_RFC2684_FDDI_NOFCS 0x000a /* FDDI, without FCS */ #define PID_RFC2684_802_6_FCS 0x0005 /* 802.6, with FCS */ #define PID_RFC2684_802_6_NOFCS 0x000b /* 802.6, without FCS */ #define PID_RFC2684_BPDU 0x000e /* BPDUs */ tcpdump-4.5.1/print-lwres.c0000644000026300017510000003314212237020316013247 0ustar mcr/* * Copyright (C) 2001 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-lwres.c,v 1.13 2004-03-24 01:54:29 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "nameser.h" #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" /* must come after interface.h */ /* BIND9 lib/lwres/include/lwres */ typedef u_int32_t lwres_uint32_t; typedef u_int16_t lwres_uint16_t; typedef u_int8_t lwres_uint8_t; struct lwres_lwpacket { lwres_uint32_t length; lwres_uint16_t version; lwres_uint16_t pktflags; lwres_uint32_t serial; lwres_uint32_t opcode; lwres_uint32_t result; lwres_uint32_t recvlength; lwres_uint16_t authtype; lwres_uint16_t authlength; }; #define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */ #define LWRES_LWPACKETVERSION_0 0 #define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U #define LWRES_FLAG_SECUREDATA 0x00000002U /* * no-op */ #define LWRES_OPCODE_NOOP 0x00000000U typedef struct { /* public */ lwres_uint16_t datalength; /* data follows */ } lwres_nooprequest_t; typedef struct { /* public */ lwres_uint16_t datalength; /* data follows */ } lwres_noopresponse_t; /* * get addresses by name */ #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U typedef struct lwres_addr lwres_addr_t; struct lwres_addr { lwres_uint32_t family; lwres_uint16_t length; /* address folows */ }; typedef struct { /* public */ lwres_uint32_t flags; lwres_uint32_t addrtypes; lwres_uint16_t namelen; /* name follows */ } lwres_gabnrequest_t; typedef struct { /* public */ lwres_uint32_t flags; lwres_uint16_t naliases; lwres_uint16_t naddrs; lwres_uint16_t realnamelen; /* aliases follows */ /* addrs follows */ /* realname follows */ } lwres_gabnresponse_t; /* * get name by address */ #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U typedef struct { /* public */ lwres_uint32_t flags; lwres_addr_t addr; /* addr body follows */ } lwres_gnbarequest_t; typedef struct { /* public */ lwres_uint32_t flags; lwres_uint16_t naliases; lwres_uint16_t realnamelen; /* aliases follows */ /* realname follows */ } lwres_gnbaresponse_t; /* * get rdata by name */ #define LWRES_OPCODE_GETRDATABYNAME 0x00010003U typedef struct { /* public */ lwres_uint32_t flags; lwres_uint16_t rdclass; lwres_uint16_t rdtype; lwres_uint16_t namelen; /* name follows */ } lwres_grbnrequest_t; typedef struct { /* public */ lwres_uint32_t flags; lwres_uint16_t rdclass; lwres_uint16_t rdtype; lwres_uint32_t ttl; lwres_uint16_t nrdatas; lwres_uint16_t nsigs; /* realname here (len + name) */ /* rdata here (len + name) */ /* signatures here (len + name) */ } lwres_grbnresponse_t; #define LWRDATA_VALIDATED 0x00000001 #define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */ #define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */ #define LWRES_MAX_ALIASES 16 /* max # of aliases */ #define LWRES_MAX_ADDRS 64 /* max # of addrs */ static const struct tok opcode[] = { { LWRES_OPCODE_NOOP, "noop", }, { LWRES_OPCODE_GETADDRSBYNAME, "getaddrsbyname", }, { LWRES_OPCODE_GETNAMEBYADDR, "getnamebyaddr", }, { LWRES_OPCODE_GETRDATABYNAME, "getrdatabyname", }, { 0, NULL, }, }; /* print-domain.c */ extern const struct tok ns_type2str[]; extern const struct tok ns_class2str[]; static int lwres_printname(size_t, const char *); static int lwres_printnamelen(const char *); static int lwres_printbinlen(const char *); static int lwres_printaddr(lwres_addr_t *); static int lwres_printname(size_t l, const char *p0) { const char *p; size_t i; p = p0; /* + 1 for terminating \0 */ if (p + l + 1 > (const char *)snapend) goto trunc; printf(" "); for (i = 0; i < l; i++) safeputchar(*p++); p++; /* skip terminating \0 */ return p - p0; trunc: return -1; } static int lwres_printnamelen(const char *p) { u_int16_t l; int advance; if (p + 2 > (const char *)snapend) goto trunc; l = EXTRACT_16BITS(p); advance = lwres_printname(l, p + 2); if (advance < 0) goto trunc; return 2 + advance; trunc: return -1; } static int lwres_printbinlen(const char *p0) { const char *p; u_int16_t l; int i; p = p0; if (p + 2 > (const char *)snapend) goto trunc; l = EXTRACT_16BITS(p); if (p + 2 + l > (const char *)snapend) goto trunc; p += 2; for (i = 0; i < l; i++) printf("%02x", *p++); return p - p0; trunc: return -1; } static int lwres_printaddr(lwres_addr_t *ap) { u_int16_t l; const char *p; int i; TCHECK(ap->length); l = EXTRACT_16BITS(&ap->length); /* XXX ap points to packed struct */ p = (const char *)&ap->length + sizeof(ap->length); TCHECK2(*p, l); switch (EXTRACT_32BITS(&ap->family)) { case 1: /* IPv4 */ if (l < 4) return -1; printf(" %s", ipaddr_string(p)); p += sizeof(struct in_addr); break; #ifdef INET6 case 2: /* IPv6 */ if (l < 16) return -1; printf(" %s", ip6addr_string(p)); p += sizeof(struct in6_addr); break; #endif default: printf(" %u/", EXTRACT_32BITS(&ap->family)); for (i = 0; i < l; i++) printf("%02x", *p++); } return p - (const char *)ap; trunc: return -1; } void lwres_print(register const u_char *bp, u_int length) { const struct lwres_lwpacket *np; u_int32_t v; const char *s; int response; int advance; int unsupported = 0; np = (const struct lwres_lwpacket *)bp; TCHECK(np->authlength); printf(" lwres"); v = EXTRACT_16BITS(&np->version); if (vflag || v != LWRES_LWPACKETVERSION_0) printf(" v%u", v); if (v != LWRES_LWPACKETVERSION_0) { s = (const char *)np + EXTRACT_32BITS(&np->length); goto tail; } response = EXTRACT_16BITS(&np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE; /* opcode and pktflags */ v = EXTRACT_32BITS(&np->opcode); s = tok2str(opcode, "#0x%x", v); printf(" %s%s", s, response ? "" : "?"); /* pktflags */ v = EXTRACT_16BITS(&np->pktflags); if (v & ~LWRES_LWPACKETFLAG_RESPONSE) printf("[0x%x]", v); if (vflag > 1) { printf(" ("); /*)*/ printf("serial:0x%x", EXTRACT_32BITS(&np->serial)); printf(" result:0x%x", EXTRACT_32BITS(&np->result)); printf(" recvlen:%u", EXTRACT_32BITS(&np->recvlength)); /* BIND910: not used */ if (vflag > 2) { printf(" authtype:0x%x", EXTRACT_16BITS(&np->authtype)); printf(" authlen:%u", EXTRACT_16BITS(&np->authlength)); } /*(*/ printf(")"); } /* per-opcode content */ if (!response) { /* * queries */ lwres_gabnrequest_t *gabn; lwres_gnbarequest_t *gnba; lwres_grbnrequest_t *grbn; u_int32_t l; gabn = NULL; gnba = NULL; grbn = NULL; switch (EXTRACT_32BITS(&np->opcode)) { case LWRES_OPCODE_NOOP: break; case LWRES_OPCODE_GETADDRSBYNAME: gabn = (lwres_gabnrequest_t *)(np + 1); TCHECK(gabn->namelen); /* XXX gabn points to packed struct */ s = (const char *)&gabn->namelen + sizeof(gabn->namelen); l = EXTRACT_16BITS(&gabn->namelen); /* BIND910: not used */ if (vflag > 2) { printf(" flags:0x%x", EXTRACT_32BITS(&gabn->flags)); } v = EXTRACT_32BITS(&gabn->addrtypes); switch (v & (LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) { case LWRES_ADDRTYPE_V4: printf(" IPv4"); break; case LWRES_ADDRTYPE_V6: printf(" IPv6"); break; case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6: printf(" IPv4/6"); break; } if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) printf("[0x%x]", v); advance = lwres_printname(l, s); if (advance < 0) goto trunc; s += advance; break; case LWRES_OPCODE_GETNAMEBYADDR: gnba = (lwres_gnbarequest_t *)(np + 1); TCHECK(gnba->addr); /* BIND910: not used */ if (vflag > 2) { printf(" flags:0x%x", EXTRACT_32BITS(&gnba->flags)); } s = (const char *)&gnba->addr; advance = lwres_printaddr(&gnba->addr); if (advance < 0) goto trunc; s += advance; break; case LWRES_OPCODE_GETRDATABYNAME: /* XXX no trace, not tested */ grbn = (lwres_grbnrequest_t *)(np + 1); TCHECK(grbn->namelen); /* BIND910: not used */ if (vflag > 2) { printf(" flags:0x%x", EXTRACT_32BITS(&grbn->flags)); } printf(" %s", tok2str(ns_type2str, "Type%d", EXTRACT_16BITS(&grbn->rdtype))); if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) { printf(" %s", tok2str(ns_class2str, "Class%d", EXTRACT_16BITS(&grbn->rdclass))); } /* XXX grbn points to packed struct */ s = (const char *)&grbn->namelen + sizeof(grbn->namelen); l = EXTRACT_16BITS(&grbn->namelen); advance = lwres_printname(l, s); if (advance < 0) goto trunc; s += advance; break; default: unsupported++; break; } } else { /* * responses */ lwres_gabnresponse_t *gabn; lwres_gnbaresponse_t *gnba; lwres_grbnresponse_t *grbn; u_int32_t l, na; u_int32_t i; gabn = NULL; gnba = NULL; grbn = NULL; switch (EXTRACT_32BITS(&np->opcode)) { case LWRES_OPCODE_NOOP: break; case LWRES_OPCODE_GETADDRSBYNAME: gabn = (lwres_gabnresponse_t *)(np + 1); TCHECK(gabn->realnamelen); /* XXX gabn points to packed struct */ s = (const char *)&gabn->realnamelen + sizeof(gabn->realnamelen); l = EXTRACT_16BITS(&gabn->realnamelen); /* BIND910: not used */ if (vflag > 2) { printf(" flags:0x%x", EXTRACT_32BITS(&gabn->flags)); } printf(" %u/%u", EXTRACT_16BITS(&gabn->naliases), EXTRACT_16BITS(&gabn->naddrs)); advance = lwres_printname(l, s); if (advance < 0) goto trunc; s += advance; /* aliases */ na = EXTRACT_16BITS(&gabn->naliases); for (i = 0; i < na; i++) { advance = lwres_printnamelen(s); if (advance < 0) goto trunc; s += advance; } /* addrs */ na = EXTRACT_16BITS(&gabn->naddrs); for (i = 0; i < na; i++) { advance = lwres_printaddr((lwres_addr_t *)s); if (advance < 0) goto trunc; s += advance; } break; case LWRES_OPCODE_GETNAMEBYADDR: gnba = (lwres_gnbaresponse_t *)(np + 1); TCHECK(gnba->realnamelen); /* XXX gnba points to packed struct */ s = (const char *)&gnba->realnamelen + sizeof(gnba->realnamelen); l = EXTRACT_16BITS(&gnba->realnamelen); /* BIND910: not used */ if (vflag > 2) { printf(" flags:0x%x", EXTRACT_32BITS(&gnba->flags)); } printf(" %u", EXTRACT_16BITS(&gnba->naliases)); advance = lwres_printname(l, s); if (advance < 0) goto trunc; s += advance; /* aliases */ na = EXTRACT_16BITS(&gnba->naliases); for (i = 0; i < na; i++) { advance = lwres_printnamelen(s); if (advance < 0) goto trunc; s += advance; } break; case LWRES_OPCODE_GETRDATABYNAME: /* XXX no trace, not tested */ grbn = (lwres_grbnresponse_t *)(np + 1); TCHECK(grbn->nsigs); /* BIND910: not used */ if (vflag > 2) { printf(" flags:0x%x", EXTRACT_32BITS(&grbn->flags)); } printf(" %s", tok2str(ns_type2str, "Type%d", EXTRACT_16BITS(&grbn->rdtype))); if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) { printf(" %s", tok2str(ns_class2str, "Class%d", EXTRACT_16BITS(&grbn->rdclass))); } printf(" TTL "); relts_print(EXTRACT_32BITS(&grbn->ttl)); printf(" %u/%u", EXTRACT_16BITS(&grbn->nrdatas), EXTRACT_16BITS(&grbn->nsigs)); /* XXX grbn points to packed struct */ s = (const char *)&grbn->nsigs+ sizeof(grbn->nsigs); advance = lwres_printnamelen(s); if (advance < 0) goto trunc; s += advance; /* rdatas */ na = EXTRACT_16BITS(&grbn->nrdatas); for (i = 0; i < na; i++) { /* XXX should decode resource data */ advance = lwres_printbinlen(s); if (advance < 0) goto trunc; s += advance; } /* sigs */ na = EXTRACT_16BITS(&grbn->nsigs); for (i = 0; i < na; i++) { /* XXX how should we print it? */ advance = lwres_printbinlen(s); if (advance < 0) goto trunc; s += advance; } break; default: unsupported++; break; } } tail: /* length mismatch */ if (EXTRACT_32BITS(&np->length) != length) { printf(" [len: %u != %u]", EXTRACT_32BITS(&np->length), length); } if (!unsupported && s < (const char *)np + EXTRACT_32BITS(&np->length)) printf("[extra]"); return; trunc: printf("[|lwres]"); return; } tcpdump-4.5.1/ppi.h0000644000026300017510000000022112237020316011546 0ustar mcrtypedef struct ppi_header { uint8_t ppi_ver; uint8_t ppi_flags; uint16_t ppi_len; uint32_t ppi_dlt; } ppi_header_t; #define PPI_HDRLEN 8 tcpdump-4.5.1/l2vpn.h0000644000026300017510000000150012237020316012020 0ustar mcr/* @(#) $Header: /tcpdump/master/tcpdump/l2vpn.h,v 1.1 2004-06-15 09:42:41 hannes Exp $ (LBL) */ /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * Original code by Hannes Gredler (hannes@juniper.net) */ extern const struct tok l2vpn_encaps_values[]; tcpdump-4.5.1/Makefile-devel-adds0000644000026300017510000000114612237020316014262 0ustar mcr# # Auto-regenerate configure script or Makefile when things change. # From autoconf.info . Works best with GNU Make. # ${srcdir}/configure: configure.in aclocal.m4 cd ${srcdir} && autoconf # autoheader might not change config.h.in, so touch a stamp file. ${srcdir}/config.h.in: ${srcdir}/stamp-h.in ${srcdir}/stamp-h.in: configure.in aclocal.m4 cd ${srcdir} && autoheader echo timestamp > ${srcdir}/stamp-h.in config.h: stamp-h stamp-h: ${srcdir}/config.h.in config.status ./config.status Makefile: Makefile.in config.status ./config.status config.status: ${srcdir}/configure ./config.status --recheck tcpdump-4.5.1/af.h0000644000026300017510000000356212237020316011357 0ustar mcr/* @(#) $Header: /tcpdump/master/tcpdump/af.h,v 1.3 2006-03-23 14:58:44 hannes Exp $ (LBL) */ /* * Copyright (c) 1998-2006 The TCPDUMP project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * Original code by Hannes Gredler (hannes@juniper.net) */ extern const struct tok af_values[]; extern const struct tok bsd_af_values[]; /* RFC1700 address family numbers */ #define AFNUM_INET 1 #define AFNUM_INET6 2 #define AFNUM_NSAP 3 #define AFNUM_HDLC 4 #define AFNUM_BBN1822 5 #define AFNUM_802 6 #define AFNUM_E163 7 #define AFNUM_E164 8 #define AFNUM_F69 9 #define AFNUM_X121 10 #define AFNUM_IPX 11 #define AFNUM_ATALK 12 #define AFNUM_DECNET 13 #define AFNUM_BANYAN 14 #define AFNUM_E164NSAP 15 #define AFNUM_VPLS 25 /* draft-kompella-ppvpn-l2vpn */ #define AFNUM_L2VPN 196 /* still to be approved by IANA */ /* * BSD AF_ values. * * Unfortunately, the BSDs don't all use the same value for AF_INET6, * so, because we want to be able to read captures from all of the BSDs, * we check for all of them. */ #define BSD_AFNUM_INET 2 #define BSD_AFNUM_NS 6 /* XEROX NS protocols */ #define BSD_AFNUM_ISO 7 #define BSD_AFNUM_APPLETALK 16 #define BSD_AFNUM_IPX 23 #define BSD_AFNUM_INET6_BSD 24 /* OpenBSD (and probably NetBSD), BSD/OS */ #define BSD_AFNUM_INET6_FREEBSD 28 #define BSD_AFNUM_INET6_DARWIN 30 tcpdump-4.5.1/print-icmp6.c0000644000026300017510000011103112237020316013123 0ustar mcr/* * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.86 2008-02-05 19:36:13 guy Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef INET6 #include #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" #include "ip6.h" #include "icmp6.h" #include "ipproto.h" #include "udp.h" #include "ah.h" static const char *get_rtpref(u_int); static const char *get_lifetime(u_int32_t); static void print_lladdr(const u_char *, size_t); static void icmp6_opt_print(const u_char *, int); static void mld6_print(const u_char *); static void mldv2_report_print(const u_char *, u_int); static void mldv2_query_print(const u_char *, u_int); static struct udphdr *get_upperlayer(u_char *, u_int *); static void dnsname_print(const u_char *, const u_char *); static void icmp6_nodeinfo_print(u_int, const u_char *, const u_char *); static void icmp6_rrenum_print(const u_char *, const u_char *); #ifndef abs #define abs(a) ((0 < (a)) ? (a) : -(a)) #endif /* inline the various RPL definitions */ #define ND_RPL_MESSAGE 0x9B static const struct tok icmp6_type_values[] = { { ICMP6_DST_UNREACH, "destination unreachable"}, { ICMP6_PACKET_TOO_BIG, "packet too big"}, { ICMP6_TIME_EXCEEDED, "time exceeded in-transit"}, { ICMP6_PARAM_PROB, "parameter problem"}, { ICMP6_ECHO_REQUEST, "echo request"}, { ICMP6_ECHO_REPLY, "echo reply"}, { MLD6_LISTENER_QUERY, "multicast listener query"}, { MLD6_LISTENER_REPORT, "multicast listener report"}, { MLD6_LISTENER_DONE, "multicast listener done"}, { ND_ROUTER_SOLICIT, "router solicitation"}, { ND_ROUTER_ADVERT, "router advertisement"}, { ND_NEIGHBOR_SOLICIT, "neighbor solicitation"}, { ND_NEIGHBOR_ADVERT, "neighbor advertisement"}, { ND_REDIRECT, "redirect"}, { ICMP6_ROUTER_RENUMBERING, "router renumbering"}, { IND_SOLICIT, "inverse neighbor solicitation"}, { IND_ADVERT, "inverse neighbor advertisement"}, { MLDV2_LISTENER_REPORT, "multicast listener report v2"}, { ICMP6_HADISCOV_REQUEST, "ha discovery request"}, { ICMP6_HADISCOV_REPLY, "ha discovery reply"}, { ICMP6_MOBILEPREFIX_SOLICIT, "mobile router solicitation"}, { ICMP6_MOBILEPREFIX_ADVERT, "mobile router advertisement"}, { ICMP6_WRUREQUEST, "who-are-you request"}, { ICMP6_WRUREPLY, "who-are-you reply"}, { ICMP6_NI_QUERY, "node information query"}, { ICMP6_NI_REPLY, "node information reply"}, { MLD6_MTRACE, "mtrace message"}, { MLD6_MTRACE_RESP, "mtrace response"}, { ND_RPL_MESSAGE, "RPL"}, { 0, NULL } }; static const struct tok icmp6_dst_unreach_code_values[] = { { ICMP6_DST_UNREACH_NOROUTE, "unreachable route" }, { ICMP6_DST_UNREACH_ADMIN, " unreachable prohibited"}, { ICMP6_DST_UNREACH_BEYONDSCOPE, "beyond scope"}, { ICMP6_DST_UNREACH_ADDR, "unreachable address"}, { ICMP6_DST_UNREACH_NOPORT, "unreachable port"}, { 0, NULL } }; static const struct tok icmp6_opt_pi_flag_values[] = { { ND_OPT_PI_FLAG_ONLINK, "onlink" }, { ND_OPT_PI_FLAG_AUTO, "auto" }, { ND_OPT_PI_FLAG_ROUTER, "router" }, { 0, NULL } }; static const struct tok icmp6_opt_ra_flag_values[] = { { ND_RA_FLAG_MANAGED, "managed" }, { ND_RA_FLAG_OTHER, "other stateful"}, { ND_RA_FLAG_HOME_AGENT, "home agent"}, { 0, NULL } }; static const struct tok icmp6_nd_na_flag_values[] = { { ND_NA_FLAG_ROUTER, "router" }, { ND_NA_FLAG_SOLICITED, "solicited" }, { ND_NA_FLAG_OVERRIDE, "override" }, { 0, NULL } }; static const struct tok icmp6_opt_values[] = { { ND_OPT_SOURCE_LINKADDR, "source link-address"}, { ND_OPT_TARGET_LINKADDR, "destination link-address"}, { ND_OPT_PREFIX_INFORMATION, "prefix info"}, { ND_OPT_REDIRECTED_HEADER, "redirected header"}, { ND_OPT_MTU, "mtu"}, { ND_OPT_RDNSS, "rdnss"}, { ND_OPT_DNSSL, "dnssl"}, { ND_OPT_ADVINTERVAL, "advertisement interval"}, { ND_OPT_HOMEAGENT_INFO, "homeagent information"}, { ND_OPT_ROUTE_INFO, "route info"}, { 0, NULL } }; /* mldv2 report types */ static const struct tok mldv2report2str[] = { { 1, "is_in" }, { 2, "is_ex" }, { 3, "to_in" }, { 4, "to_ex" }, { 5, "allow" }, { 6, "block" }, { 0, NULL } }; static const char * get_rtpref(u_int v) { static const char *rtpref_str[] = { "medium", /* 00 */ "high", /* 01 */ "rsv", /* 10 */ "low" /* 11 */ }; return rtpref_str[((v & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff]; } static const char * get_lifetime(u_int32_t v) { static char buf[20]; if (v == (u_int32_t)~0UL) return "infinity"; else { snprintf(buf, sizeof(buf), "%us", v); return buf; } } static void print_lladdr(const u_int8_t *p, size_t l) { const u_int8_t *ep, *q; q = p; ep = p + l; while (l > 0 && q < ep) { if (q > p) printf(":"); printf("%02x", *q++); l--; } } static int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp, u_int len) { return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)icp, len, IPPROTO_ICMPV6)); } enum ND_RPL_CODE { ND_RPL_DIS =0x00, ND_RPL_DIO =0x01, ND_RPL_DAO =0x02, ND_RPL_DAO_ACK=0x03, ND_RPL_SDIS =0x80, ND_RPL_SDIO =0x81, ND_RPL_SDAO =0x82, ND_RPL_SDAO_ACK=0x83, ND_RPL_SCC =0x8A, }; enum ND_RPL_DIO_FLAGS { ND_RPL_DIO_GROUNDED = 0x80, ND_RPL_DIO_DATRIG = 0x40, ND_RPL_DIO_DASUPPORT= 0x20, ND_RPL_DIO_RES4 = 0x10, ND_RPL_DIO_RES3 = 0x08, ND_RPL_DIO_PRF_MASK = 0x07, /* 3-bit preference */ }; struct nd_rpl_dio { u_int8_t rpl_flags; u_int8_t rpl_seq; u_int8_t rpl_instanceid; u_int8_t rpl_dagrank; u_int8_t rpl_dagid[16]; }; static void rpl_print(netdissect_options *ndo, const struct icmp6_hdr *hdr, const u_char *bp, u_int length _U_) { struct nd_rpl_dio *dio = (struct nd_rpl_dio *)bp; int secured = hdr->icmp6_code & 0x80; int basecode= hdr->icmp6_code & 0x7f; ND_TCHECK(dio->rpl_dagid); if(secured) { ND_PRINT((ndo, ", (SEC)")); } else { ND_PRINT((ndo, ", (CLR)")); } switch(basecode) { case ND_RPL_DIS: ND_PRINT((ndo, "DODAG Information Solicitation")); if(ndo->ndo_vflag) { } break; case ND_RPL_DIO: ND_PRINT((ndo, "DODAG Information Object")); if(ndo->ndo_vflag) { char dagid[65]; char *d = dagid; int i; for(i=0;i<16;i++) { if(isprint(dio->rpl_dagid[i])) { *d++ = dio->rpl_dagid[i]; } else { int cnt=snprintf(d,4,"0x%02x", dio->rpl_dagid[i]); d += cnt; } } *d++ = '\0'; ND_PRINT((ndo, " [seq:%u,instance:%u,rank:%u,dagid:%s]", dio->rpl_seq, dio->rpl_instanceid, dio->rpl_dagrank, dagid)); } break; case ND_RPL_DAO: ND_PRINT((ndo, "Destination Advertisement Object")); if(ndo->ndo_vflag) { } break; case ND_RPL_DAO_ACK: ND_PRINT((ndo, "Destination Advertisement Object Ack")); if(ndo->ndo_vflag) { } break; default: ND_PRINT((ndo, "RPL message, unknown code %u",hdr->icmp6_code)); break; } return; trunc: ND_PRINT((ndo," [|truncated]")); return; } void icmp6_print(netdissect_options *ndo, const u_char *bp, u_int length, const u_char *bp2, int fragmented) { const struct icmp6_hdr *dp; const struct ip6_hdr *ip; const struct ip6_hdr *oip; const struct udphdr *ouh; int dport; const u_char *ep; u_int prot; dp = (struct icmp6_hdr *)bp; ip = (struct ip6_hdr *)bp2; oip = (struct ip6_hdr *)(dp + 1); /* 'ep' points to the end of available data. */ ep = snapend; TCHECK(dp->icmp6_cksum); if (vflag && !fragmented) { u_int16_t sum, udp_sum; if (TTEST2(bp[0], length)) { udp_sum = EXTRACT_16BITS(&dp->icmp6_cksum); sum = icmp6_cksum(ip, dp, length); if (sum != 0) (void)printf("[bad icmp6 cksum 0x%04x -> 0x%04x!] ", udp_sum, in_cksum_shouldbe(udp_sum, sum)); else (void)printf("[icmp6 sum ok] "); } } printf("ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",dp->icmp6_type)); /* display cosmetics: print the packet length for printer that use the vflag now */ if (vflag && (dp->icmp6_type == ND_ROUTER_SOLICIT || dp->icmp6_type == ND_ROUTER_ADVERT || dp->icmp6_type == ND_NEIGHBOR_ADVERT || dp->icmp6_type == ND_NEIGHBOR_SOLICIT || dp->icmp6_type == ND_REDIRECT || dp->icmp6_type == ICMP6_HADISCOV_REPLY || dp->icmp6_type == ICMP6_MOBILEPREFIX_ADVERT )) printf(", length %u", length); switch (dp->icmp6_type) { case ICMP6_DST_UNREACH: TCHECK(oip->ip6_dst); printf(", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",dp->icmp6_code)); switch (dp->icmp6_code) { case ICMP6_DST_UNREACH_NOROUTE: /* fall through */ case ICMP6_DST_UNREACH_ADMIN: case ICMP6_DST_UNREACH_ADDR: printf(" %s",ip6addr_string(&oip->ip6_dst)); break; case ICMP6_DST_UNREACH_BEYONDSCOPE: printf(" %s, source address %s", ip6addr_string(&oip->ip6_dst), ip6addr_string(&oip->ip6_src)); break; case ICMP6_DST_UNREACH_NOPORT: if ((ouh = get_upperlayer((u_char *)oip, &prot)) == NULL) goto trunc; dport = EXTRACT_16BITS(&ouh->uh_dport); switch (prot) { case IPPROTO_TCP: printf(", %s tcp port %s", ip6addr_string(&oip->ip6_dst), tcpport_string(dport)); break; case IPPROTO_UDP: printf(", %s udp port %s", ip6addr_string(&oip->ip6_dst), udpport_string(dport)); break; default: printf(", %s protocol %d port %d unreachable", ip6addr_string(&oip->ip6_dst), oip->ip6_nxt, dport); break; } break; default: if (vflag <= 1) { print_unknown_data(bp,"\n\t",length); return; } break; } break; case ICMP6_PACKET_TOO_BIG: TCHECK(dp->icmp6_mtu); printf(", mtu %u", EXTRACT_32BITS(&dp->icmp6_mtu)); break; case ICMP6_TIME_EXCEEDED: TCHECK(oip->ip6_dst); switch (dp->icmp6_code) { case ICMP6_TIME_EXCEED_TRANSIT: printf(" for %s", ip6addr_string(&oip->ip6_dst)); break; case ICMP6_TIME_EXCEED_REASSEMBLY: printf(" (reassembly)"); break; default: printf(", unknown code (%u)", dp->icmp6_code); break; } break; case ICMP6_PARAM_PROB: TCHECK(oip->ip6_dst); switch (dp->icmp6_code) { case ICMP6_PARAMPROB_HEADER: printf(", erroneous - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr)); break; case ICMP6_PARAMPROB_NEXTHEADER: printf(", next header - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr)); break; case ICMP6_PARAMPROB_OPTION: printf(", option - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr)); break; default: printf(", code-#%d", dp->icmp6_code); break; } break; case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REPLY: TCHECK(dp->icmp6_seq); printf(", seq %u", EXTRACT_16BITS(&dp->icmp6_seq)); break; case ICMP6_MEMBERSHIP_QUERY: if (length == MLD_MINLEN) { mld6_print((const u_char *)dp); } else if (length >= MLDV2_MINLEN) { printf(" v2"); mldv2_query_print((const u_char *)dp, length); } else { printf(" unknown-version (len %u) ", length); } break; case ICMP6_MEMBERSHIP_REPORT: mld6_print((const u_char *)dp); break; case ICMP6_MEMBERSHIP_REDUCTION: mld6_print((const u_char *)dp); break; case ND_ROUTER_SOLICIT: #define RTSOLLEN 8 if (vflag) { icmp6_opt_print((const u_char *)dp + RTSOLLEN, length - RTSOLLEN); } break; case ND_ROUTER_ADVERT: #define RTADVLEN 16 if (vflag) { struct nd_router_advert *p; p = (struct nd_router_advert *)dp; TCHECK(p->nd_ra_retransmit); printf("\n\thop limit %u, Flags [%s]" \ ", pref %s, router lifetime %us, reachable time %us, retrans time %us", (u_int)p->nd_ra_curhoplimit, bittok2str(icmp6_opt_ra_flag_values,"none",(p->nd_ra_flags_reserved)), get_rtpref(p->nd_ra_flags_reserved), EXTRACT_16BITS(&p->nd_ra_router_lifetime), EXTRACT_32BITS(&p->nd_ra_reachable), EXTRACT_32BITS(&p->nd_ra_retransmit)); icmp6_opt_print((const u_char *)dp + RTADVLEN, length - RTADVLEN); } break; case ND_NEIGHBOR_SOLICIT: { struct nd_neighbor_solicit *p; p = (struct nd_neighbor_solicit *)dp; TCHECK(p->nd_ns_target); printf(", who has %s", ip6addr_string(&p->nd_ns_target)); if (vflag) { #define NDSOLLEN 24 icmp6_opt_print((const u_char *)dp + NDSOLLEN, length - NDSOLLEN); } } break; case ND_NEIGHBOR_ADVERT: { struct nd_neighbor_advert *p; p = (struct nd_neighbor_advert *)dp; TCHECK(p->nd_na_target); printf(", tgt is %s", ip6addr_string(&p->nd_na_target)); if (vflag) { printf(", Flags [%s]", bittok2str(icmp6_nd_na_flag_values, "none", EXTRACT_32BITS(&p->nd_na_flags_reserved))); #define NDADVLEN 24 icmp6_opt_print((const u_char *)dp + NDADVLEN, length - NDADVLEN); #undef NDADVLEN } } break; case ND_REDIRECT: #define RDR(i) ((struct nd_redirect *)(i)) TCHECK(RDR(dp)->nd_rd_dst); printf(", %s", getname6((const u_char *)&RDR(dp)->nd_rd_dst)); TCHECK(RDR(dp)->nd_rd_target); printf(" to %s", getname6((const u_char*)&RDR(dp)->nd_rd_target)); #define REDIRECTLEN 40 if (vflag) { icmp6_opt_print((const u_char *)dp + REDIRECTLEN, length - REDIRECTLEN); } break; #undef REDIRECTLEN #undef RDR case ICMP6_ROUTER_RENUMBERING: icmp6_rrenum_print(bp, ep); break; case ICMP6_NI_QUERY: case ICMP6_NI_REPLY: icmp6_nodeinfo_print(length, bp, ep); break; case IND_SOLICIT: case IND_ADVERT: break; case ICMP6_V2_MEMBERSHIP_REPORT: mldv2_report_print((const u_char *) dp, length); break; case ICMP6_MOBILEPREFIX_SOLICIT: /* fall through */ case ICMP6_HADISCOV_REQUEST: TCHECK(dp->icmp6_data16[0]); printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])); break; case ICMP6_HADISCOV_REPLY: if (vflag) { struct in6_addr *in6; u_char *cp; TCHECK(dp->icmp6_data16[0]); printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])); cp = (u_char *)dp + length; in6 = (struct in6_addr *)(dp + 1); for (; (u_char *)in6 < cp; in6++) { TCHECK(*in6); printf(", %s", ip6addr_string(in6)); } } break; case ICMP6_MOBILEPREFIX_ADVERT: if (vflag) { TCHECK(dp->icmp6_data16[0]); printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])); if (dp->icmp6_data16[1] & 0xc0) printf(" "); if (dp->icmp6_data16[1] & 0x80) printf("M"); if (dp->icmp6_data16[1] & 0x40) printf("O"); #define MPADVLEN 8 icmp6_opt_print((const u_char *)dp + MPADVLEN, length - MPADVLEN); } break; case ND_RPL_MESSAGE: rpl_print(ndo, dp, &dp->icmp6_data8[0], length); break; default: printf(", length %u", length); if (vflag <= 1) print_unknown_data(bp,"\n\t", length); return; } if (!vflag) printf(", length %u", length); return; trunc: fputs("[|icmp6]", stdout); } static struct udphdr * get_upperlayer(u_char *bp, u_int *prot) { const u_char *ep; struct ip6_hdr *ip6 = (struct ip6_hdr *)bp; struct udphdr *uh; struct ip6_hbh *hbh; struct ip6_frag *fragh; struct ah *ah; u_int nh; int hlen; /* 'ep' points to the end of available data. */ ep = snapend; if (!TTEST(ip6->ip6_nxt)) return NULL; nh = ip6->ip6_nxt; hlen = sizeof(struct ip6_hdr); while (bp < ep) { bp += hlen; switch(nh) { case IPPROTO_UDP: case IPPROTO_TCP: uh = (struct udphdr *)bp; if (TTEST(uh->uh_dport)) { *prot = nh; return(uh); } else return(NULL); /* NOTREACHED */ case IPPROTO_HOPOPTS: case IPPROTO_DSTOPTS: case IPPROTO_ROUTING: hbh = (struct ip6_hbh *)bp; if (!TTEST(hbh->ip6h_len)) return(NULL); nh = hbh->ip6h_nxt; hlen = (hbh->ip6h_len + 1) << 3; break; case IPPROTO_FRAGMENT: /* this should be odd, but try anyway */ fragh = (struct ip6_frag *)bp; if (!TTEST(fragh->ip6f_offlg)) return(NULL); /* fragments with non-zero offset are meaningless */ if ((EXTRACT_16BITS(&fragh->ip6f_offlg) & IP6F_OFF_MASK) != 0) return(NULL); nh = fragh->ip6f_nxt; hlen = sizeof(struct ip6_frag); break; case IPPROTO_AH: ah = (struct ah *)bp; if (!TTEST(ah->ah_len)) return(NULL); nh = ah->ah_nxt; hlen = (ah->ah_len + 2) << 2; break; default: /* unknown or undecodable header */ *prot = nh; /* meaningless, but set here anyway */ return(NULL); } } return(NULL); /* should be notreached, though */ } static void icmp6_opt_print(const u_char *bp, int resid) { const struct nd_opt_hdr *op; const struct nd_opt_hdr *opl; /* why there's no struct? */ const struct nd_opt_prefix_info *opp; const struct icmp6_opts_redirect *opr; const struct nd_opt_mtu *opm; const struct nd_opt_rdnss *oprd; const struct nd_opt_dnssl *opds; const struct nd_opt_advinterval *opa; const struct nd_opt_homeagent_info *oph; const struct nd_opt_route_info *opri; const u_char *cp, *ep, *domp; struct in6_addr in6, *in6p; size_t l; u_int i; #define ECHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) return cp = bp; /* 'ep' points to the end of available data. */ ep = snapend; while (cp < ep) { op = (struct nd_opt_hdr *)cp; ECHECK(op->nd_opt_len); if (resid <= 0) return; if (op->nd_opt_len == 0) goto trunc; if (cp + (op->nd_opt_len << 3) > ep) goto trunc; printf("\n\t %s option (%u), length %u (%u): ", tok2str(icmp6_opt_values, "unknown", op->nd_opt_type), op->nd_opt_type, op->nd_opt_len << 3, op->nd_opt_len); switch (op->nd_opt_type) { case ND_OPT_SOURCE_LINKADDR: opl = (struct nd_opt_hdr *)op; l = (op->nd_opt_len << 3) - 2; print_lladdr(cp + 2, l); break; case ND_OPT_TARGET_LINKADDR: opl = (struct nd_opt_hdr *)op; l = (op->nd_opt_len << 3) - 2; print_lladdr(cp + 2, l); break; case ND_OPT_PREFIX_INFORMATION: opp = (struct nd_opt_prefix_info *)op; TCHECK(opp->nd_opt_pi_prefix); printf("%s/%u%s, Flags [%s], valid time %s", ip6addr_string(&opp->nd_opt_pi_prefix), opp->nd_opt_pi_prefix_len, (op->nd_opt_len != 4) ? "badlen" : "", bittok2str(icmp6_opt_pi_flag_values, "none", opp->nd_opt_pi_flags_reserved), get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_valid_time))); printf(", pref. time %s", get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_preferred_time))); break; case ND_OPT_REDIRECTED_HEADER: opr = (struct icmp6_opts_redirect *)op; print_unknown_data(bp,"\n\t ",op->nd_opt_len<<3); /* xxx */ break; case ND_OPT_MTU: opm = (struct nd_opt_mtu *)op; TCHECK(opm->nd_opt_mtu_mtu); printf(" %u%s", EXTRACT_32BITS(&opm->nd_opt_mtu_mtu), (op->nd_opt_len != 1) ? "bad option length" : "" ); break; case ND_OPT_RDNSS: oprd = (struct nd_opt_rdnss *)op; l = (op->nd_opt_len - 1) / 2; printf(" lifetime %us,", EXTRACT_32BITS(&oprd->nd_opt_rdnss_lifetime)); for (i = 0; i < l; i++) { TCHECK(oprd->nd_opt_rdnss_addr[i]); printf(" addr: %s", ip6addr_string(&oprd->nd_opt_rdnss_addr[i])); } break; case ND_OPT_DNSSL: opds = (struct nd_opt_dnssl *)op; printf(" lifetime %us, domain(s):", EXTRACT_32BITS(&opds->nd_opt_dnssl_lifetime)); domp = cp + 8; /* domain names, variable-sized, RFC1035-encoded */ while (domp < cp + (op->nd_opt_len << 3) && *domp != '\0') { printf (" "); if ((domp = ns_nprint (domp, bp)) == NULL) goto trunc; } break; case ND_OPT_ADVINTERVAL: opa = (struct nd_opt_advinterval *)op; TCHECK(opa->nd_opt_adv_interval); printf(" %ums", EXTRACT_32BITS(&opa->nd_opt_adv_interval)); break; case ND_OPT_HOMEAGENT_INFO: oph = (struct nd_opt_homeagent_info *)op; TCHECK(oph->nd_opt_hai_lifetime); printf(" preference %u, lifetime %u", EXTRACT_16BITS(&oph->nd_opt_hai_preference), EXTRACT_16BITS(&oph->nd_opt_hai_lifetime)); break; case ND_OPT_ROUTE_INFO: opri = (struct nd_opt_route_info *)op; TCHECK(opri->nd_opt_rti_lifetime); memset(&in6, 0, sizeof(in6)); in6p = (struct in6_addr *)(opri + 1); switch (op->nd_opt_len) { case 1: break; case 2: TCHECK2(*in6p, 8); memcpy(&in6, opri + 1, 8); break; case 3: TCHECK(*in6p); memcpy(&in6, opri + 1, sizeof(in6)); break; default: goto trunc; } printf(" %s/%u", ip6addr_string(&in6), opri->nd_opt_rti_prefixlen); printf(", pref=%s", get_rtpref(opri->nd_opt_rti_flags)); printf(", lifetime=%s", get_lifetime(EXTRACT_32BITS(&opri->nd_opt_rti_lifetime))); break; default: if (vflag <= 1) { print_unknown_data(cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */ return; } break; } /* do we want to see an additional hexdump ? */ if (vflag> 1) print_unknown_data(cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */ cp += op->nd_opt_len << 3; resid -= op->nd_opt_len << 3; } return; trunc: fputs("[ndp opt]", stdout); return; #undef ECHECK } static void mld6_print(const u_char *bp) { struct mld6_hdr *mp = (struct mld6_hdr *)bp; const u_char *ep; /* 'ep' points to the end of available data. */ ep = snapend; if ((u_char *)mp + sizeof(*mp) > ep) return; printf("max resp delay: %d ", EXTRACT_16BITS(&mp->mld6_maxdelay)); printf("addr: %s", ip6addr_string(&mp->mld6_addr)); } static void mldv2_report_print(const u_char *bp, u_int len) { struct icmp6_hdr *icp = (struct icmp6_hdr *) bp; u_int group, nsrcs, ngroups; u_int i, j; /* Minimum len is 8 */ if (len < 8) { printf(" [invalid len %d]", len); return; } TCHECK(icp->icmp6_data16[1]); ngroups = EXTRACT_16BITS(&icp->icmp6_data16[1]); printf(", %d group record(s)", ngroups); if (vflag > 0) { /* Print the group records */ group = 8; for (i = 0; i < ngroups; i++) { /* type(1) + auxlen(1) + numsrc(2) + grp(16) */ if (len < group + 20) { printf(" [invalid number of groups]"); return; } TCHECK2(bp[group + 4], sizeof(struct in6_addr)); printf(" [gaddr %s", ip6addr_string(&bp[group + 4])); printf(" %s", tok2str(mldv2report2str, " [v2-report-#%d]", bp[group])); nsrcs = (bp[group + 2] << 8) + bp[group + 3]; /* Check the number of sources and print them */ if (len < group + 20 + (nsrcs * sizeof(struct in6_addr))) { printf(" [invalid number of sources %d]", nsrcs); return; } if (vflag == 1) printf(", %d source(s)", nsrcs); else { /* Print the sources */ (void)printf(" {"); for (j = 0; j < nsrcs; j++) { TCHECK2(bp[group + 20 + j * sizeof(struct in6_addr)], sizeof(struct in6_addr)); printf(" %s", ip6addr_string(&bp[group + 20 + j * sizeof(struct in6_addr)])); } (void)printf(" }"); } /* Next group record */ group += 20 + nsrcs * sizeof(struct in6_addr); printf("]"); } } return; trunc: (void)printf("[|icmp6]"); return; } static void mldv2_query_print(const u_char *bp, u_int len) { struct icmp6_hdr *icp = (struct icmp6_hdr *) bp; u_int mrc; int mrt, qqi; u_int nsrcs; register u_int i; /* Minimum len is 28 */ if (len < 28) { printf(" [invalid len %d]", len); return; } TCHECK(icp->icmp6_data16[0]); mrc = EXTRACT_16BITS(&icp->icmp6_data16[0]); if (mrc < 32768) { mrt = mrc; } else { mrt = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3); } if (vflag) { (void)printf(" [max resp delay=%d]", mrt); } TCHECK2(bp[8], sizeof(struct in6_addr)); printf(" [gaddr %s", ip6addr_string(&bp[8])); if (vflag) { TCHECK(bp[25]); if (bp[24] & 0x08) { printf(" sflag"); } if (bp[24] & 0x07) { printf(" robustness=%d", bp[24] & 0x07); } if (bp[25] < 128) { qqi = bp[25]; } else { qqi = ((bp[25] & 0x0f) | 0x10) << (((bp[25] & 0x70) >> 4) + 3); } printf(" qqi=%d", qqi); } TCHECK2(bp[26], 2); nsrcs = EXTRACT_16BITS(&bp[26]); if (nsrcs > 0) { if (len < 28 + nsrcs * sizeof(struct in6_addr)) printf(" [invalid number of sources]"); else if (vflag > 1) { printf(" {"); for (i = 0; i < nsrcs; i++) { TCHECK2(bp[28 + i * sizeof(struct in6_addr)], sizeof(struct in6_addr)); printf(" %s", ip6addr_string(&bp[28 + i * sizeof(struct in6_addr)])); } printf(" }"); } else printf(", %d source(s)", nsrcs); } printf("]"); return; trunc: (void)printf("[|icmp6]"); return; } static void dnsname_print(const u_char *cp, const u_char *ep) { int i; /* DNS name decoding - no decompression */ printf(", \""); while (cp < ep) { i = *cp++; if (i) { if (i > ep - cp) { printf("???"); break; } while (i-- && cp < ep) { safeputchar(*cp); cp++; } if (cp + 1 < ep && *cp) printf("."); } else { if (cp == ep) { /* FQDN */ printf("."); } else if (cp + 1 == ep && *cp == '\0') { /* truncated */ } else { /* invalid */ printf("???"); } break; } } printf("\""); } static void icmp6_nodeinfo_print(u_int icmp6len, const u_char *bp, const u_char *ep) { struct icmp6_nodeinfo *ni6; struct icmp6_hdr *dp; const u_char *cp; size_t siz, i; int needcomma; if (ep < bp) return; dp = (struct icmp6_hdr *)bp; ni6 = (struct icmp6_nodeinfo *)bp; siz = ep - bp; switch (ni6->ni_type) { case ICMP6_NI_QUERY: if (siz == sizeof(*dp) + 4) { /* KAME who-are-you */ printf(" who-are-you request"); break; } printf(" node information query"); TCHECK2(*dp, sizeof(*ni6)); ni6 = (struct icmp6_nodeinfo *)dp; printf(" ("); /*)*/ switch (EXTRACT_16BITS(&ni6->ni_qtype)) { case NI_QTYPE_NOOP: printf("noop"); break; case NI_QTYPE_SUPTYPES: printf("supported qtypes"); i = EXTRACT_16BITS(&ni6->ni_flags); if (i) printf(" [%s]", (i & 0x01) ? "C" : ""); break; break; case NI_QTYPE_FQDN: printf("DNS name"); break; case NI_QTYPE_NODEADDR: printf("node addresses"); i = ni6->ni_flags; if (!i) break; /* NI_NODEADDR_FLAG_TRUNCATE undefined for query */ printf(" [%s%s%s%s%s%s]", (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "", (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "", (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "", (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "", (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "", (i & NI_NODEADDR_FLAG_ALL) ? "A" : ""); break; default: printf("unknown"); break; } if (ni6->ni_qtype == NI_QTYPE_NOOP || ni6->ni_qtype == NI_QTYPE_SUPTYPES) { if (siz != sizeof(*ni6)) if (vflag) printf(", invalid len"); /*(*/ printf(")"); break; } /* XXX backward compat, icmp-name-lookup-03 */ if (siz == sizeof(*ni6)) { printf(", 03 draft"); /*(*/ printf(")"); break; } switch (ni6->ni_code) { case ICMP6_NI_SUBJ_IPV6: if (!TTEST2(*dp, sizeof(*ni6) + sizeof(struct in6_addr))) break; if (siz != sizeof(*ni6) + sizeof(struct in6_addr)) { if (vflag) printf(", invalid subject len"); break; } printf(", subject=%s", getname6((const u_char *)(ni6 + 1))); break; case ICMP6_NI_SUBJ_FQDN: printf(", subject=DNS name"); cp = (const u_char *)(ni6 + 1); if (cp[0] == ep - cp - 1) { /* icmp-name-lookup-03, pascal string */ if (vflag) printf(", 03 draft"); cp++; printf(", \""); while (cp < ep) { safeputchar(*cp); cp++; } printf("\""); } else dnsname_print(cp, ep); break; case ICMP6_NI_SUBJ_IPV4: if (!TTEST2(*dp, sizeof(*ni6) + sizeof(struct in_addr))) break; if (siz != sizeof(*ni6) + sizeof(struct in_addr)) { if (vflag) printf(", invalid subject len"); break; } printf(", subject=%s", getname((const u_char *)(ni6 + 1))); break; default: printf(", unknown subject"); break; } /*(*/ printf(")"); break; case ICMP6_NI_REPLY: if (icmp6len > siz) { printf("[|icmp6: node information reply]"); break; } needcomma = 0; ni6 = (struct icmp6_nodeinfo *)dp; printf(" node information reply"); printf(" ("); /*)*/ switch (ni6->ni_code) { case ICMP6_NI_SUCCESS: if (vflag) { printf("success"); needcomma++; } break; case ICMP6_NI_REFUSED: printf("refused"); needcomma++; if (siz != sizeof(*ni6)) if (vflag) printf(", invalid length"); break; case ICMP6_NI_UNKNOWN: printf("unknown"); needcomma++; if (siz != sizeof(*ni6)) if (vflag) printf(", invalid length"); break; } if (ni6->ni_code != ICMP6_NI_SUCCESS) { /*(*/ printf(")"); break; } switch (EXTRACT_16BITS(&ni6->ni_qtype)) { case NI_QTYPE_NOOP: if (needcomma) printf(", "); printf("noop"); if (siz != sizeof(*ni6)) if (vflag) printf(", invalid length"); break; case NI_QTYPE_SUPTYPES: if (needcomma) printf(", "); printf("supported qtypes"); i = EXTRACT_16BITS(&ni6->ni_flags); if (i) printf(" [%s]", (i & 0x01) ? "C" : ""); break; case NI_QTYPE_FQDN: if (needcomma) printf(", "); printf("DNS name"); cp = (const u_char *)(ni6 + 1) + 4; if (cp[0] == ep - cp - 1) { /* icmp-name-lookup-03, pascal string */ if (vflag) printf(", 03 draft"); cp++; printf(", \""); while (cp < ep) { safeputchar(*cp); cp++; } printf("\""); } else dnsname_print(cp, ep); if ((EXTRACT_16BITS(&ni6->ni_flags) & 0x01) != 0) printf(" [TTL=%u]", *(u_int32_t *)(ni6 + 1)); break; case NI_QTYPE_NODEADDR: if (needcomma) printf(", "); printf("node addresses"); i = sizeof(*ni6); while (i < siz) { if (i + sizeof(struct in6_addr) + sizeof(int32_t) > siz) break; printf(" %s", getname6(bp + i)); i += sizeof(struct in6_addr); printf("(%d)", (int32_t)EXTRACT_32BITS(bp + i)); i += sizeof(int32_t); } i = ni6->ni_flags; if (!i) break; printf(" [%s%s%s%s%s%s%s]", (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "", (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "", (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "", (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "", (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "", (i & NI_NODEADDR_FLAG_ALL) ? "A" : "", (i & NI_NODEADDR_FLAG_TRUNCATE) ? "T" : ""); break; default: if (needcomma) printf(", "); printf("unknown"); break; } /*(*/ printf(")"); break; } return; trunc: fputs("[|icmp6]", stdout); } static void icmp6_rrenum_print(const u_char *bp, const u_char *ep) { struct icmp6_router_renum *rr6; const char *cp; struct rr_pco_match *match; struct rr_pco_use *use; char hbuf[NI_MAXHOST]; int n; if (ep < bp) return; rr6 = (struct icmp6_router_renum *)bp; cp = (const char *)(rr6 + 1); TCHECK(rr6->rr_reserved); switch (rr6->rr_code) { case ICMP6_ROUTER_RENUMBERING_COMMAND: printf("router renum: command"); break; case ICMP6_ROUTER_RENUMBERING_RESULT: printf("router renum: result"); break; case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET: printf("router renum: sequence number reset"); break; default: printf("router renum: code-#%d", rr6->rr_code); break; } printf(", seq=%u", EXTRACT_32BITS(&rr6->rr_seqnum)); if (vflag) { #define F(x, y) ((rr6->rr_flags) & (x) ? (y) : "") printf("["); /*]*/ if (rr6->rr_flags) { printf("%s%s%s%s%s,", F(ICMP6_RR_FLAGS_TEST, "T"), F(ICMP6_RR_FLAGS_REQRESULT, "R"), F(ICMP6_RR_FLAGS_FORCEAPPLY, "A"), F(ICMP6_RR_FLAGS_SPECSITE, "S"), F(ICMP6_RR_FLAGS_PREVDONE, "P")); } printf("seg=%u,", rr6->rr_segnum); printf("maxdelay=%u", EXTRACT_16BITS(&rr6->rr_maxdelay)); if (rr6->rr_reserved) printf("rsvd=0x%x", EXTRACT_32BITS(&rr6->rr_reserved)); /*[*/ printf("]"); #undef F } if (rr6->rr_code == ICMP6_ROUTER_RENUMBERING_COMMAND) { match = (struct rr_pco_match *)cp; cp = (const char *)(match + 1); TCHECK(match->rpm_prefix); if (vflag > 1) printf("\n\t"); else printf(" "); printf("match("); /*)*/ switch (match->rpm_code) { case RPM_PCO_ADD: printf("add"); break; case RPM_PCO_CHANGE: printf("change"); break; case RPM_PCO_SETGLOBAL: printf("setglobal"); break; default: printf("#%u", match->rpm_code); break; } if (vflag) { printf(",ord=%u", match->rpm_ordinal); printf(",min=%u", match->rpm_minlen); printf(",max=%u", match->rpm_maxlen); } if (inet_ntop(AF_INET6, &match->rpm_prefix, hbuf, sizeof(hbuf))) printf(",%s/%u", hbuf, match->rpm_matchlen); else printf(",?/%u", match->rpm_matchlen); /*(*/ printf(")"); n = match->rpm_len - 3; if (n % 4) goto trunc; n /= 4; while (n-- > 0) { use = (struct rr_pco_use *)cp; cp = (const char *)(use + 1); TCHECK(use->rpu_prefix); if (vflag > 1) printf("\n\t"); else printf(" "); printf("use("); /*)*/ if (use->rpu_flags) { #define F(x, y) ((use->rpu_flags) & (x) ? (y) : "") printf("%s%s,", F(ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME, "V"), F(ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME, "P")); #undef F } if (vflag) { printf("mask=0x%x,", use->rpu_ramask); printf("raflags=0x%x,", use->rpu_raflags); if (~use->rpu_vltime == 0) printf("vltime=infty,"); else printf("vltime=%u,", EXTRACT_32BITS(&use->rpu_vltime)); if (~use->rpu_pltime == 0) printf("pltime=infty,"); else printf("pltime=%u,", EXTRACT_32BITS(&use->rpu_pltime)); } if (inet_ntop(AF_INET6, &use->rpu_prefix, hbuf, sizeof(hbuf))) printf("%s/%u/%u", hbuf, use->rpu_uselen, use->rpu_keeplen); else printf("?/%u/%u", use->rpu_uselen, use->rpu_keeplen); /*(*/ printf(")"); } } return; trunc: fputs("[|icmp6]", stdout); } #endif /* INET6 */ tcpdump-4.5.1/gmt2local.c0000644000026300017510000000423412237020316012645 0ustar mcr/* * Copyright (c) 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/gmt2local.c,v 1.9 2003-11-16 09:36:09 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif #include "gmt2local.h" /* * Returns the difference between gmt and local time in seconds. * Use gmtime() and localtime() to keep things simple. */ int32_t gmt2local(time_t t) { register int dt, dir; register struct tm *gmt, *loc; struct tm sgmt; if (t == 0) t = time(NULL); gmt = &sgmt; *gmt = *gmtime(&t); loc = localtime(&t); dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 + (loc->tm_min - gmt->tm_min) * 60; /* * If the year or julian day is different, we span 00:00 GMT * and must add or subtract a day. Check the year first to * avoid problems when the julian day wraps. */ dir = loc->tm_year - gmt->tm_year; if (dir == 0) dir = loc->tm_yday - gmt->tm_yday; dt += dir * 24 * 60 * 60; return (dt); } tcpdump-4.5.1/dccp.h0000644000026300017510000000756312237020316011707 0ustar mcr/* @(#) $Header: /tcpdump/master/tcpdump/dccp.h,v 1.5 2006-11-02 09:05:23 hannes Exp $ (LBL) */ /* * Copyright (C) Arnaldo Carvalho de Melo 2004 * Copyright (C) Ian McDonald 2005 * Copyright (C) Yoshifumi Nishida 2005 * * This software may be distributed either under the terms of the * BSD-style license that accompanies tcpdump or the GNU GPL version 2 */ #ifndef __DCCP_HDR__ #define __DCCP_HDR__ /** * struct dccp_hdr - generic part of DCCP packet header * * @dccph_sport - Relevant port on the endpoint that sent this packet * @dccph_dport - Relevant port on the other endpoint * @dccph_doff - Data Offset from the start of the DCCP header, in 32-bit words * @dccph_ccval - Used by the HC-Sender CCID * @dccph_cscov - Parts of the packet that are covered by the Checksum field * @dccph_checksum - Internet checksum, depends on dccph_cscov * @dccph_x - 0 = 24 bit sequence number, 1 = 48 * @dccph_type - packet type, see DCCP_PKT_ prefixed macros * @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x */ struct dccp_hdr { u_int16_t dccph_sport, dccph_dport; u_int8_t dccph_doff; u_int8_t dccph_ccval_cscov; u_int16_t dccph_checksum; union { u_int8_t dccph_xtr; u_int32_t dccph_seq; } dccph_xtrs; }; #define DCCPH_CCVAL(dh) (((dh)->dccph_ccval_cscov >> 4) & 0xF) #define DCCPH_CSCOV(dh) (((dh)->dccph_ccval_cscov) & 0xF) #define DCCPH_X(dh) ((dh)->dccph_xtrs.dccph_xtr & 1) #define DCCPH_TYPE(dh) (((dh)->dccph_xtrs.dccph_xtr >> 1) & 0xF) #define DCCPH_SEQ(dh) (((dh)->dccph_xtrs.dccph_seq) >> 8) /** * struct dccp_hdr_ext - the low bits of a 48 bit seq packet * * @dccph_seq_low - low 24 bits of a 48 bit seq packet */ struct dccp_hdr_ext { u_int32_t dccph_seq_low; }; /** * struct dccp_hdr_request - Conection initiation request header * * @dccph_req_service - Service to which the client app wants to connect */ struct dccp_hdr_request { u_int32_t dccph_req_service; }; /** * struct dccp_hdr_ack_bits - acknowledgment bits common to most packets * * @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR */ struct dccp_hdr_ack_bits { u_int32_t dccph_ra; u_int32_t dccph_ack_nr_low; }; #define DCCPH_ACK(dh_ack) ((dh_ack)->dccph_ra >> 8) /** * struct dccp_hdr_response - Conection initiation response header * * @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR * @dccph_resp_service - Echoes the Service Code on a received DCCP-Request */ struct dccp_hdr_response { struct dccp_hdr_ack_bits dccph_resp_ack; u_int32_t dccph_resp_service; }; #if 0 static inline struct dccp_hdr_data *dccp_hdr_data(struct dccp_hdr *hdrg) { const int ext = DCCPH_X(hdrg) ? sizeof(struct dccp_hdr_ext) : 0; return (struct dccp_hdr_data *)(((u_char *)hdrg) + sizeof(hdrg) + ext); } #endif /** * struct dccp_hdr_reset - Unconditionally shut down a connection * * @dccph_reset_service - Echoes the Service Code on a received DCCP-Request */ struct dccp_hdr_reset { struct dccp_hdr_ack_bits dccph_reset_ack; u_int8_t dccph_reset_code, dccph_reset_data[3]; }; enum dccp_pkt_type { DCCP_PKT_REQUEST = 0, DCCP_PKT_RESPONSE, DCCP_PKT_DATA, DCCP_PKT_ACK, DCCP_PKT_DATAACK, DCCP_PKT_CLOSEREQ, DCCP_PKT_CLOSE, DCCP_PKT_RESET, DCCP_PKT_SYNC, DCCP_PKT_SYNCACK, DCCP_PKT_INVALID }; enum dccp_reset_codes { DCCP_RESET_CODE_UNSPECIFIED = 0, DCCP_RESET_CODE_CLOSED, DCCP_RESET_CODE_ABORTED, DCCP_RESET_CODE_NO_CONNECTION, DCCP_RESET_CODE_PACKET_ERROR, DCCP_RESET_CODE_OPTION_ERROR, DCCP_RESET_CODE_MANDATORY_ERROR, DCCP_RESET_CODE_CONNECTION_REFUSED, DCCP_RESET_CODE_BAD_SERVICE_CODE, DCCP_RESET_CODE_TOO_BUSY, DCCP_RESET_CODE_BAD_INIT_COOKIE, DCCP_RESET_CODE_AGGRESSION_PENALTY, __DCCP_RESET_CODE_LAST }; #endif /* __DCCP_HDR__ */ tcpdump-4.5.1/print-pppoe.c0000644000026300017510000001331312237020316013234 0ustar mcr/* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Original code by Greg Stark */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-pppoe.c,v 1.31 2005-04-26 19:48:38 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "interface.h" #include "addrtoname.h" #include "ppp.h" #include "ethertype.h" #include "ether.h" #include "extract.h" /* must come after interface.h */ /* Codes */ enum { PPPOE_PADI = 0x09, PPPOE_PADO = 0x07, PPPOE_PADR = 0x19, PPPOE_PADS = 0x65, PPPOE_PADT = 0xa7 }; static const struct tok pppoecode2str[] = { { PPPOE_PADI, "PADI" }, { PPPOE_PADO, "PADO" }, { PPPOE_PADR, "PADR" }, { PPPOE_PADS, "PADS" }, { PPPOE_PADT, "PADT" }, { 0, "" }, /* PPP Data */ { 0, NULL } }; /* Tags */ enum { PPPOE_EOL = 0, PPPOE_SERVICE_NAME = 0x0101, PPPOE_AC_NAME = 0x0102, PPPOE_HOST_UNIQ = 0x0103, PPPOE_AC_COOKIE = 0x0104, PPPOE_VENDOR = 0x0105, PPPOE_RELAY_SID = 0x0110, PPPOE_MAX_PAYLOAD = 0x0120, PPPOE_SERVICE_NAME_ERROR = 0x0201, PPPOE_AC_SYSTEM_ERROR = 0x0202, PPPOE_GENERIC_ERROR = 0x0203 }; static const struct tok pppoetag2str[] = { { PPPOE_EOL, "EOL" }, { PPPOE_SERVICE_NAME, "Service-Name" }, { PPPOE_AC_NAME, "AC-Name" }, { PPPOE_HOST_UNIQ, "Host-Uniq" }, { PPPOE_AC_COOKIE, "AC-Cookie" }, { PPPOE_VENDOR, "Vendor-Specific" }, { PPPOE_RELAY_SID, "Relay-Session-ID" }, { PPPOE_MAX_PAYLOAD, "PPP-Max-Payload" }, { PPPOE_SERVICE_NAME_ERROR, "Service-Name-Error" }, { PPPOE_AC_SYSTEM_ERROR, "AC-System-Error" }, { PPPOE_GENERIC_ERROR, "Generic-Error" }, { 0, NULL } }; #define PPPOE_HDRLEN 6 #define MAXTAGPRINT 80 u_int pppoe_if_print(const struct pcap_pkthdr *h, register const u_char *p) { return (pppoe_print(p, h->len)); } u_int pppoe_print(register const u_char *bp, u_int length) { u_int16_t pppoe_ver, pppoe_type, pppoe_code, pppoe_sessionid; u_int pppoe_length; const u_char *pppoe_packet, *pppoe_payload; if (length < PPPOE_HDRLEN) { (void)printf("truncated-pppoe %u", length); return (length); } length -= PPPOE_HDRLEN; pppoe_packet = bp; TCHECK2(*pppoe_packet, PPPOE_HDRLEN); pppoe_ver = (pppoe_packet[0] & 0xF0) >> 4; pppoe_type = (pppoe_packet[0] & 0x0F); pppoe_code = pppoe_packet[1]; pppoe_sessionid = EXTRACT_16BITS(pppoe_packet + 2); pppoe_length = EXTRACT_16BITS(pppoe_packet + 4); pppoe_payload = pppoe_packet + PPPOE_HDRLEN; if (pppoe_ver != 1) { printf(" [ver %d]",pppoe_ver); } if (pppoe_type != 1) { printf(" [type %d]",pppoe_type); } printf("PPPoE %s", tok2str(pppoecode2str, "PAD-%x", pppoe_code)); if (pppoe_code == PPPOE_PADI && pppoe_length > 1484 - PPPOE_HDRLEN) { printf(" [len %u!]",pppoe_length); } if (pppoe_length > length) { printf(" [len %u > %u!]", pppoe_length, length); pppoe_length = length; } if (pppoe_sessionid) { printf(" [ses 0x%x]", pppoe_sessionid); } if (pppoe_code) { /* PPP session packets don't contain tags */ u_short tag_type = 0xffff, tag_len; const u_char *p = pppoe_payload; /* * loop invariant: * p points to current tag, * tag_type is previous tag or 0xffff for first iteration */ while (tag_type && p < pppoe_payload + pppoe_length) { TCHECK2(*p, 4); tag_type = EXTRACT_16BITS(p); tag_len = EXTRACT_16BITS(p + 2); p += 4; /* p points to tag_value */ if (tag_len) { unsigned isascii = 0, isgarbage = 0; const u_char *v; char tag_str[MAXTAGPRINT]; unsigned tag_str_len = 0; /* TODO print UTF-8 decoded text */ TCHECK2(*p, tag_len); for (v = p; v < p + tag_len && tag_str_len < MAXTAGPRINT-1; v++) if (*v >= 32 && *v < 127) { tag_str[tag_str_len++] = *v; isascii++; } else { tag_str[tag_str_len++] = '.'; isgarbage++; } tag_str[tag_str_len] = 0; if (isascii > isgarbage) { printf(" [%s \"%*.*s\"]", tok2str(pppoetag2str, "TAG-0x%x", tag_type), (int)tag_str_len, (int)tag_str_len, tag_str); } else { /* Print hex, not fast to abuse printf but this doesn't get used much */ printf(" [%s 0x", tok2str(pppoetag2str, "TAG-0x%x", tag_type)); for (v=p; v, not any of the RPC * header files * * and * * 2) if _XOPEN_SOURCE_EXTENDED is defined, doesn't declare * it * * so we undefine it. */ #undef _XOPEN_SOURCE_EXTENDED #include #if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) #include #ifdef HAVE_RPC_RPCENT_H #include #endif /* HAVE_RPC_RPCENT_H */ #endif /* defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) */ #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" #include "ip.h" #ifdef INET6 #include "ip6.h" #endif #include "rpc_auth.h" #include "rpc_msg.h" #include "pmap_prot.h" static const struct tok proc2str[] = { { SUNRPC_PMAPPROC_NULL, "null" }, { SUNRPC_PMAPPROC_SET, "set" }, { SUNRPC_PMAPPROC_UNSET, "unset" }, { SUNRPC_PMAPPROC_GETPORT, "getport" }, { SUNRPC_PMAPPROC_DUMP, "dump" }, { SUNRPC_PMAPPROC_CALLIT, "call" }, { 0, NULL } }; /* Forwards */ static char *progstr(u_int32_t); void sunrpcrequest_print(register const u_char *bp, register u_int length, register const u_char *bp2) { register const struct sunrpc_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 sunrpc_msg *)bp; if (!nflag) { snprintf(srcid, sizeof(srcid), "0x%x", EXTRACT_32BITS(&rp->rm_xid)); strlcpy(dstid, "sunrpc", sizeof(dstid)); } else { snprintf(srcid, sizeof(srcid), "0x%x", EXTRACT_32BITS(&rp->rm_xid)); snprintf(dstid, sizeof(dstid), "0x%x", SUNRPC_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", EXTRACT_32BITS(&rp->rm_call.cb_proc))); x = EXTRACT_32BITS(&rp->rm_call.cb_rpcvers); if (x != 2) printf(" [rpcver %u]", x); switch (EXTRACT_32BITS(&rp->rm_call.cb_proc)) { case SUNRPC_PMAPPROC_SET: case SUNRPC_PMAPPROC_UNSET: case SUNRPC_PMAPPROC_GETPORT: case SUNRPC_PMAPPROC_CALLIT: x = EXTRACT_32BITS(&rp->rm_call.cb_prog); if (!nflag) printf(" %s", progstr(x)); else printf(" %u", x); printf(".%u", EXTRACT_32BITS(&rp->rm_call.cb_vers)); break; } } static char * progstr(prog) u_int32_t prog; { #if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) register struct rpcent *rp; #endif static char buf[32]; static u_int32_t lastprog = 0; if (lastprog != 0 && prog == lastprog) return (buf); #if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) rp = getrpcbynumber(prog); if (rp == NULL) #endif (void) snprintf(buf, sizeof(buf), "#%u", prog); #if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) else strlcpy(buf, rp->r_name, sizeof(buf)); #endif return (buf); } tcpdump-4.5.1/udp.h0000644000026300017510000001020512237020316011551 0ustar mcr/* @(#) $Header: /tcpdump/master/tcpdump/udp.h,v 1.13 2007-08-08 17:20:58 hannes Exp $ (LBL) */ /* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)udp.h 8.1 (Berkeley) 6/10/93 */ /* * Udp protocol header. * Per RFC 768, September, 1981. */ struct udphdr { u_int16_t uh_sport; /* source port */ u_int16_t uh_dport; /* destination port */ u_int16_t uh_ulen; /* udp length */ u_int16_t uh_sum; /* udp checksum */ }; #define TFTP_PORT 69 /*XXX*/ #define KERBEROS_PORT 88 /*XXX*/ #define SUNRPC_PORT 111 /*XXX*/ #define SNMP_PORT 161 /*XXX*/ #define NTP_PORT 123 /*XXX*/ #define SNMPTRAP_PORT 162 /*XXX*/ #define ISAKMP_PORT 500 /*XXX*/ #define SYSLOG_PORT 514 /* rfc3164 */ #define TIMED_PORT 525 /*XXX*/ #define RIP_PORT 520 /*XXX*/ #define LDP_PORT 646 #define AODV_PORT 654 /*XXX*/ #define OLSR_PORT 698 /* rfc3626 */ #define KERBEROS_SEC_PORT 750 /*XXX*/ #define L2TP_PORT 1701 /*XXX*/ #define SIP_PORT 5060 #define ISAKMP_PORT_NATT 4500 /* rfc3948 */ #define ISAKMP_PORT_USER1 7500 /*XXX - nonstandard*/ #define ISAKMP_PORT_USER2 8500 /*XXX - nonstandard*/ #define RX_PORT_LOW 7000 /*XXX*/ #define RX_PORT_HIGH 7009 /*XXX*/ #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 #define HSRP_PORT 1985 /*XXX*/ #define LMP_PORT 701 /* rfc4204 */ #define LWRES_PORT 921 #define VQP_PORT 1589 #define ZEPHYR_SRV_PORT 2103 #define ZEPHYR_CLT_PORT 2104 #define VAT_PORT 3456 #define MPLS_LSP_PING_PORT 3503 /* draft-ietf-mpls-lsp-ping-02.txt */ #define BFD_CONTROL_PORT 3784 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */ #define BFD_ECHO_PORT 3785 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */ #define WB_PORT 4567 #define SFLOW_PORT 6343 /* http://www.sflow.org/developers/specifications.php */ #define LWAPP_DATA_PORT 12222 /* draft-ohara-capwap-lwapp-04.txt */ #define LWAPP_CONTROL_PORT 12223 /* draft-ohara-capwap-lwapp-04.txt */ #define OTV_PORT 8472 /* draft-hasmit-otv-04 */ #define VXLAN_PORT 4789 /* draft-mahalingam-dutt-dcops-vxlan-04 */ #ifdef INET6 #define RIPNG_PORT 521 /*XXX*/ #define DHCP6_SERV_PORT 546 /*XXX*/ #define DHCP6_CLI_PORT 547 /*XXX*/ #define BABEL_PORT 6696 #define BABEL_PORT_OLD 6697 #endif tcpdump-4.5.1/print-radius.c0000644000026300017510000010003312237020316013374 0ustar mcr/* * Copyright (C) 2000 Alfredo Andres Omella. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* * Radius printer routines as specified on: * * RFC 2865: * "Remote Authentication Dial In User Service (RADIUS)" * * RFC 2866: * "RADIUS Accounting" * * RFC 2867: * "RADIUS Accounting Modifications for Tunnel Protocol Support" * * RFC 2868: * "RADIUS Attributes for Tunnel Protocol Support" * * RFC 2869: * "RADIUS Extensions" * * Alfredo Andres Omella (aandres@s21sec.com) v0.1 2000/09/15 * * TODO: Among other things to print ok MacIntosh and Vendor values */ #ifndef lint static const char rcsid[] _U_ = "$Id: print-radius.c,v 1.28 2005-09-26 01:01:55 guy Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" #include "oui.h" #define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) ) #define PRINT_HEX(bytes_len, ptr_data) \ while(bytes_len) \ { \ printf("%02X", *ptr_data ); \ ptr_data++; \ bytes_len--; \ } /* Radius packet codes */ #define RADCMD_ACCESS_REQ 1 /* Access-Request */ #define RADCMD_ACCESS_ACC 2 /* Access-Accept */ #define RADCMD_ACCESS_REJ 3 /* Access-Reject */ #define RADCMD_ACCOUN_REQ 4 /* Accounting-Request */ #define RADCMD_ACCOUN_RES 5 /* Accounting-Response */ #define RADCMD_ACCESS_CHA 11 /* Access-Challenge */ #define RADCMD_STATUS_SER 12 /* Status-Server */ #define RADCMD_STATUS_CLI 13 /* Status-Client */ #define RADCMD_RESERVED 255 /* Reserved */ static const struct tok radius_command_values[] = { { RADCMD_ACCESS_REQ, "Access Request" }, { RADCMD_ACCESS_ACC, "Access Accept" }, { RADCMD_ACCESS_REJ, "Access Reject" }, { RADCMD_ACCOUN_REQ, "Accounting Request" }, { RADCMD_ACCOUN_RES, "Accounting Response" }, { RADCMD_ACCESS_CHA, "Access Challenge" }, { RADCMD_STATUS_SER, "Status Server" }, { RADCMD_STATUS_CLI, "Status Client" }, { RADCMD_RESERVED, "Reserved" }, { 0, NULL} }; /********************************/ /* Begin Radius Attribute types */ /********************************/ #define SERV_TYPE 6 #define FRM_IPADDR 8 #define LOG_IPHOST 14 #define LOG_SERVICE 15 #define FRM_IPX 23 #define SESSION_TIMEOUT 27 #define IDLE_TIMEOUT 28 #define FRM_ATALK_LINK 37 #define FRM_ATALK_NETWORK 38 #define ACCT_DELAY 41 #define ACCT_SESSION_TIME 46 #define TUNNEL_TYPE 64 #define TUNNEL_MEDIUM 65 #define TUNNEL_CLIENT_END 66 #define TUNNEL_SERVER_END 67 #define TUNNEL_PASS 69 #define ARAP_PASS 70 #define ARAP_FEATURES 71 #define TUNNEL_PRIV_GROUP 81 #define TUNNEL_ASSIGN_ID 82 #define TUNNEL_PREFERENCE 83 #define ARAP_CHALLENGE_RESP 84 #define ACCT_INT_INTERVAL 85 #define TUNNEL_CLIENT_AUTH 90 #define TUNNEL_SERVER_AUTH 91 /********************************/ /* End Radius Attribute types */ /********************************/ static void print_attr_string(register u_char *, u_int, u_short ); static void print_attr_num(register u_char *, u_int, u_short ); static void print_vendor_attr(register u_char *, u_int, u_short ); static void print_attr_address(register u_char *, u_int, u_short); static void print_attr_time(register u_char *, u_int, u_short); static void print_attr_strange(register u_char *, u_int, u_short); struct radius_hdr { u_int8_t code; /* Radius packet code */ u_int8_t id; /* Radius packet id */ u_int16_t len; /* Radius total length */ u_int8_t auth[16]; /* Authenticator */ }; #define MIN_RADIUS_LEN 20 struct radius_attr { u_int8_t type; /* Attribute type */ u_int8_t len; /* Attribute length */ }; /* Service-Type Attribute standard values */ static const char *serv_type[]={ NULL, "Login", "Framed", "Callback Login", "Callback Framed", "Outbound", "Administrative", "NAS Prompt", "Authenticate Only", "Callback NAS Prompt", "Call Check", "Callback Administrative", }; /* Framed-Protocol Attribute standard values */ static const char *frm_proto[]={ NULL, "PPP", "SLIP", "ARAP", "Gandalf proprietary", "Xylogics IPX/SLIP", "X.75 Synchronous", }; /* Framed-Routing Attribute standard values */ static const char *frm_routing[]={ "None", "Send", "Listen", "Send&Listen", }; /* Framed-Compression Attribute standard values */ static const char *frm_comp[]={ "None", "VJ TCP/IP", "IPX", "Stac-LZS", }; /* Login-Service Attribute standard values */ static const char *login_serv[]={ "Telnet", "Rlogin", "TCP Clear", "PortMaster(proprietary)", "LAT", "X.25-PAD", "X.25-T3POS", "Unassigned", "TCP Clear Quiet", }; /* Termination-Action Attribute standard values */ static const char *term_action[]={ "Default", "RADIUS-Request", }; /* NAS-Port-Type Attribute standard values */ static const char *nas_port_type[]={ "Async", "Sync", "ISDN Sync", "ISDN Async V.120", "ISDN Async V.110", "Virtual", "PIAFS", "HDLC Clear Channel", "X.25", "X.75", "G.3 Fax", "SDSL", "ADSL-CAP", "ADSL-DMT", "ISDN-DSL", "Ethernet", "xDSL", "Cable", "Wireless - Other", "Wireless - IEEE 802.11", }; /* Acct-Status-Type Accounting Attribute standard values */ static const char *acct_status[]={ NULL, "Start", "Stop", "Interim-Update", "Unassigned", "Unassigned", "Unassigned", "Accounting-On", "Accounting-Off", "Tunnel-Start", "Tunnel-Stop", "Tunnel-Reject", "Tunnel-Link-Start", "Tunnel-Link-Stop", "Tunnel-Link-Reject", "Failed", }; /* Acct-Authentic Accounting Attribute standard values */ static const char *acct_auth[]={ NULL, "RADIUS", "Local", "Remote", }; /* Acct-Terminate-Cause Accounting Attribute standard values */ static const char *acct_term[]={ NULL, "User Request", "Lost Carrier", "Lost Service", "Idle Timeout", "Session Timeout", "Admin Reset", "Admin Reboot", "Port Error", "NAS Error", "NAS Request", "NAS Reboot", "Port Unneeded", "Port Preempted", "Port Suspended", "Service Unavailable", "Callback", "User Error", "Host Request", }; /* Tunnel-Type Attribute standard values */ static const char *tunnel_type[]={ NULL, "PPTP", "L2F", "L2TP", "ATMP", "VTP", "AH", "IP-IP", "MIN-IP-IP", "ESP", "GRE", "DVS", "IP-in-IP Tunneling", }; /* Tunnel-Medium-Type Attribute standard values */ static const char *tunnel_medium[]={ NULL, "IPv4", "IPv6", "NSAP", "HDLC", "BBN 1822", "802", "E.163", "E.164", "F.69", "X.121", "IPX", "Appletalk", "Decnet IV", "Banyan Vines", "E.164 with NSAP subaddress", }; /* ARAP-Zone-Access Attribute standard values */ static const char *arap_zone[]={ NULL, "Only access to dfl zone", "Use zone filter inc.", "Not used", "Use zone filter exc.", }; static const char *prompt[]={ "No Echo", "Echo", }; struct attrtype { const char *name; /* Attribute name */ const char **subtypes; /* Standard Values (if any) */ u_char siz_subtypes; /* Size of total standard values */ u_char first_subtype; /* First standard value is 0 or 1 */ void (*print_func)(register u_char *, u_int, u_short ); } attr_type[]= { { NULL, NULL, 0, 0, NULL }, { "Username", NULL, 0, 0, print_attr_string }, { "Password", NULL, 0, 0, NULL }, { "CHAP Password", NULL, 0, 0, NULL }, { "NAS IP Address", NULL, 0, 0, print_attr_address }, { "NAS Port", NULL, 0, 0, print_attr_num }, { "Service Type", serv_type, TAM_SIZE(serv_type)-1, 1, print_attr_num }, { "Framed Protocol", frm_proto, TAM_SIZE(frm_proto)-1, 1, print_attr_num }, { "Framed IP Address", NULL, 0, 0, print_attr_address }, { "Framed IP Network", NULL, 0, 0, print_attr_address }, { "Framed Routing", frm_routing, TAM_SIZE(frm_routing), 0, print_attr_num }, { "Filter ID", NULL, 0, 0, print_attr_string }, { "Framed MTU", NULL, 0, 0, print_attr_num }, { "Framed Compression", frm_comp, TAM_SIZE(frm_comp), 0, print_attr_num }, { "Login IP Host", NULL, 0, 0, print_attr_address }, { "Login Service", login_serv, TAM_SIZE(login_serv), 0, print_attr_num }, { "Login TCP Port", NULL, 0, 0, print_attr_num }, { "Unassigned", NULL, 0, 0, NULL }, /*17*/ { "Reply", NULL, 0, 0, print_attr_string }, { "Callback-number", NULL, 0, 0, print_attr_string }, { "Callback-ID", NULL, 0, 0, print_attr_string }, { "Unassigned", NULL, 0, 0, NULL }, /*21*/ { "Framed Route", NULL, 0, 0, print_attr_string }, { "Framed IPX Network", NULL, 0, 0, print_attr_num }, { "State", NULL, 0, 0, print_attr_string }, { "Class", NULL, 0, 0, print_attr_string }, { "Vendor Specific", NULL, 0, 0, print_vendor_attr }, { "Session Timeout", NULL, 0, 0, print_attr_num }, { "Idle Timeout", NULL, 0, 0, print_attr_num }, { "Termination Action", term_action, TAM_SIZE(term_action), 0, print_attr_num }, { "Called Station", NULL, 0, 0, print_attr_string }, { "Calling Station", NULL, 0, 0, print_attr_string }, { "NAS ID", NULL, 0, 0, print_attr_string }, { "Proxy State", NULL, 0, 0, print_attr_string }, { "Login LAT Service", NULL, 0, 0, print_attr_string }, { "Login LAT Node", NULL, 0, 0, print_attr_string }, { "Login LAT Group", NULL, 0, 0, print_attr_string }, { "Framed Appletalk Link", NULL, 0, 0, print_attr_num }, { "Framed Appltalk Net", NULL, 0, 0, print_attr_num }, { "Framed Appletalk Zone", NULL, 0, 0, print_attr_string }, { "Accounting Status", acct_status, TAM_SIZE(acct_status)-1, 1, print_attr_num }, { "Accounting Delay", NULL, 0, 0, print_attr_num }, { "Accounting Input Octets", NULL, 0, 0, print_attr_num }, { "Accounting Output Octets", NULL, 0, 0, print_attr_num }, { "Accounting Session ID", NULL, 0, 0, print_attr_string }, { "Accounting Authentication", acct_auth, TAM_SIZE(acct_auth)-1, 1, print_attr_num }, { "Accounting Session Time", NULL, 0, 0, print_attr_num }, { "Accounting Input Packets", NULL, 0, 0, print_attr_num }, { "Accounting Output Packets", NULL, 0, 0, print_attr_num }, { "Accounting Termination Cause", acct_term, TAM_SIZE(acct_term)-1, 1, print_attr_num }, { "Accounting Multilink Session ID", NULL, 0, 0, print_attr_string }, { "Accounting Link Count", NULL, 0, 0, print_attr_num }, { "Accounting Input Giga", NULL, 0, 0, print_attr_num }, { "Accounting Output Giga", NULL, 0, 0, print_attr_num }, { "Unassigned", NULL, 0, 0, NULL }, /*54*/ { "Event Timestamp", NULL, 0, 0, print_attr_time }, { "Unassigned", NULL, 0, 0, NULL }, /*56*/ { "Unassigned", NULL, 0, 0, NULL }, /*57*/ { "Unassigned", NULL, 0, 0, NULL }, /*58*/ { "Unassigned", NULL, 0, 0, NULL }, /*59*/ { "CHAP challenge", NULL, 0, 0, print_attr_string }, { "NAS Port Type", nas_port_type, TAM_SIZE(nas_port_type), 0, print_attr_num }, { "Port Limit", NULL, 0, 0, print_attr_num }, { "Login LAT Port", NULL, 0, 0, print_attr_string }, /*63*/ { "Tunnel Type", tunnel_type, TAM_SIZE(tunnel_type)-1, 1, print_attr_num }, { "Tunnel Medium", tunnel_medium, TAM_SIZE(tunnel_medium)-1, 1, print_attr_num }, { "Tunnel Client End", NULL, 0, 0, print_attr_string }, { "Tunnel Server End", NULL, 0, 0, print_attr_string }, { "Accounting Tunnel connect", NULL, 0, 0, print_attr_string }, { "Tunnel Password", NULL, 0, 0, print_attr_string }, { "ARAP Password", NULL, 0, 0, print_attr_strange }, { "ARAP Feature", NULL, 0, 0, print_attr_strange }, { "ARAP Zone Acces", arap_zone, TAM_SIZE(arap_zone)-1, 1, print_attr_num }, /*72*/ { "ARAP Security", NULL, 0, 0, print_attr_string }, { "ARAP Security Data", NULL, 0, 0, print_attr_string }, { "Password Retry", NULL, 0, 0, print_attr_num }, { "Prompt", prompt, TAM_SIZE(prompt), 0, print_attr_num }, { "Connect Info", NULL, 0, 0, print_attr_string }, { "Config Token", NULL, 0, 0, print_attr_string }, { "EAP Message", NULL, 0, 0, print_attr_string }, { "Message Authentication", NULL, 0, 0, print_attr_string }, /*80*/ { "Tunnel Private Group", NULL, 0, 0, print_attr_string }, { "Tunnel Assigned ID", NULL, 0, 0, print_attr_string }, { "Tunnel Preference", NULL, 0, 0, print_attr_num }, { "ARAP Challenge Response", NULL, 0, 0, print_attr_strange }, { "Accounting Interim Interval", NULL, 0, 0, print_attr_num }, { "Accounting Tunnel packets lost", NULL, 0, 0, print_attr_num }, /*86*/ { "NAS Port ID", NULL, 0, 0, print_attr_string }, { "Framed Pool", NULL, 0, 0, print_attr_string }, { "Unassigned", NULL, 0, 0, NULL }, { "Tunnel Client Authentication ID", NULL, 0, 0, print_attr_string }, { "Tunnel Server Authentication ID", NULL, 0, 0, print_attr_string }, { "Unassigned", NULL, 0, 0, NULL }, /*92*/ { "Unassigned", NULL, 0, 0, NULL } /*93*/ }; /*****************************/ /* Print an attribute string */ /* value pointed by 'data' */ /* and 'length' size. */ /*****************************/ /* Returns nothing. */ /*****************************/ static void print_attr_string(register u_char *data, u_int length, u_short attr_code ) { register u_int i; TCHECK2(data[0],length); switch(attr_code) { case TUNNEL_PASS: if (length < 3) { printf(" [|radius]"); return; } if (*data && (*data <=0x1F) ) printf("Tag %u, ",*data); data++; length--; printf("Salt %u ",EXTRACT_16BITS(data) ); data+=2; length-=2; break; case TUNNEL_CLIENT_END: case TUNNEL_SERVER_END: case TUNNEL_PRIV_GROUP: case TUNNEL_ASSIGN_ID: case TUNNEL_CLIENT_AUTH: case TUNNEL_SERVER_AUTH: if (*data <= 0x1F) { if (length < 1) { printf(" [|radius]"); return; } printf("Tag %u",*data); data++; length--; } break; } for (i=0; *data && i < length ; i++, data++) printf("%c",(*data < 32 || *data > 128) ? '.' : *data ); return; trunc: printf(" [|radius]"); } /* * print vendor specific attributes */ static void print_vendor_attr(register u_char *data, u_int length, u_short attr_code _U_) { u_int idx; u_int vendor_id; u_int vendor_type; u_int vendor_length; if (length < 4) goto trunc; TCHECK2(*data, 4); vendor_id = EXTRACT_32BITS(data); data+=4; length-=4; printf("Vendor: %s (%u)", tok2str(smi_values,"Unknown",vendor_id), vendor_id); while (length >= 2) { TCHECK2(*data, 2); vendor_type = *(data); vendor_length = *(data+1); if (vendor_length < 2) { printf("\n\t Vendor Attribute: %u, Length: %u (bogus, must be >= 2)", vendor_type, vendor_length); return; } if (vendor_length > length) { printf("\n\t Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)", vendor_type, vendor_length); return; } data+=2; vendor_length-=2; length-=2; TCHECK2(*data, vendor_length); printf("\n\t Vendor Attribute: %u, Length: %u, Value: ", vendor_type, vendor_length); for (idx = 0; idx < vendor_length ; idx++, data++) printf("%c",(*data < 32 || *data > 128) ? '.' : *data ); length-=vendor_length; } return; trunc: printf(" [|radius]"); } /******************************/ /* Print an attribute numeric */ /* value pointed by 'data' */ /* and 'length' size. */ /******************************/ /* Returns nothing. */ /******************************/ static void print_attr_num(register u_char *data, u_int length, u_short attr_code ) { u_int8_t tag; u_int32_t timeout; if (length != 4) { printf("ERROR: length %u != 4", length); return; } TCHECK2(data[0],4); /* This attribute has standard values */ if (attr_type[attr_code].siz_subtypes) { static const char **table; u_int32_t data_value; table = attr_type[attr_code].subtypes; if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) ) { if (!*data) printf("Tag[Unused]"); else printf("Tag[%d]", *data); data++; data_value = EXTRACT_24BITS(data); } else { data_value = EXTRACT_32BITS(data); } if ( data_value <= (u_int32_t)(attr_type[attr_code].siz_subtypes - 1 + attr_type[attr_code].first_subtype) && data_value >= attr_type[attr_code].first_subtype ) printf("%s",table[data_value]); else printf("#%u",data_value); } else { switch(attr_code) /* Be aware of special cases... */ { case FRM_IPX: if (EXTRACT_32BITS( data) == 0xFFFFFFFE ) printf("NAS Select"); else printf("%d",EXTRACT_32BITS( data) ); break; case SESSION_TIMEOUT: case IDLE_TIMEOUT: case ACCT_DELAY: case ACCT_SESSION_TIME: case ACCT_INT_INTERVAL: timeout = EXTRACT_32BITS( data); if ( timeout < 60 ) printf( "%02d secs", timeout); else { if ( timeout < 3600 ) printf( "%02d:%02d min", timeout / 60, timeout % 60); else printf( "%02d:%02d:%02d hours", timeout / 3600, (timeout % 3600) / 60, timeout % 60); } break; case FRM_ATALK_LINK: if (EXTRACT_32BITS(data) ) printf("%d",EXTRACT_32BITS(data) ); else printf("Unnumbered" ); break; case FRM_ATALK_NETWORK: if (EXTRACT_32BITS(data) ) printf("%d",EXTRACT_32BITS(data) ); else printf("NAS assigned" ); break; case TUNNEL_PREFERENCE: tag = *data; data++; if (tag == 0) printf("Tag (Unused) %d",EXTRACT_24BITS(data) ); else printf("Tag (%d) %d", tag, EXTRACT_24BITS(data) ); break; default: printf("%d",EXTRACT_32BITS( data) ); break; } /* switch */ } /* if-else */ return; trunc: printf(" [|radius]"); } /*****************************/ /* Print an attribute IPv4 */ /* address value pointed by */ /* 'data' and 'length' size. */ /*****************************/ /* Returns nothing. */ /*****************************/ static void print_attr_address(register u_char *data, u_int length, u_short attr_code ) { if (length != 4) { printf("ERROR: length %u != 4", length); return; } TCHECK2(data[0],4); switch(attr_code) { case FRM_IPADDR: case LOG_IPHOST: if (EXTRACT_32BITS(data) == 0xFFFFFFFF ) printf("User Selected"); else if (EXTRACT_32BITS(data) == 0xFFFFFFFE ) printf("NAS Select"); else printf("%s",ipaddr_string(data)); break; default: printf("%s",ipaddr_string(data) ); break; } return; trunc: printf(" [|radius]"); } /*************************************/ /* Print an attribute of 'secs since */ /* January 1, 1970 00:00 UTC' value */ /* pointed by 'data' and 'length' */ /* size. */ /*************************************/ /* Returns nothing. */ /*************************************/ static void print_attr_time(register u_char *data, u_int length, u_short attr_code _U_) { time_t attr_time; char string[26]; if (length != 4) { printf("ERROR: length %u != 4", length); return; } TCHECK2(data[0],4); attr_time = EXTRACT_32BITS(data); strlcpy(string, ctime(&attr_time), sizeof(string)); /* Get rid of the newline */ string[24] = '\0'; printf("%.24s", string); return; trunc: printf(" [|radius]"); } /***********************************/ /* Print an attribute of 'strange' */ /* data format pointed by 'data' */ /* and 'length' size. */ /***********************************/ /* Returns nothing. */ /***********************************/ static void print_attr_strange(register u_char *data, u_int length, u_short attr_code) { u_short len_data; switch(attr_code) { case ARAP_PASS: if (length != 16) { printf("ERROR: length %u != 16", length); return; } printf("User_challenge ("); TCHECK2(data[0],8); len_data = 8; PRINT_HEX(len_data, data); printf(") User_resp("); TCHECK2(data[0],8); len_data = 8; PRINT_HEX(len_data, data); printf(")"); break; case ARAP_FEATURES: if (length != 14) { printf("ERROR: length %u != 14", length); return; } TCHECK2(data[0],1); if (*data) printf("User can change password"); else printf("User cannot change password"); data++; TCHECK2(data[0],1); printf(", Min password length: %d",*data); data++; printf(", created at: "); TCHECK2(data[0],4); len_data = 4; PRINT_HEX(len_data, data); printf(", expires in: "); TCHECK2(data[0],4); len_data = 4; PRINT_HEX(len_data, data); printf(", Current Time: "); TCHECK2(data[0],4); len_data = 4; PRINT_HEX(len_data, data); break; case ARAP_CHALLENGE_RESP: if (length < 8) { printf("ERROR: length %u != 8", length); return; } TCHECK2(data[0],8); len_data = 8; PRINT_HEX(len_data, data); break; } return; trunc: printf(" [|radius]"); } static void radius_attrs_print(register const u_char *attr, u_int length) { register const struct radius_attr *rad_attr = (struct radius_attr *)attr; const char *attr_string; while (length > 0) { if (length < 2) goto trunc; TCHECK(*rad_attr); if (rad_attr->type > 0 && rad_attr->type < TAM_SIZE(attr_type)) attr_string = attr_type[rad_attr->type].name; else attr_string = "Unknown"; if (rad_attr->len < 2) { printf("\n\t %s Attribute (%u), length: %u (bogus, must be >= 2)", attr_string, rad_attr->type, rad_attr->len); return; } if (rad_attr->len > length) { printf("\n\t %s Attribute (%u), length: %u (bogus, goes past end of packet)", attr_string, rad_attr->type, rad_attr->len); return; } printf("\n\t %s Attribute (%u), length: %u, Value: ", attr_string, rad_attr->type, rad_attr->len); if (rad_attr->type < TAM_SIZE(attr_type)) { if (rad_attr->len > 2) { if ( attr_type[rad_attr->type].print_func ) (*attr_type[rad_attr->type].print_func)( ((u_char *)(rad_attr+1)), rad_attr->len - 2, rad_attr->type); } } /* do we also want to see a hex dump ? */ if (vflag> 1) print_unknown_data((u_char *)rad_attr+2,"\n\t ",(rad_attr->len)-2); length-=(rad_attr->len); rad_attr = (struct radius_attr *)( ((char *)(rad_attr))+rad_attr->len); } return; trunc: printf(" [|radius]"); } void radius_print(const u_char *dat, u_int length) { register const struct radius_hdr *rad; u_int len, auth_idx; TCHECK2(*dat, MIN_RADIUS_LEN); rad = (struct radius_hdr *)dat; len = EXTRACT_16BITS(&rad->len); if (len < MIN_RADIUS_LEN) { printf(" [|radius]"); return; } if (len > length) len = length; if (vflag < 1) { printf("RADIUS, %s (%u), id: 0x%02x length: %u", tok2str(radius_command_values,"Unknown Command",rad->code), rad->code, rad->id, len); return; } else { printf("RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ", len, tok2str(radius_command_values,"Unknown Command",rad->code), rad->code, rad->id); for(auth_idx=0; auth_idx < 16; auth_idx++) printf("%02x", rad->auth[auth_idx] ); } if (len > MIN_RADIUS_LEN) radius_attrs_print( dat + MIN_RADIUS_LEN, len - MIN_RADIUS_LEN); return; trunc: printf(" [|radius]"); } tcpdump-4.5.1/print-ip.c0000644000026300017510000004034712237020316012530 0ustar mcr/* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.159 2007-09-14 01:29:28 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "addrtoname.h" #include "interface.h" #include "extract.h" /* must come after interface.h */ #include "ip.h" #include "ipproto.h" static const struct tok ip_option_values[] = { { IPOPT_EOL, "EOL" }, { IPOPT_NOP, "NOP" }, { IPOPT_TS, "timestamp" }, { IPOPT_SECURITY, "security" }, { IPOPT_RR, "RR" }, { IPOPT_SSRR, "SSRR" }, { IPOPT_LSRR, "LSRR" }, { IPOPT_RA, "RA" }, { IPOPT_RFC1393, "traceroute" }, { 0, NULL } }; /* * print the recorded route in an IP RR, LSRR or SSRR option. */ static void ip_printroute(register const u_char *cp, u_int length) { register u_int ptr; register u_int len; if (length < 3) { printf(" [bad length %u]", length); return; } if ((length + 1) & 3) printf(" [bad length %u]", length); ptr = cp[2] - 1; if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1) printf(" [bad ptr %u]", cp[2]); for (len = 3; len < length; len += 4) { printf(" %s", ipaddr_string(&cp[len])); if (ptr > len) printf(","); } } /* * If source-routing is present and valid, return the final destination. * Otherwise, return IP destination. * * This is used for UDP and TCP pseudo-header in the checksum * calculation. */ static u_int32_t ip_finddst(const struct ip *ip) { int length; int len; const u_char *cp; u_int32_t retval; cp = (const u_char *)(ip + 1); length = (IP_HL(ip) << 2) - sizeof(struct ip); for (; length > 0; cp += len, length -= len) { int tt; TCHECK(*cp); tt = *cp; if (tt == IPOPT_EOL) break; else if (tt == IPOPT_NOP) len = 1; else { TCHECK(cp[1]); len = cp[1]; if (len < 2) break; } TCHECK2(*cp, len); switch (tt) { case IPOPT_SSRR: case IPOPT_LSRR: if (len < 7) break; memcpy(&retval, cp + len - 4, 4); return retval; } } trunc: memcpy(&retval, &ip->ip_dst.s_addr, sizeof(u_int32_t)); return retval; } /* * Compute a V4-style checksum by building a pseudoheader. */ int nextproto4_cksum(const struct ip *ip, const u_int8_t *data, u_int len, u_int next_proto) { struct phdr { u_int32_t src; u_int32_t dst; u_char mbz; u_char proto; u_int16_t len; } ph; struct cksum_vec vec[2]; /* pseudo-header.. */ ph.len = htons((u_int16_t)len); ph.mbz = 0; ph.proto = next_proto; memcpy(&ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); if (IP_HL(ip) == 5) memcpy(&ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); else ph.dst = ip_finddst(ip); vec[0].ptr = (const u_int8_t *)(void *)&ph; vec[0].len = sizeof(ph); vec[1].ptr = data; vec[1].len = len; return (in_cksum(vec, 2)); } static void ip_printts(register const u_char *cp, u_int length) { register u_int ptr; register u_int len; int hoplen; const char *type; if (length < 4) { printf("[bad length %u]", length); return; } printf(" TS{"); hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4; if ((length - 4) & (hoplen-1)) printf("[bad length %u]", length); ptr = cp[2] - 1; len = 0; if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1) printf("[bad ptr %u]", cp[2]); switch (cp[3]&0xF) { case IPOPT_TS_TSONLY: printf("TSONLY"); break; case IPOPT_TS_TSANDADDR: printf("TS+ADDR"); break; /* * prespecified should really be 3, but some ones might send 2 * instead, and the IPOPT_TS_PRESPEC constant can apparently * have both values, so we have to hard-code it here. */ case 2: printf("PRESPEC2.0"); break; case 3: /* IPOPT_TS_PRESPEC */ printf("PRESPEC"); break; default: printf("[bad ts type %d]", cp[3]&0xF); goto done; } type = " "; for (len = 4; len < length; len += hoplen) { if (ptr == len) type = " ^ "; printf("%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]), hoplen!=8 ? "" : ipaddr_string(&cp[len])); type = " "; } done: printf("%s", ptr == len ? " ^ " : ""); if (cp[3]>>4) printf(" [%d hops not recorded]} ", cp[3]>>4); else printf("}"); } /* * print IP options. */ static void ip_optprint(register const u_char *cp, u_int length) { register u_int option_len; const char *sep = ""; for (; length > 0; cp += option_len, length -= option_len) { u_int option_code; printf("%s", sep); sep = ","; TCHECK(*cp); option_code = *cp; printf("%s", tok2str(ip_option_values,"unknown %u",option_code)); if (option_code == IPOPT_NOP || option_code == IPOPT_EOL) option_len = 1; else { TCHECK(cp[1]); option_len = cp[1]; if (option_len < 2) { printf(" [bad length %u]", option_len); return; } } if (option_len > length) { printf(" [bad length %u]", option_len); return; } TCHECK2(*cp, option_len); switch (option_code) { case IPOPT_EOL: return; case IPOPT_TS: ip_printts(cp, option_len); break; case IPOPT_RR: /* fall through */ case IPOPT_SSRR: case IPOPT_LSRR: ip_printroute(cp, option_len); break; case IPOPT_RA: if (option_len < 4) { printf(" [bad length %u]", option_len); break; } TCHECK(cp[3]); if (EXTRACT_16BITS(&cp[2]) != 0) printf(" value %u", EXTRACT_16BITS(&cp[2])); break; case IPOPT_NOP: /* nothing to print - fall through */ case IPOPT_SECURITY: default: break; } } return; trunc: printf("[|ip]"); } #define IP_RES 0x8000 static const struct tok ip_frag_values[] = { { IP_MF, "+" }, { IP_DF, "DF" }, { IP_RES, "rsvd" }, /* The RFC3514 evil ;-) bit */ { 0, NULL } }; struct ip_print_demux_state { const struct ip *ip; const u_char *cp; u_int len, off; u_char nh; int advance; }; static void ip_print_demux(netdissect_options *ndo, struct ip_print_demux_state *ipds) { struct protoent *proto; struct cksum_vec vec[1]; again: switch (ipds->nh) { case IPPROTO_AH: ipds->nh = *ipds->cp; ipds->advance = ah_print(ipds->cp); if (ipds->advance <= 0) break; ipds->cp += ipds->advance; ipds->len -= ipds->advance; goto again; case IPPROTO_ESP: { int enh, padlen; ipds->advance = esp_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip, &enh, &padlen); if (ipds->advance <= 0) break; ipds->cp += ipds->advance; ipds->len -= ipds->advance + padlen; ipds->nh = enh & 0xff; goto again; } case IPPROTO_IPCOMP: { int enh; ipds->advance = ipcomp_print(ipds->cp, &enh); if (ipds->advance <= 0) break; ipds->cp += ipds->advance; ipds->len -= ipds->advance; ipds->nh = enh & 0xff; goto again; } case IPPROTO_SCTP: sctp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len); break; case IPPROTO_DCCP: dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len); break; case IPPROTO_TCP: /* pass on the MF bit plus the offset to detect fragments */ tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, ipds->off & (IP_MF|IP_OFFMASK)); break; case IPPROTO_UDP: /* pass on the MF bit plus the offset to detect fragments */ udp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, ipds->off & (IP_MF|IP_OFFMASK)); break; case IPPROTO_ICMP: /* pass on the MF bit plus the offset to detect fragments */ icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, ipds->off & (IP_MF|IP_OFFMASK)); break; case IPPROTO_PIGP: /* * XXX - the current IANA protocol number assignments * page lists 9 as "any private interior gateway * (used by Cisco for their IGRP)" and 88 as * "EIGRP" from Cisco. * * Recent BSD headers define * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88. * We define IP_PROTO_PIGP as 9 and * IP_PROTO_EIGRP as 88; those names better * match was the current protocol number * assignments say. */ igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip); break; case IPPROTO_EIGRP: eigrp_print(ipds->cp, ipds->len); break; case IPPROTO_ND: ND_PRINT((ndo, " nd %d", ipds->len)); break; case IPPROTO_EGP: egp_print(ipds->cp, ipds->len); break; case IPPROTO_OSPF: ospf_print(ipds->cp, ipds->len, (const u_char *)ipds->ip); break; case IPPROTO_IGMP: igmp_print(ipds->cp, ipds->len); break; case IPPROTO_IPV4: /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ ip_print(ndo, ipds->cp, ipds->len); if (! vflag) { ND_PRINT((ndo, " (ipip-proto-4)")); return; } break; #ifdef INET6 case IPPROTO_IPV6: /* ip6-in-ip encapsulation */ ip6_print(ndo, ipds->cp, ipds->len); break; #endif /*INET6*/ case IPPROTO_RSVP: rsvp_print(ipds->cp, ipds->len); break; case IPPROTO_GRE: /* do it */ gre_print(ipds->cp, ipds->len); break; case IPPROTO_MOBILE: mobile_print(ipds->cp, ipds->len); break; case IPPROTO_PIM: vec[0].ptr = ipds->cp; vec[0].len = ipds->len; pim_print(ipds->cp, ipds->len, in_cksum(vec, 1)); break; case IPPROTO_VRRP: if (packettype == PT_CARP) { if (vflag) (void)printf("carp %s > %s: ", ipaddr_string(&ipds->ip->ip_src), ipaddr_string(&ipds->ip->ip_dst)); carp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl); } else { if (vflag) (void)printf("vrrp %s > %s: ", ipaddr_string(&ipds->ip->ip_src), ipaddr_string(&ipds->ip->ip_dst)); vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl); } break; case IPPROTO_PGM: pgm_print(ipds->cp, ipds->len, (const u_char *)ipds->ip); break; default: if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL) ND_PRINT((ndo, " %s", proto->p_name)); else ND_PRINT((ndo, " ip-proto-%d", ipds->nh)); ND_PRINT((ndo, " %d", ipds->len)); break; } } void ip_print_inner(netdissect_options *ndo, const u_char *bp, u_int length, u_int nh, const u_char *bp2) { struct ip_print_demux_state ipd; ipd.ip = (const struct ip *)bp2; ipd.cp = bp; ipd.len = length; ipd.off = 0; ipd.nh = nh; ipd.advance = 0; ip_print_demux(ndo, &ipd); } /* * print an IP datagram. */ void ip_print(netdissect_options *ndo, const u_char *bp, u_int length) { struct ip_print_demux_state ipd; struct ip_print_demux_state *ipds=&ipd; const u_char *ipend; u_int hlen; struct cksum_vec vec[1]; u_int16_t sum, ip_sum; struct protoent *proto; ipds->ip = (const struct ip *)bp; if (IP_V(ipds->ip) != 4) { /* print version if != 4 */ printf("IP%u ", IP_V(ipds->ip)); if (IP_V(ipds->ip) == 6) printf(", wrong link-layer encapsulation"); } else if (!eflag) printf("IP "); if ((u_char *)(ipds->ip + 1) > ndo->ndo_snapend) { printf("[|ip]"); return; } if (length < sizeof (struct ip)) { (void)printf("truncated-ip %u", length); return; } hlen = IP_HL(ipds->ip) * 4; if (hlen < sizeof (struct ip)) { (void)printf("bad-hlen %u", hlen); return; } ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len); if (length < ipds->len) (void)printf("truncated-ip - %u bytes missing! ", ipds->len - length); if (ipds->len < hlen) { #ifdef GUESS_TSO if (ipds->len) { (void)printf("bad-len %u", ipds->len); return; } else { /* we guess that it is a TSO send */ ipds->len = length; } #else (void)printf("bad-len %u", ipds->len); return; #endif /* GUESS_TSO */ } /* * Cut off the snapshot length to the end of the IP payload. */ ipend = bp + ipds->len; if (ipend < ndo->ndo_snapend) ndo->ndo_snapend = ipend; ipds->len -= hlen; ipds->off = EXTRACT_16BITS(&ipds->ip->ip_off); if (vflag) { (void)printf("(tos 0x%x", (int)ipds->ip->ip_tos); /* ECN bits */ if (ipds->ip->ip_tos & 0x03) { switch (ipds->ip->ip_tos & 0x03) { case 1: (void)printf(",ECT(1)"); break; case 2: (void)printf(",ECT(0)"); break; case 3: (void)printf(",CE"); } } if (ipds->ip->ip_ttl >= 1) (void)printf(", ttl %u", ipds->ip->ip_ttl); /* * for the firewall guys, print id, offset. * On all but the last stick a "+" in the flags portion. * For unfragmented datagrams, note the don't fragment flag. */ (void)printf(", id %u, offset %u, flags [%s], proto %s (%u)", EXTRACT_16BITS(&ipds->ip->ip_id), (ipds->off & 0x1fff) * 8, bittok2str(ip_frag_values, "none", ipds->off&0xe000), tok2str(ipproto_values,"unknown",ipds->ip->ip_p), ipds->ip->ip_p); (void)printf(", length %u", EXTRACT_16BITS(&ipds->ip->ip_len)); if ((hlen - sizeof(struct ip)) > 0) { printf(", options ("); ip_optprint((u_char *)(ipds->ip + 1), hlen - sizeof(struct ip)); printf(")"); } if (!Kflag && (u_char *)ipds->ip + hlen <= ndo->ndo_snapend) { vec[0].ptr = (const u_int8_t *)(void *)ipds->ip; vec[0].len = hlen; sum = in_cksum(vec, 1); if (sum != 0) { ip_sum = EXTRACT_16BITS(&ipds->ip->ip_sum); (void)printf(", bad cksum %x (->%x)!", ip_sum, in_cksum_shouldbe(ip_sum, sum)); } } printf(")\n "); } /* * If this is fragment zero, hand it to the next higher * level protocol. */ if ((ipds->off & 0x1fff) == 0) { ipds->cp = (const u_char *)ipds->ip + hlen; ipds->nh = ipds->ip->ip_p; if (ipds->nh != IPPROTO_TCP && ipds->nh != IPPROTO_UDP && ipds->nh != IPPROTO_SCTP && ipds->nh != IPPROTO_DCCP) { (void)printf("%s > %s: ", ipaddr_string(&ipds->ip->ip_src), ipaddr_string(&ipds->ip->ip_dst)); } ip_print_demux(ndo, ipds); } else { /* Ultra quiet now means that all this stuff should be suppressed */ if (qflag > 1) return; /* * if this isn't the first frag, we're missing the * next level protocol header. print the ip addr * and the protocol. */ if (ipds->off & 0x1fff) { (void)printf("%s > %s:", ipaddr_string(&ipds->ip->ip_src), ipaddr_string(&ipds->ip->ip_dst)); if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL) (void)printf(" %s", proto->p_name); else (void)printf(" ip-proto-%d", ipds->ip->ip_p); } } } 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 (gndo, bp, length); return; #ifdef INET6 case 6: ip6_print (gndo, bp, length); return; #endif default: (void)printf("unknown ip %d", IP_V(&hdr)); return; } } /* * Local Variables: * c-style: whitesmith * c-basic-offset: 8 * End: */ tcpdump-4.5.1/print-otv.c0000644000026300017510000000414012237020316012717 0ustar mcr/* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * Original code by Francesco Fondelli (francesco dot fondelli, gmail dot com) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "interface.h" #include "extract.h" #include "addrtoname.h" #include "udp.h" /* * OTV header, draft-hasmit-otv-04 * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |R|R|R|R|I|R|R|R| Overlay ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Instance ID | Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ void otv_print(const u_char *bp, u_int len) { u_int8_t flags; u_int32_t overlay_id; u_int32_t instance_id; if (len < 8) { printf("[|OTV]"); return; } flags = *bp; bp += 1; overlay_id = EXTRACT_24BITS(bp); bp += 3; instance_id = EXTRACT_24BITS(bp); bp += 4; printf("OTV, "); fputs("flags [", stdout); if (flags & 0x08) fputs("I", stdout); else fputs(".", stdout); fputs("] ", stdout); printf("(0x%02x), ", flags); printf("overlay %u, ", overlay_id); printf("instance %u\n", instance_id); ether_print(gndo, bp, len - 8, len - 8, NULL, NULL); return; } tcpdump-4.5.1/print-calm-fast.c0000644000026300017510000000311512237020316013757 0ustar mcr/* * Copyright (c) 2013 The TCPDUMP project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * Original code by Ola Martin Lykkja (ola.lykkja@q-free.com) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "interface.h" #include "extract.h" #include "addrtoname.h" /* ISO 29281:2009 Intelligent Transport Systems . Communications access for land mobiles (CALM) CALM non-IP networking */ /* * This is the top level routine of the printer. 'bp' points * to the calm header of the packet. */ void calm_fast_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int length) { int srcNwref = bp[0]; int dstNwref = bp[1]; length -= 2; bp += 2; printf("CALM FAST src:%s; ", etheraddr_string(eth+6)); printf("SrcNwref:%d; ", srcNwref); printf("DstNwref:%d; ", dstNwref); if (ndo->ndo_vflag) default_print(bp, length); } /* * Local Variables: * c-style: whitesmith * c-basic-offset: 8 * End: */ tcpdump-4.5.1/pcap_dump_ftell.c0000644000026300017510000000271012237020316014114 0ustar mcr/* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/pcap_dump_ftell.c,v 1.1 2005-06-03 22:08:52 guy Exp $ (LBL)"; #endif #include #include #include "pcap-missing.h" long pcap_dump_ftell(pcap_dumper_t *p) { return (ftell((FILE *)p)); } tcpdump-4.5.1/addrtoname.h0000644000026300017510000000426412237020316013107 0ustar mcr/* * Copyright (c) 1990, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header: /tcpdump/master/tcpdump/addrtoname.h,v 1.20 2007-08-08 14:06:34 hannes Exp $ (LBL) */ /* Name to address translation routines. */ enum { LINKADDR_ETHER, LINKADDR_FRELAY, LINKADDR_IEEE1394, LINKADDR_ATM }; #define BUFSIZE 128 extern const char *linkaddr_string(const u_char *, const unsigned int, const unsigned int); extern const char *etheraddr_string(const u_char *); extern const char *le64addr_string(const u_char *); extern const char *etherproto_string(u_short); extern const char *tcpport_string(u_short); extern const char *udpport_string(u_short); extern const char *getname(const u_char *); #ifdef INET6 extern const char *getname6(const u_char *); #endif extern const char *intoa(u_int32_t); extern void init_addrtoname(u_int32_t, u_int32_t); extern struct hnamemem *newhnamemem(void); #ifdef INET6 extern struct h6namemem *newh6namemem(void); #endif #define ipaddr_string(p) getname((const u_char *)(p)) #ifdef INET6 #define ip6addr_string(p) getname6((const u_char *)(p)) #endif tcpdump-4.5.1/aclocal.m40000644000026300017510000012434612237020316012464 0ustar mcrdnl @(#) $Header: /tcpdump/master/tcpdump/aclocal.m4,v 1.116 2008-09-25 21:45:50 guy Exp $ (LBL) dnl dnl Copyright (c) 1995, 1996, 1997, 1998 dnl The Regents of the University of California. All rights reserved. dnl dnl Redistribution and use in source and binary forms, with or without dnl modification, are permitted provided that: (1) source code distributions dnl retain the above copyright notice and this paragraph in its entirety, (2) dnl distributions including binary code include the above copyright notice and dnl this paragraph in its entirety in the documentation or other materials dnl provided with the distribution, and (3) all advertising materials mentioning dnl features or use of this software display the following acknowledgement: dnl ``This product includes software developed by the University of California, dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of dnl the University nor the names of its contributors may be used to endorse dnl or promote products derived from this software without specific prior dnl written permission. dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. dnl dnl LBL autoconf macros dnl dnl dnl Do whatever AC_LBL_C_INIT work is necessary before using AC_PROG_CC. dnl dnl It appears that newer versions of autoconf (2.64 and later) will, dnl if you use AC_TRY_COMPILE in a macro, stick AC_PROG_CC at the dnl beginning of the macro, even if the macro itself calls AC_PROG_CC. dnl See the "Prerequisite Macros" and "Expanded Before Required" sections dnl in the Autoconf documentation. dnl dnl This causes a steaming heap of fail in our case, as we were, in dnl AC_LBL_C_INIT, doing the tests we now do in AC_LBL_C_INIT_BEFORE_CC, dnl calling AC_PROG_CC, and then doing the tests we now do in dnl AC_LBL_C_INIT. Now, we run AC_LBL_C_INIT_BEFORE_CC, AC_PROG_CC, dnl and AC_LBL_C_INIT at the top level. dnl AC_DEFUN(AC_LBL_C_INIT_BEFORE_CC, [ AC_BEFORE([$0], [AC_LBL_C_INIT]) AC_BEFORE([$0], [AC_PROG_CC]) AC_BEFORE([$0], [AC_LBL_FIXINCLUDES]) AC_BEFORE([$0], [AC_LBL_DEVEL]) AC_ARG_WITH(gcc, [ --without-gcc don't use gcc]) $1="" if test "${srcdir}" != "." ; then $1="-I$srcdir" fi if test "${CFLAGS+set}" = set; then LBL_CFLAGS="$CFLAGS" fi if test -z "$CC" ; then case "$host_os" in bsdi*) AC_CHECK_PROG(SHLICC2, shlicc2, yes, no) if test $SHLICC2 = yes ; then CC=shlicc2 export CC fi ;; esac fi if test -z "$CC" -a "$with_gcc" = no ; then CC=cc export CC fi ]) dnl dnl Determine which compiler we're using (cc or gcc) dnl If using gcc, determine the version number dnl If using cc: dnl require that it support ansi prototypes dnl use -O (AC_PROG_CC will use -g -O2 on gcc, so we don't need to dnl do that ourselves for gcc) dnl add -g flags, as appropriate dnl explicitly specify /usr/local/include dnl dnl NOTE WELL: with newer versions of autoconf, "gcc" means any compiler dnl that defines __GNUC__, which means clang, for example, counts as "gcc". dnl dnl usage: dnl dnl AC_LBL_C_INIT(copt, incls) dnl dnl results: dnl dnl $1 (copt set) dnl $2 (incls set) dnl CC dnl LDFLAGS dnl LBL_CFLAGS dnl AC_DEFUN(AC_LBL_C_INIT, [ AC_BEFORE([$0], [AC_LBL_FIXINCLUDES]) AC_BEFORE([$0], [AC_LBL_DEVEL]) AC_BEFORE([$0], [AC_LBL_SHLIBS_INIT]) if test "$GCC" = yes ; then # # -Werror forces warnings to be errors. # ac_lbl_cc_force_warning_errors=-Werror # # Use -ffloat-store so that, on 32-bit x86, we don't # do 80-bit arithmetic with the FPU; that way we should # get the same results for floating-point calculations # on x86-32 and x86-64. # AC_LBL_CHECK_COMPILER_OPT($1, -ffloat-store) else $2="$$2 -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" case "$host_os" in darwin*) # # This is assumed either to be GCC or clang, both # of which use -Werror to force warnings to be errors. # ac_lbl_cc_force_warning_errors=-Werror ;; hpux*) # # HP C, which is what we presume we're using, doesn't # exit with a non-zero exit status if we hand it an # invalid -W flag, can't be forced to do so even with # +We, and doesn't handle GCC-style -W flags, so we # don't want to try using GCC-style -W flags. # ac_lbl_cc_dont_try_gcc_dashW=yes ;; irix*) # # MIPS C, which is what we presume we're using, doesn't # necessarily exit with a non-zero exit status if we # hand it an invalid -W flag, can't be forced to do # so, and doesn't handle GCC-style -W flags, so we # don't want to try using GCC-style -W flags. # ac_lbl_cc_dont_try_gcc_dashW=yes # # It also, apparently, defaults to "char" being # unsigned, unlike most other C implementations; # I suppose we could say "signed char" whenever # we want to guarantee a signed "char", but let's # just force signed chars. # # -xansi is normally the default, but the # configure script was setting it; perhaps -cckr # was the default in the Old Days. (Then again, # that would probably be for backwards compatibility # in the days when ANSI C was Shiny and New, i.e. # 1989 and the early '90's, so maybe we can just # drop support for those compilers.) # # -g is equivalent to -g2, which turns off # optimization; we choose -g3, which generates # debugging information but doesn't turn off # optimization (even if the optimization would # cause inaccuracies in debugging). # $1="$$1 -xansi -signed -g3" ;; osf*) # # Presumed to be DEC OSF/1, Digital UNIX, or # Tru64 UNIX. # # The DEC C compiler, which is what we presume we're # using, doesn't exit with a non-zero exit status if we # hand it an invalid -W flag, can't be forced to do # so, and doesn't handle GCC-style -W flags, so we # don't want to try using GCC-style -W flags. # ac_lbl_cc_dont_try_gcc_dashW=yes # # -g is equivalent to -g2, which turns off # optimization; we choose -g3, which generates # debugging information but doesn't turn off # optimization (even if the optimization would # cause inaccuracies in debugging). # $1="$$1 -g3" ;; solaris*) # # Assumed to be Sun C, which requires -errwarn to force # warnings to be treated as errors. # ac_lbl_cc_force_warning_errors=-errwarn ;; ultrix*) AC_MSG_CHECKING(that Ultrix $CC hacks const in prototypes) AC_CACHE_VAL(ac_cv_lbl_cc_const_proto, AC_TRY_COMPILE( [#include ], [struct a { int b; }; void c(const struct a *)], ac_cv_lbl_cc_const_proto=yes, ac_cv_lbl_cc_const_proto=no)) AC_MSG_RESULT($ac_cv_lbl_cc_const_proto) if test $ac_cv_lbl_cc_const_proto = no ; then AC_DEFINE(const,[], [to handle Ultrix compilers that don't support const in prototypes]) fi ;; esac $1="$$1 -O" fi ]) dnl dnl Check whether the compiler option specified as the second argument dnl is supported by the compiler and, if so, add it to the macro dnl specified as the first argument dnl AC_DEFUN(AC_LBL_CHECK_COMPILER_OPT, [ AC_MSG_CHECKING([whether the compiler supports the $2 option]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors $2" AC_TRY_COMPILE( [], [return 0], [ AC_MSG_RESULT([yes]) CFLAGS="$save_CFLAGS" $1="$$1 $2" ], [ AC_MSG_RESULT([no]) CFLAGS="$save_CFLAGS" ]) ]) dnl dnl Check whether the compiler supports an option to generate dnl Makefile-style dependency lines dnl dnl GCC uses -M for this. Non-GCC compilers that support this dnl use a variety of flags, including but not limited to -M. dnl dnl We test whether the flag in question is supported, as older dnl versions of compilers might not support it. dnl dnl We don't try all the possible flags, just in case some flag means dnl "generate dependencies" on one compiler but means something else dnl on another compiler. dnl dnl Most compilers that support this send the output to the standard dnl output by default. IBM's XLC, however, supports -M but sends dnl the output to {sourcefile-basename}.u, and AIX has no /dev/stdout dnl to work around that, so we don't bother with XLC. dnl AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT, [ AC_MSG_CHECKING([whether the compiler supports generating dependencies]) if test "$GCC" = yes ; then # # GCC, or a compiler deemed to be GCC by AC_PROG_CC (even # though it's not); we assume that, in this case, the flag # would be -M. # ac_lbl_dependency_flag="-M" else # # Not GCC or a compiler deemed to be GCC; what platform is # this? (We're assuming that if the compiler isn't GCC # it's the compiler from the vendor of the OS; that won't # necessarily be true for x86 platforms, where it might be # the Intel C compiler.) # case "$host_os" in irix*|osf*|darwin*) # # MIPS C for IRIX, DEC C, and clang all use -M. # ac_lbl_dependency_flag="-M" ;; solaris*) # # Sun C uses -xM. # ac_lbl_dependency_flag="-xM" ;; hpux*) # # HP's older C compilers don't support this. # HP's newer C compilers support this with # either +M or +Make; the older compilers # interpret +M as something completely # different, so we use +Make so we don't # think it works with the older compilers. # ac_lbl_dependency_flag="+Make" ;; *) # # Not one of the above; assume no support for # generating dependencies. # ac_lbl_dependency_flag="" ;; esac fi # # Is ac_lbl_dependency_flag defined and, if so, does the compiler # complain about it? # # Note: clang doesn't seem to exit with an error status when handed # an unknown non-warning error, even if you pass it # -Werror=unknown-warning-option. However, it always supports # -M, so the fact that this test always succeeds with clang # isn't an issue. # if test ! -z "$ac_lbl_dependency_flag"; then AC_LANG_CONFTEST( [AC_LANG_SOURCE([[int main(void) { return 0; }]])]) echo "$CC" $ac_lbl_dependency_flag conftest.c >&5 if "$CC" $ac_lbl_dependency_flag conftest.c >/dev/null 2>&1; then AC_MSG_RESULT([yes, with $ac_lbl_dependency_flag]) DEPENDENCY_CFLAG="$ac_lbl_dependency_flag" MKDEP='${srcdir}/mkdep' else AC_MSG_RESULT([no]) # # We can't run mkdep, so have "make depend" do # nothing. # MKDEP=: fi rm -rf conftest* else AC_MSG_RESULT([no]) # # We can't run mkdep, so have "make depend" do # nothing. # MKDEP=: fi AC_SUBST(DEPENDENCY_CFLAG) AC_SUBST(MKDEP) ]) # # Try compiling a sample of the type of code that appears in # gencode.c with "inline", "__inline__", and "__inline". # # Autoconf's AC_C_INLINE, at least in autoconf 2.13, isn't good enough, # as it just tests whether a function returning "int" can be inlined; # at least some versions of HP's C compiler can inline that, but can't # inline a function that returns a struct pointer. # # Make sure we use the V_CCOPT flags, because some of those might # disable inlining. # AC_DEFUN(AC_LBL_C_INLINE, [AC_MSG_CHECKING(for inline) save_CFLAGS="$CFLAGS" CFLAGS="$V_CCOPT" AC_CACHE_VAL(ac_cv_lbl_inline, [ ac_cv_lbl_inline="" ac_lbl_cc_inline=no for ac_lbl_inline in inline __inline__ __inline do AC_TRY_COMPILE( [#define inline $ac_lbl_inline static inline struct iltest *foo(void); struct iltest { int iltest1; int iltest2; }; static inline struct iltest * foo() { static struct iltest xxx; return &xxx; }],,ac_lbl_cc_inline=yes,) if test "$ac_lbl_cc_inline" = yes ; then break; fi done if test "$ac_lbl_cc_inline" = yes ; then ac_cv_lbl_inline=$ac_lbl_inline fi]) CFLAGS="$save_CFLAGS" if test ! -z "$ac_cv_lbl_inline" ; then AC_MSG_RESULT($ac_cv_lbl_inline) else AC_MSG_RESULT(no) fi AC_DEFINE_UNQUOTED(inline, $ac_cv_lbl_inline, [Define as token for inline if inlining supported])]) dnl dnl Use pfopen.c if available and pfopen() not in standard libraries dnl Require libpcap dnl Look for libpcap in .. dnl Use the installed libpcap if there is no local version dnl dnl usage: dnl dnl AC_LBL_LIBPCAP(pcapdep, incls) dnl dnl results: dnl dnl $1 (pcapdep set) dnl $2 (incls appended) dnl LIBS dnl LBL_LIBS dnl AC_DEFUN(AC_LBL_LIBPCAP, [AC_REQUIRE([AC_LBL_LIBRARY_NET]) dnl dnl save a copy before locating libpcap.a dnl LBL_LIBS="$LIBS" pfopen=/usr/examples/packetfilter/pfopen.c if test -f $pfopen ; then AC_CHECK_FUNCS(pfopen) if test $ac_cv_func_pfopen = "no" ; then AC_MSG_RESULT(Using $pfopen) LIBS="$LIBS $pfopen" fi fi AC_MSG_CHECKING(for local pcap library) libpcap=FAIL lastdir=FAIL places=`ls $srcdir/.. | sed -e 's,/$,,' -e "s,^,$srcdir/../," | \ egrep '/libpcap-[[0-9]]+\.[[0-9]]+(\.[[0-9]]*)?([[ab]][[0-9]]*|-PRE-GIT)?$'` for dir in $places $srcdir/../libpcap $srcdir/libpcap ; do basedir=`echo $dir | sed -e 's/[[ab]][[0-9]]*$//' | \ sed -e 's/-PRE-GIT$//' ` if test $lastdir = $basedir ; then dnl skip alphas when an actual release is present continue; fi lastdir=$dir if test -r $dir/libpcap.a ; then libpcap=$dir/libpcap.a d=$dir dnl continue and select the last one that exists fi done if test $libpcap = FAIL ; then AC_MSG_RESULT(not found) # # Look for pcap-config. # AC_PATH_TOOL(PCAP_CONFIG, pcap-config) if test -n "$PCAP_CONFIG" ; then # # Found - use it to get the include flags for # libpcap and the flags to link with libpcap. # # Please read section 11.6 "Shell Substitutions" # in the autoconf manual before doing anything # to this that involves quoting. Especially note # the statement "There is just no portable way to use # double-quoted strings inside double-quoted back-quoted # expressions (pfew!)." # cflags=`"$PCAP_CONFIG" --cflags` $2="$cflags $$2" libpcap=`"$PCAP_CONFIG" --libs` else # # Not found; look for pcap. # AC_CHECK_LIB(pcap, main, libpcap="-lpcap") if test $libpcap = FAIL ; then AC_MSG_ERROR(see the INSTALL doc for more info) fi dnl dnl Some versions of Red Hat Linux put "pcap.h" in dnl "/usr/include/pcap"; had the LBL folks done so, dnl that would have been a good idea, but for dnl the Red Hat folks to do so just breaks source dnl compatibility with other systems. dnl dnl We work around this by assuming that, as we didn't dnl find a local libpcap, libpcap is in /usr/lib or dnl /usr/local/lib and that the corresponding header dnl file is under one of those directories; if we don't dnl find it in either of those directories, we check to dnl see if it's in a "pcap" subdirectory of them and, dnl if so, add that subdirectory to the "-I" list. dnl dnl (We now also put pcap.h in /usr/include/pcap, but we dnl leave behind a /usr/include/pcap.h that includes it, dnl so you can still just include .) dnl AC_MSG_CHECKING(for extraneous pcap header directories) if test \( ! -r /usr/local/include/pcap.h \) -a \ \( ! -r /usr/include/pcap.h \); then if test -r /usr/local/include/pcap/pcap.h; then d="/usr/local/include/pcap" elif test -r /usr/include/pcap/pcap.h; then d="/usr/include/pcap" fi fi if test -z "$d" ; then AC_MSG_RESULT(not found) else $2="-I$d $$2" AC_MSG_RESULT(found -- -I$d added) fi fi else $1=$libpcap places=`ls $srcdir/.. | sed -e 's,/$,,' -e "s,^,$srcdir/../," | \ egrep '/libpcap-[[0-9]]*.[[0-9]]*(.[[0-9]]*)?([[ab]][[0-9]]*)?$'` if test -r $d/pcap.h; then $2="-I$d $$2" elif test -r $places/pcap.h; then $2="-I$places $$2" else AC_MSG_ERROR(cannot find pcap.h, see INSTALL) fi AC_MSG_RESULT($libpcap) AC_PATH_PROG(PCAP_CONFIG, pcap-config,, $d) if test -n "$PCAP_CONFIG"; then # # The libpcap directory has a pcap-config script. # Use it to get any additioal libraries needed # to link with the libpcap archive library in # that directory. # # Please read section 11.6 "Shell Substitutions" # in the autoconf manual before doing anything # to this that involves quoting. Especially note # the statement "There is just no portable way to use # double-quoted strings inside double-quoted back-quoted # expressions (pfew!)." # additional_libs=`"$PCAP_CONFIG" --additional-libs --static` libpcap="$libpcap $additional_libs" fi fi LIBS="$libpcap $LIBS" if ! test -n "$PCAP_CONFIG" ; then # # We don't have pcap-config; find out any additional link flags # we need. (If we have pcap-config, we assume it tells us what # we need.) # case "$host_os" in aix*) # # If libpcap is DLPI-based, we have to use /lib/pse.exp if # present, as we use the STREAMS routines. # # (XXX - true only if we're linking with a static libpcap?) # pseexe="/lib/pse.exp" AC_MSG_CHECKING(for $pseexe) if test -f $pseexe ; then AC_MSG_RESULT(yes) LIBS="$LIBS -I:$pseexe" fi # # If libpcap is BPF-based, we need "-lodm" and "-lcfg", as # we use them to load the BPF module. # # (XXX - true only if we're linking with a static libpcap?) # LIBS="$LIBS -lodm -lcfg" ;; esac fi dnl dnl Check for "pcap_loop()", to make sure we found a working dnl libpcap and have all the right other libraries with which dnl to link. (Otherwise, the checks below will fail, not dnl because the routines are missing from the library, but dnl because we aren't linking properly with libpcap, and dnl that will cause confusing errors at build time.) dnl AC_CHECK_FUNC(pcap_loop,, [ AC_MSG_ERROR( [Report this to tcpdump-workers@lists.tcpdump.org, and include the config.log file in your report. If you have downloaded libpcap from tcpdump.org, and built it yourself, please also include the config.log file from the libpcap source directory, the Makefile from the libpcap source directory, and the output of the make process for libpcap, as this could be a problem with the libpcap that was built, and we will not be able to determine why this is happening, and thus will not be able to fix it, without that information, as we have not been able to reproduce this problem ourselves.]) ]) dnl dnl Check for "pcap_list_datalinks()", "pcap_set_datalink()", dnl and "pcap_datalink_name_to_val()", and use substitute versions dnl if they're not present. dnl AC_CHECK_FUNC(pcap_list_datalinks, AC_DEFINE(HAVE_PCAP_LIST_DATALINKS, 1, [define if libpcap has pcap_list_datalinks()]), [ AC_LIBOBJ(datalinks) ]) AC_CHECK_FUNC(pcap_set_datalink, AC_DEFINE(HAVE_PCAP_SET_DATALINK, 1, [define if libpcap has pcap_set_datalink()])) AC_CHECK_FUNC(pcap_datalink_name_to_val, [ AC_DEFINE(HAVE_PCAP_DATALINK_NAME_TO_VAL, 1, [define if libpcap has pcap_datalink_name_to_val()]) AC_CHECK_FUNC(pcap_datalink_val_to_description, AC_DEFINE(HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION, 1, [define if libpcap has pcap_datalink_val_to_description()]), [ AC_LIBOBJ(dlnames) ]) ], [ AC_LIBOBJ(dlnames) ]) dnl dnl Check for "pcap_breakloop()"; you can't substitute for it if dnl it's absent (it has hooks into the live capture routines), dnl so just define the HAVE_ value if it's there. dnl AC_CHECK_FUNCS(pcap_breakloop) dnl dnl Check for "pcap_dump_ftell()" and use a substitute version dnl if it's not present. AC_CHECK_FUNC(pcap_dump_ftell, AC_DEFINE(HAVE_PCAP_DUMP_FTELL, 1, [define if libpcap has pcap_dump_ftell()]), [ AC_LIBOBJ(pcap_dump_ftell) ]) ]) dnl dnl Define RETSIGTYPE and RETSIGVAL dnl dnl usage: dnl dnl AC_LBL_TYPE_SIGNAL dnl dnl results: dnl dnl RETSIGTYPE (defined) dnl RETSIGVAL (defined) dnl AC_DEFUN(AC_LBL_TYPE_SIGNAL, [AC_BEFORE([$0], [AC_LBL_LIBPCAP]) AC_TYPE_SIGNAL if test "$ac_cv_type_signal" = void ; then AC_DEFINE(RETSIGVAL,[],[return value of signal handlers]) else AC_DEFINE(RETSIGVAL,(0),[return value of signal handlers]) fi case "$host_os" in irix*) AC_DEFINE(_BSD_SIGNALS,1,[get BSD semantics on Irix]) ;; *) dnl prefer sigaction() to sigset() AC_CHECK_FUNCS(sigaction) if test $ac_cv_func_sigaction = no ; then AC_CHECK_FUNCS(sigset) fi ;; esac]) dnl dnl If using gcc, make sure we have ANSI ioctl definitions dnl dnl usage: dnl dnl AC_LBL_FIXINCLUDES dnl AC_DEFUN(AC_LBL_FIXINCLUDES, [if test "$GCC" = yes ; then AC_MSG_CHECKING(for ANSI ioctl definitions) AC_CACHE_VAL(ac_cv_lbl_gcc_fixincludes, AC_TRY_COMPILE( [/* * This generates a "duplicate case value" when fixincludes * has not be run. */ # include # include # include # ifdef HAVE_SYS_IOCCOM_H # include # endif], [switch (0) { case _IO('A', 1):; case _IO('B', 1):; }], ac_cv_lbl_gcc_fixincludes=yes, ac_cv_lbl_gcc_fixincludes=no)) AC_MSG_RESULT($ac_cv_lbl_gcc_fixincludes) if test $ac_cv_lbl_gcc_fixincludes = no ; then # Don't cache failure unset ac_cv_lbl_gcc_fixincludes AC_MSG_ERROR(see the INSTALL for more info) fi fi]) dnl dnl Checks to see if union wait is used with WEXITSTATUS() dnl dnl usage: dnl dnl AC_LBL_UNION_WAIT dnl dnl results: dnl dnl DECLWAITSTATUS (defined) dnl AC_DEFUN(AC_LBL_UNION_WAIT, [AC_MSG_CHECKING(if union wait is used) AC_CACHE_VAL(ac_cv_lbl_union_wait, AC_TRY_COMPILE([ # include # include ], [int status; u_int i = WEXITSTATUS(status); u_int j = waitpid(0, &status, 0);], ac_cv_lbl_union_wait=no, ac_cv_lbl_union_wait=yes)) AC_MSG_RESULT($ac_cv_lbl_union_wait) if test $ac_cv_lbl_union_wait = yes ; then AC_DEFINE(DECLWAITSTATUS,union wait,[type for wait]) else AC_DEFINE(DECLWAITSTATUS,int,[type for wait]) fi]) dnl dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member dnl dnl usage: dnl dnl AC_LBL_SOCKADDR_SA_LEN dnl dnl results: dnl dnl HAVE_SOCKADDR_SA_LEN (defined) dnl AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN, [AC_MSG_CHECKING(if sockaddr struct has the sa_len member) AC_CACHE_VAL(ac_cv_lbl_sockaddr_has_sa_len, AC_TRY_COMPILE([ # include # include ], [u_int i = sizeof(((struct sockaddr *)0)->sa_len)], ac_cv_lbl_sockaddr_has_sa_len=yes, ac_cv_lbl_sockaddr_has_sa_len=no)) AC_MSG_RESULT($ac_cv_lbl_sockaddr_has_sa_len) if test $ac_cv_lbl_sockaddr_has_sa_len = yes ; then AC_DEFINE(HAVE_SOCKADDR_SA_LEN,1,[if struct sockaddr has the sa_len member]) fi]) dnl dnl Checks to see if -R is used dnl dnl usage: dnl dnl AC_LBL_HAVE_RUN_PATH dnl dnl results: dnl dnl ac_cv_lbl_have_run_path (yes or no) dnl AC_DEFUN(AC_LBL_HAVE_RUN_PATH, [AC_MSG_CHECKING(for ${CC-cc} -R) AC_CACHE_VAL(ac_cv_lbl_have_run_path, [echo 'main(){}' > conftest.c ${CC-cc} -o conftest conftest.c -R/a1/b2/c3 >conftest.out 2>&1 if test ! -s conftest.out ; then ac_cv_lbl_have_run_path=yes else ac_cv_lbl_have_run_path=no fi rm -f -r conftest*]) AC_MSG_RESULT($ac_cv_lbl_have_run_path) ]) dnl dnl Check whether a given format can be used to print 64-bit integers dnl AC_DEFUN(AC_LBL_CHECK_64BIT_FORMAT, [ AC_MSG_CHECKING([whether %$1x can be used to format 64-bit integers]) AC_RUN_IFELSE( [ AC_LANG_SOURCE( [[ # ifdef HAVE_INTTYPES_H #include # endif # ifdef HAVE_SYS_BITYPES_H #include # endif #include #include main() { u_int64_t t = 1; char strbuf[16+1]; sprintf(strbuf, "%016$1x", t << 32); if (strcmp(strbuf, "0000000100000000") == 0) exit(0); else exit(1); } ]]) ], [ AC_DEFINE(PRId64, "$1d", [define if the platform doesn't define PRId64]) AC_DEFINE(PRIo64, "$1o", [define if the platform doesn't define PRIo64]) AC_DEFINE(PRIx64, "$1x", [define if the platform doesn't define PRIu64]) AC_DEFINE(PRIu64, "$1u", [define if the platform doesn't define PRIx64]) AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) $2 ]) ]) dnl dnl Checks to see if unaligned memory accesses fail dnl dnl usage: dnl dnl AC_LBL_UNALIGNED_ACCESS dnl dnl results: dnl dnl LBL_ALIGN (DEFINED) dnl AC_DEFUN(AC_LBL_UNALIGNED_ACCESS, [AC_MSG_CHECKING(if unaligned accesses fail) AC_CACHE_VAL(ac_cv_lbl_unaligned_fail, [case "$host_cpu" in # # These are CPU types where: # # the CPU faults on an unaligned access, but at least some # OSes that support that CPU catch the fault and simulate # the unaligned access (e.g., Alpha/{Digital,Tru64} UNIX) - # the simulation is slow, so we don't want to use it; # # the CPU, I infer (from the old # # XXX: should also check that they don't do weird things (like on arm) # # comment) doesn't fault on unaligned accesses, but doesn't # do a normal unaligned fetch, either (e.g., presumably, ARM); # # for whatever reason, the test program doesn't work # (this has been claimed to be the case for several of those # CPUs - I don't know what the problem is; the problem # was reported as "the test program dumps core" for SuperH, # but that's what the test program is *supposed* to do - # it dumps core before it writes anything, so the test # for an empty output file should find an empty output # file and conclude that unaligned accesses don't work). # # This run-time test won't work if you're cross-compiling, so # in order to support cross-compiling for a particular CPU, # we have to wire in the list of CPU types anyway, as far as # I know, so perhaps we should just have a set of CPUs on # which we know it doesn't work, a set of CPUs on which we # know it does work, and have the script just fail on other # cpu types and update it when such a failure occurs. # alpha*|arm*|bfin*|hp*|mips*|sh*|sparc*|ia64|nv1) ac_cv_lbl_unaligned_fail=yes ;; *) cat >conftest.c < # include # include unsigned char a[[5]] = { 1, 2, 3, 4, 5 }; main() { unsigned int i; pid_t pid; int status; /* avoid "core dumped" message */ pid = fork(); if (pid < 0) exit(2); if (pid > 0) { /* parent */ pid = waitpid(pid, &status, 0); if (pid < 0) exit(3); exit(!WIFEXITED(status)); } /* child */ i = *(unsigned int *)&a[[1]]; printf("%d\n", i); exit(0); } EOF ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \ conftest.c $LIBS >/dev/null 2>&1 if test ! -x conftest ; then dnl failed to compile for some reason ac_cv_lbl_unaligned_fail=yes else ./conftest >conftest.out if test ! -s conftest.out ; then ac_cv_lbl_unaligned_fail=yes else ac_cv_lbl_unaligned_fail=no fi fi rm -f -r conftest* core core.conftest ;; esac]) AC_MSG_RESULT($ac_cv_lbl_unaligned_fail) if test $ac_cv_lbl_unaligned_fail = yes ; then AC_DEFINE(LBL_ALIGN,1,[if unaligned access fails]) fi]) dnl dnl If the file .devel exists: dnl Add some warning flags if the compiler supports them dnl If an os prototype include exists, symlink os-proto.h to it dnl dnl usage: dnl dnl AC_LBL_DEVEL(copt) dnl dnl results: dnl dnl $1 (copt appended) dnl HAVE_OS_PROTO_H (defined) dnl os-proto.h (symlinked) dnl AC_DEFUN(AC_LBL_DEVEL, [rm -f os-proto.h if test "${LBL_CFLAGS+set}" = set; then $1="$$1 ${LBL_CFLAGS}" fi if test -f .devel ; then # # Skip all the warning option stuff on some compilers. # if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then AC_LBL_CHECK_COMPILER_OPT($1, -Wall) AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-prototypes) AC_LBL_CHECK_COMPILER_OPT($1, -Wstrict-prototypes) AC_LBL_CHECK_COMPILER_OPT($1, -Wwrite-strings) AC_LBL_CHECK_COMPILER_OPT($1, -Wpointer-arith) AC_LBL_CHECK_COMPILER_OPT($1, -W) fi AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT() # # We used to set -n32 for IRIX 6 when not using GCC (presumed # to mean that we're using MIPS C or MIPSpro C); it specified # the "new" faster 32-bit ABI, introduced in IRIX 6.2. I'm # not sure why that would be something to do *only* with a # .devel file; why should the ABI for which we produce code # depend on .devel? # os=`echo $host_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'` name="lbl/os-$os.h" if test -f $name ; then ln -s $name os-proto.h AC_DEFINE(HAVE_OS_PROTO_H, 1, [if there's an os_proto.h for this platform, to use additional prototypes]) else AC_MSG_WARN(can't find $name) fi fi]) dnl dnl Improved version of AC_CHECK_LIB dnl dnl Thanks to John Hawkinson (jhawk@mit.edu) dnl dnl usage: dnl dnl AC_LBL_CHECK_LIB(LIBRARY, FUNCTION [, ACTION-IF-FOUND [, dnl ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]]) dnl dnl results: dnl dnl LIBS dnl dnl XXX - "AC_LBL_LIBRARY_NET" was redone to use "AC_SEARCH_LIBS" dnl rather than "AC_LBL_CHECK_LIB", so this isn't used any more. dnl We keep it around for reference purposes in case it's ever dnl useful in the future. dnl define(AC_LBL_CHECK_LIB, [AC_MSG_CHECKING([for $2 in -l$1]) dnl Use a cache variable name containing the library, function dnl name, and extra libraries to link with, because the test really is dnl for library $1 defining function $2, when linked with potinal dnl library $5, not just for library $1. Separate tests with the same dnl $1 and different $2's or $5's may have different results. ac_lib_var=`echo $1['_']$2['_']$5 | sed 'y%./+- %__p__%'` AC_CACHE_VAL(ac_cv_lbl_lib_$ac_lib_var, [ac_save_LIBS="$LIBS" LIBS="-l$1 $5 $LIBS" AC_TRY_LINK(dnl ifelse([$2], [main], , dnl Avoid conflicting decl of main. [/* Override any gcc2 internal prototype to avoid an error. */ ]ifelse(AC_LANG, CPLUSPLUS, [#ifdef __cplusplus extern "C" #endif ])dnl [/* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $2(); ]), [$2()], eval "ac_cv_lbl_lib_$ac_lib_var=yes", eval "ac_cv_lbl_lib_$ac_lib_var=no") LIBS="$ac_save_LIBS" ])dnl if eval "test \"`echo '$ac_cv_lbl_lib_'$ac_lib_var`\" = yes"; then AC_MSG_RESULT(yes) ifelse([$3], , [changequote(, )dnl ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` changequote([, ])dnl AC_DEFINE_UNQUOTED($ac_tr_lib) LIBS="-l$1 $LIBS" ], [$3]) else AC_MSG_RESULT(no) ifelse([$4], , , [$4 ])dnl fi ]) dnl dnl AC_LBL_LIBRARY_NET dnl dnl This test is for network applications that need socket() and dnl gethostbyname() -ish functions. Under Solaris, those applications dnl need to link with "-lsocket -lnsl". Under IRIX, they need to link dnl with "-lnsl" but should *not* link with "-lsocket" because dnl libsocket.a breaks a number of things (for instance: dnl gethostbyname() under IRIX 5.2, and snoop sockets under most dnl versions of IRIX). dnl dnl Unfortunately, many application developers are not aware of this, dnl and mistakenly write tests that cause -lsocket to be used under dnl IRIX. It is also easy to write tests that cause -lnsl to be used dnl under operating systems where neither are necessary (or useful), dnl such as SunOS 4.1.4, which uses -lnsl for TLI. dnl dnl This test exists so that every application developer does not test dnl this in a different, and subtly broken fashion. dnl It has been argued that this test should be broken up into two dnl seperate tests, one for the resolver libraries, and one for the dnl libraries necessary for using Sockets API. Unfortunately, the two dnl are carefully intertwined and allowing the autoconf user to use dnl them independantly potentially results in unfortunate ordering dnl dependancies -- as such, such component macros would have to dnl carefully use indirection and be aware if the other components were dnl executed. Since other autoconf macros do not go to this trouble, dnl and almost no applications use sockets without the resolver, this dnl complexity has not been implemented. dnl dnl The check for libresolv is in case you are attempting to link dnl statically and happen to have a libresolv.a lying around (and no dnl libnsl.a). dnl AC_DEFUN(AC_LBL_LIBRARY_NET, [ # Most operating systems have gethostbyname() in the default searched # libraries (i.e. libc): # Some OSes (eg. Solaris) place it in libnsl # Some strange OSes (SINIX) have it in libsocket: AC_SEARCH_LIBS(gethostbyname, nsl socket resolv) # Unfortunately libsocket sometimes depends on libnsl and # AC_SEARCH_LIBS isn't up to the task of handling dependencies like this. if test "$ac_cv_search_gethostbyname" = "no" then AC_CHECK_LIB(socket, gethostbyname, LIBS="-lsocket -lnsl $LIBS", , -lnsl) fi AC_SEARCH_LIBS(socket, socket, , AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl)) # DLPI needs putmsg under HPUX so test for -lstr while we're at it AC_SEARCH_LIBS(putmsg, str) ]) dnl Copyright (c) 1999 WIDE Project. All rights reserved. dnl dnl Redistribution and use in source and binary forms, with or without dnl modification, are permitted provided that the following conditions dnl are met: dnl 1. Redistributions of source code must retain the above copyright dnl notice, this list of conditions and the following disclaimer. dnl 2. Redistributions in binary form must reproduce the above copyright dnl notice, this list of conditions and the following disclaimer in the dnl documentation and/or other materials provided with the distribution. dnl 3. Neither the name of the project nor the names of its contributors dnl may be used to endorse or promote products derived from this software dnl without specific prior written permission. dnl dnl THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND dnl ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE dnl IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE dnl ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE dnl FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL dnl DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS dnl OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) dnl HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT dnl LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY dnl OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF dnl SUCH DAMAGE. dnl dnl Checks to see if AF_INET6 is defined AC_DEFUN(AC_CHECK_AF_INET6, [ AC_MSG_CHECKING(for AF_INET6) AC_CACHE_VAL($1, AC_TRY_COMPILE([ # include # include ], [int a = AF_INET6], $1=yes, $1=no)) AC_MSG_RESULT($$1) if test $$1 = yes ; then AC_DEFINE(HAVE_AF_INET6) fi ]) dnl dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member dnl borrowed from LBL libpcap AC_DEFUN(AC_CHECK_SA_LEN, [ AC_MSG_CHECKING(if sockaddr struct has sa_len member) AC_CACHE_VAL($1, AC_TRY_COMPILE([ # include # include ], [u_int i = sizeof(((struct sockaddr *)0)->sa_len)], $1=yes, $1=no)) AC_MSG_RESULT($$1) if test $$1 = yes ; then AC_DEFINE(HAVE_SOCKADDR_SA_LEN) fi ]) dnl dnl Checks for addrinfo structure AC_DEFUN(AC_STRUCT_ADDRINFO, [ AC_MSG_CHECKING(for addrinfo) AC_CACHE_VAL($1, AC_TRY_COMPILE([ # include ], [struct addrinfo a], $1=yes, $1=no)) AC_MSG_RESULT($$1) if test $$1 = yes; then AC_DEFINE(HAVE_ADDRINFO, 1, [define if you have the addrinfo function]) else AC_DEFINE(NEED_ADDRINFO_H, 1, [define if you need to include missing/addrinfo.h]) fi ]) dnl dnl Checks for NI_MAXSERV AC_DEFUN(AC_NI_MAXSERV, [ AC_MSG_CHECKING(for NI_MAXSERV) AC_CACHE_VAL($1, AC_EGREP_CPP(yes, [#include #ifdef NI_MAXSERV yes #endif], $1=yes, $1=no)) AC_MSG_RESULT($$1) if test $$1 != yes; then AC_DEFINE(NEED_ADDRINFO_H) fi ]) dnl dnl Checks for NI_NAMEREQD AC_DEFUN(AC_NI_NAMEREQD, [ AC_MSG_CHECKING(for NI_NAMEREQD) AC_CACHE_VAL($1, AC_EGREP_CPP(yes, [#include #ifdef NI_NOFQDN yes #endif], $1=yes, $1=no)) AC_MSG_RESULT($$1) if test $$1 != yes; then AC_DEFINE(NEED_ADDRINFO_H) fi ]) dnl dnl Checks for sockaddr_storage structure AC_DEFUN(AC_STRUCT_SA_STORAGE, [ AC_MSG_CHECKING(for sockaddr_storage) AC_CACHE_VAL($1, AC_TRY_COMPILE([ # include # include ], [struct sockaddr_storage s], $1=yes, $1=no)) AC_MSG_RESULT($$1) if test $$1 = yes; then AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1, [define if you have struct sockaddr_storage]) fi ]) dnl dnl check for h_errno AC_DEFUN(AC_VAR_H_ERRNO, [ AC_MSG_CHECKING(for h_errno) AC_CACHE_VAL(ac_cv_var_h_errno, AC_TRY_COMPILE([ # include # include ], [int foo = h_errno;], ac_cv_var_h_errno=yes, ac_cv_var_h_errno=no)) AC_MSG_RESULT($ac_cv_var_h_errno) if test "$ac_cv_var_h_errno" = "yes"; then AC_DEFINE(HAVE_H_ERRNO, 1, [define if you have the h_errno variable]) fi ]) dnl dnl Test for __attribute__ dnl AC_DEFUN(AC_C___ATTRIBUTE__, [ AC_MSG_CHECKING(for __attribute__) AC_CACHE_VAL(ac_cv___attribute__, [ AC_COMPILE_IFELSE([ AC_LANG_SOURCE([[ #include static void foo(void) __attribute__ ((noreturn)); static void foo(void) { exit(1); } int main(int argc, char **argv) { foo(); } ]])], ac_cv___attribute__=yes, ac_cv___attribute__=no)]) if test "$ac_cv___attribute__" = "yes"; then AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__]) else # # We can't use __attribute__, so we can't use __attribute__((unused)), # so we define _U_ to an empty string. # V_DEFS="$V_DEFS -D_U_=\"\"" fi AC_MSG_RESULT($ac_cv___attribute__) ]) dnl dnl Test whether __attribute__((unused)) can be used without warnings dnl AC_DEFUN(AC_C___ATTRIBUTE___UNUSED, [ AC_MSG_CHECKING([whether __attribute__((unused)) can be used without warnings]) AC_CACHE_VAL(ac_cv___attribute___unused, [ save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors" AC_COMPILE_IFELSE([ AC_LANG_SOURCE([[ #include #include int main(int argc __attribute((unused)), char **argv __attribute((unused))) { printf("Hello, world!\n"); return 0; } ]])], ac_cv___attribute___unused=yes, ac_cv___attribute___unused=no)]) CFLAGS="$save_CFLAGS" if test "$ac_cv___attribute___unused" = "yes"; then V_DEFS="$V_DEFS -D_U_=\"__attribute__((unused))\"" else V_DEFS="$V_DEFS -D_U_=\"\"" fi AC_MSG_RESULT($ac_cv___attribute___unused) ]) dnl dnl Test whether __attribute__((format)) can be used without warnings dnl AC_DEFUN(AC_C___ATTRIBUTE___FORMAT, [ AC_MSG_CHECKING([whether __attribute__((format)) can be used without warnings]) AC_CACHE_VAL(ac_cv___attribute___format, [ save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors" AC_COMPILE_IFELSE([ AC_LANG_SOURCE([[ #include extern int foo(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int main(int argc, char **argv) { foo("%s", "test"); } ]])], ac_cv___attribute___format=yes, ac_cv___attribute___format=no)]) CFLAGS="$save_CFLAGS" if test "$ac_cv___attribute___format" = "yes"; then AC_DEFINE(__ATTRIBUTE___FORMAT_OK, 1, [define if your compiler allows __attribute__((format)) without a warning]) fi AC_MSG_RESULT($ac_cv___attribute___format) ]) dnl dnl Test whether __attribute__((format)) can be applied to function dnl pointers dnl AC_DEFUN(AC_C___ATTRIBUTE___FORMAT_FUNCTION_POINTER, [ AC_MSG_CHECKING([whether __attribute__((format)) can be applied to function pointers]) AC_CACHE_VAL(ac_cv___attribute___format_function_pointer, [ AC_COMPILE_IFELSE([ AC_LANG_SOURCE([[ #include extern int (*foo)(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int main(int argc, char **argv) { (*foo)("%s", "test"); } ]])], ac_cv___attribute___format_function_pointer=yes, ac_cv___attribute___format_function_pointer=no)]) if test "$ac_cv___attribute___format_function_pointer" = "yes"; then AC_DEFINE(__ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS, 1, [define if your compiler allows __attribute__((format)) to be applied to function pointers]) fi AC_MSG_RESULT($ac_cv___attribute___format_function_pointer) ]) AC_DEFUN(AC_C___ATTRIBUTE___NORETURN_FUNCTION_POINTER, [ AC_MSG_CHECKING([whether __attribute__((noreturn)) can be applied to function pointers without warnings]) AC_CACHE_VAL(ac_cv___attribute___noreturn_function_pointer, [ save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors" AC_COMPILE_IFELSE([ AC_LANG_SOURCE([[ #include extern int (*foo)(int i) __attribute__ ((noreturn)); int main(int argc, char **argv) { (*foo)(1); } ]])], ac_cv___attribute___noreturn_function_pointer=yes, ac_cv___attribute___noreturn_function_pointer=no)]) CFLAGS="$save_CFLAGS" if test "$ac_cv___attribute___noreturn_function_pointer" = "yes"; then AC_DEFINE(__ATTRIBUTE___NORETURN_OK_FOR_FUNCTION_POINTERS, 1, [define if your compiler allows __attribute__((noreturn)) to be applied to function pointers]) fi AC_MSG_RESULT($ac_cv___attribute___noreturn_function_pointer) ]) AC_DEFUN(AC_LBL_SSLEAY, [ # # Find the last component of $libdir; it's not necessarily # "lib" - it might be "lib64" on, for example, x86-64 # Linux systems. # # We assume the directory in which we're looking for # libcrypto has a subdirectory with that as its name. # tmplib=`echo "$libdir" | sed 's,.*/,,'` # # XXX - is there a better way to check if a given library is # in a given directory than checking each of the possible # shared library suffixes? # # Are there any other suffixes we need to look for? Do we # have to worry about ".so.{version}"? # # Or should we just look for "libcrypto.*"? # if test -d "$1/$tmplib" -a \( -f "$1/$tmplib/libcrypto.a" -o \ -f "$1/$tmplib/libcrypto.so" -o \ -f "$1/$tmplib/libcrypto.sl" -o \ -f "$1/$tmplib/libcrypto.dylib" \); then ac_cv_ssleay_path="$1" fi # # Make sure we have the headers as well. # if test -d "$1/include/openssl" -a -f "$1/include/openssl/des.h"; then incdir="-I$1/include" fi ]) tcpdump-4.5.1/print-ipx.c0000644000026300017510000001260112237020316012710 0ustar mcr/* * Copyright (c) 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Format and print Novell IPX packets. * Contributed by Brad Parker (brad@fcr.com). */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-ipx.c,v 1.42 2005-05-06 08:26:44 guy Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "interface.h" #include "addrtoname.h" #include "ipx.h" #include "extract.h" static const char *ipxaddr_string(u_int32_t, const u_char *); void ipx_decode(const struct ipxHdr *, const u_char *, u_int); void ipx_sap_print(const u_short *, u_int); void ipx_rip_print(const u_short *, u_int); /* * Print IPX datagram packets. */ void ipx_print(const u_char *p, u_int length) { const struct ipxHdr *ipx = (const struct ipxHdr *)p; if (!eflag) printf("IPX "); TCHECK(ipx->srcSkt); (void)printf("%s.%04x > ", ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode), EXTRACT_16BITS(&ipx->srcSkt)); (void)printf("%s.%04x: ", ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode), EXTRACT_16BITS(&ipx->dstSkt)); /* take length from ipx header */ TCHECK(ipx->length); length = EXTRACT_16BITS(&ipx->length); ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize); return; trunc: printf("[|ipx %d]", length); } static const char * ipxaddr_string(u_int32_t net, const u_char *node) { static char line[256]; snprintf(line, sizeof(line), "%08x.%02x:%02x:%02x:%02x:%02x:%02x", net, node[0], node[1], node[2], node[3], node[4], node[5]); return line; } void ipx_decode(const struct ipxHdr *ipx, const u_char *datap, u_int length) { register u_short dstSkt; dstSkt = EXTRACT_16BITS(&ipx->dstSkt); switch (dstSkt) { case IPX_SKT_NCP: (void)printf("ipx-ncp %d", length); break; case IPX_SKT_SAP: ipx_sap_print((u_short *)datap, length); break; case IPX_SKT_RIP: ipx_rip_print((u_short *)datap, length); break; case IPX_SKT_NETBIOS: (void)printf("ipx-netbios %d", length); #ifdef TCPDUMP_DO_SMB ipx_netbios_print(datap, length); #endif break; case IPX_SKT_DIAGNOSTICS: (void)printf("ipx-diags %d", length); break; case IPX_SKT_NWLINK_DGM: (void)printf("ipx-nwlink-dgm %d", length); #ifdef TCPDUMP_DO_SMB ipx_netbios_print(datap, length); #endif break; case IPX_SKT_EIGRP: eigrp_print(datap, length); break; default: (void)printf("ipx-#%x %d", dstSkt, length); break; } } void ipx_sap_print(const u_short *ipx, u_int length) { int command, i; TCHECK(ipx[0]); command = EXTRACT_16BITS(ipx); ipx++; length -= 2; switch (command) { case 1: case 3: if (command == 1) (void)printf("ipx-sap-req"); else (void)printf("ipx-sap-nearest-req"); TCHECK(ipx[0]); (void)printf(" %s", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))); break; case 2: case 4: if (command == 2) (void)printf("ipx-sap-resp"); else (void)printf("ipx-sap-nearest-resp"); for (i = 0; i < 8 && length > 0; i++) { TCHECK(ipx[0]); (void)printf(" %s '", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))); if (fn_printzp((u_char *)&ipx[1], 48, snapend)) { printf("'"); goto trunc; } TCHECK2(ipx[25], 10); printf("' addr %s", ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (u_char *)&ipx[27])); ipx += 32; length -= 64; } break; default: (void)printf("ipx-sap-?%x", command); break; } return; trunc: printf("[|ipx %d]", length); } void ipx_rip_print(const u_short *ipx, u_int length) { int command, i; TCHECK(ipx[0]); command = EXTRACT_16BITS(ipx); ipx++; length -= 2; switch (command) { case 1: (void)printf("ipx-rip-req"); if (length > 0) { TCHECK(ipx[3]); (void)printf(" %08x/%d.%d", EXTRACT_32BITS(&ipx[0]), EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])); } break; case 2: (void)printf("ipx-rip-resp"); for (i = 0; i < 50 && length > 0; i++) { TCHECK(ipx[3]); (void)printf(" %08x/%d.%d", EXTRACT_32BITS(&ipx[0]), EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])); ipx += 4; length -= 8; } break; default: (void)printf("ipx-rip-?%x", command); break; } return; trunc: printf("[|ipx %d]", length); } tcpdump-4.5.1/print-ascii.c0000644000026300017510000001267512237020316013213 0ustar mcr/* $NetBSD: print-ascii.c,v 1.1 1999/09/30 14:49:12 sjg Exp $ */ /*- * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Alan Barrett and Simon J. Gerraty. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-ascii.c,v 1.17 2005-07-06 20:53:32 guy Exp $"; #endif #include #include #include "interface.h" #define ASCII_LINELENGTH 300 #define HEXDUMP_BYTES_PER_LINE 16 #define HEXDUMP_SHORTS_PER_LINE (HEXDUMP_BYTES_PER_LINE / 2) #define HEXDUMP_HEXSTUFF_PER_SHORT 5 /* 4 hex digits and a space */ #define HEXDUMP_HEXSTUFF_PER_LINE \ (HEXDUMP_HEXSTUFF_PER_SHORT * HEXDUMP_SHORTS_PER_LINE) void ascii_print(register const u_char *cp, register u_int length) { register int s; putchar('\n'); while (length > 0) { s = *cp++; length--; if (!isgraph(s) && (s != '\t' && s != ' ' && s != '\n' && s != '\r')) putchar('.'); else putchar(s); } } void hex_and_ascii_print_with_offset(register const char *ident, register const u_char *cp, register u_int length, register u_int oset) { register u_int i; register int s1, s2; register int nshorts; char hexstuff[HEXDUMP_SHORTS_PER_LINE*HEXDUMP_HEXSTUFF_PER_SHORT+1], *hsp; char asciistuff[ASCII_LINELENGTH+1], *asp; nshorts = length / sizeof(u_short); i = 0; hsp = hexstuff; asp = asciistuff; while (--nshorts >= 0) { s1 = *cp++; s2 = *cp++; (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff), " %02x%02x", s1, s2); hsp += HEXDUMP_HEXSTUFF_PER_SHORT; *(asp++) = (isgraph(s1) ? s1 : '.'); *(asp++) = (isgraph(s2) ? s2 : '.'); i++; if (i >= HEXDUMP_SHORTS_PER_LINE) { *hsp = *asp = '\0'; (void)printf("%s0x%04x: %-*s %s", ident, oset, HEXDUMP_HEXSTUFF_PER_LINE, hexstuff, asciistuff); i = 0; hsp = hexstuff; asp = asciistuff; oset += HEXDUMP_BYTES_PER_LINE; } } if (length & 1) { s1 = *cp++; (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff), " %02x", s1); hsp += 3; *(asp++) = (isgraph(s1) ? s1 : '.'); ++i; } if (i > 0) { *hsp = *asp = '\0'; (void)printf("%s0x%04x: %-*s %s", ident, oset, HEXDUMP_HEXSTUFF_PER_LINE, hexstuff, asciistuff); } } void hex_and_ascii_print(register const char *ident, register const u_char *cp, register u_int length) { hex_and_ascii_print_with_offset(ident, cp, length, 0); } /* * telnet_print() wants this. It is essentially default_print_unaligned() */ void hex_print_with_offset(register const char *ident, register const u_char *cp, register u_int length, register u_int oset) { register u_int i, s; register int nshorts; nshorts = (u_int) length / sizeof(u_short); i = 0; while (--nshorts >= 0) { if ((i++ % 8) == 0) { (void)printf("%s0x%04x: ", ident, oset); oset += HEXDUMP_BYTES_PER_LINE; } s = *cp++; (void)printf(" %02x%02x", s, *cp++); } if (length & 1) { if ((i % 8) == 0) (void)printf("%s0x%04x: ", ident, oset); (void)printf(" %02x", *cp); } } /* * just for completeness */ void hex_print(register const char *ident, register const u_char *cp, register u_int length) { hex_print_with_offset(ident, cp, length, 0); } #ifdef MAIN int main(int argc, char *argv[]) { hex_print("\n\t", "Hello, World!\n", 14); printf("\n"); hex_and_ascii_print("\n\t", "Hello, World!\n", 14); printf("\n"); ascii_print("Hello, World!\n", 14); printf("\n"); #define TMSG "Now is the winter of our discontent...\n" hex_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100); printf("\n"); hex_and_ascii_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100); printf("\n"); exit(0); } #endif /* MAIN */ tcpdump-4.5.1/print-atalk.c0000644000026300017510000003557512237020316013223 0ustar mcr/* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Format and print AppleTalk packets. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.81 2004-05-01 09:41:50 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "interface.h" #include "addrtoname.h" #include "ethertype.h" #include "extract.h" /* must come after interface.h */ #include "appletalk.h" static const struct tok type2str[] = { { ddpRTMP, "rtmp" }, { ddpRTMPrequest, "rtmpReq" }, { ddpECHO, "echo" }, { ddpIP, "IP" }, { ddpARP, "ARP" }, { ddpKLAP, "KLAP" }, { 0, NULL } }; struct aarp { 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]"; static void atp_print(const struct atATP *, u_int); static void atp_bitmap_print(u_char); static void nbp_print(const struct atNBP *, u_int, u_short, u_char, u_char); static const char *print_cstring(const char *, const u_char *); static const struct atNBPtuple *nbp_tuple_print(const struct atNBPtuple *, const u_char *, u_short, u_char, u_char); static const struct atNBPtuple *nbp_name_print(const struct atNBPtuple *, const u_char *); static const char *ataddr_string(u_short, u_char); static void ddp_print(const u_char *, u_int, int, u_short, u_char, u_char); static const char *ddpskt_string(int); /* * Print LLAP packets received on a physical LocalTalk interface. */ u_int ltalk_if_print(const struct pcap_pkthdr *h, const u_char *p) { return (llap_print(p, h->caplen)); } /* * Print AppleTalk LLAP packets. */ u_int llap_print(register const u_char *bp, u_int length) { register const struct LAP *lp; register const struct atDDP *dp; register const struct atShortDDP *sdp; u_short snet; u_int hdrlen; if (length < sizeof(*lp)) { (void)printf(" [|llap %u]", length); return (length); } lp = (const struct LAP *)bp; bp += sizeof(*lp); length -= sizeof(*lp); hdrlen = sizeof(*lp); switch (lp->type) { case lapShortDDP: if (length < ddpSSize) { (void)printf(" [|sddp %u]", length); return (length); } sdp = (const struct atShortDDP *)bp; printf("%s.%s", ataddr_string(0, lp->src), ddpskt_string(sdp->srcSkt)); printf(" > %s.%s:", ataddr_string(0, lp->dst), ddpskt_string(sdp->dstSkt)); bp += ddpSSize; length -= ddpSSize; hdrlen += ddpSSize; ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt); break; case lapDDP: if (length < ddpSize) { (void)printf(" [|ddp %u]", length); return (length); } 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; hdrlen += ddpSize; ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt); break; #ifdef notdef case lapKLAP: klap_print(bp, length); break; #endif default: printf("%d > %d at-lap#%d %u", lp->src, lp->dst, lp->type, length); break; } return (hdrlen); } /* * 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(!eflag) printf("AT "); if (length < ddpSize) { (void)printf(" [|ddp %u]", 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) { register const struct aarp *ap; #define AT(member) ataddr_string((ap->member[1]<<8)|ap->member[2],ap->member[3]) printf("aarp "); ap = (const struct aarp *)bp; if (EXTRACT_16BITS(&ap->htype) == 1 && EXTRACT_16BITS(&ap->ptype) == ETHERTYPE_ATALK && ap->halen == 6 && ap->palen == 4 ) switch (EXTRACT_16BITS(&ap->op)) { case 1: /* request */ (void)printf("who-has %s tell %s", AT(pdaddr), AT(psaddr)); return; case 2: /* response */ (void)printf("reply %s is-at %s", AT(psaddr), etheraddr_string(ap->hsaddr)); return; case 3: /* probe (oy!) */ (void)printf("probe %s tell %s", AT(pdaddr), AT(psaddr)); return; } (void)printf("len %u op %u htype %u ptype %#x halen %u palen %u", length, EXTRACT_16BITS(&ap->op), EXTRACT_16BITS(&ap->htype), EXTRACT_16BITS(&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) { switch (t) { case ddpNBP: nbp_print((const struct atNBP *)bp, length, snet, snode, skt); break; case ddpATP: atp_print((const struct atATP *)bp, length); break; case ddpEIGRP: eigrp_print(bp, length); break; default: (void)printf(" at-%s %d", tok2str(type2str, NULL, t), length); break; } } static void atp_print(register const struct atATP *ap, u_int length) { char c; u_int32_t data; if ((const u_char *)(ap + 1) > snapend) { /* Just bail if we don't have the whole chunk. */ fputs(tstr, stdout); return; } if (length < sizeof(*ap)) { (void)printf(" [|atp %u]", length); return; } length -= sizeof(*ap); switch (ap->control & 0xc0) { case atpReqCode: (void)printf(" atp-req%s %d", ap->control & atpXO? " " : "*", EXTRACT_16BITS(&ap->transID)); atp_bitmap_print(ap->bitmap); if (length != 0) (void)printf(" [len=%u]", length); switch (ap->control & (atpEOM|atpSTS)) { case atpEOM: (void)printf(" [EOM]"); break; case atpSTS: (void)printf(" [STS]"); break; case atpEOM|atpSTS: (void)printf(" [EOM,STS]"); break; } break; case atpRspCode: (void)printf(" atp-resp%s%d:%d (%u)", ap->control & atpEOM? "*" : " ", EXTRACT_16BITS(&ap->transID), ap->bitmap, length); switch (ap->control & (atpXO|atpSTS)) { case atpXO: (void)printf(" [XO]"); break; case atpSTS: (void)printf(" [STS]"); break; case atpXO|atpSTS: (void)printf(" [XO,STS]"); break; } break; case atpRelCode: (void)printf(" atp-rel %d", EXTRACT_16BITS(&ap->transID)); atp_bitmap_print(ap->bitmap); /* length should be zero */ if (length) (void)printf(" [len=%u]", length); /* there shouldn't be any control flags */ if (ap->control & (atpXO|atpEOM|atpSTS)) { c = '['; if (ap->control & atpXO) { (void)printf("%cXO", c); c = ','; } if (ap->control & atpEOM) { (void)printf("%cEOM", c); c = ','; } if (ap->control & atpSTS) { (void)printf("%cSTS", c); c = ','; } (void)printf("]"); } break; default: (void)printf(" atp-0x%x %d (%u)", ap->control, EXTRACT_16BITS(&ap->transID), length); break; } data = EXTRACT_32BITS(&ap->userData); if (data != 0) (void)printf(" 0x%x", data); } static void atp_bitmap_print(register u_char bm) { register char c; register int i; /* * The '& 0xff' below is needed for compilers that want to sign * extend a u_char, which is the case with the Ultrix compiler. * (gcc is smart enough to eliminate it, at least on the Sparc). */ if ((bm + 1) & (bm & 0xff)) { c = '<'; for (i = 0; bm; ++i) { if (bm & 1) { (void)printf("%c%d", c, i); c = ','; } bm >>= 1; } (void)printf(">"); } else { for (i = 0; bm; ++i) bm >>= 1; if (i > 1) (void)printf("<0-%d>", i - 1); else (void)printf("<0>"); } } static void nbp_print(register const struct atNBP *np, u_int length, register u_short snet, register u_char snode, register u_char skt) { register const struct atNBPtuple *tp = (const struct atNBPtuple *)((u_char *)np + nbpHeaderSize); int i; const u_char *ep; if (length < nbpHeaderSize) { (void)printf(" truncated-nbp %u", length); return; } length -= nbpHeaderSize; if (length < 8) { /* must be room for at least one tuple */ (void)printf(" truncated-nbp %u", length + nbpHeaderSize); return; } /* ep points to end of available data */ ep = snapend; if ((const u_char *)tp > ep) { fputs(tstr, stdout); return; } switch (i = np->control & 0xf0) { case nbpBrRq: case nbpLkUp: (void)printf(i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:", np->id); if ((const u_char *)(tp + 1) > ep) { fputs(tstr, stdout); return; } (void)nbp_name_print(tp, ep); /* * look for anomalies: the spec says there can only * be one tuple, the address must match the source * address and the enumerator should be zero. */ if ((np->control & 0xf) != 1) (void)printf(" [ntup=%d]", np->control & 0xf); if (tp->enumerator) (void)printf(" [enum=%d]", tp->enumerator); if (EXTRACT_16BITS(&tp->net) != snet || tp->node != snode || tp->skt != skt) (void)printf(" [addr=%s.%d]", ataddr_string(EXTRACT_16BITS(&tp->net), tp->node), tp->skt); break; case nbpLkUpReply: (void)printf(" nbp-reply %d:", np->id); /* print each of the tuples in the reply */ for (i = np->control & 0xf; --i >= 0 && tp; ) tp = nbp_tuple_print(tp, ep, snet, snode, skt); break; default: (void)printf(" nbp-0x%x %d (%u)", np->control, np->id, length); break; } } /* print a counted string */ static const char * print_cstring(register const char *cp, register const u_char *ep) { register u_int length; if (cp >= (const char *)ep) { fputs(tstr, stdout); return (0); } length = *cp++; /* Spec says string can be at most 32 bytes long */ if (length > 32) { (void)printf("[len=%u]", length); return (0); } while ((int)--length >= 0) { if (cp >= (const char *)ep) { fputs(tstr, stdout); return (0); } putchar(*cp++); } return (cp); } static const struct atNBPtuple * nbp_tuple_print(register const struct atNBPtuple *tp, register const u_char *ep, register u_short snet, register u_char snode, register u_char skt) { register const struct atNBPtuple *tpn; if ((const u_char *)(tp + 1) > ep) { fputs(tstr, stdout); return 0; } tpn = nbp_name_print(tp, ep); /* if the enumerator isn't 1, print it */ if (tp->enumerator != 1) (void)printf("(%d)", tp->enumerator); /* if the socket doesn't match the src socket, print it */ if (tp->skt != skt) (void)printf(" %d", tp->skt); /* if the address doesn't match the src address, it's an anomaly */ if (EXTRACT_16BITS(&tp->net) != snet || tp->node != snode) (void)printf(" [addr=%s]", ataddr_string(EXTRACT_16BITS(&tp->net), tp->node)); return (tpn); } static const struct atNBPtuple * nbp_name_print(const struct atNBPtuple *tp, register const u_char *ep) { register const char *cp = (const char *)tp + nbpTupleSize; putchar(' '); /* Object */ putchar('"'); if ((cp = print_cstring(cp, ep)) != NULL) { /* Type */ putchar(':'); if ((cp = print_cstring(cp, ep)) != NULL) { /* Zone */ putchar('@'); if ((cp = print_cstring(cp, ep)) != NULL) putchar('"'); } } return ((const struct atNBPtuple *)cp); } #define HASHNAMESIZE 4096 struct hnamemem { int addr; char *name; struct hnamemem *nxt; }; static struct hnamemem hnametable[HASHNAMESIZE]; static const char * ataddr_string(u_short atnet, u_char athost) { register struct hnamemem *tp, *tp2; register int i = (atnet << 8) | athost; char nambuf[256+1]; static int first = 1; FILE *fp; /* * if this is the first call, see if there's an AppleTalk * number to name map file. */ if (first && (first = 0, !nflag) && (fp = fopen("/etc/atalk.names", "r"))) { char line[256]; int i1, i2; while (fgets(line, sizeof(line), fp)) { if (line[0] == '\n' || line[0] == 0 || line[0] == '#') continue; if (sscanf(line, "%d.%d %256s", &i1, &i2, nambuf) == 3) /* got a hostname. */ i2 |= (i1 << 8); else if (sscanf(line, "%d %256s", &i1, nambuf) == 2) /* got a net name */ i2 = (i1 << 8) | 255; else continue; for (tp = &hnametable[i2 & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) ; tp->addr = i2; tp->nxt = newhnamemem(); tp->name = strdup(nambuf); } fclose(fp); } for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) if (tp->addr == i) return (tp->name); /* didn't have the node name -- see if we've got the net name */ i |= 255; for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt) if (tp2->addr == i) { tp->addr = (atnet << 8) | athost; tp->nxt = newhnamemem(); (void)snprintf(nambuf, sizeof(nambuf), "%s.%d", tp2->name, athost); tp->name = strdup(nambuf); return (tp->name); } tp->addr = (atnet << 8) | athost; tp->nxt = newhnamemem(); if (athost != 255) (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet, athost); else (void)snprintf(nambuf, sizeof(nambuf), "%d", atnet); tp->name = strdup(nambuf); return (tp->name); } static const struct tok skt2str[] = { { rtmpSkt, "rtmp" }, /* routing table maintenance */ { nbpSkt, "nis" }, /* name info socket */ { echoSkt, "echo" }, /* AppleTalk echo protocol */ { zipSkt, "zip" }, /* zone info protocol */ { 0, NULL } }; static const char * ddpskt_string(register int skt) { static char buf[8]; if (nflag) { (void)snprintf(buf, sizeof(buf), "%d", skt); return (buf); } return (tok2str(skt2str, "%d", skt)); } tcpdump-4.5.1/print-sl.c0000644000026300017510000001303012237020316012523 0ustar mcr/* * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.65 2005-04-06 21:32:42 mcr Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "interface.h" #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); u_int sl_if_print(const struct pcap_pkthdr *h, const u_char *p) { register u_int caplen = h->caplen; register u_int length = h->len; register const struct ip *ip; if (caplen < SLIP_HDRLEN) { printf("[|slip]"); return (caplen); } length -= SLIP_HDRLEN; ip = (struct ip *)(p + SLIP_HDRLEN); if (eflag) sliplink_print(p, ip, length); switch (IP_V(ip)) { case 4: ip_print(gndo, (u_char *)ip, length); break; #ifdef INET6 case 6: ip6_print(gndo, (u_char *)ip, length); break; #endif default: printf ("ip v%d", IP_V(ip)); } return (SLIP_HDRLEN); } u_int sl_bsdos_if_print(const struct pcap_pkthdr *h, const u_char *p) { register u_int caplen = h->caplen; register u_int length = h->len; register const struct ip *ip; if (caplen < SLIP_HDRLEN) { printf("[|slip]"); return (caplen); } length -= SLIP_HDRLEN; ip = (struct ip *)(p + SLIP_HDRLEN); #ifdef notdef if (eflag) sliplink_print(p, ip, length); #endif ip_print(gndo, (u_char *)ip, length); return (SLIP_HDRLEN); } static void sliplink_print(register const u_char *p, register const struct ip *ip, register u_int length) { int dir; u_int hlen; dir = p[SLX_DIR]; putchar(dir == SLIPDIR_IN ? 'I' : 'O'); putchar(' '); if (nflag) { /* XXX just dump the header */ register int i; for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i) printf("%02x.", p[i]); printf("%02x: ", p[SLX_CHDR + CHDR_LEN - 1]); return; } switch (p[SLX_CHDR] & 0xf0) { case TYPE_IP: printf("ip %d: ", length + SLIP_HDRLEN); break; case TYPE_UNCOMPRESSED_TCP: /* * The connection id is stored in the IP protocol field. * Get it from the link layer since sl_uncompress_tcp() * has restored the IP header copy to IPPROTO_TCP. */ lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p; hlen = IP_HL(ip); hlen += TH_OFF((struct tcphdr *)&((int *)ip)[hlen]); lastlen[dir][lastconn] = length - (hlen << 2); printf("utcp %d: ", lastconn); break; default: if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) { compressed_sl_print(&p[SLX_CHDR], ip, length, dir); printf(": "); } else printf("slip-%d!: ", p[SLX_CHDR]); } } static const u_char * print_sl_change(const char *str, register const u_char *cp) { register u_int i; if ((i = *cp++) == 0) { i = EXTRACT_16BITS(cp); cp += 2; } printf(" %s%d", str, i); return (cp); } static const u_char * print_sl_winchange(register const u_char *cp) { register short i; if ((i = *cp++) == 0) { i = EXTRACT_16BITS(cp); cp += 2; } if (i >= 0) printf(" W+%d", i); else printf(" W%d", i); return (cp); } static void compressed_sl_print(const u_char *chdr, const struct ip *ip, u_int length, int dir) { register const u_char *cp = chdr; register u_int flags, hlen; flags = *cp++; if (flags & NEW_C) { lastconn = *cp++; printf("ctcp %d", lastconn); } else printf("ctcp *"); /* skip tcp checksum */ cp += 2; switch (flags & SPECIALS_MASK) { case SPECIAL_I: printf(" *SA+%d", lastlen[dir][lastconn]); break; case SPECIAL_D: printf(" *S+%d", lastlen[dir][lastconn]); break; default: if (flags & NEW_U) cp = print_sl_change("U=", cp); if (flags & NEW_W) cp = print_sl_winchange(cp); if (flags & NEW_A) cp = print_sl_change("A+", cp); if (flags & NEW_S) cp = print_sl_change("S+", cp); break; } if (flags & NEW_I) cp = print_sl_change("I+", cp); /* * 'hlen' is the length of the uncompressed TCP/IP header (in words). * 'cp - chdr' is the length of the compressed header. * 'length - hlen' is the amount of data in the packet. */ hlen = IP_HL(ip); hlen += TH_OFF((struct tcphdr *)&((int32_t *)ip)[hlen]); lastlen[dir][lastconn] = length - (hlen << 2); printf(" %d (%ld)", lastlen[dir][lastconn], (long)(cp - chdr)); } tcpdump-4.5.1/print-tcp.c0000644000026300017510000010112412237020316012675 0ustar mcr/* $NetBSD: print-tcp.c,v 1.9 2007/07/26 18:15:12 plunky Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Copyright (c) 1999-2004 The tcpdump.org project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.135 2008-11-09 23:35:03 mcr Exp $ (LBL)"; #else __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" #include "tcp.h" #include "ip.h" #ifdef INET6 #include "ip6.h" #endif #include "ipproto.h" #include "rpc_auth.h" #include "rpc_msg.h" #include "nameser.h" #ifdef HAVE_LIBCRYPTO #include #include static int tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, const u_char *data, int length, const u_char *rcvsig); #endif static void print_tcp_rst_data(register const u_char *sp, u_int length); #define MAX_RST_DATA_LEN 30 struct tha { struct in_addr src; struct in_addr dst; u_int port; }; struct tcp_seq_hash { struct tcp_seq_hash *nxt; struct tha addr; tcp_seq seq; tcp_seq ack; }; #ifdef INET6 struct tha6 { struct in6_addr src; struct in6_addr dst; u_int port; }; struct tcp_seq_hash6 { struct tcp_seq_hash6 *nxt; struct tha6 addr; tcp_seq seq; tcp_seq ack; }; #endif #define TSEQ_HASHSIZE 919 /* These tcp optinos do not have the size octet */ #define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP) static struct tcp_seq_hash tcp_seq_hash4[TSEQ_HASHSIZE]; #ifdef INET6 static struct tcp_seq_hash6 tcp_seq_hash6[TSEQ_HASHSIZE]; #endif static const struct tok tcp_flag_values[] = { { TH_FIN, "F" }, { TH_SYN, "S" }, { TH_RST, "R" }, { TH_PUSH, "P" }, { TH_ACK, "." }, { TH_URG, "U" }, { TH_ECNECHO, "E" }, { TH_CWR, "W" }, { 0, NULL } }; static const struct tok tcp_option_values[] = { { TCPOPT_EOL, "eol" }, { TCPOPT_NOP, "nop" }, { TCPOPT_MAXSEG, "mss" }, { TCPOPT_WSCALE, "wscale" }, { TCPOPT_SACKOK, "sackOK" }, { TCPOPT_SACK, "sack" }, { TCPOPT_ECHO, "echo" }, { TCPOPT_ECHOREPLY, "echoreply" }, { TCPOPT_TIMESTAMP, "TS" }, { TCPOPT_CC, "cc" }, { TCPOPT_CCNEW, "ccnew" }, { TCPOPT_CCECHO, "" }, { TCPOPT_SIGNATURE, "md5" }, { TCPOPT_AUTH, "enhanced auth" }, { TCPOPT_UTO, "uto" }, { TCPOPT_MPTCP, "mptcp" }, { TCPOPT_EXPERIMENT2, "exp" }, { 0, NULL } }; static int tcp_cksum(register const struct ip *ip, register const struct tcphdr *tp, register u_int len) { return (nextproto4_cksum(ip, (const u_int8_t *)tp, len, IPPROTO_TCP)); } void tcp_print(register const u_char *bp, register u_int length, register const u_char *bp2, int fragmented) { register const struct tcphdr *tp; register const struct ip *ip; register u_char flags; register u_int hlen; register char ch; u_int16_t sport, dport, win, urp; u_int32_t seq, ack, thseq, thack; u_int utoval; u_int16_t magic; register int rev; #ifdef INET6 register const struct ip6_hdr *ip6; #endif tp = (struct tcphdr *)bp; ip = (struct ip *)bp2; #ifdef INET6 if (IP_V(ip) == 6) ip6 = (struct ip6_hdr *)bp2; else ip6 = NULL; #endif /*INET6*/ ch = '\0'; if (!TTEST(tp->th_dport)) { (void)printf("%s > %s: [|tcp]", ipaddr_string(&ip->ip_src), ipaddr_string(&ip->ip_dst)); return; } sport = EXTRACT_16BITS(&tp->th_sport); dport = EXTRACT_16BITS(&tp->th_dport); hlen = TH_OFF(tp) * 4; #ifdef INET6 if (ip6) { if (ip6->ip6_nxt == IPPROTO_TCP) { (void)printf("%s.%s > %s.%s: ", ip6addr_string(&ip6->ip6_src), tcpport_string(sport), ip6addr_string(&ip6->ip6_dst), tcpport_string(dport)); } else { (void)printf("%s > %s: ", tcpport_string(sport), tcpport_string(dport)); } } else #endif /*INET6*/ { if (ip->ip_p == IPPROTO_TCP) { (void)printf("%s.%s > %s.%s: ", ipaddr_string(&ip->ip_src), tcpport_string(sport), ipaddr_string(&ip->ip_dst), tcpport_string(dport)); } else { (void)printf("%s > %s: ", tcpport_string(sport), tcpport_string(dport)); } } if (hlen < sizeof(*tp)) { (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]", length - hlen, hlen, (unsigned long)sizeof(*tp)); return; } TCHECK(*tp); seq = EXTRACT_32BITS(&tp->th_seq); ack = EXTRACT_32BITS(&tp->th_ack); win = EXTRACT_16BITS(&tp->th_win); urp = EXTRACT_16BITS(&tp->th_urp); if (qflag) { (void)printf("tcp %d", length - hlen); if (hlen > length) { (void)printf(" [bad hdr length %u - too long, > %u]", hlen, length); } return; } flags = tp->th_flags; printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags)); if (!Sflag && (flags & TH_ACK)) { /* * Find (or record) the initial sequence numbers for * this conversation. (we pick an arbitrary * collating order so there's only one entry for * both directions). */ rev = 0; #ifdef INET6 if (ip6) { register struct tcp_seq_hash6 *th; struct tcp_seq_hash6 *tcp_seq_hash; const struct in6_addr *src, *dst; struct tha6 tha; tcp_seq_hash = tcp_seq_hash6; src = &ip6->ip6_src; dst = &ip6->ip6_dst; if (sport > dport) rev = 1; else if (sport == dport) { if (memcmp(src, dst, sizeof ip6->ip6_dst) > 0) rev = 1; } if (rev) { memcpy(&tha.src, dst, sizeof ip6->ip6_dst); memcpy(&tha.dst, src, sizeof ip6->ip6_src); tha.port = dport << 16 | sport; } else { memcpy(&tha.dst, dst, sizeof ip6->ip6_dst); memcpy(&tha.src, src, sizeof ip6->ip6_src); tha.port = sport << 16 | dport; } for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; th->nxt; th = th->nxt) if (memcmp((char *)&tha, (char *)&th->addr, sizeof(th->addr)) == 0) break; if (!th->nxt || (flags & TH_SYN)) { /* didn't find it or new conversation */ if (th->nxt == NULL) { th->nxt = (struct tcp_seq_hash6 *) calloc(1, sizeof(*th)); if (th->nxt == NULL) error("tcp_print: calloc"); } th->addr = tha; if (rev) th->ack = seq, th->seq = ack - 1; else th->seq = seq, th->ack = ack - 1; } else { if (rev) seq -= th->ack, ack -= th->seq; else seq -= th->seq, ack -= th->ack; } thseq = th->seq; thack = th->ack; } else { #else /*INET6*/ { #endif /*INET6*/ register struct tcp_seq_hash *th; struct tcp_seq_hash *tcp_seq_hash; const struct in_addr *src, *dst; struct tha tha; tcp_seq_hash = tcp_seq_hash4; src = &ip->ip_src; dst = &ip->ip_dst; if (sport > dport) rev = 1; else if (sport == dport) { if (memcmp(src, dst, sizeof ip->ip_dst) > 0) rev = 1; } if (rev) { memcpy(&tha.src, dst, sizeof ip->ip_dst); memcpy(&tha.dst, src, sizeof ip->ip_src); tha.port = dport << 16 | sport; } else { memcpy(&tha.dst, dst, sizeof ip->ip_dst); memcpy(&tha.src, src, sizeof ip->ip_src); tha.port = sport << 16 | dport; } for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; th->nxt; th = th->nxt) if (memcmp((char *)&tha, (char *)&th->addr, sizeof(th->addr)) == 0) break; if (!th->nxt || (flags & TH_SYN)) { /* didn't find it or new conversation */ if (th->nxt == NULL) { th->nxt = (struct tcp_seq_hash *) calloc(1, sizeof(*th)); if (th->nxt == NULL) error("tcp_print: calloc"); } th->addr = tha; if (rev) th->ack = seq, th->seq = ack - 1; else th->seq = seq, th->ack = ack - 1; } else { if (rev) seq -= th->ack, ack -= th->seq; else seq -= th->seq, ack -= th->ack; } thseq = th->seq; thack = th->ack; } } else { /*fool gcc*/ thseq = thack = rev = 0; } if (hlen > length) { (void)printf(" [bad hdr length %u - too long, > %u]", hlen, length); return; } if (vflag && !Kflag && !fragmented) { /* Check the checksum, if possible. */ u_int16_t sum, tcp_sum; if (IP_V(ip) == 4) { if (TTEST2(tp->th_sport, length)) { sum = tcp_cksum(ip, tp, length); tcp_sum = EXTRACT_16BITS(&tp->th_sum); (void)printf(", cksum 0x%04x", tcp_sum); if (sum != 0) (void)printf(" (incorrect -> 0x%04x)", in_cksum_shouldbe(tcp_sum, sum)); else (void)printf(" (correct)"); } } #ifdef INET6 else if (IP_V(ip) == 6 && ip6->ip6_plen) { if (TTEST2(tp->th_sport, length)) { sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, length, IPPROTO_TCP); tcp_sum = EXTRACT_16BITS(&tp->th_sum); (void)printf(", cksum 0x%04x", tcp_sum); if (sum != 0) (void)printf(" (incorrect -> 0x%04x)", in_cksum_shouldbe(tcp_sum, sum)); else (void)printf(" (correct)"); } } #endif } length -= hlen; if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) { (void)printf(", seq %u", seq); if (length > 0) { (void)printf(":%u", seq + length); } } if (flags & TH_ACK) { (void)printf(", ack %u", ack); } (void)printf(", win %d", win); if (flags & TH_URG) (void)printf(", urg %d", urp); /* * Handle any options. */ if (hlen > sizeof(*tp)) { register const u_char *cp; register u_int i, opt, datalen; register u_int len; hlen -= sizeof(*tp); cp = (const u_char *)tp + sizeof(*tp); printf(", options ["); while (hlen > 0) { if (ch != '\0') putchar(ch); TCHECK(*cp); opt = *cp++; if (ZEROLENOPT(opt)) len = 1; else { TCHECK(*cp); len = *cp++; /* total including type, len */ if (len < 2 || len > hlen) goto bad; --hlen; /* account for length byte */ } --hlen; /* account for type byte */ datalen = 0; /* Bail if "l" bytes of data are not left or were not captured */ #define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); } printf("%s", tok2str(tcp_option_values, "unknown-%u", opt)); switch (opt) { case TCPOPT_MAXSEG: datalen = 2; LENCHECK(datalen); (void)printf(" %u", EXTRACT_16BITS(cp)); break; case TCPOPT_WSCALE: datalen = 1; LENCHECK(datalen); (void)printf(" %u", *cp); break; case TCPOPT_SACK: datalen = len - 2; if (datalen % 8 != 0) { (void)printf("malformed sack"); } else { u_int32_t s, e; (void)printf(" %d ", datalen / 8); for (i = 0; i < datalen; i += 8) { LENCHECK(i + 4); s = EXTRACT_32BITS(cp + i); LENCHECK(i + 8); e = EXTRACT_32BITS(cp + i + 4); if (rev) { s -= thseq; e -= thseq; } else { s -= thack; e -= thack; } (void)printf("{%u:%u}", s, e); } } break; case TCPOPT_CC: case TCPOPT_CCNEW: case TCPOPT_CCECHO: case TCPOPT_ECHO: case TCPOPT_ECHOREPLY: /* * those options share their semantics. * fall through */ datalen = 4; LENCHECK(datalen); (void)printf(" %u", EXTRACT_32BITS(cp)); break; case TCPOPT_TIMESTAMP: datalen = 8; LENCHECK(datalen); (void)printf(" val %u ecr %u", EXTRACT_32BITS(cp), EXTRACT_32BITS(cp + 4)); break; case TCPOPT_SIGNATURE: datalen = TCP_SIGLEN; LENCHECK(datalen); #ifdef HAVE_LIBCRYPTO switch (tcp_verify_signature(ip, tp, bp + TH_OFF(tp) * 4, length, cp)) { case SIGNATURE_VALID: (void)printf("valid"); break; case SIGNATURE_INVALID: (void)printf("invalid"); break; case CANT_CHECK_SIGNATURE: (void)printf("can't check - "); for (i = 0; i < TCP_SIGLEN; ++i) (void)printf("%02x", cp[i]); break; } #else for (i = 0; i < TCP_SIGLEN; ++i) (void)printf("%02x", cp[i]); #endif break; case TCPOPT_AUTH: (void)printf("keyid %d", *cp++); datalen = len - 3; for (i = 0; i < datalen; ++i) { LENCHECK(i); (void)printf("%02x", cp[i]); } break; case TCPOPT_EOL: case TCPOPT_NOP: case TCPOPT_SACKOK: /* * Nothing interesting. * fall through */ break; case TCPOPT_UTO: datalen = 2; LENCHECK(datalen); utoval = EXTRACT_16BITS(cp); (void)printf("0x%x", utoval); if (utoval & 0x0001) utoval = (utoval >> 1) * 60; else utoval >>= 1; (void)printf(" %u", utoval); break; case TCPOPT_MPTCP: datalen = len - 2; LENCHECK(datalen); if (!mptcp_print(cp-2, len, flags)) goto bad; break; case TCPOPT_EXPERIMENT2: datalen = len - 2; LENCHECK(datalen); if (datalen < 2) goto bad; /* RFC6994 */ magic = EXTRACT_16BITS(cp); (void)printf("-"); switch(magic) { case 0xf989: /* TCP Fast Open: draft-ietf-tcpm-fastopen-04 */ if (datalen == 2) { /* Fast Open Cookie Request */ (void)printf("tfo cookiereq"); } else { /* Fast Open Cookie */ if (datalen % 2 != 0 || datalen < 6 || datalen > 18) { (void)printf("tfo malformed"); } else { (void)printf("tfo cookie "); for (i = 2; i < datalen; ++i) (void)printf("%02x", cp[i]); } } break; default: /* Unknown magic number */ (void)printf("%04x", magic); break; } break; default: datalen = len - 2; if (datalen) printf(" 0x"); for (i = 0; i < datalen; ++i) { LENCHECK(i); (void)printf("%02x", cp[i]); } break; } /* Account for data printed */ cp += datalen; hlen -= datalen; /* Check specification against observed length */ ++datalen; /* option octet */ if (!ZEROLENOPT(opt)) ++datalen; /* size octet */ if (datalen != len) (void)printf("[len %d]", len); ch = ','; if (opt == TCPOPT_EOL) break; } putchar(']'); } /* * Print length field before crawling down the stack. */ printf(", length %u", length); if (length <= 0) return; /* * Decode payload if necessary. */ bp += TH_OFF(tp) * 4; if ((flags & TH_RST) && vflag) { print_tcp_rst_data(bp, length); return; } if (packettype) { switch (packettype) { case PT_ZMTP1: zmtp1_print(bp, length); break; } return; } if (sport == TELNET_PORT || dport == TELNET_PORT) { if (!qflag && vflag) telnet_print(bp, length); } else if (sport == BGP_PORT || dport == BGP_PORT) bgp_print(bp, length); else if (sport == PPTP_PORT || dport == PPTP_PORT) pptp_print(bp); #ifdef TCPDUMP_DO_SMB else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT) nbt_tcp_print(bp, length); else if (sport == SMB_PORT || dport == SMB_PORT) smb_tcp_print(bp, length); #endif else if (sport == BEEP_PORT || dport == BEEP_PORT) beep_print(bp, length); else if (sport == OPENFLOW_PORT || dport == OPENFLOW_PORT) openflow_print(bp, length); else if (length > 2 && (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT || sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) { /* * TCP DNS query has 2byte length at the head. * XXX packet could be unaligned, it can go strange */ ns_print(bp + 2, length - 2, 0); } else if (sport == MSDP_PORT || dport == MSDP_PORT) { msdp_print(bp, length); } else if (sport == RPKI_RTR_PORT || dport == RPKI_RTR_PORT) { rpki_rtr_print(bp, length); } else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) { ldp_print(bp, length); } else if ((sport == NFS_PORT || dport == NFS_PORT) && length >= 4 && TTEST2(*bp, 4)) { /* * If data present, header length valid, and NFS port used, * assume NFS. * Pass offset of data plus 4 bytes for RPC TCP msg length * to NFS print routines. */ u_int32_t fraglen; register struct sunrpc_msg *rp; enum sunrpc_msg_type direction; fraglen = EXTRACT_32BITS(bp) & 0x7FFFFFFF; if (fraglen > (length) - 4) fraglen = (length) - 4; rp = (struct sunrpc_msg *)(bp + 4); if (TTEST(rp->rm_direction)) { direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); if (dport == NFS_PORT && direction == SUNRPC_CALL) { (void)printf(": NFS request xid %u ", EXTRACT_32BITS(&rp->rm_xid)); nfsreq_print_noaddr((u_char *)rp, fraglen, (u_char *)ip); return; } if (sport == NFS_PORT && direction == SUNRPC_REPLY) { (void)printf(": NFS reply xid %u ", EXTRACT_32BITS(&rp->rm_xid)); nfsreply_print_noaddr((u_char *)rp, fraglen, (u_char *)ip); return; } } } return; bad: fputs("[bad opt]", stdout); if (ch != '\0') putchar('>'); return; trunc: fputs("[|tcp]", stdout); if (ch != '\0') putchar('>'); } /* * RFC1122 says the following on data in RST segments: * * 4.2.2.12 RST Segment: RFC-793 Section 3.4 * * A TCP SHOULD allow a received RST segment to include data. * * DISCUSSION * It has been suggested that a RST segment could contain * ASCII text that encoded and explained the cause of the * RST. No standard has yet been established for such * data. * */ static void print_tcp_rst_data(register const u_char *sp, u_int length) { int c; if (TTEST2(*sp, length)) printf(" [RST"); else printf(" [!RST"); if (length > MAX_RST_DATA_LEN) { length = MAX_RST_DATA_LEN; /* can use -X for longer */ putchar('+'); /* indicate we truncate */ } putchar(' '); while (length-- && sp <= snapend) { c = *sp++; safeputchar(c); } putchar(']'); } #ifdef HAVE_LIBCRYPTO USES_APPLE_DEPRECATED_API static int tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, const u_char *data, int length, const u_char *rcvsig) { struct tcphdr tp1; u_char sig[TCP_SIGLEN]; char zero_proto = 0; MD5_CTX ctx; u_int16_t savecsum, tlen; #ifdef INET6 struct ip6_hdr *ip6; u_int32_t len32; u_int8_t nxt; #endif if (data + length > snapend) { printf("snaplen too short, "); return (CANT_CHECK_SIGNATURE); } tp1 = *tp; if (sigsecret == NULL) { printf("shared secret not supplied with -M, "); return (CANT_CHECK_SIGNATURE); } MD5_Init(&ctx); /* * Step 1: Update MD5 hash with IP pseudo-header. */ if (IP_V(ip) == 4) { MD5_Update(&ctx, (char *)&ip->ip_src, sizeof(ip->ip_src)); MD5_Update(&ctx, (char *)&ip->ip_dst, sizeof(ip->ip_dst)); MD5_Update(&ctx, (char *)&zero_proto, sizeof(zero_proto)); MD5_Update(&ctx, (char *)&ip->ip_p, sizeof(ip->ip_p)); tlen = EXTRACT_16BITS(&ip->ip_len) - IP_HL(ip) * 4; tlen = htons(tlen); MD5_Update(&ctx, (char *)&tlen, sizeof(tlen)); #ifdef INET6 } else if (IP_V(ip) == 6) { ip6 = (struct ip6_hdr *)ip; MD5_Update(&ctx, (char *)&ip6->ip6_src, sizeof(ip6->ip6_src)); MD5_Update(&ctx, (char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst)); len32 = htonl(EXTRACT_16BITS(&ip6->ip6_plen)); MD5_Update(&ctx, (char *)&len32, sizeof(len32)); nxt = 0; MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); nxt = IPPROTO_TCP; MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); #endif } else { #ifdef INET6 printf("IP version not 4 or 6, "); #else printf("IP version not 4, "); #endif return (CANT_CHECK_SIGNATURE); } /* * Step 2: Update MD5 hash with TCP header, excluding options. * The TCP checksum must be set to zero. */ savecsum = tp1.th_sum; tp1.th_sum = 0; MD5_Update(&ctx, (char *)&tp1, sizeof(struct tcphdr)); tp1.th_sum = savecsum; /* * Step 3: Update MD5 hash with TCP segment data, if present. */ if (length > 0) MD5_Update(&ctx, data, length); /* * Step 4: Update MD5 hash with shared secret. */ MD5_Update(&ctx, sigsecret, strlen(sigsecret)); MD5_Final(sig, &ctx); if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0) return (SIGNATURE_VALID); else return (SIGNATURE_INVALID); } USES_APPLE_RST #endif /* HAVE_LIBCRYPTO */ /* * Local Variables: * c-style: whitesmith * c-basic-offset: 8 * End: */ tcpdump-4.5.1/print-vtp.c0000644000026300017510000003023212237020316012721 0ustar mcr/* * Copyright (c) 1998-2007 The TCPDUMP project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * 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. * * VLAN TRUNKING PROTOCOL (VTP) * * Reference documentation: * http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml * http://www.cisco.com/warp/public/473/21.html * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm * * Original code ode by Carles Kishimoto */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" #include "nlpid.h" #define VTP_HEADER_LEN 36 #define VTP_DOMAIN_NAME_LEN 32 #define VTP_MD5_DIGEST_LEN 16 #define VTP_UPDATE_TIMESTAMP_LEN 12 #define VTP_VLAN_INFO_OFFSET 12 #define VTP_SUMMARY_ADV 0x01 #define VTP_SUBSET_ADV 0x02 #define VTP_ADV_REQUEST 0x03 #define VTP_JOIN_MESSAGE 0x04 struct vtp_vlan_ { u_int8_t len; u_int8_t status; u_int8_t type; u_int8_t name_len; u_int16_t vlanid; u_int16_t mtu; u_int32_t index; }; static const struct tok vtp_message_type_values[] = { { VTP_SUMMARY_ADV, "Summary advertisement"}, { VTP_SUBSET_ADV, "Subset advertisement"}, { VTP_ADV_REQUEST, "Advertisement request"}, { VTP_JOIN_MESSAGE, "Join message"}, { 0, NULL } }; static const struct tok vtp_header_values[] = { { 0x01, "Followers"}, /* On Summary advertisement, 3rd byte is Followers */ { 0x02, "Seq number"}, /* On Subset advertisement, 3rd byte is Sequence number */ { 0x03, "Rsvd"}, /* On Adver. requests 3rd byte is Rsvd */ { 0x04, "Rsvd"}, /* On Adver. requests 3rd byte is Rsvd */ { 0, NULL } }; static const struct tok vtp_vlan_type_values[] = { { 0x01, "Ethernet"}, { 0x02, "FDDI"}, { 0x03, "TrCRF"}, { 0x04, "FDDI-net"}, { 0x05, "TrBRF"}, { 0, NULL } }; static const struct tok vtp_vlan_status[] = { { 0x00, "Operational"}, { 0x01, "Suspended"}, { 0, NULL } }; #define VTP_VLAN_SOURCE_ROUTING_RING_NUMBER 0x01 #define VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER 0x02 #define VTP_VLAN_STP_TYPE 0x03 #define VTP_VLAN_PARENT_VLAN 0x04 #define VTP_VLAN_TRANS_BRIDGED_VLAN 0x05 #define VTP_VLAN_PRUNING 0x06 #define VTP_VLAN_BRIDGE_TYPE 0x07 #define VTP_VLAN_ARP_HOP_COUNT 0x08 #define VTP_VLAN_STE_HOP_COUNT 0x09 #define VTP_VLAN_BACKUP_CRF_MODE 0x0A static const struct tok vtp_vlan_tlv_values[] = { { VTP_VLAN_SOURCE_ROUTING_RING_NUMBER, "Source-Routing Ring Number TLV"}, { VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER, "Source-Routing Bridge Number TLV"}, { VTP_VLAN_STP_TYPE, "STP type TLV"}, { VTP_VLAN_PARENT_VLAN, "Parent VLAN TLV"}, { VTP_VLAN_TRANS_BRIDGED_VLAN, "Translationally bridged VLANs TLV"}, { VTP_VLAN_PRUNING, "Pruning TLV"}, { VTP_VLAN_BRIDGE_TYPE, "Bridge Type TLV"}, { VTP_VLAN_ARP_HOP_COUNT, "Max ARP Hop Count TLV"}, { VTP_VLAN_STE_HOP_COUNT, "Max STE Hop Count TLV"}, { VTP_VLAN_BACKUP_CRF_MODE, "Backup CRF Mode TLV"}, { 0, NULL } }; static const struct tok vtp_stp_type_values[] = { { 1, "SRT"}, { 2, "SRB"}, { 3, "Auto"}, { 0, NULL } }; void vtp_print (const u_char *pptr, u_int length) { int type, len, tlv_len, tlv_value; const u_char *tptr; const struct vtp_vlan_ *vtp_vlan; if (length < VTP_HEADER_LEN) goto trunc; tptr = pptr; if (!TTEST2(*tptr, VTP_HEADER_LEN)) goto trunc; type = *(tptr+1); printf("VTPv%u, Message %s (0x%02x), length %u", *tptr, tok2str(vtp_message_type_values,"Unknown message type", type), *(tptr+1), length); /* In non-verbose mode, just print version and message type */ if (vflag < 1) { return; } /* verbose mode print all fields */ printf("\n\tDomain name: %s, %s: %u", (tptr+4), tok2str(vtp_header_values,"Unknown",*(tptr+1)), *(tptr+2)); tptr += VTP_HEADER_LEN; switch (type) { case VTP_SUMMARY_ADV: /* * SUMMARY ADVERTISEMENT * * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Version | Code | Followers | MmgtD Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Management Domain Name | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Configuration revision number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Updater Identity IP address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Update Timestamp (12 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | MD5 digest (16 bytes) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ printf("\n\t Config Rev %x, Updater %s", EXTRACT_32BITS(tptr), ipaddr_string(tptr+4)); tptr += 8; printf(", Timestamp 0x%08x 0x%08x 0x%08x", EXTRACT_32BITS(tptr), EXTRACT_32BITS(tptr + 4), EXTRACT_32BITS(tptr + 8)); tptr += VTP_UPDATE_TIMESTAMP_LEN; printf(", MD5 digest: %08x%08x%08x%08x", EXTRACT_32BITS(tptr), EXTRACT_32BITS(tptr + 4), EXTRACT_32BITS(tptr + 8), EXTRACT_32BITS(tptr + 12)); tptr += VTP_MD5_DIGEST_LEN; break; case VTP_SUBSET_ADV: /* * SUBSET ADVERTISEMENT * * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Version | Code | Seq number | MmgtD Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Management Domain Name | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Configuration revision number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VLAN info field 1 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ................ | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VLAN info field N | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ printf(", Config Rev %x", EXTRACT_32BITS(tptr)); /* * VLAN INFORMATION * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | V info len | Status | VLAN type | VLAN name len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | ISL vlan id | MTU size | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | 802.10 index (SAID) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VLAN name | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ tptr += 4; while (tptr < (pptr+length)) { len = *tptr; if (len == 0) break; if (!TTEST2(*tptr, len)) goto trunc; vtp_vlan = (struct vtp_vlan_*)tptr; printf("\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name %s", tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status), tok2str(vtp_vlan_type_values,"Unknown",vtp_vlan->type), EXTRACT_16BITS(&vtp_vlan->vlanid), EXTRACT_16BITS(&vtp_vlan->mtu), EXTRACT_32BITS(&vtp_vlan->index), (tptr + VTP_VLAN_INFO_OFFSET)); /* * Vlan names are aligned to 32-bit boundaries. */ len -= VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4); tptr += VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4); /* TLV information follows */ while (len > 0) { /* * Cisco specs says 2 bytes for type + 2 bytes for length, take only 1 * See: http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm */ type = *tptr; tlv_len = *(tptr+1); printf("\n\t\t%s (0x%04x) TLV", tok2str(vtp_vlan_tlv_values, "Unknown", type), type); /* * infinite loop check */ if (type == 0 || tlv_len == 0) { return; } if (!TTEST2(*tptr, tlv_len*2 +2)) goto trunc; tlv_value = EXTRACT_16BITS(tptr+2); switch (type) { case VTP_VLAN_STE_HOP_COUNT: printf(", %u", tlv_value); break; case VTP_VLAN_PRUNING: printf(", %s (%u)", tlv_value == 1 ? "Enabled" : "Disabled", tlv_value); break; case VTP_VLAN_STP_TYPE: printf(", %s (%u)", tok2str(vtp_stp_type_values, "Unknown", tlv_value), tlv_value); break; case VTP_VLAN_BRIDGE_TYPE: printf(", %s (%u)", tlv_value == 1 ? "SRB" : "SRT", tlv_value); break; case VTP_VLAN_BACKUP_CRF_MODE: printf(", %s (%u)", tlv_value == 1 ? "Backup" : "Not backup", tlv_value); break; /* * FIXME those are the defined TLVs that lack a decoder * you are welcome to contribute code ;-) */ case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER: case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER: case VTP_VLAN_PARENT_VLAN: case VTP_VLAN_TRANS_BRIDGED_VLAN: case VTP_VLAN_ARP_HOP_COUNT: default: print_unknown_data(tptr, "\n\t\t ", 2 + tlv_len*2); break; } len -= 2 + tlv_len*2; tptr += 2 + tlv_len*2; } } break; case VTP_ADV_REQUEST: /* * ADVERTISEMENT REQUEST * * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Version | Code | Reserved | MmgtD Len | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Management Domain Name | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Start value | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ printf("\n\tStart value: %u", EXTRACT_32BITS(tptr)); break; case VTP_JOIN_MESSAGE: /* FIXME - Could not find message format */ break; default: break; } return; trunc: printf("[|vtp]"); } /* * Local Variables: * c-style: whitesmith * c-basic-offset: 4 * End: */ tcpdump-4.5.1/lbl/0000755000026300017510000000000012243146376011377 5ustar mcrtcpdump-4.5.1/lbl/os-solaris2.h0000644000026300017510000000276512237020316013723 0ustar mcr/* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header: /tcpdump/master/tcpdump/lbl/os-solaris2.h,v 1.19 2000-10-11 04:02:15 guy Exp $ (LBL) */ /* Prototypes missing in SunOS 5 */ #if defined(_STDIO_H) && defined(HAVE_SETLINEBUF) int setlinebuf(FILE *); #endif char *strerror(int); int snprintf(char *, size_t, const char *, ...); int strcasecmp(const char *, const char *); tcpdump-4.5.1/lbl/os-sunos4.h0000644000026300017510000001417112237020316013412 0ustar mcr/* * Copyright (c) 1989, 1990, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header: /tcpdump/master/tcpdump/lbl/os-sunos4.h,v 1.32 1999-10-07 23:47:13 mcr Exp $ (LBL) */ /* Prototypes missing in SunOS 4 */ #ifdef FILE int _filbuf(FILE *); int _flsbuf(u_char, FILE *); int fclose(FILE *); int fflush(FILE *); int fgetc(FILE *); int fprintf(FILE *, const char *, ...); int fputc(int, FILE *); int fputs(const char *, FILE *); u_int fread(void *, u_int, u_int, FILE *); int fseek(FILE *, long, int); u_int fwrite(const void *, u_int, u_int, FILE *); int pclose(FILE *); void rewind(FILE *); void setbuf(FILE *, char *); int setlinebuf(FILE *); int ungetc(int, FILE *); int vfprintf(FILE *, const char *, ...); int vprintf(const char *, ...); #endif #if __GNUC__ <= 1 int read(int, char *, u_int); int write(int, char *, u_int); #endif long a64l(const char *); #ifdef __STDC__ struct sockaddr; #endif int accept(int, struct sockaddr *, int *); int bind(int, struct sockaddr *, int); int bcmp(const void *, const void *, u_int); void bcopy(const void *, void *, u_int); void bzero(void *, int); int chroot(const char *); int close(int); void closelog(void); int connect(int, struct sockaddr *, int); char *crypt(const char *, const char *); int daemon(int, int); int fchmod(int, int); int fchown(int, int, int); void endgrent(void); void endpwent(void); void endservent(void); #ifdef __STDC__ struct ether_addr; #endif struct ether_addr *ether_aton(const char *); int flock(int, int); #ifdef __STDC__ struct stat; #endif int fstat(int, struct stat *); #ifdef __STDC__ struct statfs; #endif int fstatfs(int, struct statfs *); int fsync(int); #ifdef __STDC__ struct timeb; #endif int ftime(struct timeb *); int ftruncate(int, off_t); int getdtablesize(void); long gethostid(void); int gethostname(char *, int); int getopt(int, char * const *, const char *); int getpagesize(void); char *getpass(char *); int getpeername(int, struct sockaddr *, int *); int getpriority(int, int); #ifdef __STDC__ struct rlimit; #endif int getrlimit(int, struct rlimit *); int getsockname(int, struct sockaddr *, int *); int getsockopt(int, int, int, char *, int *); #ifdef __STDC__ struct timeval; struct timezone; #endif int gettimeofday(struct timeval *, struct timezone *); char *getusershell(void); char *getwd(char *); int initgroups(const char *, int); int ioctl(int, int, caddr_t); int iruserok(u_long, int, char *, char *); int isatty(int); int killpg(int, int); int listen(int, int); #ifdef __STDC__ struct utmp; #endif void login(struct utmp *); int logout(const char *); off_t lseek(int, off_t, int); int lstat(const char *, struct stat *); int mkstemp(char *); char *mktemp(char *); int munmap(caddr_t, int); void openlog(const char *, int, int); void perror(const char *); int printf(const char *, ...); int puts(const char *); long random(void); int readlink(const char *, char *, int); #ifdef __STDC__ struct iovec; #endif int readv(int, struct iovec *, int); int recv(int, char *, u_int, int); int recvfrom(int, char *, u_int, int, struct sockaddr *, int *); int rename(const char *, const char *); int rcmd(char **, u_short, char *, char *, char *, int *); int rresvport(int *); int send(int, char *, u_int, int); int sendto(int, char *, u_int, int, struct sockaddr *, int); int setenv(const char *, const char *, int); int seteuid(int); int setpriority(int, int, int); int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); int setpgrp(int, int); void setpwent(void); int setrlimit(int, struct rlimit *); void setservent(int); int setsockopt(int, int, int, char *, int); int shutdown(int, int); int sigblock(int); void (*signal (int, void (*) (int))) (int); int sigpause(int); int sigsetmask(int); #ifdef __STDC__ struct sigvec; #endif int sigvec(int, struct sigvec *, struct sigvec*); int snprintf(char *, size_t, const char *, ...); int socket(int, int, int); int socketpair(int, int, int, int *); int symlink(const char *, const char *); void srandom(int); int sscanf(char *, const char *, ...); int stat(const char *, struct stat *); int statfs(char *, struct statfs *); char *strerror(int); int strcasecmp(const char *, const char *); #ifdef __STDC__ struct tm; #endif int strftime(char *, int, char *, struct tm *); int strncasecmp(const char *, const char *, int); long strtol(const char *, char **, int); void sync(void); void syslog(int, const char *, ...); int system(const char *); long tell(int); time_t time(time_t *); char *timezone(int, int); int tolower(int); int toupper(int); int truncate(char *, off_t); void unsetenv(const char *); int vfork(void); int vsprintf(char *, const char *, ...); int writev(int, struct iovec *, int); #ifdef __STDC__ struct rusage; #endif int utimes(const char *, struct timeval *); #if __GNUC__ <= 1 int wait(int *); pid_t wait3(int *, int, struct rusage *); #endif /* Ugly signal hacking */ #ifdef SIG_ERR #undef SIG_ERR #define SIG_ERR (void (*)(int))-1 #undef SIG_DFL #define SIG_DFL (void (*)(int))0 #undef SIG_IGN #define SIG_IGN (void (*)(int))1 #ifdef KERNEL #undef SIG_CATCH #define SIG_CATCH (void (*)(int))2 #endif #undef SIG_HOLD #define SIG_HOLD (void (*)(int))3 #endif tcpdump-4.5.1/lbl/os-osf4.h0000644000026300017510000000263212237020316013031 0ustar mcr/* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header: /tcpdump/master/tcpdump/lbl/os-osf4.h,v 1.1 2002-12-11 05:03:13 guy Exp $ (LBL) */ /* Prototypes missing in Digital UNIX 4.x */ int snprintf(char *, size_t, const char *, ...); int vsnprintf(char *, size_t, const char *, va_list); tcpdump-4.5.1/lbl/os-ultrix4.h0000644000026300017510000000335312237020316013572 0ustar mcr/* * Copyright (c) 1990, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header: /tcpdump/master/tcpdump/lbl/os-ultrix4.h,v 1.19 1999-10-07 23:47:13 mcr Exp $ (LBL) */ /* Prototypes missing in Ultrix 4 */ int bcmp(const char *, const char *, u_int); void bcopy(const void *, void *, u_int); void bzero(void *, u_int); void endservent(void); int getopt(int, char * const *, const char *); #ifdef __STDC__ struct timeval; struct timezone; #endif int gettimeofday(struct timeval *, struct timezone *); int ioctl(int, int, caddr_t); int pfopen(char *, int); int setlinebuf(FILE *); int socket(int, int, int); int strcasecmp(const char *, const char *); tcpdump-4.5.1/print-cip.c0000644000026300017510000000523412237020316012667 0ustar mcr/* * Marko Kiiskila carnil@cs.tut.fi * * Tampere University of Technology - Telecommunications Laboratory * * Permission to use, copy, modify and distribute this * software and its documentation is hereby granted, * provided that both the copyright notice and this * permission notice appear in all copies of the software, * derivative works or modified versions, and any portions * thereof, that both notices appear in supporting * documentation, and that the use of this software is * acknowledged in any publications resulting from using * the software. * * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS * SOFTWARE. * */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-cip.c,v 1.26 2005-07-07 01:22:17 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "interface.h" #include "addrtoname.h" #include "ethertype.h" #include "ether.h" #define RFC1483LLC_LEN 8 static unsigned char rfcllc[] = { 0xaa, /* DSAP: non-ISO */ 0xaa, /* SSAP: non-ISO */ 0x03, /* Ctrl: Unnumbered Information Command PDU */ 0x00, /* OUI: EtherType */ 0x00, 0x00 }; static inline void cip_print(int length) { /* * There is no MAC-layer header, so just print the length. */ printf("%d: ", length); } /* * This is the top level routine of the printer. 'p' points * to the LLC/SNAP or raw header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ u_int cip_if_print(const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; u_short extracted_ethertype; if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) { printf("[|cip]"); return (0); } if (eflag) cip_print(length); if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) { /* * LLC header is present. Try to print it & higher layers. */ if (llc_print(p, length, caplen, NULL, NULL, &extracted_ethertype) == 0) { /* ether_type not known, print raw packet */ if (!eflag) cip_print(length); if (extracted_ethertype) { printf("(LLC %s) ", etherproto_string(htons(extracted_ethertype))); } if (!suppress_default_print) default_print(p, caplen); } } else { /* * LLC header is absent; treat it as just IP. */ ip_print(gndo, p, length); } return (0); } /* * Local Variables: * c-style: whitesmith * c-basic-offset: 8 * End: */ tcpdump-4.5.1/print-lspping.c0000644000026300017510000012251612237020316013573 0ustar mcr/* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * Original code by Hannes Gredler (hannes@juniper.net) */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.20 2008-01-28 14:20:43 hannes Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "interface.h" #include "extract.h" #include "addrtoname.h" #include "bgp.h" #include "l2vpn.h" #include "oui.h" /* * LSPPING common header * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Version Number | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Message Type | Reply mode | Return Code | Return Subcode| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Sender's Handle | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Sequence Number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | TimeStamp Sent (seconds) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | TimeStamp Sent (microseconds) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | TimeStamp Received (seconds) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | TimeStamp Received (microseconds) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | TLVs ... | * . . * . . * . . */ struct lspping_common_header { u_int8_t version[2]; u_int8_t reserved[2]; u_int8_t msg_type; u_int8_t reply_mode; u_int8_t return_code; u_int8_t return_subcode; u_int8_t sender_handle[4]; u_int8_t seq_number[4]; u_int8_t ts_sent_sec[4]; u_int8_t ts_sent_usec[4]; u_int8_t ts_rcvd_sec[4]; u_int8_t ts_rcvd_usec[4]; }; #define LSPPING_VERSION 1 static const struct tok lspping_msg_type_values[] = { { 1, "MPLS Echo Request"}, { 2, "MPLS Echo Reply"}, { 0, NULL} }; static const struct tok lspping_reply_mode_values[] = { { 1, "Do not reply"}, { 2, "Reply via an IPv4/IPv6 UDP packet"}, { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"}, { 4, "Reply via application level control channel"}, { 0, NULL} }; static const struct tok lspping_return_code_values[] = { { 0, "No return code or return code contained in the Error Code TLV"}, { 1, "Malformed echo request received"}, { 2, "One or more of the TLVs was not understood"}, { 3, "Replying router is an egress for the FEC at stack depth"}, { 4, "Replying router has no mapping for the FEC at stack depth"}, { 5, "Reserved"}, { 6, "Reserved"}, { 7, "Reserved"}, { 8, "Label switched at stack-depth"}, { 9, "Label switched but no MPLS forwarding at stack-depth"}, { 10, "Mapping for this FEC is not the given label at stack depth"}, { 11, "No label entry at stack-depth"}, { 12, "Protocol not associated with interface at FEC stack depth"}, }; /* * LSPPING TLV header * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Type | Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Value | * . . * . . * . . * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_header { u_int8_t type[2]; u_int8_t length[2]; }; #define LSPPING_TLV_TARGET_FEC_STACK 1 #define LSPPING_TLV_DOWNSTREAM_MAPPING 2 #define LSPPING_TLV_PAD 3 #define LSPPING_TLV_VENDOR_ENTERPRISE 5 #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4 #define LSPPING_TLV_INTERFACE_LABEL_STACK 7 #define LSPPING_TLV_ERROR_CODE 9 #define LSPPING_TLV_REPLY_TOS_BYTE 10 #define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */ #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4 #define LSPPING_TLV_VENDOR_PRIVATE 0xfc00 static const struct tok lspping_tlv_values[] = { { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" }, { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" }, { LSPPING_TLV_PAD, "Pad" }, { LSPPING_TLV_ERROR_CODE, "Error Code" }, { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" }, { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" }, { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" }, { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" }, { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" }, { 0, NULL} }; #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1 #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2 #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3 #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4 #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6 #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7 #define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8 #define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD 9 #define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID 10 #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 11 #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 12 static const struct tok lspping_tlvtargetfec_subtlv_values[] = { { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"}, { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"}, { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"}, { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"}, { 5, "Reserved"}, { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"}, { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"}, { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"}, { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD, "L2 circuit ID (old)"}, { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID, "L2 circuit ID"}, { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"}, { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"}, { 0, NULL} }; /* * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv4 prefix | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Prefix Length | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t { u_int8_t prefix [4]; u_int8_t prefix_len; }; /* * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv6 prefix | * | (16 octets) | * | | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Prefix Length | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t { u_int8_t prefix [16]; u_int8_t prefix_len; }; /* * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Sender identifier | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv4 prefix | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Prefix Length | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t { u_int8_t sender_id [4]; u_int8_t prefix [4]; u_int8_t prefix_len; }; /* * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Sender identifier | * | (16 octets) | * | | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv6 prefix | * | (16 octets) | * | | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Prefix Length | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t { u_int8_t sender_id [16]; u_int8_t prefix [16]; u_int8_t prefix_len; }; /* * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv4 tunnel end point address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Must Be Zero | Tunnel ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Extended Tunnel ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv4 tunnel sender address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Must Be Zero | LSP ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t { u_int8_t tunnel_endpoint [4]; u_int8_t res[2]; u_int8_t tunnel_id[2]; u_int8_t extended_tunnel_id[4]; u_int8_t tunnel_sender [4]; u_int8_t res2[2]; u_int8_t lsp_id [2]; }; /* * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv6 tunnel end point address | * | | * | | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Must Be Zero | Tunnel ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Extended Tunnel ID | * | | * | | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv6 tunnel sender address | * | | * | | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Must Be Zero | LSP ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t { u_int8_t tunnel_endpoint [16]; u_int8_t res[2]; u_int8_t tunnel_id[2]; u_int8_t extended_tunnel_id[16]; u_int8_t tunnel_sender [16]; u_int8_t res2[2]; u_int8_t lsp_id [2]; }; /* * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Route Distinguisher | * | (8 octets) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv4 prefix | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Prefix Length | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t { u_int8_t rd [8]; u_int8_t prefix [4]; u_int8_t prefix_len; }; /* * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Route Distinguisher | * | (8 octets) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IPv6 prefix | * | (16 octets) | * | | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Prefix Length | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t { u_int8_t rd [8]; u_int8_t prefix [16]; u_int8_t prefix_len; }; /* * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Route Distinguisher | * | (8 octets) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Sender's CE ID | Receiver's CE ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Encapsulation Type | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 0 1 2 3 */ struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t { u_int8_t rd [8]; u_int8_t sender_ce_id [2]; u_int8_t receiver_ce_id [2]; u_int8_t encapsulation[2]; }; /* * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Remote PE Address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VC ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Encapsulation Type | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t { u_int8_t remote_pe_address [4]; u_int8_t vc_id [4]; u_int8_t encapsulation[2]; }; /* * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Sender's PE Address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Remote PE Address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | VC ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Encapsulation Type | Must Be Zero | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t { u_int8_t sender_pe_address [4]; u_int8_t remote_pe_address [4]; u_int8_t vc_id [4]; u_int8_t encapsulation[2]; }; /* * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | MTU | Address Type | Resvd (SBZ) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Downstream IP Address (4 or 16 octets) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Downstream Interface Address (4 or 16 octets) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Hash Key Type | Depth Limit | Multipath Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * . . * . (Multipath Information) . * . . * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Downstream Label | Protocol | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * . . * . . * . . * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Downstream Label | Protocol | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct lspping_tlv_downstream_map_ipv4_t { u_int8_t mtu [2]; u_int8_t address_type; u_int8_t res; u_int8_t downstream_ip[4]; u_int8_t downstream_interface[4]; }; struct lspping_tlv_downstream_map_ipv6_t { u_int8_t mtu [2]; u_int8_t address_type; u_int8_t res; u_int8_t downstream_ip[16]; u_int8_t downstream_interface[16]; }; struct lspping_tlv_downstream_map_info_t { u_int8_t hash_key_type; u_int8_t depth_limit; u_int8_t multipath_length [2]; }; #define LSPPING_AFI_IPV4 1 #define LSPPING_AFI_UNMB 2 #define LSPPING_AFI_IPV6 3 static const struct tok lspping_tlv_downstream_addr_values[] = { { LSPPING_AFI_IPV4, "IPv4"}, { LSPPING_AFI_IPV6, "IPv6"}, { LSPPING_AFI_UNMB, "Unnumbered"}, { 0, NULL} }; void lspping_print(register const u_char *pptr, register u_int len) { const struct lspping_common_header *lspping_com_header; const struct lspping_tlv_header *lspping_tlv_header; const struct lspping_tlv_header *lspping_subtlv_header; const u_char *tptr,*tlv_tptr,*subtlv_tptr; int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen; int tlv_hexdump,subtlv_hexdump; int lspping_subtlv_len,lspping_subtlv_type; struct timeval timestamp; union { const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4; const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6; const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info; } tlv_ptr; union { const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4; const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6; const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4; const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6; const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4; const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6; const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt; const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old; const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid; const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4; const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6; } subtlv_ptr; tptr=pptr; lspping_com_header = (const struct lspping_common_header *)pptr; TCHECK(*lspping_com_header); /* * Sanity checking of the header. */ if (EXTRACT_16BITS(&lspping_com_header->version[0]) != LSPPING_VERSION) { printf("LSP-PING version %u packet not supported", EXTRACT_16BITS(&lspping_com_header->version[0])); return; } /* in non-verbose mode just lets print the basic Message Type*/ if (vflag < 1) { printf("LSP-PINGv%u, %s, seq %u, length: %u", EXTRACT_16BITS(&lspping_com_header->version[0]), tok2str(lspping_msg_type_values, "unknown (%u)",lspping_com_header->msg_type), EXTRACT_32BITS(lspping_com_header->seq_number), len); return; } /* ok they seem to want to know everything - lets fully decode it */ tlen=len; printf("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)", EXTRACT_16BITS(&lspping_com_header->version[0]), tok2str(lspping_msg_type_values, "unknown",lspping_com_header->msg_type), lspping_com_header->msg_type, len, tok2str(lspping_reply_mode_values, "unknown",lspping_com_header->reply_mode), lspping_com_header->reply_mode); /* * the following return codes require that the subcode is attached * at the end of the translated token output */ if (lspping_com_header->return_code == 3 || lspping_com_header->return_code == 4 || lspping_com_header->return_code == 8 || lspping_com_header->return_code == 10 || lspping_com_header->return_code == 11 || lspping_com_header->return_code == 12 ) printf("\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)", tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code), lspping_com_header->return_subcode, lspping_com_header->return_code, lspping_com_header->return_subcode); else printf("\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)", tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code), lspping_com_header->return_code, lspping_com_header->return_subcode); printf("\n\t Sender Handle: 0x%08x, Sequence: %u", EXTRACT_32BITS(lspping_com_header->sender_handle), EXTRACT_32BITS(lspping_com_header->seq_number)); timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_sent_sec); timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_sent_usec); printf("\n\t Sender Timestamp: "); ts_print(×tamp); timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec); timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec); printf("Receiver Timestamp: "); if ((timestamp.tv_sec != 0) && (timestamp.tv_usec != 0)) ts_print(×tamp); else printf("no timestamp"); tptr+=sizeof(const struct lspping_common_header); tlen-=sizeof(const struct lspping_common_header); while(tlen>(int)sizeof(struct lspping_tlv_header)) { /* did we capture enough for fully decoding the tlv header ? */ if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header))) goto trunc; lspping_tlv_header = (const struct lspping_tlv_header *)tptr; lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type); lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length); /* some little sanity checking */ if (lspping_tlv_type == 0 || lspping_tlv_len == 0) return; if(lspping_tlv_len < 4) { printf("\n\t ERROR: TLV %u bogus size %u",lspping_tlv_type,lspping_tlv_len); return; } printf("\n\t %s TLV (%u), length: %u", tok2str(lspping_tlv_values, "Unknown", lspping_tlv_type), lspping_tlv_type, lspping_tlv_len); tlv_tptr=tptr+sizeof(struct lspping_tlv_header); tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */ /* did we capture enough for fully decoding the tlv ? */ if (!TTEST2(*tptr, lspping_tlv_len)) goto trunc; tlv_hexdump=FALSE; switch(lspping_tlv_type) { case LSPPING_TLV_TARGET_FEC_STACK: while(tlv_tlen>(int)sizeof(struct lspping_tlv_header)) { /* did we capture enough for fully decoding the subtlv header ? */ if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header))) goto trunc; subtlv_hexdump=FALSE; lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr; lspping_subtlv_type=EXTRACT_16BITS(lspping_subtlv_header->type); lspping_subtlv_len=EXTRACT_16BITS(lspping_subtlv_header->length); subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header); if (lspping_subtlv_len == 0) break; printf("\n\t %s subTLV (%u), length: %u", tok2str(lspping_tlvtargetfec_subtlv_values, "Unknown", lspping_subtlv_type), lspping_subtlv_type, lspping_subtlv_len); switch(lspping_subtlv_type) { case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4: subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 = \ (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr; printf("\n\t %s/%u", ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix), subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len); break; #ifdef INET6 case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6: subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 = \ (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr; printf("\n\t %s/%u", ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix), subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len); break; #endif case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4: subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 = \ (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr; printf("\n\t %s/%u, sender-id %s", ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix), subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len, ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->sender_id)); break; #ifdef INET6 case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6: subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 = \ (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr; printf("\n\t %s/%u, sender-id %s", ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix), subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len, ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->sender_id)); break; #endif case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4: subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 = \ (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr; printf("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \ "\n\t tunnel-id 0x%04x, extended tunnel-id %s", ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint), ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender), EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id), EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id), ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id)); break; #ifdef INET6 case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6: subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 = \ (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr; printf("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \ "\n\t tunnel-id 0x%04x, extended tunnel-id %s", ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint), ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender), EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id), EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id), ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id)); break; #endif case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4: subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 = \ (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr; printf("\n\t RD: %s, %s/%u", bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd), ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix), subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len); break; #ifdef INET6 case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6: subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 = \ (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr; printf("\n\t RD: %s, %s/%u", bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd), ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix), subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len); break; #endif case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT: subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt = \ (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr; printf("\n\t RD: %s, Sender CE-ID: %u, Receiver CE-ID: %u" \ "\n\t Encapsulation Type: %s (%u)", bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd), EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ce_id), EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ce_id), tok2str(l2vpn_encaps_values, "unknown", EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)), EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)); break; /* the old L2VPN VCID subTLV does not have support for the sender field */ case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD: subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = \ (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *)subtlv_tptr; printf("\n\t Remote PE: %s" \ "\n\t VC-ID: 0x%08x, Encapsulation Type: %s (%u)", ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address), EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->vc_id), tok2str(l2vpn_encaps_values, "unknown", EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)), EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)); break; case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID: subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = \ (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *)subtlv_tptr; printf("\n\t Sender PE: %s, Remote PE: %s" \ "\n\t VC-ID: 0x%08x, Encapsulation Type: %s (%u)", ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address), ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address), EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->vc_id), tok2str(l2vpn_encaps_values, "unknown", EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)), EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)); break; default: subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ break; } /* do we want to see an additionally subtlv hexdump ? */ if (vflag > 1 || subtlv_hexdump==TRUE) print_unknown_data(tlv_tptr+sizeof(struct lspping_tlv_header), \ "\n\t ", lspping_subtlv_len); tlv_tptr+=lspping_subtlv_len; tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header); } break; case LSPPING_TLV_DOWNSTREAM_MAPPING: /* that strange thing with the downstream map TLV is that until now * we do not know if its IPv4 or IPv6 , after we found the adress-type * lets recast the tlv_tptr and move on */ tlv_ptr.lspping_tlv_downstream_map_ipv4= \ (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr; tlv_ptr.lspping_tlv_downstream_map_ipv6= \ (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr; printf("\n\t MTU: %u, Address-Type: %s (%u)", EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->mtu), tok2str(lspping_tlv_downstream_addr_values, "unknown", tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type), tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type); switch(tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type) { case LSPPING_AFI_IPV4: printf("\n\t Downstream IP: %s" \ "\n\t Downstream Interface IP: %s", ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)); tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); break; #ifdef INET6 case LSPPING_AFI_IPV6: printf("\n\t Downstream IP: %s" \ "\n\t Downstream Interface IP: %s", ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip), ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface)); tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t); break; #endif case LSPPING_AFI_UNMB: printf("\n\t Downstream IP: %s" \ "\n\t Downstream Interface Index: 0x%08x", ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)); tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); break; default: /* should not happen ! - no error message - tok2str() has barked already */ break; } tlv_ptr.lspping_tlv_downstream_map_info= \ (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr; /* FIXME add hash-key type, depth limit, multipath processing */ tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_info_t); tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_info_t); /* FIXME print downstream labels */ tlv_hexdump=TRUE; /* dump the TLV until code complete */ break; case LSPPING_TLV_BFD_DISCRIMINATOR: tptr += sizeof(struct lspping_tlv_header); if (!TTEST2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN)) goto trunc; printf("\n\t BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr)); break; case LSPPING_TLV_VENDOR_ENTERPRISE: { u_int32_t vendor_id; if (!TTEST2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN)) goto trunc; vendor_id = EXTRACT_32BITS(tlv_tptr); printf("\n\t Vendor: %s (0x%04x)", tok2str(smi_values, "Unknown", vendor_id), vendor_id); } break; /* * FIXME those are the defined TLVs that lack a decoder * you are welcome to contribute code ;-) */ case LSPPING_TLV_PAD: case LSPPING_TLV_ERROR_CODE: case LSPPING_TLV_VENDOR_PRIVATE: default: if (vflag <= 1) print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen); break; } /* do we want to see an additionally tlv hexdump ? */ if (vflag > 1 || tlv_hexdump==TRUE) print_unknown_data(tptr+sizeof(struct lspping_tlv_header),"\n\t ", lspping_tlv_len); /* All TLVs are aligned to four octet boundary */ if (lspping_tlv_len % 4) { lspping_tlv_len += (4 - lspping_tlv_len % 4); } tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header); tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header); } return; trunc: printf("\n\t\t packet exceeded snapshot"); } tcpdump-4.5.1/print-udld.c0000644000026300017510000001072512237020316013045 0ustar mcr/* * Copyright (c) 1998-2007 The TCPDUMP project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * 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. * * UNIDIRECTIONAL LINK DETECTION (UDLD) as per * http://www.ietf.org/internet-drafts/draft-foschiano-udld-02.txt * * Original code by Carles Kishimoto */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" #include "nlpid.h" #define UDLD_HEADER_LEN 4 #define UDLD_DEVICE_ID_TLV 0x0001 #define UDLD_PORT_ID_TLV 0x0002 #define UDLD_ECHO_TLV 0x0003 #define UDLD_MESSAGE_INTERVAL_TLV 0x0004 #define UDLD_TIMEOUT_INTERVAL_TLV 0x0005 #define UDLD_DEVICE_NAME_TLV 0x0006 #define UDLD_SEQ_NUMBER_TLV 0x0007 static const struct tok udld_tlv_values[] = { { UDLD_DEVICE_ID_TLV, "Device-ID TLV"}, { UDLD_PORT_ID_TLV, "Port-ID TLV"}, { UDLD_ECHO_TLV, "Echo TLV"}, { UDLD_MESSAGE_INTERVAL_TLV, "Message Interval TLV"}, { UDLD_TIMEOUT_INTERVAL_TLV, "Timeout Interval TLV"}, { UDLD_DEVICE_NAME_TLV, "Device Name TLV"}, { UDLD_SEQ_NUMBER_TLV,"Sequence Number TLV"}, { 0, NULL} }; static const struct tok udld_code_values[] = { { 0x00, "Reserved"}, { 0x01, "Probe message"}, { 0x02, "Echo message"}, { 0x03, "Flush message"}, { 0, NULL} }; static const struct tok udld_flags_values[] = { { 0x00, "RT"}, { 0x01, "RSY"}, { 0, NULL} }; /* * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Ver | Opcode | Flags | Checksum | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | List of TLVs (variable length list) | * | ... | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ #define UDLD_EXTRACT_VERSION(x) (((x)&0xe0)>>5) #define UDLD_EXTRACT_OPCODE(x) ((x)&0x1f) void udld_print (const u_char *pptr, u_int length) { int code, type, len; const u_char *tptr; if (length < UDLD_HEADER_LEN) goto trunc; tptr = pptr; if (!TTEST2(*tptr, UDLD_HEADER_LEN)) goto trunc; code = UDLD_EXTRACT_OPCODE(*tptr); printf("UDLDv%u, Code %s (%x), Flags [%s] (0x%02x), length %u", UDLD_EXTRACT_VERSION(*tptr), tok2str(udld_code_values, "Reserved", code), code, bittok2str(udld_flags_values, "none", *(tptr+1)), *(tptr+1), length); /* * In non-verbose mode, just print version and opcode type */ if (vflag < 1) { return; } printf("\n\tChecksum 0x%04x (unverified)", EXTRACT_16BITS(tptr+2)); tptr += UDLD_HEADER_LEN; while (tptr < (pptr+length)) { if (!TTEST2(*tptr, 4)) goto trunc; type = EXTRACT_16BITS(tptr); len = EXTRACT_16BITS(tptr+2); len -= 4; tptr += 4; /* infinite loop check */ if (type == 0 || len == 0) { return; } printf("\n\t%s (0x%04x) TLV, length %u", tok2str(udld_tlv_values, "Unknown", type), type, len); switch (type) { case UDLD_DEVICE_ID_TLV: case UDLD_PORT_ID_TLV: case UDLD_ECHO_TLV: case UDLD_DEVICE_NAME_TLV: printf(", %s", tptr); break; case UDLD_MESSAGE_INTERVAL_TLV: case UDLD_TIMEOUT_INTERVAL_TLV: printf(", %us", (*tptr)); break; case UDLD_SEQ_NUMBER_TLV: printf(", %u", EXTRACT_32BITS(tptr)); break; default: break; } tptr += len; } return; trunc: printf("[|udld]"); } /* * Local Variables: * c-style: whitesmith * c-basic-offset: 4 * End: */ tcpdump-4.5.1/gmpls.h0000644000026300017510000000274612237020316012116 0ustar mcr/* @(#) $Header: /tcpdump/master/tcpdump/gmpls.h,v 1.5 2006-04-14 07:11:59 hannes Exp $ (LBL) */ /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * Original code by Hannes Gredler (hannes@juniper.net) */ #define GMPLS_PSC1 1 #define GMPLS_PSC2 2 #define GMPLS_PSC3 3 #define GMPLS_PSC4 4 #define GMPLS_L2SC 51 #define GMPLS_TSC 100 #define GMPLS_LSC 150 #define GMPLS_FSC 200 extern const struct tok gmpls_link_prot_values[]; extern const struct tok gmpls_switch_cap_values[]; extern const struct tok gmpls_switch_cap_tsc_indication_values[]; extern const struct tok gmpls_encoding_values[]; extern const struct tok gmpls_payload_values[]; extern const struct tok diffserv_te_bc_values[]; extern const struct tok lmp_sd_service_config_cpsa_link_type_values[]; extern const struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[]; extern const struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[]; tcpdump-4.5.1/print-802_11.c0000644000026300017510000017240712237020316012735 0ustar mcr/* * Copyright (c) 2001 * Fortress Technologies, Inc. All rights reserved. * Charlie Lenahan (clenahan@fortresstech.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "interface.h" #include "addrtoname.h" #include "ethertype.h" #include "extract.h" #include "cpack.h" #include "ieee802_11.h" #include "ieee802_11_radio.h" /* Radiotap state */ /* This is used to save state when parsing/processing parameters */ struct radiotap_state { u_int32_t present; u_int8_t rate; }; #define PRINT_SSID(p) \ if (p.ssid_present) { \ printf(" ("); \ fn_print(p.ssid.ssid, NULL); \ printf(")"); \ } #define PRINT_RATE(_sep, _r, _suf) \ printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf) #define PRINT_RATES(p) \ if (p.rates_present) { \ int z; \ const char *sep = " ["; \ for (z = 0; z < p.rates.length ; z++) { \ PRINT_RATE(sep, p.rates.rate[z], \ (p.rates.rate[z] & 0x80 ? "*" : "")); \ sep = " "; \ } \ if (p.rates.length != 0) \ printf(" Mbit]"); \ } #define PRINT_DS_CHANNEL(p) \ if (p.ds_present) \ printf(" CH: %u", p.ds.channel); \ printf("%s", \ CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" ); #define MAX_MCS_INDEX 76 /* * Indices are: * * the MCS index (0-76); * * 0 for 20 MHz, 1 for 40 MHz; * * 0 for a long guard interval, 1 for a short guard interval. */ static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = { /* MCS 0 */ { /* 20 Mhz */ { 6.5, /* SGI */ 7.2, }, /* 40 Mhz */ { 13.5, /* SGI */ 15.0, }, }, /* MCS 1 */ { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, }, /* 40 Mhz */ { 27.0, /* SGI */ 30.0, }, }, /* MCS 2 */ { /* 20 Mhz */ { 19.5, /* SGI */ 21.7, }, /* 40 Mhz */ { 40.5, /* SGI */ 45.0, }, }, /* MCS 3 */ { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, }, /* 40 Mhz */ { 54.0, /* SGI */ 60.0, }, }, /* MCS 4 */ { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, }, /* MCS 5 */ { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, }, /* MCS 6 */ { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, }, /* 40 Mhz */ { 121.5, /* SGI */ 135.0, }, }, /* MCS 7 */ { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, }, /* MCS 8 */ { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, }, /* 40 Mhz */ { 27.0, /* SGI */ 30.0, }, }, /* MCS 9 */ { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, }, /* 40 Mhz */ { 54.0, /* SGI */ 60.0, }, }, /* MCS 10 */ { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, }, /* MCS 11 */ { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, }, /* MCS 12 */ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, }, /* MCS 13 */ { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, }, /* MCS 14 */ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, }, /* MCS 15 */ { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, }, /* 40 Mhz */ { 270.0, /* SGI */ 300.0, }, }, /* MCS 16 */ { /* 20 Mhz */ { 19.5, /* SGI */ 21.7, }, /* 40 Mhz */ { 40.5, /* SGI */ 45.0, }, }, /* MCS 17 */ { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, }, /* MCS 18 */ { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, }, /* 40 Mhz */ { 121.5, /* SGI */ 135.0, }, }, /* MCS 19 */ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, }, /* MCS 20 */ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, }, /* MCS 21 */ { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, }, /* MCS 22 */ { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, }, /* 40 Mhz */ { 364.5, /* SGI */ 405.0, }, }, /* MCS 23 */ { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, }, /* 40 Mhz */ { 405.0, /* SGI */ 450.0, }, }, /* MCS 24 */ { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, }, /* 40 Mhz */ { 54.0, /* SGI */ 60.0, }, }, /* MCS 25 */ { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, }, /* MCS 26 */ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, }, /* MCS 27 */ { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, }, /* MCS 28 */ { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, }, /* MCS 29 */ { /* 20 Mhz */ { 208.0, /* SGI */ 231.1, }, /* 40 Mhz */ { 432.0, /* SGI */ 480.0, }, }, /* MCS 30 */ { /* 20 Mhz */ { 234.0, /* SGI */ 260.0, }, /* 40 Mhz */ { 486.0, /* SGI */ 540.0, }, }, /* MCS 31 */ { /* 20 Mhz */ { 260.0, /* SGI */ 288.9, }, /* 40 Mhz */ { 540.0, /* SGI */ 600.0, }, }, /* MCS 32 */ { /* 20 Mhz */ { 0.0, /* SGI */ 0.0, }, /* not valid */ /* 40 Mhz */ { 6.0, /* SGI */ 6.7, }, }, /* MCS 33 */ { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, }, /* 40 Mhz */ { 81.0, /* SGI */ 90.0, }, }, /* MCS 34 */ { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, }, /* MCS 35 */ { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, }, /* MCS 36 */ { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, }, /* 40 Mhz */ { 121.5, /* SGI */ 135.0, }, }, /* MCS 37 */ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, }, /* MCS 38 */ { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, }, /* MCS 39 */ { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, }, /* 40 Mhz */ { 108.0, /* SGI */ 120.0, }, }, /* MCS 40 */ { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, }, /* MCS 41 */ { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, }, /* MCS 42 */ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, }, /* MCS 43 */ { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, }, /* MCS 44 */ { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, }, /* MCS 45 */ { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, }, /* MCS 46 */ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, }, /* MCS 47 */ { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, }, /* MCS 48 */ { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, }, /* MCS 49 */ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, }, /* MCS 50 */ { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, }, /* MCS 51 */ { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, }, /* MCS 52 */ { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, }, /* MCS 53 */ { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, }, /* 40 Mhz */ { 135.0, /* SGI */ 150.0, }, }, /* MCS 54 */ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, }, /* MCS 55 */ { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, }, /* MCS 56 */ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, }, /* 40 Mhz */ { 162.0, /* SGI */ 180.0, }, }, /* MCS 57 */ { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, }, /* 40 Mhz */ { 189.0, /* SGI */ 210.0, }, }, /* MCS 58 */ { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, }, /* MCS 59 */ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, }, /* MCS 60 */ { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, }, /* 40 Mhz */ { 216.0, /* SGI */ 240.0, }, }, /* MCS 61 */ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, }, /* MCS 62 */ { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, }, /* 40 Mhz */ { 270.0, /* SGI */ 300.0, }, }, /* MCS 63 */ { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, }, /* 40 Mhz */ { 270.0, /* SGI */ 300.0, }, }, /* MCS 64 */ { /* 20 Mhz */ { 143.0, /* SGI */ 158.9, }, /* 40 Mhz */ { 297.0, /* SGI */ 330.0, }, }, /* MCS 65 */ { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, }, /* 40 Mhz */ { 202.5, /* SGI */ 225.0, }, }, /* MCS 66 */ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, }, /* MCS 67 */ { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, }, /* MCS 68 */ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, }, /* 40 Mhz */ { 243.0, /* SGI */ 270.0, }, }, /* MCS 69 */ { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, }, /* 40 Mhz */ { 283.5, /* SGI */ 315.0, }, }, /* MCS 70 */ { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, }, /* MCS 71 */ { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, }, /* 40 Mhz */ { 364.5, /* SGI */ 405.0, }, }, /* MCS 72 */ { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, }, /* 40 Mhz */ { 324.0, /* SGI */ 360.0, }, }, /* MCS 73 */ { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, }, /* 40 Mhz */ { 364.5, /* SGI */ 405.0, }, }, /* MCS 74 */ { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, }, /* 40 Mhz */ { 405.0, /* SGI */ 450.0, }, }, /* MCS 75 */ { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, }, /* 40 Mhz */ { 405.0, /* SGI */ 450.0, }, }, /* MCS 76 */ { /* 20 Mhz */ { 214.5, /* SGI */ 238.3, }, /* 40 Mhz */ { 445.5, /* SGI */ 495.0, }, }, }; static const char *auth_alg_text[]={"Open System","Shared Key","EAP"}; #define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0]) static const char *status_text[] = { "Successful", /* 0 */ "Unspecified failure", /* 1 */ "Reserved", /* 2 */ "Reserved", /* 3 */ "Reserved", /* 4 */ "Reserved", /* 5 */ "Reserved", /* 6 */ "Reserved", /* 7 */ "Reserved", /* 8 */ "Reserved", /* 9 */ "Cannot Support all requested capabilities in the Capability " "Information field", /* 10 */ "Reassociation denied due to inability to confirm that association " "exists", /* 11 */ "Association denied due to reason outside the scope of the " "standard", /* 12 */ "Responding station does not support the specified authentication " "algorithm ", /* 13 */ "Received an Authentication frame with authentication transaction " "sequence number out of expected sequence", /* 14 */ "Authentication rejected because of challenge failure", /* 15 */ "Authentication rejected due to timeout waiting for next frame in " "sequence", /* 16 */ "Association denied because AP is unable to handle additional" "associated stations", /* 17 */ "Association denied due to requesting station not supporting all of " "the data rates in BSSBasicRateSet parameter", /* 18 */ "Association denied due to requesting station not supporting " "short preamble operation", /* 19 */ "Association denied due to requesting station not supporting " "PBCC encoding", /* 20 */ "Association denied due to requesting station not supporting " "channel agility", /* 21 */ "Association request rejected because Spectrum Management " "capability is required", /* 22 */ "Association request rejected because the information in the " "Power Capability element is unacceptable", /* 23 */ "Association request rejected because the information in the " "Supported Channels element is unacceptable", /* 24 */ "Association denied due to requesting station not supporting " "short slot operation", /* 25 */ "Association denied due to requesting station not supporting " "DSSS-OFDM operation", /* 26 */ "Association denied because the requested STA does not support HT " "features", /* 27 */ "Reserved", /* 28 */ "Association denied because the requested STA does not support " "the PCO transition time required by the AP", /* 29 */ "Reserved", /* 30 */ "Reserved", /* 31 */ "Unspecified, QoS-related failure", /* 32 */ "Association denied due to QAP having insufficient bandwidth " "to handle another QSTA", /* 33 */ "Association denied due to excessive frame loss rates and/or " "poor conditions on current operating channel", /* 34 */ "Association (with QBSS) denied due to requesting station not " "supporting the QoS facility", /* 35 */ "Association denied due to requesting station not supporting " "Block Ack", /* 36 */ "The request has been declined", /* 37 */ "The request has not been successful as one or more parameters " "have invalid values", /* 38 */ "The TS has not been created because the request cannot be honored. " "However, a suggested TSPEC is provided so that the initiating QSTA" "may attempt to set another TS with the suggested changes to the " "TSPEC", /* 39 */ "Invalid Information Element", /* 40 */ "Group Cipher is not valid", /* 41 */ "Pairwise Cipher is not valid", /* 42 */ "AKMP is not valid", /* 43 */ "Unsupported RSN IE version", /* 44 */ "Invalid RSN IE Capabilities", /* 45 */ "Cipher suite is rejected per security policy", /* 46 */ "The TS has not been created. However, the HC may be capable of " "creating a TS, in response to a request, after the time indicated " "in the TS Delay element", /* 47 */ "Direct Link is not allowed in the BSS by policy", /* 48 */ "Destination STA is not present within this QBSS.", /* 49 */ "The Destination STA is not a QSTA.", /* 50 */ }; #define NUM_STATUSES (sizeof status_text / sizeof status_text[0]) static const char *reason_text[] = { "Reserved", /* 0 */ "Unspecified reason", /* 1 */ "Previous authentication no longer valid", /* 2 */ "Deauthenticated because sending station is leaving (or has left) " "IBSS or ESS", /* 3 */ "Disassociated due to inactivity", /* 4 */ "Disassociated because AP is unable to handle all currently " " associated stations", /* 5 */ "Class 2 frame received from nonauthenticated station", /* 6 */ "Class 3 frame received from nonassociated station", /* 7 */ "Disassociated because sending station is leaving " "(or has left) BSS", /* 8 */ "Station requesting (re)association is not authenticated with " "responding station", /* 9 */ "Disassociated because the information in the Power Capability " "element is unacceptable", /* 10 */ "Disassociated because the information in the SupportedChannels " "element is unacceptable", /* 11 */ "Invalid Information Element", /* 12 */ "Reserved", /* 13 */ "Michael MIC failure", /* 14 */ "4-Way Handshake timeout", /* 15 */ "Group key update timeout", /* 16 */ "Information element in 4-Way Handshake different from (Re)Association" "Request/Probe Response/Beacon", /* 17 */ "Group Cipher is not valid", /* 18 */ "AKMP is not valid", /* 20 */ "Unsupported RSN IE version", /* 21 */ "Invalid RSN IE Capabilities", /* 22 */ "IEEE 802.1X Authentication failed", /* 23 */ "Cipher suite is rejected per security policy", /* 24 */ "Reserved", /* 25 */ "Reserved", /* 26 */ "Reserved", /* 27 */ "Reserved", /* 28 */ "Reserved", /* 29 */ "Reserved", /* 30 */ "TS deleted because QoS AP lacks sufficient bandwidth for this " "QoS STA due to a change in BSS service characteristics or " "operational mode (e.g. an HT BSS change from 40 MHz channel " "to 20 MHz channel)", /* 31 */ "Disassociated for unspecified, QoS-related reason", /* 32 */ "Disassociated because QoS AP lacks sufficient bandwidth for this " "QoS STA", /* 33 */ "Disassociated because of excessive number of frames that need to be " "acknowledged, but are not acknowledged for AP transmissions " "and/or poor channel conditions", /* 34 */ "Disassociated because STA is transmitting outside the limits " "of its TXOPs", /* 35 */ "Requested from peer STA as the STA is leaving the BSS " "(or resetting)", /* 36 */ "Requested from peer STA as it does not want to use the " "mechanism", /* 37 */ "Requested from peer STA as the STA received frames using the " "mechanism for which a set up is required", /* 38 */ "Requested from peer STA due to time out", /* 39 */ "Reserved", /* 40 */ "Reserved", /* 41 */ "Reserved", /* 42 */ "Reserved", /* 43 */ "Reserved", /* 44 */ "Peer STA does not support the requested cipher suite", /* 45 */ "Association denied due to requesting STA not supporting HT " "features", /* 46 */ }; #define NUM_REASONS (sizeof reason_text / sizeof reason_text[0]) static int wep_print(const u_char *p) { u_int32_t iv; if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN)) return 0; iv = EXTRACT_LE_32BITS(p); printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv), IV_KEYID(iv)); return 1; } static int parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset, u_int length) { u_int elementlen; struct ssid_t ssid; struct challenge_t challenge; struct rates_t rates; struct ds_t ds; struct cf_t cf; struct tim_t tim; /* * We haven't seen any elements yet. */ pbody->challenge_present = 0; pbody->ssid_present = 0; pbody->rates_present = 0; pbody->ds_present = 0; pbody->cf_present = 0; pbody->tim_present = 0; while (length != 0) { if (!TTEST2(*(p + offset), 1)) return 0; if (length < 1) return 0; switch (*(p + offset)) { case E_SSID: if (!TTEST2(*(p + offset), 2)) return 0; if (length < 2) return 0; memcpy(&ssid, p + offset, 2); offset += 2; length -= 2; if (ssid.length != 0) { if (ssid.length > sizeof(ssid.ssid) - 1) return 0; if (!TTEST2(*(p + offset), ssid.length)) return 0; if (length < ssid.length) return 0; memcpy(&ssid.ssid, p + offset, ssid.length); offset += ssid.length; length -= ssid.length; } ssid.ssid[ssid.length] = '\0'; /* * Present and not truncated. * * If we haven't already seen an SSID IE, * copy this one, otherwise ignore this one, * so we later report the first one we saw. */ if (!pbody->ssid_present) { pbody->ssid = ssid; pbody->ssid_present = 1; } break; case E_CHALLENGE: if (!TTEST2(*(p + offset), 2)) return 0; if (length < 2) return 0; memcpy(&challenge, p + offset, 2); offset += 2; length -= 2; if (challenge.length != 0) { if (challenge.length > sizeof(challenge.text) - 1) return 0; if (!TTEST2(*(p + offset), challenge.length)) return 0; if (length < challenge.length) return 0; memcpy(&challenge.text, p + offset, challenge.length); offset += challenge.length; length -= challenge.length; } challenge.text[challenge.length] = '\0'; /* * Present and not truncated. * * If we haven't already seen a challenge IE, * copy this one, otherwise ignore this one, * so we later report the first one we saw. */ if (!pbody->challenge_present) { pbody->challenge = challenge; pbody->challenge_present = 1; } break; case E_RATES: if (!TTEST2(*(p + offset), 2)) return 0; if (length < 2) return 0; memcpy(&rates, p + offset, 2); offset += 2; length -= 2; if (rates.length != 0) { if (rates.length > sizeof rates.rate) return 0; if (!TTEST2(*(p + offset), rates.length)) return 0; if (length < rates.length) return 0; memcpy(&rates.rate, p + offset, rates.length); offset += rates.length; length -= rates.length; } /* * Present and not truncated. * * If we haven't already seen a rates IE, * copy this one if it's not zero-length, * otherwise ignore this one, so we later * report the first one we saw. * * We ignore zero-length rates IEs as some * devices seem to put a zero-length rates * IE, followed by an SSID IE, followed by * a non-zero-length rates IE into frames, * even though IEEE Std 802.11-2007 doesn't * seem to indicate that a zero-length rates * IE is valid. */ if (!pbody->rates_present && rates.length != 0) { pbody->rates = rates; pbody->rates_present = 1; } break; case E_DS: if (!TTEST2(*(p + offset), 3)) return 0; if (length < 3) return 0; memcpy(&ds, p + offset, 3); offset += 3; length -= 3; /* * Present and not truncated. * * If we haven't already seen a DS IE, * copy this one, otherwise ignore this one, * so we later report the first one we saw. */ if (!pbody->ds_present) { pbody->ds = ds; pbody->ds_present = 1; } break; case E_CF: if (!TTEST2(*(p + offset), 8)) return 0; if (length < 8) return 0; memcpy(&cf, p + offset, 8); offset += 8; length -= 8; /* * Present and not truncated. * * If we haven't already seen a CF IE, * copy this one, otherwise ignore this one, * so we later report the first one we saw. */ if (!pbody->cf_present) { pbody->cf = cf; pbody->cf_present = 1; } break; case E_TIM: if (!TTEST2(*(p + offset), 2)) return 0; if (length < 2) return 0; memcpy(&tim, p + offset, 2); offset += 2; length -= 2; if (!TTEST2(*(p + offset), 3)) return 0; if (length < 3) return 0; memcpy(&tim.count, p + offset, 3); offset += 3; length -= 3; if (tim.length <= 3) break; if (tim.length - 3 > (int)sizeof tim.bitmap) return 0; if (!TTEST2(*(p + offset), tim.length - 3)) return 0; if (length < (u_int)(tim.length - 3)) return 0; memcpy(tim.bitmap, p + (tim.length - 3), (tim.length - 3)); offset += tim.length - 3; length -= tim.length - 3; /* * Present and not truncated. * * If we haven't already seen a TIM IE, * copy this one, otherwise ignore this one, * so we later report the first one we saw. */ if (!pbody->tim_present) { pbody->tim = tim; pbody->tim_present = 1; } break; default: #if 0 printf("(1) unhandled element_id (%d) ", *(p + offset)); #endif if (!TTEST2(*(p + offset), 2)) return 0; if (length < 2) return 0; elementlen = *(p + offset + 1); if (!TTEST2(*(p + offset + 2), elementlen)) return 0; if (length < elementlen + 2) return 0; offset += elementlen + 2; length -= elementlen + 2; break; } } /* No problems found. */ return 1; } /********************************************************************************* * Print Handle functions for the management frame types *********************************************************************************/ static int handle_beacon(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + IEEE802_11_CAPINFO_LEN)) return 0; if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + IEEE802_11_CAPINFO_LEN) return 0; memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN); offset += IEEE802_11_TSTAMP_LEN; length -= IEEE802_11_TSTAMP_LEN; pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_BCNINT_LEN; length -= IEEE802_11_BCNINT_LEN; pbody.capability_info = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_CAPINFO_LEN; length -= IEEE802_11_CAPINFO_LEN; ret = parse_elements(&pbody, p, offset, length); PRINT_SSID(pbody); PRINT_RATES(pbody); printf(" %s", CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS"); PRINT_DS_CHANNEL(pbody); return ret; } static int handle_assoc_request(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)) return 0; if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN) return 0; pbody.capability_info = EXTRACT_LE_16BITS(p); offset += IEEE802_11_CAPINFO_LEN; length -= IEEE802_11_CAPINFO_LEN; pbody.listen_interval = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_LISTENINT_LEN; length -= IEEE802_11_LISTENINT_LEN; ret = parse_elements(&pbody, p, offset, length); PRINT_SSID(pbody); PRINT_RATES(pbody); return ret; } static int handle_assoc_response(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + IEEE802_11_AID_LEN)) return 0; if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + IEEE802_11_AID_LEN) return 0; pbody.capability_info = EXTRACT_LE_16BITS(p); offset += IEEE802_11_CAPINFO_LEN; length -= IEEE802_11_CAPINFO_LEN; pbody.status_code = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_STATUS_LEN; length -= IEEE802_11_STATUS_LEN; pbody.aid = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_AID_LEN; length -= IEEE802_11_AID_LEN; ret = parse_elements(&pbody, p, offset, length); printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 , CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "", (pbody.status_code < NUM_STATUSES ? status_text[pbody.status_code] : "n/a")); return ret; } static int handle_reassoc_request(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + IEEE802_11_AP_LEN)) return 0; if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + IEEE802_11_AP_LEN) return 0; pbody.capability_info = EXTRACT_LE_16BITS(p); offset += IEEE802_11_CAPINFO_LEN; length -= IEEE802_11_CAPINFO_LEN; pbody.listen_interval = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_LISTENINT_LEN; length -= IEEE802_11_LISTENINT_LEN; memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN); offset += IEEE802_11_AP_LEN; length -= IEEE802_11_AP_LEN; ret = parse_elements(&pbody, p, offset, length); PRINT_SSID(pbody); printf(" AP : %s", etheraddr_string( pbody.ap )); return ret; } static int handle_reassoc_response(const u_char *p, u_int length) { /* Same as a Association Reponse */ return handle_assoc_response(p, length); } static int handle_probe_request(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; int ret; memset(&pbody, 0, sizeof(pbody)); ret = parse_elements(&pbody, p, offset, length); PRINT_SSID(pbody); PRINT_RATES(pbody); return ret; } static int handle_probe_response(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + IEEE802_11_CAPINFO_LEN)) return 0; if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + IEEE802_11_CAPINFO_LEN) return 0; memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN); offset += IEEE802_11_TSTAMP_LEN; length -= IEEE802_11_TSTAMP_LEN; pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_BCNINT_LEN; length -= IEEE802_11_BCNINT_LEN; pbody.capability_info = EXTRACT_LE_16BITS(p+offset); offset += IEEE802_11_CAPINFO_LEN; length -= IEEE802_11_CAPINFO_LEN; ret = parse_elements(&pbody, p, offset, length); PRINT_SSID(pbody); PRINT_RATES(pbody); PRINT_DS_CHANNEL(pbody); return ret; } static int handle_atim(void) { /* the frame body for ATIM is null. */ return 1; } static int handle_disassoc(const u_char *p, u_int length) { struct mgmt_body_t pbody; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_REASON_LEN)) return 0; if (length < IEEE802_11_REASON_LEN) return 0; pbody.reason_code = EXTRACT_LE_16BITS(p); printf(": %s", (pbody.reason_code < NUM_REASONS) ? reason_text[pbody.reason_code] : "Reserved" ); return 1; } static int handle_auth(const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; int ret; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, 6)) return 0; if (length < 6) return 0; pbody.auth_alg = EXTRACT_LE_16BITS(p); offset += 2; length -= 2; pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset); offset += 2; length -= 2; pbody.status_code = EXTRACT_LE_16BITS(p + offset); offset += 2; length -= 2; ret = parse_elements(&pbody, p, offset, length); if ((pbody.auth_alg == 1) && ((pbody.auth_trans_seq_num == 2) || (pbody.auth_trans_seq_num == 3))) { printf(" (%s)-%x [Challenge Text] %s", (pbody.auth_alg < NUM_AUTH_ALGS) ? auth_alg_text[pbody.auth_alg] : "Reserved", pbody.auth_trans_seq_num, ((pbody.auth_trans_seq_num % 2) ? ((pbody.status_code < NUM_STATUSES) ? status_text[pbody.status_code] : "n/a") : "")); return ret; } printf(" (%s)-%x: %s", (pbody.auth_alg < NUM_AUTH_ALGS) ? auth_alg_text[pbody.auth_alg] : "Reserved", pbody.auth_trans_seq_num, (pbody.auth_trans_seq_num % 2) ? ((pbody.status_code < NUM_STATUSES) ? status_text[pbody.status_code] : "n/a") : ""); return ret; } static int handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length) { struct mgmt_body_t pbody; int offset = 0; const char *reason = NULL; memset(&pbody, 0, sizeof(pbody)); if (!TTEST2(*p, IEEE802_11_REASON_LEN)) return 0; if (length < IEEE802_11_REASON_LEN) return 0; pbody.reason_code = EXTRACT_LE_16BITS(p); offset += IEEE802_11_REASON_LEN; length -= IEEE802_11_REASON_LEN; reason = (pbody.reason_code < NUM_REASONS) ? reason_text[pbody.reason_code] : "Reserved"; if (eflag) { printf(": %s", reason); } else { printf(" (%s): %s", etheraddr_string(pmh->sa), reason); } return 1; } #define PRINT_HT_ACTION(v) (\ (v) == 0 ? printf("TxChWidth") : \ (v) == 1 ? printf("MIMOPwrSave") : \ printf("Act#%d", (v)) \ ) #define PRINT_BA_ACTION(v) (\ (v) == 0 ? printf("ADDBA Request") : \ (v) == 1 ? printf("ADDBA Response") : \ (v) == 2 ? printf("DELBA") : \ printf("Act#%d", (v)) \ ) #define PRINT_MESHLINK_ACTION(v) (\ (v) == 0 ? printf("Request") : \ (v) == 1 ? printf("Report") : \ printf("Act#%d", (v)) \ ) #define PRINT_MESHPEERING_ACTION(v) (\ (v) == 0 ? printf("Open") : \ (v) == 1 ? printf("Confirm") : \ (v) == 2 ? printf("Close") : \ printf("Act#%d", (v)) \ ) #define PRINT_MESHPATH_ACTION(v) (\ (v) == 0 ? printf("Request") : \ (v) == 1 ? printf("Report") : \ (v) == 2 ? printf("Error") : \ (v) == 3 ? printf("RootAnnouncement") : \ printf("Act#%d", (v)) \ ) #define PRINT_MESH_ACTION(v) (\ (v) == 0 ? printf("MeshLink") : \ (v) == 1 ? printf("HWMP") : \ (v) == 2 ? printf("Gate Announcement") : \ (v) == 3 ? printf("Congestion Control") : \ (v) == 4 ? printf("MCCA Setup Request") : \ (v) == 5 ? printf("MCCA Setup Reply") : \ (v) == 6 ? printf("MCCA Advertisement Request") : \ (v) == 7 ? printf("MCCA Advertisement") : \ (v) == 8 ? printf("MCCA Teardown") : \ (v) == 9 ? printf("TBTT Adjustment Request") : \ (v) == 10 ? printf("TBTT Adjustment Response") : \ printf("Act#%d", (v)) \ ) #define PRINT_MULTIHOP_ACTION(v) (\ (v) == 0 ? printf("Proxy Update") : \ (v) == 1 ? printf("Proxy Update Confirmation") : \ printf("Act#%d", (v)) \ ) #define PRINT_SELFPROT_ACTION(v) (\ (v) == 1 ? printf("Peering Open") : \ (v) == 2 ? printf("Peering Confirm") : \ (v) == 3 ? printf("Peering Close") : \ (v) == 4 ? printf("Group Key Inform") : \ (v) == 5 ? printf("Group Key Acknowledge") : \ printf("Act#%d", (v)) \ ) static int handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length) { if (!TTEST2(*p, 2)) return 0; if (length < 2) return 0; if (eflag) { printf(": "); } else { printf(" (%s): ", etheraddr_string(pmh->sa)); } switch (p[0]) { case 0: printf("Spectrum Management Act#%d", p[1]); break; case 1: printf("QoS Act#%d", p[1]); break; case 2: printf("DLS Act#%d", p[1]); break; case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break; case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break; case 13: printf("MeshAction "); PRINT_MESH_ACTION(p[1]); break; case 14: printf("MultiohopAction "); PRINT_MULTIHOP_ACTION(p[1]); break; case 15: printf("SelfprotectAction "); PRINT_SELFPROT_ACTION(p[1]); break; case 127: printf("Vendor Act#%d", p[1]); break; default: printf("Reserved(%d) Act#%d", p[0], p[1]); break; } return 1; } /********************************************************************************* * Print Body funcs *********************************************************************************/ static int mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh, const u_char *p, u_int length) { switch (FC_SUBTYPE(fc)) { case ST_ASSOC_REQUEST: printf("Assoc Request"); return handle_assoc_request(p, length); case ST_ASSOC_RESPONSE: printf("Assoc Response"); return handle_assoc_response(p, length); case ST_REASSOC_REQUEST: printf("ReAssoc Request"); return handle_reassoc_request(p, length); case ST_REASSOC_RESPONSE: printf("ReAssoc Response"); return handle_reassoc_response(p, length); case ST_PROBE_REQUEST: printf("Probe Request"); return handle_probe_request(p, length); case ST_PROBE_RESPONSE: printf("Probe Response"); return handle_probe_response(p, length); case ST_BEACON: printf("Beacon"); return handle_beacon(p, length); case ST_ATIM: printf("ATIM"); return handle_atim(); case ST_DISASSOC: printf("Disassociation"); return handle_disassoc(p, length); case ST_AUTH: printf("Authentication"); if (!TTEST2(*p, 3)) return 0; if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) { printf("Authentication (Shared-Key)-3 "); return wep_print(p); } return handle_auth(p, length); case ST_DEAUTH: printf("DeAuthentication"); return handle_deauth(pmh, p, length); break; case ST_ACTION: printf("Action"); return handle_action(pmh, p, length); break; default: printf("Unhandled Management subtype(%x)", FC_SUBTYPE(fc)); return 1; } } /********************************************************************************* * Handles printing all the control frame types *********************************************************************************/ static int ctrl_body_print(u_int16_t fc, const u_char *p) { switch (FC_SUBTYPE(fc)) { case CTRL_CONTROL_WRAPPER: printf("Control Wrapper"); /* XXX - requires special handling */ break; case CTRL_BAR: printf("BAR"); if (!TTEST2(*p, CTRL_BAR_HDRLEN)) return 0; if (!eflag) printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ", etheraddr_string(((const struct ctrl_bar_t *)p)->ra), etheraddr_string(((const struct ctrl_bar_t *)p)->ta), EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq))); break; case CTRL_BA: printf("BA"); if (!TTEST2(*p, CTRL_BA_HDRLEN)) return 0; if (!eflag) printf(" RA:%s ", etheraddr_string(((const struct ctrl_ba_t *)p)->ra)); break; case CTRL_PS_POLL: printf("Power Save-Poll"); if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN)) return 0; printf(" AID(%x)", EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid))); break; case CTRL_RTS: printf("Request-To-Send"); if (!TTEST2(*p, CTRL_RTS_HDRLEN)) return 0; if (!eflag) printf(" TA:%s ", etheraddr_string(((const struct ctrl_rts_t *)p)->ta)); break; case CTRL_CTS: printf("Clear-To-Send"); if (!TTEST2(*p, CTRL_CTS_HDRLEN)) return 0; if (!eflag) printf(" RA:%s ", etheraddr_string(((const struct ctrl_cts_t *)p)->ra)); break; case CTRL_ACK: printf("Acknowledgment"); if (!TTEST2(*p, CTRL_ACK_HDRLEN)) return 0; if (!eflag) printf(" RA:%s ", etheraddr_string(((const struct ctrl_ack_t *)p)->ra)); break; case CTRL_CF_END: printf("CF-End"); if (!TTEST2(*p, CTRL_END_HDRLEN)) return 0; if (!eflag) printf(" RA:%s ", etheraddr_string(((const struct ctrl_end_t *)p)->ra)); break; case CTRL_END_ACK: printf("CF-End+CF-Ack"); if (!TTEST2(*p, CTRL_END_ACK_HDRLEN)) return 0; if (!eflag) printf(" RA:%s ", etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra)); break; default: printf("Unknown Ctrl Subtype"); } return 1; } /* * Print Header funcs */ /* * Data Frame - Address field contents * * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4 * 0 | 0 | DA | SA | BSSID | n/a * 0 | 1 | DA | BSSID | SA | n/a * 1 | 0 | BSSID | SA | DA | n/a * 1 | 1 | RA | TA | DA | SA */ static void data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, const u_int8_t **dstp) { u_int subtype = FC_SUBTYPE(fc); if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) || DATA_FRAME_IS_QOS(subtype)) { printf("CF "); if (DATA_FRAME_IS_CF_ACK(subtype)) { if (DATA_FRAME_IS_CF_POLL(subtype)) printf("Ack/Poll"); else printf("Ack"); } else { if (DATA_FRAME_IS_CF_POLL(subtype)) printf("Poll"); } if (DATA_FRAME_IS_QOS(subtype)) printf("+QoS"); printf(" "); } #define ADDR1 (p + 4) #define ADDR2 (p + 10) #define ADDR3 (p + 16) #define ADDR4 (p + 24) if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR2; if (dstp != NULL) *dstp = ADDR1; if (!eflag) return; printf("DA:%s SA:%s BSSID:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3)); } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR3; if (dstp != NULL) *dstp = ADDR1; if (!eflag) return; printf("DA:%s BSSID:%s SA:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3)); } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR2; if (dstp != NULL) *dstp = ADDR3; if (!eflag) return; printf("BSSID:%s SA:%s DA:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3)); } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR4; if (dstp != NULL) *dstp = ADDR3; if (!eflag) return; printf("RA:%s TA:%s DA:%s SA:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3), etheraddr_string(ADDR4)); } #undef ADDR1 #undef ADDR2 #undef ADDR3 #undef ADDR4 } static void mgmt_header_print(const u_char *p, const u_int8_t **srcp, const u_int8_t **dstp) { const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p; if (srcp != NULL) *srcp = hp->sa; if (dstp != NULL) *dstp = hp->da; if (!eflag) return; printf("BSSID:%s DA:%s SA:%s ", etheraddr_string((hp)->bssid), etheraddr_string((hp)->da), etheraddr_string((hp)->sa)); } static void ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, const u_int8_t **dstp) { if (srcp != NULL) *srcp = NULL; if (dstp != NULL) *dstp = NULL; if (!eflag) return; switch (FC_SUBTYPE(fc)) { case CTRL_BAR: printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ", etheraddr_string(((const struct ctrl_bar_t *)p)->ra), etheraddr_string(((const struct ctrl_bar_t *)p)->ta), EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq))); break; case CTRL_BA: printf("RA:%s ", etheraddr_string(((const struct ctrl_ba_t *)p)->ra)); break; case CTRL_PS_POLL: printf("BSSID:%s TA:%s ", etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid), etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta)); break; case CTRL_RTS: printf("RA:%s TA:%s ", etheraddr_string(((const struct ctrl_rts_t *)p)->ra), etheraddr_string(((const struct ctrl_rts_t *)p)->ta)); break; case CTRL_CTS: printf("RA:%s ", etheraddr_string(((const struct ctrl_cts_t *)p)->ra)); break; case CTRL_ACK: printf("RA:%s ", etheraddr_string(((const struct ctrl_ack_t *)p)->ra)); break; case CTRL_CF_END: printf("RA:%s BSSID:%s ", etheraddr_string(((const struct ctrl_end_t *)p)->ra), etheraddr_string(((const struct ctrl_end_t *)p)->bssid)); break; case CTRL_END_ACK: printf("RA:%s BSSID:%s ", etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra), etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid)); break; default: printf("(H) Unknown Ctrl Subtype"); break; } } static int extract_header_length(u_int16_t fc) { int len; switch (FC_TYPE(fc)) { case T_MGMT: return MGMT_HDRLEN; case T_CTRL: switch (FC_SUBTYPE(fc)) { case CTRL_BAR: return CTRL_BAR_HDRLEN; case CTRL_PS_POLL: return CTRL_PS_POLL_HDRLEN; case CTRL_RTS: return CTRL_RTS_HDRLEN; case CTRL_CTS: return CTRL_CTS_HDRLEN; case CTRL_ACK: return CTRL_ACK_HDRLEN; case CTRL_CF_END: return CTRL_END_HDRLEN; case CTRL_END_ACK: return CTRL_END_ACK_HDRLEN; default: return 0; } case T_DATA: len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24; if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) len += 2; return len; default: printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc)); return 0; } } static int extract_mesh_header_length(const u_char *p) { return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3)); } /* * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp" * to point to the source and destination MAC addresses in any case if * "srcp" and "dstp" aren't null. */ static void ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen, u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp) { if (vflag) { if (FC_MORE_DATA(fc)) printf("More Data "); if (FC_MORE_FLAG(fc)) printf("More Fragments "); if (FC_POWER_MGMT(fc)) printf("Pwr Mgmt "); if (FC_RETRY(fc)) printf("Retry "); if (FC_ORDER(fc)) printf("Strictly Ordered "); if (FC_WEP(fc)) printf("WEP Encrypted "); if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL) printf("%dus ", EXTRACT_LE_16BITS( &((const struct mgmt_header_t *)p)->duration)); } if (meshdrlen != 0) { const struct meshcntl_t *mc = (const struct meshcntl_t *)&p[hdrlen - meshdrlen]; int ae = mc->flags & 3; printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl, EXTRACT_LE_32BITS(mc->seq)); if (ae > 0) printf(" A4:%s", etheraddr_string(mc->addr4)); if (ae > 1) printf(" A5:%s", etheraddr_string(mc->addr5)); if (ae > 2) printf(" A6:%s", etheraddr_string(mc->addr6)); printf(") "); } switch (FC_TYPE(fc)) { case T_MGMT: mgmt_header_print(p, srcp, dstp); break; case T_CTRL: ctrl_header_print(fc, p, srcp, dstp); break; case T_DATA: data_header_print(fc, p, srcp, dstp); break; default: printf("(header) unknown IEEE802.11 frame type (%d)", FC_TYPE(fc)); *srcp = NULL; *dstp = NULL; break; } } #ifndef roundup2 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ #endif static u_int ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad, u_int fcslen) { u_int16_t fc; u_int caplen, hdrlen, meshdrlen; const u_int8_t *src, *dst; u_short extracted_ethertype; caplen = orig_caplen; /* Remove FCS, if present */ if (length < fcslen) { printf("[|802.11]"); return caplen; } length -= fcslen; if (caplen > length) { /* Amount of FCS in actual packet data, if any */ fcslen = caplen - length; caplen -= fcslen; snapend -= fcslen; } if (caplen < IEEE802_11_FC_LEN) { printf("[|802.11]"); return orig_caplen; } fc = EXTRACT_LE_16BITS(p); hdrlen = extract_header_length(fc); if (pad) hdrlen = roundup2(hdrlen, 4); if (Hflag && FC_TYPE(fc) == T_DATA && DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) { meshdrlen = extract_mesh_header_length(p+hdrlen); hdrlen += meshdrlen; } else meshdrlen = 0; if (caplen < hdrlen) { printf("[|802.11]"); return hdrlen; } ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst); /* * Go past the 802.11 header. */ length -= hdrlen; caplen -= hdrlen; p += hdrlen; switch (FC_TYPE(fc)) { case T_MGMT: if (!mgmt_body_print(fc, (const struct mgmt_header_t *)(p - hdrlen), p, length)) { printf("[|802.11]"); return hdrlen; } break; case T_CTRL: if (!ctrl_body_print(fc, p - hdrlen)) { printf("[|802.11]"); return hdrlen; } break; case T_DATA: if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc))) return hdrlen; /* no-data frame */ /* There may be a problem w/ AP not having this bit set */ if (FC_WEP(fc)) { if (!wep_print(p)) { printf("[|802.11]"); return hdrlen; } } else if (llc_print(p, length, caplen, dst, src, &extracted_ethertype) == 0) { /* * Some kinds of LLC packet we cannot * handle intelligently */ if (!eflag) ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen, meshdrlen, NULL, NULL); if (extracted_ethertype) printf("(LLC %s) ", etherproto_string( htons(extracted_ethertype))); if (!suppress_default_print) default_print(p, caplen); } break; default: printf("unknown 802.11 frame type (%d)", FC_TYPE(fc)); break; } return hdrlen; } /* * This is the top level routine of the printer. 'p' points * to the 802.11 header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ u_int ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p) { return ieee802_11_print(p, h->len, h->caplen, 0, 0); } #define IEEE80211_CHAN_FHSS \ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) #define IEEE80211_CHAN_A \ (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) #define IEEE80211_CHAN_B \ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) #define IEEE80211_CHAN_PUREG \ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) #define IEEE80211_CHAN_G \ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) #define IS_CHAN_FHSS(flags) \ ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) #define IS_CHAN_A(flags) \ ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) #define IS_CHAN_B(flags) \ ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) #define IS_CHAN_PUREG(flags) \ ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) #define IS_CHAN_G(flags) \ ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) #define IS_CHAN_ANYG(flags) \ (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags)) static void print_chaninfo(int freq, int flags) { printf("%u MHz", freq); if (IS_CHAN_FHSS(flags)) printf(" FHSS"); if (IS_CHAN_A(flags)) { if (flags & IEEE80211_CHAN_HALF) printf(" 11a/10Mhz"); else if (flags & IEEE80211_CHAN_QUARTER) printf(" 11a/5Mhz"); else printf(" 11a"); } if (IS_CHAN_ANYG(flags)) { if (flags & IEEE80211_CHAN_HALF) printf(" 11g/10Mhz"); else if (flags & IEEE80211_CHAN_QUARTER) printf(" 11g/5Mhz"); else printf(" 11g"); } else if (IS_CHAN_B(flags)) printf(" 11b"); if (flags & IEEE80211_CHAN_TURBO) printf(" Turbo"); if (flags & IEEE80211_CHAN_HT20) printf(" ht/20"); else if (flags & IEEE80211_CHAN_HT40D) printf(" ht/40-"); else if (flags & IEEE80211_CHAN_HT40U) printf(" ht/40+"); printf(" "); } static int print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags, struct radiotap_state *state, u_int32_t presentflags) { union { int8_t i8; u_int8_t u8; int16_t i16; u_int16_t u16; u_int32_t u32; u_int64_t u64; } u, u2, u3, u4; int rc; switch (bit) { case IEEE80211_RADIOTAP_FLAGS: rc = cpack_uint8(s, &u.u8); if (rc != 0) break; *flags = u.u8; break; case IEEE80211_RADIOTAP_RATE: rc = cpack_uint8(s, &u.u8); if (rc != 0) break; /* Save state rate */ state->rate = u.u8; break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: case IEEE80211_RADIOTAP_DB_ANTNOISE: case IEEE80211_RADIOTAP_ANTENNA: rc = cpack_uint8(s, &u.u8); break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: case IEEE80211_RADIOTAP_DBM_ANTNOISE: rc = cpack_int8(s, &u.i8); break; case IEEE80211_RADIOTAP_CHANNEL: rc = cpack_uint16(s, &u.u16); if (rc != 0) break; rc = cpack_uint16(s, &u2.u16); break; case IEEE80211_RADIOTAP_FHSS: case IEEE80211_RADIOTAP_LOCK_QUALITY: case IEEE80211_RADIOTAP_TX_ATTENUATION: case IEEE80211_RADIOTAP_RX_FLAGS: rc = cpack_uint16(s, &u.u16); break; case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: rc = cpack_uint8(s, &u.u8); break; case IEEE80211_RADIOTAP_DBM_TX_POWER: rc = cpack_int8(s, &u.i8); break; case IEEE80211_RADIOTAP_TSFT: rc = cpack_uint64(s, &u.u64); break; case IEEE80211_RADIOTAP_XCHANNEL: rc = cpack_uint32(s, &u.u32); if (rc != 0) break; rc = cpack_uint16(s, &u2.u16); if (rc != 0) break; rc = cpack_uint8(s, &u3.u8); if (rc != 0) break; rc = cpack_uint8(s, &u4.u8); break; case IEEE80211_RADIOTAP_MCS: rc = cpack_uint8(s, &u.u8); if (rc != 0) break; rc = cpack_uint8(s, &u2.u8); if (rc != 0) break; rc = cpack_uint8(s, &u3.u8); break; case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: { u_int8_t vns[3]; u_int16_t length; u_int8_t subspace; if ((cpack_align_and_reserve(s, 2)) == NULL) { rc = -1; break; } rc = cpack_uint8(s, &vns[0]); if (rc != 0) break; rc = cpack_uint8(s, &vns[1]); if (rc != 0) break; rc = cpack_uint8(s, &vns[2]); if (rc != 0) break; rc = cpack_uint8(s, &subspace); if (rc != 0) break; rc = cpack_uint16(s, &length); if (rc != 0) break; /* Skip up to length */ s->c_next += length; break; } default: /* this bit indicates a field whose * size we do not know, so we cannot * proceed. Just print the bit number. */ printf("[bit %u] ", bit); return -1; } if (rc != 0) { printf("[|802.11]"); return rc; } /* Preserve the state present flags */ state->present = presentflags; switch (bit) { case IEEE80211_RADIOTAP_CHANNEL: /* * If CHANNEL and XCHANNEL are both present, skip * CHANNEL. */ if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL)) break; print_chaninfo(u.u16, u2.u16); break; case IEEE80211_RADIOTAP_FHSS: printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff); break; case IEEE80211_RADIOTAP_RATE: /* * XXX On FreeBSD rate & 0x80 means we have an MCS. On * Linux and AirPcap it does not. (What about * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?) * * This is an issue either for proprietary extensions * to 11a or 11g, which do exist, or for 11n * implementations that stuff a rate value into * this field, which also appear to exist. * * We currently handle that by assuming that * if the 0x80 bit is set *and* the remaining * bits have a value between 0 and 15 it's * an MCS value, otherwise it's a rate. If * there are cases where systems that use * "0x80 + MCS index" for MCS indices > 15, * or stuff a rate value here between 64 and * 71.5 Mb/s in here, we'll need a preference * setting. Such rates do exist, e.g. 11n * MCS 7 at 20 MHz with a long guard interval. */ if (u.u8 >= 0x80 && u.u8 <= 0x8f) { /* * XXX - we don't know the channel width * or guard interval length, so we can't * convert this to a data rate. * * If you want us to show a data rate, * use the MCS field, not the Rate field; * the MCS field includes not only the * MCS index, it also includes bandwidth * and guard interval information. * * XXX - can we get the channel width * from XChannel and the guard interval * information from Flags, at least on * FreeBSD? */ printf("MCS %u ", u.u8 & 0x7f); } else printf("%2.1f Mb/s ", .5*u.u8); break; case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: printf("%ddB signal ", u.i8); break; case IEEE80211_RADIOTAP_DBM_ANTNOISE: printf("%ddB noise ", u.i8); break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: printf("%ddB signal ", u.u8); break; case IEEE80211_RADIOTAP_DB_ANTNOISE: printf("%ddB noise ", u.u8); break; case IEEE80211_RADIOTAP_LOCK_QUALITY: printf("%u sq ", u.u16); break; case IEEE80211_RADIOTAP_TX_ATTENUATION: printf("%d tx power ", -(int)u.u16); break; case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: printf("%ddB tx power ", -(int)u.u8); break; case IEEE80211_RADIOTAP_DBM_TX_POWER: printf("%ddBm tx power ", u.i8); break; case IEEE80211_RADIOTAP_FLAGS: if (u.u8 & IEEE80211_RADIOTAP_F_CFP) printf("cfp "); if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE) printf("short preamble "); if (u.u8 & IEEE80211_RADIOTAP_F_WEP) printf("wep "); if (u.u8 & IEEE80211_RADIOTAP_F_FRAG) printf("fragmented "); if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS) printf("bad-fcs "); break; case IEEE80211_RADIOTAP_ANTENNA: printf("antenna %d ", u.u8); break; case IEEE80211_RADIOTAP_TSFT: printf("%" PRIu64 "us tsft ", u.u64); break; case IEEE80211_RADIOTAP_RX_FLAGS: /* Do nothing for now */ break; case IEEE80211_RADIOTAP_XCHANNEL: print_chaninfo(u2.u16, u.u32); break; case IEEE80211_RADIOTAP_MCS: { static const char *bandwidth[4] = { "20 MHz", "40 MHz", "20 MHz (L)", "20 MHz (U)" }; float htrate; if (u.u8 & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) { /* * We know the MCS index. */ if (u3.u8 <= MAX_MCS_INDEX) { /* * And it's in-range. */ if (u.u8 & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) { /* * And we know both the bandwidth and * the guard interval, so we can look * up the rate. */ htrate = ieee80211_float_htrates \ [u3.u8] \ [((u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \ [((u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)]; } else { /* * We don't know both the bandwidth * and the guard interval, so we can * only report the MCS index. */ htrate = 0.0; } } else { /* * The MCS value is out of range. */ htrate = 0.0; } if (htrate != 0.0) { /* * We have the rate. * Print it. */ printf("%.1f Mb/s MCS %u ", htrate, u3.u8); } else { /* * We at least have the MCS index. * Print it. */ printf("MCS %u ", u3.u8); } } if (u.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) { printf("%s ", bandwidth[u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]); } if (u.u8 & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) { printf("%s GI ", (u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? "short" : "lon"); } if (u.u8 & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) { printf("%s ", (u2.u8 & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ? "greenfield" : "mixed"); } if (u.u8 & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) { printf("%s FEC ", (u2.u8 & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ? "LDPC" : "BCC"); } if (u.u8 & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) { printf("RX-STBC%u ", (u2.u8 & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT); } break; } } return 0; } static u_int ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen) { #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x))) #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x))) #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x))) #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x))) #define BITNO_2(x) (((x) & 2) ? 1 : 0) #define BIT(n) (1U << n) #define IS_EXTENDED(__p) \ (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0 struct cpack_state cpacker; struct ieee80211_radiotap_header *hdr; u_int32_t present, next_present; u_int32_t presentflags = 0; u_int32_t *presentp, *last_presentp; enum ieee80211_radiotap_type bit; int bit0; u_int len; u_int8_t flags; int pad; u_int fcslen; struct radiotap_state state; if (caplen < sizeof(*hdr)) { printf("[|802.11]"); return caplen; } hdr = (struct ieee80211_radiotap_header *)p; len = EXTRACT_LE_16BITS(&hdr->it_len); if (caplen < len) { printf("[|802.11]"); return caplen; } cpack_init(&cpacker, (u_int8_t *)hdr, len); /* align against header start */ cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */ for (last_presentp = &hdr->it_present; IS_EXTENDED(last_presentp) && (u_char*)(last_presentp + 1) <= p + len; last_presentp++) cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */ /* are there more bitmap extensions than bytes in header? */ if (IS_EXTENDED(last_presentp)) { printf("[|802.11]"); return caplen; } /* Assume no flags */ flags = 0; /* Assume no Atheros padding between 802.11 header and body */ pad = 0; /* Assume no FCS at end of frame */ fcslen = 0; for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp; presentp++, bit0 += 32) { presentflags = EXTRACT_LE_32BITS(presentp); /* Clear state. */ memset(&state, 0, sizeof(state)); for (present = EXTRACT_LE_32BITS(presentp); present; present = next_present) { /* clear the least significant bit that is set */ next_present = present & (present - 1); /* extract the least significant bit that is set */ bit = (enum ieee80211_radiotap_type) (bit0 + BITNO_32(present ^ next_present)); if (print_radiotap_field(&cpacker, bit, &flags, &state, presentflags) != 0) goto out; } } out: if (flags & IEEE80211_RADIOTAP_F_DATAPAD) pad = 1; /* Atheros padding */ if (flags & IEEE80211_RADIOTAP_F_FCS) fcslen = 4; /* FCS at end of packet */ return len + ieee802_11_print(p + len, length - len, caplen - len, pad, fcslen); #undef BITNO_32 #undef BITNO_16 #undef BITNO_8 #undef BITNO_4 #undef BITNO_2 #undef BIT } static u_int ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen) { u_int32_t caphdr_len; if (caplen < 8) { printf("[|802.11]"); return caplen; } caphdr_len = EXTRACT_32BITS(p + 4); if (caphdr_len < 8) { /* * Yow! The capture header length is claimed not * to be large enough to include even the version * cookie or capture header length! */ printf("[|802.11]"); return caplen; } if (caplen < caphdr_len) { printf("[|802.11]"); return caplen; } return caphdr_len + ieee802_11_print(p + caphdr_len, length - caphdr_len, caplen - caphdr_len, 0, 0); } #define PRISM_HDR_LEN 144 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002 /* * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header, * containing information such as radio information, which we * currently ignore. * * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS * (currently, on Linux, there's no ARPHRD_ type for * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for * the AVS header, and the first 4 bytes of the header are used to * indicate whether it's a Prism header or an AVS header). */ u_int prism_if_print(const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; u_int32_t msgcode; if (caplen < 4) { printf("[|802.11]"); return caplen; } msgcode = EXTRACT_32BITS(p); if (msgcode == WLANCAP_MAGIC_COOKIE_V1 || msgcode == WLANCAP_MAGIC_COOKIE_V2) return ieee802_11_avs_radio_print(p, length, caplen); if (caplen < PRISM_HDR_LEN) { printf("[|802.11]"); return caplen; } return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN, length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0); } /* * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra * header, containing information such as radio information. */ u_int ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p) { return ieee802_11_radio_print(p, h->len, h->caplen); } /* * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an * extra header, containing information such as radio information, * which we currently ignore. */ u_int ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p) { return ieee802_11_avs_radio_print(p, h->len, h->caplen); } tcpdump-4.5.1/nfs.h0000644000026300017510000003301312237020316011551 0ustar mcr/* @(#) $Header: /tcpdump/master/tcpdump/nfs.h,v 1.9 2007-11-18 03:24:38 guy Exp $ (LBL) */ /* NetBSD: nfs.h,v 1.1 1996/05/23 22:49:53 fvdl Exp */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Rick Macklem at The University of Guelph. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)nfsproto.h 8.2 (Berkeley) 3/30/95 */ /* * nfs definitions as per the Version 2 and 3 specs */ /* * Constants as defined in the Sun NFS Version 2 and 3 specs. * "NFS: Network File System Protocol Specification" RFC1094 * and in the "NFS: Network File System Version 3 Protocol * Specification" */ #define NFS_PORT 2049 #define NFS_PROG 100003 #define NFS_VER2 2 #define NFS_VER3 3 #define NFS_V2MAXDATA 8192 #define NFS_MAXDGRAMDATA 16384 #define NFS_MAXDATA 32768 #define NFS_MAXPATHLEN 1024 #define NFS_MAXNAMLEN 255 #define NFS_MAXPKTHDR 404 #define NFS_MAXPACKET (NFS_MAXPKTHDR + NFS_MAXDATA) #define NFS_MINPACKET 20 #define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */ /* Stat numbers for rpc returns (version 2 and 3) */ #define NFS_OK 0 #define NFSERR_PERM 1 #define NFSERR_NOENT 2 #define NFSERR_IO 5 #define NFSERR_NXIO 6 #define NFSERR_ACCES 13 #define NFSERR_EXIST 17 #define NFSERR_XDEV 18 /* Version 3 only */ #define NFSERR_NODEV 19 #define NFSERR_NOTDIR 20 #define NFSERR_ISDIR 21 #define NFSERR_INVAL 22 /* Version 3 only */ #define NFSERR_FBIG 27 #define NFSERR_NOSPC 28 #define NFSERR_ROFS 30 #define NFSERR_MLINK 31 /* Version 3 only */ #define NFSERR_NAMETOL 63 #define NFSERR_NOTEMPTY 66 #define NFSERR_DQUOT 69 #define NFSERR_STALE 70 #define NFSERR_REMOTE 71 /* Version 3 only */ #define NFSERR_WFLUSH 99 /* Version 2 only */ #define NFSERR_BADHANDLE 10001 /* The rest Version 3 only */ #define NFSERR_NOT_SYNC 10002 #define NFSERR_BAD_COOKIE 10003 #define NFSERR_NOTSUPP 10004 #define NFSERR_TOOSMALL 10005 #define NFSERR_SERVERFAULT 10006 #define NFSERR_BADTYPE 10007 #define NFSERR_JUKEBOX 10008 #define NFSERR_TRYLATER NFSERR_JUKEBOX #define NFSERR_STALEWRITEVERF 30001 /* Fake return for nfs_commit() */ #define NFSERR_RETVOID 0x20000000 /* Return void, not error */ #define NFSERR_AUTHERR 0x40000000 /* Mark an authentication error */ #define NFSERR_RETERR 0x80000000 /* Mark an error return for V3 */ /* Sizes in bytes of various nfs rpc components */ #define NFSX_UNSIGNED 4 /* specific to NFS Version 2 */ #define NFSX_V2FH 32 #define NFSX_V2FATTR 68 #define NFSX_V2SATTR 32 #define NFSX_V2COOKIE 4 #define NFSX_V2STATFS 20 /* specific to NFS Version 3 */ #if 0 #define NFSX_V3FH (sizeof (fhandle_t)) /* size this server uses */ #endif #define NFSX_V3FHMAX 64 /* max. allowed by protocol */ #define NFSX_V3FATTR 84 #define NFSX_V3SATTR 60 /* max. all fields filled in */ #define NFSX_V3SRVSATTR (sizeof (struct nfsv3_sattr)) #define NFSX_V3POSTOPATTR (NFSX_V3FATTR + NFSX_UNSIGNED) #define NFSX_V3WCCDATA (NFSX_V3POSTOPATTR + 8 * NFSX_UNSIGNED) #define NFSX_V3COOKIEVERF 8 #define NFSX_V3WRITEVERF 8 #define NFSX_V3CREATEVERF 8 #define NFSX_V3STATFS 52 #define NFSX_V3FSINFO 48 #define NFSX_V3PATHCONF 24 /* variants for both versions */ #define NFSX_FH(v3) ((v3) ? (NFSX_V3FHMAX + NFSX_UNSIGNED) : \ NFSX_V2FH) #define NFSX_SRVFH(v3) ((v3) ? NFSX_V3FH : NFSX_V2FH) #define NFSX_FATTR(v3) ((v3) ? NFSX_V3FATTR : NFSX_V2FATTR) #define NFSX_PREOPATTR(v3) ((v3) ? (7 * NFSX_UNSIGNED) : 0) #define NFSX_POSTOPATTR(v3) ((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : 0) #define NFSX_POSTOPORFATTR(v3) ((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : \ NFSX_V2FATTR) #define NFSX_WCCDATA(v3) ((v3) ? NFSX_V3WCCDATA : 0) #define NFSX_WCCORFATTR(v3) ((v3) ? NFSX_V3WCCDATA : NFSX_V2FATTR) #define NFSX_SATTR(v3) ((v3) ? NFSX_V3SATTR : NFSX_V2SATTR) #define NFSX_COOKIEVERF(v3) ((v3) ? NFSX_V3COOKIEVERF : 0) #define NFSX_WRITEVERF(v3) ((v3) ? NFSX_V3WRITEVERF : 0) #define NFSX_READDIR(v3) ((v3) ? (5 * NFSX_UNSIGNED) : \ (2 * NFSX_UNSIGNED)) #define NFSX_STATFS(v3) ((v3) ? NFSX_V3STATFS : NFSX_V2STATFS) /* nfs rpc procedure numbers (before version mapping) */ #define NFSPROC_NULL 0 #define NFSPROC_GETATTR 1 #define NFSPROC_SETATTR 2 #define NFSPROC_LOOKUP 3 #define NFSPROC_ACCESS 4 #define NFSPROC_READLINK 5 #define NFSPROC_READ 6 #define NFSPROC_WRITE 7 #define NFSPROC_CREATE 8 #define NFSPROC_MKDIR 9 #define NFSPROC_SYMLINK 10 #define NFSPROC_MKNOD 11 #define NFSPROC_REMOVE 12 #define NFSPROC_RMDIR 13 #define NFSPROC_RENAME 14 #define NFSPROC_LINK 15 #define NFSPROC_READDIR 16 #define NFSPROC_READDIRPLUS 17 #define NFSPROC_FSSTAT 18 #define NFSPROC_FSINFO 19 #define NFSPROC_PATHCONF 20 #define NFSPROC_COMMIT 21 /* And leasing (nqnfs) procedure numbers (must be last) */ #define NQNFSPROC_GETLEASE 22 #define NQNFSPROC_VACATED 23 #define NQNFSPROC_EVICTED 24 #define NFSPROC_NOOP 25 #define NFS_NPROCS 26 /* Actual Version 2 procedure numbers */ #define NFSV2PROC_NULL 0 #define NFSV2PROC_GETATTR 1 #define NFSV2PROC_SETATTR 2 #define NFSV2PROC_NOOP 3 #define NFSV2PROC_ROOT NFSV2PROC_NOOP /* Obsolete */ #define NFSV2PROC_LOOKUP 4 #define NFSV2PROC_READLINK 5 #define NFSV2PROC_READ 6 #define NFSV2PROC_WRITECACHE NFSV2PROC_NOOP /* Obsolete */ #define NFSV2PROC_WRITE 8 #define NFSV2PROC_CREATE 9 #define NFSV2PROC_REMOVE 10 #define NFSV2PROC_RENAME 11 #define NFSV2PROC_LINK 12 #define NFSV2PROC_SYMLINK 13 #define NFSV2PROC_MKDIR 14 #define NFSV2PROC_RMDIR 15 #define NFSV2PROC_READDIR 16 #define NFSV2PROC_STATFS 17 /* * Constants used by the Version 3 protocol for various RPCs */ #define NFSV3SATTRTIME_DONTCHANGE 0 #define NFSV3SATTRTIME_TOSERVER 1 #define NFSV3SATTRTIME_TOCLIENT 2 #define NFSV3ATTRTIME_NMODES 3 #define NFSV3ACCESS_READ 0x01 #define NFSV3ACCESS_LOOKUP 0x02 #define NFSV3ACCESS_MODIFY 0x04 #define NFSV3ACCESS_EXTEND 0x08 #define NFSV3ACCESS_DELETE 0x10 #define NFSV3ACCESS_EXECUTE 0x20 #define NFSV3ACCESS_FULL 0x3f #define NFSV3WRITE_UNSTABLE 0 #define NFSV3WRITE_DATASYNC 1 #define NFSV3WRITE_FILESYNC 2 #define NFSV3WRITE_NMODES 3 #define NFSV3CREATE_UNCHECKED 0 #define NFSV3CREATE_GUARDED 1 #define NFSV3CREATE_EXCLUSIVE 2 #define NFSV3CREATE_NMODES 3 #define NFSV3FSINFO_LINK 0x01 #define NFSV3FSINFO_SYMLINK 0x02 #define NFSV3FSINFO_HOMOGENEOUS 0x08 #define NFSV3FSINFO_CANSETTIME 0x10 /* Conversion macros */ #define vtonfsv2_mode(t,m) \ txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \ MAKEIMODE((t), (m))) #define vtonfsv3_mode(m) txdr_unsigned((m) & 07777) #define nfstov_mode(a) (fxdr_unsigned(u_int16_t, (a))&07777) #define vtonfsv2_type(a) txdr_unsigned(nfsv2_type[((int32_t)(a))]) #define vtonfsv3_type(a) txdr_unsigned(nfsv3_type[((int32_t)(a))]) #define nfsv2tov_type(a) nv2tov_type[fxdr_unsigned(u_int32_t,(a))&0x7] #define nfsv3tov_type(a) nv3tov_type[fxdr_unsigned(u_int32_t,(a))&0x7] /* File types */ typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5, NFSOCK=6, NFFIFO=7 } nfs_type; /* Structs for common parts of the rpc's */ /* * File Handle (32 bytes for version 2), variable up to 64 for version 3. * File Handles of up to NFS_SMALLFH in size are stored directly in the * nfs node, whereas larger ones are malloc'd. (This never happens when * NFS_SMALLFH is set to 64.) * NFS_SMALLFH should be in the range of 32 to 64 and be divisible by 4. */ #ifndef NFS_SMALLFH #define NFS_SMALLFH 64 #endif union nfsfh { /* fhandle_t fh_generic; */ u_char fh_bytes[NFS_SMALLFH]; }; typedef union nfsfh nfsfh_t; struct nfsv2_time { u_int32_t nfsv2_sec; u_int32_t nfsv2_usec; }; typedef struct nfsv2_time nfstime2; struct nfsv3_time { u_int32_t nfsv3_sec; u_int32_t nfsv3_nsec; }; typedef struct nfsv3_time nfstime3; /* * Quads are defined as arrays of 2 longs to ensure dense packing for the * protocol and to facilitate xdr conversion. */ struct nfs_uquad { u_int32_t nfsuquad[2]; }; typedef struct nfs_uquad nfsuint64; /* * NFS Version 3 special file number. */ struct nfsv3_spec { u_int32_t specdata1; u_int32_t specdata2; }; typedef struct nfsv3_spec nfsv3spec; /* * File attributes and setable attributes. These structures cover both * NFS version 2 and the version 3 protocol. Note that the union is only * used so that one pointer can refer to both variants. These structures * go out on the wire and must be densely packed, so no quad data types * are used. (all fields are longs or u_longs or structures of same) * NB: You can't do sizeof(struct nfs_fattr), you must use the * NFSX_FATTR(v3) macro. */ struct nfs_fattr { u_int32_t fa_type; u_int32_t fa_mode; u_int32_t fa_nlink; u_int32_t fa_uid; u_int32_t fa_gid; union { struct { u_int32_t nfsv2fa_size; u_int32_t nfsv2fa_blocksize; u_int32_t nfsv2fa_rdev; u_int32_t nfsv2fa_blocks; u_int32_t nfsv2fa_fsid; u_int32_t nfsv2fa_fileid; nfstime2 nfsv2fa_atime; nfstime2 nfsv2fa_mtime; nfstime2 nfsv2fa_ctime; } fa_nfsv2; struct { nfsuint64 nfsv3fa_size; nfsuint64 nfsv3fa_used; nfsv3spec nfsv3fa_rdev; nfsuint64 nfsv3fa_fsid; nfsuint64 nfsv3fa_fileid; nfstime3 nfsv3fa_atime; nfstime3 nfsv3fa_mtime; nfstime3 nfsv3fa_ctime; } fa_nfsv3; } fa_un; }; /* and some ugly defines for accessing union components */ #define fa2_size fa_un.fa_nfsv2.nfsv2fa_size #define fa2_blocksize fa_un.fa_nfsv2.nfsv2fa_blocksize #define fa2_rdev fa_un.fa_nfsv2.nfsv2fa_rdev #define fa2_blocks fa_un.fa_nfsv2.nfsv2fa_blocks #define fa2_fsid fa_un.fa_nfsv2.nfsv2fa_fsid #define fa2_fileid fa_un.fa_nfsv2.nfsv2fa_fileid #define fa2_atime fa_un.fa_nfsv2.nfsv2fa_atime #define fa2_mtime fa_un.fa_nfsv2.nfsv2fa_mtime #define fa2_ctime fa_un.fa_nfsv2.nfsv2fa_ctime #define fa3_size fa_un.fa_nfsv3.nfsv3fa_size #define fa3_used fa_un.fa_nfsv3.nfsv3fa_used #define fa3_rdev fa_un.fa_nfsv3.nfsv3fa_rdev #define fa3_fsid fa_un.fa_nfsv3.nfsv3fa_fsid #define fa3_fileid fa_un.fa_nfsv3.nfsv3fa_fileid #define fa3_atime fa_un.fa_nfsv3.nfsv3fa_atime #define fa3_mtime fa_un.fa_nfsv3.nfsv3fa_mtime #define fa3_ctime fa_un.fa_nfsv3.nfsv3fa_ctime struct nfsv2_sattr { u_int32_t sa_mode; u_int32_t sa_uid; u_int32_t sa_gid; u_int32_t sa_size; nfstime2 sa_atime; nfstime2 sa_mtime; }; /* * NFS Version 3 sattr structure for the new node creation case. */ struct nfsv3_sattr { u_int32_t sa_modeset; u_int32_t sa_mode; u_int32_t sa_uidset; u_int32_t sa_uid; u_int32_t sa_gidset; u_int32_t sa_gid; u_int32_t sa_sizeset; u_int32_t sa_size; u_int32_t sa_atimetype; nfstime3 sa_atime; u_int32_t sa_mtimetype; nfstime3 sa_mtime; }; struct nfs_statfs { union { struct { u_int32_t nfsv2sf_tsize; u_int32_t nfsv2sf_bsize; u_int32_t nfsv2sf_blocks; u_int32_t nfsv2sf_bfree; u_int32_t nfsv2sf_bavail; } sf_nfsv2; struct { nfsuint64 nfsv3sf_tbytes; nfsuint64 nfsv3sf_fbytes; nfsuint64 nfsv3sf_abytes; nfsuint64 nfsv3sf_tfiles; nfsuint64 nfsv3sf_ffiles; nfsuint64 nfsv3sf_afiles; u_int32_t nfsv3sf_invarsec; } sf_nfsv3; } sf_un; }; #define sf_tsize sf_un.sf_nfsv2.nfsv2sf_tsize #define sf_bsize sf_un.sf_nfsv2.nfsv2sf_bsize #define sf_blocks sf_un.sf_nfsv2.nfsv2sf_blocks #define sf_bfree sf_un.sf_nfsv2.nfsv2sf_bfree #define sf_bavail sf_un.sf_nfsv2.nfsv2sf_bavail #define sf_tbytes sf_un.sf_nfsv3.nfsv3sf_tbytes #define sf_fbytes sf_un.sf_nfsv3.nfsv3sf_fbytes #define sf_abytes sf_un.sf_nfsv3.nfsv3sf_abytes #define sf_tfiles sf_un.sf_nfsv3.nfsv3sf_tfiles #define sf_ffiles sf_un.sf_nfsv3.nfsv3sf_ffiles #define sf_afiles sf_un.sf_nfsv3.nfsv3sf_afiles #define sf_invarsec sf_un.sf_nfsv3.nfsv3sf_invarsec struct nfsv3_fsinfo { u_int32_t fs_rtmax; u_int32_t fs_rtpref; u_int32_t fs_rtmult; u_int32_t fs_wtmax; u_int32_t fs_wtpref; u_int32_t fs_wtmult; u_int32_t fs_dtpref; nfsuint64 fs_maxfilesize; nfstime3 fs_timedelta; u_int32_t fs_properties; }; struct nfsv3_pathconf { u_int32_t pc_linkmax; u_int32_t pc_namemax; u_int32_t pc_notrunc; u_int32_t pc_chownrestricted; u_int32_t pc_caseinsensitive; u_int32_t pc_casepreserving; }; tcpdump-4.5.1/print-pflog.c0000644000026300017510000001105212237020316013216 0ustar mcr/* * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-pflog.c,v 1.16 2007-09-12 19:36:18 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef HAVE_NET_PFVAR_H #error "No pf headers available" #endif #include #include #include #include #include #include #include #include #include "extract.h" #include "interface.h" #include "addrtoname.h" static const struct tok pf_reasons[] = { { 0, "0(match)" }, { 1, "1(bad-offset)" }, { 2, "2(fragment)" }, { 3, "3(short)" }, { 4, "4(normalize)" }, { 5, "5(memory)" }, { 6, "6(bad-timestamp)" }, { 7, "7(congestion)" }, { 8, "8(ip-option)" }, { 9, "9(proto-cksum)" }, { 10, "10(state-mismatch)" }, { 11, "11(state-insert)" }, { 12, "12(state-limit)" }, { 13, "13(src-limit)" }, { 14, "14(synproxy)" }, { 0, NULL } }; static const struct tok pf_actions[] = { { PF_PASS, "pass" }, { PF_DROP, "block" }, { PF_SCRUB, "scrub" }, { PF_NAT, "nat" }, { PF_NONAT, "nat" }, { PF_BINAT, "binat" }, { PF_NOBINAT, "binat" }, { PF_RDR, "rdr" }, { PF_NORDR, "rdr" }, { PF_SYNPROXY_DROP, "synproxy-drop" }, { 0, NULL } }; static const struct tok pf_directions[] = { { PF_INOUT, "in/out" }, { PF_IN, "in" }, { PF_OUT, "out" }, { 0, NULL } }; /* For reading capture files on other systems */ #define OPENBSD_AF_INET 2 #define OPENBSD_AF_INET6 24 static void pflog_print(const struct pfloghdr *hdr) { u_int32_t rulenr, subrulenr; rulenr = EXTRACT_32BITS(&hdr->rulenr); subrulenr = EXTRACT_32BITS(&hdr->subrulenr); if (subrulenr == (u_int32_t)-1) printf("rule %u/", rulenr); else printf("rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr); printf("%s: %s %s on %s: ", tok2str(pf_reasons, "unkn(%u)", hdr->reason), tok2str(pf_actions, "unkn(%u)", hdr->action), tok2str(pf_directions, "unkn(%u)", hdr->dir), hdr->ifname); } u_int pflog_if_print(const struct pcap_pkthdr *h, register const u_char *p) { u_int length = h->len; u_int hdrlen; u_int caplen = h->caplen; const struct pfloghdr *hdr; u_int8_t af; /* check length */ if (caplen < sizeof(u_int8_t)) { printf("[|pflog]"); return (caplen); } #define MIN_PFLOG_HDRLEN 45 hdr = (struct pfloghdr *)p; if (hdr->length < MIN_PFLOG_HDRLEN) { printf("[pflog: invalid header length!]"); return (hdr->length); /* XXX: not really */ } hdrlen = BPF_WORDALIGN(hdr->length); if (caplen < hdrlen) { printf("[|pflog]"); return (hdrlen); /* XXX: true? */ } /* print what we know */ hdr = (struct pfloghdr *)p; TCHECK(*hdr); if (eflag) pflog_print(hdr); /* skip to the real packet */ af = hdr->af; length -= hdrlen; caplen -= hdrlen; p += hdrlen; switch (af) { case AF_INET: #if OPENBSD_AF_INET != AF_INET case OPENBSD_AF_INET: /* XXX: read pcap files */ #endif ip_print(gndo, p, length); break; #ifdef INET6 case AF_INET6: #if OPENBSD_AF_INET6 != AF_INET6 case OPENBSD_AF_INET6: /* XXX: read pcap files */ #endif ip6_print(gndo, p, length); break; #endif default: /* address family not handled, print raw packet */ if (!eflag) pflog_print(hdr); if (!suppress_default_print) default_print(p, caplen); } return (hdrlen); trunc: printf("[|pflog]"); return (hdrlen); } /* * Local Variables: * c-style: whitesmith * c-basic-offset: 8 * End: */ tcpdump-4.5.1/print-slow.c0000644000026300017510000005464212237020316013107 0ustar mcr/* * Copyright (c) 1998-2006 The TCPDUMP project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * 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. * * support for the IEEE "slow protocols" LACP, MARKER as per 802.3ad * OAM as per 802.3ah * * Original code by Hannes Gredler (hannes@juniper.net) */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-slow.c,v 1.8 2006-10-12 05:44:33 hannes Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "interface.h" #include "extract.h" #include "addrtoname.h" #include "ether.h" #include "oui.h" struct slow_common_header_t { u_int8_t proto_subtype; u_int8_t version; }; #define SLOW_PROTO_LACP 1 #define SLOW_PROTO_MARKER 2 #define SLOW_PROTO_OAM 3 #define LACP_VERSION 1 #define MARKER_VERSION 1 static const struct tok slow_proto_values[] = { { SLOW_PROTO_LACP, "LACP" }, { SLOW_PROTO_MARKER, "MARKER" }, { SLOW_PROTO_OAM, "OAM" }, { 0, NULL} }; static const struct tok slow_oam_flag_values[] = { { 0x0001, "Link Fault" }, { 0x0002, "Dying Gasp" }, { 0x0004, "Critical Event" }, { 0x0008, "Local Evaluating" }, { 0x0010, "Local Stable" }, { 0x0020, "Remote Evaluating" }, { 0x0040, "Remote Stable" }, { 0, NULL} }; #define SLOW_OAM_CODE_INFO 0x00 #define SLOW_OAM_CODE_EVENT_NOTIF 0x01 #define SLOW_OAM_CODE_VAR_REQUEST 0x02 #define SLOW_OAM_CODE_VAR_RESPONSE 0x03 #define SLOW_OAM_CODE_LOOPBACK_CTRL 0x04 #define SLOW_OAM_CODE_PRIVATE 0xfe static const struct tok slow_oam_code_values[] = { { SLOW_OAM_CODE_INFO, "Information" }, { SLOW_OAM_CODE_EVENT_NOTIF, "Event Notification" }, { SLOW_OAM_CODE_VAR_REQUEST, "Variable Request" }, { SLOW_OAM_CODE_VAR_RESPONSE, "Variable Response" }, { SLOW_OAM_CODE_LOOPBACK_CTRL, "Loopback Control" }, { SLOW_OAM_CODE_PRIVATE, "Vendor Private" }, { 0, NULL} }; struct slow_oam_info_t { u_int8_t info_type; u_int8_t info_length; u_int8_t oam_version; u_int8_t revision[2]; u_int8_t state; u_int8_t oam_config; u_int8_t oam_pdu_config[2]; u_int8_t oui[3]; u_int8_t vendor_private[4]; }; #define SLOW_OAM_INFO_TYPE_END_OF_TLV 0x00 #define SLOW_OAM_INFO_TYPE_LOCAL 0x01 #define SLOW_OAM_INFO_TYPE_REMOTE 0x02 #define SLOW_OAM_INFO_TYPE_ORG_SPECIFIC 0xfe static const struct tok slow_oam_info_type_values[] = { { SLOW_OAM_INFO_TYPE_END_OF_TLV, "End of TLV marker" }, { SLOW_OAM_INFO_TYPE_LOCAL, "Local" }, { SLOW_OAM_INFO_TYPE_REMOTE, "Remote" }, { SLOW_OAM_INFO_TYPE_ORG_SPECIFIC, "Organization specific" }, { 0, NULL} }; #define OAM_INFO_TYPE_PARSER_MASK 0x3 static const struct tok slow_oam_info_type_state_parser_values[] = { { 0x00, "forwarding" }, { 0x01, "looping back" }, { 0x02, "discarding" }, { 0x03, "reserved" }, { 0, NULL} }; #define OAM_INFO_TYPE_MUX_MASK 0x4 static const struct tok slow_oam_info_type_state_mux_values[] = { { 0x00, "forwarding" }, { 0x04, "discarding" }, { 0, NULL} }; static const struct tok slow_oam_info_type_oam_config_values[] = { { 0x01, "Active" }, { 0x02, "Unidirectional" }, { 0x04, "Remote-Loopback" }, { 0x08, "Link-Events" }, { 0x10, "Variable-Retrieval" }, { 0, NULL} }; /* 11 Bits */ #define OAM_INFO_TYPE_PDU_SIZE_MASK 0x7ff #define SLOW_OAM_LINK_EVENT_END_OF_TLV 0x00 #define SLOW_OAM_LINK_EVENT_ERR_SYM_PER 0x01 #define SLOW_OAM_LINK_EVENT_ERR_FRM 0x02 #define SLOW_OAM_LINK_EVENT_ERR_FRM_PER 0x03 #define SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM 0x04 #define SLOW_OAM_LINK_EVENT_ORG_SPECIFIC 0xfe static const struct tok slow_oam_link_event_values[] = { { SLOW_OAM_LINK_EVENT_END_OF_TLV, "End of TLV marker" }, { SLOW_OAM_LINK_EVENT_ERR_SYM_PER, "Errored Symbol Period Event" }, { SLOW_OAM_LINK_EVENT_ERR_FRM, "Errored Frame Event" }, { SLOW_OAM_LINK_EVENT_ERR_FRM_PER, "Errored Frame Period Event" }, { SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM, "Errored Frame Seconds Summary Event" }, { SLOW_OAM_LINK_EVENT_ORG_SPECIFIC, "Organization specific" }, { 0, NULL} }; struct slow_oam_link_event_t { u_int8_t event_type; u_int8_t event_length; u_int8_t time_stamp[2]; u_int8_t window[8]; u_int8_t threshold[8]; u_int8_t errors[8]; u_int8_t errors_running_total[8]; u_int8_t event_running_total[4]; }; struct slow_oam_variablerequest_t { u_int8_t branch; u_int8_t leaf[2]; }; struct slow_oam_variableresponse_t { u_int8_t branch; u_int8_t leaf[2]; u_int8_t length; }; struct slow_oam_loopbackctrl_t { u_int8_t command; }; static const struct tok slow_oam_loopbackctrl_cmd_values[] = { { 0x01, "Enable OAM Remote Loopback" }, { 0x02, "Disable OAM Remote Loopback" }, { 0, NULL} }; struct tlv_header_t { u_int8_t type; u_int8_t length; }; #define LACP_TLV_TERMINATOR 0x00 #define LACP_TLV_ACTOR_INFO 0x01 #define LACP_TLV_PARTNER_INFO 0x02 #define LACP_TLV_COLLECTOR_INFO 0x03 #define MARKER_TLV_TERMINATOR 0x00 #define MARKER_TLV_MARKER_INFO 0x01 static const struct tok slow_tlv_values[] = { { (SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR, "Terminator"}, { (SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO, "Actor Information"}, { (SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO, "Partner Information"}, { (SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO, "Collector Information"}, { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_TERMINATOR, "Terminator"}, { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO, "Marker Information"}, { 0, NULL} }; struct lacp_tlv_actor_partner_info_t { u_int8_t sys_pri[2]; u_int8_t sys[ETHER_ADDR_LEN]; u_int8_t key[2]; u_int8_t port_pri[2]; u_int8_t port[2]; u_int8_t state; u_int8_t pad[3]; }; static const struct tok lacp_tlv_actor_partner_info_state_values[] = { { 0x01, "Activity"}, { 0x02, "Timeout"}, { 0x04, "Aggregation"}, { 0x08, "Synchronization"}, { 0x10, "Collecting"}, { 0x20, "Distributing"}, { 0x40, "Default"}, { 0x80, "Expired"}, { 0, NULL} }; struct lacp_tlv_collector_info_t { u_int8_t max_delay[2]; u_int8_t pad[12]; }; struct marker_tlv_marker_info_t { u_int8_t req_port[2]; u_int8_t req_sys[ETHER_ADDR_LEN]; u_int8_t req_trans_id[4]; u_int8_t pad[2]; }; struct lacp_marker_tlv_terminator_t { u_int8_t pad[50]; }; void slow_marker_lacp_print(register const u_char *, register u_int); void slow_oam_print(register const u_char *, register u_int); const struct slow_common_header_t *slow_com_header; void slow_print(register const u_char *pptr, register u_int len) { int print_version; slow_com_header = (const struct slow_common_header_t *)pptr; TCHECK(*slow_com_header); /* * Sanity checking of the header. */ switch (slow_com_header->proto_subtype) { case SLOW_PROTO_LACP: if (slow_com_header->version != LACP_VERSION) { printf("LACP version %u packet not supported",slow_com_header->version); return; } print_version = 1; break; case SLOW_PROTO_MARKER: if (slow_com_header->version != MARKER_VERSION) { printf("MARKER version %u packet not supported",slow_com_header->version); return; } print_version = 1; break; case SLOW_PROTO_OAM: /* fall through */ print_version = 0; break; default: /* print basic information and exit */ print_version = -1; break; } if (print_version) { printf("%sv%u, length %u", tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype), slow_com_header->version, len); } else { /* some slow protos don't have a version number in the header */ printf("%s, length %u", tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype), len); } /* unrecognized subtype */ if (print_version == -1) { print_unknown_data(pptr, "\n\t", len); return; } if (!vflag) return; switch (slow_com_header->proto_subtype) { default: /* should not happen */ break; case SLOW_PROTO_OAM: /* skip proto_subtype */ slow_oam_print(pptr+1, len-1); break; case SLOW_PROTO_LACP: /* LACP and MARKER share the same semantics */ case SLOW_PROTO_MARKER: /* skip slow_common_header */ len -= sizeof(const struct slow_common_header_t); pptr += sizeof(const struct slow_common_header_t); slow_marker_lacp_print(pptr, len); break; } return; trunc: printf("\n\t\t packet exceeded snapshot"); } void slow_marker_lacp_print(register const u_char *tptr, register u_int tlen) { const struct tlv_header_t *tlv_header; const u_char *tlv_tptr; u_int tlv_len, tlv_tlen; union { const struct lacp_marker_tlv_terminator_t *lacp_marker_tlv_terminator; const struct lacp_tlv_actor_partner_info_t *lacp_tlv_actor_partner_info; const struct lacp_tlv_collector_info_t *lacp_tlv_collector_info; const struct marker_tlv_marker_info_t *marker_tlv_marker_info; } tlv_ptr; while(tlen>0) { /* did we capture enough for fully decoding the tlv header ? */ TCHECK2(*tptr, sizeof(struct tlv_header_t)); tlv_header = (const struct tlv_header_t *)tptr; tlv_len = tlv_header->length; printf("\n\t%s TLV (0x%02x), length %u", tok2str(slow_tlv_values, "Unknown", (slow_com_header->proto_subtype << 8) + tlv_header->type), tlv_header->type, tlv_len); if ((tlv_len < sizeof(struct tlv_header_t) || tlv_len > tlen) && tlv_header->type != LACP_TLV_TERMINATOR && tlv_header->type != MARKER_TLV_TERMINATOR) { printf("\n\t-----trailing data-----"); print_unknown_data(tptr+sizeof(struct tlv_header_t),"\n\t ",tlen); return; } tlv_tptr=tptr+sizeof(struct tlv_header_t); tlv_tlen=tlv_len-sizeof(struct tlv_header_t); /* did we capture enough for fully decoding the tlv ? */ TCHECK2(*tptr, tlv_len); switch((slow_com_header->proto_subtype << 8) + tlv_header->type) { /* those two TLVs have the same structure -> fall through */ case ((SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO): case ((SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO): tlv_ptr.lacp_tlv_actor_partner_info = (const struct lacp_tlv_actor_partner_info_t *)tlv_tptr; printf("\n\t System %s, System Priority %u, Key %u" \ ", Port %u, Port Priority %u\n\t State Flags [%s]", etheraddr_string(tlv_ptr.lacp_tlv_actor_partner_info->sys), EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->sys_pri), EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->key), EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port), EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port_pri), bittok2str(lacp_tlv_actor_partner_info_state_values, "none", tlv_ptr.lacp_tlv_actor_partner_info->state)); break; case ((SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO): tlv_ptr.lacp_tlv_collector_info = (const struct lacp_tlv_collector_info_t *)tlv_tptr; printf("\n\t Max Delay %u", EXTRACT_16BITS(tlv_ptr.lacp_tlv_collector_info->max_delay)); break; case ((SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO): tlv_ptr.marker_tlv_marker_info = (const struct marker_tlv_marker_info_t *)tlv_tptr; printf("\n\t Request System %s, Request Port %u, Request Transaction ID 0x%08x", etheraddr_string(tlv_ptr.marker_tlv_marker_info->req_sys), EXTRACT_16BITS(tlv_ptr.marker_tlv_marker_info->req_port), EXTRACT_32BITS(tlv_ptr.marker_tlv_marker_info->req_trans_id)); break; /* those two TLVs have the same structure -> fall through */ case ((SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR): case ((SLOW_PROTO_MARKER << 8) + LACP_TLV_TERMINATOR): tlv_ptr.lacp_marker_tlv_terminator = (const struct lacp_marker_tlv_terminator_t *)tlv_tptr; if (tlv_len == 0) { tlv_len = sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad) + sizeof(struct tlv_header_t); /* tell the user that we modified the length field */ if (vflag>1) printf(" (=%u)",tlv_len); /* we have messed around with the length field - now we need to check * again if there are enough bytes on the wire for the hexdump */ TCHECK2(tlv_ptr.lacp_marker_tlv_terminator->pad[0], sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad)); } break; default: if (vflag <= 1) print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen); break; } /* do we want to see an additional hexdump ? */ if (vflag > 1) { print_unknown_data(tptr+sizeof(struct tlv_header_t),"\n\t ", tlv_len-sizeof(struct tlv_header_t)); } tptr+=tlv_len; tlen-=tlv_len; } return; trunc: printf("\n\t\t packet exceeded snapshot"); } void slow_oam_print(register const u_char *tptr, register u_int tlen) { u_int hexdump; struct slow_oam_common_header_t { u_int8_t flags[2]; u_int8_t code; }; struct slow_oam_tlv_header_t { u_int8_t type; u_int8_t length; }; union { const struct slow_oam_common_header_t *slow_oam_common_header; const struct slow_oam_tlv_header_t *slow_oam_tlv_header; } ptr; union { const struct slow_oam_info_t *slow_oam_info; const struct slow_oam_link_event_t *slow_oam_link_event; const struct slow_oam_variablerequest_t *slow_oam_variablerequest; const struct slow_oam_variableresponse_t *slow_oam_variableresponse; const struct slow_oam_loopbackctrl_t *slow_oam_loopbackctrl; } tlv; ptr.slow_oam_common_header = (struct slow_oam_common_header_t *)tptr; tptr += sizeof(struct slow_oam_common_header_t); tlen -= sizeof(struct slow_oam_common_header_t); printf("\n\tCode %s OAM PDU, Flags [%s]", tok2str(slow_oam_code_values, "Unknown (%u)", ptr.slow_oam_common_header->code), bittok2str(slow_oam_flag_values, "none", EXTRACT_16BITS(&ptr.slow_oam_common_header->flags))); switch (ptr.slow_oam_common_header->code) { case SLOW_OAM_CODE_INFO: while (tlen > 0) { ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr; printf("\n\t %s Information Type (%u), length %u", tok2str(slow_oam_info_type_values, "Reserved", ptr.slow_oam_tlv_header->type), ptr.slow_oam_tlv_header->type, ptr.slow_oam_tlv_header->length); hexdump = FALSE; switch (ptr.slow_oam_tlv_header->type) { case SLOW_OAM_INFO_TYPE_END_OF_TLV: if (ptr.slow_oam_tlv_header->length != 0) { printf("\n\t ERROR: illegal length - should be 0"); } return; case SLOW_OAM_INFO_TYPE_LOCAL: /* identical format - fall through */ case SLOW_OAM_INFO_TYPE_REMOTE: tlv.slow_oam_info = (const struct slow_oam_info_t *)tptr; if (tlv.slow_oam_info->info_length != sizeof(struct slow_oam_info_t)) { printf("\n\t ERROR: illegal length - should be %lu", (unsigned long) sizeof(struct slow_oam_info_t)); return; } printf("\n\t OAM-Version %u, Revision %u", tlv.slow_oam_info->oam_version, EXTRACT_16BITS(&tlv.slow_oam_info->revision)); printf("\n\t State-Parser-Action %s, State-MUX-Action %s", tok2str(slow_oam_info_type_state_parser_values, "Reserved", tlv.slow_oam_info->state & OAM_INFO_TYPE_PARSER_MASK), tok2str(slow_oam_info_type_state_mux_values, "Reserved", tlv.slow_oam_info->state & OAM_INFO_TYPE_MUX_MASK)); printf("\n\t OAM-Config Flags [%s], OAM-PDU-Config max-PDU size %u", bittok2str(slow_oam_info_type_oam_config_values, "none", tlv.slow_oam_info->oam_config), EXTRACT_16BITS(&tlv.slow_oam_info->oam_pdu_config) & OAM_INFO_TYPE_PDU_SIZE_MASK); printf("\n\t OUI %s (0x%06x), Vendor-Private 0x%08x", tok2str(oui_values, "Unknown", EXTRACT_24BITS(&tlv.slow_oam_info->oui)), EXTRACT_24BITS(&tlv.slow_oam_info->oui), EXTRACT_32BITS(&tlv.slow_oam_info->vendor_private)); break; case SLOW_OAM_INFO_TYPE_ORG_SPECIFIC: hexdump = TRUE; break; default: hexdump = TRUE; break; } /* infinite loop check */ if (!ptr.slow_oam_tlv_header->length) { return; } /* do we also want to see a hex dump ? */ if (vflag > 1 || hexdump==TRUE) { print_unknown_data(tptr,"\n\t ", ptr.slow_oam_tlv_header->length); } tlen -= ptr.slow_oam_tlv_header->length; tptr += ptr.slow_oam_tlv_header->length; } break; case SLOW_OAM_CODE_EVENT_NOTIF: while (tlen > 0) { ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr; printf("\n\t %s Link Event Type (%u), length %u", tok2str(slow_oam_link_event_values, "Reserved", ptr.slow_oam_tlv_header->type), ptr.slow_oam_tlv_header->type, ptr.slow_oam_tlv_header->length); hexdump = FALSE; switch (ptr.slow_oam_tlv_header->type) { case SLOW_OAM_LINK_EVENT_END_OF_TLV: if (ptr.slow_oam_tlv_header->length != 0) { printf("\n\t ERROR: illegal length - should be 0"); } return; case SLOW_OAM_LINK_EVENT_ERR_SYM_PER: /* identical format - fall through */ case SLOW_OAM_LINK_EVENT_ERR_FRM: case SLOW_OAM_LINK_EVENT_ERR_FRM_PER: case SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM: tlv.slow_oam_link_event = (const struct slow_oam_link_event_t *)tptr; if (tlv.slow_oam_link_event->event_length != sizeof(struct slow_oam_link_event_t)) { printf("\n\t ERROR: illegal length - should be %lu", (unsigned long) sizeof(struct slow_oam_link_event_t)); return; } printf("\n\t Timestamp %u ms, Errored Window %" PRIu64 "\n\t Errored Threshold %" PRIu64 "\n\t Errors %" PRIu64 "\n\t Error Running Total %" PRIu64 "\n\t Event Running Total %u", EXTRACT_16BITS(&tlv.slow_oam_link_event->time_stamp)*100, EXTRACT_64BITS(&tlv.slow_oam_link_event->window), EXTRACT_64BITS(&tlv.slow_oam_link_event->threshold), EXTRACT_64BITS(&tlv.slow_oam_link_event->errors), EXTRACT_64BITS(&tlv.slow_oam_link_event->errors_running_total), EXTRACT_32BITS(&tlv.slow_oam_link_event->event_running_total)); break; case SLOW_OAM_LINK_EVENT_ORG_SPECIFIC: hexdump = TRUE; break; default: hexdump = TRUE; break; } /* infinite loop check */ if (!ptr.slow_oam_tlv_header->length) { return; } /* do we also want to see a hex dump ? */ if (vflag > 1 || hexdump==TRUE) { print_unknown_data(tptr,"\n\t ", ptr.slow_oam_tlv_header->length); } tlen -= ptr.slow_oam_tlv_header->length; tptr += ptr.slow_oam_tlv_header->length; } break; case SLOW_OAM_CODE_LOOPBACK_CTRL: tlv.slow_oam_loopbackctrl = (const struct slow_oam_loopbackctrl_t *)tptr; printf("\n\t Command %s (%u)", tok2str(slow_oam_loopbackctrl_cmd_values, "Unknown", tlv.slow_oam_loopbackctrl->command), tlv.slow_oam_loopbackctrl->command); tptr ++; tlen --; break; /* * FIXME those are the defined codes that lack a decoder * you are welcome to contribute code ;-) */ case SLOW_OAM_CODE_VAR_REQUEST: case SLOW_OAM_CODE_VAR_RESPONSE: case SLOW_OAM_CODE_PRIVATE: default: if (vflag <= 1) { print_unknown_data(tptr,"\n\t ", tlen); } break; } return; } tcpdump-4.5.1/util.c0000644000026300017510000003350012237020316011734 0ustar mcr/* * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.109 2007-01-29 09:59:42 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_FCNTL_H #include #endif #include #include #include #include #include #include "interface.h" char * ts_format(register int, register int); /* * Print out a null-terminated filename (or other ascii string). * If ep is NULL, assume no truncation check is needed. * Return true if truncated. */ int fn_print(register const u_char *s, register const u_char *ep) { register int ret; register u_char c; ret = 1; /* assume truncated */ while (ep == NULL || s < ep) { c = *s++; if (c == '\0') { ret = 0; break; } if (!isascii(c)) { c = toascii(c); putchar('M'); putchar('-'); } if (!isprint(c)) { c ^= 0x40; /* DEL to ?, others to alpha */ putchar('^'); } putchar(c); } return(ret); } /* * Print out a counted filename (or other ascii string). * If ep is NULL, assume no truncation check is needed. * Return true if truncated. */ int fn_printn(register const u_char *s, register u_int n, register const u_char *ep) { register u_char c; while (n > 0 && (ep == NULL || s < ep)) { n--; c = *s++; if (!isascii(c)) { c = toascii(c); putchar('M'); putchar('-'); } if (!isprint(c)) { c ^= 0x40; /* DEL to ?, others to alpha */ putchar('^'); } putchar(c); } return (n == 0) ? 0 : 1; } /* * Print out a null-padded filename (or other ascii string). * If ep is NULL, assume no truncation check is needed. * Return true if truncated. */ int fn_printzp(register const u_char *s, register u_int n, register const u_char *ep) { register int ret; register u_char c; ret = 1; /* assume truncated */ while (n > 0 && (ep == NULL || s < ep)) { n--; c = *s++; if (c == '\0') { ret = 0; break; } if (!isascii(c)) { c = toascii(c); putchar('M'); putchar('-'); } if (!isprint(c)) { c ^= 0x40; /* DEL to ?, others to alpha */ putchar('^'); } putchar(c); } return (n == 0) ? 0 : ret; } /* * Format the timestamp */ char * ts_format(register int sec, register int usec) { static char buf[sizeof("00:00:00.000000")]; (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%06u", sec / 3600, (sec % 3600) / 60, sec % 60, usec); return buf; } /* * Print the timestamp */ void ts_print(register const struct timeval *tvp) { register int s; struct tm *tm; time_t Time; static unsigned b_sec; static unsigned b_usec; int d_usec; int d_sec; switch (tflag) { case 0: /* Default */ s = (tvp->tv_sec + thiszone) % 86400; (void)printf("%s ", ts_format(s, tvp->tv_usec)); break; case 1: /* No time stamp */ break; case 2: /* Unix timeval style */ (void)printf("%u.%06u ", (unsigned)tvp->tv_sec, (unsigned)tvp->tv_usec); break; case 3: /* Microseconds since previous packet */ case 5: /* Microseconds since first packet */ if (b_sec == 0) { /* init timestamp for first packet */ b_usec = tvp->tv_usec; b_sec = tvp->tv_sec; } d_usec = tvp->tv_usec - b_usec; d_sec = tvp->tv_sec - b_sec; while (d_usec < 0) { d_usec += 1000000; d_sec--; } (void)printf("%s ", ts_format(d_sec, d_usec)); if (tflag == 3) { /* set timestamp for last packet */ b_sec = tvp->tv_sec; b_usec = tvp->tv_usec; } break; case 4: /* Default + Date*/ s = (tvp->tv_sec + thiszone) % 86400; Time = (tvp->tv_sec + thiszone) - s; tm = gmtime (&Time); if (!tm) printf("Date fail "); else printf("%04d-%02d-%02d %s ", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, ts_format(s, tvp->tv_usec)); break; } } /* * Print a relative number of seconds (e.g. hold time, prune timer) * in the form 5m1s. This does no truncation, so 32230861 seconds * is represented as 1y1w1d1h1m1s. */ void relts_print(int secs) { static const char *lengths[] = {"y", "w", "d", "h", "m", "s"}; static const int seconds[] = {31536000, 604800, 86400, 3600, 60, 1}; const char **l = lengths; const int *s = seconds; if (secs == 0) { (void)printf("0s"); return; } if (secs < 0) { (void)printf("-"); secs = -secs; } while (secs > 0) { if (secs >= *s) { (void)printf("%d%s", secs / *s, *l); secs -= (secs / *s) * *s; } s++; l++; } } /* * this is a generic routine for printing unknown data; * we pass on the linefeed plus indentation string to * get a proper output - returns 0 on error */ int print_unknown_data(const u_char *cp,const char *ident,int len) { if (len < 0) { printf("%sDissector error: print_unknown_data called with negative length", ident); return(0); } if (snapend - cp < len) len = snapend - cp; if (len < 0) { printf("%sDissector error: print_unknown_data called with pointer past end of packet", ident); return(0); } hex_print(ident,cp,len); return(1); /* everything is ok */ } /* * Convert a token value to a string; use "fmt" if not found. */ const char * tok2strbuf(register const struct tok *lp, register const char *fmt, register int v, char *buf, size_t bufsize) { if (lp != NULL) { while (lp->s != NULL) { if (lp->v == v) return (lp->s); ++lp; } } if (fmt == NULL) fmt = "#%d"; (void)snprintf(buf, bufsize, fmt, v); return (const char *)buf; } /* * Convert a token value to a string; use "fmt" if not found. */ const char * tok2str(register const struct tok *lp, register const char *fmt, register int v) { static char buf[4][128]; static int idx = 0; char *ret; ret = buf[idx]; idx = (idx+1) & 3; return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0])); } /* * Convert a bit token value to a string; use "fmt" if not found. * this is useful for parsing bitfields, the output strings are seperated * if the s field is positive. */ static char * bittok2str_internal(register const struct tok *lp, register const char *fmt, register int v, register int sep) { static char buf[256]; /* our stringbuffer */ int buflen=0; register int rotbit; /* this is the bit we rotate through all bitpositions */ register int tokval; while (lp != NULL && lp->s != NULL) { tokval=lp->v; /* load our first value */ rotbit=1; while (rotbit != 0) { /* * lets AND the rotating bit with our token value * and see if we have got a match */ if (tokval == (v&rotbit)) { /* ok we have found something */ buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s", lp->s, sep ? ", " : ""); break; } rotbit=rotbit<<1; /* no match - lets shift and try again */ } lp++; } /* user didn't want string seperation - no need to cut off trailing seperators */ if (!sep) { return (buf); } if (buflen != 0) { /* did we find anything */ /* yep, set the the trailing zero 2 bytes before to eliminate the last comma & whitespace */ buf[buflen-2] = '\0'; return (buf); } else { /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */ if (fmt == NULL) fmt = "#%d"; (void)snprintf(buf, sizeof(buf), fmt, v); return (buf); } } /* * Convert a bit token value to a string; use "fmt" if not found. * this is useful for parsing bitfields, the output strings are not seperated. */ char * bittok2str_nosep(register const struct tok *lp, register const char *fmt, register int v) { return (bittok2str_internal(lp, fmt, v, 0)); } /* * Convert a bit token value to a string; use "fmt" if not found. * this is useful for parsing bitfields, the output strings are comma seperated. */ char * bittok2str(register const struct tok *lp, register const char *fmt, register int v) { return (bittok2str_internal(lp, fmt, v, 1)); } /* * Convert a value to a string using an array; the macro * tok2strary() in is the public interface to * this function and ensures that the second argument is * correct for bounds-checking. */ const char * tok2strary_internal(register const char **lp, int n, register const char *fmt, register int v) { static char buf[128]; if (v >= 0 && v < n && lp[v] != NULL) return lp[v]; if (fmt == NULL) fmt = "#%d"; (void)snprintf(buf, sizeof(buf), fmt, v); return (buf); } /* * Convert a 32-bit netmask to prefixlen if possible * the function returns the prefix-len; if plen == -1 * then conversion was not possible; */ int mask2plen(u_int32_t mask) { u_int32_t bitmasks[33] = { 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff }; int prefix_len = 32; /* let's see if we can transform the mask into a prefixlen */ while (prefix_len >= 0) { if (bitmasks[prefix_len] == mask) break; prefix_len--; } return (prefix_len); } #ifdef INET6 int mask62plen(const u_char *mask) { u_char bitmasks[9] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; int byte; int cidr_len = 0; for (byte = 0; byte < 16; byte++) { u_int bits; for (bits = 0; bits < (sizeof (bitmasks) / sizeof (bitmasks[0])); bits++) { if (mask[byte] == bitmasks[bits]) { cidr_len += bits; break; } } if (mask[byte] != 0xff) break; } return (cidr_len); } #endif /* INET6 */ /* VARARGS */ void error(const char *fmt, ...) { va_list ap; (void)fprintf(stderr, "%s: ", program_name); va_start(ap, fmt); (void)vfprintf(stderr, fmt, ap); va_end(ap); if (*fmt) { fmt += strlen(fmt); if (fmt[-1] != '\n') (void)fputc('\n', stderr); } exit(1); /* NOTREACHED */ } /* VARARGS */ void warning(const char *fmt, ...) { va_list ap; (void)fprintf(stderr, "%s: WARNING: ", program_name); va_start(ap, fmt); (void)vfprintf(stderr, fmt, ap); va_end(ap); if (*fmt) { fmt += strlen(fmt); if (fmt[-1] != '\n') (void)fputc('\n', stderr); } } /* * Copy arg vector into a new buffer, concatenating arguments with spaces. */ char * copy_argv(register char **argv) { register char **p; register u_int len = 0; char *buf; char *src, *dst; p = argv; if (*p == 0) return 0; while (*p) len += strlen(*p++) + 1; buf = (char *)malloc(len); if (buf == NULL) error("copy_argv: malloc"); p = argv; dst = buf; while ((src = *p++) != NULL) { while ((*dst++ = *src++) != '\0') ; dst[-1] = ' '; } dst[-1] = '\0'; return buf; } /* * On Windows, we need to open the file in binary mode, so that * we get all the bytes specified by the size we get from "fstat()". * On UNIX, that's not necessary. O_BINARY is defined on Windows; * we define it as 0 if it's not defined, so it does nothing. */ #ifndef O_BINARY #define O_BINARY 0 #endif char * read_infile(char *fname) { register int i, fd, cc; register char *cp; struct stat buf; fd = open(fname, O_RDONLY|O_BINARY); if (fd < 0) error("can't open %s: %s", fname, pcap_strerror(errno)); if (fstat(fd, &buf) < 0) error("can't stat %s: %s", fname, pcap_strerror(errno)); cp = malloc((u_int)buf.st_size + 1); if (cp == NULL) error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1, fname, pcap_strerror(errno)); cc = read(fd, cp, (u_int)buf.st_size); if (cc < 0) error("read %s: %s", fname, pcap_strerror(errno)); if (cc != buf.st_size) error("short read %s (%d != %d)", fname, cc, (int)buf.st_size); close(fd); /* replace "# comment" with spaces */ for (i = 0; i < cc; i++) { if (cp[i] == '#') while (i < cc && cp[i] != '\n') cp[i++] = ' '; } cp[cc] = '\0'; return (cp); } void safeputs(const char *s, int maxlen) { int idx = 0; while (*s && idx < maxlen) { safeputchar(*s); idx++; s++; } } void safeputchar(int c) { unsigned char ch; ch = (unsigned char)(c & 0xff); if (ch < 0x80 && isprint(ch)) printf("%c", ch); else printf("\\0x%02x", ch); } tcpdump-4.5.1/machdep.h0000644000026300017510000000252312237020316012366 0ustar mcr/* * Copyright (c) 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * @(#) $Header: /tcpdump/master/tcpdump/machdep.h,v 1.2 2000-01-17 06:24:24 itojun Exp $ (LBL) */ #ifndef tcpdump_machdep_h #define tcpdump_machdep_h int abort_on_misalignment(char *, size_t); #endif tcpdump-4.5.1/CHANGES0000644000026300017510000012004112237020316011603 0ustar mcrThursday Nov. 7, 2013 mcr@sandelman.ca and guy@alum.mit.edu. Summary for 4.5.0 tcpdump release some NFSv4 fixes for printing fix printing of unknown TCP options, and tcp fast-open fixes for syslog parser some gcc-version-specific flag tuning adopt MacOS deprecation workarounds for openssl improvements to babel printing add OpenFlow 1.0 (no SSL) and test cases GeoNet printer. added STBC Rx support improvements to DHCPv6 decoder clarify which autoconf is needed Point users to the the-tcpdump-group repository on GitHub rather than the mcr repository Add MSDP printer. Fixed IPv6 check on Solaris and other OSes requiring extra networking libraries. Add support for VXLAN (draft-mahalingam-dutt-dcops-vxlan-03), and add "vxlan" as an option for -T. Add support for OTV (draft-hasmit-otv-04). fixes for DLT_IEEE802_11_RADIO datalink types added MPTCP decoder Saturday April 6, 2013 guy@alum.mit.edu. Summary for 4.4.0 tcpdump release RPKI-RTR (RFC6810) is now official (TCP Port 323) Fix detection of OpenSSL libcrypto. Add DNSSL (RFC6106) support. Add "radius" as an option for -T. Update Action codes for handle_action function according to 802.11s amendment. Decode DHCPv6 AFTR-Name option (RFC6334). Updates for Babel. Fix printing of infinite lifetime in ICMPv6. Added support for SPB, SPBM Service Identifier, and Unicast Address sub-TLV in ISIS. Decode RIPv2 authentication up to RFC4822. Fix RIP Request/full table decoding issues. On Linux systems with cap-ng.h, drop root privileges using Linux Capabilities. Add support for reading multiple files. Add MS NLB heartbeat printer. Separate multiple nexthops in BGP. Wednesday November 28, 2012 guy@alum.mit.edu. Summary for 4.3.1 tcpdump release Print "LLDP, length N" for LLDP packets even when not in verbose mode, so something is printed even if only the timestamp is present Document "-T carp" Print NTP poll interval correctly (it's an exponent, so print both its raw value and 2^value) Document that "-e" is used to get MAC addresses More clearly document that you need to escape or quote backslashes in filter expressions on the command line Fix some "the the" in the man page Use the right maximum path length Don't treat 192_1_2, when passed to -i, as an interface number Friday April 3, 2012. mcr@sandelman.ca. Summary for 4.3.0 tcpdump release fixes for forces: SPARSE data (per RFC 5810) some more test cases added updates to documentation on -l, -U and -w flags. Fix printing of BGP optional headers. Tried to include DLT_PFSYNC support, failed due to headers required. added TIPC support. Fix LLDP Network Policy bit definitions. fixes for IGMPv3's Max Response Time: it is in units of 0.1 second. SIGUSR1 can be used rather than SIGINFO for stats permit -n flag to affect print-ip for protocol numbers ND_OPT_ADVINTERVAL is in milliseconds, not seconds Teach PPPoE parser about RFC 4638 Friday December 9, 2011. guy@alum.mit.edu. Summary for 4.2.1 tcpdump release Only build the Babel printer if IPv6 is enabled. Support Babel on port 6696 as well as 6697. Include ppi.h in release tarball. Include all the test files in the release tarball, and don't "include" test files that no longer exist. Don't assume we have - check for it. Support "-T carp" as a way of dissecting IP protocol 112 as CARP rather than VRRP. Support Hilscher NetAnalyzer link-layer header format. Constify some pointers and fix compiler warnings. Get rid of never-true test. Fix an unintended fall-through in a case statement in the ARP printer. Fix several cases where sizeof(sizeof(XXX)) was used when just sizeof(XXX) was intended. Make stricter sanity checks in the ES-IS printer. Get rid of some GCCisms that caused builds to fai with compilers that don't support them. Fix typo in man page. Added length checks to Babel printer. Sunday July 24, 2011. mcr@sandelman.ca. Summary for 4.2.+ merged 802.15.4 decoder from Dmitry Eremin-Solenikov updates to forces for new port numbers Use "-H", not "-h", for the 802.11s option. (-h always help) Better ICMPv6 checksum handling. add support for the RPKI/Router Protocol, per -ietf-sidr-rpki-rtr-12 get rid of uuencoded pcap test files, git can do binary. sFlow changes for 64-bit counters. fixes for PPI packet header handling and printing. Add DCB Exchange protocol (DCBX) version 1.01. Babel dissector, from Juliusz Chroboczek and Grégoire Henry. improvements to radiotap for rate values > 127. Many improvements to ForCES decode, including fix SCTP TML port updated RPL type code to RPL-17 draft Improve printout of DHCPv6 options. added support and test case for QinQ (802.1q VLAN) packets Handle DLT_IEEE802_15_4_NOFCS like DLT_IEEE802_15_4. Build fixes for Sparc and other machines with alignment restrictions. Merged changes from Debian package. PGM: Add ACK decoding and add PGMCC DATA and FEEDBACK options. Build fixes for OSX (Snow Leopard and others) Add support for IEEE 802.15.4 packets Tue. July 20, 2010. guy@alum.mit.edu. Summary for 4.1.2 tcpdump release If -U is specified, flush the file after creating it, so it's not zero-length Fix TCP flags output description, and some typoes, in the man page Add a -h flag, and only attempt to recognize 802.11s mesh headers if it's set When printing the link-layer type list, send *all* output to stderr Include the CFLAGS setting when configure was run in the compiler flags Thu. April 1, 2010. guy@alum.mit.edu. Summary for 4.1.1 tcpdump release Fix build on systems with PF, such as FreeBSD and OpenBSD. Don't blow up if a zero-length link-layer address is passed to linkaddr_string(). Thu. March 11, 2010. ken@netfunctional.ca/guy@alum.mit.edu. Summary for 4.1.0 tcpdump release Fix printing of MAC addresses for VLAN frames with a length field Add some additional bounds checks and use the EXTRACT_ macros more Add a -b flag to print the AS number in BGP packets in ASDOT notation rather than ASPLAIN notation Add ICMPv6 RFC 5006 support Decode the access flags in NFS access requests Handle the new DLT_ for memory-mapped USB captures on Linux Make the default snapshot (-s) the maximum Print name of device (when -L is used) Support for OpenSolaris (and SXCE build 125 and later) Print new TCP flags Add support for RPL DIO Add support for TCP User Timeout (UTO) Add support for non-standard Ethertypes used by 3com PPPoE gear Add support for 802.11n and 802.11s Add support for Transparent Ethernet Bridge ethertype in GRE Add 4 byte AS support for BGP printer Add support for the MDT SAFI 66 BG printer Add basic IPv6 support to print-olsr Add USB printer Add printer for ForCES Handle frames with an FCS Handle 802.11n Control Wrapper, Block Acq Req and Block Ack frames Fix TCP sequence number printing Report 802.2 packets as 802.2 instead of 802.3 Don't include -L/usr/lib in LDFLAGS On x86_64 Linux, look in lib64 directory too Lots of code clean ups Autoconf clean ups Update testcases to make output changes Fix compiling with/out smi (--with{,out}-smi) Fix compiling without IPv6 support (--disable-ipv6) Mon. October 27, 2008. ken@netfunctional.ca. Summary for 4.0.0 tcpdump release Add support for Bluetooth Sniffing Add support for Realtek Remote Control Protocol (openrrcp.org.ru) Add support for 802.11 AVS Add support for SMB over TCP Add support for 4 byte BGP AS printing Add support for compiling on case-insensitive file systems Add support for ikev2 printing Update support for decoding AFS Update DHCPv6 printer Use newer libpcap API's (allows -B option on all platforms) Add -I to turn on monitor mode Bugfixes in lldp, lspping, dccp, ESP, NFS printers Cleanup unused files and various cruft Mon. September 10, 2007. ken@xelerance.com. Summary for 3.9.8 tcpdump release Rework ARP printer Rework OSPFv3 printer Add support for Frame-Relay ARP Decode DHCP Option 121 (RFC 3442 Classless Static Route) Decode DHCP Option 249 (MS Classless Static Route) the same as Option 121 TLV: Add support for Juniper .pcap extensions Print EGP header in new-world-order style Converted print-isakmp.c to NETDISSECT Moved AF specific stuff into af.h Test subsystem now table driven, and saves outputs and diffs to one place Require for pf definitions - allows reading of pflog formatted libpcap files on an OS other than where the file was generated Wed. July 23, 2007. mcr@xelerance.com. Summary for 3.9.7 libpcap release NFS: Print unsigned values as such. RX: parse safely. BGP: fixes for IPv6-less builds. 801.1ag: use standard codepoint. use /dev/bpf on systems with such a device. 802.11: print QoS data, avoid dissect of no-data frame, ignore padding. smb: make sure that we haven't gone past the end of the captured data. smb: squelch an uninitialized complaint from coverity. NFS: from NetBSD; don't interpret the reply as a possible NFS reply if it got MSG_DENIED. BGP: don't print TLV values that didn't fit, from www.digit-labs.org. revised INSTALL.txt about libpcap dependancy. Wed. April 25, 2007. ken@xelerance.com. Summary for 3.9.6 tcpdump release Update man page to reflect changes to libpcap Changes to both TCP and IP Printer Output Fix a potential buffer overflow in the 802.11 printer Print basic info about a few more Cisco LAN protocols. mDNS cleanup ICMP MPLS rework of the extension code bugfix: use the correct codepoint for the OSPF simple text auth token entry, and use safeputs to print the password. Add support in pflog for additional values Add support for OIF RSVP Extensions UNI 1.0 Rev. 2 and additional RSVP objects Add support for the Message-id NACK c-type. Add support for 802.3ah loopback ctrl msg Add support for Multiple-STP as per 802.1s Add support for rapid-SPT as per 802.1w Add support for CFM Link-trace msg, Link-trace-Reply msg, Sender-ID tlv, private tlv, port, interface status Add support for unidirectional link detection as per http://www.ietf.org/internet-drafts/draft-foschiano-udld-02.txt Add support for the olsr protocol as per RFC 3626 plus the LQ extensions from olsr.org Add support for variable-length checksum in DCCP, as per section 9 of RFC 4340. Add support for per-VLAN spanning tree and per-VLAN rapid spanning tree Add support for Multiple-STP as per 802.1s Add support for the cisco propriatry 'dynamic trunking protocol' Add support for the cisco proprietary VTP protocol Update dhcp6 options table as per IETF standardization activities Tue. September 19, 2006. ken@xelerance.com. Summary for 3.9.5 tcpdump release Fix compiling on AIX (, at end of ENUM) Updated list of DNS RR typecodes Use local Ethernet defs on WIN32 Add support for Frame-Relay ARP Fixes for compiling under MSVC++ Add support for parsing Juniper .pcap files Add support for FRF.16 Multilink Frame-Relay (DLT_MFR) Rework the OSPFv3 printer Fix printing for 4.4BSD/NetBSD NFS Filehandles Add support for Cisco style NLPID encapsulation Add cisco prop. eigrp related, extended communities Add support for BGP signaled VPLS Cleanup the bootp printer Add support for PPP over Frame-Relay Add some bounds checking to the IP options code, and clean up the options output a bit. Add additional modp groups to ISAKMP printer Add support for Address-Withdraw and Label-Withdraw Msgs Add support for the BFD Discriminator TLV Fixes for 64bit compiling Add support for PIMv2 checksum verification Add support for further dissection of the IPCP Compression Option Add support for Cisco's proposed VQP protocol Add basic support for keyed authentication TCP option Lots of minor cosmetic changes to output printers Mon. September 19, 2005. ken@xelerance.com. Summary for 3.9.4 tcpdump release Decoder support for more Juniper link-layer types Fix a potential buffer overflow (although it can't occur in practice). Fix the handling of unknown management frame types in the 802.11 printer. Add FRF.16 support, fix various Frame Relay bugs. Add support for RSVP integrity objects, update fast-reroute object printer to latest spec. Clean up documentation of vlan filter expression, document mpls filter expression. Document new pppoed and pppoes filter expressions. Update diffserver-TE codepoints as per RFC 4124. Spelling fixes in ICMPv6. Don't require any fields other than flags to be present in IS-IS restart signaling TLVs, and only print the system ID in those TLVs as system IDs, not as node IDs. Support for DCCP. Tue. July 5, 2005. ken@xelerance.com. Summary for 3.9.3 tcpdump release Option to chroot() when dropping privs Fixes for compiling on nearly every platform, including improved 64bit support Many new testcases Support for sending packets Many compliation fixes on most platforms Fixes for recent version of GCC to eliminate warnings Improved Unicode support Decoders & DLT Changes, Updates and New: AES ESP support Juniper ATM, FRF.15, FRF.16, PPPoE, ML-FR, ML-PIC, ML-PPP, PL-PPP, LS-PIC GGSN,ES,MONITOR,SERVICES L2VPN Axent Raptor/Symantec Firewall TCP-MD5 (RFC 2385) ESP-in-UDP (RFC 3948) ATM OAM LMP, LMP Service Discovery IP over FC IP over IEEE 1394 BACnet MS/TP SS7 LDP over TCP LACP, MARKER as per 802.3ad PGM (RFC 3208) LSP-PING G.7041/Y.1303 Generic Framing Procedure EIGRP-IP, EIGRP-IPX ICMP6 Radio - via radiotap DHCPv6 HDLC over PPP Tue. March 30, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.3 release No changes from 3.8.2. Version bumped only to maintain consistency with libpcap 0.8.3. Mon. March 29, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.2 release Fixes for print-isakmp.c CVE: CAN-2004-0183, CAN-2004-0184 http://www.rapid7.com/advisories/R7-0017.html IP-over-IEEE1394 printing. some MINGW32 changes. updates for autoconf 2.5 fixes for print-aodv.c - check for too short packets formatting changes to print-ascii for hex output. check for too short packets: print-bgp.c, print-bootp.c, print-cdp.c, print-chdlc.c, print-domain.c, print-icmp.c, print-icmp6.c, print-ip.c, print-lwres.c, print-ospf.c, print-pim.c, print-ppp.c,print-pppoe.c, print-rsvp.c, print-wb.c print-ether.c - better handling of unknown types. print-isoclns.c - additional decoding of types. print-llc.c - strings for LLC names added. print-pfloc.c - various enhancements print-radius.c - better decoding to strings. Wed. November 12, 2003. mcr@sandelman.ottawa.on.ca. Summary for 3.8 release changed syntax of -E argument so that multiple SAs can be decrypted fixes for Digital Unix headers and Documentation __attribute__ fixes CDP changes from Terry Kennedy . IPv6 mobility updates from Kazushi Sugyo Fixes for ASN.1 decoder for 2.100.3 forms. Added a count of packets received and processed to clarify numbers. Incorporated WinDUMP patches for Win32 builds. PPPoE payload length headers. Fixes for HP C compiler builds. Use new pcap_breakloop() and pcap_findalldevs() if we can. BGP output split into multiple lines. Fixes to 802.11 decoding. Fixes to PIM decoder. SuperH is a CPU that can't handle unaligned access. Many fixes for unaligned access work. Fixes to Frame-Relay decoder for Q.933/922 frames. Clarified when Solaris can do captures as non-root. Added tests/ subdir for examples/regression tests. New -U flag. -flush stdout after every packet New -A flag -print ascii only support for decoding IS-IS inside Cisco HDLC Frames more verbosity for tftp decoder mDNS decoder new BFD decoder cross compilation patches RFC 3561 AODV support. UDP/TCP pseudo-checksum properly for source-route options. sanitized all files to modified BSD license Add support for RFC 2625 IP-over-Fibre Channel. fixes for DECnet support. Support RFC 2684 bridging of Ethernet, 802.5 Token Ring, and FDDI. RFC 2684 encapsulation of BPDUs. Tuesday, February 25, 2003. fenner@research.att.com. 3.7.2 release Fixed infinite loop when parsing malformed isakmp packets. (reported by iDefense; already fixed in CVS) Fixed infinite loop when parsing malformed BGP packets. Fixed buffer overflow with certain malformed NFS packets. Pretty-print unprintable network names in 802.11 printer. Handle truncated nbp (appletalk) packets. Updated DHCPv6 printer to match draft-ietf-dhc-dhcpv6-22.txt Print IP protocol name even if we don't have a printer for it. Print IP protocol name or number for fragments. Print the whole MPLS label stack, not just the top label. Print request header and file handle for NFS v3 FSINFO and PATHCONF requests. Fix NFS packet truncation checks. Handle "old" DR-Priority and Bidir-Capable PIM HELLO options. Handle unknown RADIUS attributes properly. Fix an ASN.1 parsing error that would cause e.g. the OID 2.100.3 to be misrepresented as 4.20.3 . Monday, January 21, 2002. mcr@sandelman.ottawa.on.ca. Summary for 3.7 release see http://www.tcpdump.org/cvs-log/2002-01-21.10:16:48.html for commit log. keyword "ipx" added. Better OSI/802.2 support on Linux. IEEE 802.11 support, from clenahan@fortresstech.com, achirica@ttd.net. LLC SAP support for FDDI/token ring/RFC-1483 style ATM BXXP protocol was replaced by the BEEP protocol; improvements to SNAP demux. Changes to "any" interface documentation. Documentation on pcap_stats() counters. Fix a memory leak found by Miklos Szeredi - pcap_ether_aton(). Added MPLS encapsulation decoding per RFC3032. DNS dissector handles TKEY, TSIG and IXFR. adaptive SLIP interface patch from Igor Khristophorov SMB printing has much improved bounds checks OUI 0x0000f8 decoded as encapsulated ethernet for Cisco-custom bridging Zephyr support, from Nickolai Zeldovich . Solaris - devices with digits in them. Stefan Hudson IPX socket 0x85be is for Cisco EIGRP over IPX. Improvements to fragmented ESP handling. SCTP support from Armando L. Caro Jr. Linux ARPHDR_ATM support fixed. Added a "netbeui" keyword, which selects NetBEUI packets. IPv6 ND improvements, MobileIP dissector, 2292bis-02 for RA option. Handle ARPHDR_HDLC from Marcus Felipe Pereira . Handle IPX socket 0x553 -> NetBIOS-over-IPX socket, "nwlink-dgm" Better Linux libc5 compat. BIND9 lwres dissector added. MIPS and SPARC get strict alignment macros (affects print-bgp.c) Apple LocalTalk LINKTYPE_ reserved. New time stamp formats documented. DHCP6 updated to draft-22.txt spec. ICMP types/codes now accept symbolic names. Add SIGINFO handler from LBL encrypted CIPE tunnels in IRIX, from Franz Schaefer . now we are -Wstrict-prototype clean. NetBSD DLT_PPP_ETHER; adapted from Martin Husemann . PPPoE dissector cleaned up. Support for LocalTalk hardware, from Uns Lider . In dissector, now the caller prints the IP addresses rather than proto. cjclark@alum.mit.edu: print the IP proto for non-initial fragments. LLC frames with a DSAP and LSAP of 0xe0 are IPX frames. Linux cooked frames with a type value of LINUX_SLL_P_802_3 are IPX. captures on the "any" device won't be done in promiscuous mode Token Ring support on DLPI - Onno van der Linden ARCNet support, from NetBSD. HSRP dissector, from Julian Cowley . Handle (GRE-encapsulated) PPTP added -C option to rotate save file every optarg * 1,000,000 bytes. support for "vrrp" name - NetBSD, by Klaus Klein . PPTP support, from Motonori Shindo . IS-IS over PPP support, from Hannes Gredler . CNFP support for IPv6,format. Harry Raaymakers . ESP printing updated to RFC2406. HP-UX can now handle large number of PPAs. MSDP printer added. L2TP dissector improvements from Motonori Shindo. Tuesday January 9, 2001. mcr@sandelman.ottawa.on.ca. Summary for 3.6 release Cleaned up documentation. Promisc mode fixes for Linux IPsec changes/cleanups. Alignment fixes for picky architectures Removed dependency on native headers for packet dissectors. Removed Linux specific headers that were shipped libpcap changes provide for exchanging capture files between systems. Save files now have well known PACKET_ values instead of depending upon system dependant mappings of DLT_* types. Support for computing/checking IP and UDP/TCP checksums. Updated autoconf stock files. IPv6 improvements: dhcp (draft-15), mobile-ip6, ppp, ospf6, Added dissector support for: ISOCLNS, Token Ring, IGMPv3, bxxp, timed, vrrp, radius, chdlc, cnfp, cdp, IEEE802.1d, raw-AppleTalk Added filtering support for: VLANs, ESIS, ISIS Improvements to: print-telnet, IPTalk, bootp/dhcp, ECN, PPP, L2TP, PPPoE HP-UX 11.0 -- find the right dlpi device. Solaris 8 - IPv6 works Linux - Added support for an "any" device to capture on all interfaces Security fixes: buffer overrun audit done. Strcpy replaced with strlcpy, sprintf replaced with snprintf. Look for lex problems, and warn about them. v3.5 Fri Jan 28 18:00:00 PST 2000 Bill Fenner - switch to config.h for autoconf - unify RCSID strings - Updated PIMv1, PIMv2, DVMRP, IGMP parsers, add Cisco Auto-RP parser - Really fix the RIP printer - Fix MAC address -> name translation. - some -Wall -Wformat fixes - update makemib to parse much of SMIv2 - Print TCP sequence # with -vv even if you normally wouldn't - Print as much of IP/TCP/UDP headers as possible even if truncated. itojun@iijlab.net - -X will make a ascii dump. from netbsd. - telnet command sequence decoder (ff xx xx). from netbsd. - print-bgp.c: improve options printing. ugly code exists for unaligned option parsing (need some fix). - const poisoning in SMB decoder. - -Wall -Werror clean checks. - bring in KAME IPv6/IPsec decoding code. Assar Westerlund - SNMPv2 and SNMPv3 printer - If compiled with libsmi, tcpdump can load MIBs on the fly to decode SNMP packets. - Incorporate NFS parsing code from NetBSD. Adds support for nfsv3. - portability fixes - permit building in different directories. Ken Hornstein - bring in code at /afs/transarc.com/public/afs-contrib/tools/tcpdump for parsing AFS3 packets Andrew Tridgell - SMB printing code Love - print-rx.c: add code for printing MakeDir and StoreStatus. Also change date format to the right one. Michael C. Richardson - Created tcpdump.org repository v3.4 Sat Jul 25 12:40:55 PDT 1998 - Hardwire Linux slip support since it's too hard to detect. - Redo configuration of "network" libraries (-lsocket and -lnsl) to deal with IRIX. Thanks to John Hawkinson (jhawk@mit.edu) - Added -a which tries to translate network and broadcast addresses to names. Suggested by Rob van Nieuwkerk (robn@verdi.et.tudelft.nl) - Added a configure option to disable gcc. - Added a "raw" packet printer. - Not having an interface address is no longer fatal. Requested by John Hawkinson. - Rework signal setup to accommodate Linux. - OSPF truncation check fix. Also display the type of OSPF packets using MD5 authentication. Thanks to Brian Wellington (bwelling@tis.com) - Fix truncation check bugs in the Kerberos printer. Reported by Ezra Peisach (epeisach@mit.edu) - Don't catch SIGHUP when invoked with nohup(1). Thanks to Dave Plonka (plonka@mfa.com) - Specify full install target as a way of detecting if install directory does not exist. Thanks to Dave Plonka. - Bit-swap FDDI addresses for BSD/OS too. Thanks to Paul Vixie (paul@vix.com) - Fix off-by-one bug when testing size of ethernet packets. Thanks to Marty Leisner (leisner@sdsp.mc.xerox.com) - Add a local autoconf macro to check for routines in libraries; the autoconf version is broken (it only puts the library name in the cache variable name). Thanks to John Hawkinson. - Add a local autoconf macro to check for types; the autoconf version is broken (it uses grep instead of actually compiling a code fragment). - Modified to support the new BSD/OS 2.1 PPP and SLIP link layer header formats. - Extend OSF ip header workaround to versions 1 and 2. - Fix some signed problems in the nfs printer. As reported by David Sacerdote (davids@silence.secnet.com) - Detect group wheel and use it as the default since BSD/OS' install can't hack numeric groups. Reported by David Sacerdote. - AIX needs special loader options. Thanks to Jonathan I. Kamens (jik@cam.ov.com) - Fixed the nfs printer to print port numbers in decimal. Thanks to Kent Vander Velden (graphix@iastate.edu) - Find installed libpcap in /usr/local/lib when not using gcc. - Disallow network masks with non-network bits set. - Attempt to detect "egcs" versions of gcc. - Add missing closing double quotes when displaying bootp strings. Reported by Viet-Trung Luu (vluu@picard.math.uwaterloo.ca) v3.3 Sat Nov 30 20:56:27 PST 1996 - Added Linux support. - GRE encapsulated packet printer thanks to John Hawkinson (jhawk@mit.edu) - Rewrite gmt2local() to avoid problematic os dependencies. - Suppress nfs truncation message on errors. - Add missing m4 quoting in AC_LBL_UNALIGNED_ACCESS autoconf macro. Reported by Joachim Ott (ott@ardala.han.de) - Enable "ip_hl vs. ip_vhl" workaround for OSF4 too. - Print arp hardware type in host order. Thanks to Onno van der Linden (onno@simplex.nl) - Avoid solaris compiler warnings. Thanks to Bruce Barnett (barnett@grymoire.crd.ge.com) - Fix rip printer to not print one more route than is actually in the packet. Thanks to Jean-Luc Richier (Jean-Luc.Richier@imag.fr) and Bill Fenner (fenner@parc.xerox.com) - Use autoconf endian detection since BYTE_ORDER isn't defined on all systems. - Fix dvmrp printer truncation checks and add a dvmrp probe printer. Thanks to Danny J. Mitzel (mitzel@ipsilon.com) - Rewrite ospf printer to improve truncation checks. - Don't parse tcp options past the EOL. As noted by David Sacerdote (davids@secnet.com). Also, check tcp options to make sure they ar actually in the tcp header (in addition to the normal truncation checks). Fix the SACK code to print the N blocks (instead of the first block N times). - Don't say really small UDP packets are truncated just because they aren't big enough to be a RPC. As noted by David Sacerdote. v3.2.1 Sun Jul 14 03:02:26 PDT 1996 - Added rfc1716 icmp codes as suggested by Martin Fredriksson (martin@msp.se) - Print mtu for icmp unreach need frag packets. Thanks to John Hawkinson (jhawk@mit.edu) - Decode icmp router discovery messages. Thanks to Jeffrey Honig (jch@bsdi.com) - Added a printer entry for DLT_IEEE802 as suggested by Tak Kushida (kushida@trl.ibm.co.jp) - Check igmp checksum if possible. Thanks to John Hawkinson. - Made changes for SINIX. Thanks to Andrej Borsenkow (borsenkow.msk@sni.de) - Use autoconf's idea of the top level directory in install targets. Thanks to John Hawkinson. - Avoid infinite loop in tcp options printing code. Thanks to Jeffrey Mogul (mogul@pa.dec.com) - Avoid using -lsocket in IRIX 5.2 and earlier since it breaks snoop. Thanks to John Hawkinson. - Added some more packet truncation checks. - On systems that have it, use sigset() instead of signal() since signal() has different semantics on these systems. - Fixed some more alignment problems on the alpha. - Add code to massage unprintable characters in the domain and ipx printers. Thanks to John Hawkinson. - Added explicit netmask support. Thanks to Steve Nuchia (steve@research.oknet.com) - Add "sca" keyword (for DEC cluster services) as suggested by Terry Kennedy (terry@spcvxa.spc.edu) - Add "atalk" keyword as suggested by John Hawkinson. - Added an igrp printer. Thanks to Francis Dupont (francis.dupont@inria.fr) - Print IPX net numbers in hex a la Novell Netware. Thanks to Terry Kennedy (terry@spcvxa.spc.edu) - Fixed snmp extended tag field parsing bug. Thanks to Pascal Hennequin (pascal.hennequin@hugo.int-evry.fr) - Added some ETHERTYPEs missing on some systems. - Added truncated packet macros and various checks. - Fixed endian problems with the DECnet printer. - Use $CC when checking gcc version. Thanks to Carl Lindberg (carl_lindberg@blacksmith.com) - Fixes for AIX (although this system is not yet supported). Thanks to John Hawkinson. - Fix bugs in the autoconf misaligned accesses code fragment. - Include sys/param.h to get BYTE_ORDER in a few places. Thanks to Pavlin Ivanov Radoslavov (pavlin@cs.titech.ac.jp) v3.2 Sun Jun 23 02:28:10 PDT 1996 - Print new icmp unreachable codes as suggested by Martin Fredriksson (martin@msp.se). Also print code value when unknown for icmp redirect and time exceeded. - Fix an alignment endian bug in getname(). Thanks to John Hawkinson. - Define "new" domain record types if not found in arpa/nameserv.h. Resulted from a suggestion from John Hawkinson (jhawk@mit.edu). Also fixed an endian bug when printing mx record and added some new record types. - Added RIP V2 support. Thanks to Jeffrey Honig (jch@bsdi.com) - Added T/TCP options printing. As suggested by Richard Stevens (rstevens@noao.edu) - Use autoconf to detect architectures that can't handle misaligned accesses. v3.1 Thu Jun 13 20:59:32 PDT 1996 - Changed u_int32/int32 to u_int32_t/int32_t to be consistent with bsd and bind (as suggested by Charles Hannum). - Port to GNU autoconf. - Add support for printing DVMRP and PIM traffic thanks to Havard Eidnes (Havard.Eidnes@runit.sintef.no). - Fix AppleTalk, IPX and DECnet byte order problems due to wrong endian define being referenced. Reported by Terry Kennedy. - Minor fixes to the man page thanks to Mark Andrews. - Endian fixes to RTP and vat packet dumpers, thanks to Bruce Mah (bmah@cs.berkeley.edu). - Added support for new dns types, thanks to Rainer Orth. - Fixed tftp_print() to print the block number for ACKs. - Document -dd and -ddd. Resulted from a bug report from Charlie Slater (cslater@imatek.com). - Check return status from malloc/calloc/etc. - Check return status from pcap_loop() so we can print an error and exit with a bad status if there were problems. - Bail if ip option length is <= 0. Resulted from a bug report from Darren Reed (darrenr@vitruvius.arbld.unimelb.edu.au). - Print out a little more information for sun rpc packets. - Add suport for Kerberos 4 thanks to John Hawkinson (jhawk@mit.edu). - Fixed the Fix EXTRACT_SHORT() and EXTRACT_LONG() macros (which were wrong on little endian machines). - Fixed alignment bug in ipx_decode(). Thanks to Matt Crawford (crawdad@fnal.gov). - Fix ntp_print() to not print garbage when the stratum is "unspecified." Thanks to Deus Ex Machina (root@belle.bork.com). - Rewrote tcp options printer code to check for truncation. Added selective acknowledgment case. - Fixed an endian bug in the ospf printer. Thanks to Jeffrey C Honig (jch@bsdi.com) - Fix rip printer to handle 4.4 BSD sockaddr struct which only uses one octet for the sa_family member. Thanks to Yoshitaka Tokugawa (toku@dit.co.jp) - Don't checksum ip header if we don't have all of it. Thanks to John Hawkinson (jhawk@mit.edu). - Print out hostnames if possible in egp printer. Thanks to Jeffrey Honig (jhc@bsdi.com) v3.1a1 Wed May 3 19:21:11 PDT 1995 - Include time.h when SVR4 is defined to avoid problems under Solaris 2.3. - Fix etheraddr_string() in the ETHER_SERVICE to return the saved strings, not the local buffer. Thanks to Stefan Petri (petri@ibr.cs.tu-bs.de). - Detect when pcap raises the snaplen (e.g. with snit). Print a warning that the selected value was not used. Thanks to Pascal Hennequin (Pascal.Hennequin@hugo.int-evry.fr). - Add a truncated packet test to print-nfs.c. Thanks to Pascal Hennequin. - BYTEORDER -> BYTE_ORDER Thanks to Terry Kennedy (terry@spcvxa.spc.edu). v3.0.3 Sun Oct 1 18:35:00 GMT 1995 - Although there never was a 3.0.3 release, the linux boys cleverly "released" one in late 1995. v3.0.2 Thu Apr 20 21:28:16 PDT 1995 - Change configuration to not use gcc v2 flags with gcc v1. - Redo gmt2local() so that it works under BSDI (which seems to return an empty timezone struct from gettimeofday()). Based on report from Terry Kennedy (terry@spcvxa.spc.edu). - Change configure to recognize IP[0-9]* as "mips" SGI hardware. Based on report from Mark Andrews (mandrews@alias.com). - Don't pass cc flags to gcc. Resulted from a bug report from Rainer Orth (ro@techfak.uni-bielefeld.de). - Fixed printout of connection id for uncompressed tcp slip packets. Resulted from a bug report from Richard Stevens (rstevens@noao.edu). - Hack around deficiency in Ultrix's make. - Add ETHERTYPE_TRAIL define which is missing from irix5. v3.0.1 Wed Aug 31 22:42:26 PDT 1994 - Fix problems with gcc2 vs. malloc() and read() prototypes under SunOS 4. v3.0 Mon Jun 20 19:23:27 PDT 1994 - Added support for printing tcp option timestamps thanks to Mark Andrews (mandrews@alias.com). - Reorganize protocol dumpers to take const pointers to packets so they never change the contents (i.e., they used to do endian conversions in place). Previously, whenever more than one pass was taken over the packet, the packet contents would be dumped incorrectly (i.e., the output form -x would be wrong on little endian machines because the protocol dumpers would modify the data). Thanks to Charles Hannum (mycroft@gnu.ai.mit.edu) for reporting this problem. - Added support for decnet protocol dumping thanks to Jeff Mogul (mogul@pa.dec.com). - Fix bug that caused length of packet to be incorrectly printed (off by ether header size) for unknown ethernet types thanks to Greg Miller (gmiller@kayak.mitre.org). - Added support for IPX protocol dumping thanks to Brad Parker (brad@fcr.com). - Added check to verify IP header checksum under -v thanks to Brad Parker (brad@fcr.com). - Move packet capture code to new libpcap library (which is packaged separately). - Prototype everything and assume an ansi compiler. - print-arp.c: Print hardware ethernet addresses if they're not what we expect. - print-bootp.c: Decode the cmu vendor field. Add RFC1497 tags. Many helpful suggestions from Gordon Ross (gwr@jericho.mc.com). - print-fddi.c: Improvements. Thanks to Jeffrey Mogul (mogul@pa.dec.com). - print-icmp.c: Byte swap netmask before printing. Thanks to Richard Stevens (rstevens@noao.edu). Print icmp type when unknown. - print-ip.c: Print the inner ip datagram of ip-in-ip encapsulated packets. By default, only the inner packet is dumped, appended with the token "(encap)". Under -v, both the inner and output packets are dumped (on the same line). Note that the filter applies to the original packet, not the encapsulated packet. So if you run tcpdump on a net with an IP Multicast tunnel, you cannot filter out the datagrams using the conventional syntax. (You can filter away all the ip-in-ip traffic with "not ip proto 4".) - print-nfs.c: Keep pending rpc's in circular table. Add generic nfs header and remove os dependences. Thanks to Jeffrey Mogul. - print-ospf.c: Improvements. Thanks to Jeffrey Mogul. - tcpdump.c: Add -T flag allows interpretation of "vat", "wb", "rpc" (sunrpc) and rtp packets. Added "inbound" and "outbound" keywords Add && and || operators v2.2.1 Tue Jun 6 17:57:22 PDT 1992 - Fix bug with -c flag. v2.2 Fri May 22 17:19:41 PDT 1992 - savefile.c: Remove hack that shouldn't have been exported. Add truncate checks. - Added the 'icmp' keyword. For example, 'icmp[0] != 8 and icmp[0] != 0' matches non-echo/reply ICMP packets. - Many improvements to filter code optimizer. - Added 'multicast' keyword and extended the 'broadcast' keyword can now be so that protocol qualifications are allowed. For example, "ip broadcast" and "ether multicast" are valid filters. - Added support for monitoring the loopback interface (i.e. 'tcpdump -i lo'). Jeffrey Honig (jch@MITCHELL.CIT.CORNELL.EDU) contributed the kernel patches to netinet/if_loop.c. - Added support for the Ungermann-Bass Ethernet on IBM/PC-RTs running AOS. Contact Jeffrey Honig (jch@MITCHELL.CIT.CORNELL.EDU) for the diffs. - Added EGP and OSPF printers, thanks to Jeffrey Honig. v2.1 Tue Jan 28 11:00:14 PST 1992 - Internal release (never publically exported). v2.0.1 Sun Jan 26 21:10:10 PDT - Various byte ordering fixes. - Add truncation checks. - inet.c: Support BSD style SIOCGIFCONF. - nametoaddr.c: Handle multi addresses for single host. - optimize.c: Rewritten. - pcap-bpf.c: don't choke when we get ptraced. only set promiscuous for broadcast nets. - print-atal.c: Fix an alignment bug (thanks to stanonik@nprdc.navy.mil) Add missing printf() argument. - print-bootp.c: First attempt at decoding the vendor buffer. - print-domain.c: Fix truncation checks. - print-icmp.c: Calculate length of packets from the ip header. - print-ip.c: Print frag id in decimal (so it's easier to match up with non-frags). Add support for ospf, egp and igmp. - print-nfs.c: Lots of changes. - print-ntp.c: Make some verbose output depend on -v. - print-snmp.c: New version from John LoVerso. - print-tcp.c: Print rfc1072 tcp options. - tcpdump.c: Print "0x" prefix for %x formats. Always print 6 digits (microseconds) worth of precision. Fix uid bugs. - A packet dumper has been added (thanks to Jeff Mogul of DECWRL). With this option, you can create an architecture independent binary trace file in real time, without the overhead of the packet printer. At a later time, the packets can be filtered (again) and printed. - BSD is supported. You must have BPF in your kernel. Since the filtering is now done in the kernel, fewer packets are dropped. In fact, with BPF and the packet dumper option, a measly Sun 3/50 can keep up with a busy network. - Compressed SLIP packets can now be dumped, provided you use our SLIP software and BPF. These packets are dumped as any other IP packet; the compressed headers are dumped with the '-e' option. - Machines with little-endian byte ordering are supported (thanks to Jeff Mogul). - Ultrix 4.0 is supported (also thanks to Jeff Mogul). - IBM RT and Stanford Enetfilter support has been added by Rayan Zachariassen . Tcpdump has been tested under both the vanilla Enetfilter interface, and the extended interface (#ifdef'd by IBMRTPC) present in the MERIT version of the Enetfilter. - TFTP packets are now printed (requests only). - BOOTP packets are now printed. - SNMP packets are now printed. (thanks to John LoVerso of Xylogics). - Sparc architectures, including the Sparcstation-1, are now supported thanks to Steve McCanne and Craig Leres. - SunOS 4 is now supported thanks to Micky Liu of Columbia University (micky@cunixc.cc.columbia.edu). - IP options are now printed. - RIP packets are now printed. - There's a -v flag that prints out more information than the default (e.g., it will enable printing of IP ttl, tos and id) and -q flag that prints out less (e.g., it will disable interpretation of AppleTalk-in-UDP). - The grammar has undergone substantial changes (if you have an earlier version of tcpdump, you should re-read the manual entry). The most useful change is the addition of an expression syntax that lets you filter on arbitrary fields or values in the packet. E.g., "ip[0] > 0x45" would print only packets with IP options, "tcp[13] & 3 != 0" would print only TCP SYN and FIN packets. The most painful change is that concatenation no longer means "and" -- e.g., you have to say "host foo and port bar" instead of "host foo port bar". The up side to this down is that repeated qualifiers can be omitted, making most filter expressions shorter. E.g., you can now say "ip host foo and (bar or baz)" to look at ip traffic between hosts foo and bar or between hosts foo and baz. [The old way of saying this was "ip host foo and (ip host bar or ip host baz)".] v2.0 Sun Jan 13 12:20:40 PST 1991 - Initial public release. tcpdump-4.5.1/print-icmp.c0000644000026300017510000005452212237020316013050 0ustar mcr/* * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.87 2007-09-13 17:42:31 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" /* must come after interface.h */ #include "ip.h" #include "udp.h" #include "ipproto.h" #include "mpls.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_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 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 }; #define ICMP_MPLS_EXT_EXTRACT_VERSION(x) (((x)&0xf0)>>4) #define ICMP_MPLS_EXT_VERSION 2 /* * 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_EXTD_MINLEN (156 - sizeof (struct ip)) /* draft-bonica-internet-icmp-08 */ #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) #define ICMP_MPLS_EXT_TYPE(type) \ ((type) == ICMP_UNREACH || \ (type) == ICMP_TIMXCEED || \ (type) == ICMP_PARAMPROB) /* rfc1700 */ #ifndef ICMP_UNREACH_NET_UNKNOWN #define ICMP_UNREACH_NET_UNKNOWN 6 /* destination net unknown */ #endif #ifndef ICMP_UNREACH_HOST_UNKNOWN #define ICMP_UNREACH_HOST_UNKNOWN 7 /* destination host unknown */ #endif #ifndef ICMP_UNREACH_ISOLATED #define ICMP_UNREACH_ISOLATED 8 /* source host isolated */ #endif #ifndef ICMP_UNREACH_NET_PROHIB #define ICMP_UNREACH_NET_PROHIB 9 /* admin prohibited net */ #endif #ifndef ICMP_UNREACH_HOST_PROHIB #define ICMP_UNREACH_HOST_PROHIB 10 /* admin prohibited host */ #endif #ifndef ICMP_UNREACH_TOSNET #define ICMP_UNREACH_TOSNET 11 /* tos prohibited net */ #endif #ifndef ICMP_UNREACH_TOSHOST #define ICMP_UNREACH_TOSHOST 12 /* tos prohibited host */ #endif /* rfc1716 */ #ifndef ICMP_UNREACH_FILTER_PROHIB #define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */ #endif #ifndef ICMP_UNREACH_HOST_PRECEDENCE #define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host precedence violation */ #endif #ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF #define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */ #endif /* Most of the icmp types */ static const struct tok icmp2str[] = { { ICMP_ECHOREPLY, "echo reply" }, { ICMP_SOURCEQUENCH, "source quench" }, { ICMP_ECHO, "echo request" }, { ICMP_ROUTERSOLICIT, "router solicitation" }, { ICMP_TSTAMP, "time stamp request" }, { ICMP_TSTAMPREPLY, "time stamp reply" }, { ICMP_IREQ, "information request" }, { ICMP_IREQREPLY, "information reply" }, { ICMP_MASKREQ, "address mask request" }, { 0, NULL } }; /* Formats for most of the ICMP_UNREACH codes */ static const struct tok unreach2str[] = { { ICMP_UNREACH_NET, "net %s unreachable" }, { ICMP_UNREACH_HOST, "host %s unreachable" }, { ICMP_UNREACH_SRCFAIL, "%s unreachable - source route failed" }, { ICMP_UNREACH_NET_UNKNOWN, "net %s unreachable - unknown" }, { ICMP_UNREACH_HOST_UNKNOWN, "host %s unreachable - unknown" }, { ICMP_UNREACH_ISOLATED, "%s unreachable - source host isolated" }, { ICMP_UNREACH_NET_PROHIB, "net %s unreachable - admin prohibited" }, { ICMP_UNREACH_HOST_PROHIB, "host %s unreachable - admin prohibited" }, { ICMP_UNREACH_TOSNET, "net %s unreachable - tos prohibited" }, { ICMP_UNREACH_TOSHOST, "host %s unreachable - tos prohibited" }, { ICMP_UNREACH_FILTER_PROHIB, "host %s unreachable - admin prohibited filter" }, { ICMP_UNREACH_HOST_PRECEDENCE, "host %s unreachable - host precedence violation" }, { ICMP_UNREACH_PRECEDENCE_CUTOFF, "host %s unreachable - precedence cutoff" }, { 0, NULL } }; /* Formats for the ICMP_REDIRECT codes */ static const struct tok type2str[] = { { ICMP_REDIRECT_NET, "redirect %s to net %s" }, { ICMP_REDIRECT_HOST, "redirect %s to host %s" }, { ICMP_REDIRECT_TOSNET, "redirect-tos %s to net %s" }, { ICMP_REDIRECT_TOSHOST, "redirect-tos %s to host %s" }, { 0, NULL } }; /* rfc1191 */ struct mtu_discovery { u_int16_t unused; u_int16_t nexthopmtu; }; /* rfc1256 */ struct ih_rdiscovery { u_int8_t ird_addrnum; u_int8_t ird_addrsiz; u_int16_t ird_lifetime; }; struct id_rdiscovery { u_int32_t ird_addr; u_int32_t ird_pref; }; /* * draft-bonica-internet-icmp-08 * * The Destination Unreachable, Time Exceeded * and Parameter Problem messages are slighly changed as per * the above draft. A new Length field gets added to give * the caller an idea about the length of the piggypacked * IP packet before the MPLS extension header starts. * * The Length field represents length of the padded "original datagram" * field measured in 32-bit words. * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Type | Code | Checksum | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | unused | Length | unused | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Internet Header + leading octets of original datagram | * | | * | // | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct icmp_ext_t { u_int8_t icmp_type; u_int8_t icmp_code; u_int8_t icmp_checksum[2]; u_int8_t icmp_reserved; u_int8_t icmp_length; u_int8_t icmp_reserved2[2]; u_int8_t icmp_ext_legacy_header[128]; /* extension header starts 128 bytes after ICMP header */ u_int8_t icmp_ext_version_res[2]; u_int8_t icmp_ext_checksum[2]; u_int8_t icmp_ext_data[1]; }; struct icmp_mpls_ext_object_header_t { u_int8_t length[2]; u_int8_t class_num; u_int8_t ctype; }; static const struct tok icmp_mpls_ext_obj_values[] = { { 1, "MPLS Stack Entry" }, { 2, "Extended Payload" }, { 0, NULL} }; /* prototypes */ const char *icmp_tstamp_print(u_int); /* print the milliseconds since midnight UTC */ const char * icmp_tstamp_print(u_int tstamp) { u_int msec,sec,min,hrs; static char buf[64]; msec = tstamp % 1000; sec = tstamp / 1000; min = sec / 60; sec -= min * 60; hrs = min / 60; min -= hrs * 60; snprintf(buf, sizeof(buf), "%02u:%02u:%02u.%03u",hrs,min,sec,msec); return buf; } void icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) { char *cp; const struct icmp *dp; const struct icmp_ext_t *ext_dp; const struct ip *ip; const char *str, *fmt; const struct ip *oip; const struct udphdr *ouh; const u_int8_t *obj_tptr; u_int32_t raw_label; const u_char *snapend_save; const struct icmp_mpls_ext_object_header_t *icmp_mpls_ext_object_header; u_int hlen, dport, mtu, obj_tlen, obj_class_num, obj_ctype; char buf[MAXHOSTNAMELEN + 100]; struct cksum_vec vec[1]; dp = (struct icmp *)bp; ext_dp = (struct icmp_ext_t *)bp; ip = (struct ip *)bp2; str = buf; TCHECK(dp->icmp_code); switch (dp->icmp_type) { case ICMP_ECHO: case ICMP_ECHOREPLY: TCHECK(dp->icmp_seq); (void)snprintf(buf, sizeof(buf), "echo %s, id %u, seq %u", dp->icmp_type == ICMP_ECHO ? "request" : "reply", EXTRACT_16BITS(&dp->icmp_id), EXTRACT_16BITS(&dp->icmp_seq)); break; case ICMP_UNREACH: TCHECK(dp->icmp_ip.ip_dst); switch (dp->icmp_code) { 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); break; case ICMP_UNREACH_PORT: TCHECK(dp->icmp_ip.ip_p); oip = &dp->icmp_ip; hlen = IP_HL(oip) * 4; ouh = (struct udphdr *)(((u_char *)oip) + hlen); TCHECK(ouh->uh_dport); dport = EXTRACT_16BITS(&ouh->uh_dport); switch (oip->ip_p) { case IPPROTO_TCP: (void)snprintf(buf, sizeof(buf), "%s tcp port %s unreachable", ipaddr_string(&oip->ip_dst), tcpport_string(dport)); break; case IPPROTO_UDP: (void)snprintf(buf, sizeof(buf), "%s udp port %s unreachable", ipaddr_string(&oip->ip_dst), udpport_string(dport)); break; default: (void)snprintf(buf, sizeof(buf), "%s protocol %d port %d unreachable", ipaddr_string(&oip->ip_dst), oip->ip_p, dport); break; } break; case ICMP_UNREACH_NEEDFRAG: { register const struct mtu_discovery *mp; mp = (struct mtu_discovery *)(u_char *)&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)); } } break; default: fmt = tok2str(unreach2str, "#%d %%s unreachable", dp->icmp_code); (void)snprintf(buf, sizeof(buf), fmt, ipaddr_string(&dp->icmp_ip.ip_dst)); break; } break; case ICMP_REDIRECT: TCHECK(dp->icmp_ip.ip_dst); fmt = tok2str(type2str, "redirect-#%d %%s to net %%s", dp->icmp_code); (void)snprintf(buf, sizeof(buf), fmt, ipaddr_string(&dp->icmp_ip.ip_dst), ipaddr_string(&dp->icmp_gwaddr)); break; case ICMP_ROUTERADVERT: { register const struct ih_rdiscovery *ihp; register const struct id_rdiscovery *idp; u_int lifetime, num, size; (void)snprintf(buf, sizeof(buf), "router advertisement"); cp = buf + strlen(buf); ihp = (struct ih_rdiscovery *)&dp->icmp_void; TCHECK(*ihp); (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) - (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) - (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) - (cp - buf), " %d:", num); cp = buf + strlen(buf); size = ihp->ird_addrsiz; if (size != 2) { (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) - (cp - buf), " {%s %u}", ipaddr_string(&idp->ird_addr), EXTRACT_32BITS(&idp->ird_pref)); cp = buf + strlen(buf); ++idp; } } break; case ICMP_TIMXCEED: TCHECK(dp->icmp_ip.ip_dst); switch (dp->icmp_code) { case ICMP_TIMXCEED_INTRANS: str = "time exceeded in-transit"; break; case ICMP_TIMXCEED_REASS: str = "ip reassembly time exceeded"; break; default: (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); else { TCHECK(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", EXTRACT_32BITS(&dp->icmp_mask)); break; case ICMP_TSTAMP: TCHECK(dp->icmp_seq); (void)snprintf(buf, sizeof(buf), "time stamp query id %u seq %u", EXTRACT_16BITS(&dp->icmp_id), EXTRACT_16BITS(&dp->icmp_seq)); break; case ICMP_TSTAMPREPLY: TCHECK(dp->icmp_ttime); (void)snprintf(buf, sizeof(buf), "time stamp reply id %u seq %u: org %s", EXTRACT_16BITS(&dp->icmp_id), EXTRACT_16BITS(&dp->icmp_seq), icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_otime))); (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", recv %s", icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_rtime))); (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", xmit %s", icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_ttime))); break; default: str = tok2str(icmp2str, "type-#%d", dp->icmp_type); break; } (void)printf("ICMP %s, length %u", str, plen); if (vflag && !fragmented) { /* don't attempt checksumming if this is a frag */ u_int16_t sum, icmp_sum; struct cksum_vec vec[1]; if (TTEST2(*bp, plen)) { vec[0].ptr = (const u_int8_t *)(void *)dp; vec[0].len = plen; sum = in_cksum(vec, 1); if (sum != 0) { icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum); (void)printf(" (wrong icmp cksum %x (->%x)!)", icmp_sum, in_cksum_shouldbe(icmp_sum, sum)); } } } /* * print the remnants of the IP packet. * save the snaplength as this may get overidden in the IP printer. */ if (vflag >= 1 && !ICMP_INFOTYPE(dp->icmp_type)) { bp += 8; (void)printf("\n\t"); ip = (struct ip *)bp; snaplen = snapend - bp; snapend_save = snapend; ip_print(gndo, bp, EXTRACT_16BITS(&ip->ip_len)); snapend = snapend_save; } /* * Attempt to decode the MPLS extensions only for some ICMP types. */ if (vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) { TCHECK(*ext_dp); /* * Check first if the mpls extension header shows a non-zero length. * If the length field is not set then silently verify the checksum * to check if an extension header is present. This is expedient, * however not all implementations set the length field proper. */ if (!ext_dp->icmp_length) { vec[0].ptr = (const u_int8_t *)(void *)&ext_dp->icmp_ext_version_res; vec[0].len = plen - ICMP_EXTD_MINLEN; if (in_cksum(vec, 1)) { return; } } printf("\n\tMPLS extension v%u", ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res))); /* * Sanity checking of the header. */ if (ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)) != ICMP_MPLS_EXT_VERSION) { printf(" packet not supported"); return; } hlen = plen - ICMP_EXTD_MINLEN; vec[0].ptr = (const u_int8_t *)(void *)&ext_dp->icmp_ext_version_res; vec[0].len = hlen; printf(", checksum 0x%04x (%scorrect), length %u", EXTRACT_16BITS(ext_dp->icmp_ext_checksum), in_cksum(vec, 1) ? "in" : "", hlen); hlen -= 4; /* subtract common header size */ obj_tptr = (u_int8_t *)ext_dp->icmp_ext_data; while (hlen > sizeof(struct icmp_mpls_ext_object_header_t)) { icmp_mpls_ext_object_header = (struct icmp_mpls_ext_object_header_t *)obj_tptr; TCHECK(*icmp_mpls_ext_object_header); obj_tlen = EXTRACT_16BITS(icmp_mpls_ext_object_header->length); obj_class_num = icmp_mpls_ext_object_header->class_num; obj_ctype = icmp_mpls_ext_object_header->ctype; obj_tptr += sizeof(struct icmp_mpls_ext_object_header_t); printf("\n\t %s Object (%u), Class-Type: %u, length %u", tok2str(icmp_mpls_ext_obj_values,"unknown",obj_class_num), obj_class_num, obj_ctype, obj_tlen); hlen-=sizeof(struct icmp_mpls_ext_object_header_t); /* length field includes tlv header */ /* infinite loop protection */ if ((obj_class_num == 0) || (obj_tlen < sizeof(struct icmp_mpls_ext_object_header_t))) { return; } obj_tlen-=sizeof(struct icmp_mpls_ext_object_header_t); switch (obj_class_num) { case 1: switch(obj_ctype) { case 1: TCHECK2(*obj_tptr, 4); raw_label = EXTRACT_32BITS(obj_tptr); printf("\n\t label %u, exp %u", MPLS_LABEL(raw_label), MPLS_EXP(raw_label)); if (MPLS_STACK(raw_label)) printf(", [S]"); printf(", ttl %u", MPLS_TTL(raw_label)); break; default: print_unknown_data(obj_tptr, "\n\t ", obj_tlen); } break; /* * FIXME those are the defined objects that lack a decoder * you are welcome to contribute code ;-) */ case 2: default: print_unknown_data(obj_tptr, "\n\t ", obj_tlen); break; } if (hlen < obj_tlen) break; hlen -= obj_tlen; obj_tptr += obj_tlen; } } return; trunc: fputs("[|icmp]", stdout); } tcpdump-4.5.1/print-arp.c0000644000026300017510000003227212237020316012700 0ustar mcr/* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.66 2006-03-03 22:53:21 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "netdissect.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 arp_pkthdr { 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_ARCNET 7 /* arcnet hardware format */ #define ARPHRD_FRELAY 15 /* frame relay hardware format */ #define ARPHRD_ATM2225 19 /* ATM (RFC 2225) */ #define ARPHRD_STRIP 23 /* Ricochet Starmode Radio hardware format */ #define ARPHRD_IEEE1394 24 /* IEEE 1394 (FireWire) 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 */ #define ARPOP_NAK 10 /* NAK - only valif for ATM ARP */ /* * 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 ar_sha(ap) (((const u_char *)((ap)+1))+0) #define ar_spa(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln) #define ar_tha(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln+(ap)->ar_pln) #define ar_tpa(ap) (((const u_char *)((ap)+1))+2*(ap)->ar_hln+(ap)->ar_pln) }; #define ARP_HDRLEN 8 #define HRD(ap) EXTRACT_16BITS(&(ap)->ar_hrd) #define HRD_LEN(ap) ((ap)->ar_hln) #define PROTO_LEN(ap) ((ap)->ar_pln) #define OP(ap) EXTRACT_16BITS(&(ap)->ar_op) #define PRO(ap) EXTRACT_16BITS(&(ap)->ar_pro) #define SHA(ap) (ar_sha(ap)) #define SPA(ap) (ar_spa(ap)) #define THA(ap) (ar_tha(ap)) #define TPA(ap) (ar_tpa(ap)) static const struct tok arpop_values[] = { { ARPOP_REQUEST, "Request" }, { ARPOP_REPLY, "Reply" }, { ARPOP_REVREQUEST, "Reverse Request" }, { ARPOP_REVREPLY, "Reverse Reply" }, { ARPOP_INVREQUEST, "Inverse Request" }, { ARPOP_INVREPLY, "Inverse Reply" }, { ARPOP_NAK, "NACK Reply" }, { 0, NULL } }; static const struct tok arphrd_values[] = { { ARPHRD_ETHER, "Ethernet" }, { ARPHRD_IEEE802, "TokenRing" }, { ARPHRD_ARCNET, "ArcNet" }, { ARPHRD_FRELAY, "FrameRelay" }, { ARPHRD_STRIP, "Strip" }, { ARPHRD_IEEE1394, "IEEE 1394" }, { ARPHRD_ATM2225, "ATM" }, { 0, NULL } }; /* * ATM Address Resolution Protocol. * * See RFC 2225 for protocol description. ATMARP packets are similar * to ARP packets, except that there are no length fields for the * protocol address - instead, there are type/length fields for * the ATM number and subaddress - and the hardware addresses consist * of an ATM number and an ATM subaddress. */ struct atmarp_pkthdr { u_short aar_hrd; /* format of hardware address */ u_short aar_pro; /* format of protocol address */ u_char aar_shtl; /* length of source ATM number */ u_char aar_sstl; /* length of source ATM subaddress */ #define ATMARP_IS_E164 0x40 /* bit in type/length for E.164 format */ #define ATMARP_LEN_MASK 0x3F /* length of {sub}address in type/length */ u_short aar_op; /* same as regular ARP */ u_char aar_spln; /* length of source protocol address */ u_char aar_thtl; /* length of target ATM number */ u_char aar_tstl; /* length of target ATM subaddress */ u_char aar_tpln; /* length of target protocol address */ /* * The remaining fields are variable in size, * according to the sizes above. */ #ifdef COMMENT_ONLY u_char aar_sha[]; /* source ATM number */ u_char aar_ssa[]; /* source ATM subaddress */ u_char aar_spa[]; /* sender protocol address */ u_char aar_tha[]; /* target ATM number */ u_char aar_tsa[]; /* target ATM subaddress */ u_char aar_tpa[]; /* target protocol address */ #endif #define ATMHRD(ap) EXTRACT_16BITS(&(ap)->aar_hrd) #define ATMSHRD_LEN(ap) ((ap)->aar_shtl & ATMARP_LEN_MASK) #define ATMSSLN(ap) ((ap)->aar_sstl & ATMARP_LEN_MASK) #define ATMSPROTO_LEN(ap) ((ap)->aar_spln) #define ATMOP(ap) EXTRACT_16BITS(&(ap)->aar_op) #define ATMPRO(ap) EXTRACT_16BITS(&(ap)->aar_pro) #define ATMTHRD_LEN(ap) ((ap)->aar_thtl & ATMARP_LEN_MASK) #define ATMTSLN(ap) ((ap)->aar_tstl & ATMARP_LEN_MASK) #define ATMTPROTO_LEN(ap) ((ap)->aar_tpln) #define aar_sha(ap) ((const u_char *)((ap)+1)) #define aar_ssa(ap) (aar_sha(ap) + ATMSHRD_LEN(ap)) #define aar_spa(ap) (aar_ssa(ap) + ATMSSLN(ap)) #define aar_tha(ap) (aar_spa(ap) + ATMSPROTO_LEN(ap)) #define aar_tsa(ap) (aar_tha(ap) + ATMTHRD_LEN(ap)) #define aar_tpa(ap) (aar_tsa(ap) + ATMTSLN(ap)) }; #define ATMSHA(ap) (aar_sha(ap)) #define ATMSSA(ap) (aar_ssa(ap)) #define ATMSPA(ap) (aar_spa(ap)) #define ATMTHA(ap) (aar_tha(ap)) #define ATMTSA(ap) (aar_tsa(ap)) #define ATMTPA(ap) (aar_tpa(ap)) static u_char ezero[6]; static void atmarp_addr_print(netdissect_options *ndo, const u_char *ha, u_int ha_len, const u_char *srca, u_int srca_len) { if (ha_len == 0) ND_PRINT((ndo, "")); else { ND_PRINT((ndo, "%s", linkaddr_string(ha, LINKADDR_ATM, ha_len))); if (srca_len != 0) ND_PRINT((ndo, ",%s", linkaddr_string(srca, LINKADDR_ATM, srca_len))); } } static void atmarp_print(netdissect_options *ndo, const u_char *bp, u_int length, u_int caplen) { const struct atmarp_pkthdr *ap; u_short pro, hrd, op; ap = (const struct atmarp_pkthdr *)bp; ND_TCHECK(*ap); hrd = ATMHRD(ap); pro = ATMPRO(ap); op = ATMOP(ap); if (!ND_TTEST2(*aar_tpa(ap), ATMTPROTO_LEN(ap))) { ND_PRINT((ndo, "[|ARP]")); ND_DEFAULTPRINT((const u_char *)ap, length); return; } if (!ndo->ndo_eflag) { ND_PRINT((ndo, "ARP, ")); } if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || ATMSPROTO_LEN(ap) != 4 || ATMTPROTO_LEN(ap) != 4 || ndo->ndo_vflag) { ND_PRINT((ndo, "%s, %s (len %u/%u)", tok2str(arphrd_values, "Unknown Hardware (%u)", hrd), tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro), ATMSPROTO_LEN(ap), ATMTPROTO_LEN(ap))); /* don't know know about the address formats */ if (!ndo->ndo_vflag) { goto out; } } /* print operation */ printf("%s%s ", ndo->ndo_vflag ? ", " : "", tok2str(arpop_values, "Unknown (%u)", op)); switch (op) { case ARPOP_REQUEST: ND_PRINT((ndo, "who-has %s", ipaddr_string(ATMTPA(ap)))); if (ATMTHRD_LEN(ap) != 0) { ND_PRINT((ndo, " (")); atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), ATMTSA(ap), ATMTSLN(ap)); ND_PRINT((ndo, ")")); } ND_PRINT((ndo, "tell %s", ipaddr_string(ATMSPA(ap)))); break; case ARPOP_REPLY: ND_PRINT((ndo, "%s is-at ", ipaddr_string(ATMSPA(ap)))); atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); break; case ARPOP_INVREQUEST: ND_PRINT((ndo, "who-is ")); atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), ATMTSA(ap), ATMTSLN(ap)); ND_PRINT((ndo, " tell ")); atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); break; case ARPOP_INVREPLY: atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), ATMSSLN(ap)); ND_PRINT((ndo, "at %s", ipaddr_string(ATMSPA(ap)))); break; case ARPOP_NAK: ND_PRINT((ndo, "for %s", ipaddr_string(ATMSPA(ap)))); break; default: ND_DEFAULTPRINT((const u_char *)ap, caplen); return; } out: ND_PRINT((ndo, ", length %u", length)); return; trunc: ND_PRINT((ndo, "[|ARP]")); } void arp_print(netdissect_options *ndo, const u_char *bp, u_int length, u_int caplen) { const struct arp_pkthdr *ap; u_short pro, hrd, op, linkaddr; ap = (const struct arp_pkthdr *)bp; ND_TCHECK(*ap); hrd = HRD(ap); pro = PRO(ap); op = OP(ap); /* if its ATM then call the ATM ARP printer for Frame-relay ARP most of the fields are similar to Ethernet so overload the Ethernet Printer and set the linkaddr type for linkaddr_string() accordingly */ switch(hrd) { case ARPHRD_ATM2225: atmarp_print(ndo, bp, length, caplen); return; case ARPHRD_FRELAY: linkaddr = LINKADDR_FRELAY; break; default: linkaddr = LINKADDR_ETHER; break; } if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) { ND_PRINT((ndo, "[|ARP]")); ND_DEFAULTPRINT((const u_char *)ap, length); return; } if (!ndo->ndo_eflag) { ND_PRINT((ndo, "ARP, ")); } /* print hardware type/len and proto type/len */ if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || PROTO_LEN(ap) != 4 || HRD_LEN(ap) == 0 || ndo->ndo_vflag) { ND_PRINT((ndo, "%s (len %u), %s (len %u)", tok2str(arphrd_values, "Unknown Hardware (%u)", hrd), HRD_LEN(ap), tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro), PROTO_LEN(ap))); /* don't know know about the address formats */ if (!ndo->ndo_vflag) { goto out; } } /* print operation */ printf("%s%s ", ndo->ndo_vflag ? ", " : "", tok2str(arpop_values, "Unknown (%u)", op)); switch (op) { case ARPOP_REQUEST: ND_PRINT((ndo, "who-has %s", ipaddr_string(TPA(ap)))); if (memcmp((const char *)ezero, (const char *)THA(ap), HRD_LEN(ap)) != 0) ND_PRINT((ndo, " (%s)", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)))); ND_PRINT((ndo, " tell %s", ipaddr_string(SPA(ap)))); break; case ARPOP_REPLY: ND_PRINT((ndo, "%s is-at %s", ipaddr_string(SPA(ap)), linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); break; case ARPOP_REVREQUEST: ND_PRINT((ndo, "who-is %s tell %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); break; case ARPOP_REVREPLY: ND_PRINT((ndo, "%s at %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), ipaddr_string(TPA(ap)))); break; case ARPOP_INVREQUEST: ND_PRINT((ndo, "who-is %s tell %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); break; case ARPOP_INVREPLY: ND_PRINT((ndo,"%s at %s", linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), ipaddr_string(TPA(ap)))); break; default: ND_DEFAULTPRINT((const u_char *)ap, caplen); return; } out: ND_PRINT((ndo, ", length %u", length)); return; trunc: ND_PRINT((ndo, "[|ARP]")); } /* * Local Variables: * c-style: bsd * End: */ tcpdump-4.5.1/ieee802_11_radio.h0000644000026300017510000002733712237020316013617 0ustar mcr/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */ /* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp */ /* $Header: /tcpdump/master/tcpdump/ieee802_11_radio.h,v 1.3 2007-08-29 02:31:44 mcr Exp $ */ /*- * Copyright (c) 2003, 2004 David Young. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of David Young may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifndef _NET_IF_IEEE80211RADIOTAP_H_ #define _NET_IF_IEEE80211RADIOTAP_H_ /* A generic radio capture format is desirable. It must be * rigidly defined (e.g., units for fields should be given), * and easily extensible. * * The following is an extensible radio capture format. It is * based on a bitmap indicating which fields are present. * * I am trying to describe precisely what the application programmer * should expect in the following, and for that reason I tell the * units and origin of each measurement (where it applies), or else I * use sufficiently weaselly language ("is a monotonically nondecreasing * function of...") that I cannot set false expectations for lawyerly * readers. */ /* * The radio capture header precedes the 802.11 header. * * Note well: all radiotap fields are little-endian. */ struct ieee80211_radiotap_header { u_int8_t it_version; /* Version 0. Only increases * for drastic changes, * introduction of compatible * new fields does not count. */ u_int8_t it_pad; u_int16_t it_len; /* length of the whole * header in bytes, including * it_version, it_pad, * it_len, and data fields. */ u_int32_t it_present; /* A bitmap telling which * fields are present. Set bit 31 * (0x80000000) to extend the * bitmap by another 32 bits. * Additional extensions are made * by setting bit 31. */ }; /* Name Data type Units * ---- --------- ----- * * IEEE80211_RADIOTAP_TSFT u_int64_t microseconds * * Value in microseconds of the MAC's 64-bit 802.11 Time * Synchronization Function timer when the first bit of the * MPDU arrived at the MAC. For received frames, only. * * IEEE80211_RADIOTAP_CHANNEL 2 x u_int16_t MHz, bitmap * * Tx/Rx frequency in MHz, followed by flags (see below). * Note that IEEE80211_RADIOTAP_XCHANNEL must be used to * represent an HT channel as there is not enough room in * the flags word. * * IEEE80211_RADIOTAP_FHSS u_int16_t see below * * For frequency-hopping radios, the hop set (first byte) * and pattern (second byte). * * IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s or index * * Tx/Rx data rate. If bit 0x80 is set then it represents an * an MCS index and not an IEEE rate. * * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from * one milliwatt (dBm) * * RF signal power at the antenna, decibel difference from * one milliwatt. * * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from * one milliwatt (dBm) * * RF noise power at the antenna, decibel difference from one * milliwatt. * * IEEE80211_RADIOTAP_DB_ANTSIGNAL u_int8_t decibel (dB) * * RF signal power at the antenna, decibel difference from an * arbitrary, fixed reference. * * IEEE80211_RADIOTAP_DB_ANTNOISE u_int8_t decibel (dB) * * RF noise power at the antenna, decibel difference from an * arbitrary, fixed reference point. * * IEEE80211_RADIOTAP_LOCK_QUALITY u_int16_t unitless * * Quality of Barker code lock. Unitless. Monotonically * nondecreasing with "better" lock strength. Called "Signal * Quality" in datasheets. (Is there a standard way to measure * this?) * * IEEE80211_RADIOTAP_TX_ATTENUATION u_int16_t unitless * * Transmit power expressed as unitless distance from max * power set at factory calibration. 0 is max power. * Monotonically nondecreasing with lower power levels. * * IEEE80211_RADIOTAP_DB_TX_ATTENUATION u_int16_t decibels (dB) * * Transmit power expressed as decibel distance from max power * set at factory calibration. 0 is max power. Monotonically * nondecreasing with lower power levels. * * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from * one milliwatt (dBm) * * Transmit power expressed as dBm (decibels from a 1 milliwatt * reference). This is the absolute power level measured at * the antenna port. * * IEEE80211_RADIOTAP_FLAGS u_int8_t bitmap * * Properties of transmitted and received frames. See flags * defined below. * * IEEE80211_RADIOTAP_ANTENNA u_int8_t antenna index * * Unitless indication of the Rx/Tx antenna for this packet. * The first antenna is antenna 0. * * IEEE80211_RADIOTAP_RX_FLAGS u_int16_t bitmap * * Properties of received frames. See flags defined below. * * IEEE80211_RADIOTAP_XCHANNEL u_int32_t bitmap * u_int16_t MHz * u_int8_t channel number * u_int8_t .5 dBm * * Extended channel specification: flags (see below) followed by * frequency in MHz, the corresponding IEEE channel number, and * finally the maximum regulatory transmit power cap in .5 dBm * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL * and only one of the two should be present. * * IEEE80211_RADIOTAP_MCS u_int8_t known * u_int8_t flags * u_int8_t mcs * * Bitset indicating which fields have known values, followed * by bitset of flag values, followed by the MCS rate index as * in IEEE 802.11n. * * IEEE80211_RADIOTAP_VENDOR_NAMESPACE * u_int8_t OUI[3] * u_int8_t subspace * u_int16_t length * * The Vendor Namespace Field contains three sub-fields. The first * sub-field is 3 bytes long. It contains the vendor's IEEE 802 * Organizationally Unique Identifier (OUI). The fourth byte is a * vendor-specific "namespace selector." * */ enum ieee80211_radiotap_type { IEEE80211_RADIOTAP_TSFT = 0, IEEE80211_RADIOTAP_FLAGS = 1, IEEE80211_RADIOTAP_RATE = 2, IEEE80211_RADIOTAP_CHANNEL = 3, IEEE80211_RADIOTAP_FHSS = 4, IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, IEEE80211_RADIOTAP_LOCK_QUALITY = 7, IEEE80211_RADIOTAP_TX_ATTENUATION = 8, IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, IEEE80211_RADIOTAP_DBM_TX_POWER = 10, IEEE80211_RADIOTAP_ANTENNA = 11, IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, IEEE80211_RADIOTAP_DB_ANTNOISE = 13, IEEE80211_RADIOTAP_RX_FLAGS = 14, /* NB: gap for netbsd definitions */ IEEE80211_RADIOTAP_XCHANNEL = 18, IEEE80211_RADIOTAP_MCS = 19, IEEE80211_RADIOTAP_NAMESPACE = 29, IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, IEEE80211_RADIOTAP_EXT = 31 }; /* channel attributes */ #define IEEE80211_CHAN_TURBO 0x00010 /* Turbo channel */ #define IEEE80211_CHAN_CCK 0x00020 /* CCK channel */ #define IEEE80211_CHAN_OFDM 0x00040 /* OFDM channel */ #define IEEE80211_CHAN_2GHZ 0x00080 /* 2 GHz spectrum channel. */ #define IEEE80211_CHAN_5GHZ 0x00100 /* 5 GHz spectrum channel */ #define IEEE80211_CHAN_PASSIVE 0x00200 /* Only passive scan allowed */ #define IEEE80211_CHAN_DYN 0x00400 /* Dynamic CCK-OFDM channel */ #define IEEE80211_CHAN_GFSK 0x00800 /* GFSK channel (FHSS PHY) */ #define IEEE80211_CHAN_GSM 0x01000 /* 900 MHz spectrum channel */ #define IEEE80211_CHAN_STURBO 0x02000 /* 11a static turbo channel only */ #define IEEE80211_CHAN_HALF 0x04000 /* Half rate channel */ #define IEEE80211_CHAN_QUARTER 0x08000 /* Quarter rate channel */ #define IEEE80211_CHAN_HT20 0x10000 /* HT 20 channel */ #define IEEE80211_CHAN_HT40U 0x20000 /* HT 40 channel w/ ext above */ #define IEEE80211_CHAN_HT40D 0x40000 /* HT 40 channel w/ ext below */ /* Useful combinations of channel characteristics, borrowed from Ethereal */ #define IEEE80211_CHAN_A \ (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) #define IEEE80211_CHAN_B \ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) #define IEEE80211_CHAN_G \ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) #define IEEE80211_CHAN_TA \ (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) #define IEEE80211_CHAN_TG \ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO) /* For IEEE80211_RADIOTAP_FLAGS */ #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received * during CFP */ #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received * with short * preamble */ #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received * with WEP encryption */ #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received * with fragmentation */ #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between * 802.11 header and payload * (to 32-bit boundary) */ #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */ /* For IEEE80211_RADIOTAP_RX_FLAGS */ #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ #define IEEE80211_RADIOTAP_F_RX_PLCP_CRC 0x0002 /* frame failed PLCP CRC check */ /* For IEEE80211_RADIOTAP_MCS known */ #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN 0x01 #define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN 0x02 /* MCS index field */ #define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN 0x04 #define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN 0x08 #define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN 0x10 #define IEEE80211_RADIOTAP_MCS_STBC_KNOWN 0x20 /* For IEEE80211_RADIOTAP_MCS flags */ #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK 0x03 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20 0 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 1 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L 2 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U 3 #define IEEE80211_RADIOTAP_MCS_SHORT_GI 0x04 /* short guard interval */ #define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD 0x08 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 #define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 #define IEEE80211_RADIOTAP_MCS_STBC_1 1 #define IEEE80211_RADIOTAP_MCS_STBC_2 2 #define IEEE80211_RADIOTAP_MCS_STBC_3 3 #define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 #endif /* _NET_IF_IEEE80211RADIOTAP_H_ */ tcpdump-4.5.1/print-dhcp6.c0000644000026300017510000005267012237020316013126 0ustar mcr/* * Copyright (C) 1998 and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * RFC3315: DHCPv6 * supported DHCPv6 options: * RFC3319: Session Initiation Protocol (SIP) Servers options, * RFC3633: IPv6 Prefix options, * RFC3646: DNS Configuration options, * RFC3898: Network Information Service (NIS) Configuration options, * RFC4075: Simple Network Time Protocol (SNTP) Configuration option, * RFC4242: Information Refresh Time option, * RFC4280: Broadcast and Multicast Control Servers options, * RFC5908: Network Time Protocol (NTP) Server Option for DHCPv6 * RFC6334: Dual-Stack Lite option, */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.37 2008-02-06 10:26:09 guy Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" /* lease duration */ #define DHCP6_DURATITION_INFINITE 0xffffffff /* Error Values */ #define DH6ERR_FAILURE 16 #define DH6ERR_AUTHFAIL 17 #define DH6ERR_POORLYFORMED 18 #define DH6ERR_UNAVAIL 19 #define DH6ERR_OPTUNAVAIL 20 /* Message type */ #define DH6_SOLICIT 1 #define DH6_ADVERTISE 2 #define DH6_REQUEST 3 #define DH6_CONFIRM 4 #define DH6_RENEW 5 #define DH6_REBIND 6 #define DH6_REPLY 7 #define DH6_RELEASE 8 #define DH6_DECLINE 9 #define DH6_RECONFIGURE 10 #define DH6_INFORM_REQ 11 #define DH6_RELAY_FORW 12 #define DH6_RELAY_REPLY 13 #define DH6_LEASEQUERY 14 #define DH6_LQ_REPLY 15 /* DHCP6 base packet format */ struct dhcp6 { union { u_int8_t m; u_int32_t x; } dh6_msgtypexid; /* options follow */ }; #define dh6_msgtype dh6_msgtypexid.m #define dh6_xid dh6_msgtypexid.x #define DH6_XIDMASK 0x00ffffff /* DHCPv6 relay messages */ struct dhcp6_relay { u_int8_t dh6relay_msgtype; u_int8_t dh6relay_hcnt; u_int8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */ u_int8_t dh6relay_peeraddr[16]; /* options follow */ }; /* options */ #define DH6OPT_CLIENTID 1 #define DH6OPT_SERVERID 2 #define DH6OPT_IA_NA 3 #define DH6OPT_IA_TA 4 #define DH6OPT_IA_ADDR 5 #define DH6OPT_ORO 6 #define DH6OPT_PREFERENCE 7 # define DH6OPT_PREF_MAX 255 #define DH6OPT_ELAPSED_TIME 8 #define DH6OPT_RELAY_MSG 9 /*#define DH6OPT_SERVER_MSG 10 deprecated */ #define DH6OPT_AUTH 11 # define DH6OPT_AUTHPROTO_DELAYED 2 # define DH6OPT_AUTHPROTO_RECONFIG 3 # define DH6OPT_AUTHALG_HMACMD5 1 # define DH6OPT_AUTHRDM_MONOCOUNTER 0 # define DH6OPT_AUTHRECONFIG_KEY 1 # define DH6OPT_AUTHRECONFIG_HMACMD5 2 #define DH6OPT_UNICAST 12 #define DH6OPT_STATUS_CODE 13 # define DH6OPT_STCODE_SUCCESS 0 # define DH6OPT_STCODE_UNSPECFAIL 1 # define DH6OPT_STCODE_NOADDRAVAIL 2 # define DH6OPT_STCODE_NOBINDING 3 # define DH6OPT_STCODE_NOTONLINK 4 # define DH6OPT_STCODE_USEMULTICAST 5 # define DH6OPT_STCODE_NOPREFIXAVAIL 6 # define DH6OPT_STCODE_UNKNOWNQUERYTYPE 7 # define DH6OPT_STCODE_MALFORMEDQUERY 8 # define DH6OPT_STCODE_NOTCONFIGURED 9 # define DH6OPT_STCODE_NOTALLOWED 10 #define DH6OPT_RAPID_COMMIT 14 #define DH6OPT_USER_CLASS 15 #define DH6OPT_VENDOR_CLASS 16 #define DH6OPT_VENDOR_OPTS 17 #define DH6OPT_INTERFACE_ID 18 #define DH6OPT_RECONF_MSG 19 #define DH6OPT_RECONF_ACCEPT 20 #define DH6OPT_SIP_SERVER_D 21 #define DH6OPT_SIP_SERVER_A 22 #define DH6OPT_DNS_SERVERS 23 #define DH6OPT_DOMAIN_LIST 24 #define DH6OPT_IA_PD 25 #define DH6OPT_IA_PD_PREFIX 26 #define DH6OPT_NIS_SERVERS 27 #define DH6OPT_NISP_SERVERS 28 #define DH6OPT_NIS_NAME 29 #define DH6OPT_NISP_NAME 30 #define DH6OPT_SNTP_SERVERS 31 #define DH6OPT_LIFETIME 32 #define DH6OPT_BCMCS_SERVER_D 33 #define DH6OPT_BCMCS_SERVER_A 34 #define DH6OPT_GEOCONF_CIVIC 36 #define DH6OPT_REMOTE_ID 37 #define DH6OPT_SUBSCRIBER_ID 38 #define DH6OPT_CLIENT_FQDN 39 #define DH6OPT_PANA_AGENT 40 #define DH6OPT_NEW_POSIX_TIMEZONE 41 #define DH6OPT_NEW_TZDB_TIMEZONE 42 #define DH6OPT_ERO 43 #define DH6OPT_LQ_QUERY 44 #define DH6OPT_CLIENT_DATA 45 #define DH6OPT_CLT_TIME 46 #define DH6OPT_LQ_RELAY_DATA 47 #define DH6OPT_LQ_CLIENT_LINK 48 #define DH6OPT_NTP_SERVER 56 # define DH6OPT_NTP_SUBOPTION_SRV_ADDR 1 # define DH6OPT_NTP_SUBOPTION_MC_ADDR 2 # define DH6OPT_NTP_SUBOPTION_SRV_FQDN 3 #define DH6OPT_AFTR_NAME 64 struct dhcp6opt { u_int16_t dh6opt_type; u_int16_t dh6opt_len; /* type-dependent data follows */ }; static const char * dhcp6opt_name(int type) { static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */ if (type > 65535) return "INVALID-option"; switch(type) { case DH6OPT_CLIENTID: return "client-ID"; case DH6OPT_SERVERID: return "server-ID"; case DH6OPT_IA_NA: return "IA_NA"; case DH6OPT_IA_TA: return "IA_TA"; case DH6OPT_IA_ADDR: return "IA_ADDR"; case DH6OPT_ORO: return "option-request"; case DH6OPT_PREFERENCE: return "preference"; case DH6OPT_ELAPSED_TIME: return "elapsed-time"; case DH6OPT_RELAY_MSG: return "relay-message"; case DH6OPT_AUTH: return "authentication"; case DH6OPT_UNICAST: return "server-unicast"; case DH6OPT_STATUS_CODE: return "status-code"; case DH6OPT_RAPID_COMMIT: return "rapid-commit"; case DH6OPT_USER_CLASS: return "user-class"; case DH6OPT_VENDOR_CLASS: return "vendor-class"; case DH6OPT_VENDOR_OPTS: return "vendor-specific-info"; case DH6OPT_INTERFACE_ID: return "interface-ID"; case DH6OPT_RECONF_MSG: return "reconfigure-message"; case DH6OPT_RECONF_ACCEPT: return "reconfigure-accept"; case DH6OPT_SIP_SERVER_D: return "SIP-servers-domain"; case DH6OPT_SIP_SERVER_A: return "SIP-servers-address"; case DH6OPT_DNS_SERVERS: return "DNS-server"; case DH6OPT_DOMAIN_LIST: return "DNS-search-list"; case DH6OPT_IA_PD: return "IA_PD"; case DH6OPT_IA_PD_PREFIX: return "IA_PD-prefix"; case DH6OPT_SNTP_SERVERS: return "SNTP-servers"; case DH6OPT_LIFETIME: return "lifetime"; case DH6OPT_NIS_SERVERS: return "NIS-server"; case DH6OPT_NISP_SERVERS: return "NIS+-server"; case DH6OPT_NIS_NAME: return "NIS-domain-name"; case DH6OPT_NISP_NAME: return "NIS+-domain-name"; case DH6OPT_BCMCS_SERVER_D: return "BCMCS-domain-name"; case DH6OPT_BCMCS_SERVER_A: return "BCMCS-server"; case DH6OPT_GEOCONF_CIVIC: return "Geoconf-Civic"; case DH6OPT_REMOTE_ID: return "Remote-ID"; case DH6OPT_SUBSCRIBER_ID: return "Subscriber-ID"; case DH6OPT_CLIENT_FQDN: return "Client-FQDN"; case DH6OPT_PANA_AGENT: return "PANA-agent"; case DH6OPT_NEW_POSIX_TIMEZONE: return "POSIX-timezone"; case DH6OPT_NEW_TZDB_TIMEZONE: return "POSIX-tz-database"; case DH6OPT_ERO: return "Echo-request-option"; case DH6OPT_LQ_QUERY: return "Lease-query"; case DH6OPT_CLIENT_DATA: return "LQ-client-data"; case DH6OPT_CLT_TIME: return "Clt-time"; case DH6OPT_LQ_RELAY_DATA: return "LQ-relay-data"; case DH6OPT_LQ_CLIENT_LINK: return "LQ-client-link"; case DH6OPT_NTP_SERVER: return "NTP-server"; case DH6OPT_AFTR_NAME: return "AFTR-Name"; default: snprintf(genstr, sizeof(genstr), "opt_%d", type); return(genstr); } } static const char * dhcp6stcode(int code) { static char genstr[sizeof("code255") + 1]; /* XXX thread unsafe */ if (code > 255) return "INVALID code"; switch(code) { case DH6OPT_STCODE_SUCCESS: return "success"; case DH6OPT_STCODE_UNSPECFAIL: return "unspec failure"; case DH6OPT_STCODE_NOADDRAVAIL: return "no addresses"; case DH6OPT_STCODE_NOBINDING: return "no binding"; case DH6OPT_STCODE_NOTONLINK: return "not on-link"; case DH6OPT_STCODE_USEMULTICAST: return "use multicast"; case DH6OPT_STCODE_NOPREFIXAVAIL: return "no prefixes"; case DH6OPT_STCODE_UNKNOWNQUERYTYPE: return "unknown query type"; case DH6OPT_STCODE_MALFORMEDQUERY: return "malformed query"; case DH6OPT_STCODE_NOTCONFIGURED: return "not configured"; case DH6OPT_STCODE_NOTALLOWED: return "not allowed"; default: snprintf(genstr, sizeof(genstr), "code%d", code); return(genstr); } } static void dhcp6opt_print(const u_char *cp, const u_char *ep) { const struct dhcp6opt *dh6o; const u_char *tp; size_t i; u_int16_t opttype; size_t optlen; u_int8_t auth_proto; u_int authinfolen, authrealmlen; int remain_len; /* Length of remaining options */ int label_len; /* Label length */ u_int16_t subopt_code; u_int16_t subopt_len; if (cp == ep) return; while (cp < ep) { if (ep < cp + sizeof(*dh6o)) goto trunc; dh6o = (struct dhcp6opt *)cp; TCHECK(*dh6o); optlen = EXTRACT_16BITS(&dh6o->dh6opt_len); if (ep < cp + sizeof(*dh6o) + optlen) goto trunc; opttype = EXTRACT_16BITS(&dh6o->dh6opt_type); printf(" (%s", dhcp6opt_name(opttype)); switch (opttype) { case DH6OPT_CLIENTID: case DH6OPT_SERVERID: if (optlen < 2) { /*(*/ printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); switch (EXTRACT_16BITS(tp)) { case 1: if (optlen >= 2 + 6) { printf(" hwaddr/time type %u time %u ", EXTRACT_16BITS(&tp[2]), EXTRACT_32BITS(&tp[4])); for (i = 8; i < optlen; i++) printf("%02x", tp[i]); /*(*/ printf(")"); } else { /*(*/ printf(" ?)"); } break; case 2: if (optlen >= 2 + 8) { printf(" vid "); for (i = 2; i < 2 + 8; i++) printf("%02x", tp[i]); /*(*/ printf(")"); } else { /*(*/ printf(" ?)"); } break; case 3: if (optlen >= 2 + 2) { printf(" hwaddr type %u ", EXTRACT_16BITS(&tp[2])); for (i = 4; i < optlen; i++) printf("%02x", tp[i]); /*(*/ printf(")"); } else { /*(*/ printf(" ?)"); } break; default: printf(" type %d)", EXTRACT_16BITS(tp)); break; } break; case DH6OPT_IA_ADDR: if (optlen < 24) { /*(*/ printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); printf(" %s", ip6addr_string(&tp[0])); printf(" pltime:%u vltime:%u", EXTRACT_32BITS(&tp[16]), EXTRACT_32BITS(&tp[20])); if (optlen > 24) { /* there are sub-options */ dhcp6opt_print(tp + 24, tp + optlen); } printf(")"); break; case DH6OPT_ORO: case DH6OPT_ERO: if (optlen % 2) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); for (i = 0; i < optlen; i += 2) { printf(" %s", dhcp6opt_name(EXTRACT_16BITS(&tp[i]))); } printf(")"); break; case DH6OPT_PREFERENCE: if (optlen != 1) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); printf(" %d)", *tp); break; case DH6OPT_ELAPSED_TIME: if (optlen != 2) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); printf(" %d)", EXTRACT_16BITS(tp)); break; case DH6OPT_RELAY_MSG: printf(" ("); tp = (u_char *)(dh6o + 1); dhcp6_print(tp, optlen); printf(")"); break; case DH6OPT_AUTH: if (optlen < 11) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); auth_proto = *tp; switch (auth_proto) { case DH6OPT_AUTHPROTO_DELAYED: printf(" proto: delayed"); break; case DH6OPT_AUTHPROTO_RECONFIG: printf(" proto: reconfigure"); break; default: printf(" proto: %d", auth_proto); break; } tp++; switch (*tp) { case DH6OPT_AUTHALG_HMACMD5: /* XXX: may depend on the protocol */ printf(", alg: HMAC-MD5"); break; default: printf(", alg: %d", *tp); break; } tp++; switch (*tp) { case DH6OPT_AUTHRDM_MONOCOUNTER: printf(", RDM: mono"); break; default: printf(", RDM: %d", *tp); break; } tp++; printf(", RD:"); for (i = 0; i < 4; i++, tp += 2) printf(" %04x", EXTRACT_16BITS(tp)); /* protocol dependent part */ authinfolen = optlen - 11; switch (auth_proto) { case DH6OPT_AUTHPROTO_DELAYED: if (authinfolen == 0) break; if (authinfolen < 20) { printf(" ??"); break; } authrealmlen = authinfolen - 20; if (authrealmlen > 0) { printf(", realm: "); } for (i = 0; i < authrealmlen; i++, tp++) printf("%02x", *tp); printf(", key ID: %08x", EXTRACT_32BITS(tp)); tp += 4; printf(", HMAC-MD5:"); for (i = 0; i < 4; i++, tp+= 4) printf(" %08x", EXTRACT_32BITS(tp)); break; case DH6OPT_AUTHPROTO_RECONFIG: if (authinfolen != 17) { printf(" ??"); break; } switch (*tp++) { case DH6OPT_AUTHRECONFIG_KEY: printf(" reconfig-key"); break; case DH6OPT_AUTHRECONFIG_HMACMD5: printf(" type: HMAC-MD5"); break; default: printf(" type: ??"); break; } printf(" value:"); for (i = 0; i < 4; i++, tp+= 4) printf(" %08x", EXTRACT_32BITS(tp)); break; default: printf(" ??"); break; } printf(")"); break; case DH6OPT_RAPID_COMMIT: /* nothing todo */ printf(")"); break; case DH6OPT_INTERFACE_ID: case DH6OPT_SUBSCRIBER_ID: /* * Since we cannot predict the encoding, print hex dump * at most 10 characters. */ tp = (u_char *)(dh6o + 1); printf(" "); for (i = 0; i < optlen && i < 10; i++) printf("%02x", tp[i]); printf("...)"); break; case DH6OPT_RECONF_MSG: tp = (u_char *)(dh6o + 1); switch (*tp) { case DH6_RENEW: printf(" for renew)"); break; case DH6_INFORM_REQ: printf(" for inf-req)"); break; default: printf(" for ?\?\?(%02x))", *tp); break; } break; case DH6OPT_RECONF_ACCEPT: /* nothing todo */ printf(")"); break; case DH6OPT_SIP_SERVER_A: case DH6OPT_DNS_SERVERS: case DH6OPT_SNTP_SERVERS: case DH6OPT_NIS_SERVERS: case DH6OPT_NISP_SERVERS: case DH6OPT_BCMCS_SERVER_A: case DH6OPT_PANA_AGENT: case DH6OPT_LQ_CLIENT_LINK: if (optlen % 16) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); for (i = 0; i < optlen; i += 16) printf(" %s", ip6addr_string(&tp[i])); printf(")"); break; case DH6OPT_SIP_SERVER_D: case DH6OPT_DOMAIN_LIST: tp = (u_char *)(dh6o + 1); while (tp < cp + sizeof(*dh6o) + optlen) { putchar(' '); if ((tp = ns_nprint(tp, cp + sizeof(*dh6o) + optlen)) == NULL) goto trunc; } printf(")"); break; case DH6OPT_STATUS_CODE: if (optlen < 2) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); printf(" %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0]))); break; case DH6OPT_IA_NA: case DH6OPT_IA_PD: if (optlen < 12) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); printf(" IAID:%u T1:%u T2:%u", EXTRACT_32BITS(&tp[0]), EXTRACT_32BITS(&tp[4]), EXTRACT_32BITS(&tp[8])); if (optlen > 12) { /* there are sub-options */ dhcp6opt_print(tp + 12, tp + optlen); } printf(")"); break; case DH6OPT_IA_TA: if (optlen < 4) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); printf(" IAID:%u", EXTRACT_32BITS(tp)); if (optlen > 4) { /* there are sub-options */ dhcp6opt_print(tp + 4, tp + optlen); } printf(")"); break; case DH6OPT_IA_PD_PREFIX: if (optlen < 25) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); printf(" %s/%d", ip6addr_string(&tp[9]), tp[8]); printf(" pltime:%u vltime:%u", EXTRACT_32BITS(&tp[0]), EXTRACT_32BITS(&tp[4])); if (optlen > 25) { /* there are sub-options */ dhcp6opt_print(tp + 25, tp + optlen); } printf(")"); break; case DH6OPT_LIFETIME: case DH6OPT_CLT_TIME: if (optlen != 4) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); printf(" %d)", EXTRACT_32BITS(tp)); break; case DH6OPT_REMOTE_ID: if (optlen < 4) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); printf(" %d ", EXTRACT_32BITS(tp)); /* * Print hex dump first 10 characters. */ for (i = 4; i < optlen && i < 14; i++) printf("%02x", tp[i]); printf("...)"); break; case DH6OPT_LQ_QUERY: if (optlen < 17) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); switch (*tp) { case 1: printf(" by-address"); break; case 2: printf(" by-clientID"); break; default: printf(" type_%d", (int)*tp); break; } printf(" %s", ip6addr_string(&tp[1])); if (optlen > 17) { /* there are query-options */ dhcp6opt_print(tp + 17, tp + optlen); } printf(")"); break; case DH6OPT_CLIENT_DATA: tp = (u_char *)(dh6o + 1); if (optlen > 0) { /* there are encapsulated options */ dhcp6opt_print(tp, tp + optlen); } printf(")"); break; case DH6OPT_LQ_RELAY_DATA: if (optlen < 16) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); printf(" %s ", ip6addr_string(&tp[0])); /* * Print hex dump first 10 characters. */ for (i = 16; i < optlen && i < 26; i++) printf("%02x", tp[i]); printf("...)"); break; case DH6OPT_NTP_SERVER: if (optlen < 4) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); while (tp < cp + sizeof(*dh6o) + optlen - 4) { subopt_code = EXTRACT_16BITS(tp); tp += 2; subopt_len = EXTRACT_16BITS(tp); tp += 2; if (tp + subopt_len > cp + sizeof(*dh6o) + optlen) goto trunc; printf(" subopt:%d", subopt_code); switch (subopt_code) { case DH6OPT_NTP_SUBOPTION_SRV_ADDR: case DH6OPT_NTP_SUBOPTION_MC_ADDR: if (subopt_len != 16) { printf(" ?"); break; } printf(" %s", ip6addr_string(&tp[0])); break; case DH6OPT_NTP_SUBOPTION_SRV_FQDN: putchar(' '); if (ns_nprint(tp, tp + subopt_len) == NULL) goto trunc; break; default: printf(" ?"); break; } tp += subopt_len; } printf(")"); break; case DH6OPT_AFTR_NAME: if (optlen < 3) { printf(" ?)"); break; } tp = (u_char *)(dh6o + 1); remain_len = optlen; printf(" "); /* Encoding is described in section 3.1 of RFC 1035 */ while (remain_len && *tp) { label_len = *tp++; if (label_len < remain_len - 1) { printf("%.*s", label_len, tp); tp += label_len; remain_len -= (label_len + 1); if(*tp) printf("."); } else { printf(" ?"); break; } } printf(")"); break; default: printf(")"); break; } cp += sizeof(*dh6o) + optlen; } return; trunc: printf("[|dhcp6ext]"); } /* * Print dhcp6 packets */ void dhcp6_print(const u_char *cp, u_int length) { struct dhcp6 *dh6; struct dhcp6_relay *dh6relay; const u_char *ep; u_char *extp; const char *name; printf("dhcp6"); ep = (u_char *)snapend; if (cp + length < ep) ep = cp + length; dh6 = (struct dhcp6 *)cp; dh6relay = (struct dhcp6_relay *)cp; TCHECK(dh6->dh6_xid); switch (dh6->dh6_msgtype) { case DH6_SOLICIT: name = "solicit"; break; case DH6_ADVERTISE: name = "advertise"; break; case DH6_REQUEST: name = "request"; break; case DH6_CONFIRM: name = "confirm"; break; case DH6_RENEW: name = "renew"; break; case DH6_REBIND: name = "rebind"; break; case DH6_REPLY: name = "reply"; break; case DH6_RELEASE: name = "release"; break; case DH6_DECLINE: name = "decline"; break; case DH6_RECONFIGURE: name = "reconfigure"; break; case DH6_INFORM_REQ: name= "inf-req"; break; case DH6_RELAY_FORW: name= "relay-fwd"; break; case DH6_RELAY_REPLY: name= "relay-reply"; break; case DH6_LEASEQUERY: name= "leasequery"; break; case DH6_LQ_REPLY: name= "leasequery-reply"; break; default: name = NULL; break; } if (!vflag) { if (name) printf(" %s", name); else if (dh6->dh6_msgtype != DH6_RELAY_FORW && dh6->dh6_msgtype != DH6_RELAY_REPLY) { printf(" msgtype-%u", dh6->dh6_msgtype); } return; } /* XXX relay agent messages have to be handled differently */ if (name) printf(" %s (", name); /*)*/ else printf(" msgtype-%u (", dh6->dh6_msgtype); /*)*/ if (dh6->dh6_msgtype != DH6_RELAY_FORW && dh6->dh6_msgtype != DH6_RELAY_REPLY) { printf("xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK); extp = (u_char *)(dh6 + 1); dhcp6opt_print(extp, ep); } else { /* relay messages */ struct in6_addr addr6; TCHECK(dh6relay->dh6relay_peeraddr); memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6)); printf("linkaddr=%s", ip6addr_string(&addr6)); memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6)); printf(" peeraddr=%s", ip6addr_string(&addr6)); dhcp6opt_print((u_char *)(dh6relay + 1), ep); } /*(*/ printf(")"); return; trunc: printf("[|dhcp6]"); } tcpdump-4.5.1/print-ripng.c0000644000026300017510000000724012237020316013232 0ustar mcr/* * Copyright (c) 1989, 1990, 1991, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-ripng.c,v 1.18 2005-01-04 00:15:54 guy Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef INET6 #include #include #include "route6d.h" #include "interface.h" #include "addrtoname.h" #include "extract.h" #if !defined(IN6_IS_ADDR_UNSPECIFIED) && !defined(_MSC_VER) /* MSVC inline */ static int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *addr) { static const struct in6_addr in6addr_any; /* :: */ return (memcmp(addr, &in6addr_any, sizeof(*addr)) == 0); } #endif static int rip6_entry_print(register const struct netinfo6 *ni, int metric) { int l; l = printf("%s/%d", ip6addr_string(&ni->rip6_dest), ni->rip6_plen); if (ni->rip6_tag) l += printf(" [%d]", EXTRACT_16BITS(&ni->rip6_tag)); if (metric) l += printf(" (%d)", ni->rip6_metric); return l; } void ripng_print(const u_char *dat, unsigned int length) { register const struct rip6 *rp = (struct rip6 *)dat; register const struct netinfo6 *ni; register u_int amt; register u_int i; int j; int trunc; if (snapend < dat) return; amt = snapend - dat; i = min(length, amt); if (i < (sizeof(struct rip6) - sizeof(struct netinfo6))) return; i -= (sizeof(struct rip6) - sizeof(struct netinfo6)); switch (rp->rip6_cmd) { case RIP6_REQUEST: j = length / sizeof(*ni); if (j == 1 && rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6 && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) { printf(" ripng-req dump"); break; } if (j * sizeof(*ni) != length - 4) printf(" ripng-req %d[%u]:", j, length); else printf(" ripng-req %d:", j); trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i); for (ni = rp->rip6_nets; i >= sizeof(*ni); i -= sizeof(*ni), ++ni) { if (vflag > 1) printf("\n\t"); else printf(" "); rip6_entry_print(ni, 0); } break; case RIP6_RESPONSE: j = length / sizeof(*ni); if (j * sizeof(*ni) != length - 4) printf(" ripng-resp %d[%u]:", j, length); else printf(" ripng-resp %d:", j); trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i); for (ni = rp->rip6_nets; i >= sizeof(*ni); i -= sizeof(*ni), ++ni) { if (vflag > 1) printf("\n\t"); else printf(" "); rip6_entry_print(ni, ni->rip6_metric); } if (trunc) printf("[|ripng]"); break; default: printf(" ripng-%d ?? %u", rp->rip6_cmd, length); break; } if (rp->rip6_vers != RIP6_VERSION) printf(" [vers %d]", rp->rip6_vers); } #endif /* INET6 */ tcpdump-4.5.1/print-hsrp.c0000644000026300017510000001066012237020316013067 0ustar mcr/* * Copyright (C) 2001 Julian Cowley * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* Cisco Hot Standby Router Protocol (HSRP). */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-hsrp.c,v 1.10 2005-05-06 07:56:52 guy Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "interface.h" #include "addrtoname.h" /* HSRP op code types. */ static const char *op_code_str[] = { "hello", "coup", "resign" }; /* HSRP states and associated names. */ static const struct tok states[] = { { 0, "initial" }, { 1, "learn" }, { 2, "listen" }, { 4, "speak" }, { 8, "standby" }, { 16, "active" }, { 0, NULL } }; /* * RFC 2281: * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Version | Op Code | State | Hellotime | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Holdtime | Priority | Group | Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Authentication Data | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Authentication Data | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Virtual IP Address | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ #define HSRP_AUTH_SIZE 8 /* HSRP protocol header. */ struct hsrp { u_int8_t hsrp_version; u_int8_t hsrp_op_code; u_int8_t hsrp_state; u_int8_t hsrp_hellotime; u_int8_t hsrp_holdtime; u_int8_t hsrp_priority; u_int8_t hsrp_group; u_int8_t hsrp_reserved; u_int8_t hsrp_authdata[HSRP_AUTH_SIZE]; struct in_addr hsrp_virtaddr; }; void hsrp_print(register const u_int8_t *bp, register u_int len) { struct hsrp *hp = (struct hsrp *) bp; TCHECK(hp->hsrp_version); printf("HSRPv%d", hp->hsrp_version); if (hp->hsrp_version != 0) return; TCHECK(hp->hsrp_op_code); printf("-"); printf("%s ", tok2strary(op_code_str, "unknown (%d)", hp->hsrp_op_code)); printf("%d: ", len); TCHECK(hp->hsrp_state); printf("state=%s ", tok2str(states, "Unknown (%d)", hp->hsrp_state)); TCHECK(hp->hsrp_group); printf("group=%d ", hp->hsrp_group); TCHECK(hp->hsrp_reserved); if (hp->hsrp_reserved != 0) { printf("[reserved=%d!] ", hp->hsrp_reserved); } TCHECK(hp->hsrp_virtaddr); printf("addr=%s", ipaddr_string(&hp->hsrp_virtaddr)); if (vflag) { printf(" hellotime="); relts_print(hp->hsrp_hellotime); printf(" holdtime="); relts_print(hp->hsrp_holdtime); printf(" priority=%d", hp->hsrp_priority); printf(" auth=\""); if (fn_printn(hp->hsrp_authdata, sizeof(hp->hsrp_authdata), snapend)) { printf("\""); goto trunc; } printf("\""); } return; trunc: printf("[|hsrp]"); } tcpdump-4.5.1/openflow.h0000644000026300017510000000317512237020316012622 0ustar mcr/* * Copyright (c) 2013 The TCPDUMP project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* OpenFlow: protocol between controller and datapath. */ #define OF_HEADER_LEN 8 /* * Routines to print packets for various versions of OpenFlow. */ extern const u_char *of10_header_body_print(const u_char *, const u_char *, const uint8_t, const uint16_t, const uint32_t); tcpdump-4.5.1/bgp.h0000644000026300017510000000147712237020316011544 0ustar mcr/* @(#) $Header: /tcpdump/master/tcpdump/bgp.h,v 1.3 2004-06-16 08:45:15 hannes Exp $ (LBL) */ /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code * distributions retain the above copyright notice and this paragraph * in its entirety, and (2) distributions including binary code include * the above copyright notice and this paragraph in its entirety in * the documentation or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * Original code by Hannes Gredler (hannes@juniper.net) */ extern char *bgp_vpn_rd_print (const u_char *); tcpdump-4.5.1/igrp.h0000644000026300017510000000211712237020316011725 0ustar mcr/* @(#) $Header: /tcpdump/master/tcpdump/igrp.h,v 1.6 2002-12-11 07:13:52 guy Exp $ (LBL) */ /* Cisco IGRP definitions */ /* IGRP Header */ struct igrphdr { u_int8_t ig_vop; /* protocol version number / opcode */ #define IGRP_V(x) (((x) & 0xf0) >> 4) #define IGRP_OP(x) ((x) & 0x0f) u_int8_t ig_ed; /* edition number */ u_int16_t ig_as; /* autonomous system number */ u_int16_t ig_ni; /* number of subnet in local net */ u_int16_t ig_ns; /* number of networks in AS */ u_int16_t ig_nx; /* number of networks ouside AS */ u_int16_t ig_sum; /* checksum of IGRP header & data */ }; #define IGRP_UPDATE 1 #define IGRP_REQUEST 2 /* IGRP routing entry */ struct igrprte { u_int8_t igr_net[3]; /* 3 significant octets of IP address */ u_int8_t igr_dly[3]; /* delay in tens of microseconds */ u_int8_t igr_bw[3]; /* bandwidth in units of 1 kb/s */ u_int8_t igr_mtu[2]; /* MTU in octets */ u_int8_t igr_rel; /* percent packets successfully tx/rx */ u_int8_t igr_ld; /* percent of channel occupied */ u_int8_t igr_hct; /* hop count */ }; #define IGRP_RTE_SIZE 14 /* don't believe sizeof ! */ tcpdump-4.5.1/ieee802_11.h0000644000026300017510000002047312237020316012433 0ustar mcr/* @(#) $Header: /tcpdump/master/tcpdump/ieee802_11.h,v 1.12 2007-07-22 19:59:06 guy Exp $ (LBL) */ /* * Copyright (c) 2001 * Fortress Technologies * Charlie Lenahan ( clenahan@fortresstech.com ) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* Lengths of 802.11 header components. */ #define IEEE802_11_FC_LEN 2 #define IEEE802_11_DUR_LEN 2 #define IEEE802_11_DA_LEN 6 #define IEEE802_11_SA_LEN 6 #define IEEE802_11_BSSID_LEN 6 #define IEEE802_11_RA_LEN 6 #define IEEE802_11_TA_LEN 6 #define IEEE802_11_SEQ_LEN 2 #define IEEE802_11_CTL_LEN 2 #define IEEE802_11_IV_LEN 3 #define IEEE802_11_KID_LEN 1 /* Frame check sequence length. */ #define IEEE802_11_FCS_LEN 4 /* Lengths of beacon components. */ #define IEEE802_11_TSTAMP_LEN 8 #define IEEE802_11_BCNINT_LEN 2 #define IEEE802_11_CAPINFO_LEN 2 #define IEEE802_11_LISTENINT_LEN 2 #define IEEE802_11_AID_LEN 2 #define IEEE802_11_STATUS_LEN 2 #define IEEE802_11_REASON_LEN 2 /* Length of previous AP in reassocation frame */ #define IEEE802_11_AP_LEN 6 #define T_MGMT 0x0 /* management */ #define T_CTRL 0x1 /* control */ #define T_DATA 0x2 /* data */ #define T_RESV 0x3 /* reserved */ #define ST_ASSOC_REQUEST 0x0 #define ST_ASSOC_RESPONSE 0x1 #define ST_REASSOC_REQUEST 0x2 #define ST_REASSOC_RESPONSE 0x3 #define ST_PROBE_REQUEST 0x4 #define ST_PROBE_RESPONSE 0x5 /* RESERVED 0x6 */ /* RESERVED 0x7 */ #define ST_BEACON 0x8 #define ST_ATIM 0x9 #define ST_DISASSOC 0xA #define ST_AUTH 0xB #define ST_DEAUTH 0xC #define ST_ACTION 0xD /* RESERVED 0xE */ /* RESERVED 0xF */ #define CTRL_CONTROL_WRAPPER 0x7 #define CTRL_BAR 0x8 #define CTRL_BA 0x9 #define CTRL_PS_POLL 0xA #define CTRL_RTS 0xB #define CTRL_CTS 0xC #define CTRL_ACK 0xD #define CTRL_CF_END 0xE #define CTRL_END_ACK 0xF #define DATA_DATA 0x0 #define DATA_DATA_CF_ACK 0x1 #define DATA_DATA_CF_POLL 0x2 #define DATA_DATA_CF_ACK_POLL 0x3 #define DATA_NODATA 0x4 #define DATA_NODATA_CF_ACK 0x5 #define DATA_NODATA_CF_POLL 0x6 #define DATA_NODATA_CF_ACK_POLL 0x7 #define DATA_QOS_DATA 0x8 #define DATA_QOS_DATA_CF_ACK 0x9 #define DATA_QOS_DATA_CF_POLL 0xA #define DATA_QOS_DATA_CF_ACK_POLL 0xB #define DATA_QOS_NODATA 0xC #define DATA_QOS_CF_POLL_NODATA 0xE #define DATA_QOS_CF_ACK_POLL_NODATA 0xF /* * The subtype field of a data frame is, in effect, composed of 4 flag * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have * any data), and QoS. */ #define DATA_FRAME_IS_CF_ACK(x) ((x) & 0x01) #define DATA_FRAME_IS_CF_POLL(x) ((x) & 0x02) #define DATA_FRAME_IS_NULL(x) ((x) & 0x04) #define DATA_FRAME_IS_QOS(x) ((x) & 0x08) /* * Bits in the frame control field. */ #define FC_VERSION(fc) ((fc) & 0x3) #define FC_TYPE(fc) (((fc) >> 2) & 0x3) #define FC_SUBTYPE(fc) (((fc) >> 4) & 0xF) #define FC_TO_DS(fc) ((fc) & 0x0100) #define FC_FROM_DS(fc) ((fc) & 0x0200) #define FC_MORE_FLAG(fc) ((fc) & 0x0400) #define FC_RETRY(fc) ((fc) & 0x0800) #define FC_POWER_MGMT(fc) ((fc) & 0x1000) #define FC_MORE_DATA(fc) ((fc) & 0x2000) #define FC_WEP(fc) ((fc) & 0x4000) #define FC_ORDER(fc) ((fc) & 0x8000) struct mgmt_header_t { u_int16_t fc; u_int16_t duration; u_int8_t da[6]; u_int8_t sa[6]; u_int8_t bssid[6]; u_int16_t seq_ctrl; }; #define MGMT_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_DA_LEN+IEEE802_11_SA_LEN+\ IEEE802_11_BSSID_LEN+IEEE802_11_SEQ_LEN) #define CAPABILITY_ESS(cap) ((cap) & 0x0001) #define CAPABILITY_IBSS(cap) ((cap) & 0x0002) #define CAPABILITY_CFP(cap) ((cap) & 0x0004) #define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008) #define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010) struct ssid_t { u_int8_t element_id; u_int8_t length; u_char ssid[33]; /* 32 + 1 for null */ }; struct rates_t { u_int8_t element_id; u_int8_t length; u_int8_t rate[16]; }; struct challenge_t { u_int8_t element_id; u_int8_t length; u_int8_t text[254]; /* 1-253 + 1 for null */ }; struct fh_t { u_int8_t element_id; u_int8_t length; u_int16_t dwell_time; u_int8_t hop_set; u_int8_t hop_pattern; u_int8_t hop_index; }; struct ds_t { u_int8_t element_id; u_int8_t length; u_int8_t channel; }; struct cf_t { u_int8_t element_id; u_int8_t length; u_int8_t count; u_int8_t period; u_int16_t max_duration; u_int16_t dur_remaing; }; struct tim_t { u_int8_t element_id; u_int8_t length; u_int8_t count; u_int8_t period; u_int8_t bitmap_control; u_int8_t bitmap[251]; }; #define E_SSID 0 #define E_RATES 1 #define E_FH 2 #define E_DS 3 #define E_CF 4 #define E_TIM 5 #define E_IBSS 6 /* reserved 7 */ /* reserved 8 */ /* reserved 9 */ /* reserved 10 */ /* reserved 11 */ /* reserved 12 */ /* reserved 13 */ /* reserved 14 */ /* reserved 15 */ /* reserved 16 */ #define E_CHALLENGE 16 /* reserved 17 */ /* reserved 18 */ /* reserved 19 */ /* reserved 16 */ /* reserved 16 */ struct mgmt_body_t { u_int8_t timestamp[IEEE802_11_TSTAMP_LEN]; u_int16_t beacon_interval; u_int16_t listen_interval; u_int16_t status_code; u_int16_t aid; u_char ap[IEEE802_11_AP_LEN]; u_int16_t reason_code; u_int16_t auth_alg; u_int16_t auth_trans_seq_num; int challenge_present; struct challenge_t challenge; u_int16_t capability_info; int ssid_present; struct ssid_t ssid; int rates_present; struct rates_t rates; int ds_present; struct ds_t ds; int cf_present; struct cf_t cf; int fh_present; struct fh_t fh; int tim_present; struct tim_t tim; }; struct ctrl_rts_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t ta[6]; u_int8_t fcs[4]; }; #define CTRL_RTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_TA_LEN) struct ctrl_cts_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t fcs[4]; }; #define CTRL_CTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) struct ctrl_ack_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t fcs[4]; }; #define CTRL_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) struct ctrl_ps_poll_t { u_int16_t fc; u_int16_t aid; u_int8_t bssid[6]; u_int8_t ta[6]; u_int8_t fcs[4]; }; #define CTRL_PS_POLL_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+\ IEEE802_11_BSSID_LEN+IEEE802_11_TA_LEN) struct ctrl_end_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t bssid[6]; u_int8_t fcs[4]; }; #define CTRL_END_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) struct ctrl_end_ack_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t bssid[6]; u_int8_t fcs[4]; }; #define CTRL_END_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) struct ctrl_ba_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t fcs[4]; }; #define CTRL_BA_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) struct ctrl_bar_t { u_int16_t fc; u_int16_t dur; u_int8_t ra[6]; u_int8_t ta[6]; u_int16_t ctl; u_int16_t seq; u_int8_t fcs[4]; }; #define CTRL_BAR_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ IEEE802_11_RA_LEN+IEEE802_11_TA_LEN+\ IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN) struct meshcntl_t { u_int8_t flags; u_int8_t ttl; u_int8_t seq[4]; u_int8_t addr4[6]; u_int8_t addr5[6]; u_int8_t addr6[6]; }; #define IV_IV(iv) ((iv) & 0xFFFFFF) #define IV_PAD(iv) (((iv) >> 24) & 0x3F) #define IV_KEYID(iv) (((iv) >> 30) & 0x03) tcpdump-4.5.1/print-bgp.c0000644000026300017510000027033312237020316012670 0ustar mcr/* * Copyright (C) 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Extensively modified by Hannes Gredler (hannes@juniper.net) for more * complete BGP support. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.118 2007-12-07 15:54:52 hannes Exp $"; #endif #include #include #include #include "interface.h" #include "decode_prefix.h" #include "addrtoname.h" #include "extract.h" #include "bgp.h" #include "af.h" #include "l2vpn.h" struct bgp { u_int8_t bgp_marker[16]; u_int16_t bgp_len; u_int8_t bgp_type; }; #define BGP_SIZE 19 /* unaligned */ #define BGP_OPEN 1 #define BGP_UPDATE 2 #define BGP_NOTIFICATION 3 #define BGP_KEEPALIVE 4 #define BGP_ROUTE_REFRESH 5 static const struct tok bgp_msg_values[] = { { BGP_OPEN, "Open"}, { BGP_UPDATE, "Update"}, { BGP_NOTIFICATION, "Notification"}, { BGP_KEEPALIVE, "Keepalive"}, { BGP_ROUTE_REFRESH, "Route Refresh"}, { 0, NULL} }; struct bgp_open { u_int8_t bgpo_marker[16]; u_int16_t bgpo_len; u_int8_t bgpo_type; u_int8_t bgpo_version; u_int16_t bgpo_myas; u_int16_t bgpo_holdtime; u_int32_t bgpo_id; u_int8_t bgpo_optlen; /* options should follow */ }; #define BGP_OPEN_SIZE 29 /* unaligned */ struct bgp_opt { u_int8_t bgpopt_type; u_int8_t bgpopt_len; /* variable length */ }; #define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */ #define BGP_CAP_HEADER_SIZE 2 /* some compilers may pad to 4 bytes */ struct bgp_notification { u_int8_t bgpn_marker[16]; u_int16_t bgpn_len; u_int8_t bgpn_type; u_int8_t bgpn_major; u_int8_t bgpn_minor; }; #define BGP_NOTIFICATION_SIZE 21 /* unaligned */ struct bgp_route_refresh { u_int8_t bgp_marker[16]; u_int16_t len; u_int8_t type; u_int8_t afi[2]; /* the compiler messes this structure up */ u_int8_t res; /* when doing misaligned sequences of int8 and int16 */ u_int8_t safi; /* afi should be int16 - so we have to access it using */ }; /* EXTRACT_16BITS(&bgp_route_refresh->afi) (sigh) */ #define BGP_ROUTE_REFRESH_SIZE 23 #define bgp_attr_lenlen(flags, p) \ (((flags) & 0x10) ? 2 : 1) #define bgp_attr_len(flags, p) \ (((flags) & 0x10) ? EXTRACT_16BITS(p) : *(p)) #define BGPTYPE_ORIGIN 1 #define BGPTYPE_AS_PATH 2 #define BGPTYPE_NEXT_HOP 3 #define BGPTYPE_MULTI_EXIT_DISC 4 #define BGPTYPE_LOCAL_PREF 5 #define BGPTYPE_ATOMIC_AGGREGATE 6 #define BGPTYPE_AGGREGATOR 7 #define BGPTYPE_COMMUNITIES 8 /* RFC1997 */ #define BGPTYPE_ORIGINATOR_ID 9 /* RFC1998 */ #define BGPTYPE_CLUSTER_LIST 10 /* RFC1998 */ #define BGPTYPE_DPA 11 /* draft-ietf-idr-bgp-dpa */ #define BGPTYPE_ADVERTISERS 12 /* RFC1863 */ #define BGPTYPE_RCID_PATH 13 /* RFC1863 */ #define BGPTYPE_MP_REACH_NLRI 14 /* RFC2283 */ #define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2283 */ #define BGPTYPE_EXTD_COMMUNITIES 16 /* draft-ietf-idr-bgp-ext-communities */ #define BGPTYPE_AS4_PATH 17 /* RFC4893 */ #define BGPTYPE_AGGREGATOR4 18 /* RFC4893 */ #define BGPTYPE_PMSI_TUNNEL 22 /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ #define BGPTYPE_ATTR_SET 128 /* draft-marques-ppvpn-ibgp */ #define BGP_MP_NLRI_MINSIZE 3 /* End of RIB Marker detection */ static const struct tok bgp_attr_values[] = { { BGPTYPE_ORIGIN, "Origin"}, { BGPTYPE_AS_PATH, "AS Path"}, { BGPTYPE_AS4_PATH, "AS4 Path"}, { BGPTYPE_NEXT_HOP, "Next Hop"}, { BGPTYPE_MULTI_EXIT_DISC, "Multi Exit Discriminator"}, { BGPTYPE_LOCAL_PREF, "Local Preference"}, { BGPTYPE_ATOMIC_AGGREGATE, "Atomic Aggregate"}, { BGPTYPE_AGGREGATOR, "Aggregator"}, { BGPTYPE_AGGREGATOR4, "Aggregator4"}, { BGPTYPE_COMMUNITIES, "Community"}, { BGPTYPE_ORIGINATOR_ID, "Originator ID"}, { BGPTYPE_CLUSTER_LIST, "Cluster List"}, { BGPTYPE_DPA, "DPA"}, { BGPTYPE_ADVERTISERS, "Advertisers"}, { BGPTYPE_RCID_PATH, "RCID Path / Cluster ID"}, { BGPTYPE_MP_REACH_NLRI, "Multi-Protocol Reach NLRI"}, { BGPTYPE_MP_UNREACH_NLRI, "Multi-Protocol Unreach NLRI"}, { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"}, { BGPTYPE_PMSI_TUNNEL, "PMSI Tunnel"}, { BGPTYPE_ATTR_SET, "Attribute Set"}, { 255, "Reserved for development"}, { 0, NULL} }; #define BGP_AS_SET 1 #define BGP_AS_SEQUENCE 2 #define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */ #define BGP_CONFED_AS_SET 4 /* draft-ietf-idr-rfc3065bis-01 */ #define BGP_AS_SEG_TYPE_MIN BGP_AS_SET #define BGP_AS_SEG_TYPE_MAX BGP_CONFED_AS_SET static const struct tok bgp_as_path_segment_open_values[] = { { BGP_AS_SEQUENCE, ""}, { BGP_AS_SET, "{ "}, { BGP_CONFED_AS_SEQUENCE, "( "}, { BGP_CONFED_AS_SET, "({ "}, { 0, NULL} }; static const struct tok bgp_as_path_segment_close_values[] = { { BGP_AS_SEQUENCE, ""}, { BGP_AS_SET, "}"}, { BGP_CONFED_AS_SEQUENCE, ")"}, { BGP_CONFED_AS_SET, "})"}, { 0, NULL} }; #define BGP_OPT_AUTH 1 #define BGP_OPT_CAP 2 static const struct tok bgp_opt_values[] = { { BGP_OPT_AUTH, "Authentication Information"}, { BGP_OPT_CAP, "Capabilities Advertisement"}, { 0, NULL} }; #define BGP_CAPCODE_MP 1 #define BGP_CAPCODE_RR 2 #define BGP_CAPCODE_ORF 3 /* XXX */ #define BGP_CAPCODE_RESTART 64 /* draft-ietf-idr-restart-05 */ #define BGP_CAPCODE_AS_NEW 65 /* XXX */ #define BGP_CAPCODE_DYN_CAP 67 /* XXX */ #define BGP_CAPCODE_RR_CISCO 128 static const struct tok bgp_capcode_values[] = { { BGP_CAPCODE_MP, "Multiprotocol Extensions"}, { BGP_CAPCODE_RR, "Route Refresh"}, { BGP_CAPCODE_ORF, "Cooperative Route Filtering"}, { BGP_CAPCODE_RESTART, "Graceful Restart"}, { BGP_CAPCODE_AS_NEW, "32-Bit AS Number"}, { BGP_CAPCODE_DYN_CAP, "Dynamic Capability"}, { BGP_CAPCODE_RR_CISCO, "Route Refresh (Cisco)"}, { 0, NULL} }; #define BGP_NOTIFY_MAJOR_MSG 1 #define BGP_NOTIFY_MAJOR_OPEN 2 #define BGP_NOTIFY_MAJOR_UPDATE 3 #define BGP_NOTIFY_MAJOR_HOLDTIME 4 #define BGP_NOTIFY_MAJOR_FSM 5 #define BGP_NOTIFY_MAJOR_CEASE 6 #define BGP_NOTIFY_MAJOR_CAP 7 static const struct tok bgp_notify_major_values[] = { { BGP_NOTIFY_MAJOR_MSG, "Message Header Error"}, { BGP_NOTIFY_MAJOR_OPEN, "OPEN Message Error"}, { BGP_NOTIFY_MAJOR_UPDATE, "UPDATE Message Error"}, { BGP_NOTIFY_MAJOR_HOLDTIME,"Hold Timer Expired"}, { BGP_NOTIFY_MAJOR_FSM, "Finite State Machine Error"}, { BGP_NOTIFY_MAJOR_CEASE, "Cease"}, { BGP_NOTIFY_MAJOR_CAP, "Capability Message Error"}, { 0, NULL} }; /* draft-ietf-idr-cease-subcode-02 */ #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX 1 static const struct tok bgp_notify_minor_cease_values[] = { { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"}, { 2, "Administratively Shutdown"}, { 3, "Peer Unconfigured"}, { 4, "Administratively Reset"}, { 5, "Connection Rejected"}, { 6, "Other Configuration Change"}, { 7, "Connection Collision Resolution"}, { 0, NULL} }; static const struct tok bgp_notify_minor_msg_values[] = { { 1, "Connection Not Synchronized"}, { 2, "Bad Message Length"}, { 3, "Bad Message Type"}, { 0, NULL} }; static const struct tok bgp_notify_minor_open_values[] = { { 1, "Unsupported Version Number"}, { 2, "Bad Peer AS"}, { 3, "Bad BGP Identifier"}, { 4, "Unsupported Optional Parameter"}, { 5, "Authentication Failure"}, { 6, "Unacceptable Hold Time"}, { 7, "Capability Message Error"}, { 0, NULL} }; static const struct tok bgp_notify_minor_update_values[] = { { 1, "Malformed Attribute List"}, { 2, "Unrecognized Well-known Attribute"}, { 3, "Missing Well-known Attribute"}, { 4, "Attribute Flags Error"}, { 5, "Attribute Length Error"}, { 6, "Invalid ORIGIN Attribute"}, { 7, "AS Routing Loop"}, { 8, "Invalid NEXT_HOP Attribute"}, { 9, "Optional Attribute Error"}, { 10, "Invalid Network Field"}, { 11, "Malformed AS_PATH"}, { 0, NULL} }; static const struct tok bgp_notify_minor_cap_values[] = { { 1, "Invalid Action Value" }, { 2, "Invalid Capability Length" }, { 3, "Malformed Capability Value" }, { 4, "Unsupported Capability Code" }, { 0, NULL } }; static const struct tok bgp_origin_values[] = { { 0, "IGP"}, { 1, "EGP"}, { 2, "Incomplete"}, { 0, NULL} }; #define BGP_PMSI_TUNNEL_RSVP_P2MP 1 #define BGP_PMSI_TUNNEL_LDP_P2MP 2 #define BGP_PMSI_TUNNEL_PIM_SSM 3 #define BGP_PMSI_TUNNEL_PIM_SM 4 #define BGP_PMSI_TUNNEL_PIM_BIDIR 5 #define BGP_PMSI_TUNNEL_INGRESS 6 #define BGP_PMSI_TUNNEL_LDP_MP2MP 7 static const struct tok bgp_pmsi_tunnel_values[] = { { BGP_PMSI_TUNNEL_RSVP_P2MP, "RSVP-TE P2MP LSP"}, { BGP_PMSI_TUNNEL_LDP_P2MP, "LDP P2MP LSP"}, { BGP_PMSI_TUNNEL_PIM_SSM, "PIM-SSM Tree"}, { BGP_PMSI_TUNNEL_PIM_SM, "PIM-SM Tree"}, { BGP_PMSI_TUNNEL_PIM_BIDIR, "PIM-Bidir Tree"}, { BGP_PMSI_TUNNEL_INGRESS, "Ingress Replication"}, { BGP_PMSI_TUNNEL_LDP_MP2MP, "LDP MP2MP LSP"}, { 0, NULL} }; static const struct tok bgp_pmsi_flag_values[] = { { 0x01, "Leaf Information required"}, { 0, NULL} }; /* Subsequent address family identifier, RFC2283 section 7 */ #define SAFNUM_RES 0 #define SAFNUM_UNICAST 1 #define SAFNUM_MULTICAST 2 #define SAFNUM_UNIMULTICAST 3 /* labeled BGP RFC3107 */ #define SAFNUM_LABUNICAST 4 /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ #define SAFNUM_MULTICAST_VPN 5 #define SAFNUM_TUNNEL 64 /* XXX */ #define SAFNUM_VPLS 65 /* XXX */ /* draft-nalawade-idr-mdt-safi-03 */ #define SAFNUM_MDT 66 /* Section 4.3.4 of draft-rosen-rfc2547bis-03.txt */ #define SAFNUM_VPNUNICAST 128 #define SAFNUM_VPNMULTICAST 129 #define SAFNUM_VPNUNIMULTICAST 130 /* draft-marques-ppvpn-rt-constrain-01.txt */ #define SAFNUM_RT_ROUTING_INFO 132 #define BGP_VPN_RD_LEN 8 static const struct tok bgp_safi_values[] = { { SAFNUM_RES, "Reserved"}, { SAFNUM_UNICAST, "Unicast"}, { SAFNUM_MULTICAST, "Multicast"}, { SAFNUM_UNIMULTICAST, "Unicast+Multicast"}, { SAFNUM_LABUNICAST, "labeled Unicast"}, { SAFNUM_TUNNEL, "Tunnel"}, { SAFNUM_VPLS, "VPLS"}, { SAFNUM_MDT, "MDT"}, { SAFNUM_VPNUNICAST, "labeled VPN Unicast"}, { SAFNUM_VPNMULTICAST, "labeled VPN Multicast"}, { SAFNUM_VPNUNIMULTICAST, "labeled VPN Unicast+Multicast"}, { SAFNUM_RT_ROUTING_INFO, "Route Target Routing Information"}, { SAFNUM_MULTICAST_VPN, "Multicast VPN"}, { 0, NULL } }; /* well-known community */ #define BGP_COMMUNITY_NO_EXPORT 0xffffff01 #define BGP_COMMUNITY_NO_ADVERT 0xffffff02 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03 /* Extended community type - draft-ietf-idr-bgp-ext-communities-05 */ #define BGP_EXT_COM_RT_0 0x0002 /* Route Target,Format AS(2bytes):AN(4bytes) */ #define BGP_EXT_COM_RT_1 0x0102 /* Route Target,Format IP address:AN(2bytes) */ #define BGP_EXT_COM_RT_2 0x0202 /* Route Target,Format AN(4bytes):local(2bytes) */ #define BGP_EXT_COM_RO_0 0x0003 /* Route Origin,Format AS(2bytes):AN(4bytes) */ #define BGP_EXT_COM_RO_1 0x0103 /* Route Origin,Format IP address:AN(2bytes) */ #define BGP_EXT_COM_RO_2 0x0203 /* Route Origin,Format AN(4bytes):local(2bytes) */ #define BGP_EXT_COM_LINKBAND 0x4004 /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */ /* rfc2547 bgp-mpls-vpns */ #define BGP_EXT_COM_VPN_ORIGIN 0x0005 /* OSPF Domain ID / VPN of Origin - draft-rosen-vpns-ospf-bgp-mpls */ #define BGP_EXT_COM_VPN_ORIGIN2 0x0105 /* duplicate - keep for backwards compatability */ #define BGP_EXT_COM_VPN_ORIGIN3 0x0205 /* duplicate - keep for backwards compatability */ #define BGP_EXT_COM_VPN_ORIGIN4 0x8005 /* duplicate - keep for backwards compatability */ #define BGP_EXT_COM_OSPF_RTYPE 0x0306 /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */ #define BGP_EXT_COM_OSPF_RTYPE2 0x8000 /* duplicate - keep for backwards compatability */ #define BGP_EXT_COM_OSPF_RID 0x0107 /* OSPF Router ID,Format RouterID(4B):Unused(2B) */ #define BGP_EXT_COM_OSPF_RID2 0x8001 /* duplicate - keep for backwards compatability */ #define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */ #define BGP_EXT_COM_SOURCE_AS 0x0009 /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */ #define BGP_EXT_COM_VRF_RT_IMP 0x010b /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */ #define BGP_EXT_COM_L2VPN_RT_0 0x000a /* L2VPN Identifier,Format AS(2bytes):AN(4bytes) */ #define BGP_EXT_COM_L2VPN_RT_1 0xF10a /* L2VPN Identifier,Format IP address:AN(2bytes) */ /* http://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml */ #define BGP_EXT_COM_EIGRP_GEN 0x8800 #define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY 0x8801 #define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802 #define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU 0x8803 #define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804 #define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805 static const struct tok bgp_extd_comm_flag_values[] = { { 0x8000, "vendor-specific"}, { 0x4000, "non-transitive"}, { 0, NULL}, }; static const struct tok bgp_extd_comm_subtype_values[] = { { BGP_EXT_COM_RT_0, "target"}, { BGP_EXT_COM_RT_1, "target"}, { BGP_EXT_COM_RT_2, "target"}, { BGP_EXT_COM_RO_0, "origin"}, { BGP_EXT_COM_RO_1, "origin"}, { BGP_EXT_COM_RO_2, "origin"}, { BGP_EXT_COM_LINKBAND, "link-BW"}, { BGP_EXT_COM_VPN_ORIGIN, "ospf-domain"}, { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"}, { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"}, { BGP_EXT_COM_VPN_ORIGIN4, "ospf-domain"}, { BGP_EXT_COM_OSPF_RTYPE, "ospf-route-type"}, { BGP_EXT_COM_OSPF_RTYPE2, "ospf-route-type"}, { BGP_EXT_COM_OSPF_RID, "ospf-router-id"}, { BGP_EXT_COM_OSPF_RID2, "ospf-router-id"}, { BGP_EXT_COM_L2INFO, "layer2-info"}, { BGP_EXT_COM_EIGRP_GEN , "eigrp-general-route (flag, tag)" }, { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY , "eigrp-route-metric (AS, delay)" }, { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW , "eigrp-route-metric (reliability, nexthop, bandwidth)" }, { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU , "eigrp-route-metric (load, MTU)" }, { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID , "eigrp-external-route (remote-AS, remote-ID)" }, { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC , "eigrp-external-route (remote-proto, remote-metric)" }, { BGP_EXT_COM_SOURCE_AS, "source-AS" }, { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"}, { BGP_EXT_COM_L2VPN_RT_0, "l2vpn-id"}, { BGP_EXT_COM_L2VPN_RT_1, "l2vpn-id"}, { 0, NULL}, }; /* OSPF codes for BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls */ #define BGP_OSPF_RTYPE_RTR 1 /* OSPF Router LSA */ #define BGP_OSPF_RTYPE_NET 2 /* OSPF Network LSA */ #define BGP_OSPF_RTYPE_SUM 3 /* OSPF Summary LSA */ #define BGP_OSPF_RTYPE_EXT 5 /* OSPF External LSA, note that ASBR doesn't apply to MPLS-VPN */ #define BGP_OSPF_RTYPE_NSSA 7 /* OSPF NSSA External*/ #define BGP_OSPF_RTYPE_SHAM 129 /* OSPF-MPLS-VPN Sham link */ #define BGP_OSPF_RTYPE_METRIC_TYPE 0x1 /* LSB of RTYPE Options Field */ static const struct tok bgp_extd_comm_ospf_rtype_values[] = { { BGP_OSPF_RTYPE_RTR, "Router" }, { BGP_OSPF_RTYPE_NET, "Network" }, { BGP_OSPF_RTYPE_SUM, "Summary" }, { BGP_OSPF_RTYPE_EXT, "External" }, { BGP_OSPF_RTYPE_NSSA,"NSSA External" }, { BGP_OSPF_RTYPE_SHAM,"MPLS-VPN Sham" }, { 0, NULL }, }; #define TOKBUFSIZE 128 static char astostr[20]; /* * as_printf * * Convert an AS number into a string and return string pointer. * * Bepending on bflag is set or not, AS number is converted into ASDOT notation * or plain number notation. * */ static char * as_printf (char *str, int size, u_int asnum) { if (!bflag || asnum <= 0xFFFF) { snprintf(str, size, "%u", asnum); } else { snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF); } return str; } #define ITEMCHECK(minlen) if (itemlen < minlen) goto badtlv; int decode_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen) { struct in_addr addr; u_int plen, plenbytes; TCHECK(pptr[0]); ITEMCHECK(1); plen = pptr[0]; if (32 < plen) return -1; itemlen -= 1; memset(&addr, 0, sizeof(addr)); plenbytes = (plen + 7) / 8; TCHECK2(pptr[1], plenbytes); ITEMCHECK(plenbytes); memcpy(&addr, &pptr[1], plenbytes); if (plen % 8) { ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } snprintf(buf, buflen, "%s/%d", getname((u_char *)&addr), plen); return 1 + plenbytes; trunc: return -2; badtlv: return -3; } static int decode_labeled_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen) { struct in_addr addr; u_int plen, plenbytes; /* prefix length and label = 4 bytes */ TCHECK2(pptr[0], 4); ITEMCHECK(4); plen = pptr[0]; /* get prefix length */ /* this is one of the weirdnesses of rfc3107 the label length (actually the label + COS bits) is added to the prefix length; we also do only read out just one label - there is no real application for advertisement of stacked labels in a a single BGP message */ if (24 > plen) return -1; plen-=24; /* adjust prefixlen - labellength */ if (32 < plen) return -1; itemlen -= 4; memset(&addr, 0, sizeof(addr)); plenbytes = (plen + 7) / 8; TCHECK2(pptr[4], plenbytes); ITEMCHECK(plenbytes); memcpy(&addr, &pptr[4], plenbytes); if (plen % 8) { ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } /* the label may get offsetted by 4 bits so lets shift it right */ snprintf(buf, buflen, "%s/%d, label:%u %s", getname((u_char *)&addr), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); return 4 + plenbytes; trunc: return -2; badtlv: return -3; } /* * bgp_vpn_ip_print * * print an ipv4 or ipv6 address into a buffer dependend on address length. */ static char * bgp_vpn_ip_print (const u_char *pptr, u_int addr_length) { /* worst case string is s fully formatted v6 address */ static char addr[sizeof("1234:5678:89ab:cdef:1234:5678:89ab:cdef")]; char *pos = addr; switch(addr_length) { case (sizeof(struct in_addr) << 3): /* 32 */ TCHECK2(pptr[0], sizeof(struct in_addr)); snprintf(pos, sizeof(addr), "%s", ipaddr_string(pptr)); break; #ifdef INET6 case (sizeof(struct in6_addr) << 3): /* 128 */ TCHECK2(pptr[0], sizeof(struct in6_addr)); snprintf(pos, sizeof(addr), "%s", ip6addr_string(pptr)); break; #endif default: snprintf(pos, sizeof(addr), "bogus address length %u", addr_length); break; } pos += strlen(pos); trunc: *(pos) = '\0'; return (addr); } /* * bgp_vpn_sg_print * * print an multicast s,g entry into a buffer. * the s,g entry is encoded like this. * * +-----------------------------------+ * | Multicast Source Length (1 octet) | * +-----------------------------------+ * | Multicast Source (Variable) | * +-----------------------------------+ * | Multicast Group Length (1 octet) | * +-----------------------------------+ * | Multicast Group (Variable) | * +-----------------------------------+ * * return the number of bytes read from the wire. */ static int bgp_vpn_sg_print (const u_char *pptr, char *buf, u_int buflen) { u_int8_t addr_length; u_int total_length, offset; total_length = 0; /* Source address length, encoded in bits */ TCHECK2(pptr[0], 1); addr_length = *pptr++; /* Source address */ TCHECK2(pptr[0], (addr_length >> 3)); total_length += (addr_length >> 3) + 1; offset = strlen(buf); if (addr_length) { snprintf(buf + offset, buflen - offset, ", Source %s", bgp_vpn_ip_print(pptr, addr_length)); pptr += (addr_length >> 3); } /* Group address length, encoded in bits */ TCHECK2(pptr[0], 1); addr_length = *pptr++; /* Group address */ TCHECK2(pptr[0], (addr_length >> 3)); total_length += (addr_length >> 3) + 1; offset = strlen(buf); if (addr_length) { snprintf(buf + offset, buflen - offset, ", Group %s", bgp_vpn_ip_print(pptr, addr_length)); pptr += (addr_length >> 3); } trunc: return (total_length); } /* RDs and RTs share the same semantics * we use bgp_vpn_rd_print for * printing route targets inside a NLRI */ char * bgp_vpn_rd_print (const u_char *pptr) { /* allocate space for the largest possible string */ static char rd[sizeof("xxxxxxxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")]; char *pos = rd; /* ok lets load the RD format */ switch (EXTRACT_16BITS(pptr)) { /* 2-byte-AS:number fmt*/ case 0: snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (= %u.%u.%u.%u)", EXTRACT_16BITS(pptr+2), EXTRACT_32BITS(pptr+4), *(pptr+4), *(pptr+5), *(pptr+6), *(pptr+7)); break; /* IP-address:AS fmt*/ case 1: snprintf(pos, sizeof(rd) - (pos - rd), "%u.%u.%u.%u:%u", *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6)); break; /* 4-byte-AS:number fmt*/ case 2: snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)", as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+2)), EXTRACT_16BITS(pptr+6), *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6)); break; default: snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format"); break; } pos += strlen(pos); *(pos) = '\0'; return (rd); } static int decode_rt_routing_info(const u_char *pptr, char *buf, u_int buflen) { u_int8_t route_target[8]; u_int plen; TCHECK(pptr[0]); plen = pptr[0]; /* get prefix length */ if (0 == plen) return 1; /* default route target */ if (32 > plen) return -1; plen-=32; /* adjust prefix length */ if (64 < plen) return -1; memset(&route_target, 0, sizeof(route_target)); TCHECK2(pptr[1], (plen + 7) / 8); memcpy(&route_target, &pptr[1], (plen + 7) / 8); if (plen % 8) { ((u_char *)&route_target)[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } snprintf(buf, buflen, "origin AS: %s, route target %s", as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)), bgp_vpn_rd_print((u_char *)&route_target)); return 5 + (plen + 7) / 8; trunc: return -2; } static int decode_labeled_vpn_prefix4(const u_char *pptr, char *buf, u_int buflen) { struct in_addr addr; u_int plen; TCHECK(pptr[0]); plen = pptr[0]; /* get prefix length */ if ((24+64) > plen) return -1; plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ if (32 < plen) return -1; memset(&addr, 0, sizeof(addr)); TCHECK2(pptr[12], (plen + 7) / 8); memcpy(&addr, &pptr[12], (plen + 7) / 8); if (plen % 8) { ((u_char *)&addr)[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } /* the label may get offsetted by 4 bits so lets shift it right */ snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", bgp_vpn_rd_print(pptr+4), getname((u_char *)&addr), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); return 12 + (plen + 7) / 8; trunc: return -2; } /* * +-------------------------------+ * | | * | RD:IPv4-address (12 octets) | * | | * +-------------------------------+ * | MDT Group-address (4 octets) | * +-------------------------------+ */ #define MDT_VPN_NLRI_LEN 16 static int decode_mdt_vpn_nlri(const u_char *pptr, char *buf, u_int buflen) { const u_char *rd; const u_char *vpn_ip; TCHECK(pptr[0]); /* if the NLRI is not predefined length, quit.*/ if (*pptr != MDT_VPN_NLRI_LEN * NBBY) return -1; pptr++; /* RD */ TCHECK2(pptr[0], 8); rd = pptr; pptr+=8; /* IPv4 address */ TCHECK2(pptr[0], sizeof(struct in_addr)); vpn_ip = pptr; pptr+=sizeof(struct in_addr); /* MDT Group Address */ TCHECK2(pptr[0], sizeof(struct in_addr)); snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s", bgp_vpn_rd_print(rd), ipaddr_string(vpn_ip), ipaddr_string(pptr)); return MDT_VPN_NLRI_LEN + 1; trunc: return -2; } #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI 1 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI 2 #define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI 3 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF 4 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE 5 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN 6 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN 7 static const struct tok bgp_multicast_vpn_route_type_values[] = { { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI, "Intra-AS I-PMSI"}, { BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI, "Inter-AS I-PMSI"}, { BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI, "S-PMSI"}, { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF, "Intra-AS Segment-Leaf"}, { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"}, { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"}, { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"}, }; static int decode_multicast_vpn(const u_char *pptr, char *buf, u_int buflen) { u_int8_t route_type, route_length, addr_length, sg_length; u_int offset; TCHECK2(pptr[0], 2); route_type = *pptr++; route_length = *pptr++; snprintf(buf, buflen, "Route-Type: %s (%u), length: %u", tok2str(bgp_multicast_vpn_route_type_values, "Unknown", route_type), route_type, route_length); switch(route_type) { case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI: TCHECK2(pptr[0], BGP_VPN_RD_LEN); offset = strlen(buf); snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s", bgp_vpn_rd_print(pptr), bgp_vpn_ip_print(pptr + BGP_VPN_RD_LEN, (route_length - BGP_VPN_RD_LEN) << 3)); break; case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI: TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4); offset = strlen(buf); snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", bgp_vpn_rd_print(pptr), as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); break; case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI: TCHECK2(pptr[0], BGP_VPN_RD_LEN); offset = strlen(buf); snprintf(buf + offset, buflen - offset, ", RD: %s", bgp_vpn_rd_print(pptr)); pptr += BGP_VPN_RD_LEN; sg_length = bgp_vpn_sg_print(pptr, buf, buflen); addr_length = route_length - sg_length; TCHECK2(pptr[0], addr_length); offset = strlen(buf); snprintf(buf + offset, buflen - offset, ", Originator %s", bgp_vpn_ip_print(pptr, addr_length << 3)); break; case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE: TCHECK2(pptr[0], BGP_VPN_RD_LEN); offset = strlen(buf); snprintf(buf + offset, buflen - offset, ", RD: %s", bgp_vpn_rd_print(pptr)); pptr += BGP_VPN_RD_LEN; bgp_vpn_sg_print(pptr, buf, buflen); break; case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */ case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN: TCHECK2(pptr[0], BGP_VPN_RD_LEN); offset = strlen(buf); snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", bgp_vpn_rd_print(pptr), as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); pptr += BGP_VPN_RD_LEN; bgp_vpn_sg_print(pptr, buf, buflen); break; /* * no per route-type printing yet. */ case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF: default: break; } return route_length + 2; trunc: return -2; } /* * As I remember, some versions of systems have an snprintf() that * returns -1 if the buffer would have overflowed. If the return * value is negative, set buflen to 0, to indicate that we've filled * the buffer up. * * If the return value is greater than buflen, that means that * the buffer would have overflowed; again, set buflen to 0 in * that case. */ #define UPDATE_BUF_BUFLEN(buf, buflen, strlen) \ if (strlen<0) \ buflen=0; \ else if ((u_int)strlen>buflen) \ buflen=0; \ else { \ buflen-=strlen; \ buf+=strlen; \ } static int decode_labeled_vpn_l2(const u_char *pptr, char *buf, u_int buflen) { int plen,tlen,strlen,tlv_type,tlv_len,ttlv_len; TCHECK2(pptr[0], 2); plen=EXTRACT_16BITS(pptr); tlen=plen; pptr+=2; /* Old and new L2VPN NLRI share AFI/SAFI * -> Assume a 12 Byte-length NLRI is auto-discovery-only * and > 17 as old format. Complain for the middle case */ if (plen==12) { /* assume AD-only with RD, BGPNH */ TCHECK2(pptr[0],12); buf[0]='\0'; strlen=snprintf(buf, buflen, "RD: %s, BGPNH: %s", bgp_vpn_rd_print(pptr), /* need something like getname() here */ getname(pptr+8) ); UPDATE_BUF_BUFLEN(buf, buflen, strlen); pptr+=12; tlen-=12; return plen; } else if (plen>17) { /* assume old format */ /* RD, ID, LBLKOFF, LBLBASE */ TCHECK2(pptr[0],15); buf[0]='\0'; strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u", bgp_vpn_rd_print(pptr), EXTRACT_16BITS(pptr+8), EXTRACT_16BITS(pptr+10), EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */ UPDATE_BUF_BUFLEN(buf, buflen, strlen); pptr+=15; tlen-=15; /* ok now the variable part - lets read out TLVs*/ while (tlen>0) { if (tlen < 3) return -1; TCHECK2(pptr[0], 3); tlv_type=*pptr++; tlv_len=EXTRACT_16BITS(pptr); ttlv_len=tlv_len; pptr+=2; switch(tlv_type) { case 1: if (buflen!=0) { strlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x", tlv_type, tlv_len); UPDATE_BUF_BUFLEN(buf, buflen, strlen); } ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */ while (ttlv_len>0) { TCHECK(pptr[0]); if (buflen!=0) { strlen=snprintf(buf,buflen, "%02x",*pptr++); UPDATE_BUF_BUFLEN(buf, buflen, strlen); } ttlv_len--; } break; default: if (buflen!=0) { strlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u", tlv_type, tlv_len); UPDATE_BUF_BUFLEN(buf, buflen, strlen); } break; } tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */ } return plen+2; } else { /* complain bitterly ? */ /* fall through */ goto trunc; } trunc: return -2; } #ifdef INET6 int decode_prefix6(const u_char *pd, u_int itemlen, char *buf, u_int buflen) { struct in6_addr addr; u_int plen, plenbytes; TCHECK(pd[0]); ITEMCHECK(1); plen = pd[0]; if (128 < plen) return -1; itemlen -= 1; memset(&addr, 0, sizeof(addr)); plenbytes = (plen + 7) / 8; TCHECK2(pd[1], plenbytes); ITEMCHECK(plenbytes); memcpy(&addr, &pd[1], plenbytes); if (plen % 8) { addr.s6_addr[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } snprintf(buf, buflen, "%s/%d", getname6((u_char *)&addr), plen); return 1 + plenbytes; trunc: return -2; badtlv: return -3; } static int decode_labeled_prefix6(const u_char *pptr, u_int itemlen, char *buf, u_int buflen) { struct in6_addr addr; u_int plen, plenbytes; /* prefix length and label = 4 bytes */ TCHECK2(pptr[0], 4); ITEMCHECK(4); plen = pptr[0]; /* get prefix length */ if (24 > plen) return -1; plen-=24; /* adjust prefixlen - labellength */ if (128 < plen) return -1; itemlen -= 4; memset(&addr, 0, sizeof(addr)); plenbytes = (plen + 7) / 8; TCHECK2(pptr[4], plenbytes); memcpy(&addr, &pptr[4], plenbytes); if (plen % 8) { addr.s6_addr[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } /* the label may get offsetted by 4 bits so lets shift it right */ snprintf(buf, buflen, "%s/%d, label:%u %s", getname6((u_char *)&addr), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); return 4 + plenbytes; trunc: return -2; badtlv: return -3; } static int decode_labeled_vpn_prefix6(const u_char *pptr, char *buf, u_int buflen) { struct in6_addr addr; u_int plen; TCHECK(pptr[0]); plen = pptr[0]; /* get prefix length */ if ((24+64) > plen) return -1; plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ if (128 < plen) return -1; memset(&addr, 0, sizeof(addr)); TCHECK2(pptr[12], (plen + 7) / 8); memcpy(&addr, &pptr[12], (plen + 7) / 8); if (plen % 8) { addr.s6_addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } /* the label may get offsetted by 4 bits so lets shift it right */ snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", bgp_vpn_rd_print(pptr+4), getname6((u_char *)&addr), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); return 12 + (plen + 7) / 8; trunc: return -2; } #endif static int decode_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) { u_int8_t addr[19]; u_int plen; TCHECK(pptr[0]); plen = pptr[0]; /* get prefix length */ if (152 < plen) return -1; memset(&addr, 0, sizeof(addr)); TCHECK2(pptr[4], (plen + 7) / 8); memcpy(&addr, &pptr[4], (plen + 7) / 8); if (plen % 8) { addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } snprintf(buf, buflen, "%s/%d", isonsap_string(addr,(plen + 7) / 8), plen); return 1 + (plen + 7) / 8; trunc: return -2; } static int decode_labeled_vpn_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) { u_int8_t addr[19]; u_int plen; TCHECK(pptr[0]); plen = pptr[0]; /* get prefix length */ if ((24+64) > plen) return -1; plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ if (152 < plen) return -1; memset(&addr, 0, sizeof(addr)); TCHECK2(pptr[12], (plen + 7) / 8); memcpy(&addr, &pptr[12], (plen + 7) / 8); if (plen % 8) { addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } /* the label may get offsetted by 4 bits so lets shift it right */ snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", bgp_vpn_rd_print(pptr+4), isonsap_string(addr,(plen + 7) / 8), plen, EXTRACT_24BITS(pptr+1)>>4, ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); return 12 + (plen + 7) / 8; trunc: return -2; } /* * bgp_attr_get_as_size * * Try to find the size of the ASs encoded in an as-path. It is not obvious, as * both Old speakers that do not support 4 byte AS, and the new speakers that do * support, exchange AS-Path with the same path-attribute type value 0x02. */ static int bgp_attr_get_as_size (u_int8_t bgpa_type, const u_char *pptr, int len) { const u_char *tptr = pptr; /* * If the path attribute is the optional AS4 path type, then we already * know, that ASs must be encoded in 4 byte format. */ if (bgpa_type == BGPTYPE_AS4_PATH) { return 4; } /* * Let us assume that ASs are of 2 bytes in size, and check if the AS-Path * TLV is good. If not, ask the caller to try with AS encoded as 4 bytes * each. */ while (tptr < pptr + len) { TCHECK(tptr[0]); /* * If we do not find a valid segment type, our guess might be wrong. */ if (tptr[0] < BGP_AS_SEG_TYPE_MIN || tptr[0] > BGP_AS_SEG_TYPE_MAX) { goto trunc; } TCHECK(tptr[1]); tptr += 2 + tptr[1] * 2; } /* * If we correctly reached end of the AS path attribute data content, * then most likely ASs were indeed encoded as 2 bytes. */ if (tptr == pptr + len) { return 2; } trunc: /* * We can come here, either we did not have enough data, or if we * try to decode 4 byte ASs in 2 byte format. Either way, return 4, * so that calller can try to decode each AS as of 4 bytes. If indeed * there was not enough data, it will crib and end the parse anyways. */ return 4; } static int bgp_attr_print(u_int atype, const u_char *pptr, u_int len) { int i; u_int16_t af; u_int8_t safi, snpa, nhlen; union { /* copy buffer for bandwidth values */ float f; u_int32_t i; } bw; int advance; u_int tlen; const u_char *tptr; char buf[MAXHOSTNAMELEN + 100]; char tokbuf[TOKBUFSIZE]; int as_size; tptr = pptr; tlen=len; switch (atype) { case BGPTYPE_ORIGIN: if (len != 1) printf("invalid len"); else { TCHECK(*tptr); printf("%s", tok2strbuf(bgp_origin_values, "Unknown Origin Typecode", tptr[0], tokbuf, sizeof(tokbuf))); } break; /* * Process AS4 byte path and AS2 byte path attributes here. */ case BGPTYPE_AS4_PATH: case BGPTYPE_AS_PATH: if (len % 2) { printf("invalid len"); break; } if (!len) { printf("empty"); break; } /* * BGP updates exchanged between New speakers that support 4 * byte AS, ASs are always encoded in 4 bytes. There is no * definitive way to find this, just by the packet's * contents. So, check for packet's TLV's sanity assuming * 2 bytes first, and it does not pass, assume that ASs are * encoded in 4 bytes format and move on. */ as_size = bgp_attr_get_as_size(atype, pptr, len); while (tptr < pptr + len) { TCHECK(tptr[0]); printf("%s", tok2strbuf(bgp_as_path_segment_open_values, "?", tptr[0], tokbuf, sizeof(tokbuf))); for (i = 0; i < tptr[1] * as_size; i += as_size) { TCHECK2(tptr[2 + i], as_size); printf("%s ", as_printf(astostr, sizeof(astostr), as_size == 2 ? EXTRACT_16BITS(&tptr[2 + i]) : EXTRACT_32BITS(&tptr[2 + i]))); } TCHECK(tptr[0]); printf("%s", tok2strbuf(bgp_as_path_segment_close_values, "?", tptr[0], tokbuf, sizeof(tokbuf))); TCHECK(tptr[1]); tptr += 2 + tptr[1] * as_size; } break; case BGPTYPE_NEXT_HOP: if (len != 4) printf("invalid len"); else { TCHECK2(tptr[0], 4); printf("%s", getname(tptr)); } break; case BGPTYPE_MULTI_EXIT_DISC: case BGPTYPE_LOCAL_PREF: if (len != 4) printf("invalid len"); else { TCHECK2(tptr[0], 4); printf("%u", EXTRACT_32BITS(tptr)); } break; case BGPTYPE_ATOMIC_AGGREGATE: if (len != 0) printf("invalid len"); break; case BGPTYPE_AGGREGATOR: /* * Depending on the AS encoded is of 2 bytes or of 4 bytes, * the length of this PA can be either 6 bytes or 8 bytes. */ if (len != 6 && len != 8) { printf("invalid len"); break; } TCHECK2(tptr[0], len); if (len == 6) { printf(" AS #%s, origin %s", as_printf(astostr, sizeof(astostr), EXTRACT_16BITS(tptr)), getname(tptr + 2)); } else { printf(" AS #%s, origin %s", as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr)), getname(tptr + 4)); } break; case BGPTYPE_AGGREGATOR4: if (len != 8) { printf("invalid len"); break; } TCHECK2(tptr[0], 8); printf(" AS #%s, origin %s", as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr)), getname(tptr + 4)); break; case BGPTYPE_COMMUNITIES: if (len % 4) { printf("invalid len"); break; } while (tlen>0) { u_int32_t comm; TCHECK2(tptr[0], 4); comm = EXTRACT_32BITS(tptr); switch (comm) { case BGP_COMMUNITY_NO_EXPORT: printf(" NO_EXPORT"); break; case BGP_COMMUNITY_NO_ADVERT: printf(" NO_ADVERTISE"); break; case BGP_COMMUNITY_NO_EXPORT_SUBCONFED: printf(" NO_EXPORT_SUBCONFED"); break; default: printf("%u:%u%s", (comm >> 16) & 0xffff, comm & 0xffff, (tlen>4) ? ", " : ""); break; } tlen -=4; tptr +=4; } break; case BGPTYPE_ORIGINATOR_ID: if (len != 4) { printf("invalid len"); break; } TCHECK2(tptr[0], 4); printf("%s",getname(tptr)); break; case BGPTYPE_CLUSTER_LIST: if (len % 4) { printf("invalid len"); break; } while (tlen>0) { TCHECK2(tptr[0], 4); printf("%s%s", getname(tptr), (tlen>4) ? ", " : ""); tlen -=4; tptr +=4; } break; case BGPTYPE_MP_REACH_NLRI: TCHECK2(tptr[0], 3); af = EXTRACT_16BITS(tptr); safi = tptr[2]; printf("\n\t AFI: %s (%u), %sSAFI: %s (%u)", tok2strbuf(af_values, "Unknown AFI", af, tokbuf, sizeof(tokbuf)), af, (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ tok2strbuf(bgp_safi_values, "Unknown SAFI", safi, tokbuf, sizeof(tokbuf)), safi); switch(af<<8 | safi) { case (AFNUM_INET<<8 | SAFNUM_UNICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST): case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): case (AFNUM_INET<<8 | SAFNUM_MDT): #ifdef INET6 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): #endif case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): case (AFNUM_VPLS<<8 | SAFNUM_VPLS): break; default: TCHECK2(tptr[0], tlen); printf("\n\t no AFI %u / SAFI %u decoder",af,safi); if (vflag <= 1) print_unknown_data(tptr,"\n\t ",tlen); goto done; break; } tptr +=3; TCHECK(tptr[0]); nhlen = tptr[0]; tlen = nhlen; tptr++; if (tlen) { int nnh = 0; printf("\n\t nexthop: "); while (tlen > 0) { if ( nnh++ > 0 ) { printf( ", " ); } switch(af<<8 | safi) { case (AFNUM_INET<<8 | SAFNUM_UNICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST): case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): case (AFNUM_INET<<8 | SAFNUM_MDT): if (tlen < (int)sizeof(struct in_addr)) { printf("invalid len"); tlen = 0; } else { TCHECK2(tptr[0], sizeof(struct in_addr)); printf("%s",getname(tptr)); tlen -= sizeof(struct in_addr); tptr += sizeof(struct in_addr); } break; case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): if (tlen < (int)(sizeof(struct in_addr)+BGP_VPN_RD_LEN)) { printf("invalid len"); tlen = 0; } else { TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN); printf("RD: %s, %s", bgp_vpn_rd_print(tptr), getname(tptr+BGP_VPN_RD_LEN)); tlen -= (sizeof(struct in_addr)+BGP_VPN_RD_LEN); tptr += (sizeof(struct in_addr)+BGP_VPN_RD_LEN); } break; #ifdef INET6 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): if (tlen < (int)sizeof(struct in6_addr)) { printf("invalid len"); tlen = 0; } else { TCHECK2(tptr[0], sizeof(struct in6_addr)); printf("%s", getname6(tptr)); tlen -= sizeof(struct in6_addr); tptr += sizeof(struct in6_addr); } break; case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): if (tlen < (int)(sizeof(struct in6_addr)+BGP_VPN_RD_LEN)) { printf("invalid len"); tlen = 0; } else { TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN); printf("RD: %s, %s", bgp_vpn_rd_print(tptr), getname6(tptr+BGP_VPN_RD_LEN)); tlen -= (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); tptr += (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); } break; #endif case (AFNUM_VPLS<<8 | SAFNUM_VPLS): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): if (tlen < (int)sizeof(struct in_addr)) { printf("invalid len"); tlen = 0; } else { TCHECK2(tptr[0], sizeof(struct in_addr)); printf("%s", getname(tptr)); tlen -= (sizeof(struct in_addr)); tptr += (sizeof(struct in_addr)); } break; case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): TCHECK2(tptr[0], tlen); printf("%s",isonsap_string(tptr,tlen)); tptr += tlen; tlen = 0; break; case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): if (tlen < BGP_VPN_RD_LEN+1) { printf("invalid len"); tlen = 0; } else { TCHECK2(tptr[0], tlen); printf("RD: %s, %s", bgp_vpn_rd_print(tptr), isonsap_string(tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN)); /* rfc986 mapped IPv4 address ? */ if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601) printf(" = %s", getname(tptr+BGP_VPN_RD_LEN+4)); #ifdef INET6 /* rfc1888 mapped IPv6 address ? */ else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000) printf(" = %s", getname6(tptr+BGP_VPN_RD_LEN+3)); #endif tptr += tlen; tlen = 0; } break; default: TCHECK2(tptr[0], tlen); printf("no AFI %u/SAFI %u decoder",af,safi); if (vflag <= 1) print_unknown_data(tptr,"\n\t ",tlen); tptr += tlen; tlen = 0; goto done; break; } } } printf(", nh-length: %u", nhlen); tptr += tlen; TCHECK(tptr[0]); snpa = tptr[0]; tptr++; if (snpa) { printf("\n\t %u SNPA", snpa); for (/*nothing*/; snpa > 0; snpa--) { TCHECK(tptr[0]); printf("\n\t %d bytes", tptr[0]); tptr += tptr[0] + 1; } } else { printf(", no SNPA"); } while (len - (tptr - pptr) > 0) { switch (af<<8 | safi) { case (AFNUM_INET<<8 | SAFNUM_UNICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST): case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): advance = decode_prefix4(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else if (advance == -3) break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): advance = decode_labeled_prefix4(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else if (advance == -3) break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): advance = decode_rt_routing_info(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): advance = decode_multicast_vpn(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_MDT): advance = decode_mdt_vpn_nlri(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; #ifdef INET6 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): advance = decode_prefix6(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else if (advance == -3) break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): advance = decode_labeled_prefix6(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else if (advance == -3) break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; #endif case (AFNUM_VPLS<<8 | SAFNUM_VPLS): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): advance = decode_clnp_prefix(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): advance = decode_labeled_vpn_clnp_prefix(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; default: TCHECK2(*tptr,tlen); printf("\n\t no AFI %u / SAFI %u decoder",af,safi); if (vflag <= 1) print_unknown_data(tptr,"\n\t ",tlen); advance = 0; tptr = pptr + len; break; } if (advance < 0) break; tptr += advance; } done: break; case BGPTYPE_MP_UNREACH_NLRI: TCHECK2(tptr[0], BGP_MP_NLRI_MINSIZE); af = EXTRACT_16BITS(tptr); safi = tptr[2]; printf("\n\t AFI: %s (%u), %sSAFI: %s (%u)", tok2strbuf(af_values, "Unknown AFI", af, tokbuf, sizeof(tokbuf)), af, (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ tok2strbuf(bgp_safi_values, "Unknown SAFI", safi, tokbuf, sizeof(tokbuf)), safi); if (len == BGP_MP_NLRI_MINSIZE) printf("\n\t End-of-Rib Marker (empty NLRI)"); tptr += 3; while (len - (tptr - pptr) > 0) { switch (af<<8 | safi) { case (AFNUM_INET<<8 | SAFNUM_UNICAST): case (AFNUM_INET<<8 | SAFNUM_MULTICAST): case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): advance = decode_prefix4(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else if (advance == -3) break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): advance = decode_labeled_prefix4(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else if (advance == -3) break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; #ifdef INET6 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): advance = decode_prefix6(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else if (advance == -3) break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): advance = decode_labeled_prefix6(tptr, len, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else if (advance == -3) break; /* bytes left, but not enough */ else printf("\n\t %s", buf); break; case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; #endif case (AFNUM_VPLS<<8 | SAFNUM_VPLS): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): advance = decode_clnp_prefix(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): advance = decode_labeled_vpn_clnp_prefix(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_MDT): advance = decode_mdt_vpn_nlri(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): advance = decode_multicast_vpn(tptr, buf, sizeof(buf)); if (advance == -1) printf("\n\t (illegal prefix length)"); else if (advance == -2) goto trunc; else printf("\n\t %s", buf); break; default: TCHECK2(*(tptr-3),tlen); printf("no AFI %u / SAFI %u decoder",af,safi); if (vflag <= 1) print_unknown_data(tptr-3,"\n\t ",tlen); advance = 0; tptr = pptr + len; break; } if (advance < 0) break; tptr += advance; } break; case BGPTYPE_EXTD_COMMUNITIES: if (len % 8) { printf("invalid len"); break; } while (tlen>0) { u_int16_t extd_comm; TCHECK2(tptr[0], 2); extd_comm=EXTRACT_16BITS(tptr); printf("\n\t %s (0x%04x), Flags [%s]", tok2strbuf(bgp_extd_comm_subtype_values, "unknown extd community typecode", extd_comm, tokbuf, sizeof(tokbuf)), extd_comm, bittok2str(bgp_extd_comm_flag_values, "none", extd_comm)); TCHECK2(*(tptr+2), 6); switch(extd_comm) { case BGP_EXT_COM_RT_0: case BGP_EXT_COM_RO_0: case BGP_EXT_COM_L2VPN_RT_0: printf(": %u:%u (= %s)", EXTRACT_16BITS(tptr+2), EXTRACT_32BITS(tptr+4), getname(tptr+4)); break; case BGP_EXT_COM_RT_1: case BGP_EXT_COM_RO_1: case BGP_EXT_COM_L2VPN_RT_1: case BGP_EXT_COM_VRF_RT_IMP: printf(": %s:%u", getname(tptr+2), EXTRACT_16BITS(tptr+6)); break; case BGP_EXT_COM_RT_2: case BGP_EXT_COM_RO_2: printf(": %s:%u", as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr+2)), EXTRACT_16BITS(tptr+6)); break; case BGP_EXT_COM_LINKBAND: bw.i = EXTRACT_32BITS(tptr+2); printf(": bandwidth: %.3f Mbps", bw.f*8/1000000); break; case BGP_EXT_COM_VPN_ORIGIN: case BGP_EXT_COM_VPN_ORIGIN2: case BGP_EXT_COM_VPN_ORIGIN3: case BGP_EXT_COM_VPN_ORIGIN4: case BGP_EXT_COM_OSPF_RID: case BGP_EXT_COM_OSPF_RID2: printf("%s", getname(tptr+2)); break; case BGP_EXT_COM_OSPF_RTYPE: case BGP_EXT_COM_OSPF_RTYPE2: printf(": area:%s, router-type:%s, metric-type:%s%s", getname(tptr+2), tok2strbuf(bgp_extd_comm_ospf_rtype_values, "unknown (0x%02x)", *(tptr+6), tokbuf, sizeof(tokbuf)), (*(tptr+7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "", ((*(tptr+6) == BGP_OSPF_RTYPE_EXT) || (*(tptr+6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : ""); break; case BGP_EXT_COM_L2INFO: printf(": %s Control Flags [0x%02x]:MTU %u", tok2strbuf(l2vpn_encaps_values, "unknown encaps", *(tptr+2), tokbuf, sizeof(tokbuf)), *(tptr+3), EXTRACT_16BITS(tptr+4)); break; case BGP_EXT_COM_SOURCE_AS: printf(": AS %u", EXTRACT_16BITS(tptr+2)); break; default: TCHECK2(*tptr,8); print_unknown_data(tptr,"\n\t ",8); break; } tlen -=8; tptr +=8; } break; case BGPTYPE_PMSI_TUNNEL: { u_int8_t tunnel_type, flags; tunnel_type = *(tptr+1); flags = *tptr; tlen = len; TCHECK2(tptr[0], 5); printf("\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u", tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type), tunnel_type, bittok2str(bgp_pmsi_flag_values, "none", flags), EXTRACT_24BITS(tptr+2)>>4); tptr +=5; tlen -= 5; switch (tunnel_type) { case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */ case BGP_PMSI_TUNNEL_PIM_BIDIR: TCHECK2(tptr[0], 8); printf("\n\t Sender %s, P-Group %s", ipaddr_string(tptr), ipaddr_string(tptr+4)); break; case BGP_PMSI_TUNNEL_PIM_SSM: TCHECK2(tptr[0], 8); printf("\n\t Root-Node %s, P-Group %s", ipaddr_string(tptr), ipaddr_string(tptr+4)); break; case BGP_PMSI_TUNNEL_INGRESS: TCHECK2(tptr[0], 4); printf("\n\t Tunnel-Endpoint %s", ipaddr_string(tptr)); break; case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */ case BGP_PMSI_TUNNEL_LDP_MP2MP: TCHECK2(tptr[0], 8); printf("\n\t Root-Node %s, LSP-ID 0x%08x", ipaddr_string(tptr), EXTRACT_32BITS(tptr+4)); break; case BGP_PMSI_TUNNEL_RSVP_P2MP: TCHECK2(tptr[0], 8); printf("\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x", ipaddr_string(tptr), EXTRACT_32BITS(tptr+4)); break; default: if (vflag <= 1) { print_unknown_data(tptr,"\n\t ",tlen); } } break; } case BGPTYPE_ATTR_SET: TCHECK2(tptr[0], 4); if (len < 4) goto trunc; printf("\n\t Origin AS: %s", as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr))); tptr+=4; len -=4; while (len) { u_int aflags, atype, alenlen, alen; TCHECK2(tptr[0], 2); if (len < 2) goto trunc; aflags = *tptr; atype = *(tptr + 1); tptr += 2; len -= 2; alenlen = bgp_attr_lenlen(aflags, tptr); TCHECK2(tptr[0], alenlen); if (len < alenlen) goto trunc; alen = bgp_attr_len(aflags, tptr); tptr += alenlen; len -= alenlen; printf("\n\t %s (%u), length: %u", tok2strbuf(bgp_attr_values, "Unknown Attribute", atype, tokbuf, sizeof(tokbuf)), atype, alen); if (aflags) { printf(", Flags [%s%s%s%s", aflags & 0x80 ? "O" : "", aflags & 0x40 ? "T" : "", aflags & 0x20 ? "P" : "", aflags & 0x10 ? "E" : ""); if (aflags & 0xf) printf("+%x", aflags & 0xf); printf("]: "); } /* FIXME check for recursion */ if (!bgp_attr_print(atype, tptr, alen)) return 0; tptr += alen; len -= alen; } break; default: TCHECK2(*pptr,len); printf("\n\t no Attribute %u decoder",atype); /* we have no decoder for the attribute */ if (vflag <= 1) print_unknown_data(pptr,"\n\t ",len); break; } if (vflag > 1 && len) { /* omit zero length attributes*/ TCHECK2(*pptr,len); print_unknown_data(pptr,"\n\t ",len); } return 1; trunc: return 0; } static void bgp_capabilities_print(const u_char *opt, int caps_len) { char tokbuf[TOKBUFSIZE]; char tokbuf2[TOKBUFSIZE]; int cap_type, cap_len, tcap_len, cap_offset; int i = 0; while (i < caps_len) { TCHECK2(opt[i], BGP_CAP_HEADER_SIZE); cap_type=opt[i]; cap_len=opt[i+1]; tcap_len=cap_len; printf("\n\t %s (%u), length: %u", tok2strbuf(bgp_capcode_values, "Unknown", cap_type, tokbuf, sizeof(tokbuf)), cap_type, cap_len); TCHECK2(opt[i+2], cap_len); switch (cap_type) { case BGP_CAPCODE_MP: printf("\n\t\tAFI %s (%u), SAFI %s (%u)", tok2strbuf(af_values, "Unknown", EXTRACT_16BITS(opt+i+2), tokbuf, sizeof(tokbuf)), EXTRACT_16BITS(opt+i+2), tok2strbuf(bgp_safi_values, "Unknown", opt[i+5], tokbuf, sizeof(tokbuf)), opt[i+5]); break; case BGP_CAPCODE_RESTART: printf("\n\t\tRestart Flags: [%s], Restart Time %us", ((opt[i+2])&0x80) ? "R" : "none", EXTRACT_16BITS(opt+i+2)&0xfff); tcap_len-=2; cap_offset=4; while(tcap_len>=4) { printf("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", tok2strbuf(af_values,"Unknown", EXTRACT_16BITS(opt+i+cap_offset), tokbuf, sizeof(tokbuf)), EXTRACT_16BITS(opt+i+cap_offset), tok2strbuf(bgp_safi_values,"Unknown", opt[i+cap_offset+2], tokbuf2, sizeof(tokbuf2)), opt[i+cap_offset+2], ((opt[i+cap_offset+3])&0x80) ? "yes" : "no" ); tcap_len-=4; cap_offset+=4; } break; case BGP_CAPCODE_RR: case BGP_CAPCODE_RR_CISCO: break; case BGP_CAPCODE_AS_NEW: /* * Extract the 4 byte AS number encoded. */ if (cap_len == 4) { printf("\n\t\t 4 Byte AS %s", as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(opt + i + 2))); } break; default: printf("\n\t\tno decoder for Capability %u", cap_type); if (vflag <= 1) print_unknown_data(&opt[i+2],"\n\t\t",cap_len); break; } if (vflag > 1 && cap_len > 0) { print_unknown_data(&opt[i+2],"\n\t\t",cap_len); } i += BGP_CAP_HEADER_SIZE + cap_len; } return; trunc: printf("[|BGP]"); } static void bgp_open_print(const u_char *dat, int length) { struct bgp_open bgpo; struct bgp_opt bgpopt; const u_char *opt; int i; char tokbuf[TOKBUFSIZE]; TCHECK2(dat[0], BGP_OPEN_SIZE); memcpy(&bgpo, dat, BGP_OPEN_SIZE); printf("\n\t Version %d, ", bgpo.bgpo_version); printf("my AS %s, ", as_printf(astostr, sizeof(astostr), ntohs(bgpo.bgpo_myas))); printf("Holdtime %us, ", ntohs(bgpo.bgpo_holdtime)); printf("ID %s", getname((u_char *)&bgpo.bgpo_id)); printf("\n\t Optional parameters, length: %u", bgpo.bgpo_optlen); /* some little sanity checking */ if (length < bgpo.bgpo_optlen+BGP_OPEN_SIZE) return; /* ugly! */ opt = &((const struct bgp_open *)dat)->bgpo_optlen; opt++; i = 0; while (i < bgpo.bgpo_optlen) { TCHECK2(opt[i], BGP_OPT_SIZE); memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE); if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) { printf("\n\t Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len); break; } printf("\n\t Option %s (%u), length: %u", tok2strbuf(bgp_opt_values,"Unknown", bgpopt.bgpopt_type, tokbuf, sizeof(tokbuf)), bgpopt.bgpopt_type, bgpopt.bgpopt_len); /* now let's decode the options we know*/ switch(bgpopt.bgpopt_type) { case BGP_OPT_CAP: bgp_capabilities_print(&opt[i+BGP_OPT_SIZE], bgpopt.bgpopt_len); break; case BGP_OPT_AUTH: default: printf("\n\t no decoder for option %u", bgpopt.bgpopt_type); break; } i += BGP_OPT_SIZE + bgpopt.bgpopt_len; } return; trunc: printf("[|BGP]"); } static void bgp_update_print(const u_char *dat, int length) { struct bgp bgp; const u_char *p; int withdrawn_routes_len; int len; int i; char tokbuf[TOKBUFSIZE]; #ifndef INET6 char buf[MAXHOSTNAMELEN + 100]; int wpfx; #endif TCHECK2(dat[0], BGP_SIZE); if (length < BGP_SIZE) goto trunc; memcpy(&bgp, dat, BGP_SIZE); p = dat + BGP_SIZE; /*XXX*/ length -= BGP_SIZE; /* Unfeasible routes */ TCHECK2(p[0], 2); if (length < 2) goto trunc; withdrawn_routes_len = EXTRACT_16BITS(p); p += 2; length -= 2; if (withdrawn_routes_len) { /* * Without keeping state from the original NLRI message, * it's not possible to tell if this a v4 or v6 route, * so only try to decode it if we're not v6 enabled. */ TCHECK2(p[0], withdrawn_routes_len); if (length < withdrawn_routes_len) goto trunc; #ifdef INET6 printf("\n\t Withdrawn routes: %d bytes", withdrawn_routes_len); p += withdrawn_routes_len; length -= withdrawn_routes_len; #else if (withdrawn_routes_len < 2) goto trunc; length -= 2; withdrawn_routes_len -= 2; printf("\n\t Withdrawn routes:"); while(withdrawn_routes_len > 0) { wpfx = decode_prefix4(p, withdrawn_routes_len, buf, sizeof(buf)); if (wpfx == -1) { printf("\n\t (illegal prefix length)"); break; } else if (wpfx == -2) goto trunc; else if (wpfx == -3) goto trunc; /* bytes left, but not enough */ else { printf("\n\t %s", buf); p += wpfx; length -= wpfx; withdrawn_routes_len -= wpfx; } } #endif } TCHECK2(p[0], 2); if (length < 2) goto trunc; len = EXTRACT_16BITS(p); p += 2; length -= 2; if (withdrawn_routes_len == 0 && len == 0 && length == 0) { /* No withdrawn routes, no path attributes, no NLRI */ printf("\n\t End-of-Rib Marker (empty NLRI)"); return; } if (len) { /* do something more useful!*/ while (len) { int aflags, atype, alenlen, alen; TCHECK2(p[0], 2); if (len < 2) goto trunc; if (length < 2) goto trunc; aflags = *p; atype = *(p + 1); p += 2; len -= 2; length -= 2; alenlen = bgp_attr_lenlen(aflags, p); TCHECK2(p[0], alenlen); if (len < alenlen) goto trunc; if (length < alenlen) goto trunc; alen = bgp_attr_len(aflags, p); p += alenlen; len -= alenlen; length -= alenlen; printf("\n\t %s (%u), length: %u", tok2strbuf(bgp_attr_values, "Unknown Attribute", atype, tokbuf, sizeof(tokbuf)), atype, alen); if (aflags) { printf(", Flags [%s%s%s%s", aflags & 0x80 ? "O" : "", aflags & 0x40 ? "T" : "", aflags & 0x20 ? "P" : "", aflags & 0x10 ? "E" : ""); if (aflags & 0xf) printf("+%x", aflags & 0xf); printf("]: "); } if (len < alen) goto trunc; if (length < alen) goto trunc; if (!bgp_attr_print(atype, p, alen)) goto trunc; p += alen; len -= alen; length -= alen; } } if (length) { /* * XXX - what if they're using the "Advertisement of * Multiple Paths in BGP" feature: * * https://datatracker.ietf.org/doc/draft-ietf-idr-add-paths/ * * http://tools.ietf.org/html/draft-ietf-idr-add-paths-06 */ printf("\n\t Updated routes:"); while (length) { char buf[MAXHOSTNAMELEN + 100]; i = decode_prefix4(p, length, buf, sizeof(buf)); if (i == -1) { printf("\n\t (illegal prefix length)"); break; } else if (i == -2) goto trunc; else if (i == -3) goto trunc; /* bytes left, but not enough */ else { printf("\n\t %s", buf); p += i; length -= i; } } } return; trunc: printf("[|BGP]"); } static void bgp_notification_print(const u_char *dat, int length) { struct bgp_notification bgpn; const u_char *tptr; char tokbuf[TOKBUFSIZE]; char tokbuf2[TOKBUFSIZE]; TCHECK2(dat[0], BGP_NOTIFICATION_SIZE); memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE); /* some little sanity checking */ if (length= BGP_NOTIFICATION_SIZE + 7) { tptr = dat + BGP_NOTIFICATION_SIZE; TCHECK2(*tptr, 7); printf(", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u", tok2strbuf(af_values, "Unknown", EXTRACT_16BITS(tptr), tokbuf, sizeof(tokbuf)), EXTRACT_16BITS(tptr), tok2strbuf(bgp_safi_values, "Unknown", *(tptr+2), tokbuf2, sizeof(tokbuf)), *(tptr+2), EXTRACT_32BITS(tptr+3)); } break; default: break; } return; trunc: printf("[|BGP]"); } static void bgp_route_refresh_print(const u_char *pptr, int len) { const struct bgp_route_refresh *bgp_route_refresh_header; char tokbuf[TOKBUFSIZE]; char tokbuf2[TOKBUFSIZE]; TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE); /* some little sanity checking */ if (lenafi), tokbuf, sizeof(tokbuf)), EXTRACT_16BITS(&bgp_route_refresh_header->afi), tok2strbuf(bgp_safi_values,"Unknown", bgp_route_refresh_header->safi, tokbuf2, sizeof(tokbuf2)), bgp_route_refresh_header->safi); if (vflag > 1) { TCHECK2(*pptr, len); print_unknown_data(pptr,"\n\t ", len); } return; trunc: printf("[|BGP]"); } static int bgp_header_print(const u_char *dat, int length) { struct bgp bgp; char tokbuf[TOKBUFSIZE]; TCHECK2(dat[0], BGP_SIZE); memcpy(&bgp, dat, BGP_SIZE); printf("\n\t%s Message (%u), length: %u", tok2strbuf(bgp_msg_values, "Unknown", bgp.bgp_type, tokbuf, sizeof(tokbuf)), bgp.bgp_type, length); switch (bgp.bgp_type) { case BGP_OPEN: bgp_open_print(dat, length); break; case BGP_UPDATE: bgp_update_print(dat, length); break; case BGP_NOTIFICATION: bgp_notification_print(dat, length); break; case BGP_KEEPALIVE: break; case BGP_ROUTE_REFRESH: bgp_route_refresh_print(dat, length); break; default: /* we have no decoder for the BGP message */ TCHECK2(*dat, length); printf("\n\t no Message %u decoder",bgp.bgp_type); print_unknown_data(dat,"\n\t ",length); break; } return 1; trunc: printf("[|BGP]"); return 0; } void bgp_print(const u_char *dat, int length) { const u_char *p; const u_char *ep; const u_char *start; const u_char marker[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; struct bgp bgp; u_int16_t hlen; char tokbuf[TOKBUFSIZE]; ep = dat + length; if (snapend < dat + length) ep = snapend; printf(": BGP, length: %u",length); if (vflag < 1) /* lets be less chatty */ return; p = dat; start = p; while (p < ep) { if (!TTEST2(p[0], 1)) break; if (p[0] != 0xff) { p++; continue; } if (!TTEST2(p[0], sizeof(marker))) break; if (memcmp(p, marker, sizeof(marker)) != 0) { p++; continue; } /* found BGP header */ TCHECK2(p[0], BGP_SIZE); /*XXX*/ memcpy(&bgp, p, BGP_SIZE); if (start != p) printf(" [|BGP]"); hlen = ntohs(bgp.bgp_len); if (hlen < BGP_SIZE) { printf("\n[|BGP Bogus header length %u < %u]", hlen, BGP_SIZE); break; } if (TTEST2(p[0], hlen)) { if (!bgp_header_print(p, hlen)) return; p += hlen; start = p; } else { printf("\n[|BGP %s]", tok2strbuf(bgp_msg_values, "Unknown Message Type", bgp.bgp_type, tokbuf, sizeof(tokbuf))); break; } } return; trunc: printf(" [|BGP]"); } /* * Local Variables: * c-style: whitesmith * c-basic-offset: 4 * End: */ tcpdump-4.5.1/print-fr.c0000644000026300017510000006420612237020316012527 0ustar mcr/* * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] _U_ = "@(#)$Header: /tcpdump/master/tcpdump/print-fr.c,v 1.51 2006-06-23 22:20:32 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "addrtoname.h" #include "interface.h" #include "ethertype.h" #include "nlpid.h" #include "extract.h" #include "oui.h" static void frf15_print(const u_char *, u_int); /* * the frame relay header has a variable length * * the EA bit determines if there is another byte * in the header * * minimum header length is 2 bytes * maximum header length is 4 bytes * * 7 6 5 4 3 2 1 0 * +----+----+----+----+----+----+----+----+ * | DLCI (6 bits) | CR | EA | * +----+----+----+----+----+----+----+----+ * | DLCI (4 bits) |FECN|BECN| DE | EA | * +----+----+----+----+----+----+----+----+ * | DLCI (7 bits) | EA | * +----+----+----+----+----+----+----+----+ * | DLCI (6 bits) |SDLC| EA | * +----+----+----+----+----+----+----+----+ */ #define FR_EA_BIT 0x01 #define FR_CR_BIT 0x02000000 #define FR_DE_BIT 0x00020000 #define FR_BECN_BIT 0x00040000 #define FR_FECN_BIT 0x00080000 #define FR_SDLC_BIT 0x00000002 static const struct tok fr_header_flag_values[] = { { FR_CR_BIT, "C!" }, { FR_DE_BIT, "DE" }, { FR_BECN_BIT, "BECN" }, { FR_FECN_BIT, "FECN" }, { FR_SDLC_BIT, "sdlcore" }, { 0, NULL } }; /* FRF.15 / FRF.16 */ #define MFR_B_BIT 0x80 #define MFR_E_BIT 0x40 #define MFR_C_BIT 0x20 #define MFR_BEC_MASK (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT) #define MFR_CTRL_FRAME (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT) #define MFR_FRAG_FRAME (MFR_B_BIT | MFR_E_BIT ) static const struct tok frf_flag_values[] = { { MFR_B_BIT, "Begin" }, { MFR_E_BIT, "End" }, { MFR_C_BIT, "Control" }, { 0, NULL } }; /* Finds out Q.922 address length, DLCI and flags. Returns 0 on success * save the flags dep. on address length */ static int parse_q922_addr(const u_char *p, u_int *dlci, u_int *addr_len, u_int8_t *flags) { if ((p[0] & FR_EA_BIT)) return -1; *addr_len = 2; *dlci = ((p[0] & 0xFC) << 2) | ((p[1] & 0xF0) >> 4); flags[0] = p[0] & 0x02; /* populate the first flag fields */ flags[1] = p[1] & 0x0c; flags[2] = 0; /* clear the rest of the flags */ flags[3] = 0; if (p[1] & FR_EA_BIT) return 0; /* 2-byte Q.922 address */ p += 2; (*addr_len)++; /* 3- or 4-byte Q.922 address */ if ((p[0] & FR_EA_BIT) == 0) { *dlci = (*dlci << 7) | (p[0] >> 1); (*addr_len)++; /* 4-byte Q.922 address */ p++; } if ((p[0] & FR_EA_BIT) == 0) return -1; /* more than 4 bytes of Q.922 address? */ flags[3] = p[0] & 0x02; *dlci = (*dlci << 6) | (p[0] >> 2); return 0; } char *q922_string(const u_char *p) { static u_int dlci, addr_len; static u_int8_t flags[4]; static char buffer[sizeof("DLCI xxxxxxxxxx")]; memset(buffer, 0, sizeof(buffer)); if (parse_q922_addr(p, &dlci, &addr_len, flags) == 0){ snprintf(buffer, sizeof(buffer), "DLCI %u", dlci); } return buffer; } /* Frame Relay packet structure, with flags and CRC removed +---------------------------+ | Q.922 Address* | +-- --+ | | +---------------------------+ | Control (UI = 0x03) | +---------------------------+ | Optional Pad (0x00) | +---------------------------+ | NLPID | +---------------------------+ | . | | . | | . | | Data | | . | | . | +---------------------------+ * Q.922 addresses, as presently defined, are two octets and contain a 10-bit DLCI. In some networks Q.922 addresses may optionally be increased to three or four octets. */ static u_int fr_hdrlen(const u_char *p, u_int addr_len) { if (!p[addr_len + 1] /* pad exist */) return addr_len + 1 /* UI */ + 1 /* pad */ + 1 /* NLPID */; else return addr_len + 1 /* UI */ + 1 /* NLPID */; } static void fr_hdr_print(int length, u_int addr_len, u_int dlci, u_int8_t *flags, u_int16_t nlpid) { if (qflag) { (void)printf("Q.922, DLCI %u, length %u: ", dlci, length); } else { if (nlpid <= 0xff) /* if its smaller than 256 then its a NLPID */ (void)printf("Q.922, hdr-len %u, DLCI %u, Flags [%s], NLPID %s (0x%02x), length %u: ", addr_len, dlci, bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)), tok2str(nlpid_values,"unknown", nlpid), nlpid, length); else /* must be an ethertype */ (void)printf("Q.922, hdr-len %u, DLCI %u, Flags [%s], cisco-ethertype %s (0x%04x), length %u: ", addr_len, dlci, bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)), tok2str(ethertype_values, "unknown", nlpid), nlpid, length); } } u_int fr_if_print(const struct pcap_pkthdr *h, register const u_char *p) { register u_int length = h->len; register u_int caplen = h->caplen; TCHECK2(*p, 4); /* minimum frame header length */ if ((length = fr_print(p, length)) == 0) return (0); else return length; trunc: printf("[|fr]"); return caplen; } u_int fr_print(register const u_char *p, u_int length) { u_int16_t extracted_ethertype; u_int dlci; u_int addr_len; u_int16_t nlpid; u_int hdr_len; u_int8_t flags[4]; if (parse_q922_addr(p, &dlci, &addr_len, flags)) { printf("Q.922, invalid address"); return 0; } TCHECK2(*p,addr_len+1+1); hdr_len = fr_hdrlen(p, addr_len); TCHECK2(*p,hdr_len); if (p[addr_len] != 0x03 && dlci != 0) { /* lets figure out if we have cisco style encapsulation: */ extracted_ethertype = EXTRACT_16BITS(p+addr_len); if (eflag) fr_hdr_print(length, addr_len, dlci, flags, extracted_ethertype); if (ethertype_print(gndo, extracted_ethertype, p+addr_len+ETHERTYPE_LEN, length-addr_len-ETHERTYPE_LEN, length-addr_len-ETHERTYPE_LEN) == 0) /* ether_type not known, probably it wasn't one */ printf("UI %02x! ", p[addr_len]); else return hdr_len; } if (!p[addr_len + 1]) { /* pad byte should be used with 3-byte Q.922 */ if (addr_len != 3) printf("Pad! "); } else if (addr_len == 3) printf("No pad! "); nlpid = p[hdr_len - 1]; if (eflag) fr_hdr_print(length, addr_len, dlci, flags, nlpid); p += hdr_len; length -= hdr_len; switch (nlpid) { case NLPID_IP: ip_print(gndo, p, length); break; #ifdef INET6 case NLPID_IP6: ip6_print(gndo, p, length); break; #endif case NLPID_CLNP: case NLPID_ESIS: case NLPID_ISIS: isoclns_print(p-1, length+1, length+1); /* OSI printers need the NLPID field */ break; case NLPID_SNAP: if (snap_print(p, length, length, 0) == 0) { /* ether_type not known, print raw packet */ if (!eflag) fr_hdr_print(length + hdr_len, hdr_len, dlci, flags, nlpid); if (!suppress_default_print) default_print(p - hdr_len, length + hdr_len); } break; case NLPID_Q933: q933_print(p, length); break; case NLPID_MFR: frf15_print(p, length); break; case NLPID_PPP: ppp_print(p, length); break; default: if (!eflag) fr_hdr_print(length + hdr_len, addr_len, dlci, flags, nlpid); if (!xflag) default_print(p, length); } return hdr_len; trunc: printf("[|fr]"); return 0; } u_int mfr_if_print(const struct pcap_pkthdr *h, register const u_char *p) { register u_int length = h->len; register u_int caplen = h->caplen; TCHECK2(*p, 2); /* minimum frame header length */ if ((length = mfr_print(p, length)) == 0) return (0); else return length; trunc: printf("[|mfr]"); return caplen; } #define MFR_CTRL_MSG_ADD_LINK 1 #define MFR_CTRL_MSG_ADD_LINK_ACK 2 #define MFR_CTRL_MSG_ADD_LINK_REJ 3 #define MFR_CTRL_MSG_HELLO 4 #define MFR_CTRL_MSG_HELLO_ACK 5 #define MFR_CTRL_MSG_REMOVE_LINK 6 #define MFR_CTRL_MSG_REMOVE_LINK_ACK 7 static const struct tok mfr_ctrl_msg_values[] = { { MFR_CTRL_MSG_ADD_LINK, "Add Link" }, { MFR_CTRL_MSG_ADD_LINK_ACK, "Add Link ACK" }, { MFR_CTRL_MSG_ADD_LINK_REJ, "Add Link Reject" }, { MFR_CTRL_MSG_HELLO, "Hello" }, { MFR_CTRL_MSG_HELLO_ACK, "Hello ACK" }, { MFR_CTRL_MSG_REMOVE_LINK, "Remove Link" }, { MFR_CTRL_MSG_REMOVE_LINK_ACK, "Remove Link ACK" }, { 0, NULL } }; #define MFR_CTRL_IE_BUNDLE_ID 1 #define MFR_CTRL_IE_LINK_ID 2 #define MFR_CTRL_IE_MAGIC_NUM 3 #define MFR_CTRL_IE_TIMESTAMP 5 #define MFR_CTRL_IE_VENDOR_EXT 6 #define MFR_CTRL_IE_CAUSE 7 static const struct tok mfr_ctrl_ie_values[] = { { MFR_CTRL_IE_BUNDLE_ID, "Bundle ID"}, { MFR_CTRL_IE_LINK_ID, "Link ID"}, { MFR_CTRL_IE_MAGIC_NUM, "Magic Number"}, { MFR_CTRL_IE_TIMESTAMP, "Timestamp"}, { MFR_CTRL_IE_VENDOR_EXT, "Vendor Extension"}, { MFR_CTRL_IE_CAUSE, "Cause"}, { 0, NULL } }; #define MFR_ID_STRING_MAXLEN 50 struct ie_tlv_header_t { u_int8_t ie_type; u_int8_t ie_len; }; u_int mfr_print(register const u_char *p, u_int length) { u_int tlen,idx,hdr_len = 0; u_int16_t sequence_num; u_int8_t ie_type,ie_len; const u_int8_t *tptr; /* * FRF.16 Link Integrity Control Frame * * 7 6 5 4 3 2 1 0 * +----+----+----+----+----+----+----+----+ * | B | E | C=1| 0 0 0 0 | EA | * +----+----+----+----+----+----+----+----+ * | 0 0 0 0 0 0 0 0 | * +----+----+----+----+----+----+----+----+ * | message type | * +----+----+----+----+----+----+----+----+ */ TCHECK2(*p, 4); /* minimum frame header length */ if ((p[0] & MFR_BEC_MASK) == MFR_CTRL_FRAME && p[1] == 0) { printf("FRF.16 Control, Flags [%s], %s, length %u", bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)), tok2str(mfr_ctrl_msg_values,"Unknown Message (0x%02x)",p[2]), length); tptr = p + 3; tlen = length -3; hdr_len = 3; if (!vflag) return hdr_len; while (tlen>sizeof(struct ie_tlv_header_t)) { TCHECK2(*tptr, sizeof(struct ie_tlv_header_t)); ie_type=tptr[0]; ie_len=tptr[1]; printf("\n\tIE %s (%u), length %u: ", tok2str(mfr_ctrl_ie_values,"Unknown",ie_type), ie_type, ie_len); /* infinite loop check */ if (ie_type == 0 || ie_len <= sizeof(struct ie_tlv_header_t)) return hdr_len; TCHECK2(*tptr,ie_len); tptr+=sizeof(struct ie_tlv_header_t); /* tlv len includes header */ ie_len-=sizeof(struct ie_tlv_header_t); tlen-=sizeof(struct ie_tlv_header_t); switch (ie_type) { case MFR_CTRL_IE_MAGIC_NUM: printf("0x%08x",EXTRACT_32BITS(tptr)); break; case MFR_CTRL_IE_BUNDLE_ID: /* same message format */ case MFR_CTRL_IE_LINK_ID: for (idx = 0; idx < ie_len && idx < MFR_ID_STRING_MAXLEN; idx++) { if (*(tptr+idx) != 0) /* don't print null termination */ safeputchar(*(tptr+idx)); else break; } break; case MFR_CTRL_IE_TIMESTAMP: if (ie_len == sizeof(struct timeval)) { ts_print((const struct timeval *)tptr); break; } /* fall through and hexdump if no unix timestamp */ /* * FIXME those are the defined IEs that lack a decoder * you are welcome to contribute code ;-) */ case MFR_CTRL_IE_VENDOR_EXT: case MFR_CTRL_IE_CAUSE: default: if (vflag <= 1) print_unknown_data(tptr,"\n\t ",ie_len); break; } /* do we want to see a hexdump of the IE ? */ if (vflag > 1 ) print_unknown_data(tptr,"\n\t ",ie_len); tlen-=ie_len; tptr+=ie_len; } return hdr_len; } /* * FRF.16 Fragmentation Frame * * 7 6 5 4 3 2 1 0 * +----+----+----+----+----+----+----+----+ * | B | E | C=0|seq. (high 4 bits) | EA | * +----+----+----+----+----+----+----+----+ * | sequence (low 8 bits) | * +----+----+----+----+----+----+----+----+ * | DLCI (6 bits) | CR | EA | * +----+----+----+----+----+----+----+----+ * | DLCI (4 bits) |FECN|BECN| DE | EA | * +----+----+----+----+----+----+----+----+ */ sequence_num = (p[0]&0x1e)<<7 | p[1]; /* whole packet or first fragment ? */ if ((p[0] & MFR_BEC_MASK) == MFR_FRAG_FRAME || (p[0] & MFR_BEC_MASK) == MFR_B_BIT) { printf("FRF.16 Frag, seq %u, Flags [%s], ", sequence_num, bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK))); hdr_len = 2; fr_print(p+hdr_len,length-hdr_len); return hdr_len; } /* must be a middle or the last fragment */ printf("FRF.16 Frag, seq %u, Flags [%s]", sequence_num, bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK))); print_unknown_data(p,"\n\t",length); return hdr_len; trunc: printf("[|mfr]"); return length; } /* an NLPID of 0xb1 indicates a 2-byte * FRF.15 header * * 7 6 5 4 3 2 1 0 * +----+----+----+----+----+----+----+----+ * ~ Q.922 header ~ * +----+----+----+----+----+----+----+----+ * | NLPID (8 bits) | NLPID=0xb1 * +----+----+----+----+----+----+----+----+ * | B | E | C |seq. (high 4 bits) | R | * +----+----+----+----+----+----+----+----+ * | sequence (low 8 bits) | * +----+----+----+----+----+----+----+----+ */ #define FR_FRF15_FRAGTYPE 0x01 static void frf15_print (const u_char *p, u_int length) { u_int16_t sequence_num, flags; flags = p[0]&MFR_BEC_MASK; sequence_num = (p[0]&0x1e)<<7 | p[1]; printf("FRF.15, seq 0x%03x, Flags [%s],%s Fragmentation, length %u", sequence_num, bittok2str(frf_flag_values,"none",flags), p[0]&FR_FRF15_FRAGTYPE ? "Interface" : "End-to-End", length); /* TODO: * depending on all permutations of the B, E and C bit * dig as deep as we can - e.g. on the first (B) fragment * there is enough payload to print the IP header * on non (B) fragments it depends if the fragmentation * model is end-to-end or interface based wether we want to print * another Q.922 header */ } /* * Q.933 decoding portion for framerelay specific. */ /* Q.933 packet format Format of Other Protocols using Q.933 NLPID +-------------------------------+ | Q.922 Address | +---------------+---------------+ |Control 0x03 | NLPID 0x08 | +---------------+---------------+ | L2 Protocol ID | | octet 1 | octet 2 | +-------------------------------+ | L3 Protocol ID | | octet 2 | octet 2 | +-------------------------------+ | Protocol Data | +-------------------------------+ | FCS | +-------------------------------+ */ /* L2 (Octet 1)- Call Reference Usually is 0x0 */ /* * L2 (Octet 2)- Message Types definition 1 byte long. */ /* Call Establish */ #define MSG_TYPE_ESC_TO_NATIONAL 0x00 #define MSG_TYPE_ALERT 0x01 #define MSG_TYPE_CALL_PROCEEDING 0x02 #define MSG_TYPE_CONNECT 0x07 #define MSG_TYPE_CONNECT_ACK 0x0F #define MSG_TYPE_PROGRESS 0x03 #define MSG_TYPE_SETUP 0x05 /* Call Clear */ #define MSG_TYPE_DISCONNECT 0x45 #define MSG_TYPE_RELEASE 0x4D #define MSG_TYPE_RELEASE_COMPLETE 0x5A #define MSG_TYPE_RESTART 0x46 #define MSG_TYPE_RESTART_ACK 0x4E /* Status */ #define MSG_TYPE_STATUS 0x7D #define MSG_TYPE_STATUS_ENQ 0x75 static const struct tok fr_q933_msg_values[] = { { MSG_TYPE_ESC_TO_NATIONAL, "ESC to National" }, { MSG_TYPE_ALERT, "Alert" }, { MSG_TYPE_CALL_PROCEEDING, "Call proceeding" }, { MSG_TYPE_CONNECT, "Connect" }, { MSG_TYPE_CONNECT_ACK, "Connect ACK" }, { MSG_TYPE_PROGRESS, "Progress" }, { MSG_TYPE_SETUP, "Setup" }, { MSG_TYPE_DISCONNECT, "Disconnect" }, { MSG_TYPE_RELEASE, "Release" }, { MSG_TYPE_RELEASE_COMPLETE, "Release Complete" }, { MSG_TYPE_RESTART, "Restart" }, { MSG_TYPE_RESTART_ACK, "Restart ACK" }, { MSG_TYPE_STATUS, "Status Reply" }, { MSG_TYPE_STATUS_ENQ, "Status Enquiry" }, { 0, NULL } }; #define MSG_ANSI_LOCKING_SHIFT 0x95 #define FR_LMI_ANSI_REPORT_TYPE_IE 0x01 #define FR_LMI_ANSI_LINK_VERIFY_IE_91 0x19 /* details? */ #define FR_LMI_ANSI_LINK_VERIFY_IE 0x03 #define FR_LMI_ANSI_PVC_STATUS_IE 0x07 #define FR_LMI_CCITT_REPORT_TYPE_IE 0x51 #define FR_LMI_CCITT_LINK_VERIFY_IE 0x53 #define FR_LMI_CCITT_PVC_STATUS_IE 0x57 static const struct tok fr_q933_ie_values_codeset5[] = { { FR_LMI_ANSI_REPORT_TYPE_IE, "ANSI Report Type" }, { FR_LMI_ANSI_LINK_VERIFY_IE_91, "ANSI Link Verify" }, { FR_LMI_ANSI_LINK_VERIFY_IE, "ANSI Link Verify" }, { FR_LMI_ANSI_PVC_STATUS_IE, "ANSI PVC Status" }, { FR_LMI_CCITT_REPORT_TYPE_IE, "CCITT Report Type" }, { FR_LMI_CCITT_LINK_VERIFY_IE, "CCITT Link Verify" }, { FR_LMI_CCITT_PVC_STATUS_IE, "CCITT PVC Status" }, { 0, NULL } }; #define FR_LMI_REPORT_TYPE_IE_FULL_STATUS 0 #define FR_LMI_REPORT_TYPE_IE_LINK_VERIFY 1 #define FR_LMI_REPORT_TYPE_IE_ASYNC_PVC 2 static const struct tok fr_lmi_report_type_ie_values[] = { { FR_LMI_REPORT_TYPE_IE_FULL_STATUS, "Full Status" }, { FR_LMI_REPORT_TYPE_IE_LINK_VERIFY, "Link verify" }, { FR_LMI_REPORT_TYPE_IE_ASYNC_PVC, "Async PVC Status" }, { 0, NULL } }; /* array of 16 codepages - currently we only support codepage 1,5 */ static const struct tok *fr_q933_ie_codesets[] = { NULL, fr_q933_ie_values_codeset5, NULL, NULL, NULL, fr_q933_ie_values_codeset5, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static int fr_q933_print_ie_codeset5(const struct ie_tlv_header_t *ie_p, const u_char *p); typedef int (*codeset_pr_func_t)(const struct ie_tlv_header_t *ie_p, const u_char *p); /* array of 16 codepages - currently we only support codepage 1,5 */ static codeset_pr_func_t fr_q933_print_ie_codeset[] = { NULL, fr_q933_print_ie_codeset5, NULL, NULL, NULL, fr_q933_print_ie_codeset5, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; void q933_print(const u_char *p, u_int length) { const u_char *ptemp = p; struct ie_tlv_header_t *ie_p; int olen; int is_ansi = 0; u_int codeset; u_int ie_is_known = 0; if (length < 9) { /* shortest: Q.933a LINK VERIFY */ printf("[|q.933]"); return; } codeset = p[2]&0x0f; /* extract the codeset */ if (p[2] == MSG_ANSI_LOCKING_SHIFT) { is_ansi = 1; } printf("%s", eflag ? "" : "Q.933, "); /* printing out header part */ printf("%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset); if (p[0]) { printf(", Call Ref: 0x%02x", p[0]); } if (vflag) { printf(", %s (0x%02x), length %u", tok2str(fr_q933_msg_values, "unknown message", p[1]), p[1], length); } else { printf(", %s", tok2str(fr_q933_msg_values, "unknown message 0x%02x", p[1])); } olen = length; /* preserve the original length for non verbose mode */ if (length < (u_int)(2 - is_ansi)) { printf("[|q.933]"); return; } length -= 2 + is_ansi; ptemp += 2 + is_ansi; /* Loop through the rest of IE */ while (length > sizeof(struct ie_tlv_header_t)) { ie_p = (struct ie_tlv_header_t *)ptemp; if (length < sizeof(struct ie_tlv_header_t) || length < sizeof(struct ie_tlv_header_t) + ie_p->ie_len) { if (vflag) { /* not bark if there is just a trailer */ printf("\n[|q.933]"); } else { printf(", length %u",olen); } return; } /* lets do the full IE parsing only in verbose mode * however some IEs (DLCI Status, Link Verify) * are also interestting in non-verbose mode */ if (vflag) { printf("\n\t%s IE (0x%02x), length %u: ", tok2str(fr_q933_ie_codesets[codeset], "unknown", ie_p->ie_type), ie_p->ie_type, ie_p->ie_len); } /* sanity check */ if (ie_p->ie_type == 0 || ie_p->ie_len == 0) { return; } if (fr_q933_print_ie_codeset[codeset] != NULL) { ie_is_known = fr_q933_print_ie_codeset[codeset](ie_p, ptemp); } if (vflag >= 1 && !ie_is_known) { print_unknown_data(ptemp+2,"\n\t",ie_p->ie_len); } /* do we want to see a hexdump of the IE ? */ if (vflag> 1 && ie_is_known) { print_unknown_data(ptemp+2,"\n\t ",ie_p->ie_len); } length = length - ie_p->ie_len - 2; ptemp = ptemp + ie_p->ie_len + 2; } if (!vflag) { printf(", length %u",olen); } } static int fr_q933_print_ie_codeset5(const struct ie_tlv_header_t *ie_p, const u_char *p) { u_int dlci; switch (ie_p->ie_type) { case FR_LMI_ANSI_REPORT_TYPE_IE: /* fall through */ case FR_LMI_CCITT_REPORT_TYPE_IE: if (vflag) { printf("%s (%u)", tok2str(fr_lmi_report_type_ie_values,"unknown",p[2]), p[2]); } return 1; case FR_LMI_ANSI_LINK_VERIFY_IE: /* fall through */ case FR_LMI_CCITT_LINK_VERIFY_IE: case FR_LMI_ANSI_LINK_VERIFY_IE_91: if (!vflag) { printf(", "); } printf("TX Seq: %3d, RX Seq: %3d", p[2], p[3]); return 1; case FR_LMI_ANSI_PVC_STATUS_IE: /* fall through */ case FR_LMI_CCITT_PVC_STATUS_IE: if (!vflag) { printf(", "); } /* now parse the DLCI information element. */ if ((ie_p->ie_len < 3) || (p[2] & 0x80) || ((ie_p->ie_len == 3) && !(p[3] & 0x80)) || ((ie_p->ie_len == 4) && ((p[3] & 0x80) || !(p[4] & 0x80))) || ((ie_p->ie_len == 5) && ((p[3] & 0x80) || (p[4] & 0x80) || !(p[5] & 0x80))) || (ie_p->ie_len > 5) || !(p[ie_p->ie_len + 1] & 0x80)) { printf("Invalid DLCI IE"); } dlci = ((p[2] & 0x3F) << 4) | ((p[3] & 0x78) >> 3); if (ie_p->ie_len == 4) { dlci = (dlci << 6) | ((p[4] & 0x7E) >> 1); } else if (ie_p->ie_len == 5) { dlci = (dlci << 13) | (p[4] & 0x7F) | ((p[5] & 0x7E) >> 1); } printf("DLCI %u: status %s%s", dlci, p[ie_p->ie_len + 1] & 0x8 ? "New, " : "", p[ie_p->ie_len + 1] & 0x2 ? "Active" : "Inactive"); return 1; } return 0; } tcpdump-4.5.1/mptcp.h0000644000026300017510000001125112237020316012106 0ustar mcr/** * Copyright (c) 2012 * * Gregory Detal * Christoph Paasch * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #define MPTCP_SUB_CAPABLE 0x0 #define MPTCP_SUB_JOIN 0x1 #define MPTCP_SUB_DSS 0x2 #define MPTCP_SUB_ADD_ADDR 0x3 #define MPTCP_SUB_REMOVE_ADDR 0x4 #define MPTCP_SUB_PRIO 0x5 #define MPTCP_SUB_FAIL 0x6 #define MPTCP_SUB_FCLOSE 0x7 struct mptcp_option { u_int8_t kind; u_int8_t len; u_int8_t sub_etc; /* subtype upper 4 bits, other stuff lower 4 bits */ }; #define MPTCP_OPT_SUBTYPE(sub_etc) (((sub_etc) >> 4) & 0xF) struct mp_capable { u_int8_t kind; u_int8_t len; u_int8_t sub_ver; u_int8_t flags; u_int8_t sender_key[8]; u_int8_t receiver_key[8]; }; #define MP_CAPABLE_OPT_VERSION(sub_ver) (((sub_ver) >> 0) & 0xF) #define MP_CAPABLE_C 0x80 #define MP_CAPABLE_S 0x01 struct mp_join { u_int8_t kind; u_int8_t len; u_int8_t sub_b; u_int8_t addr_id; union { struct { u_int8_t token[4]; u_int8_t nonce[4]; } syn; struct { u_int8_t mac[8]; u_int8_t nonce[4]; } synack; struct { u_int8_t mac[20]; } ack; } u; }; #define MP_JOIN_B 0x01 struct mp_dss { u_int8_t kind; u_int8_t len; u_int8_t sub; u_int8_t flags; }; #define MP_DSS_F 0x10 #define MP_DSS_m 0x08 #define MP_DSS_M 0x04 #define MP_DSS_a 0x02 #define MP_DSS_A 0x01 struct mp_add_addr { u_int8_t kind; u_int8_t len; u_int8_t sub_ipver; u_int8_t addr_id; union { struct { u_int8_t addr[4]; u_int8_t port[2]; } v4; struct { u_int8_t addr[16]; u_int8_t port[2]; } v6; } u; }; #define MP_ADD_ADDR_IPVER(sub_ipver) (((sub_ipver) >> 0) & 0xF) struct mp_remove_addr { u_int8_t kind; u_int8_t len; u_int8_t sub; /* list of addr_id */ u_int8_t addrs_id; }; struct mp_fail { u_int8_t kind; u_int8_t len; u_int8_t sub; u_int8_t resv; u_int8_t data_seq[8]; }; struct mp_close { u_int8_t kind; u_int8_t len; u_int8_t sub; u_int8_t rsv; u_int8_t key[8]; }; struct mp_prio { u_int8_t kind; u_int8_t len; u_int8_t sub_b; u_int8_t addr_id; }; #define MP_PRIO_B 0x01 tcpdump-4.5.1/print-sunatm.c0000644000026300017510000000663712237020316013433 0ustar mcr/* * Copyright (c) 1997 Yen Yen Lim and North Dakota State University * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Yen Yen Lim and North Dakota State University * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-sunatm.c,v 1.8 2004-03-17 23:24:38 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include struct mbuf; struct rtentry; #include #include #include "interface.h" #include "extract.h" #include "addrtoname.h" #include "atm.h" #include "atmuni31.h" /* SunATM header for ATM packet */ #define DIR_POS 0 /* Direction (0x80 = transmit, 0x00 = receive) */ #define VPI_POS 1 /* VPI */ #define VCI_POS 2 /* VCI */ #define PKT_BEGIN_POS 4 /* Start of the ATM packet */ /* Protocol type values in the bottom for bits of the byte at SUNATM_DIR_POS. */ #define PT_LANE 0x01 /* LANE */ #define PT_LLC 0x02 /* LLC encapsulation */ /* * This is the top level routine of the printer. 'p' points * to the SunATM pseudo-header for the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ u_int sunatm_if_print(const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; u_short vci; u_char vpi; u_int traftype; if (caplen < PKT_BEGIN_POS) { printf("[|atm]"); return (caplen); } if (eflag) { if (p[DIR_POS] & 0x80) printf("Tx: "); else printf("Rx: "); } switch (p[DIR_POS] & 0x0f) { case PT_LANE: traftype = ATM_LANE; break; case PT_LLC: traftype = ATM_LLC; break; default: traftype = ATM_UNKNOWN; break; } vci = EXTRACT_16BITS(&p[VCI_POS]); vpi = p[VPI_POS]; p += PKT_BEGIN_POS; caplen -= PKT_BEGIN_POS; length -= PKT_BEGIN_POS; atm_print(vpi, vci, traftype, p, length, caplen); return (PKT_BEGIN_POS); } tcpdump-4.5.1/print-ospf.c0000644000026300017510000011271512237020316013066 0ustar mcr/* * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-ospf.c,v 1.66 2007-10-08 07:53:21 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" #include "gmpls.h" #include "ospf.h" #include "ip.h" static const struct tok ospf_option_values[] = { { OSPF_OPTION_T, "MultiTopology" }, /* draft-ietf-ospf-mt-09 */ { OSPF_OPTION_E, "External" }, { OSPF_OPTION_MC, "Multicast" }, { OSPF_OPTION_NP, "NSSA" }, { OSPF_OPTION_L, "LLS" }, { OSPF_OPTION_DC, "Demand Circuit" }, { OSPF_OPTION_O, "Opaque" }, { OSPF_OPTION_DN, "Up/Down" }, { 0, NULL } }; static const struct tok ospf_authtype_values[] = { { OSPF_AUTH_NONE, "none" }, { OSPF_AUTH_SIMPLE, "simple" }, { OSPF_AUTH_MD5, "MD5" }, { 0, NULL } }; static const struct tok ospf_rla_flag_values[] = { { RLA_FLAG_B, "ABR" }, { RLA_FLAG_E, "ASBR" }, { RLA_FLAG_W1, "Virtual" }, { RLA_FLAG_W2, "W2" }, { 0, NULL } }; static const struct tok type2str[] = { { OSPF_TYPE_UMD, "UMD" }, { OSPF_TYPE_HELLO, "Hello" }, { OSPF_TYPE_DD, "Database Description" }, { OSPF_TYPE_LS_REQ, "LS-Request" }, { OSPF_TYPE_LS_UPDATE, "LS-Update" }, { OSPF_TYPE_LS_ACK, "LS-Ack" }, { 0, NULL } }; static const struct tok lsa_values[] = { { LS_TYPE_ROUTER, "Router" }, { LS_TYPE_NETWORK, "Network" }, { LS_TYPE_SUM_IP, "Summary" }, { LS_TYPE_SUM_ABR, "ASBR Summary" }, { LS_TYPE_ASE, "External" }, { LS_TYPE_GROUP, "Multicast Group" }, { LS_TYPE_NSSA, "NSSA" }, { LS_TYPE_OPAQUE_LL, "Link Local Opaque" }, { LS_TYPE_OPAQUE_AL, "Area Local Opaque" }, { LS_TYPE_OPAQUE_DW, "Domain Wide Opaque" }, { 0, NULL } }; static const struct tok ospf_dd_flag_values[] = { { OSPF_DB_INIT, "Init" }, { OSPF_DB_MORE, "More" }, { OSPF_DB_MASTER, "Master" }, { OSPF_DB_RESYNC, "OOBResync" }, { 0, NULL } }; static const struct tok lsa_opaque_values[] = { { LS_OPAQUE_TYPE_TE, "Traffic Engineering" }, { LS_OPAQUE_TYPE_GRACE, "Graceful restart" }, { LS_OPAQUE_TYPE_RI, "Router Information" }, { 0, NULL } }; static const struct tok lsa_opaque_te_tlv_values[] = { { LS_OPAQUE_TE_TLV_ROUTER, "Router Address" }, { LS_OPAQUE_TE_TLV_LINK, "Link" }, { 0, NULL } }; static const struct tok lsa_opaque_te_link_tlv_subtlv_values[] = { { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE, "Link Type" }, { LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID, "Link ID" }, { LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP, "Local Interface IP address" }, { LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP, "Remote Interface IP address" }, { LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC, "Traffic Engineering Metric" }, { LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW, "Maximum Bandwidth" }, { LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW, "Maximum Reservable Bandwidth" }, { LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW, "Unreserved Bandwidth" }, { LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP, "Administrative Group" }, { LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" }, { LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE, "Link Protection Type" }, { LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, { LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP, "Shared Risk Link Group" }, { LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS, "Bandwidth Constraints" }, { 0, NULL } }; static const struct tok lsa_opaque_grace_tlv_values[] = { { LS_OPAQUE_GRACE_TLV_PERIOD, "Grace Period" }, { LS_OPAQUE_GRACE_TLV_REASON, "Graceful restart Reason" }, { LS_OPAQUE_GRACE_TLV_INT_ADDRESS, "IPv4 interface address" }, { 0, NULL } }; static const struct tok lsa_opaque_grace_tlv_reason_values[] = { { LS_OPAQUE_GRACE_TLV_REASON_UNKNOWN, "Unknown" }, { LS_OPAQUE_GRACE_TLV_REASON_SW_RESTART, "Software Restart" }, { LS_OPAQUE_GRACE_TLV_REASON_SW_UPGRADE, "Software Reload/Upgrade" }, { LS_OPAQUE_GRACE_TLV_REASON_CP_SWITCH, "Control Processor Switch" }, { 0, NULL } }; static const struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = { { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP, "Point-to-point" }, { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA, "Multi-Access" }, { 0, NULL } }; static const struct tok lsa_opaque_ri_tlv_values[] = { { LS_OPAQUE_RI_TLV_CAP, "Router Capabilities" }, { 0, NULL } }; static const struct tok lsa_opaque_ri_tlv_cap_values[] = { { 1, "Reserved" }, { 2, "Reserved" }, { 4, "Reserved" }, { 8, "Reserved" }, { 16, "graceful restart capable" }, { 32, "graceful restart helper" }, { 64, "Stub router support" }, { 128, "Traffic engineering" }, { 256, "p2p over LAN" }, { 512, "path computation server" }, { 0, NULL } }; static const struct tok ospf_lls_tlv_values[] = { { OSPF_LLS_EO, "Extended Options" }, { OSPF_LLS_MD5, "MD5 Authentication" }, { 0, NULL } }; static const struct tok ospf_lls_eo_options[] = { { OSPF_LLS_EO_LR, "LSDB resync" }, { OSPF_LLS_EO_RS, "Restart" }, { 0, NULL } }; static char tstr[] = " [|ospf2]"; static int ospf_print_lshdr(const struct lsa_hdr *); static const u_char *ospf_print_lsa(const struct lsa *); static int ospf_decode_v2(const struct ospfhdr *, const u_char *); static int ospf_decode_lls(const struct ospfhdr *, register u_int); int ospf_print_grace_lsa (const u_int8_t *tptr, u_int ls_length) { u_int tlv_type, tlv_length; while (ls_length > 0) { TCHECK2(*tptr, 4); if (ls_length < 4) { printf("\n\t Remaining LS length %u < 4", ls_length); return -1; } tlv_type = EXTRACT_16BITS(tptr); tlv_length = EXTRACT_16BITS(tptr+2); tptr+=4; ls_length-=4; printf("\n\t %s TLV (%u), length %u, value: ", tok2str(lsa_opaque_grace_tlv_values,"unknown",tlv_type), tlv_type, tlv_length); if (tlv_length > ls_length) { printf("\n\t Bogus length %u > %u", tlv_length, ls_length); return -1; } /* Infinite loop protection. */ if (tlv_type == 0 || tlv_length ==0) { return -1; } TCHECK2(*tptr, tlv_length); switch(tlv_type) { case LS_OPAQUE_GRACE_TLV_PERIOD: if (tlv_length != 4) { printf("\n\t Bogus length %u != 4", tlv_length); return -1; } printf("%us",EXTRACT_32BITS(tptr)); break; case LS_OPAQUE_GRACE_TLV_REASON: if (tlv_length != 1) { printf("\n\t Bogus length %u != 1", tlv_length); return -1; } printf("%s (%u)", tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", *tptr), *tptr); break; case LS_OPAQUE_GRACE_TLV_INT_ADDRESS: if (tlv_length != 4) { printf("\n\t Bogus length %u != 4", tlv_length); return -1; } printf("%s", ipaddr_string(tptr)); break; default: if (vflag <= 1) { if(!print_unknown_data(tptr,"\n\t ",tlv_length)) return -1; } break; } /* in OSPF everything has to be 32-bit aligned, including TLVs */ if (tlv_length%4 != 0) tlv_length+=4-(tlv_length%4); ls_length-=tlv_length; tptr+=tlv_length; } return 0; trunc: return -1; } int ospf_print_te_lsa (const u_int8_t *tptr, u_int ls_length) { u_int tlv_type, tlv_length, subtlv_type, subtlv_length; u_int priority_level, te_class, count_srlg; union { /* int to float conversion buffer for several subTLVs */ float f; u_int32_t i; } bw; while (ls_length != 0) { TCHECK2(*tptr, 4); if (ls_length < 4) { printf("\n\t Remaining LS length %u < 4", ls_length); return -1; } tlv_type = EXTRACT_16BITS(tptr); tlv_length = EXTRACT_16BITS(tptr+2); tptr+=4; ls_length-=4; printf("\n\t %s TLV (%u), length: %u", tok2str(lsa_opaque_te_tlv_values,"unknown",tlv_type), tlv_type, tlv_length); if (tlv_length > ls_length) { printf("\n\t Bogus length %u > %u", tlv_length, ls_length); return -1; } /* Infinite loop protection. */ if (tlv_type == 0 || tlv_length ==0) { return -1; } switch(tlv_type) { case LS_OPAQUE_TE_TLV_LINK: while (tlv_length >= sizeof(subtlv_type) + sizeof(subtlv_length)) { if (tlv_length < 4) { printf("\n\t Remaining TLV length %u < 4", tlv_length); return -1; } TCHECK2(*tptr, 4); subtlv_type = EXTRACT_16BITS(tptr); subtlv_length = EXTRACT_16BITS(tptr+2); tptr+=4; tlv_length-=4; printf("\n\t %s subTLV (%u), length: %u", tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type), subtlv_type, subtlv_length); TCHECK2(*tptr, subtlv_length); switch(subtlv_type) { case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP: printf(", 0x%08x", EXTRACT_32BITS(tptr)); break; case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID: case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID: printf(", %s (0x%08x)", ipaddr_string(tptr), EXTRACT_32BITS(tptr)); if (subtlv_length == 8) /* rfc4203 */ printf(", %s (0x%08x)", ipaddr_string(tptr+4), EXTRACT_32BITS(tptr+4)); break; case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP: case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP: printf(", %s", ipaddr_string(tptr)); break; case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW: case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW: bw.i = EXTRACT_32BITS(tptr); printf(", %.3f Mbps", bw.f*8/1000000 ); break; case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW: for (te_class = 0; te_class < 8; te_class++) { bw.i = EXTRACT_32BITS(tptr+te_class*4); printf("\n\t\tTE-Class %u: %.3f Mbps", te_class, bw.f*8/1000000 ); } break; case LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS: printf("\n\t\tBandwidth Constraints Model ID: %s (%u)", tok2str(diffserv_te_bc_values, "unknown", *tptr), *tptr); /* decode BCs until the subTLV ends */ for (te_class = 0; te_class < (subtlv_length-4)/4; te_class++) { bw.i = EXTRACT_32BITS(tptr+4+te_class*4); printf("\n\t\t Bandwidth constraint CT%u: %.3f Mbps", te_class, bw.f*8/1000000 ); } break; case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC: printf(", Metric %u", EXTRACT_32BITS(tptr)); break; case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE: printf(", %s, Priority %u", bittok2str(gmpls_link_prot_values, "none", *tptr), *(tptr+1)); break; case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR: printf("\n\t\tInterface Switching Capability: %s", tok2str(gmpls_switch_cap_values, "Unknown", *(tptr))); printf("\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:", tok2str(gmpls_encoding_values, "Unknown", *(tptr+1))); for (priority_level = 0; priority_level < 8; priority_level++) { bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4)); printf("\n\t\t priority level %d: %.3f Mbps", priority_level, bw.f*8/1000000 ); } break; case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE: printf(", %s (%u)", tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr), *tptr); break; case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP: count_srlg = subtlv_length / 4; if (count_srlg != 0) printf("\n\t\t Shared risk group: "); while (count_srlg > 0) { bw.i = EXTRACT_32BITS(tptr); printf("%d",bw.i); tptr+=4; count_srlg--; if (count_srlg > 0) printf(", "); } break; default: if (vflag <= 1) { if(!print_unknown_data(tptr,"\n\t\t",subtlv_length)) return -1; } break; } /* in OSPF everything has to be 32-bit aligned, including subTLVs */ if (subtlv_length%4 != 0) subtlv_length+=4-(subtlv_length%4); tlv_length-=subtlv_length; tptr+=subtlv_length; } break; case LS_OPAQUE_TE_TLV_ROUTER: if (tlv_length < 4) { printf("\n\t TLV length %u < 4", tlv_length); return -1; } TCHECK2(*tptr, 4); printf(", %s", ipaddr_string(tptr)); break; default: if (vflag <= 1) { if(!print_unknown_data(tptr,"\n\t ",tlv_length)) return -1; } break; } /* in OSPF everything has to be 32-bit aligned, including TLVs */ if (tlv_length%4 != 0) tlv_length+=4-(tlv_length%4); ls_length-=tlv_length; tptr+=tlv_length; } return 0; trunc: return -1; } static int ospf_print_lshdr(register const struct lsa_hdr *lshp) { u_int ls_length; TCHECK(lshp->ls_length); ls_length = EXTRACT_16BITS(&lshp->ls_length); if (ls_length < sizeof(struct lsa_hdr)) { printf("\n\t Bogus length %u < header (%lu)", ls_length, (unsigned long)sizeof(struct lsa_hdr)); return(-1); } TCHECK(lshp->ls_seq); /* XXX - ls_length check checked this */ printf("\n\t Advertising Router %s, seq 0x%08x, age %us, length %u", ipaddr_string(&lshp->ls_router), EXTRACT_32BITS(&lshp->ls_seq), EXTRACT_16BITS(&lshp->ls_age), ls_length-(u_int)sizeof(struct lsa_hdr)); TCHECK(lshp->ls_type); /* XXX - ls_length check checked this */ switch (lshp->ls_type) { /* the LSA header for opaque LSAs was slightly changed */ case LS_TYPE_OPAQUE_LL: case LS_TYPE_OPAQUE_AL: case LS_TYPE_OPAQUE_DW: printf("\n\t %s LSA (%d), Opaque-Type %s LSA (%u), Opaque-ID %u", tok2str(lsa_values,"unknown",lshp->ls_type), lshp->ls_type, tok2str(lsa_opaque_values, "unknown", *(&lshp->un_lsa_id.opaque_field.opaque_type)), *(&lshp->un_lsa_id.opaque_field.opaque_type), EXTRACT_24BITS(&lshp->un_lsa_id.opaque_field.opaque_id) ); break; /* all other LSA types use regular style LSA headers */ default: printf("\n\t %s LSA (%d), LSA-ID: %s", tok2str(lsa_values,"unknown",lshp->ls_type), lshp->ls_type, ipaddr_string(&lshp->un_lsa_id.lsa_id)); break; } TCHECK(lshp->ls_options); /* XXX - ls_length check checked this */ printf("\n\t Options: [%s]", bittok2str(ospf_option_values,"none",lshp->ls_options)); return (ls_length); trunc: return (-1); } /* draft-ietf-ospf-mt-09 */ static const struct tok ospf_topology_values[] = { { 0, "default " }, { 1, "multicast " }, { 2, "management " }, { 0, NULL } }; /* * Print all the per-topology metrics. */ static void ospf_print_tos_metrics(const union un_tos *tos) { int metric_count; int toscount; toscount = tos->link.link_tos_count+1; metric_count = 0; /* * All but the first metric contain a valid topology id. */ while (toscount) { printf("\n\t\ttopology %s(%u), metric %u", tok2str(ospf_topology_values, "", metric_count ? tos->metrics.tos_type : 0), metric_count ? tos->metrics.tos_type : 0, EXTRACT_16BITS(&tos->metrics.tos_metric)); metric_count++; tos++; toscount--; } } /* * Print a single link state advertisement. If truncated or if LSA length * field is less than the length of the LSA header, return NULl, else * return pointer to data past end of LSA. */ static const u_int8_t * ospf_print_lsa(register const struct lsa *lsap) { register const u_int8_t *ls_end; register const struct rlalink *rlp; register const struct in_addr *ap; register const struct aslametric *almp; register const struct mcla *mcp; register const u_int32_t *lp; register int j, tlv_type, tlv_length, topology; register int ls_length; const u_int8_t *tptr; tptr = (u_int8_t *)lsap->lsa_un.un_unknown; /* squelch compiler warnings */ ls_length = ospf_print_lshdr(&lsap->ls_hdr); if (ls_length == -1) return(NULL); ls_end = (u_int8_t *)lsap + ls_length; ls_length -= sizeof(struct lsa_hdr); switch (lsap->ls_hdr.ls_type) { case LS_TYPE_ROUTER: TCHECK(lsap->lsa_un.un_rla.rla_flags); printf("\n\t Router LSA Options: [%s]", bittok2str(ospf_rla_flag_values,"none",lsap->lsa_un.un_rla.rla_flags)); TCHECK(lsap->lsa_un.un_rla.rla_count); j = EXTRACT_16BITS(&lsap->lsa_un.un_rla.rla_count); TCHECK(lsap->lsa_un.un_rla.rla_link); rlp = lsap->lsa_un.un_rla.rla_link; while (j--) { TCHECK(*rlp); switch (rlp->un_tos.link.link_type) { case RLA_TYPE_VIRTUAL: printf("\n\t Virtual Link: Neighbor Router-ID: %s, Interface Address: %s", ipaddr_string(&rlp->link_id), ipaddr_string(&rlp->link_data)); break; case RLA_TYPE_ROUTER: printf("\n\t Neighbor Router-ID: %s, Interface Address: %s", ipaddr_string(&rlp->link_id), ipaddr_string(&rlp->link_data)); break; case RLA_TYPE_TRANSIT: printf("\n\t Neighbor Network-ID: %s, Interface Address: %s", ipaddr_string(&rlp->link_id), ipaddr_string(&rlp->link_data)); break; case RLA_TYPE_STUB: printf("\n\t Stub Network: %s, Mask: %s", ipaddr_string(&rlp->link_id), ipaddr_string(&rlp->link_data)); break; default: printf("\n\t Unknown Router Link Type (%u)", rlp->un_tos.link.link_type); return (ls_end); } ospf_print_tos_metrics(&rlp->un_tos); rlp = (struct rlalink *)((u_char *)(rlp + 1) + ((rlp->un_tos.link.link_tos_count) * sizeof(union un_tos))); } break; case LS_TYPE_NETWORK: TCHECK(lsap->lsa_un.un_nla.nla_mask); printf("\n\t Mask %s\n\t Connected Routers:", ipaddr_string(&lsap->lsa_un.un_nla.nla_mask)); ap = lsap->lsa_un.un_nla.nla_router; while ((u_char *)ap < ls_end) { TCHECK(*ap); printf("\n\t %s", ipaddr_string(ap)); ++ap; } break; case LS_TYPE_SUM_IP: TCHECK(lsap->lsa_un.un_nla.nla_mask); printf("\n\t Mask %s", ipaddr_string(&lsap->lsa_un.un_sla.sla_mask)); TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); lp = lsap->lsa_un.un_sla.sla_tosmetric; while ((u_char *)lp < ls_end) { register u_int32_t ul; TCHECK(*lp); ul = EXTRACT_32BITS(lp); topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; printf("\n\t\ttopology %s(%u) metric %d", tok2str(ospf_topology_values, "", topology), topology, ul & SLA_MASK_METRIC); ++lp; } break; case LS_TYPE_SUM_ABR: TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); lp = lsap->lsa_un.un_sla.sla_tosmetric; while ((u_char *)lp < ls_end) { register u_int32_t ul; TCHECK(*lp); ul = EXTRACT_32BITS(lp); topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; printf("\n\t\ttopology %s(%u) metric %d", tok2str(ospf_topology_values, "", topology), topology, ul & SLA_MASK_METRIC); ++lp; } break; case LS_TYPE_ASE: case LS_TYPE_NSSA: /* fall through - those LSAs share the same format */ TCHECK(lsap->lsa_un.un_nla.nla_mask); printf("\n\t Mask %s", ipaddr_string(&lsap->lsa_un.un_asla.asla_mask)); TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); almp = lsap->lsa_un.un_asla.asla_metric; while ((u_char *)almp < ls_end) { register u_int32_t ul; TCHECK(almp->asla_tosmetric); ul = EXTRACT_32BITS(&almp->asla_tosmetric); topology = ((ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS); printf("\n\t\ttopology %s(%u), type %d, metric", tok2str(ospf_topology_values, "", topology), topology, (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1); if ((ul & ASLA_MASK_METRIC)==0xffffff) printf(" infinite"); else printf(" %d", (ul & ASLA_MASK_METRIC)); TCHECK(almp->asla_forward); if (almp->asla_forward.s_addr) { printf(", forward %s", ipaddr_string(&almp->asla_forward)); } TCHECK(almp->asla_tag); if (almp->asla_tag.s_addr) { printf(", tag %s", ipaddr_string(&almp->asla_tag)); } ++almp; } break; case LS_TYPE_GROUP: /* Multicast extensions as of 23 July 1991 */ mcp = lsap->lsa_un.un_mcla; while ((u_char *)mcp < ls_end) { TCHECK(mcp->mcla_vid); switch (EXTRACT_32BITS(&mcp->mcla_vtype)) { case MCLA_VERTEX_ROUTER: printf("\n\t Router Router-ID %s", ipaddr_string(&mcp->mcla_vid)); break; case MCLA_VERTEX_NETWORK: printf("\n\t Network Designated Router %s", ipaddr_string(&mcp->mcla_vid)); break; default: printf("\n\t unknown VertexType (%u)", EXTRACT_32BITS(&mcp->mcla_vtype)); break; } ++mcp; } break; case LS_TYPE_OPAQUE_LL: /* fall through */ case LS_TYPE_OPAQUE_AL: case LS_TYPE_OPAQUE_DW: switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) { case LS_OPAQUE_TYPE_RI: tptr = (u_int8_t *)(&lsap->lsa_un.un_ri_tlv.type); while (ls_length != 0) { TCHECK2(*tptr, 4); if (ls_length < 4) { printf("\n\t Remaining LS length %u < 4", ls_length); return(ls_end); } tlv_type = EXTRACT_16BITS(tptr); tlv_length = EXTRACT_16BITS(tptr+2); tptr+=4; ls_length-=4; printf("\n\t %s TLV (%u), length: %u, value: ", tok2str(lsa_opaque_ri_tlv_values,"unknown",tlv_type), tlv_type, tlv_length); if (tlv_length > ls_length) { printf("\n\t Bogus length %u > %u", tlv_length, ls_length); return(ls_end); } TCHECK2(*tptr, tlv_length); switch(tlv_type) { case LS_OPAQUE_RI_TLV_CAP: if (tlv_length != 4) { printf("\n\t Bogus length %u != 4", tlv_length); return(ls_end); } printf("Capabilities: %s", bittok2str(lsa_opaque_ri_tlv_cap_values, "Unknown", EXTRACT_32BITS(tptr))); break; default: if (vflag <= 1) { if(!print_unknown_data(tptr,"\n\t ",tlv_length)) return(ls_end); } break; } tptr+=tlv_length; ls_length-=tlv_length; } break; case LS_OPAQUE_TYPE_GRACE: if (ospf_print_grace_lsa((u_int8_t *)(&lsap->lsa_un.un_grace_tlv.type), ls_length) == -1) { return(ls_end); } break; case LS_OPAQUE_TYPE_TE: if (ospf_print_te_lsa((u_int8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type), ls_length) == -1) { return(ls_end); } break; default: if (vflag <= 1) { if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown, "\n\t ", ls_length)) return(ls_end); } break; } } /* do we want to see an additionally hexdump ? */ if (vflag> 1) if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown, "\n\t ", ls_length)) { return(ls_end); } return (ls_end); trunc: return (NULL); } static int ospf_decode_lls(register const struct ospfhdr *op, register u_int length) { register const u_char *dptr; register const u_char *dataend; register u_int length2; register u_int16_t lls_type, lls_len; register u_int32_t lls_flags; switch (op->ospf_type) { case OSPF_TYPE_HELLO: if (!(op->ospf_hello.hello_options & OSPF_OPTION_L)) return (0); break; case OSPF_TYPE_DD: if (!(op->ospf_db.db_options & OSPF_OPTION_L)) return (0); break; default: return (0); } /* dig deeper if LLS data is available; see RFC4813 */ length2 = EXTRACT_16BITS(&op->ospf_len); dptr = (u_char *)op + length2; dataend = (u_char *)op + length; if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) { dptr = dptr + op->ospf_authdata[3]; length2 += op->ospf_authdata[3]; } if (length2 >= length) { printf("\n\t[LLS truncated]"); return (1); } TCHECK2(*dptr, 2); printf("\n\t LLS: checksum: 0x%04x", (u_int)EXTRACT_16BITS(dptr)); dptr += 2; TCHECK2(*dptr, 2); length2 = EXTRACT_16BITS(dptr); printf(", length: %u", length2); dptr += 2; TCHECK(*dptr); while (dptr < dataend) { TCHECK2(*dptr, 2); lls_type = EXTRACT_16BITS(dptr); printf("\n\t %s (%u)", tok2str(ospf_lls_tlv_values,"Unknown TLV",lls_type), lls_type); dptr += 2; TCHECK2(*dptr, 2); lls_len = EXTRACT_16BITS(dptr); printf(", length: %u", lls_len); dptr += 2; switch (lls_type) { case OSPF_LLS_EO: if (lls_len != 4) { printf(" [should be 4]"); lls_len = 4; } TCHECK2(*dptr, 4); lls_flags = EXTRACT_32BITS(dptr); printf("\n\t Options: 0x%08x [%s]", lls_flags, bittok2str(ospf_lls_eo_options,"?",lls_flags)); break; case OSPF_LLS_MD5: if (lls_len != 20) { printf(" [should be 20]"); lls_len = 20; } TCHECK2(*dptr, 4); printf("\n\t Sequence number: 0x%08x", EXTRACT_32BITS(dptr)); break; } dptr += lls_len; } return (0); trunc: return (1); } static int ospf_decode_v2(register const struct ospfhdr *op, register const u_char *dataend) { register const struct in_addr *ap; register const struct lsr *lsrp; register const struct lsa_hdr *lshp; register const struct lsa *lsap; register u_int32_t lsa_count,lsa_count_max; switch (op->ospf_type) { case OSPF_TYPE_UMD: /* * Rob Coltun's special monitoring packets; * do nothing */ break; case OSPF_TYPE_HELLO: printf("\n\tOptions [%s]", bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options)); TCHECK(op->ospf_hello.hello_deadint); printf("\n\t Hello Timer %us, Dead Timer %us, Mask %s, Priority %u", EXTRACT_16BITS(&op->ospf_hello.hello_helloint), EXTRACT_32BITS(&op->ospf_hello.hello_deadint), ipaddr_string(&op->ospf_hello.hello_mask), op->ospf_hello.hello_priority); TCHECK(op->ospf_hello.hello_dr); if (op->ospf_hello.hello_dr.s_addr != 0) printf("\n\t Designated Router %s", ipaddr_string(&op->ospf_hello.hello_dr)); TCHECK(op->ospf_hello.hello_bdr); if (op->ospf_hello.hello_bdr.s_addr != 0) printf(", Backup Designated Router %s", ipaddr_string(&op->ospf_hello.hello_bdr)); ap = op->ospf_hello.hello_neighbor; if ((u_char *)ap < dataend) printf("\n\t Neighbor List:"); while ((u_char *)ap < dataend) { TCHECK(*ap); printf("\n\t %s", ipaddr_string(ap)); ++ap; } break; /* HELLO */ case OSPF_TYPE_DD: TCHECK(op->ospf_db.db_options); printf("\n\tOptions [%s]", bittok2str(ospf_option_values,"none",op->ospf_db.db_options)); TCHECK(op->ospf_db.db_flags); printf(", DD Flags [%s]", bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags)); TCHECK(op->ospf_db.db_ifmtu); if (op->ospf_db.db_ifmtu) { printf(", MTU: %u", EXTRACT_16BITS(&op->ospf_db.db_ifmtu)); } TCHECK(op->ospf_db.db_seq); printf(", Sequence: 0x%08x", EXTRACT_32BITS(&op->ospf_db.db_seq)); /* Print all the LS adv's */ lshp = op->ospf_db.db_lshdr; while (((u_char *)lshp < dataend) && ospf_print_lshdr(lshp) != -1) { ++lshp; } break; case OSPF_TYPE_LS_REQ: lsrp = op->ospf_lsr; while ((u_char *)lsrp < dataend) { TCHECK(*lsrp); printf("\n\t Advertising Router: %s, %s LSA (%u)", ipaddr_string(&lsrp->ls_router), tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)), EXTRACT_32BITS(&lsrp->ls_type)); switch (EXTRACT_32BITS(lsrp->ls_type)) { /* the LSA header for opaque LSAs was slightly changed */ case LS_TYPE_OPAQUE_LL: case LS_TYPE_OPAQUE_AL: case LS_TYPE_OPAQUE_DW: printf(", Opaque-Type: %s LSA (%u), Opaque-ID: %u", tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type), lsrp->un_ls_stateid.opaque_field.opaque_type, EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id)); break; default: printf(", LSA-ID: %s", ipaddr_string(&lsrp->un_ls_stateid.ls_stateid)); break; } ++lsrp; } break; case OSPF_TYPE_LS_UPDATE: lsap = op->ospf_lsu.lsu_lsa; TCHECK(op->ospf_lsu.lsu_count); lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count); printf(", %d LSA%s",lsa_count_max, PLURAL_SUFFIX(lsa_count_max)); for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) { printf("\n\t LSA #%u",lsa_count); lsap = (const struct lsa *)ospf_print_lsa(lsap); if (lsap == NULL) goto trunc; } break; case OSPF_TYPE_LS_ACK: lshp = op->ospf_lsa.lsa_lshdr; while (ospf_print_lshdr(lshp) != -1) { ++lshp; } break; default: break; } return (0); trunc: return (1); } void ospf_print(register const u_char *bp, register u_int length, const u_char *bp2 _U_) { register const struct ospfhdr *op; register const u_char *dataend; register const char *cp; op = (struct ospfhdr *)bp; /* XXX Before we do anything else, strip off the MD5 trailer */ TCHECK(op->ospf_authtype); if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) { length -= OSPF_AUTH_MD5_LEN; snapend -= OSPF_AUTH_MD5_LEN; } /* If the type is valid translate it, or just print the type */ /* value. If it's not valid, say so and return */ TCHECK(op->ospf_type); cp = tok2str(type2str, "unknown LS-type", op->ospf_type); printf("OSPFv%u, %s, length %u", op->ospf_version, cp, length); if (*cp == 'u') return; if(!vflag) { /* non verbose - so lets bail out here */ return; } TCHECK(op->ospf_len); if (length != EXTRACT_16BITS(&op->ospf_len)) { printf(" [len %d]", EXTRACT_16BITS(&op->ospf_len)); } if (length > EXTRACT_16BITS(&op->ospf_len)) { dataend = bp + EXTRACT_16BITS(&op->ospf_len); } else { dataend = bp + length; } TCHECK(op->ospf_routerid); printf("\n\tRouter-ID %s", ipaddr_string(&op->ospf_routerid)); TCHECK(op->ospf_areaid); if (op->ospf_areaid.s_addr != 0) printf(", Area %s", ipaddr_string(&op->ospf_areaid)); else printf(", Backbone Area"); if (vflag) { /* Print authentication data (should we really do this?) */ TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata)); printf(", Authentication Type: %s (%u)", tok2str(ospf_authtype_values,"unknown",EXTRACT_16BITS(&op->ospf_authtype)), EXTRACT_16BITS(&op->ospf_authtype)); switch (EXTRACT_16BITS(&op->ospf_authtype)) { case OSPF_AUTH_NONE: break; case OSPF_AUTH_SIMPLE: printf("\n\tSimple text password: "); safeputs((const char *)op->ospf_authdata, OSPF_AUTH_SIMPLE_LEN); break; case OSPF_AUTH_MD5: printf("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x", *((op->ospf_authdata)+2), *((op->ospf_authdata)+3), EXTRACT_32BITS((op->ospf_authdata)+4)); break; default: return; } } /* Do rest according to version. */ switch (op->ospf_version) { case 2: /* ospf version 2 */ if (ospf_decode_v2(op, dataend)) goto trunc; if (length > EXTRACT_16BITS(&op->ospf_len)) { if (ospf_decode_lls(op, length)) goto trunc; } break; default: printf(" ospf [version %d]", op->ospf_version); break; } /* end switch on version */ return; trunc: fputs(tstr, stdout); } tcpdump-4.5.1/print-aodv.c0000644000026300017510000003041612237020316013045 0ustar mcr/* * Copyright (c) 2003 Bruce M. Simpson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bruce M. Simpson. * 4. Neither the name of Bruce M. Simpson nor the names of co- * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bruce M. Simpson OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/print-aodv.c,v 1.11 2004-03-24 00:30:19 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "interface.h" #include "addrtoname.h" #include "extract.h" /* must come after interface.h */ #include "aodv.h" static void aodv_extension(const struct aodv_ext *ep, u_int length) { u_int i; const struct aodv_hello *ah; switch (ep->type) { case AODV_EXT_HELLO: if (snapend < (u_char *) ep) { printf(" [|hello]"); return; } i = min(length, (u_int)(snapend - (u_char *)ep)); if (i < sizeof(struct aodv_hello)) { printf(" [|hello]"); return; } i -= sizeof(struct aodv_hello); ah = (void *)ep; printf("\n\text HELLO %ld ms", (unsigned long)EXTRACT_32BITS(&ah->interval)); break; default: printf("\n\text %u %u", ep->type, ep->length); break; } } static void aodv_rreq(const union aodv *ap, const u_char *dat, u_int length) { u_int i; if (snapend < dat) { printf(" [|aodv]"); return; } i = min(length, (u_int)(snapend - dat)); if (i < sizeof(ap->rreq)) { printf(" [|rreq]"); return; } i -= sizeof(ap->rreq); printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n" "\tdst %s seq %lu src %s seq %lu", length, ap->rreq.rreq_type & RREQ_JOIN ? "[J]" : "", ap->rreq.rreq_type & RREQ_REPAIR ? "[R]" : "", ap->rreq.rreq_type & RREQ_GRAT ? "[G]" : "", ap->rreq.rreq_type & RREQ_DEST ? "[D]" : "", ap->rreq.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", ap->rreq.rreq_hops, (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_id), ipaddr_string(&ap->rreq.rreq_da), (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_ds), ipaddr_string(&ap->rreq.rreq_oa), (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_os)); if (i >= sizeof(struct aodv_ext)) aodv_extension((void *)(&ap->rreq + 1), i); } static void aodv_rrep(const union aodv *ap, const u_char *dat, u_int length) { u_int i; if (snapend < dat) { printf(" [|aodv]"); return; } i = min(length, (u_int)(snapend - dat)); if (i < sizeof(ap->rrep)) { printf(" [|rrep]"); return; } i -= sizeof(ap->rrep); printf(" rrep %u %s%sprefix %u hops %u\n" "\tdst %s dseq %lu src %s %lu ms", length, ap->rrep.rrep_type & RREP_REPAIR ? "[R]" : "", ap->rrep.rrep_type & RREP_ACK ? "[A] " : " ", ap->rrep.rrep_ps & RREP_PREFIX_MASK, ap->rrep.rrep_hops, ipaddr_string(&ap->rrep.rrep_da), (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_ds), ipaddr_string(&ap->rrep.rrep_oa), (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_life)); if (i >= sizeof(struct aodv_ext)) aodv_extension((void *)(&ap->rrep + 1), i); } static void aodv_rerr(const union aodv *ap, const u_char *dat, u_int length) { u_int i; const struct rerr_unreach *dp = NULL; int n, trunc; if (snapend < dat) { printf(" [|aodv]"); return; } i = min(length, (u_int)(snapend - dat)); if (i < offsetof(struct aodv_rerr, r)) { printf(" [|rerr]"); return; } i -= offsetof(struct aodv_rerr, r); dp = &ap->rerr.r.dest[0]; n = ap->rerr.rerr_dc * sizeof(ap->rerr.r.dest[0]); printf(" rerr %s [items %u] [%u]:", ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", ap->rerr.rerr_dc, length); trunc = n - (i/sizeof(ap->rerr.r.dest[0])); for (; i >= sizeof(ap->rerr.r.dest[0]); ++dp, i -= sizeof(ap->rerr.r.dest[0])) { printf(" {%s}(%ld)", ipaddr_string(&dp->u_da), (unsigned long)EXTRACT_32BITS(&dp->u_ds)); } if (trunc) printf("[|rerr]"); } static void #ifdef INET6 aodv_v6_rreq(const union aodv *ap, const u_char *dat, u_int length) #else aodv_v6_rreq(const union aodv *ap _U_, const u_char *dat _U_, u_int length) #endif { #ifdef INET6 u_int i; if (snapend < dat) { printf(" [|aodv]"); return; } i = min(length, (u_int)(snapend - dat)); if (i < sizeof(ap->rreq6)) { printf(" [|rreq6]"); return; } i -= sizeof(ap->rreq6); printf(" v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n" "\tdst %s seq %lu src %s seq %lu", length, ap->rreq6.rreq_type & RREQ_JOIN ? "[J]" : "", ap->rreq6.rreq_type & RREQ_REPAIR ? "[R]" : "", ap->rreq6.rreq_type & RREQ_GRAT ? "[G]" : "", ap->rreq6.rreq_type & RREQ_DEST ? "[D]" : "", ap->rreq6.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", ap->rreq6.rreq_hops, (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_id), ip6addr_string(&ap->rreq6.rreq_da), (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_ds), ip6addr_string(&ap->rreq6.rreq_oa), (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_os)); if (i >= sizeof(struct aodv_ext)) aodv_extension((void *)(&ap->rreq6 + 1), i); #else printf(" v6 rreq %u", length); #endif } static void #ifdef INET6 aodv_v6_rrep(const union aodv *ap, const u_char *dat, u_int length) #else aodv_v6_rrep(const union aodv *ap _U_, const u_char *dat _U_, u_int length) #endif { #ifdef INET6 u_int i; if (snapend < dat) { printf(" [|aodv]"); return; } i = min(length, (u_int)(snapend - dat)); if (i < sizeof(ap->rrep6)) { printf(" [|rrep6]"); return; } i -= sizeof(ap->rrep6); printf(" rrep %u %s%sprefix %u hops %u\n" "\tdst %s dseq %lu src %s %lu ms", length, ap->rrep6.rrep_type & RREP_REPAIR ? "[R]" : "", ap->rrep6.rrep_type & RREP_ACK ? "[A] " : " ", ap->rrep6.rrep_ps & RREP_PREFIX_MASK, ap->rrep6.rrep_hops, ip6addr_string(&ap->rrep6.rrep_da), (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_ds), ip6addr_string(&ap->rrep6.rrep_oa), (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_life)); if (i >= sizeof(struct aodv_ext)) aodv_extension((void *)(&ap->rrep6 + 1), i); #else printf(" rrep %u", length); #endif } static void #ifdef INET6 aodv_v6_rerr(const union aodv *ap, u_int length) #else aodv_v6_rerr(const union aodv *ap _U_, u_int length) #endif { #ifdef INET6 const struct rerr_unreach6 *dp6 = NULL; int i, j, n, trunc; i = length - offsetof(struct aodv_rerr, r); j = sizeof(ap->rerr.r.dest6[0]); dp6 = &ap->rerr.r.dest6[0]; n = ap->rerr.rerr_dc * j; printf(" rerr %s [items %u] [%u]:", ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", ap->rerr.rerr_dc, length); trunc = n - (i/j); for (; i -= j >= 0; ++dp6) { printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da), (unsigned long)EXTRACT_32BITS(&dp6->u_ds)); } if (trunc) printf("[|rerr]"); #else printf(" rerr %u", length); #endif } static void #ifdef INET6 aodv_v6_draft_01_rreq(const union aodv *ap, const u_char *dat, u_int length) #else aodv_v6_draft_01_rreq(const union aodv *ap _U_, const u_char *dat _U_, u_int length) #endif { #ifdef INET6 u_int i; if (snapend < dat) { printf(" [|aodv]"); return; } i = min(length, (u_int)(snapend - dat)); if (i < sizeof(ap->rreq6_draft_01)) { printf(" [|rreq6]"); return; } i -= sizeof(ap->rreq6_draft_01); printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n" "\tdst %s seq %lu src %s seq %lu", length, ap->rreq6_draft_01.rreq_type & RREQ_JOIN ? "[J]" : "", ap->rreq6_draft_01.rreq_type & RREQ_REPAIR ? "[R]" : "", ap->rreq6_draft_01.rreq_type & RREQ_GRAT ? "[G]" : "", ap->rreq6_draft_01.rreq_type & RREQ_DEST ? "[D]" : "", ap->rreq6_draft_01.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", ap->rreq6_draft_01.rreq_hops, (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_id), ip6addr_string(&ap->rreq6_draft_01.rreq_da), (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_ds), ip6addr_string(&ap->rreq6_draft_01.rreq_oa), (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_os)); if (i >= sizeof(struct aodv_ext)) aodv_extension((void *)(&ap->rreq6_draft_01 + 1), i); #else printf(" rreq %u", length); #endif } static void #ifdef INET6 aodv_v6_draft_01_rrep(const union aodv *ap, const u_char *dat, u_int length) #else aodv_v6_draft_01_rrep(const union aodv *ap _U_, const u_char *dat _U_, u_int length) #endif { #ifdef INET6 u_int i; if (snapend < dat) { printf(" [|aodv]"); return; } i = min(length, (u_int)(snapend - dat)); if (i < sizeof(ap->rrep6_draft_01)) { printf(" [|rrep6]"); return; } i -= sizeof(ap->rrep6_draft_01); printf(" rrep %u %s%sprefix %u hops %u\n" "\tdst %s dseq %lu src %s %lu ms", length, ap->rrep6_draft_01.rrep_type & RREP_REPAIR ? "[R]" : "", ap->rrep6_draft_01.rrep_type & RREP_ACK ? "[A] " : " ", ap->rrep6_draft_01.rrep_ps & RREP_PREFIX_MASK, ap->rrep6_draft_01.rrep_hops, ip6addr_string(&ap->rrep6_draft_01.rrep_da), (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_ds), ip6addr_string(&ap->rrep6_draft_01.rrep_oa), (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_life)); if (i >= sizeof(struct aodv_ext)) aodv_extension((void *)(&ap->rrep6_draft_01 + 1), i); #else printf(" rrep %u", length); #endif } static void #ifdef INET6 aodv_v6_draft_01_rerr(const union aodv *ap, u_int length) #else aodv_v6_draft_01_rerr(const union aodv *ap _U_, u_int length) #endif { #ifdef INET6 const struct rerr_unreach6_draft_01 *dp6 = NULL; int i, j, n, trunc; i = length - offsetof(struct aodv_rerr, r); j = sizeof(ap->rerr.r.dest6_draft_01[0]); dp6 = &ap->rerr.r.dest6_draft_01[0]; n = ap->rerr.rerr_dc * j; printf(" rerr %s [items %u] [%u]:", ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", ap->rerr.rerr_dc, length); trunc = n - (i/j); for (; i -= j >= 0; ++dp6) { printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da), (unsigned long)EXTRACT_32BITS(&dp6->u_ds)); } if (trunc) printf("[|rerr]"); #else printf(" rerr %u", length); #endif } void aodv_print(const u_char *dat, u_int length, int is_ip6) { const union aodv *ap; ap = (union aodv *)dat; if (snapend < dat) { printf(" [|aodv]"); return; } if (min(length, (u_int)(snapend - dat)) < sizeof(ap->rrep_ack)) { printf(" [|aodv]"); return; } printf(" aodv"); switch (ap->rerr.rerr_type) { case AODV_RREQ: if (is_ip6) aodv_v6_rreq(ap, dat, length); else aodv_rreq(ap, dat, length); break; case AODV_RREP: if (is_ip6) aodv_v6_rrep(ap, dat, length); else aodv_rrep(ap, dat, length); break; case AODV_RERR: if (is_ip6) aodv_v6_rerr(ap, length); else aodv_rerr(ap, dat, length); break; case AODV_RREP_ACK: printf(" rrep-ack %u", length); break; case AODV_V6_DRAFT_01_RREQ: aodv_v6_draft_01_rreq(ap, dat, length); break; case AODV_V6_DRAFT_01_RREP: aodv_v6_draft_01_rrep(ap, dat, length); break; case AODV_V6_DRAFT_01_RERR: aodv_v6_draft_01_rerr(ap, length); break; case AODV_V6_DRAFT_01_RREP_ACK: printf(" rrep-ack %u", length); break; default: printf(" %u %u", ap->rreq.rreq_type, length); } } tcpdump-4.5.1/strcasecmp.c0000644000026300017510000000676712237020316013142 0ustar mcr/* * Copyright (c) 1987 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of California at Berkeley. The name of the University * may not be used to endorse or promote products derived from this * software without specific written prior permission. This software * is provided ``as is'' without express or implied warranty. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef lint static const char rcsid[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/strcasecmp.c,v 1.6 2003-11-16 09:36:43 guy Exp $"; #endif #include #include "interface.h" /* * This array is designed for mapping upper and lower case letter * together for a case independent comparison. The mappings are * based upon ascii character sequences. */ static const u_char charmap[] = { '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337', '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', }; int strcasecmp(s1, s2) const char *s1, *s2; { register const u_char *cm = charmap, *us1 = (u_char *)s1, *us2 = (u_char *)s2; while (cm[*us1] == cm[*us2++]) if (*us1++ == '\0') return(0); return(cm[*us1] - cm[*--us2]); } int strncasecmp(s1, s2, n) const char *s1, *s2; register int n; { register const u_char *cm = charmap, *us1 = (u_char *)s1, *us2 = (u_char *)s2; while (--n >= 0 && cm[*us1] == cm[*us2++]) if (*us1++ == '\0') return(0); return(n < 0 ? 0 : cm[*us1] - cm[*--us2]); } tcpdump-4.5.1/README.md0000644000026300017510000002302712237020316012075 0ustar mcr# tcpdump [![Build Status](https://travis-ci.org/the-tcpdump-group/tcpdump.png)](https://travis-ci.org/the-tcpdump-group/tcpdump) TCPDUMP 4.x.y Now maintained by "The Tcpdump Group" See www.tcpdump.org Please send inquiries/comments/reports to: * tcpdump-workers@lists.tcpdump.org Anonymous Git is available via: git clone git://bpf.tcpdump.org/tcpdump Please submit patches by forking the branch on GitHub at: * http://github.com/the-tcpdump-group/tcpdump/tree/master and issuing a pull request. formerly from Lawrence Berkeley National Laboratory Network Research Group ftp://ftp.ee.lbl.gov/old/tcpdump.tar.Z (3.4) This directory contains source code for tcpdump, a tool for network monitoring and data acquisition. This software was originally developed by the Network Research Group at the Lawrence Berkeley National Laboratory. The original distribution is available via anonymous ftp to `ftp.ee.lbl.gov`, in `tcpdump.tar.Z`. More recent development is performed at tcpdump.org, http://www.tcpdump.org/ Tcpdump uses libpcap, a system-independent interface for user-level packet capture. Before building tcpdump, you must first retrieve and build libpcap, also originally from LBL and now being maintained by tcpdump.org; see http://www.tcpdump.org/ . Once libpcap is built (either install it or make sure it's in `../libpcap`), you can build tcpdump using the procedure in the `INSTALL.txt` file. The program is loosely based on SMI's "etherfind" although none of the etherfind code remains. It was originally written by Van Jacobson as part of an ongoing research project to investigate and improve tcp and internet gateway performance. The parts of the program originally taken from Sun's etherfind were later re-written by Steven McCanne of LBL. To insure that there would be no vestige of proprietary code in tcpdump, Steve wrote these pieces from the specification given by the manual entry, with no access to the source of tcpdump or etherfind. Over the past few years, tcpdump has been steadily improved by the excellent contributions from the Internet community (just browse through the `CHANGES` file). We are grateful for all the input. Richard Stevens gives an excellent treatment of the Internet protocols in his book *"TCP/IP Illustrated, Volume 1"*. If you want to learn more about tcpdump and how to interpret its output, pick up this book. Some tools for viewing and analyzing tcpdump trace files are available from the Internet Traffic Archive: * http://www.acm.org/sigcomm/ITA/ Another tool that tcpdump users might find useful is tcpslice: * https://github.com/the-tcpdump-group/tcpslice It is a program that can be used to extract portions of tcpdump binary trace files. See the above distribution for further details and documentation. Problems, bugs, questions, desirable enhancements, etc. should be sent to the address "tcpdump-workers@lists.tcpdump.org". Bugs, support requests, and feature requests may also be submitted on the GitHub issue tracker for tcpdump at: * https://github.com/the-tcpdump-group/tcpdump/issues Source code contributions, etc. should be sent to the email address above or submitted by forking the branch on GitHub at: * http://github.com/the-tcpdump-group/tcpdump/tree/master and issuing a pull request. Current versions can be found at www.tcpdump.org. - The TCPdump team original text by: Steve McCanne, Craig Leres, Van Jacobson ------------------------------------- ``` This directory also contains some short awk programs intended as examples of ways to reduce tcpdump data when you're tracking particular network problems: send-ack.awk Simplifies the tcpdump trace for an ftp (or other unidirectional tcp transfer). Since we assume that one host only sends and the other only acks, all address information is left off and we just note if the packet is a "send" or an "ack". There is one output line per line of the original trace. Field 1 is the packet time in decimal seconds, relative to the start of the conversation. Field 2 is delta-time from last packet. Field 3 is packet type/direction. "Send" means data going from sender to receiver, "ack" means an ack going from the receiver to the sender. A preceding "*" indicates that the data is a retransmission. A preceding "-" indicates a hole in the sequence space (i.e., missing packet(s)), a "#" means an odd-size (not max seg size) packet. Field 4 has the packet flags (same format as raw trace). Field 5 is the sequence number (start seq. num for sender, next expected seq number for acks). The number in parens following an ack is the delta-time from the first send of the packet to the ack. A number in parens following a send is the delta-time from the first send of the packet to the current send (on duplicate packets only). Duplicate sends or acks have a number in square brackets showing the number of duplicates so far. Here is a short sample from near the start of an ftp: 3.00 0.20 send . 512 3.20 0.20 ack . 1024 (0.20) 3.20 0.00 send P 1024 3.40 0.20 ack . 1536 (0.20) 3.80 0.40 * send . 0 (3.80) [2] 3.82 0.02 * ack . 1536 (0.62) [2] Three seconds into the conversation, bytes 512 through 1023 were sent. 200ms later they were acked. Shortly thereafter bytes 1024-1535 were sent and again acked after 200ms. Then, for no apparent reason, 0-511 is retransmitted, 3.8 seconds after its initial send (the round trip time for this ftp was 1sec, +-500ms). Since the receiver is expecting 1536, 1536 is re-acked when 0 arrives. packetdat.awk Computes chunk summary data for an ftp (or similar unidirectional tcp transfer). [A "chunk" refers to a chunk of the sequence space -- essentially the packet sequence number divided by the max segment size.] A summary line is printed showing the number of chunks, the number of packets it took to send that many chunks (if there are no lost or duplicated packets, the number of packets should equal the number of chunks) and the number of acks. Following the summary line is one line of information per chunk. The line contains eight fields: 1 - the chunk number 2 - the start sequence number for this chunk 3 - time of first send 4 - time of last send 5 - time of first ack 6 - time of last ack 7 - number of times chunk was sent 8 - number of times chunk was acked (all times are in decimal seconds, relative to the start of the conversation.) As an example, here is the first part of the output for an ftp trace: # 134 chunks. 536 packets sent. 508 acks. 1 1 0.00 5.80 0.20 0.20 4 1 2 513 0.28 6.20 0.40 0.40 4 1 3 1025 1.16 6.32 1.20 1.20 4 1 4 1561 1.86 15.00 2.00 2.00 6 1 5 2049 2.16 15.44 2.20 2.20 5 1 6 2585 2.64 16.44 2.80 2.80 5 1 7 3073 3.00 16.66 3.20 3.20 4 1 8 3609 3.20 17.24 3.40 5.82 4 11 9 4097 6.02 6.58 6.20 6.80 2 5 This says that 134 chunks were transferred (about 70K since the average packet size was 512 bytes). It took 536 packets to transfer the data (i.e., on the average each chunk was transmitted four times). Looking at, say, chunk 4, we see it represents the 512 bytes of sequence space from 1561 to 2048. It was first sent 1.86 seconds into the conversation. It was last sent 15 seconds into the conversation and was sent a total of 6 times (i.e., it was retransmitted every 2 seconds on the average). It was acked once, 140ms after it first arrived. stime.awk atime.awk Output one line per send or ack, respectively, in the form