diff options
Diffstat (limited to 'freebsd/contrib/tcpdump')
221 files changed, 89361 insertions, 0 deletions
diff --git a/freebsd/contrib/tcpdump/addrtoname.c b/freebsd/contrib/tcpdump/addrtoname.c new file mode 100644 index 00000000..cd5963d5 --- /dev/null +++ b/freebsd/contrib/tcpdump/addrtoname.c @@ -0,0 +1,1218 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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. + * + * Internet, ethernet, port, and protocol string to address + * and address to string conversion routines + * + * $FreeBSD$ + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.119 2007-08-08 14:06:34 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#ifdef USE_ETHER_NTOHOST +#ifdef HAVE_NETINET_IF_ETHER_H +struct mbuf; /* Squelch compiler warnings on some platforms for */ +struct rtentry; /* declarations in <net/if.h> */ +#include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */ +#include <netinet/if_ether.h> +#endif /* HAVE_NETINET_IF_ETHER_H */ +#ifdef NETINET_ETHER_H_DECLARES_ETHER_NTOHOST +#include <netinet/ether.h> +#endif /* NETINET_ETHER_H_DECLARES_ETHER_NTOHOST */ + +#if !defined(HAVE_DECL_ETHER_NTOHOST) || !HAVE_DECL_ETHER_NTOHOST +#ifndef HAVE_STRUCT_ETHER_ADDR +struct ether_addr { + unsigned char ether_addr_octet[6]; +}; +#endif +extern int ether_ntohost(char *, const struct ether_addr *); +#endif + +#endif /* USE_ETHER_NTOHOST */ + +#include <pcap.h> +#include <pcap-namedb.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "interface.h" +#include "addrtoname.h" +#include "llc.h" +#include "setsignal.h" +#include "extract.h" +#include "oui.h" + +#ifndef ETHER_ADDR_LEN +#define ETHER_ADDR_LEN 6 +#endif + +/* + * hash tables for whatever-to-name translations + * + * XXX there has to be error checks against strdup(3) failure + */ + +#define HASHNAMESIZE 4096 + +struct hnamemem { + u_int32_t addr; + const char *name; + struct hnamemem *nxt; +}; + +static struct hnamemem hnametable[HASHNAMESIZE]; +static struct hnamemem tporttable[HASHNAMESIZE]; +static struct hnamemem uporttable[HASHNAMESIZE]; +static struct hnamemem eprototable[HASHNAMESIZE]; +static struct hnamemem dnaddrtable[HASHNAMESIZE]; +static struct hnamemem ipxsaptable[HASHNAMESIZE]; + +#if defined(INET6) && defined(WIN32) +/* + * fake gethostbyaddr for Win2k/XP + * gethostbyaddr() returns incorrect value when AF_INET6 is passed + * to 3rd argument. + * + * h_name in struct hostent is only valid. + */ +static struct hostent * +win32_gethostbyaddr(const char *addr, int len, int type) +{ + static struct hostent host; + static char hostbuf[NI_MAXHOST]; + char hname[NI_MAXHOST]; + struct sockaddr_in6 addr6; + + host.h_name = hostbuf; + switch (type) { + case AF_INET: + return gethostbyaddr(addr, len, type); + break; + case AF_INET6: + memset(&addr6, 0, sizeof(addr6)); + addr6.sin6_family = AF_INET6; + memcpy(&addr6.sin6_addr, addr, len); + if (getnameinfo((struct sockaddr *)&addr6, sizeof(addr6), + hname, sizeof(hname), NULL, 0, 0)) { + return NULL; + } else { + strcpy(host.h_name, hname); + return &host; + } + break; + default: + return NULL; + } +} +#define gethostbyaddr win32_gethostbyaddr +#endif /* INET6 & WIN32 */ + +#ifdef INET6 +struct h6namemem { + struct in6_addr addr; + char *name; + struct h6namemem *nxt; +}; + +static struct h6namemem h6nametable[HASHNAMESIZE]; +#endif /* INET6 */ + +struct enamemem { + u_short e_addr0; + u_short e_addr1; + u_short e_addr2; + const char *e_name; + u_char *e_nsap; /* used only for nsaptable[] */ +#define e_bs e_nsap /* for bytestringtable */ + struct enamemem *e_nxt; +}; + +static struct enamemem enametable[HASHNAMESIZE]; +static struct enamemem nsaptable[HASHNAMESIZE]; +static struct enamemem bytestringtable[HASHNAMESIZE]; + +struct protoidmem { + u_int32_t p_oui; + u_short p_proto; + const char *p_name; + struct protoidmem *p_nxt; +}; + +static struct protoidmem protoidtable[HASHNAMESIZE]; + +/* + * A faster replacement for inet_ntoa(). + */ +const char * +intoa(u_int32_t addr) +{ + register char *cp; + register u_int byte; + register int n; + static char buf[sizeof(".xxx.xxx.xxx.xxx")]; + + NTOHL(addr); + cp = buf + sizeof(buf); + *--cp = '\0'; + + n = 4; + do { + byte = addr & 0xff; + *--cp = byte % 10 + '0'; + byte /= 10; + if (byte > 0) { + *--cp = byte % 10 + '0'; + byte /= 10; + if (byte > 0) + *--cp = byte + '0'; + } + *--cp = '.'; + addr >>= 8; + } while (--n > 0); + + return cp + 1; +} + +static u_int32_t f_netmask; +static u_int32_t f_localnet; + +/* + * Return a name for the IP address pointed to by ap. This address + * is assumed to be in network byte order. + * + * NOTE: ap is *NOT* necessarily part of the packet data (not even if + * this is being called with the "ipaddr_string()" macro), so you + * *CANNOT* use the TCHECK{2}/TTEST{2} macros on it. Furthermore, + * even in cases where it *is* part of the packet data, the caller + * would still have to check for a null return value, even if it's + * just printing the return value with "%s" - not all versions of + * printf print "(null)" with "%s" and a null pointer, some of them + * don't check for a null pointer and crash in that case. + * + * The callers of this routine should, before handing this routine + * a pointer to packet data, be sure that the data is present in + * the packet buffer. They should probably do those checks anyway, + * as other data at that layer might not be IP addresses, and it + * also needs to check whether they're present in the packet buffer. + */ +const char * +getname(const u_char *ap) +{ + register struct hostent *hp; + u_int32_t addr; + static struct hnamemem *p; /* static for longjmp() */ + + memcpy(&addr, ap, sizeof(addr)); + p = &hnametable[addr & (HASHNAMESIZE-1)]; + for (; p->nxt; p = p->nxt) { + if (p->addr == addr) + return (p->name); + } + p->addr = addr; + p->nxt = newhnamemem(); + + /* + * Print names unless: + * (1) -n was given. + * (2) Address is foreign and -f was given. (If -f was not + * given, f_netmask and f_localnet are 0 and the test + * evaluates to true) + */ + if (!nflag && + (addr & f_netmask) == f_localnet) { + hp = gethostbyaddr((char *)&addr, 4, AF_INET); + if (hp) { + char *dotp; + + p->name = strdup(hp->h_name); + if (Nflag) { + /* Remove domain qualifications */ + dotp = strchr(p->name, '.'); + if (dotp) + *dotp = '\0'; + } + return (p->name); + } + } + p->name = strdup(intoa(addr)); + return (p->name); +} + +#ifdef INET6 +/* + * Return a name for the IP6 address pointed to by ap. This address + * is assumed to be in network byte order. + */ +const char * +getname6(const u_char *ap) +{ + register struct hostent *hp; + struct in6_addr addr; + static struct h6namemem *p; /* static for longjmp() */ + register const char *cp; + char ntop_buf[INET6_ADDRSTRLEN]; + + memcpy(&addr, ap, sizeof(addr)); + p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)]; + for (; p->nxt; p = p->nxt) { + if (memcmp(&p->addr, &addr, sizeof(addr)) == 0) + return (p->name); + } + p->addr = addr; + p->nxt = newh6namemem(); + + /* + * Do not print names if -n was given. + */ + if (!nflag) { + hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6); + if (hp) { + char *dotp; + + p->name = strdup(hp->h_name); + if (Nflag) { + /* Remove domain qualifications */ + dotp = strchr(p->name, '.'); + if (dotp) + *dotp = '\0'; + } + return (p->name); + } + } + cp = inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf)); + p->name = strdup(cp); + return (p->name); +} +#endif /* INET6 */ + +static const char hex[] = "0123456789abcdef"; + + +/* Find the hash node that corresponds the ether address 'ep' */ + +static inline struct enamemem * +lookup_emem(const u_char *ep) +{ + register u_int i, j, k; + struct enamemem *tp; + + k = (ep[0] << 8) | ep[1]; + j = (ep[2] << 8) | ep[3]; + i = (ep[4] << 8) | ep[5]; + + tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)]; + while (tp->e_nxt) + if (tp->e_addr0 == i && + tp->e_addr1 == j && + tp->e_addr2 == k) + return tp; + else + tp = tp->e_nxt; + tp->e_addr0 = i; + tp->e_addr1 = j; + tp->e_addr2 = k; + tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); + if (tp->e_nxt == NULL) + error("lookup_emem: calloc"); + + return tp; +} + +/* + * Find the hash node that corresponds to the bytestring 'bs' + * with length 'nlen' + */ + +static inline struct enamemem * +lookup_bytestring(register const u_char *bs, const unsigned int nlen) +{ + struct enamemem *tp; + register u_int i, j, k; + + if (nlen >= 6) { + k = (bs[0] << 8) | bs[1]; + j = (bs[2] << 8) | bs[3]; + i = (bs[4] << 8) | bs[5]; + } else if (nlen >= 4) { + k = (bs[0] << 8) | bs[1]; + j = (bs[2] << 8) | bs[3]; + i = 0; + } else + i = j = k = 0; + + tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)]; + while (tp->e_nxt) + if (tp->e_addr0 == i && + tp->e_addr1 == j && + tp->e_addr2 == k && + memcmp((const char *)bs, (const char *)(tp->e_bs), nlen) == 0) + return tp; + else + tp = tp->e_nxt; + + tp->e_addr0 = i; + tp->e_addr1 = j; + tp->e_addr2 = k; + + tp->e_bs = (u_char *) calloc(1, nlen + 1); + if (tp->e_bs == NULL) + error("lookup_bytestring: calloc"); + + memcpy(tp->e_bs, bs, nlen); + tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); + if (tp->e_nxt == NULL) + error("lookup_bytestring: calloc"); + + return tp; +} + +/* Find the hash node that corresponds the NSAP 'nsap' */ + +static inline struct enamemem * +lookup_nsap(register const u_char *nsap) +{ + register u_int i, j, k; + unsigned int nlen = *nsap; + struct enamemem *tp; + const u_char *ensap = nsap + nlen - 6; + + if (nlen > 6) { + k = (ensap[0] << 8) | ensap[1]; + j = (ensap[2] << 8) | ensap[3]; + i = (ensap[4] << 8) | ensap[5]; + } + else + i = j = k = 0; + + tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)]; + while (tp->e_nxt) + if (tp->e_addr0 == i && + tp->e_addr1 == j && + tp->e_addr2 == k && + tp->e_nsap[0] == nlen && + memcmp((const char *)&(nsap[1]), + (char *)&(tp->e_nsap[1]), nlen) == 0) + return tp; + else + tp = tp->e_nxt; + tp->e_addr0 = i; + tp->e_addr1 = j; + tp->e_addr2 = k; + tp->e_nsap = (u_char *)malloc(nlen + 1); + if (tp->e_nsap == NULL) + error("lookup_nsap: malloc"); + memcpy((char *)tp->e_nsap, (const char *)nsap, nlen + 1); + tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); + if (tp->e_nxt == NULL) + error("lookup_nsap: calloc"); + + return tp; +} + +/* Find the hash node that corresponds the protoid 'pi'. */ + +static inline struct protoidmem * +lookup_protoid(const u_char *pi) +{ + register u_int i, j; + struct protoidmem *tp; + + /* 5 octets won't be aligned */ + i = (((pi[0] << 8) + pi[1]) << 8) + pi[2]; + j = (pi[3] << 8) + pi[4]; + /* XXX should be endian-insensitive, but do big-endian testing XXX */ + + tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)]; + while (tp->p_nxt) + if (tp->p_oui == i && tp->p_proto == j) + return tp; + else + tp = tp->p_nxt; + tp->p_oui = i; + tp->p_proto = j; + tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp)); + if (tp->p_nxt == NULL) + error("lookup_protoid: calloc"); + + return tp; +} + +const char * +etheraddr_string(register const u_char *ep) +{ + register int i; + register char *cp; + register struct enamemem *tp; + int oui; + char buf[BUFSIZE]; + + tp = lookup_emem(ep); + if (tp->e_name) + return (tp->e_name); +#ifdef USE_ETHER_NTOHOST + if (!nflag) { + char buf2[BUFSIZE]; + + /* + * We don't cast it to "const struct ether_addr *" + * because some systems fail to declare the second + * argument as a "const" pointer, even though they + * don't modify what it points to. + */ + if (ether_ntohost(buf2, (struct ether_addr *)ep) == 0) { + tp->e_name = strdup(buf2); + return (tp->e_name); + } + } +#endif + cp = buf; + oui = EXTRACT_24BITS(ep); + *cp++ = hex[*ep >> 4 ]; + *cp++ = hex[*ep++ & 0xf]; + for (i = 5; --i >= 0;) { + *cp++ = ':'; + *cp++ = hex[*ep >> 4 ]; + *cp++ = hex[*ep++ & 0xf]; + } + + if (!nflag) { + snprintf(cp, BUFSIZE - (2 + 5*3), " (oui %s)", + tok2str(oui_values, "Unknown", oui)); + } else + *cp = '\0'; + tp->e_name = strdup(buf); + return (tp->e_name); +} + +const char * +le64addr_string(const u_char *ep) +{ + const unsigned int len = 8; + register u_int i; + register char *cp; + register struct enamemem *tp; + char buf[BUFSIZE]; + + tp = lookup_bytestring(ep, len); + if (tp->e_name) + return (tp->e_name); + + cp = buf; + for (i = len; i > 0 ; --i) { + *cp++ = hex[*(ep + i - 1) >> 4]; + *cp++ = hex[*(ep + i - 1) & 0xf]; + *cp++ = ':'; + } + cp --; + + *cp = '\0'; + + tp->e_name = strdup(buf); + + return (tp->e_name); +} + +const char * +linkaddr_string(const u_char *ep, const unsigned int type, const unsigned int len) +{ + register u_int i; + register char *cp; + register struct enamemem *tp; + + if (len == 0) + return ("<empty>"); + + if (type == LINKADDR_ETHER && len == ETHER_ADDR_LEN) + return (etheraddr_string(ep)); + + if (type == LINKADDR_FRELAY) + return (q922_string(ep)); + + tp = lookup_bytestring(ep, len); + if (tp->e_name) + return (tp->e_name); + + tp->e_name = cp = (char *)malloc(len*3); + if (tp->e_name == NULL) + error("linkaddr_string: malloc"); + *cp++ = hex[*ep >> 4]; + *cp++ = hex[*ep++ & 0xf]; + for (i = len-1; i > 0 ; --i) { + *cp++ = ':'; + *cp++ = hex[*ep >> 4]; + *cp++ = hex[*ep++ & 0xf]; + } + *cp = '\0'; + return (tp->e_name); +} + +const char * +etherproto_string(u_short port) +{ + register char *cp; + register struct hnamemem *tp; + register u_int32_t i = port; + char buf[sizeof("0000")]; + + for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) + if (tp->addr == i) + return (tp->name); + + tp->addr = i; + tp->nxt = newhnamemem(); + + cp = buf; + NTOHS(port); + *cp++ = hex[port >> 12 & 0xf]; + *cp++ = hex[port >> 8 & 0xf]; + *cp++ = hex[port >> 4 & 0xf]; + *cp++ = hex[port & 0xf]; + *cp++ = '\0'; + tp->name = strdup(buf); + return (tp->name); +} + +const char * +protoid_string(register const u_char *pi) +{ + register u_int i, j; + register char *cp; + register struct protoidmem *tp; + char buf[sizeof("00:00:00:00:00")]; + + tp = lookup_protoid(pi); + if (tp->p_name) + return tp->p_name; + + cp = buf; + if ((j = *pi >> 4) != 0) + *cp++ = hex[j]; + *cp++ = hex[*pi++ & 0xf]; + for (i = 4; (int)--i >= 0;) { + *cp++ = ':'; + if ((j = *pi >> 4) != 0) + *cp++ = hex[j]; + *cp++ = hex[*pi++ & 0xf]; + } + *cp = '\0'; + tp->p_name = strdup(buf); + return (tp->p_name); +} + +#define ISONSAP_MAX_LENGTH 20 +const char * +isonsap_string(const u_char *nsap, register u_int nsap_length) +{ + register u_int nsap_idx; + register char *cp; + register struct enamemem *tp; + + if (nsap_length < 1 || nsap_length > ISONSAP_MAX_LENGTH) + return ("isonsap_string: illegal length"); + + tp = lookup_nsap(nsap); + if (tp->e_name) + return tp->e_name; + + tp->e_name = cp = (char *)malloc(sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx")); + if (cp == NULL) + error("isonsap_string: malloc"); + + for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) { + *cp++ = hex[*nsap >> 4]; + *cp++ = hex[*nsap++ & 0xf]; + if (((nsap_idx & 1) == 0) && + (nsap_idx + 1 < nsap_length)) { + *cp++ = '.'; + } + } + *cp = '\0'; + return (tp->e_name); +} + +const char * +tcpport_string(u_short port) +{ + register struct hnamemem *tp; + register u_int32_t i = port; + char buf[sizeof("00000")]; + + for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) + if (tp->addr == i) + return (tp->name); + + tp->addr = i; + tp->nxt = newhnamemem(); + + (void)snprintf(buf, sizeof(buf), "%u", i); + tp->name = strdup(buf); + return (tp->name); +} + +const char * +udpport_string(register u_short port) +{ + register struct hnamemem *tp; + register u_int32_t i = port; + char buf[sizeof("00000")]; + + for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) + if (tp->addr == i) + return (tp->name); + + tp->addr = i; + tp->nxt = newhnamemem(); + + (void)snprintf(buf, sizeof(buf), "%u", i); + tp->name = strdup(buf); + return (tp->name); +} + +const char * +ipxsap_string(u_short port) +{ + register char *cp; + register struct hnamemem *tp; + register u_int32_t i = port; + char buf[sizeof("0000")]; + + for (tp = &ipxsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) + if (tp->addr == i) + return (tp->name); + + tp->addr = i; + tp->nxt = newhnamemem(); + + cp = buf; + NTOHS(port); + *cp++ = hex[port >> 12 & 0xf]; + *cp++ = hex[port >> 8 & 0xf]; + *cp++ = hex[port >> 4 & 0xf]; + *cp++ = hex[port & 0xf]; + *cp++ = '\0'; + tp->name = strdup(buf); + return (tp->name); +} + +static void +init_servarray(void) +{ + struct servent *sv; + register struct hnamemem *table; + register int i; + char buf[sizeof("0000000000")]; + + while ((sv = getservent()) != NULL) { + int port = ntohs(sv->s_port); + i = port & (HASHNAMESIZE-1); + if (strcmp(sv->s_proto, "tcp") == 0) + table = &tporttable[i]; + else if (strcmp(sv->s_proto, "udp") == 0) + table = &uporttable[i]; + else + continue; + + while (table->name) + table = table->nxt; + if (nflag) { + (void)snprintf(buf, sizeof(buf), "%d", port); + table->name = strdup(buf); + } else + table->name = strdup(sv->s_name); + table->addr = port; + table->nxt = newhnamemem(); + } + endservent(); +} + +/* in libpcap.a (nametoaddr.c) */ +#if defined(WIN32) && !defined(USE_STATIC_LIBPCAP) +__declspec(dllimport) +#else +extern +#endif +const struct eproto { + const char *s; + u_short p; +} eproto_db[]; + +static void +init_eprotoarray(void) +{ + register int i; + register struct hnamemem *table; + + for (i = 0; eproto_db[i].s; i++) { + int j = htons(eproto_db[i].p) & (HASHNAMESIZE-1); + table = &eprototable[j]; + while (table->name) + table = table->nxt; + table->name = eproto_db[i].s; + table->addr = htons(eproto_db[i].p); + table->nxt = newhnamemem(); + } +} + +static const struct protoidlist { + const u_char protoid[5]; + const char *name; +} protoidlist[] = { + {{ 0x00, 0x00, 0x0c, 0x01, 0x07 }, "CiscoMLS" }, + {{ 0x00, 0x00, 0x0c, 0x20, 0x00 }, "CiscoCDP" }, + {{ 0x00, 0x00, 0x0c, 0x20, 0x01 }, "CiscoCGMP" }, + {{ 0x00, 0x00, 0x0c, 0x20, 0x03 }, "CiscoVTP" }, + {{ 0x00, 0xe0, 0x2b, 0x00, 0xbb }, "ExtremeEDP" }, + {{ 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL } +}; + +/* + * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet + * types. + */ +static void +init_protoidarray(void) +{ + register int i; + register struct protoidmem *tp; + const struct protoidlist *pl; + u_char protoid[5]; + + protoid[0] = 0; + protoid[1] = 0; + protoid[2] = 0; + for (i = 0; eproto_db[i].s; i++) { + u_short etype = htons(eproto_db[i].p); + + memcpy((char *)&protoid[3], (char *)&etype, 2); + tp = lookup_protoid(protoid); + tp->p_name = strdup(eproto_db[i].s); + } + /* Hardwire some SNAP proto ID names */ + for (pl = protoidlist; pl->name != NULL; ++pl) { + tp = lookup_protoid(pl->protoid); + /* Don't override existing name */ + if (tp->p_name != NULL) + continue; + + tp->p_name = pl->name; + } +} + +static const struct etherlist { + const u_char addr[6]; + const char *name; +} etherlist[] = { + {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" }, + {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL } +}; + +/* + * Initialize the ethers hash table. We take two different approaches + * depending on whether or not the system provides the ethers name + * service. If it does, we just wire in a few names at startup, + * and etheraddr_string() fills in the table on demand. If it doesn't, + * then we suck in the entire /etc/ethers file at startup. The idea + * is that parsing the local file will be fast, but spinning through + * all the ethers entries via NIS & next_etherent might be very slow. + * + * XXX pcap_next_etherent doesn't belong in the pcap interface, but + * since the pcap module already does name-to-address translation, + * it's already does most of the work for the ethernet address-to-name + * translation, so we just pcap_next_etherent as a convenience. + */ +static void +init_etherarray(void) +{ + register const struct etherlist *el; + register struct enamemem *tp; +#ifdef USE_ETHER_NTOHOST + char name[256]; +#else + register struct pcap_etherent *ep; + register FILE *fp; + + /* Suck in entire ethers file */ + fp = fopen(PCAP_ETHERS_FILE, "r"); + if (fp != NULL) { + while ((ep = pcap_next_etherent(fp)) != NULL) { + tp = lookup_emem(ep->addr); + tp->e_name = strdup(ep->name); + } + (void)fclose(fp); + } +#endif + + /* Hardwire some ethernet names */ + for (el = etherlist; el->name != NULL; ++el) { + tp = lookup_emem(el->addr); + /* Don't override existing name */ + if (tp->e_name != NULL) + continue; + +#ifdef USE_ETHER_NTOHOST + /* + * Use YP/NIS version of name if available. + * + * We don't cast it to "const struct ether_addr *" + * because some systems don't modify the Ethernet + * address but fail to declare the second argument + * as a "const" pointer. + */ + if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) { + tp->e_name = strdup(name); + continue; + } +#endif + tp->e_name = el->name; + } +} + +static const struct tok ipxsap_db[] = { + { 0x0000, "Unknown" }, + { 0x0001, "User" }, + { 0x0002, "User Group" }, + { 0x0003, "PrintQueue" }, + { 0x0004, "FileServer" }, + { 0x0005, "JobServer" }, + { 0x0006, "Gateway" }, + { 0x0007, "PrintServer" }, + { 0x0008, "ArchiveQueue" }, + { 0x0009, "ArchiveServer" }, + { 0x000a, "JobQueue" }, + { 0x000b, "Administration" }, + { 0x000F, "Novell TI-RPC" }, + { 0x0017, "Diagnostics" }, + { 0x0020, "NetBIOS" }, + { 0x0021, "NAS SNA Gateway" }, + { 0x0023, "NACS AsyncGateway" }, + { 0x0024, "RemoteBridge/RoutingService" }, + { 0x0026, "BridgeServer" }, + { 0x0027, "TCP/IP Gateway" }, + { 0x0028, "Point-to-point X.25 BridgeServer" }, + { 0x0029, "3270 Gateway" }, + { 0x002a, "CHI Corp" }, + { 0x002c, "PC Chalkboard" }, + { 0x002d, "TimeSynchServer" }, + { 0x002e, "ARCserve5.0/PalindromeBackup" }, + { 0x0045, "DI3270 Gateway" }, + { 0x0047, "AdvertisingPrintServer" }, + { 0x004a, "NetBlazerModems" }, + { 0x004b, "BtrieveVAP" }, + { 0x004c, "NetwareSQL" }, + { 0x004d, "XtreeNetwork" }, + { 0x0050, "BtrieveVAP4.11" }, + { 0x0052, "QuickLink" }, + { 0x0053, "PrintQueueUser" }, + { 0x0058, "Multipoint X.25 Router" }, + { 0x0060, "STLB/NLM" }, + { 0x0064, "ARCserve" }, + { 0x0066, "ARCserve3.0" }, + { 0x0072, "WAN CopyUtility" }, + { 0x007a, "TES-NetwareVMS" }, + { 0x0092, "WATCOM Debugger/EmeraldTapeBackupServer" }, + { 0x0095, "DDA OBGYN" }, + { 0x0098, "NetwareAccessServer" }, + { 0x009a, "Netware for VMS II/NamedPipeServer" }, + { 0x009b, "NetwareAccessServer" }, + { 0x009e, "PortableNetwareServer/SunLinkNVT" }, + { 0x00a1, "PowerchuteAPC UPS" }, + { 0x00aa, "LAWserve" }, + { 0x00ac, "CompaqIDA StatusMonitor" }, + { 0x0100, "PIPE STAIL" }, + { 0x0102, "LAN ProtectBindery" }, + { 0x0103, "OracleDataBaseServer" }, + { 0x0107, "Netware386/RSPX RemoteConsole" }, + { 0x010f, "NovellSNA Gateway" }, + { 0x0111, "TestServer" }, + { 0x0112, "HP PrintServer" }, + { 0x0114, "CSA MUX" }, + { 0x0115, "CSA LCA" }, + { 0x0116, "CSA CM" }, + { 0x0117, "CSA SMA" }, + { 0x0118, "CSA DBA" }, + { 0x0119, "CSA NMA" }, + { 0x011a, "CSA SSA" }, + { 0x011b, "CSA STATUS" }, + { 0x011e, "CSA APPC" }, + { 0x0126, "SNA TEST SSA Profile" }, + { 0x012a, "CSA TRACE" }, + { 0x012b, "NetwareSAA" }, + { 0x012e, "IKARUS VirusScan" }, + { 0x0130, "CommunicationsExecutive" }, + { 0x0133, "NNS DomainServer/NetwareNamingServicesDomain" }, + { 0x0135, "NetwareNamingServicesProfile" }, + { 0x0137, "Netware386 PrintQueue/NNS PrintQueue" }, + { 0x0141, "LAN SpoolServer" }, + { 0x0152, "IRMALAN Gateway" }, + { 0x0154, "NamedPipeServer" }, + { 0x0166, "NetWareManagement" }, + { 0x0168, "Intel PICKIT CommServer/Intel CAS TalkServer" }, + { 0x0173, "Compaq" }, + { 0x0174, "Compaq SNMP Agent" }, + { 0x0175, "Compaq" }, + { 0x0180, "XTreeServer/XTreeTools" }, + { 0x018A, "NASI ServicesBroadcastServer" }, + { 0x01b0, "GARP Gateway" }, + { 0x01b1, "Binfview" }, + { 0x01bf, "IntelLanDeskManager" }, + { 0x01ca, "AXTEC" }, + { 0x01cb, "ShivaNetModem/E" }, + { 0x01cc, "ShivaLanRover/E" }, + { 0x01cd, "ShivaLanRover/T" }, + { 0x01ce, "ShivaUniversal" }, + { 0x01d8, "CastelleFAXPressServer" }, + { 0x01da, "CastelleLANPressPrintServer" }, + { 0x01dc, "CastelleFAX/Xerox7033 FaxServer/ExcelLanFax" }, + { 0x01f0, "LEGATO" }, + { 0x01f5, "LEGATO" }, + { 0x0233, "NMS Agent/NetwareManagementAgent" }, + { 0x0237, "NMS IPX Discovery/LANternReadWriteChannel" }, + { 0x0238, "NMS IP Discovery/LANternTrapAlarmChannel" }, + { 0x023a, "LANtern" }, + { 0x023c, "MAVERICK" }, + { 0x023f, "NovellSMDR" }, + { 0x024e, "NetwareConnect" }, + { 0x024f, "NASI ServerBroadcast Cisco" }, + { 0x026a, "NMS ServiceConsole" }, + { 0x026b, "TimeSynchronizationServer Netware 4.x" }, + { 0x0278, "DirectoryServer Netware 4.x" }, + { 0x027b, "NetwareManagementAgent" }, + { 0x0280, "Novell File and Printer Sharing Service for PC" }, + { 0x0304, "NovellSAA Gateway" }, + { 0x0308, "COM/VERMED" }, + { 0x030a, "GalacticommWorldgroupServer" }, + { 0x030c, "IntelNetport2/HP JetDirect/HP Quicksilver" }, + { 0x0320, "AttachmateGateway" }, + { 0x0327, "MicrosoftDiagnostiocs" }, + { 0x0328, "WATCOM SQL Server" }, + { 0x0335, "MultiTechSystems MultisynchCommServer" }, + { 0x0343, "Xylogics RemoteAccessServer/LANModem" }, + { 0x0355, "ArcadaBackupExec" }, + { 0x0358, "MSLCD1" }, + { 0x0361, "NETINELO" }, + { 0x037e, "Powerchute UPS Monitoring" }, + { 0x037f, "ViruSafeNotify" }, + { 0x0386, "HP Bridge" }, + { 0x0387, "HP Hub" }, + { 0x0394, "NetWare SAA Gateway" }, + { 0x039b, "LotusNotes" }, + { 0x03b7, "CertusAntiVirus" }, + { 0x03c4, "ARCserve4.0" }, + { 0x03c7, "LANspool3.5" }, + { 0x03d7, "LexmarkPrinterServer" }, + { 0x03d8, "LexmarkXLE PrinterServer" }, + { 0x03dd, "BanyanENS NetwareClient" }, + { 0x03de, "GuptaSequelBaseServer/NetWareSQL" }, + { 0x03e1, "UnivelUnixware" }, + { 0x03e4, "UnivelUnixware" }, + { 0x03fc, "IntelNetport" }, + { 0x03fd, "PrintServerQueue" }, + { 0x040A, "ipnServer" }, + { 0x040D, "LVERRMAN" }, + { 0x040E, "LVLIC" }, + { 0x0414, "NET Silicon (DPI)/Kyocera" }, + { 0x0429, "SiteLockVirus" }, + { 0x0432, "UFHELPR???" }, + { 0x0433, "Synoptics281xAdvancedSNMPAgent" }, + { 0x0444, "MicrosoftNT SNA Server" }, + { 0x0448, "Oracle" }, + { 0x044c, "ARCserve5.01" }, + { 0x0457, "CanonGP55" }, + { 0x045a, "QMS Printers" }, + { 0x045b, "DellSCSI Array" }, + { 0x0491, "NetBlazerModems" }, + { 0x04ac, "OnTimeScheduler" }, + { 0x04b0, "CD-Net" }, + { 0x0513, "EmulexNQA" }, + { 0x0520, "SiteLockChecks" }, + { 0x0529, "SiteLockChecks" }, + { 0x052d, "CitrixOS2 AppServer" }, + { 0x0535, "Tektronix" }, + { 0x0536, "Milan" }, + { 0x055d, "Attachmate SNA gateway" }, + { 0x056b, "IBM8235 ModemServer" }, + { 0x056c, "ShivaLanRover/E PLUS" }, + { 0x056d, "ShivaLanRover/T PLUS" }, + { 0x0580, "McAfeeNetShield" }, + { 0x05B8, "NLM to workstation communication (Revelation Software)" }, + { 0x05BA, "CompatibleSystemsRouters" }, + { 0x05BE, "CheyenneHierarchicalStorageManager" }, + { 0x0606, "JCWatermarkImaging" }, + { 0x060c, "AXISNetworkPrinter" }, + { 0x0610, "AdaptecSCSIManagement" }, + { 0x0621, "IBM AntiVirus" }, + { 0x0640, "Windows95 RemoteRegistryService" }, + { 0x064e, "MicrosoftIIS" }, + { 0x067b, "Microsoft Win95/98 File and Print Sharing for NetWare" }, + { 0x067c, "Microsoft Win95/98 File and Print Sharing for NetWare" }, + { 0x076C, "Xerox" }, + { 0x079b, "ShivaLanRover/E 115" }, + { 0x079c, "ShivaLanRover/T 115" }, + { 0x07B4, "CubixWorldDesk" }, + { 0x07c2, "Quarterdeck IWare Connect V2.x NLM" }, + { 0x07c1, "Quarterdeck IWare Connect V3.x NLM" }, + { 0x0810, "ELAN License Server Demo" }, + { 0x0824, "ShivaLanRoverAccessSwitch/E" }, + { 0x086a, "ISSC Collector" }, + { 0x087f, "ISSC DAS AgentAIX" }, + { 0x0880, "Intel Netport PRO" }, + { 0x0881, "Intel Netport PRO" }, + { 0x0b29, "SiteLock" }, + { 0x0c29, "SiteLockApplications" }, + { 0x0c2c, "LicensingServer" }, + { 0x2101, "PerformanceTechnologyInstantInternet" }, + { 0x2380, "LAI SiteLock" }, + { 0x238c, "MeetingMaker" }, + { 0x4808, "SiteLockServer/SiteLockMetering" }, + { 0x5555, "SiteLockUser" }, + { 0x6312, "Tapeware" }, + { 0x6f00, "RabbitGateway" }, + { 0x7703, "MODEM" }, + { 0x8002, "NetPortPrinters" }, + { 0x8008, "WordPerfectNetworkVersion" }, + { 0x85BE, "Cisco EIGRP" }, + { 0x8888, "WordPerfectNetworkVersion/QuickNetworkManagement" }, + { 0x9000, "McAfeeNetShield" }, + { 0x9604, "CSA-NT_MON" }, + { 0xb6a8, "OceanIsleReachoutRemoteControl" }, + { 0xf11f, "SiteLockMetering" }, + { 0xf1ff, "SiteLock" }, + { 0xf503, "Microsoft SQL Server" }, + { 0xF905, "IBM TimeAndPlace" }, + { 0xfbfb, "TopCallIII FaxServer" }, + { 0xffff, "AnyService/Wildcard" }, + { 0, (char *)0 } +}; + +static void +init_ipxsaparray(void) +{ + register int i; + register struct hnamemem *table; + + for (i = 0; ipxsap_db[i].s != NULL; i++) { + int j = htons(ipxsap_db[i].v) & (HASHNAMESIZE-1); + table = &ipxsaptable[j]; + while (table->name) + table = table->nxt; + table->name = ipxsap_db[i].s; + table->addr = htons(ipxsap_db[i].v); + table->nxt = newhnamemem(); + } +} + +/* + * Initialize the address to name translation machinery. We map all + * non-local IP addresses to numeric addresses if fflag is true (i.e., + * to prevent blocking on the nameserver). localnet is the IP address + * of the local network. mask is its subnet mask. + */ +void +init_addrtoname(u_int32_t localnet, u_int32_t mask) +{ + if (fflag) { + f_localnet = localnet; + f_netmask = mask; + } + if (nflag) + /* + * Simplest way to suppress names. + */ + return; + + init_etherarray(); + init_servarray(); + init_eprotoarray(); + init_protoidarray(); + init_ipxsaparray(); +} + +const char * +dnaddr_string(u_short dnaddr) +{ + register struct hnamemem *tp; + + for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0; + tp = tp->nxt) + if (tp->addr == dnaddr) + return (tp->name); + + tp->addr = dnaddr; + tp->nxt = newhnamemem(); + if (nflag) + tp->name = dnnum_string(dnaddr); + else + tp->name = dnname_string(dnaddr); + + return(tp->name); +} + +/* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */ +struct hnamemem * +newhnamemem(void) +{ + register struct hnamemem *p; + static struct hnamemem *ptr = NULL; + static u_int num = 0; + + if (num <= 0) { + num = 64; + ptr = (struct hnamemem *)calloc(num, sizeof (*ptr)); + if (ptr == NULL) + error("newhnamemem: calloc"); + } + --num; + p = ptr++; + return (p); +} + +#ifdef INET6 +/* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */ +struct h6namemem * +newh6namemem(void) +{ + register struct h6namemem *p; + static struct h6namemem *ptr = NULL; + static u_int num = 0; + + if (num <= 0) { + num = 64; + ptr = (struct h6namemem *)calloc(num, sizeof (*ptr)); + if (ptr == NULL) + error("newh6namemem: calloc"); + } + --num; + p = ptr++; + return (p); +} +#endif /* INET6 */ diff --git a/freebsd/contrib/tcpdump/addrtoname.h b/freebsd/contrib/tcpdump/addrtoname.h new file mode 100644 index 00000000..cd5c41f4 --- /dev/null +++ b/freebsd/contrib/tcpdump/addrtoname.h @@ -0,0 +1,56 @@ +/* + * 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 diff --git a/freebsd/contrib/tcpdump/af.c b/freebsd/contrib/tcpdump/af.c new file mode 100644 index 00000000..4e307a02 --- /dev/null +++ b/freebsd/contrib/tcpdump/af.c @@ -0,0 +1,65 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/af.c,v 1.3 2006-03-23 14:58:44 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> +#include "interface.h" +#include "af.h" + +const struct tok af_values[] = { + { 0, "Reserved"}, + { AFNUM_INET, "IPv4"}, + { AFNUM_INET6, "IPv6"}, + { AFNUM_NSAP, "NSAP"}, + { AFNUM_HDLC, "HDLC"}, + { AFNUM_BBN1822, "BBN 1822"}, + { AFNUM_802, "802"}, + { AFNUM_E163, "E.163"}, + { AFNUM_E164, "E.164"}, + { AFNUM_F69, "F.69"}, + { AFNUM_X121, "X.121"}, + { AFNUM_IPX, "Novell IPX"}, + { AFNUM_ATALK, "Appletalk"}, + { AFNUM_DECNET, "Decnet IV"}, + { AFNUM_BANYAN, "Banyan Vines"}, + { AFNUM_E164NSAP, "E.164 with NSAP subaddress"}, + { AFNUM_L2VPN, "Layer-2 VPN"}, + { AFNUM_VPLS, "VPLS"}, + { 0, NULL}, +}; + +const struct tok bsd_af_values[] = { + { BSD_AFNUM_INET, "IPv4" }, + { BSD_AFNUM_NS, "NS" }, + { BSD_AFNUM_ISO, "ISO" }, + { BSD_AFNUM_APPLETALK, "Appletalk" }, + { BSD_AFNUM_IPX, "IPX" }, + { BSD_AFNUM_INET6_BSD, "IPv6" }, + { BSD_AFNUM_INET6_FREEBSD, "IPv6" }, + { BSD_AFNUM_INET6_DARWIN, "IPv6" }, + { 0, NULL} +}; diff --git a/freebsd/contrib/tcpdump/af.h b/freebsd/contrib/tcpdump/af.h new file mode 100644 index 00000000..679cc8e5 --- /dev/null +++ b/freebsd/contrib/tcpdump/af.h @@ -0,0 +1,57 @@ +/* @(#) $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 diff --git a/freebsd/contrib/tcpdump/ah.h b/freebsd/contrib/tcpdump/ah.h new file mode 100644 index 00000000..c22806af --- /dev/null +++ b/freebsd/contrib/tcpdump/ah.h @@ -0,0 +1,57 @@ +/* $NetBSD: ah.h,v 1.12 2000/07/23 05:23:04 itojun Exp $ */ +/* $KAME: ah.h,v 1.12 2000/07/20 17:41:01 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 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. + */ + +/* + * RFC1826/2402 authentication header. + */ + +#ifndef _NETINET6_AH_H_ +#define _NETINET6_AH_H_ + +struct ah { + u_int8_t ah_nxt; /* Next Header */ + u_int8_t ah_len; /* Length of data, in 32bit */ + u_int16_t ah_reserve; /* Reserved for future use */ + u_int32_t ah_spi; /* Security parameter index */ + /* variable size, 32bit bound*/ /* Authentication data */ +}; + +struct newah { + u_int8_t ah_nxt; /* Next Header */ + u_int8_t ah_len; /* Length of data + 1, in 32bit */ + u_int16_t ah_reserve; /* Reserved for future use */ + u_int32_t ah_spi; /* Security parameter index */ + u_int32_t ah_seq; /* Sequence number field */ + /* variable size, 32bit bound*/ /* Authentication data */ +}; + +#endif /*_NETINET6_AH_H_*/ diff --git a/freebsd/contrib/tcpdump/aodv.h b/freebsd/contrib/tcpdump/aodv.h new file mode 100644 index 00000000..456ec8b3 --- /dev/null +++ b/freebsd/contrib/tcpdump/aodv.h @@ -0,0 +1,190 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/aodv.h,v 1.3 2003-09-13 01:34:42 guy Exp $ (LBL) */ +/* + * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org> + * 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 _AODV_H_ +#define _AODV_H_ + +struct aodv_rreq { + u_int8_t rreq_type; /* AODV message type (1) */ + u_int8_t rreq_flags; /* various flags */ + u_int8_t rreq_zero0; /* reserved, set to zero */ + u_int8_t rreq_hops; /* number of hops from originator */ + u_int32_t rreq_id; /* request ID */ + u_int32_t rreq_da; /* destination IPv4 address */ + u_int32_t rreq_ds; /* destination sequence number */ + u_int32_t rreq_oa; /* originator IPv4 address */ + u_int32_t rreq_os; /* originator sequence number */ +}; +#ifdef INET6 +struct aodv_rreq6 { + u_int8_t rreq_type; /* AODV message type (1) */ + u_int8_t rreq_flags; /* various flags */ + u_int8_t rreq_zero0; /* reserved, set to zero */ + u_int8_t rreq_hops; /* number of hops from originator */ + u_int32_t rreq_id; /* request ID */ + struct in6_addr rreq_da; /* destination IPv6 address */ + u_int32_t rreq_ds; /* destination sequence number */ + struct in6_addr rreq_oa; /* originator IPv6 address */ + u_int32_t rreq_os; /* originator sequence number */ +}; +struct aodv_rreq6_draft_01 { + u_int8_t rreq_type; /* AODV message type (16) */ + u_int8_t rreq_flags; /* various flags */ + u_int8_t rreq_zero0; /* reserved, set to zero */ + u_int8_t rreq_hops; /* number of hops from originator */ + u_int32_t rreq_id; /* request ID */ + u_int32_t rreq_ds; /* destination sequence number */ + u_int32_t rreq_os; /* originator sequence number */ + struct in6_addr rreq_da; /* destination IPv6 address */ + struct in6_addr rreq_oa; /* originator IPv6 address */ +}; +#endif + +#define RREQ_JOIN 0x80 /* join (reserved for multicast */ +#define RREQ_REPAIR 0x40 /* repair (reserved for multicast */ +#define RREQ_GRAT 0x20 /* gratuitous RREP */ +#define RREQ_DEST 0x10 /* destination only */ +#define RREQ_UNKNOWN 0x08 /* unknown destination sequence num */ +#define RREQ_FLAGS_MASK 0xF8 /* mask for rreq_flags */ + +struct aodv_rrep { + u_int8_t rrep_type; /* AODV message type (2) */ + u_int8_t rrep_flags; /* various flags */ + u_int8_t rrep_ps; /* prefix size */ + u_int8_t rrep_hops; /* number of hops from o to d */ + u_int32_t rrep_da; /* destination IPv4 address */ + u_int32_t rrep_ds; /* destination sequence number */ + u_int32_t rrep_oa; /* originator IPv4 address */ + u_int32_t rrep_life; /* lifetime of this route */ +}; +#ifdef INET6 +struct aodv_rrep6 { + u_int8_t rrep_type; /* AODV message type (2) */ + u_int8_t rrep_flags; /* various flags */ + u_int8_t rrep_ps; /* prefix size */ + u_int8_t rrep_hops; /* number of hops from o to d */ + struct in6_addr rrep_da; /* destination IPv6 address */ + u_int32_t rrep_ds; /* destination sequence number */ + struct in6_addr rrep_oa; /* originator IPv6 address */ + u_int32_t rrep_life; /* lifetime of this route */ +}; +struct aodv_rrep6_draft_01 { + u_int8_t rrep_type; /* AODV message type (17) */ + u_int8_t rrep_flags; /* various flags */ + u_int8_t rrep_ps; /* prefix size */ + u_int8_t rrep_hops; /* number of hops from o to d */ + u_int32_t rrep_ds; /* destination sequence number */ + struct in6_addr rrep_da; /* destination IPv6 address */ + struct in6_addr rrep_oa; /* originator IPv6 address */ + u_int32_t rrep_life; /* lifetime of this route */ +}; +#endif + +#define RREP_REPAIR 0x80 /* repair (reserved for multicast */ +#define RREP_ACK 0x40 /* acknowledgement required */ +#define RREP_FLAGS_MASK 0xC0 /* mask for rrep_flags */ +#define RREP_PREFIX_MASK 0x1F /* mask for prefix size */ + +struct rerr_unreach { + u_int32_t u_da; /* IPv4 address */ + u_int32_t u_ds; /* sequence number */ +}; +#ifdef INET6 +struct rerr_unreach6 { + struct in6_addr u_da; /* IPv6 address */ + u_int32_t u_ds; /* sequence number */ +}; +struct rerr_unreach6_draft_01 { + struct in6_addr u_da; /* IPv6 address */ + u_int32_t u_ds; /* sequence number */ +}; +#endif + +struct aodv_rerr { + u_int8_t rerr_type; /* AODV message type (3 or 18) */ + u_int8_t rerr_flags; /* various flags */ + u_int8_t rerr_zero0; /* reserved, set to zero */ + u_int8_t rerr_dc; /* destination count */ + union { + struct rerr_unreach dest[1]; +#ifdef INET6 + struct rerr_unreach6 dest6[1]; + struct rerr_unreach6_draft_01 dest6_draft_01[1]; +#endif + } r; +}; + +#define RERR_NODELETE 0x80 /* don't delete the link */ +#define RERR_FLAGS_MASK 0x80 /* mask for rerr_flags */ + +struct aodv_rrep_ack { + u_int8_t ra_type; + u_int8_t ra_zero0; +}; + +union aodv { + struct aodv_rreq rreq; + struct aodv_rrep rrep; + struct aodv_rerr rerr; + struct aodv_rrep_ack rrep_ack; +#ifdef INET6 + struct aodv_rreq6 rreq6; + struct aodv_rreq6_draft_01 rreq6_draft_01; + struct aodv_rrep6 rrep6; + struct aodv_rrep6_draft_01 rrep6_draft_01; +#endif +}; + +#define AODV_RREQ 1 /* route request */ +#define AODV_RREP 2 /* route response */ +#define AODV_RERR 3 /* error report */ +#define AODV_RREP_ACK 4 /* route response acknowledgement */ + +#define AODV_V6_DRAFT_01_RREQ 16 /* IPv6 route request */ +#define AODV_V6_DRAFT_01_RREP 17 /* IPv6 route response */ +#define AODV_V6_DRAFT_01_RERR 18 /* IPv6 error report */ +#define AODV_V6_DRAFT_01_RREP_ACK 19 /* IPV6 route response acknowledgment */ + +struct aodv_ext { + u_int8_t type; /* extension type */ + u_int8_t length; /* extension length */ +}; + +struct aodv_hello { + struct aodv_ext eh; /* extension header */ + u_int32_t interval; /* expect my next hello in + * (n) ms */ +}; + +#define AODV_EXT_HELLO 1 + +#endif /* _AODV_H_ */ diff --git a/freebsd/contrib/tcpdump/appletalk.h b/freebsd/contrib/tcpdump/appletalk.h new file mode 100644 index 00000000..ff972f65 --- /dev/null +++ b/freebsd/contrib/tcpdump/appletalk.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1988, 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. + * + * AppleTalk protocol formats (courtesy Bill Croft of Stanford/SUMEX). + * + * @(#) $Header: /tcpdump/master/tcpdump/appletalk.h,v 1.16 2004-05-01 09:41:50 hannes Exp $ (LBL) + */ + +struct LAP { + u_int8_t dst; + u_int8_t src; + u_int8_t type; +}; +#define lapShortDDP 1 /* short DDP type */ +#define lapDDP 2 /* DDP type */ +#define lapKLAP 'K' /* Kinetics KLAP type */ + +/* Datagram Delivery Protocol */ + +struct atDDP { + u_int16_t length; + u_int16_t checksum; + u_int16_t dstNet; + u_int16_t srcNet; + u_int8_t dstNode; + u_int8_t srcNode; + u_int8_t dstSkt; + u_int8_t srcSkt; + u_int8_t type; +}; + +struct atShortDDP { + u_int16_t length; + u_int8_t dstSkt; + u_int8_t srcSkt; + u_int8_t type; +}; + +#define ddpMaxWKS 0x7F +#define ddpMaxData 586 +#define ddpLengthMask 0x3FF +#define ddpHopShift 10 +#define ddpSize 13 /* size of DDP header (avoid struct padding) */ +#define ddpSSize 5 +#define ddpWKS 128 /* boundary of DDP well known sockets */ +#define ddpRTMP 1 /* RTMP type */ +#define ddpRTMPrequest 5 /* RTMP request type */ +#define ddpNBP 2 /* NBP type */ +#define ddpATP 3 /* ATP type */ +#define ddpECHO 4 /* ECHO type */ +#define ddpIP 22 /* IP type */ +#define ddpARP 23 /* ARP type */ +#define ddpEIGRP 88 /* EIGRP over Appletalk */ +#define ddpKLAP 0x4b /* Kinetics KLAP type */ + + +/* AppleTalk Transaction Protocol */ + +struct atATP { + u_int8_t control; + u_int8_t bitmap; + u_int16_t transID; + int32_t userData; +}; + +#define atpReqCode 0x40 +#define atpRspCode 0x80 +#define atpRelCode 0xC0 +#define atpXO 0x20 +#define atpEOM 0x10 +#define atpSTS 0x08 +#define atpFlagMask 0x3F +#define atpControlMask 0xF8 +#define atpMaxNum 8 +#define atpMaxData 578 + + +/* AppleTalk Echo Protocol */ + +struct atEcho { + u_int8_t echoFunction; + u_int8_t *echoData; +}; + +#define echoSkt 4 /* the echoer socket */ +#define echoSize 1 /* size of echo header */ +#define echoRequest 1 /* echo request */ +#define echoReply 2 /* echo request */ + + +/* Name Binding Protocol */ + +struct atNBP { + u_int8_t control; + u_int8_t id; +}; + +struct atNBPtuple { + u_int16_t net; + u_int8_t node; + u_int8_t skt; + u_int8_t enumerator; +}; + +#define nbpBrRq 0x10 +#define nbpLkUp 0x20 +#define nbpLkUpReply 0x30 + +#define nbpNIS 2 +#define nbpTupleMax 15 + +#define nbpHeaderSize 2 +#define nbpTupleSize 5 + +#define nbpSkt 2 /* NIS */ + + +/* Routing Table Maint. Protocol */ + +#define rtmpSkt 1 /* number of RTMP socket */ +#define rtmpSize 4 /* minimum size */ +#define rtmpTupleSize 3 + + +/* Zone Information Protocol */ + +struct zipHeader { + u_int8_t command; + u_int8_t netcount; +}; + +#define zipHeaderSize 2 +#define zipQuery 1 +#define zipReply 2 +#define zipTakedown 3 +#define zipBringup 4 +#define ddpZIP 6 +#define zipSkt 6 +#define GetMyZone 7 +#define GetZoneList 8 + +/* + * UDP port range used for ddp-in-udp encapsulation is 16512-16639 + * for client sockets (128-255) and 200-327 for server sockets + * (0-127). We also try to recognize the pre-April 88 server + * socket range of 768-895. + */ +#define atalk_port(p) \ + (((unsigned)((p) - 16512) < 128) || \ + ((unsigned)((p) - 200) < 128) || \ + ((unsigned)((p) - 768) < 128)) diff --git a/freebsd/contrib/tcpdump/arcnet.h b/freebsd/contrib/tcpdump/arcnet.h new file mode 100644 index 00000000..3b609566 --- /dev/null +++ b/freebsd/contrib/tcpdump/arcnet.h @@ -0,0 +1,101 @@ +/* + * 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. + * + * @(#) $Id: arcnet.h,v 1.3 2003-01-23 09:05:37 guy Exp $ (LBL) + * + * from: NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp + */ + +/* + * Structure of a 2.5MB/s Arcnet header on the BSDs, + * as given to interface code. + */ +struct arc_header { + u_int8_t arc_shost; + u_int8_t arc_dhost; + u_int8_t arc_type; + /* + * only present for newstyle encoding with LL fragmentation. + * Don't use sizeof(anything), use ARC_HDR{,NEW}LEN instead. + */ + u_int8_t arc_flag; + u_int16_t arc_seqid; + + /* + * only present in exception packets (arc_flag == 0xff) + */ + u_int8_t arc_type2; /* same as arc_type */ + u_int8_t arc_flag2; /* real flag value */ + u_int16_t arc_seqid2; /* real seqid value */ +}; + +#define ARC_HDRLEN 3 +#define ARC_HDRNEWLEN 6 +#define ARC_HDRNEWLEN_EXC 10 + +/* RFC 1051 */ +#define ARCTYPE_IP_OLD 240 /* IP protocol */ +#define ARCTYPE_ARP_OLD 241 /* address resolution protocol */ + +/* RFC 1201 */ +#define ARCTYPE_IP 212 /* IP protocol */ +#define ARCTYPE_ARP 213 /* address resolution protocol */ +#define ARCTYPE_REVARP 214 /* reverse addr resolution protocol */ + +#define ARCTYPE_ATALK 221 /* Appletalk */ +#define ARCTYPE_BANIAN 247 /* Banyan Vines */ +#define ARCTYPE_IPX 250 /* Novell IPX */ + +#define ARCTYPE_INET6 0xc4 /* IPng */ +#define ARCTYPE_DIAGNOSE 0x80 /* as per ANSI/ATA 878.1 */ + +/* + * Structure of a 2.5MB/s Arcnet header on Linux. Linux has + * an extra "offset" field when given to interface code, and + * never presents packets that look like exception frames. + */ +struct arc_linux_header { + u_int8_t arc_shost; + u_int8_t arc_dhost; + u_int16_t arc_offset; + u_int8_t arc_type; + /* + * only present for newstyle encoding with LL fragmentation. + * Don't use sizeof(anything), use ARC_LINUX_HDR{,NEW}LEN + * instead. + */ + u_int8_t arc_flag; + u_int16_t arc_seqid; +}; + +#define ARC_LINUX_HDRLEN 5 +#define ARC_LINUX_HDRNEWLEN 8 diff --git a/freebsd/contrib/tcpdump/atm.h b/freebsd/contrib/tcpdump/atm.h new file mode 100644 index 00000000..65ac5c17 --- /dev/null +++ b/freebsd/contrib/tcpdump/atm.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2002 Guy Harris. + * 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, 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. + * The name of Guy Harris 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. + * + * @(#) $Header: /tcpdump/master/tcpdump/atm.h,v 1.3 2006-02-08 01:43:00 hannes Exp $ + */ + +/* + * Traffic types for ATM. + */ +#define ATM_UNKNOWN 0 /* Unknown */ +#define ATM_LANE 1 /* LANE */ +#define ATM_LLC 2 /* LLC encapsulation */ + +/* + * some OAM cell captures (most notably Juniper's) + * do not deliver a heading HEC byte + */ +#define ATM_OAM_NOHEC 0 +#define ATM_OAM_HEC 1 +#define ATM_HDR_LEN_NOHEC 4 diff --git a/freebsd/contrib/tcpdump/bgp.h b/freebsd/contrib/tcpdump/bgp.h new file mode 100644 index 00000000..50815960 --- /dev/null +++ b/freebsd/contrib/tcpdump/bgp.h @@ -0,0 +1,17 @@ +/* @(#) $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 *); diff --git a/freebsd/contrib/tcpdump/bootp.h b/freebsd/contrib/tcpdump/bootp.h new file mode 100644 index 00000000..b1b81dce --- /dev/null +++ b/freebsd/contrib/tcpdump/bootp.h @@ -0,0 +1,231 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/bootp.h,v 1.19 2008-04-22 09:46:03 hannes Exp $ (LBL) */ +/* + * Bootstrap Protocol (BOOTP). RFC951 and RFC1048. + * + * This file specifies the "implementation-independent" BOOTP protocol + * information which is common to both client and server. + * + * Copyright 1988 by Carnegie Mellon. + * + * Permission to use, copy, modify, and distribute this program for any + * purpose and without fee is hereby granted, provided that this copyright + * and permission notice appear on all copies and supporting documentation, + * the name of Carnegie Mellon not be used in advertising or publicity + * pertaining to distribution of the program without specific prior + * permission, and notice be given in supporting documentation that copying + * and distribution is by permission of Carnegie Mellon and Stanford + * University. Carnegie Mellon makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + + +struct bootp { + u_int8_t bp_op; /* packet opcode type */ + u_int8_t bp_htype; /* hardware addr type */ + u_int8_t bp_hlen; /* hardware addr length */ + u_int8_t bp_hops; /* gateway hops */ + u_int32_t bp_xid; /* transaction ID */ + u_int16_t bp_secs; /* seconds since boot began */ + u_int16_t bp_flags; /* flags - see bootp_flag_values[] + in print-bootp.c */ + struct in_addr bp_ciaddr; /* client IP address */ + struct in_addr bp_yiaddr; /* 'your' IP address */ + struct in_addr bp_siaddr; /* server IP address */ + struct in_addr bp_giaddr; /* gateway IP address */ + u_int8_t bp_chaddr[16]; /* client hardware address */ + u_int8_t bp_sname[64]; /* server host name */ + u_int8_t bp_file[128]; /* boot file name */ + u_int8_t bp_vend[64]; /* vendor-specific area */ +} UNALIGNED; + +/* + * UDP port numbers, server and client. + */ +#define IPPORT_BOOTPS 67 +#define IPPORT_BOOTPC 68 + +#define BOOTPREPLY 2 +#define BOOTPREQUEST 1 + +/* + * Vendor magic cookie (v_magic) for CMU + */ +#define VM_CMU "CMU" + +/* + * Vendor magic cookie (v_magic) for RFC1048 + */ +#define VM_RFC1048 { 99, 130, 83, 99 } + + + +/* + * RFC1048 tag values used to specify what information is being supplied in + * the vendor field of the packet. + */ + +#define TAG_PAD ((u_int8_t) 0) +#define TAG_SUBNET_MASK ((u_int8_t) 1) +#define TAG_TIME_OFFSET ((u_int8_t) 2) +#define TAG_GATEWAY ((u_int8_t) 3) +#define TAG_TIME_SERVER ((u_int8_t) 4) +#define TAG_NAME_SERVER ((u_int8_t) 5) +#define TAG_DOMAIN_SERVER ((u_int8_t) 6) +#define TAG_LOG_SERVER ((u_int8_t) 7) +#define TAG_COOKIE_SERVER ((u_int8_t) 8) +#define TAG_LPR_SERVER ((u_int8_t) 9) +#define TAG_IMPRESS_SERVER ((u_int8_t) 10) +#define TAG_RLP_SERVER ((u_int8_t) 11) +#define TAG_HOSTNAME ((u_int8_t) 12) +#define TAG_BOOTSIZE ((u_int8_t) 13) +#define TAG_END ((u_int8_t) 255) +/* RFC1497 tags */ +#define TAG_DUMPPATH ((u_int8_t) 14) +#define TAG_DOMAINNAME ((u_int8_t) 15) +#define TAG_SWAP_SERVER ((u_int8_t) 16) +#define TAG_ROOTPATH ((u_int8_t) 17) +#define TAG_EXTPATH ((u_int8_t) 18) +/* RFC2132 */ +#define TAG_IP_FORWARD ((u_int8_t) 19) +#define TAG_NL_SRCRT ((u_int8_t) 20) +#define TAG_PFILTERS ((u_int8_t) 21) +#define TAG_REASS_SIZE ((u_int8_t) 22) +#define TAG_DEF_TTL ((u_int8_t) 23) +#define TAG_MTU_TIMEOUT ((u_int8_t) 24) +#define TAG_MTU_TABLE ((u_int8_t) 25) +#define TAG_INT_MTU ((u_int8_t) 26) +#define TAG_LOCAL_SUBNETS ((u_int8_t) 27) +#define TAG_BROAD_ADDR ((u_int8_t) 28) +#define TAG_DO_MASK_DISC ((u_int8_t) 29) +#define TAG_SUPPLY_MASK ((u_int8_t) 30) +#define TAG_DO_RDISC ((u_int8_t) 31) +#define TAG_RTR_SOL_ADDR ((u_int8_t) 32) +#define TAG_STATIC_ROUTE ((u_int8_t) 33) +#define TAG_USE_TRAILERS ((u_int8_t) 34) +#define TAG_ARP_TIMEOUT ((u_int8_t) 35) +#define TAG_ETH_ENCAP ((u_int8_t) 36) +#define TAG_TCP_TTL ((u_int8_t) 37) +#define TAG_TCP_KEEPALIVE ((u_int8_t) 38) +#define TAG_KEEPALIVE_GO ((u_int8_t) 39) +#define TAG_NIS_DOMAIN ((u_int8_t) 40) +#define TAG_NIS_SERVERS ((u_int8_t) 41) +#define TAG_NTP_SERVERS ((u_int8_t) 42) +#define TAG_VENDOR_OPTS ((u_int8_t) 43) +#define TAG_NETBIOS_NS ((u_int8_t) 44) +#define TAG_NETBIOS_DDS ((u_int8_t) 45) +#define TAG_NETBIOS_NODE ((u_int8_t) 46) +#define TAG_NETBIOS_SCOPE ((u_int8_t) 47) +#define TAG_XWIN_FS ((u_int8_t) 48) +#define TAG_XWIN_DM ((u_int8_t) 49) +#define TAG_NIS_P_DOMAIN ((u_int8_t) 64) +#define TAG_NIS_P_SERVERS ((u_int8_t) 65) +#define TAG_MOBILE_HOME ((u_int8_t) 68) +#define TAG_SMPT_SERVER ((u_int8_t) 69) +#define TAG_POP3_SERVER ((u_int8_t) 70) +#define TAG_NNTP_SERVER ((u_int8_t) 71) +#define TAG_WWW_SERVER ((u_int8_t) 72) +#define TAG_FINGER_SERVER ((u_int8_t) 73) +#define TAG_IRC_SERVER ((u_int8_t) 74) +#define TAG_STREETTALK_SRVR ((u_int8_t) 75) +#define TAG_STREETTALK_STDA ((u_int8_t) 76) +/* DHCP options */ +#define TAG_REQUESTED_IP ((u_int8_t) 50) +#define TAG_IP_LEASE ((u_int8_t) 51) +#define TAG_OPT_OVERLOAD ((u_int8_t) 52) +#define TAG_TFTP_SERVER ((u_int8_t) 66) +#define TAG_BOOTFILENAME ((u_int8_t) 67) +#define TAG_DHCP_MESSAGE ((u_int8_t) 53) +#define TAG_SERVER_ID ((u_int8_t) 54) +#define TAG_PARM_REQUEST ((u_int8_t) 55) +#define TAG_MESSAGE ((u_int8_t) 56) +#define TAG_MAX_MSG_SIZE ((u_int8_t) 57) +#define TAG_RENEWAL_TIME ((u_int8_t) 58) +#define TAG_REBIND_TIME ((u_int8_t) 59) +#define TAG_VENDOR_CLASS ((u_int8_t) 60) +#define TAG_CLIENT_ID ((u_int8_t) 61) +/* RFC 2241 */ +#define TAG_NDS_SERVERS ((u_int8_t) 85) +#define TAG_NDS_TREE_NAME ((u_int8_t) 86) +#define TAG_NDS_CONTEXT ((u_int8_t) 87) +/* RFC 2242 */ +#define TAG_NDS_IPDOMAIN ((u_int8_t) 62) +#define TAG_NDS_IPINFO ((u_int8_t) 63) +/* RFC 2485 */ +#define TAG_OPEN_GROUP_UAP ((u_int8_t) 98) +/* RFC 2563 */ +#define TAG_DISABLE_AUTOCONF ((u_int8_t) 116) +/* RFC 2610 */ +#define TAG_SLP_DA ((u_int8_t) 78) +#define TAG_SLP_SCOPE ((u_int8_t) 79) +/* RFC 2937 */ +#define TAG_NS_SEARCH ((u_int8_t) 117) +/* RFC 3011 */ +#define TAG_IP4_SUBNET_SELECT ((u_int8_t) 118) +/* RFC 3442 */ +#define TAG_CLASSLESS_STATIC_RT ((u_int8_t) 121) +#define TAG_CLASSLESS_STA_RT_MS ((u_int8_t) 249) +/* ftp://ftp.isi.edu/.../assignments/bootp-dhcp-extensions */ +#define TAG_USER_CLASS ((u_int8_t) 77) +#define TAG_SLP_NAMING_AUTH ((u_int8_t) 80) +#define TAG_CLIENT_FQDN ((u_int8_t) 81) +#define TAG_AGENT_CIRCUIT ((u_int8_t) 82) +#define TAG_AGENT_REMOTE ((u_int8_t) 83) +#define TAG_AGENT_MASK ((u_int8_t) 84) +#define TAG_TZ_STRING ((u_int8_t) 88) +#define TAG_FQDN_OPTION ((u_int8_t) 89) +#define TAG_AUTH ((u_int8_t) 90) +#define TAG_VINES_SERVERS ((u_int8_t) 91) +#define TAG_SERVER_RANK ((u_int8_t) 92) +#define TAG_CLIENT_ARCH ((u_int8_t) 93) +#define TAG_CLIENT_NDI ((u_int8_t) 94) +#define TAG_CLIENT_GUID ((u_int8_t) 97) +#define TAG_LDAP_URL ((u_int8_t) 95) +#define TAG_6OVER4 ((u_int8_t) 96) +#define TAG_PRINTER_NAME ((u_int8_t) 100) +#define TAG_MDHCP_SERVER ((u_int8_t) 101) +#define TAG_IPX_COMPAT ((u_int8_t) 110) +#define TAG_NETINFO_PARENT ((u_int8_t) 112) +#define TAG_NETINFO_PARENT_TAG ((u_int8_t) 113) +#define TAG_URL ((u_int8_t) 114) +#define TAG_FAILOVER ((u_int8_t) 115) +#define TAG_EXTENDED_REQUEST ((u_int8_t) 126) +#define TAG_EXTENDED_OPTION ((u_int8_t) 127) + + +/* DHCP Message types (values for TAG_DHCP_MESSAGE option) */ +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 +#define DHCPINFORM 8 + + +/* + * "vendor" data permitted for CMU bootp clients. + */ + +struct cmu_vend { + u_int8_t v_magic[4]; /* magic number */ + u_int32_t v_flags; /* flags/opcodes, etc. */ + struct in_addr v_smask; /* Subnet mask */ + struct in_addr v_dgate; /* Default gateway */ + struct in_addr v_dns1, v_dns2; /* Domain name servers */ + struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */ + struct in_addr v_ts1, v_ts2; /* Time servers */ + u_int8_t v_unused[24]; /* currently unused */ +} UNALIGNED; + + +/* v_flags values */ +#define VF_SMASK 1 /* Subnet mask field contains valid data */ + +/* RFC 4702 DHCP Client FQDN Option */ + +#define CLIENT_FQDN_FLAGS_S 0x01 +#define CLIENT_FQDN_FLAGS_O 0x02 +#define CLIENT_FQDN_FLAGS_E 0x04 +#define CLIENT_FQDN_FLAGS_N 0x08 diff --git a/freebsd/contrib/tcpdump/bpf_dump.c b/freebsd/contrib/tcpdump/bpf_dump.c new file mode 100644 index 00000000..841f8d77 --- /dev/null +++ b/freebsd/contrib/tcpdump/bpf_dump.c @@ -0,0 +1,68 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1992, 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/bpf_dump.c,v 1.17 2008-02-14 20:53:49 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> + +#include "interface.h" + +void +bpf_dump(const struct bpf_program *p, int option) +{ + struct bpf_insn *insn; + int i; + int n = p->bf_len; + + insn = p->bf_insns; + if (option > 2) { + printf("%d\n", n); + for (i = 0; i < n; ++insn, ++i) { + printf("%u %u %u %u\n", insn->code, + insn->jt, insn->jf, insn->k); + } + return ; + } + if (option > 1) { + for (i = 0; i < n; ++insn, ++i) + printf("{ 0x%x, %d, %d, 0x%08x },\n", + insn->code, insn->jt, insn->jf, insn->k); + return; + } + for (i = 0; i < n; ++insn, ++i) { +#ifdef BDEBUG + extern int bids[]; + printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1); +#endif + puts(bpf_image(insn, i)); + } +} diff --git a/freebsd/contrib/tcpdump/chdlc.h b/freebsd/contrib/tcpdump/chdlc.h new file mode 100644 index 00000000..d1172633 --- /dev/null +++ b/freebsd/contrib/tcpdump/chdlc.h @@ -0,0 +1,27 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/chdlc.h,v 1.1 2000-09-18 05:11:43 guy Exp $ (LBL) */ +/* + * 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. + */ + +#define CHDLC_HDRLEN 4 +#define CHDLC_UNICAST 0x0f +#define CHDLC_BCAST 0x8f +#define CHDLC_TYPE_SLARP 0x8035 +#define CHDLC_TYPE_CDP 0x2000 diff --git a/freebsd/contrib/tcpdump/checksum.c b/freebsd/contrib/tcpdump/checksum.c new file mode 100644 index 00000000..a9077303 --- /dev/null +++ b/freebsd/contrib/tcpdump/checksum.c @@ -0,0 +1,196 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * miscellaneous checksumming routines + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/checksum.c,v 1.4 2006-09-25 09:23:32 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "interface.h" + +/* + * CRC-10 table generated using the following Python snippet: + +import sys + +crc_table = [] +for i in range(256): + accum = i << 2 + for j in range(8): + accum <<= 1 + if accum & 0x400: + accum ^= 0x633 + crc_table.append(accum) + +for i in range(len(crc_table)/8): + for j in range(8): + sys.stdout.write("0x%04x, " % crc_table[i*8+j]) + sys.stdout.write("\n") + + */ +static const u_int16_t crc10_table[256] = +{ + 0x0000, 0x0233, 0x0255, 0x0066, 0x0299, 0x00aa, 0x00cc, 0x02ff, + 0x0301, 0x0132, 0x0154, 0x0367, 0x0198, 0x03ab, 0x03cd, 0x01fe, + 0x0031, 0x0202, 0x0264, 0x0057, 0x02a8, 0x009b, 0x00fd, 0x02ce, + 0x0330, 0x0103, 0x0165, 0x0356, 0x01a9, 0x039a, 0x03fc, 0x01cf, + 0x0062, 0x0251, 0x0237, 0x0004, 0x02fb, 0x00c8, 0x00ae, 0x029d, + 0x0363, 0x0150, 0x0136, 0x0305, 0x01fa, 0x03c9, 0x03af, 0x019c, + 0x0053, 0x0260, 0x0206, 0x0035, 0x02ca, 0x00f9, 0x009f, 0x02ac, + 0x0352, 0x0161, 0x0107, 0x0334, 0x01cb, 0x03f8, 0x039e, 0x01ad, + 0x00c4, 0x02f7, 0x0291, 0x00a2, 0x025d, 0x006e, 0x0008, 0x023b, + 0x03c5, 0x01f6, 0x0190, 0x03a3, 0x015c, 0x036f, 0x0309, 0x013a, + 0x00f5, 0x02c6, 0x02a0, 0x0093, 0x026c, 0x005f, 0x0039, 0x020a, + 0x03f4, 0x01c7, 0x01a1, 0x0392, 0x016d, 0x035e, 0x0338, 0x010b, + 0x00a6, 0x0295, 0x02f3, 0x00c0, 0x023f, 0x000c, 0x006a, 0x0259, + 0x03a7, 0x0194, 0x01f2, 0x03c1, 0x013e, 0x030d, 0x036b, 0x0158, + 0x0097, 0x02a4, 0x02c2, 0x00f1, 0x020e, 0x003d, 0x005b, 0x0268, + 0x0396, 0x01a5, 0x01c3, 0x03f0, 0x010f, 0x033c, 0x035a, 0x0169, + 0x0188, 0x03bb, 0x03dd, 0x01ee, 0x0311, 0x0122, 0x0144, 0x0377, + 0x0289, 0x00ba, 0x00dc, 0x02ef, 0x0010, 0x0223, 0x0245, 0x0076, + 0x01b9, 0x038a, 0x03ec, 0x01df, 0x0320, 0x0113, 0x0175, 0x0346, + 0x02b8, 0x008b, 0x00ed, 0x02de, 0x0021, 0x0212, 0x0274, 0x0047, + 0x01ea, 0x03d9, 0x03bf, 0x018c, 0x0373, 0x0140, 0x0126, 0x0315, + 0x02eb, 0x00d8, 0x00be, 0x028d, 0x0072, 0x0241, 0x0227, 0x0014, + 0x01db, 0x03e8, 0x038e, 0x01bd, 0x0342, 0x0171, 0x0117, 0x0324, + 0x02da, 0x00e9, 0x008f, 0x02bc, 0x0043, 0x0270, 0x0216, 0x0025, + 0x014c, 0x037f, 0x0319, 0x012a, 0x03d5, 0x01e6, 0x0180, 0x03b3, + 0x024d, 0x007e, 0x0018, 0x022b, 0x00d4, 0x02e7, 0x0281, 0x00b2, + 0x017d, 0x034e, 0x0328, 0x011b, 0x03e4, 0x01d7, 0x01b1, 0x0382, + 0x027c, 0x004f, 0x0029, 0x021a, 0x00e5, 0x02d6, 0x02b0, 0x0083, + 0x012e, 0x031d, 0x037b, 0x0148, 0x03b7, 0x0184, 0x01e2, 0x03d1, + 0x022f, 0x001c, 0x007a, 0x0249, 0x00b6, 0x0285, 0x02e3, 0x00d0, + 0x011f, 0x032c, 0x034a, 0x0179, 0x0386, 0x01b5, 0x01d3, 0x03e0, + 0x021e, 0x002d, 0x004b, 0x0278, 0x0087, 0x02b4, 0x02d2, 0x00e1 +}; + +static void +init_crc10_table(void) +{ +#define CRC10_POLYNOMIAL 0x633 + register int i, j; + register u_int16_t accum; + u_int16_t verify_crc10_table[256]; + + for ( i = 0; i < 256; i++ ) + { + accum = ((unsigned short) i << 2); + for ( j = 0; j < 8; j++ ) + { + if ((accum <<= 1) & 0x400) accum ^= CRC10_POLYNOMIAL; + } + verify_crc10_table[i] = accum; + } + assert(memcmp(verify_crc10_table, + crc10_table, + sizeof(verify_crc10_table)) == 0); +#undef CRC10_POLYNOMIAL +} + +u_int16_t +verify_crc10_cksum(u_int16_t accum, const u_char *p, int length) +{ + register int i; + + for ( i = 0; i < length; i++ ) + { + accum = ((accum << 8) & 0x3ff) + ^ crc10_table[( accum >> 2) & 0xff] + ^ *p++; + } + return accum; +} + +/* precompute checksum tables */ +void +init_checksum(void) { + + init_crc10_table(); + +} + +/* + * Creates the OSI Fletcher checksum. See 8473-1, Appendix C, section C.3. + * The checksum field of the passed PDU does not need to be reset to zero. + */ +u_int16_t +create_osi_cksum (const u_int8_t *pptr, int checksum_offset, int length) +{ + + int x; + int y; + u_int32_t mul; + u_int32_t c0; + u_int32_t c1; + u_int16_t checksum; + int index; + + c0 = 0; + c1 = 0; + + for (index = 0; index < length; index++) { + /* + * Ignore the contents of the checksum field. + */ + if (index == checksum_offset || + index == checksum_offset+1) { + c1 += c0; + pptr++; + } else { + c0 = c0 + *(pptr++); + c1 += c0; + } + } + + c0 = c0 % 255; + c1 = c1 % 255; + + mul = (length - checksum_offset)*(c0); + + x = mul - c0 - c1; + y = c1 - mul - 1; + + if ( y >= 0 ) y++; + if ( x < 0 ) x--; + + x %= 255; + y %= 255; + + + if (x == 0) x = 255; + if (y == 0) y = 255; + + y &= 0x00FF; + checksum = ((x << 8) | y); + + return checksum; +} diff --git a/freebsd/contrib/tcpdump/cpack.c b/freebsd/contrib/tcpdump/cpack.c new file mode 100644 index 00000000..e34fc1dc --- /dev/null +++ b/freebsd/contrib/tcpdump/cpack.c @@ -0,0 +1,146 @@ +#include <machine/rtems-bsd-user-space.h> + +/*- + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> +#include <tcpdump-stdinc.h> + +#include "cpack.h" +#include "extract.h" + +u_int8_t * +cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment) +{ + size_t misalignment = (size_t)(p - buf) % alignment; + + if (misalignment == 0) + return p; + + return p + (alignment - misalignment); +} + +/* Advance to the next wordsize boundary. Return NULL if fewer than + * wordsize bytes remain in the buffer after the boundary. Otherwise, + * return a pointer to the boundary. + */ +u_int8_t * +cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize) +{ + u_int8_t *next; + + /* Ensure alignment. */ + next = cpack_next_boundary(cs->c_buf, cs->c_next, wordsize); + + /* Too little space for wordsize bytes? */ + if (next - cs->c_buf + wordsize > cs->c_len) + return NULL; + + return next; +} + +int +cpack_init(struct cpack_state *cs, u_int8_t *buf, size_t buflen) +{ + memset(cs, 0, sizeof(*cs)); + + cs->c_buf = buf; + cs->c_len = buflen; + cs->c_next = cs->c_buf; + + return 0; +} + +/* Unpack a 64-bit unsigned integer. */ +int +cpack_uint64(struct cpack_state *cs, u_int64_t *u) +{ + u_int8_t *next; + + if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) + return -1; + + *u = EXTRACT_LE_64BITS(next); + + /* Move pointer past the u_int64_t. */ + cs->c_next = next + sizeof(*u); + return 0; +} + +/* Unpack a 32-bit unsigned integer. */ +int +cpack_uint32(struct cpack_state *cs, u_int32_t *u) +{ + u_int8_t *next; + + if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) + return -1; + + *u = EXTRACT_LE_32BITS(next); + + /* Move pointer past the u_int32_t. */ + cs->c_next = next + sizeof(*u); + return 0; +} + +/* Unpack a 16-bit unsigned integer. */ +int +cpack_uint16(struct cpack_state *cs, u_int16_t *u) +{ + u_int8_t *next; + + if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL) + return -1; + + *u = EXTRACT_LE_16BITS(next); + + /* Move pointer past the u_int16_t. */ + cs->c_next = next + sizeof(*u); + return 0; +} + +/* Unpack an 8-bit unsigned integer. */ +int +cpack_uint8(struct cpack_state *cs, u_int8_t *u) +{ + /* No space left? */ + if ((size_t)(cs->c_next - cs->c_buf) >= cs->c_len) + return -1; + + *u = *cs->c_next; + + /* Move pointer past the u_int8_t. */ + cs->c_next++; + return 0; +} diff --git a/freebsd/contrib/tcpdump/cpack.h b/freebsd/contrib/tcpdump/cpack.h new file mode 100644 index 00000000..74f97960 --- /dev/null +++ b/freebsd/contrib/tcpdump/cpack.h @@ -0,0 +1,54 @@ +/*- + * 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 _CPACK_H +#define _CPACK_H + +struct cpack_state { + u_int8_t *c_buf; + u_int8_t *c_next; + size_t c_len; +}; + +int cpack_init(struct cpack_state *, u_int8_t *, size_t); + +int cpack_uint8(struct cpack_state *, u_int8_t *); +int cpack_uint16(struct cpack_state *, u_int16_t *); +int cpack_uint32(struct cpack_state *, u_int32_t *); +int cpack_uint64(struct cpack_state *, u_int64_t *); + +u_int8_t *cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment); +u_int8_t *cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize); + +#define cpack_int8(__s, __p) cpack_uint8((__s), (u_int8_t*)(__p)) +#define cpack_int16(__s, __p) cpack_uint16((__s), (u_int16_t*)(__p)) +#define cpack_int32(__s, __p) cpack_uint32((__s), (u_int32_t*)(__p)) +#define cpack_int64(__s, __p) cpack_uint64((__s), (u_int64_t*)(__p)) + +#endif /* _CPACK_H */ diff --git a/freebsd/contrib/tcpdump/dccp.h b/freebsd/contrib/tcpdump/dccp.h new file mode 100644 index 00000000..5c66e23c --- /dev/null +++ b/freebsd/contrib/tcpdump/dccp.h @@ -0,0 +1,139 @@ +/* @(#) $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 <iam4@cs.waikato.ac.nz> + * 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__ */ diff --git a/freebsd/contrib/tcpdump/decnet.h b/freebsd/contrib/tcpdump/decnet.h new file mode 100644 index 00000000..d25d157d --- /dev/null +++ b/freebsd/contrib/tcpdump/decnet.h @@ -0,0 +1,461 @@ +/* + * Copyright (c) 1992, 1994, 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/decnet.h,v 1.11 2002-12-11 07:13:50 guy Exp $ (LBL) + */ + +#ifndef WIN32 +typedef u_int8_t byte[1]; /* single byte field */ +#else +/* + * the keyword 'byte' generates conflicts in Windows + */ +typedef unsigned char Byte[1]; /* single byte field */ +#define byte Byte +#endif /* WIN32 */ +typedef u_int8_t word[2]; /* 2 byte field */ +typedef u_int8_t longword[4]; /* 4 bytes field */ + +/* + * Definitions for DECNET Phase IV protocol headers + */ +union etheraddress { + u_int8_t dne_addr[6]; /* full ethernet address */ + struct { + u_int8_t dne_hiord[4]; /* DECnet HIORD prefix */ + u_int8_t dne_nodeaddr[2]; /* DECnet node address */ + } dne_remote; +}; + +typedef union etheraddress etheraddr; /* Ethernet address */ + +#define HIORD 0x000400aa /* high 32-bits of address (swapped) */ + +#define AREAMASK 0176000 /* mask for area field */ +#define AREASHIFT 10 /* bit-offset for area field */ +#define NODEMASK 01777 /* mask for node address field */ + +#define DN_MAXADDL 20 /* max size of DECnet address */ +struct dn_naddr { + u_int16_t a_len; /* length of address */ + u_int8_t a_addr[DN_MAXADDL]; /* address as bytes */ +}; + +/* + * Define long and short header formats. + */ +struct shorthdr + { + byte sh_flags; /* route flags */ + word sh_dst; /* destination node address */ + word sh_src; /* source node address */ + byte sh_visits; /* visit count */ + }; + +struct longhdr + { + byte lg_flags; /* route flags */ + byte lg_darea; /* destination area (reserved) */ + byte lg_dsarea; /* destination subarea (reserved) */ + etheraddr lg_dst; /* destination id */ + byte lg_sarea; /* source area (reserved) */ + byte lg_ssarea; /* source subarea (reserved) */ + etheraddr lg_src; /* source id */ + byte lg_nextl2; /* next level 2 router (reserved) */ + byte lg_visits; /* visit count */ + byte lg_service; /* service class (reserved) */ + byte lg_pt; /* protocol type (reserved) */ + }; + +union routehdr + { + struct shorthdr rh_short; /* short route header */ + struct longhdr rh_long; /* long route header */ + }; + +/* + * Define the values of various fields in the protocol messages. + * + * 1. Data packet formats. + */ +#define RMF_MASK 7 /* mask for message type */ +#define RMF_SHORT 2 /* short message format */ +#define RMF_LONG 6 /* long message format */ +#ifndef RMF_RQR +#define RMF_RQR 010 /* request return to sender */ +#define RMF_RTS 020 /* returning to sender */ +#define RMF_IE 040 /* intra-ethernet packet */ +#endif /* RMR_RQR */ +#define RMF_FVER 0100 /* future version flag */ +#define RMF_PAD 0200 /* pad field */ +#define RMF_PADMASK 0177 /* pad field mask */ + +#define VIS_MASK 077 /* visit field mask */ + +/* + * 2. Control packet formats. + */ +#define RMF_CTLMASK 017 /* mask for message type */ +#define RMF_CTLMSG 01 /* control message indicator */ +#define RMF_INIT 01 /* initialization message */ +#define RMF_VER 03 /* verification message */ +#define RMF_TEST 05 /* hello and test message */ +#define RMF_L1ROUT 07 /* level 1 routing message */ +#define RMF_L2ROUT 011 /* level 2 routing message */ +#define RMF_RHELLO 013 /* router hello message */ +#define RMF_EHELLO 015 /* endnode hello message */ + +#define TI_L2ROUT 01 /* level 2 router */ +#define TI_L1ROUT 02 /* level 1 router */ +#define TI_ENDNODE 03 /* endnode */ +#define TI_VERIF 04 /* verification required */ +#define TI_BLOCK 010 /* blocking requested */ + +#define VE_VERS 2 /* version number (2) */ +#define VE_ECO 0 /* ECO number */ +#define VE_UECO 0 /* user ECO number (0) */ + +#define P3_VERS 1 /* phase III version number (1) */ +#define P3_ECO 3 /* ECO number (3) */ +#define P3_UECO 0 /* user ECO number (0) */ + +#define II_L2ROUT 01 /* level 2 router */ +#define II_L1ROUT 02 /* level 1 router */ +#define II_ENDNODE 03 /* endnode */ +#define II_VERIF 04 /* verification required */ +#define II_NOMCAST 040 /* no multicast traffic accepted */ +#define II_BLOCK 0100 /* blocking requested */ +#define II_TYPEMASK 03 /* mask for node type */ + +#define TESTDATA 0252 /* test data bytes */ +#define TESTLEN 1 /* length of transmitted test data */ + +/* + * Define control message formats. + */ +struct initmsgIII /* phase III initialization message */ + { + byte inIII_flags; /* route flags */ + word inIII_src; /* source node address */ + byte inIII_info; /* routing layer information */ + word inIII_blksize; /* maximum data link block size */ + byte inIII_vers; /* version number */ + byte inIII_eco; /* ECO number */ + byte inIII_ueco; /* user ECO number */ + byte inIII_rsvd; /* reserved image field */ + }; + +struct initmsg /* initialization message */ + { + byte in_flags; /* route flags */ + word in_src; /* source node address */ + byte in_info; /* routing layer information */ + word in_blksize; /* maximum data link block size */ + byte in_vers; /* version number */ + byte in_eco; /* ECO number */ + byte in_ueco; /* user ECO number */ + word in_hello; /* hello timer */ + byte in_rsvd; /* reserved image field */ + }; + +struct verifmsg /* verification message */ + { + byte ve_flags; /* route flags */ + word ve_src; /* source node address */ + byte ve_fcnval; /* function value image field */ + }; + +struct testmsg /* hello and test message */ + { + byte te_flags; /* route flags */ + word te_src; /* source node address */ + byte te_data; /* test data image field */ + }; + +struct l1rout /* level 1 routing message */ + { + byte r1_flags; /* route flags */ + word r1_src; /* source node address */ + byte r1_rsvd; /* reserved field */ + }; + +struct l2rout /* level 2 routing message */ + { + byte r2_flags; /* route flags */ + word r2_src; /* source node address */ + byte r2_rsvd; /* reserved field */ + }; + +struct rhellomsg /* router hello message */ + { + byte rh_flags; /* route flags */ + byte rh_vers; /* version number */ + byte rh_eco; /* ECO number */ + byte rh_ueco; /* user ECO number */ + etheraddr rh_src; /* source id */ + byte rh_info; /* routing layer information */ + word rh_blksize; /* maximum data link block size */ + byte rh_priority; /* router's priority */ + byte rh_area; /* reserved */ + word rh_hello; /* hello timer */ + byte rh_mpd; /* reserved */ + }; + +struct ehellomsg /* endnode hello message */ + { + byte eh_flags; /* route flags */ + byte eh_vers; /* version number */ + byte eh_eco; /* ECO number */ + byte eh_ueco; /* user ECO number */ + etheraddr eh_src; /* source id */ + byte eh_info; /* routing layer information */ + word eh_blksize; /* maximum data link block size */ + byte eh_area; /* area (reserved) */ + byte eh_seed[8]; /* verification seed */ + etheraddr eh_router; /* designated router */ + word eh_hello; /* hello timer */ + byte eh_mpd; /* (reserved) */ + byte eh_data; /* test data image field */ + }; + +union controlmsg + { + struct initmsg cm_init; /* initialization message */ + struct verifmsg cm_ver; /* verification message */ + struct testmsg cm_test; /* hello and test message */ + struct l1rout cm_l1rou; /* level 1 routing message */ + struct l2rout cm_l2rout; /* level 2 routing message */ + struct rhellomsg cm_rhello; /* router hello message */ + struct ehellomsg cm_ehello; /* endnode hello message */ + }; + +/* Macros for decoding routing-info fields */ +#define RI_COST(x) ((x)&0777) +#define RI_HOPS(x) (((x)>>10)&037) + +/* + * NSP protocol fields and values. + */ + +#define NSP_TYPEMASK 014 /* mask to isolate type code */ +#define NSP_SUBMASK 0160 /* mask to isolate subtype code */ +#define NSP_SUBSHFT 4 /* shift to move subtype code */ + +#define MFT_DATA 0 /* data message */ +#define MFT_ACK 04 /* acknowledgement message */ +#define MFT_CTL 010 /* control message */ + +#define MFS_ILS 020 /* data or I/LS indicator */ +#define MFS_BOM 040 /* beginning of message (data) */ +#define MFS_MOM 0 /* middle of message (data) */ +#define MFS_EOM 0100 /* end of message (data) */ +#define MFS_INT 040 /* interrupt message */ + +#define MFS_DACK 0 /* data acknowledgement */ +#define MFS_IACK 020 /* I/LS acknowledgement */ +#define MFS_CACK 040 /* connect acknowledgement */ + +#define MFS_NOP 0 /* no operation */ +#define MFS_CI 020 /* connect initiate */ +#define MFS_CC 040 /* connect confirm */ +#define MFS_DI 060 /* disconnect initiate */ +#define MFS_DC 0100 /* disconnect confirm */ +#define MFS_RCI 0140 /* retransmitted connect initiate */ + +#define SGQ_ACK 0100000 /* ack */ +#define SGQ_NAK 0110000 /* negative ack */ +#define SGQ_OACK 0120000 /* other channel ack */ +#define SGQ_ONAK 0130000 /* other channel negative ack */ +#define SGQ_MASK 07777 /* mask to isolate seq # */ +#define SGQ_OTHER 020000 /* other channel qualifier */ +#define SGQ_DELAY 010000 /* ack delay flag */ + +#define SGQ_EOM 0100000 /* pseudo flag for end-of-message */ + +#define LSM_MASK 03 /* mask for modifier field */ +#define LSM_NOCHANGE 0 /* no change */ +#define LSM_DONOTSEND 1 /* do not send data */ +#define LSM_SEND 2 /* send data */ + +#define LSI_MASK 014 /* mask for interpretation field */ +#define LSI_DATA 0 /* data segment or message count */ +#define LSI_INTR 4 /* interrupt request count */ +#define LSI_INTM 0377 /* funny marker for int. message */ + +#define COS_MASK 014 /* mask for flow control field */ +#define COS_NONE 0 /* no flow control */ +#define COS_SEGMENT 04 /* segment flow control */ +#define COS_MESSAGE 010 /* message flow control */ +#define COS_CRYPTSER 020 /* cryptographic services requested */ +#define COS_DEFAULT 1 /* default value for field */ + +#define COI_MASK 3 /* mask for version field */ +#define COI_32 0 /* version 3.2 */ +#define COI_31 1 /* version 3.1 */ +#define COI_40 2 /* version 4.0 */ +#define COI_41 3 /* version 4.1 */ + +#define MNU_MASK 140 /* mask for session control version */ +#define MNU_10 000 /* session V1.0 */ +#define MNU_20 040 /* session V2.0 */ +#define MNU_ACCESS 1 /* access control present */ +#define MNU_USRDATA 2 /* user data field present */ +#define MNU_INVKPROXY 4 /* invoke proxy field present */ +#define MNU_UICPROXY 8 /* use uic-based proxy */ + +#define DC_NORESOURCES 1 /* no resource reason code */ +#define DC_NOLINK 41 /* no link terminate reason code */ +#define DC_COMPLETE 42 /* disconnect complete reason code */ + +#define DI_NOERROR 0 /* user disconnect */ +#define DI_SHUT 3 /* node is shutting down */ +#define DI_NOUSER 4 /* destination end user does not exist */ +#define DI_INVDEST 5 /* invalid end user destination */ +#define DI_REMRESRC 6 /* insufficient remote resources */ +#define DI_TPA 8 /* third party abort */ +#define DI_PROTOCOL 7 /* protocol error discovered */ +#define DI_ABORT 9 /* user abort */ +#define DI_LOCALRESRC 32 /* insufficient local resources */ +#define DI_REMUSERRESRC 33 /* insufficient remote user resources */ +#define DI_BADACCESS 34 /* bad access control information */ +#define DI_BADACCNT 36 /* bad ACCOUNT information */ +#define DI_CONNECTABORT 38 /* connect request cancelled */ +#define DI_TIMEDOUT 38 /* remote node or user crashed */ +#define DI_UNREACHABLE 39 /* local timers expired due to ... */ +#define DI_BADIMAGE 43 /* bad image data in connect */ +#define DI_SERVMISMATCH 54 /* cryptographic service mismatch */ + +#define UC_OBJREJECT 0 /* object rejected connect */ +#define UC_USERDISCONNECT 0 /* user disconnect */ +#define UC_RESOURCES 1 /* insufficient resources (local or remote) */ +#define UC_NOSUCHNODE 2 /* unrecognized node name */ +#define UC_REMOTESHUT 3 /* remote node shutting down */ +#define UC_NOSUCHOBJ 4 /* unrecognized object */ +#define UC_INVOBJFORMAT 5 /* invalid object name format */ +#define UC_OBJTOOBUSY 6 /* object too busy */ +#define UC_NETWORKABORT 8 /* network abort */ +#define UC_USERABORT 9 /* user abort */ +#define UC_INVNODEFORMAT 10 /* invalid node name format */ +#define UC_LOCALSHUT 11 /* local node shutting down */ +#define UC_ACCESSREJECT 34 /* invalid access control information */ +#define UC_NORESPONSE 38 /* no response from object */ +#define UC_UNREACHABLE 39 /* node unreachable */ + +/* + * NSP message formats. + */ +struct nsphdr /* general nsp header */ + { + byte nh_flags; /* message flags */ + word nh_dst; /* destination link address */ + word nh_src; /* source link address */ + }; + +struct seghdr /* data segment header */ + { + byte sh_flags; /* message flags */ + word sh_dst; /* destination link address */ + word sh_src; /* source link address */ + word sh_seq[3]; /* sequence numbers */ + }; + +struct minseghdr /* minimum data segment header */ + { + byte ms_flags; /* message flags */ + word ms_dst; /* destination link address */ + word ms_src; /* source link address */ + word ms_seq; /* sequence number */ + }; + +struct lsmsg /* link service message (after hdr) */ + { + byte ls_lsflags; /* link service flags */ + byte ls_fcval; /* flow control value */ + }; + +struct ackmsg /* acknowledgement message */ + { + byte ak_flags; /* message flags */ + word ak_dst; /* destination link address */ + word ak_src; /* source link address */ + word ak_acknum[2]; /* acknowledgement numbers */ + }; + +struct minackmsg /* minimum acknowledgement message */ + { + byte mk_flags; /* message flags */ + word mk_dst; /* destination link address */ + word mk_src; /* source link address */ + word mk_acknum; /* acknowledgement number */ + }; + +struct ciackmsg /* connect acknowledgement message */ + { + byte ck_flags; /* message flags */ + word ck_dst; /* destination link address */ + }; + +struct cimsg /* connect initiate message */ + { + byte ci_flags; /* message flags */ + word ci_dst; /* destination link address (0) */ + word ci_src; /* source link address */ + byte ci_services; /* requested services */ + byte ci_info; /* information */ + word ci_segsize; /* maximum segment size */ + }; + +struct ccmsg /* connect confirm message */ + { + byte cc_flags; /* message flags */ + word cc_dst; /* destination link address */ + word cc_src; /* source link address */ + byte cc_services; /* requested services */ + byte cc_info; /* information */ + word cc_segsize; /* maximum segment size */ + byte cc_optlen; /* optional data length */ + }; + +struct cnmsg /* generic connect message */ + { + byte cn_flags; /* message flags */ + word cn_dst; /* destination link address */ + word cn_src; /* source link address */ + byte cn_services; /* requested services */ + byte cn_info; /* information */ + word cn_segsize; /* maximum segment size */ + }; + +struct dimsg /* disconnect initiate message */ + { + byte di_flags; /* message flags */ + word di_dst; /* destination link address */ + word di_src; /* source link address */ + word di_reason; /* reason code */ + byte di_optlen; /* optional data length */ + }; + +struct dcmsg /* disconnect confirm message */ + { + byte dc_flags; /* message flags */ + word dc_dst; /* destination link address */ + word dc_src; /* source link address */ + word dc_reason; /* reason code */ + }; diff --git a/freebsd/contrib/tcpdump/decode_prefix.h b/freebsd/contrib/tcpdump/decode_prefix.h new file mode 100644 index 00000000..8bb4a767 --- /dev/null +++ b/freebsd/contrib/tcpdump/decode_prefix.h @@ -0,0 +1,41 @@ +/* + * 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. + */ + +#ifndef tcpdump_decode_prefix_h +#define tcpdump_decode_prefix_h + +extern int decode_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen); +#ifdef INET6 +extern int decode_prefix6(const u_char *pd, u_int itemlen, char *buf, u_int buflen); +#endif + +#endif diff --git a/freebsd/contrib/tcpdump/enc.h b/freebsd/contrib/tcpdump/enc.h new file mode 100644 index 00000000..2d57e2b8 --- /dev/null +++ b/freebsd/contrib/tcpdump/enc.h @@ -0,0 +1,47 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/enc.h,v 1.1 2003-03-08 08:55:33 guy Exp $ (LBL) */ +/* From $OpenBSD: if_enc.h,v 1.8 2001/06/25 05:14:00 angelos Exp $ */ +/* + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). + * + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. + * + * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, + * by Angelos D. Keromytis. + * + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. + * + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis + * and Niels Provos. + * Copyright (c) 2001, Angelos D. Keromytis. + * + * Permission to use, copy, and modify this software with or without fee + * is hereby granted, provided that this entire notice is included in + * all copies of any software which is or includes a copy or + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR + * PURPOSE. + */ + +#define ENC_HDRLEN 12 + +/* From $OpenBSD: mbuf.h,v 1.56 2002/01/25 15:50:23 art Exp $ */ +#define M_CONF 0x0400 /* packet was encrypted (ESP-transport) */ +#define M_AUTH 0x0800 /* packet was authenticated (AH) */ + +struct enchdr { + u_int32_t af; + u_int32_t spi; + u_int32_t flags; +}; diff --git a/freebsd/contrib/tcpdump/esp.h b/freebsd/contrib/tcpdump/esp.h new file mode 100644 index 00000000..56cdada0 --- /dev/null +++ b/freebsd/contrib/tcpdump/esp.h @@ -0,0 +1,68 @@ +/* $NetBSD: esp.h,v 1.13 2000/09/26 08:37:38 itojun Exp $ */ +/* $KAME: esp.h,v 1.15 2000/09/20 18:15:22 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 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. + */ + +/* + * RFC1827/2406 Encapsulated Security Payload. + */ + +#ifndef _NETINET6_ESP_H_ +#define _NETINET6_ESP_H_ + +struct esp { + u_int32_t esp_spi; /* ESP */ + /*variable size, 32bit bound*/ /* Initialization Vector */ + /*variable size*/ /* Payload data */ + /*variable size*/ /* padding */ + /*8bit*/ /* pad size */ + /*8bit*/ /* next header */ + /*8bit*/ /* next header */ + /*variable size, 32bit bound*/ /* Authentication data (new IPsec) */ +}; + +struct newesp { + u_int32_t esp_spi; /* ESP */ + u_int32_t esp_seq; /* Sequence number */ + /*variable size*/ /* (IV and) Payload data */ + /*variable size*/ /* padding */ + /*8bit*/ /* pad size */ + /*8bit*/ /* next header */ + /*8bit*/ /* next header */ + /*variable size, 32bit bound*/ /* Authentication data */ +}; + +struct esptail { + u_int8_t esp_padlen; /* pad length */ + u_int8_t esp_nxt; /* Next header */ + /*variable size, 32bit bound*/ /* Authentication data (new IPsec)*/ +}; + +#endif /*_NETINET6_ESP_H_*/ diff --git a/freebsd/contrib/tcpdump/ether.h b/freebsd/contrib/tcpdump/ether.h new file mode 100644 index 00000000..e8b3a713 --- /dev/null +++ b/freebsd/contrib/tcpdump/ether.h @@ -0,0 +1,59 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/ether.h,v 1.8 2002-12-11 07:13:51 guy 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. + * + * @(#)if_ether.h 8.3 (Berkeley) 5/2/95 + */ + +#define ETHERMTU 1500 + +/* + * The number of bytes in an ethernet (MAC) address. + */ +#define ETHER_ADDR_LEN 6 + +/* + * Structure of a DEC/Intel/Xerox or 802.3 Ethernet header. + */ +struct ether_header { + u_int8_t ether_dhost[ETHER_ADDR_LEN]; + u_int8_t ether_shost[ETHER_ADDR_LEN]; + u_int16_t ether_type; +}; + +/* + * Length of a DEC/Intel/Xerox or 802.3 Ethernet header; note that some + * compilers may pad "struct ether_header" to a multiple of 4 bytes, + * for example, so "sizeof (struct ether_header)" may not give the right + * answer. + */ +#define ETHER_HDRLEN 14 diff --git a/freebsd/contrib/tcpdump/ethertype.h b/freebsd/contrib/tcpdump/ethertype.h new file mode 100644 index 00000000..2c79ba28 --- /dev/null +++ b/freebsd/contrib/tcpdump/ethertype.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 1993, 1994, 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/ethertype.h,v 1.30 2008-02-06 10:47:53 guy Exp $ (LBL) + * $FreeBSD$ + */ + +/* + * Ethernet types. + * + * We wrap the declarations with #ifdef, so that if a file includes + * <netinet/if_ether.h>, which may declare some of these, we don't + * get a bunch of complaints from the C compiler about redefinitions + * of these values. + * + * We declare all of them here so that no file has to include + * <netinet/if_ether.h> if all it needs are ETHERTYPE_ values. + */ + +#ifndef ETHERTYPE_LEN +#define ETHERTYPE_LEN 2 +#endif + +#ifndef ETHERTYPE_GRE_ISO +#define ETHERTYPE_GRE_ISO 0x00FE /* not really an ethertype only used in GRE */ +#endif +#ifndef ETHERTYPE_PUP +#define ETHERTYPE_PUP 0x0200 /* PUP protocol */ +#endif +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP 0x0800 /* IP protocol */ +#endif +#ifndef ETHERTYPE_ARP +#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ +#endif +#ifndef ETHERTYPE_REVARP +#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ +#endif +#ifndef ETHERTYPE_NS +#define ETHERTYPE_NS 0x0600 +#endif +#ifndef ETHERTYPE_SPRITE +#define ETHERTYPE_SPRITE 0x0500 +#endif +#ifndef ETHERTYPE_TRAIL +#define ETHERTYPE_TRAIL 0x1000 +#endif +#ifndef ETHERTYPE_MOPDL +#define ETHERTYPE_MOPDL 0x6001 +#endif +#ifndef ETHERTYPE_MOPRC +#define ETHERTYPE_MOPRC 0x6002 +#endif +#ifndef ETHERTYPE_DN +#define ETHERTYPE_DN 0x6003 +#endif +#ifndef ETHERTYPE_LAT +#define ETHERTYPE_LAT 0x6004 +#endif +#ifndef ETHERTYPE_SCA +#define ETHERTYPE_SCA 0x6007 +#endif +#ifndef ETHERTYPE_TEB +#define ETHERTYPE_TEB 0x6558 +#endif +#ifndef ETHERTYPE_LANBRIDGE +#define ETHERTYPE_LANBRIDGE 0x8038 +#endif +#ifndef ETHERTYPE_DECDNS +#define ETHERTYPE_DECDNS 0x803c +#endif +#ifndef ETHERTYPE_DECDTS +#define ETHERTYPE_DECDTS 0x803e +#endif +#ifndef ETHERTYPE_VEXP +#define ETHERTYPE_VEXP 0x805b +#endif +#ifndef ETHERTYPE_VPROD +#define ETHERTYPE_VPROD 0x805c +#endif +#ifndef ETHERTYPE_ATALK +#define ETHERTYPE_ATALK 0x809b +#endif +#ifndef ETHERTYPE_AARP +#define ETHERTYPE_AARP 0x80f3 +#endif +#ifndef ETHERTYPE_TIPC +#define ETHERTYPE_TIPC 0x88ca +#endif +#ifndef ETHERTYPE_8021Q +#define ETHERTYPE_8021Q 0x8100 +#endif + +/* see: + http://en.wikipedia.org/wiki/IEEE_802.1Q + and http://en.wikipedia.org/wiki/QinQ +*/ +#ifndef ETHERTYPE_8021Q9100 +#define ETHERTYPE_8021Q9100 0x9100 +#endif +#ifndef ETHERTYPE_8021Q9200 +#define ETHERTYPE_8021Q9200 0x9200 +#endif +#ifndef ETHERTYPE_8021QinQ +#define ETHERTYPE_8021QinQ 0x88a8 +#endif +#ifndef ETHERTYPE_IPX +#define ETHERTYPE_IPX 0x8137 +#endif +#ifndef ETHERTYPE_IPV6 +#define ETHERTYPE_IPV6 0x86dd +#endif +#ifndef ETHERTYPE_PPP +#define ETHERTYPE_PPP 0x880b +#endif +#ifndef ETHERTYPE_MPCP +#define ETHERTYPE_MPCP 0x8808 +#endif +#ifndef ETHERTYPE_SLOW +#define ETHERTYPE_SLOW 0x8809 +#endif +#ifndef ETHERTYPE_MPLS +#define ETHERTYPE_MPLS 0x8847 +#endif +#ifndef ETHERTYPE_MPLS_MULTI +#define ETHERTYPE_MPLS_MULTI 0x8848 +#endif +#ifndef ETHERTYPE_PPPOED +#define ETHERTYPE_PPPOED 0x8863 +#endif +#ifndef ETHERTYPE_PPPOES +#define ETHERTYPE_PPPOES 0x8864 +#endif +#ifndef ETHERTYPE_PPPOED2 +#define ETHERTYPE_PPPOED2 0x3c12 +#endif +#ifndef ETHERTYPE_PPPOES2 +#define ETHERTYPE_PPPOES2 0x3c13 +#endif +#ifndef ETHERTYPE_MS_NLB_HB +#define ETHERTYPE_MS_NLB_HB 0x886f /* MS Network Load Balancing Heartbeat */ +#endif +#ifndef ETHERTYPE_JUMBO +#define ETHERTYPE_JUMBO 0x8870 +#endif +#ifndef ETHERTYPE_LLDP +#define ETHERTYPE_LLDP 0x88cc +#endif +#ifndef ETHERTYPE_EAPOL +#define ETHERTYPE_EAPOL 0x888e +#endif +#ifndef ETHERTYPE_RRCP +#define ETHERTYPE_RRCP 0x8899 +#endif +#ifndef ETHERTYPE_LOOPBACK +#define ETHERTYPE_LOOPBACK 0x9000 +#endif +#ifndef ETHERTYPE_VMAN +#define ETHERTYPE_VMAN 0x9100 /* Extreme VMAN Protocol */ +#endif +#ifndef ETHERTYPE_CFM_OLD +#define ETHERTYPE_CFM_OLD 0xabcd /* 802.1ag depreciated */ +#endif +#ifndef ETHERTYPE_CFM +#define ETHERTYPE_CFM 0x8902 /* 802.1ag */ +#endif +#ifndef ETHERTYPE_ISO +#define ETHERTYPE_ISO 0xfefe /* nonstandard - used in Cisco HDLC encapsulation */ +#endif + +extern const struct tok ethertype_values[]; diff --git a/freebsd/contrib/tcpdump/extract.h b/freebsd/contrib/tcpdump/extract.h new file mode 100644 index 00000000..60ecd680 --- /dev/null +++ b/freebsd/contrib/tcpdump/extract.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 1992, 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/extract.h,v 1.25 2006-01-30 16:20:07 hannes Exp $ (LBL) + */ + +/* + * Macros to extract possibly-unaligned big-endian integral values. + */ +#ifdef LBL_ALIGN +/* + * The processor doesn't natively handle unaligned loads. + */ +#ifdef HAVE___ATTRIBUTE__ +/* + * We have __attribute__; we assume that means we have __attribute__((packed)). + * Declare packed structures containing a u_int16_t and a u_int32_t, + * cast the pointer to point to one of those, and fetch through it; + * the GCC manual doesn't appear to explicitly say that + * __attribute__((packed)) causes the compiler to generate unaligned-safe + * code, but it apppears to do so. + * + * We do this in case the compiler can generate, for this instruction set, + * better code to do an unaligned load and pass stuff to "ntohs()" or + * "ntohl()" than the code to fetch the bytes one at a time and + * assemble them. (That might not be the case on a little-endian platform, + * where "ntohs()" and "ntohl()" might not be done inline.) + */ +typedef struct { + u_int16_t val; +} __attribute__((packed)) unaligned_u_int16_t; + +typedef struct { + u_int32_t val; +} __attribute__((packed)) unaligned_u_int32_t; + +static inline u_int16_t +EXTRACT_16BITS(const void *p) +{ + return ((u_int16_t)ntohs(((const unaligned_u_int16_t *)(p))->val)); +} + +static inline u_int32_t +EXTRACT_32BITS(const void *p) +{ + return ((u_int32_t)ntohl(((const unaligned_u_int32_t *)(p))->val)); +} + +static inline u_int64_t +EXTRACT_64BITS(const void *p) +{ + return ((u_int64_t)(((u_int64_t)ntohl(((const unaligned_u_int32_t *)(p) + 0)->val)) << 32 | \ + ((u_int64_t)ntohl(((const unaligned_u_int32_t *)(p) + 1)->val)) << 0)); + +} + +#else /* HAVE___ATTRIBUTE__ */ +/* + * We don't have __attribute__, so do unaligned loads of big-endian + * quantities the hard way - fetch the bytes one at a time and + * assemble them. + */ +#define EXTRACT_16BITS(p) \ + ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | \ + (u_int16_t)*((const u_int8_t *)(p) + 1))) +#define EXTRACT_32BITS(p) \ + ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | \ + (u_int32_t)*((const u_int8_t *)(p) + 1) << 16 | \ + (u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | \ + (u_int32_t)*((const u_int8_t *)(p) + 3))) +#define EXTRACT_64BITS(p) \ + ((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 0) << 56 | \ + (u_int64_t)*((const u_int8_t *)(p) + 1) << 48 | \ + (u_int64_t)*((const u_int8_t *)(p) + 2) << 40 | \ + (u_int64_t)*((const u_int8_t *)(p) + 3) << 32 | \ + (u_int64_t)*((const u_int8_t *)(p) + 4) << 24 | \ + (u_int64_t)*((const u_int8_t *)(p) + 5) << 16 | \ + (u_int64_t)*((const u_int8_t *)(p) + 6) << 8 | \ + (u_int64_t)*((const u_int8_t *)(p) + 7))) +#endif /* HAVE___ATTRIBUTE__ */ +#else /* LBL_ALIGN */ +/* + * The processor natively handles unaligned loads, so we can just + * cast the pointer and fetch through it. + */ +static inline u_int16_t +EXTRACT_16BITS(const void *p) +{ + return ((u_int16_t)ntohs(*(const u_int16_t *)(p))); +} + +static inline u_int32_t +EXTRACT_32BITS(const void *p) +{ + return ((u_int32_t)ntohl(*(const u_int32_t *)(p))); +} + +static inline u_int64_t +EXTRACT_64BITS(const void *p) +{ + return ((u_int64_t)(((u_int64_t)ntohl(*((const u_int32_t *)(p) + 0))) << 32 | \ + ((u_int64_t)ntohl(*((const u_int32_t *)(p) + 1))) << 0)); + +} + +#endif /* LBL_ALIGN */ + +#define EXTRACT_24BITS(p) \ + ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 16 | \ + (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int32_t)*((const u_int8_t *)(p) + 2))) + +/* + * Macros to extract possibly-unaligned little-endian integral values. + * XXX - do loads on little-endian machines that support unaligned loads? + */ +#define EXTRACT_LE_8BITS(p) (*(p)) +#define EXTRACT_LE_16BITS(p) \ + ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int16_t)*((const u_int8_t *)(p) + 0))) +#define EXTRACT_LE_32BITS(p) \ + ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 3) << 24 | \ + (u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \ + (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int32_t)*((const u_int8_t *)(p) + 0))) +#define EXTRACT_LE_24BITS(p) \ + ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \ + (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int32_t)*((const u_int8_t *)(p) + 0))) +#define EXTRACT_LE_64BITS(p) \ + ((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 7) << 56 | \ + (u_int64_t)*((const u_int8_t *)(p) + 6) << 48 | \ + (u_int64_t)*((const u_int8_t *)(p) + 5) << 40 | \ + (u_int64_t)*((const u_int8_t *)(p) + 4) << 32 | \ + (u_int64_t)*((const u_int8_t *)(p) + 3) << 24 | \ + (u_int64_t)*((const u_int8_t *)(p) + 2) << 16 | \ + (u_int64_t)*((const u_int8_t *)(p) + 1) << 8 | \ + (u_int64_t)*((const u_int8_t *)(p) + 0))) diff --git a/freebsd/contrib/tcpdump/fddi.h b/freebsd/contrib/tcpdump/fddi.h new file mode 100644 index 00000000..df38c8e9 --- /dev/null +++ b/freebsd/contrib/tcpdump/fddi.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 1992, 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/fddi.h,v 1.11 2002-12-11 07:13:51 guy Exp $ (LBL) + */ + +/* + * Based on Ultrix if_fddi.h + */ + +/* + * This stuff should come from a system header file, but there's no + * obviously portable way to do that and it's not really going + * to change from system to system (except for the padding business). + */ + +struct fddi_header { + u_char fddi_fc; /* frame control */ + u_char fddi_dhost[6]; + u_char fddi_shost[6]; +}; + +/* + * Length of an FDDI header; note that some compilers may pad + * "struct fddi_header" to a multiple of 4 bytes, for example, so + * "sizeof (struct fddi_header)" may not give the right + * answer. + */ +#define FDDI_HDRLEN 13 + +/* Useful values for fddi_fc (frame control) field */ + +/* + * FDDI Frame Control bits + */ +#define FDDIFC_C 0x80 /* Class bit */ +#define FDDIFC_L 0x40 /* Address length bit */ +#define FDDIFC_F 0x30 /* Frame format bits */ +#define FDDIFC_Z 0x0f /* Control bits */ + +/* + * FDDI Frame Control values. (48-bit addressing only). + */ +#define FDDIFC_VOID 0x40 /* Void frame */ +#define FDDIFC_NRT 0x80 /* Nonrestricted token */ +#define FDDIFC_RT 0xc0 /* Restricted token */ +#define FDDIFC_SMT_INFO 0x41 /* SMT Info */ +#define FDDIFC_SMT_NSA 0x4F /* SMT Next station adrs */ +#define FDDIFC_MAC_BEACON 0xc2 /* MAC Beacon frame */ +#define FDDIFC_MAC_CLAIM 0xc3 /* MAC Claim frame */ +#define FDDIFC_LLC_ASYNC 0x50 /* Async. LLC frame */ +#define FDDIFC_LLC_SYNC 0xd0 /* Sync. LLC frame */ +#define FDDIFC_IMP_ASYNC 0x60 /* Implementor Async. */ +#define FDDIFC_IMP_SYNC 0xe0 /* Implementor Synch. */ +#define FDDIFC_SMT 0x40 /* SMT frame */ +#define FDDIFC_MAC 0xc0 /* MAC frame */ + +#define FDDIFC_CLFF 0xF0 /* Class/Length/Format bits */ +#define FDDIFC_ZZZZ 0x0F /* Control bits */ diff --git a/freebsd/contrib/tcpdump/forces.h b/freebsd/contrib/tcpdump/forces.h new file mode 100644 index 00000000..d41475f9 --- /dev/null +++ b/freebsd/contrib/tcpdump/forces.h @@ -0,0 +1,679 @@ +/* + * 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. + * + * Copyright (c) 2009 Mojatatu Networks, Inc + * + */ + +/* + * Per draft-ietf-forces-protocol-22 +*/ +#define ForCES_VERS 1 +#define ForCES_HDRL 24 +#define ForCES_ALNL 4U +#define TLV_HDRL 4 +#define ILV_HDRL 8 + +#define TOM_RSVD 0x0 +#define TOM_ASSNSETUP 0x1 +#define TOM_ASSNTEARD 0x2 +#define TOM_CONFIG 0x3 +#define TOM_QUERY 0x4 +#define TOM_EVENTNOT 0x5 +#define TOM_PKTREDIR 0x6 +#define TOM_HEARTBT 0x0F +#define TOM_ASSNSETREP 0x11 +#define TOM_CONFIGREP 0x13 +#define TOM_QUERYREP 0x14 + +/* + * tom_h Flags: resv1(8b):maxtlvs(4b):resv2(2b):mintlv(2b) +*/ +#define ZERO_TTLV 0x01 +#define ZERO_MORE_TTLV 0x02 +#define ONE_MORE_TTLV 0x04 +#define ZERO_TLV 0x00 +#define ONE_TLV 0x10 +#define TWO_TLV 0x20 +#define MAX_TLV 0xF0 + +#define TTLV_T1 (ONE_MORE_TTLV|ONE_TLV) +#define TTLV_T2 (ONE_MORE_TTLV|MAX_TLV) + +struct tom_h { + u_int32_t v; + u_int16_t flags; + u_int16_t op_msk; + const char *s; + int (*print) (register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +}; + +enum { + TOM_RSV_I, + TOM_ASS_I, + TOM_AST_I, + TOM_CFG_I, + TOM_QRY_I, + TOM_EVN_I, + TOM_RED_I, + TOM_HBT_I, + TOM_ASR_I, + TOM_CNR_I, + TOM_QRR_I, + _TOM_RSV_MAX +}; +#define TOM_MAX_IND (_TOM_RSV_MAX - 1) + +int lfbselect_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int redirect_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int asrtlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int asttlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int gentltlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int print_metailv(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int print_metatlv(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int print_reddata(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); + +static inline int tom_valid(u_int8_t tom) +{ + if (tom > 0) { + if (tom >= 0x7 && tom <= 0xe) + return 0; + if (tom == 0x10) + return 0; + if (tom > 0x14) + return 0; + return 1; + } else + return 0; +} + +static inline const char *ForCES_node(u_int32_t node) +{ + if (node <= 0x3FFFFFFF) + return "FE"; + if (node >= 0x40000000 && node <= 0x7FFFFFFF) + return "CE"; + if (node >= 0xC0000000 && node <= 0xFFFFFFEF) + return "AllMulticast"; + if (node == 0xFFFFFFFD) + return "AllCEsBroadcast"; + if (node == 0xFFFFFFFE) + return "AllFEsBroadcast"; + if (node == 0xFFFFFFFF) + return "AllBroadcast"; + + return "ForCESreserved"; + +} + +static inline const char *ForCES_ACKp(u_int32_t flg) +{ + if (flg == 0x0) + return "NoACK"; + if (flg == 0x1) + return "SuccessACK"; + if (flg == 0x2) + return "FailureACK"; + if (flg == 0x3) + return "AlwaysACK"; + return "ACKUnknown"; +} + +static inline const char *ForCES_EMp(u_int32_t flg) +{ + if (flg == 0x0) + return "EMReserved"; + if (flg == 0x1) + return "execute-all-or-none"; + if (flg == 0x2) + return "execute-until-failure"; + if (flg == 0x3) + return "continue-execute-on-failure"; + return "EMUnknown"; +} + +static inline const char *ForCES_ATp(u_int32_t flg) +{ + if (flg == 0x0) + return "Standalone"; + if (flg == 0x1) + return "2PCtransaction"; + return "ATUnknown"; +} + +static inline const char *ForCES_TPp(u_int32_t flg) +{ + if (flg == 0x0) + return "StartofTransaction"; + if (flg == 0x1) + return "MiddleofTransaction"; + if (flg == 0x2) + return "EndofTransaction"; + if (flg == 0x3) + return "abort"; + return "TPUnknown"; +} + +/* + * Structure of forces header, naked of TLVs. + */ +struct forcesh { + u_int8_t fm_vrsvd; /* version and reserved */ +#define ForCES_V(forcesh) ((forcesh)->fm_vrsvd >> 4) + u_int8_t fm_tom; /* type of message */ + u_int16_t fm_len; /* total length * 4 bytes */ +#define ForCES_BLN(forcesh) ((u_int32_t)(EXTRACT_16BITS(&(forcesh)->fm_len) << 2)) + u_int32_t fm_sid; /* Source ID */ +#define ForCES_SID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_sid) + u_int32_t fm_did; /* Destination ID */ +#define ForCES_DID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_did) + u_int8_t fm_cor[8]; /* correlator */ + u_int32_t fm_flags; /* flags */ +#define ForCES_ACK(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0xC0000000) >> 30) +#define ForCES_PRI(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x38000000) >> 27) +#define ForCES_RS1(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x07000000) >> 24) +#define ForCES_EM(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00C00000) >> 22) +#define ForCES_AT(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00200000) >> 21) +#define ForCES_TP(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00180000) >> 19) +#define ForCES_RS2(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x0007FFFF) >> 0) +}; + +#define ForCES_HLN_VALID(fhl,tlen) ((tlen) >= ForCES_HDRL && \ + (fhl) >= ForCES_HDRL && \ + (fhl) == (tlen)) + +#define F_LFB_RSVD 0x0 +#define F_LFB_FEO 0x1 +#define F_LFB_FEPO 0x2 +const struct tok ForCES_LFBs[] = { + {F_LFB_RSVD, "Invalid TLV"}, + {F_LFB_FEO, "FEObj LFB"}, + {F_LFB_FEPO, "FEProtoObj LFB"}, + {0, NULL} +}; + +int forces_type_print(register const u_char * pptr, const struct forcesh *fhdr, + register u_int mlen, const struct tom_h *tops); + +enum { + F_OP_RSV, + F_OP_SET, + F_OP_SETPROP, + F_OP_SETRESP, + F_OP_SETPRESP, + F_OP_DEL, + F_OP_DELRESP, + F_OP_GET, + F_OP_GETPROP, + F_OP_GETRESP, + F_OP_GETPRESP, + F_OP_REPORT, + F_OP_COMMIT, + F_OP_RCOMMIT, + F_OP_RTRCOMP, + _F_OP_MAX +}; + +#define F_OP_MAX (_F_OP_MAX - 1) +enum { + B_OP_SET = 1 << (F_OP_SET - 1), + B_OP_SETPROP = 1 << (F_OP_SETPROP - 1), + B_OP_SETRESP = 1 << (F_OP_SETRESP - 1), + B_OP_SETPRESP = 1 << (F_OP_SETPRESP - 1), + B_OP_DEL = 1 << (F_OP_DEL - 1), + B_OP_DELRESP = 1 << (F_OP_DELRESP - 1), + B_OP_GET = 1 << (F_OP_GET - 1), + B_OP_GETPROP = 1 << (F_OP_GETPROP - 1), + B_OP_GETRESP = 1 << (F_OP_GETRESP - 1), + B_OP_GETPRESP = 1 << (F_OP_GETPRESP - 1), + B_OP_REPORT = 1 << (F_OP_REPORT - 1), + B_OP_COMMIT = 1 << (F_OP_COMMIT - 1), + B_OP_RCOMMIT = 1 << (F_OP_RCOMMIT - 1), + B_OP_RTRCOMP = 1 << (F_OP_RTRCOMP - 1), +}; + +struct optlv_h { + u_int16_t flags; + u_int16_t op_msk; + const char *s; + int (*print) (register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +}; + +int genoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int recpdoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int invoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); + +#define OP_MIN_SIZ 8 +struct pathdata_h { + u_int16_t pflags; + u_int16_t pIDcnt; +}; + +#define B_FULLD 0x1 +#define B_SPARD 0x2 +#define B_RESTV 0x4 +#define B_KEYIN 0x8 + +static const struct optlv_h OPTLV_msg[F_OP_MAX + 1] = { + /* F_OP_RSV */ {ZERO_TTLV, 0, "Invalid OPTLV", invoptlv_print}, + /* F_OP_SET */ {TTLV_T2, B_FULLD | B_SPARD, " Set", recpdoptlv_print}, + /* F_OP_SETPROP */ + {TTLV_T2, B_FULLD | B_SPARD, " SetProp", recpdoptlv_print}, + /* F_OP_SETRESP */ {TTLV_T2, B_RESTV, " SetResp", recpdoptlv_print}, + /* F_OP_SETPRESP */ {TTLV_T2, B_RESTV, " SetPropResp", recpdoptlv_print}, + /* F_OP_DEL */ {ZERO_TTLV, 0, " Del", recpdoptlv_print}, + /* F_OP_DELRESP */ {TTLV_T2, B_RESTV, " DelResp", recpdoptlv_print}, + /* F_OP_GET */ {ZERO_TTLV, 0, " Get", recpdoptlv_print}, + /* F_OP_GETPROP */ {ZERO_TTLV, 0, " GetProp", recpdoptlv_print}, + /* F_OP_GETRESP */ + {TTLV_T2, B_FULLD | B_SPARD | B_RESTV, " GetResp", recpdoptlv_print}, + /* F_OP_GETPRESP */ + {TTLV_T2, B_FULLD | B_RESTV, " GetPropResp", recpdoptlv_print}, + /* F_OP_REPORT */ + {TTLV_T2, B_FULLD | B_SPARD, " Report", recpdoptlv_print}, + /* F_OP_COMMIT */ {ZERO_TTLV, 0, " Commit", NULL}, + /* F_OP_RCOMMIT */ {TTLV_T1, B_RESTV, " RCommit", genoptlv_print}, + /* F_OP_RTRCOMP */ {ZERO_TTLV, 0, " RTRCOMP", NULL}, +}; + +static inline const struct optlv_h *get_forces_optlv_h(u_int16_t opt) +{ + if (opt > F_OP_MAX || opt <= F_OP_RSV) + return &OPTLV_msg[F_OP_RSV]; + + return &OPTLV_msg[opt]; +} + +#define IND_SIZE 256 +#define IND_CHR ' ' +#define IND_PREF '\n' +#define IND_SUF 0x0 +char ind_buf[IND_SIZE]; + +static inline char *indent_pr(int indent, int nlpref) +{ + int i = 0; + char *r = ind_buf; + + if (indent > (IND_SIZE - 1)) + indent = IND_SIZE - 1; + + if (nlpref) { + r[i] = IND_PREF; + i++; + indent--; + } + + while (--indent >= 0) + r[i++] = IND_CHR; + + r[i] = IND_SUF; + return r; +} + +static inline int op_valid(u_int16_t op, u_int16_t mask) +{ + int opb = 1 << (op - 1); + + if (op == 0) + return 0; + if (opb & mask) + return 1; + /* I guess we should allow vendor operations? */ + if (op >= 0x8000) + return 1; + return 0; +} + +#define F_TLV_RSVD 0x0000 +#define F_TLV_REDR 0x0001 +#define F_TLV_ASRS 0x0010 +#define F_TLV_ASRT 0x0011 +#define F_TLV_LFBS 0x1000 +#define F_TLV_PDAT 0x0110 +#define F_TLV_KEYI 0x0111 +#define F_TLV_FULD 0x0112 +#define F_TLV_SPAD 0x0113 +#define F_TLV_REST 0x0114 +#define F_TLV_METD 0x0115 +#define F_TLV_REDD 0x0116 +#define F_TLV_VNST 0x8000 + +static const struct tok ForCES_TLV[] = { + {F_TLV_RSVD, "Invalid TLV"}, + {F_TLV_REDR, "REDIRECT TLV"}, + {F_TLV_ASRS, "ASResult TLV"}, + {F_TLV_ASRT, "ASTreason TLV"}, + {F_TLV_LFBS, "LFBselect TLV"}, + {F_TLV_PDAT, "PATH-DATA TLV"}, + {F_TLV_KEYI, "KEYINFO TLV"}, + {F_TLV_FULD, "FULLDATA TLV"}, + {F_TLV_SPAD, "SPARSEDATA TLV"}, + {F_TLV_REST, "RESULT TLV"}, + {F_TLV_METD, "METADATA TLV"}, + {F_TLV_REDD, "REDIRECTDATA TLV"}, + {0, NULL} +}; + +#define TLV_HLN 4 +static inline int ttlv_valid(u_int16_t ttlv) +{ + if (ttlv > 0) { + if (ttlv == 1 || ttlv == 0x1000) + return 1; + if (ttlv >= 0x10 && ttlv <= 0x11) + return 1; + if (ttlv >= 0x110 && ttlv <= 0x116) + return 1; + if (ttlv >= 0x8000) + return 0; /* XXX: */ + } + + return 0; +} + +struct forces_ilv { + u_int32_t type; + u_int32_t length; +}; + +struct forces_tlv { + u_int16_t type; + u_int16_t length; +}; + +int otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk, int indent); + +#define F_ALN_LEN(len) ( ((len)+ForCES_ALNL-1) & ~(ForCES_ALNL-1) ) +#define GET_TOP_TLV(fhdr) ((struct forces_tlv *)((fhdr) + sizeof (struct forcesh))) +#define TLV_SET_LEN(len) (F_ALN_LEN(TLV_HDRL) + (len)) +#define TLV_ALN_LEN(len) F_ALN_LEN(TLV_SET_LEN(len)) +#define TLV_RDAT_LEN(tlv) ((int)(EXTRACT_16BITS(&(tlv)->length) - TLV_SET_LEN(0)) +#define TLV_DATA(tlvp) ((void*)(((char*)(tlvp)) + TLV_SET_LEN(0))) +#define GO_NXT_TLV(tlv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)), \ + (struct forces_tlv*)(((char*)(tlv)) \ + + F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)))) +#define ILV_SET_LEN(len) (F_ALN_LEN(ILV_HDRL) + (len)) +#define ILV_ALN_LEN(len) F_ALN_LEN(ILV_SET_LEN(len)) +#define ILV_RDAT_LEN(ilv) ((int)(EXTRACT_32BITS(&(ilv)->length)) - ILV_SET_LEN(0)) +#define ILV_DATA(ilvp) ((void*)(((char*)(ilvp)) + ILV_SET_LEN(0))) +#define GO_NXT_ILV(ilv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)), \ + (struct forces_ilv *)(((char*)(ilv)) \ + + F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)))) +#define INVALID_RLEN -1 +#define INVALID_STLN -2 +#define INVALID_LTLN -3 +#define INVALID_ALEN -4 + +static const struct tok ForCES_TLV_err[] = { + {INVALID_RLEN, "Invalid total length"}, + {INVALID_STLN, "xLV too short"}, + {INVALID_LTLN, "xLV too long"}, + {INVALID_ALEN, "data padding missing"}, + {0, NULL} +}; + +static inline int tlv_valid(const struct forces_tlv *tlv, u_int rlen) +{ + if (rlen < TLV_HDRL) + return INVALID_RLEN; + if (EXTRACT_16BITS(&tlv->length) < TLV_HDRL) + return INVALID_STLN; + if (EXTRACT_16BITS(&tlv->length) > rlen) + return INVALID_LTLN; + if (rlen < F_ALN_LEN(EXTRACT_16BITS(&tlv->length))) + return INVALID_ALEN; + + return 0; +} + +static inline int ilv_valid(const struct forces_ilv *ilv, u_int rlen) +{ + if (rlen < ILV_HDRL) + return INVALID_RLEN; + if (EXTRACT_32BITS(&ilv->length) < ILV_HDRL) + return INVALID_STLN; + if (EXTRACT_32BITS(&ilv->length) > rlen) + return INVALID_LTLN; + if (rlen < F_ALN_LEN(EXTRACT_32BITS(&ilv->length))) + return INVALID_ALEN; + + return 0; +} + +struct forces_lfbsh { + u_int32_t class; + u_int32_t instance; +}; + +#define ASSNS_OPS (B_OP_REPORT) +#define CFG_OPS (B_OP_SET|B_OP_SETPROP|B_OP_DEL|B_OP_COMMIT|B_OP_RTRCOMP) +#define CFG_ROPS (B_OP_SETRESP|B_OP_SETPRESP|B_OP_DELRESP|B_OP_RCOMMIT) +#define CFG_QY (B_OP_GET|B_OP_GETPROP) +#define CFG_QYR (B_OP_GETRESP|B_OP_GETPRESP) +#define CFG_EVN (B_OP_REPORT) + +static const struct tom_h ForCES_msg[TOM_MAX_IND + 1] = { + /* TOM_RSV_I */ {TOM_RSVD, ZERO_TTLV, 0, "Invalid message", NULL}, + /* TOM_ASS_I */ {TOM_ASSNSETUP, ZERO_MORE_TTLV | TWO_TLV, ASSNS_OPS, + "Association Setup", lfbselect_print}, + /* TOM_AST_I */ + {TOM_ASSNTEARD, TTLV_T1, 0, "Association TearDown", asttlv_print}, + /* TOM_CFG_I */ {TOM_CONFIG, TTLV_T2, CFG_OPS, "Config", lfbselect_print}, + /* TOM_QRY_I */ {TOM_QUERY, TTLV_T2, CFG_QY, "Query", lfbselect_print}, + /* TOM_EVN_I */ {TOM_EVENTNOT, TTLV_T1, CFG_EVN, "Event Notification", + lfbselect_print}, + /* TOM_RED_I */ + {TOM_PKTREDIR, TTLV_T2, 0, "Packet Redirect", redirect_print}, + /* TOM_HBT_I */ {TOM_HEARTBT, ZERO_TTLV, 0, "HeartBeat", NULL}, + /* TOM_ASR_I */ + {TOM_ASSNSETREP, TTLV_T1, 0, "Association Response", asrtlv_print}, + /* TOM_CNR_I */ {TOM_CONFIGREP, TTLV_T2, CFG_ROPS, "Config Response", + lfbselect_print}, + /* TOM_QRR_I */ + {TOM_QUERYREP, TTLV_T2, CFG_QYR, "Query Response", lfbselect_print}, +}; + +static inline const struct tom_h *get_forces_tom(u_int8_t tom) +{ + int i; + for (i = TOM_RSV_I; i <= TOM_MAX_IND; i++) { + const struct tom_h *th = &ForCES_msg[i]; + if (th->v == tom) + return th; + } + return &ForCES_msg[TOM_RSV_I]; +} + +struct pdata_ops { + u_int32_t v; + u_int16_t flags; + u_int16_t op_msk; + const char *s; + int (*print) (register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +}; + +enum { + PD_RSV_I, + PD_SEL_I, + PD_FDT_I, + PD_SDT_I, + PD_RES_I, + PD_PDT_I, + _PD_RSV_MAX +}; +#define PD_MAX_IND (_TOM_RSV_MAX - 1) + +static inline int pd_valid(u_int16_t pd) +{ + if (pd >= F_TLV_PDAT && pd <= F_TLV_REST) + return 1; + return 0; +} + +static inline void chk_op_type(u_int16_t type, u_int16_t msk, u_int16_t omsk) +{ + if (type != F_TLV_PDAT) { + if (msk & B_KEYIN) { + if (type != F_TLV_KEYI) { + printf + ("Based on flags expected KEYINFO TLV!\n"); + } + } else { + if (!(msk & omsk)) { + printf + ("Illegal DATA encoding for type 0x%x programmed %x got %x \n", + type, omsk, msk); + } + } + } + +} + +int fdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int sdatailv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int sdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int pdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +int pkeyitlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); + +int pdatacnt_print(register const u_char * pptr, register u_int len, + u_int16_t IDcnt, u_int16_t op_msk, int indent); +int pdata_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); + +int prestlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent); +#define F_SELKEY 1 + +struct res_val { + u_int8_t result; + u_int8_t resv1; + u_int16_t resv2; +}; + +static const struct pdata_ops ForCES_pdata[PD_MAX_IND + 1] = { + /* PD_RSV_I */ {0, 0, 0, "Invalid message", NULL}, + /* PD_SEL_I */ {F_TLV_KEYI, 0, 0, "KEYINFO TLV", pkeyitlv_print}, + /* PD_FDT_I */ {F_TLV_FULD, 0, B_FULLD, "FULLDATA TLV", fdatatlv_print}, + /* PD_SDT_I */ {F_TLV_SPAD, 0, B_SPARD, "SPARSEDATA TLV", sdatatlv_print}, + /* PD_RES_I */ {F_TLV_REST, 0, B_RESTV, "RESULT TLV", prestlv_print}, + /* PD_PDT_I */ + {F_TLV_PDAT, 0, 0, "Inner PATH-DATA TLV", recpdoptlv_print}, +}; + +static inline const struct pdata_ops *get_forces_pd(u_int16_t pd) +{ + int i; + for (i = PD_RSV_I + 1; i <= PD_MAX_IND; i++) { + const struct pdata_ops *pdo = &ForCES_pdata[i]; + if (pdo->v == pd) + return pdo; + } + return &ForCES_pdata[TOM_RSV_I]; +} + +enum { + E_SUCCESS, + E_INVALID_HEADER, + E_LENGTH_MISMATCH, + E_VERSION_MISMATCH, + E_INVALID_DESTINATION_PID, + E_LFB_UNKNOWN, + E_LFB_NOT_FOUND, + E_LFB_INSTANCE_ID_NOT_FOUND, + E_INVALID_PATH, + E_COMPONENT_DOES_NOT_EXIST, + E_EXISTS, + E_NOT_FOUND, + E_READ_ONLY, + E_INVALID_ARRAY_CREATION, + E_VALUE_OUT_OF_RANGE, + E_CONTENTS_TOO_LONG, + E_INVALID_PARAMETERS, + E_INVALID_MESSAGE_TYPE, + E_INVALID_FLAGS, + E_INVALID_TLV, + E_EVENT_ERROR, + E_NOT_SUPPORTED, + E_MEMORY_ERROR, + E_INTERNAL_ERROR, + /* 0x18-0xFE are reserved .. */ + E_UNSPECIFIED_ERROR = 0XFF +}; + +const struct tok ForCES_errs[] = { + {E_SUCCESS, "SUCCESS"}, + {E_INVALID_HEADER, "INVALID HEADER"}, + {E_LENGTH_MISMATCH, "LENGTH MISMATCH"}, + {E_VERSION_MISMATCH, "VERSION MISMATCH"}, + {E_INVALID_DESTINATION_PID, "INVALID DESTINATION PID"}, + {E_LFB_UNKNOWN, "LFB UNKNOWN"}, + {E_LFB_NOT_FOUND, "LFB NOT FOUND"}, + {E_LFB_INSTANCE_ID_NOT_FOUND, "LFB INSTANCE ID NOT FOUND"}, + {E_INVALID_PATH, "INVALID PATH"}, + {E_COMPONENT_DOES_NOT_EXIST, "COMPONENT DOES NOT EXIST"}, + {E_EXISTS, "EXISTS ALREADY"}, + {E_NOT_FOUND, "NOT FOUND"}, + {E_READ_ONLY, "READ ONLY"}, + {E_INVALID_ARRAY_CREATION, "INVALID ARRAY CREATION"}, + {E_VALUE_OUT_OF_RANGE, "VALUE OUT OF RANGE"}, + {E_CONTENTS_TOO_LONG, "CONTENTS TOO LONG"}, + {E_INVALID_PARAMETERS, "INVALID PARAMETERS"}, + {E_INVALID_MESSAGE_TYPE, "INVALID MESSAGE TYPE"}, + {E_INVALID_FLAGS, "INVALID FLAGS"}, + {E_INVALID_TLV, "INVALID TLV"}, + {E_EVENT_ERROR, "EVENT ERROR"}, + {E_NOT_SUPPORTED, "NOT SUPPORTED"}, + {E_MEMORY_ERROR, "MEMORY ERROR"}, + {E_INTERNAL_ERROR, "INTERNAL ERROR"}, + {E_UNSPECIFIED_ERROR, "UNSPECIFIED ERROR"}, + {0, NULL} +}; diff --git a/freebsd/contrib/tcpdump/gmpls.c b/freebsd/contrib/tcpdump/gmpls.c new file mode 100644 index 00000000..8216d658 --- /dev/null +++ b/freebsd/contrib/tcpdump/gmpls.c @@ -0,0 +1,199 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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/gmpls.c,v 1.7 2006-04-14 07:11:59 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include "interface.h" +#include "gmpls.h" + +/* rfc3471 */ +const struct tok gmpls_link_prot_values[] = { + { 0x01, "Extra Traffic"}, + { 0x02, "Unprotected"}, + { 0x04, "Shared"}, + { 0x08, "Dedicated 1:1"}, + { 0x10, "Dedicated 1+1"}, + { 0x20, "Enhanced"}, + { 0x40, "Reserved"}, + { 0x80, "Reserved"}, + { 0, NULL } +}; + +/* rfc3471 */ +const struct tok gmpls_switch_cap_values[] = { + { GMPLS_PSC1, "Packet-Switch Capable-1"}, + { GMPLS_PSC2, "Packet-Switch Capable-2"}, + { GMPLS_PSC3, "Packet-Switch Capable-3"}, + { GMPLS_PSC4, "Packet-Switch Capable-4"}, + { GMPLS_L2SC, "Layer-2 Switch Capable"}, + { GMPLS_TSC, "Time-Division-Multiplex"}, + { GMPLS_LSC, "Lambda-Switch Capable"}, + { GMPLS_FSC, "Fiber-Switch Capable"}, + { 0, NULL } +}; + +/* rfc4205 */ +const struct tok gmpls_switch_cap_tsc_indication_values[] = { + { 0, "Standard SONET/SDH" }, + { 1, "Arbitrary SONET/SDH" }, + { 0, NULL } +}; + +/* rfc3471 */ +const struct tok gmpls_encoding_values[] = { + { 1, "Packet"}, + { 2, "Ethernet V2/DIX"}, + { 3, "ANSI/ETSI PDH"}, + { 4, "Reserved"}, + { 5, "SDH ITU-T G.707/SONET ANSI T1.105"}, + { 6, "Reserved"}, + { 7, "Digital Wrapper"}, + { 8, "Lambda (photonic)"}, + { 9, "Fiber"}, + { 10, "Reserved"}, + { 11, "FiberChannel"}, + { 0, NULL } +}; + +/* rfc3471 */ +const struct tok gmpls_payload_values[] = { + { 0, "Unknown"}, + { 1, "Reserved"}, + { 2, "Reserved"}, + { 3, "Reserved"}, + { 4, "Reserved"}, + { 5, "Asynchronous mapping of E4"}, + { 6, "Asynchronous mapping of DS3/T3"}, + { 7, "Asynchronous mapping of E3"}, + { 8, "Bit synchronous mapping of E3"}, + { 9, "Byte synchronous mapping of E3"}, + { 10, "Asynchronous mapping of DS2/T2"}, + { 11, "Bit synchronous mapping of DS2/T2"}, + { 12, "Reserved"}, + { 13, "Asynchronous mapping of E1"}, + { 14, "Byte synchronous mapping of E1"}, + { 15, "Byte synchronous mapping of 31 * DS0"}, + { 16, "Asynchronous mapping of DS1/T1"}, + { 17, "Bit synchronous mapping of DS1/T1"}, + { 18, "Byte synchronous mapping of DS1/T1"}, + { 19, "VC-11 in VC-12"}, + { 20, "Reserved"}, + { 21, "Reserved"}, + { 22, "DS1 SF Asynchronous"}, + { 23, "DS1 ESF Asynchronous"}, + { 24, "DS3 M23 Asynchronous"}, + { 25, "DS3 C-Bit Parity Asynchronous"}, + { 26, "VT/LOVC"}, + { 27, "STS SPE/HOVC"}, + { 28, "POS - No Scrambling, 16 bit CRC"}, + { 29, "POS - No Scrambling, 32 bit CRC"}, + { 30, "POS - Scrambling, 16 bit CRC"}, + { 31, "POS - Scrambling, 32 bit CRC"}, + { 32, "ATM mapping"}, + { 33, "Ethernet PHY"}, + { 34, "SONET/SDH"}, + { 35, "Reserved (SONET deprecated)"}, + { 36, "Digital Wrapper"}, + { 37, "Lambda"}, + { 38, "ANSI/ETSI PDH"}, + { 39, "Reserved"}, + { 40, "Link Access Protocol SDH (X.85 and X.86)"}, + { 41, "FDDI"}, + { 42, "DQDB (ETSI ETS 300 216)"}, + { 43, "FiberChannel-3 (Services)"}, + { 44, "HDLC"}, + { 45, "Ethernet V2/DIX (only)"}, + { 46, "Ethernet 802.3 (only)"}, +/* draft-ietf-ccamp-gmpls-g709-04.txt */ + { 47, "G.709 ODUj"}, + { 48, "G.709 OTUk(v)"}, + { 49, "CBR/CBRa"}, + { 50, "CBRb"}, + { 51, "BSOT"}, + { 52, "BSNT"}, + { 53, "IP/PPP (GFP)"}, + { 54, "Ethernet MAC (framed GFP)"}, + { 55, "Ethernet PHY (transparent GFP)"}, + { 56, "ESCON"}, + { 57, "FICON"}, + { 58, "Fiber Channel"}, + { 0, NULL } +}; + +/* + * Link Type values used by LMP Service Discovery (specifically, the Client + * Port Service Attributes Object). See UNI 1.0 section 9.4.2 for details. + */ +const struct tok lmp_sd_service_config_cpsa_link_type_values[] = { + { 5, "SDH ITU-T G.707"}, + { 6, "SONET ANSI T1.105"}, + { 0, NULL} +}; + +/* + * Signal Type values for SDH links used by LMP Service Discovery (specifically, + * the Client Port Service Attributes Object). See UNI 1.0 section 9.4.2 for + * details. + */ +const struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[] = { + { 5, "VC-3"}, + { 6, "VC-4"}, + { 7, "STM-0"}, + { 8, "STM-1"}, + { 9, "STM-4"}, + { 10, "STM-16"}, + { 11, "STM-64"}, + { 12, "STM-256"}, + { 0, NULL} +}; + +/* + * Signal Type values for SONET links used by LMP Service Discovery (specifically, + * the Client Port Service Attributes Object). See UNI 1.0 section 9.4.2 for + * details. + */ +const struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[] = { + { 5, "STS-1 SPE"}, + { 6, "STS-3c SPE"}, + { 7, "STS-1"}, + { 8, "STM-3"}, + { 9, "STM-12"}, + { 10, "STM-48"}, + { 11, "STM-192"}, + { 12, "STM-768"}, + { 0, NULL} +}; + +#define DIFFSERV_BC_MODEL_RDM 0 /* draft-ietf-tewg-diff-te-proto-07 */ +#define DIFFSERV_BC_MODEL_MAM 1 /* draft-ietf-tewg-diff-te-proto-07 */ +#define DIFFSERV_BC_MODEL_EXTD_MAM 254 /* experimental */ + +const struct tok diffserv_te_bc_values[] = { + { DIFFSERV_BC_MODEL_RDM, "Russian dolls"}, + { DIFFSERV_BC_MODEL_MAM, "Maximum allocation"}, + { DIFFSERV_BC_MODEL_EXTD_MAM, "Maximum allocation with E-LSP support"}, + { 0, NULL } +}; diff --git a/freebsd/contrib/tcpdump/gmpls.h b/freebsd/contrib/tcpdump/gmpls.h new file mode 100644 index 00000000..8db99dea --- /dev/null +++ b/freebsd/contrib/tcpdump/gmpls.h @@ -0,0 +1,34 @@ +/* @(#) $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[]; diff --git a/freebsd/contrib/tcpdump/gmt2local.c b/freebsd/contrib/tcpdump/gmt2local.c new file mode 100644 index 00000000..6e220919 --- /dev/null +++ b/freebsd/contrib/tcpdump/gmt2local.c @@ -0,0 +1,73 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> + +#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); +} diff --git a/freebsd/contrib/tcpdump/gmt2local.h b/freebsd/contrib/tcpdump/gmt2local.h new file mode 100644 index 00000000..f7b3841e --- /dev/null +++ b/freebsd/contrib/tcpdump/gmt2local.h @@ -0,0 +1,27 @@ +/* + * 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. + * + * @(#) $Header: /tcpdump/master/tcpdump/gmt2local.h,v 1.2 1999-10-07 23:47:10 mcr Exp $ (LBL) + */ +#ifndef gmt2local_h +#define gmt2local_h + +int32_t gmt2local(time_t); +#endif diff --git a/freebsd/contrib/tcpdump/icmp6.h b/freebsd/contrib/tcpdump/icmp6.h new file mode 100644 index 00000000..c4d292e5 --- /dev/null +++ b/freebsd/contrib/tcpdump/icmp6.h @@ -0,0 +1,473 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/icmp6.h,v 1.18 2007-08-29 02:31:44 mcr Exp $ (LBL) */ +/* NetBSD: icmp6.h,v 1.13 2000/08/03 16:30:37 itojun Exp */ +/* $KAME: icmp6.h,v 1.22 2000/08/03 15:25:16 jinmei Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 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. + */ + +/* + * 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. + * + * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93 + */ + +#ifndef _NETINET_ICMP6_H_ +#define _NETINET_ICMP6_H_ + +struct icmp6_hdr { + u_int8_t icmp6_type; /* type field */ + u_int8_t icmp6_code; /* code field */ + u_int16_t icmp6_cksum; /* checksum field */ + union { + u_int32_t icmp6_un_data32[1]; /* type-specific field */ + u_int16_t icmp6_un_data16[2]; /* type-specific field */ + u_int8_t icmp6_un_data8[4]; /* type-specific field */ + } icmp6_dataun; +}; + +#define icmp6_data32 icmp6_dataun.icmp6_un_data32 +#define icmp6_data16 icmp6_dataun.icmp6_un_data16 +#define icmp6_data8 icmp6_dataun.icmp6_un_data8 +#define icmp6_pptr icmp6_data32[0] /* parameter prob */ +#define icmp6_mtu icmp6_data32[0] /* packet too big */ +#define icmp6_id icmp6_data16[0] /* echo request/reply */ +#define icmp6_seq icmp6_data16[1] /* echo request/reply */ +#define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */ + +#define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */ +#define ICMP6_PACKET_TOO_BIG 2 /* packet too big */ +#define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */ +#define ICMP6_PARAM_PROB 4 /* ip6 header bad */ + +#define ICMP6_ECHO_REQUEST 128 /* echo service */ +#define ICMP6_ECHO_REPLY 129 /* echo reply */ +#define ICMP6_MEMBERSHIP_QUERY 130 /* group membership query */ +#define MLD6_LISTENER_QUERY 130 /* multicast listener query */ +#define ICMP6_MEMBERSHIP_REPORT 131 /* group membership report */ +#define MLD6_LISTENER_REPORT 131 /* multicast listener report */ +#define ICMP6_MEMBERSHIP_REDUCTION 132 /* group membership termination */ +#define MLD6_LISTENER_DONE 132 /* multicast listener done */ + +#define ND_ROUTER_SOLICIT 133 /* router solicitation */ +#define ND_ROUTER_ADVERT 134 /* router advertisement */ +#define ND_NEIGHBOR_SOLICIT 135 /* neighbor solicitation */ +#define ND_NEIGHBOR_ADVERT 136 /* neighbor advertisement */ +#define ND_REDIRECT 137 /* redirect */ + +#define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */ + +#define ICMP6_WRUREQUEST 139 /* who are you request */ +#define ICMP6_WRUREPLY 140 /* who are you reply */ +#define ICMP6_FQDN_QUERY 139 /* FQDN query */ +#define ICMP6_FQDN_REPLY 140 /* FQDN reply */ +#define ICMP6_NI_QUERY 139 /* node information request */ +#define ICMP6_NI_REPLY 140 /* node information reply */ +#define IND_SOLICIT 141 /* inverse neighbor solicitation */ +#define IND_ADVERT 142 /* inverse neighbor advertisement */ + +#define ICMP6_V2_MEMBERSHIP_REPORT 143 /* v2 membership report */ +#define MLDV2_LISTENER_REPORT 143 /* v2 multicast listener report */ +#define ICMP6_HADISCOV_REQUEST 144 +#define ICMP6_HADISCOV_REPLY 145 +#define ICMP6_MOBILEPREFIX_SOLICIT 146 +#define ICMP6_MOBILEPREFIX_ADVERT 147 + +#define MLD6_MTRACE_RESP 200 /* mtrace response(to sender) */ +#define MLD6_MTRACE 201 /* mtrace messages */ + +#define ICMP6_MAXTYPE 201 + +#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ +#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */ +#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */ +#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ +#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ +#define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */ + +#define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */ +#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */ + +#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ +#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */ +#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */ + +#define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */ + +#define ICMP6_NI_SUBJ_IPV6 0 /* Query Subject is an IPv6 address */ +#define ICMP6_NI_SUBJ_FQDN 1 /* Query Subject is a Domain name */ +#define ICMP6_NI_SUBJ_IPV4 2 /* Query Subject is an IPv4 address */ + +#define ICMP6_NI_SUCCESS 0 /* node information successful reply */ +#define ICMP6_NI_REFUSED 1 /* node information request is refused */ +#define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */ + +#define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */ +#define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */ +#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */ + +/* Used in kernel only */ +#define ND_REDIRECT_ONLINK 0 /* redirect to an on-link node */ +#define ND_REDIRECT_ROUTER 1 /* redirect to a better router */ + +/* + * Multicast Listener Discovery + */ +struct mld6_hdr { + struct icmp6_hdr mld6_hdr; + struct in6_addr mld6_addr; /* multicast address */ +}; + +#define mld6_type mld6_hdr.icmp6_type +#define mld6_code mld6_hdr.icmp6_code +#define mld6_cksum mld6_hdr.icmp6_cksum +#define mld6_maxdelay mld6_hdr.icmp6_data16[0] +#define mld6_reserved mld6_hdr.icmp6_data16[1] + +#define MLD_MINLEN 24 +#define MLDV2_MINLEN 28 + +/* + * Neighbor Discovery + */ + +struct nd_router_solicit { /* router solicitation */ + struct icmp6_hdr nd_rs_hdr; + /* could be followed by options */ +}; + +#define nd_rs_type nd_rs_hdr.icmp6_type +#define nd_rs_code nd_rs_hdr.icmp6_code +#define nd_rs_cksum nd_rs_hdr.icmp6_cksum +#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0] + +struct nd_router_advert { /* router advertisement */ + struct icmp6_hdr nd_ra_hdr; + u_int32_t nd_ra_reachable; /* reachable time */ + u_int32_t nd_ra_retransmit; /* retransmit timer */ + /* could be followed by options */ +}; + +#define nd_ra_type nd_ra_hdr.icmp6_type +#define nd_ra_code nd_ra_hdr.icmp6_code +#define nd_ra_cksum nd_ra_hdr.icmp6_cksum +#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0] +#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1] +#define ND_RA_FLAG_MANAGED 0x80 +#define ND_RA_FLAG_OTHER 0x40 +#define ND_RA_FLAG_HOME_AGENT 0x20 + +/* + * Router preference values based on draft-draves-ipngwg-router-selection-01. + * These are non-standard definitions. + */ +#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ + +#define ND_RA_FLAG_RTPREF_HIGH 0x08 /* 00001000 */ +#define ND_RA_FLAG_RTPREF_MEDIUM 0x00 /* 00000000 */ +#define ND_RA_FLAG_RTPREF_LOW 0x18 /* 00011000 */ +#define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */ + +#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1] + +struct nd_neighbor_solicit { /* neighbor solicitation */ + struct icmp6_hdr nd_ns_hdr; + struct in6_addr nd_ns_target; /*target address */ + /* could be followed by options */ +}; + +#define nd_ns_type nd_ns_hdr.icmp6_type +#define nd_ns_code nd_ns_hdr.icmp6_code +#define nd_ns_cksum nd_ns_hdr.icmp6_cksum +#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0] + +struct nd_neighbor_advert { /* neighbor advertisement */ + struct icmp6_hdr nd_na_hdr; + struct in6_addr nd_na_target; /* target address */ + /* could be followed by options */ +}; + +#define nd_na_type nd_na_hdr.icmp6_type +#define nd_na_code nd_na_hdr.icmp6_code +#define nd_na_cksum nd_na_hdr.icmp6_cksum +#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0] + +#define ND_NA_FLAG_ROUTER 0x80000000 +#define ND_NA_FLAG_SOLICITED 0x40000000 +#define ND_NA_FLAG_OVERRIDE 0x20000000 + +struct nd_redirect { /* redirect */ + struct icmp6_hdr nd_rd_hdr; + struct in6_addr nd_rd_target; /* target address */ + struct in6_addr nd_rd_dst; /* destination address */ + /* could be followed by options */ +}; + +#define nd_rd_type nd_rd_hdr.icmp6_type +#define nd_rd_code nd_rd_hdr.icmp6_code +#define nd_rd_cksum nd_rd_hdr.icmp6_cksum +#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] + +struct nd_opt_hdr { /* Neighbor discovery option header */ + u_int8_t nd_opt_type; + u_int8_t nd_opt_len; + /* followed by option specific data*/ +}; + +#define ND_OPT_SOURCE_LINKADDR 1 +#define ND_OPT_TARGET_LINKADDR 2 +#define ND_OPT_PREFIX_INFORMATION 3 +#define ND_OPT_REDIRECTED_HEADER 4 +#define ND_OPT_MTU 5 +#define ND_OPT_ADVINTERVAL 7 +#define ND_OPT_HOMEAGENT_INFO 8 +#define ND_OPT_ROUTE_INFO 9 /* draft-ietf-ipngwg-router-preference, not officially assigned yet */ +#define ND_OPT_RDNSS 25 +#define ND_OPT_DNSSL 31 + +struct nd_opt_prefix_info { /* prefix information */ + u_int8_t nd_opt_pi_type; + u_int8_t nd_opt_pi_len; + u_int8_t nd_opt_pi_prefix_len; + u_int8_t nd_opt_pi_flags_reserved; + u_int8_t nd_opt_pi_valid_time[4]; + u_int8_t nd_opt_pi_preferred_time[4]; + u_int8_t nd_opt_pi_reserved2[4]; + struct in6_addr nd_opt_pi_prefix; +}; + +#define ND_OPT_PI_FLAG_ONLINK 0x80 +#define ND_OPT_PI_FLAG_AUTO 0x40 +#define ND_OPT_PI_FLAG_ROUTER 0x20 /*2292bis*/ + +struct nd_opt_rd_hdr { /* redirected header */ + u_int8_t nd_opt_rh_type; + u_int8_t nd_opt_rh_len; + u_int16_t nd_opt_rh_reserved1; + u_int32_t nd_opt_rh_reserved2; + /* followed by IP header and data */ +}; + +struct nd_opt_mtu { /* MTU option */ + u_int8_t nd_opt_mtu_type; + u_int8_t nd_opt_mtu_len; + u_int16_t nd_opt_mtu_reserved; + u_int32_t nd_opt_mtu_mtu; +}; + +struct nd_opt_rdnss { /* RDNSS RFC 6106 5.1 */ + u_int8_t nd_opt_rdnss_type; + u_int8_t nd_opt_rdnss_len; + u_int16_t nd_opt_rdnss_reserved; + u_int32_t nd_opt_rdnss_lifetime; + struct in6_addr nd_opt_rdnss_addr[1]; /* variable-length */ +}; + +struct nd_opt_dnssl { /* DNSSL RFC 6106 5.2 */ + u_int8_t nd_opt_dnssl_type; + u_int8_t nd_opt_dnssl_len; + u_int16_t nd_opt_dnssl_reserved; + u_int32_t nd_opt_dnssl_lifetime; + /* followed by list of DNS search domains, variable-length */ +}; + +struct nd_opt_advinterval { /* Advertisement interval option */ + u_int8_t nd_opt_adv_type; + u_int8_t nd_opt_adv_len; + u_int16_t nd_opt_adv_reserved; + u_int32_t nd_opt_adv_interval; +}; + +struct nd_opt_homeagent_info { /* Home Agent info */ + u_int8_t nd_opt_hai_type; + u_int8_t nd_opt_hai_len; + u_int16_t nd_opt_hai_reserved; + int16_t nd_opt_hai_preference; + u_int16_t nd_opt_hai_lifetime; +}; + +struct nd_opt_route_info { /* route info */ + u_int8_t nd_opt_rti_type; + u_int8_t nd_opt_rti_len; + u_int8_t nd_opt_rti_prefixlen; + u_int8_t nd_opt_rti_flags; + u_int32_t nd_opt_rti_lifetime; + /* prefix follows */ +}; + +/* + * icmp6 namelookup + */ + +struct icmp6_namelookup { + struct icmp6_hdr icmp6_nl_hdr; + u_int8_t icmp6_nl_nonce[8]; + int32_t icmp6_nl_ttl; +#if 0 + u_int8_t icmp6_nl_len; + u_int8_t icmp6_nl_name[3]; +#endif + /* could be followed by options */ +}; + +/* + * icmp6 node information + */ +struct icmp6_nodeinfo { + struct icmp6_hdr icmp6_ni_hdr; + u_int8_t icmp6_ni_nonce[8]; + /* could be followed by reply data */ +}; + +#define ni_type icmp6_ni_hdr.icmp6_type +#define ni_code icmp6_ni_hdr.icmp6_code +#define ni_cksum icmp6_ni_hdr.icmp6_cksum +#define ni_qtype icmp6_ni_hdr.icmp6_data16[0] +#define ni_flags icmp6_ni_hdr.icmp6_data16[1] + +#define NI_QTYPE_NOOP 0 /* NOOP */ +#define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes */ +#define NI_QTYPE_FQDN 2 /* FQDN (draft 04) */ +#define NI_QTYPE_DNSNAME 2 /* DNS Name */ +#define NI_QTYPE_NODEADDR 3 /* Node Addresses */ +#define NI_QTYPE_IPV4ADDR 4 /* IPv4 Addresses */ + +/* network endian */ +#define NI_SUPTYPE_FLAG_COMPRESS ((u_int16_t)htons(0x1)) +#define NI_FQDN_FLAG_VALIDTTL ((u_int16_t)htons(0x1)) + +/* network endian */ +#define NI_NODEADDR_FLAG_TRUNCATE ((u_int16_t)htons(0x1)) +#define NI_NODEADDR_FLAG_ALL ((u_int16_t)htons(0x2)) +#define NI_NODEADDR_FLAG_COMPAT ((u_int16_t)htons(0x4)) +#define NI_NODEADDR_FLAG_LINKLOCAL ((u_int16_t)htons(0x8)) +#define NI_NODEADDR_FLAG_SITELOCAL ((u_int16_t)htons(0x10)) +#define NI_NODEADDR_FLAG_GLOBAL ((u_int16_t)htons(0x20)) +#define NI_NODEADDR_FLAG_ANYCAST ((u_int16_t)htons(0x40)) /* just experimental. not in spec */ + +struct ni_reply_fqdn { + u_int32_t ni_fqdn_ttl; /* TTL */ + u_int8_t ni_fqdn_namelen; /* length in octets of the FQDN */ + u_int8_t ni_fqdn_name[3]; /* XXX: alignment */ +}; + +/* + * Router Renumbering. as router-renum-08.txt + */ +struct icmp6_router_renum { /* router renumbering header */ + struct icmp6_hdr rr_hdr; + u_int8_t rr_segnum; + u_int8_t rr_flags; + u_int16_t rr_maxdelay; + u_int32_t rr_reserved; +}; +#define ICMP6_RR_FLAGS_TEST 0x80 +#define ICMP6_RR_FLAGS_REQRESULT 0x40 +#define ICMP6_RR_FLAGS_FORCEAPPLY 0x20 +#define ICMP6_RR_FLAGS_SPECSITE 0x10 +#define ICMP6_RR_FLAGS_PREVDONE 0x08 + +#define rr_type rr_hdr.icmp6_type +#define rr_code rr_hdr.icmp6_code +#define rr_cksum rr_hdr.icmp6_cksum +#define rr_seqnum rr_hdr.icmp6_data32[0] + +struct rr_pco_match { /* match prefix part */ + u_int8_t rpm_code; + u_int8_t rpm_len; + u_int8_t rpm_ordinal; + u_int8_t rpm_matchlen; + u_int8_t rpm_minlen; + u_int8_t rpm_maxlen; + u_int16_t rpm_reserved; + struct in6_addr rpm_prefix; +}; + +#define RPM_PCO_ADD 1 +#define RPM_PCO_CHANGE 2 +#define RPM_PCO_SETGLOBAL 3 +#define RPM_PCO_MAX 4 + +struct rr_pco_use { /* use prefix part */ + u_int8_t rpu_uselen; + u_int8_t rpu_keeplen; + u_int8_t rpu_ramask; + u_int8_t rpu_raflags; + u_int32_t rpu_vltime; + u_int32_t rpu_pltime; + u_int32_t rpu_flags; + struct in6_addr rpu_prefix; +}; +#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x80 +#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x40 + +/* network endian */ +#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME ((u_int32_t)htonl(0x80000000)) +#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME ((u_int32_t)htonl(0x40000000)) + +struct rr_result { /* router renumbering result message */ + u_int16_t rrr_flags; + u_int8_t rrr_ordinal; + u_int8_t rrr_matchedlen; + u_int32_t rrr_ifid; + struct in6_addr rrr_prefix; +}; +/* network endian */ +#define ICMP6_RR_RESULT_FLAGS_OOB ((u_int16_t)htons(0x0002)) +#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN ((u_int16_t)htons(0x0001)) + +#endif /* not _NETINET_ICMP6_H_ */ diff --git a/freebsd/contrib/tcpdump/ieee802_11.h b/freebsd/contrib/tcpdump/ieee802_11.h new file mode 100644 index 00000000..2aa13450 --- /dev/null +++ b/freebsd/contrib/tcpdump/ieee802_11.h @@ -0,0 +1,347 @@ +/* @(#) $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) diff --git a/freebsd/contrib/tcpdump/ieee802_11_radio.h b/freebsd/contrib/tcpdump/ieee802_11_radio.h new file mode 100644 index 00000000..812b5ac3 --- /dev/null +++ b/freebsd/contrib/tcpdump/ieee802_11_radio.h @@ -0,0 +1,291 @@ +/* $FreeBSD$ */ +/* 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 + +/* 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 + +#endif /* _NET_IF_IEEE80211RADIOTAP_H_ */ diff --git a/freebsd/contrib/tcpdump/igrp.h b/freebsd/contrib/tcpdump/igrp.h new file mode 100644 index 00000000..b5f133bc --- /dev/null +++ b/freebsd/contrib/tcpdump/igrp.h @@ -0,0 +1,33 @@ +/* @(#) $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 ! */ diff --git a/freebsd/contrib/tcpdump/in_cksum.c b/freebsd/contrib/tcpdump/in_cksum.c new file mode 100644 index 00000000..bfd6be98 --- /dev/null +++ b/freebsd/contrib/tcpdump/in_cksum.c @@ -0,0 +1,202 @@ +#include <machine/rtems-bsd-user-space.h> + +/* in_cksum.c + * 4.4-Lite-2 Internet checksum routine, modified to take a vector of + * pointers/lengths giving the pieces to be checksummed. Also using + * Tahoe/CGI version of ADDCARRY(x) macro instead of from portable version. + */ + +/* + * Copyright (c) 1988, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that 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 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. + * + * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include "interface.h" + +/* + * Checksum routine for Internet Protocol family headers (Portable Version). + * + * This routine is very heavily used in the network + * code and should be modified for each CPU to be as fast as possible. + */ + +#define ADDCARRY(x) {if ((x) > 65535) (x) -= 65535;} +#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} + +u_int16_t +in_cksum(const struct cksum_vec *vec, int veclen) +{ + register const u_int16_t *w; + register int sum = 0; + register int mlen = 0; + int byte_swapped = 0; + + union { + u_int8_t c[2]; + u_int16_t s; + } s_util; + union { + u_int16_t s[2]; + u_int32_t l; + } l_util; + + for (; veclen != 0; vec++, veclen--) { + if (vec->len == 0) + continue; + w = (const u_int16_t *)(void *)vec->ptr; + if (mlen == -1) { + /* + * The first byte of this chunk is the continuation + * of a word spanning between this chunk and the + * last chunk. + * + * s_util.c[0] is already saved when scanning previous + * chunk. + */ + s_util.c[1] = *(const u_int8_t *)w; + sum += s_util.s; + w = (const u_int16_t *)(void *)((const u_int8_t *)w + 1); + mlen = vec->len - 1; + } else + mlen = vec->len; + /* + * Force to even boundary. + */ + if ((1 & (unsigned long) w) && (mlen > 0)) { + REDUCE; + sum <<= 8; + s_util.c[0] = *(const u_int8_t *)w; + w = (const u_int16_t *)(void *)((const u_int8_t *)w + 1); + mlen--; + byte_swapped = 1; + } + /* + * Unroll the loop to make overhead from + * branches &c small. + */ + while ((mlen -= 32) >= 0) { + sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; + sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; + sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11]; + sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15]; + w += 16; + } + mlen += 32; + while ((mlen -= 8) >= 0) { + sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; + w += 4; + } + mlen += 8; + if (mlen == 0 && byte_swapped == 0) + continue; + REDUCE; + while ((mlen -= 2) >= 0) { + sum += *w++; + } + if (byte_swapped) { + REDUCE; + sum <<= 8; + byte_swapped = 0; + if (mlen == -1) { + s_util.c[1] = *(const u_int8_t *)w; + sum += s_util.s; + mlen = 0; + } else + mlen = -1; + } else if (mlen == -1) + s_util.c[0] = *(const u_int8_t *)w; + } + if (mlen == -1) { + /* The last mbuf has odd # of bytes. Follow the + standard (the odd byte may be shifted left by 8 bits + or not as determined by endian-ness of the machine) */ + s_util.c[1] = 0; + sum += s_util.s; + } + REDUCE; + return (~sum & 0xffff); +} + +/* + * Given the host-byte-order value of the checksum field in a packet + * header, and the network-byte-order computed checksum of the data + * that the checksum covers (including the checksum itself), compute + * what the checksum field *should* have been. + */ +u_int16_t +in_cksum_shouldbe(u_int16_t sum, u_int16_t computed_sum) +{ + u_int32_t shouldbe; + + /* + * The value that should have gone into the checksum field + * is the negative of the value gotten by summing up everything + * *but* the checksum field. + * + * We can compute that by subtracting the value of the checksum + * field from the sum of all the data in the packet, and then + * computing the negative of that value. + * + * "sum" is the value of the checksum field, and "computed_sum" + * is the negative of the sum of all the data in the packets, + * so that's -(-computed_sum - sum), or (sum + computed_sum). + * + * All the arithmetic in question is one's complement, so the + * addition must include an end-around carry; we do this by + * doing the arithmetic in 32 bits (with no sign-extension), + * and then adding the upper 16 bits of the sum, which contain + * the carry, to the lower 16 bits of the sum, and then do it + * again in case *that* sum produced a carry. + * + * As RFC 1071 notes, the checksum can be computed without + * byte-swapping the 16-bit words; summing 16-bit words + * on a big-endian machine gives a big-endian checksum, which + * can be directly stuffed into the big-endian checksum fields + * in protocol headers, and summing words on a little-endian + * machine gives a little-endian checksum, which must be + * byte-swapped before being stuffed into a big-endian checksum + * field. + * + * "computed_sum" is a network-byte-order value, so we must put + * it in host byte order before subtracting it from the + * host-byte-order value from the header; the adjusted checksum + * will be in host byte order, which is what we'll return. + */ + shouldbe = sum; + shouldbe += ntohs(computed_sum); + shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); + shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); + return shouldbe; +} diff --git a/freebsd/contrib/tcpdump/interface.h b/freebsd/contrib/tcpdump/interface.h new file mode 100644 index 00000000..175c33e2 --- /dev/null +++ b/freebsd/contrib/tcpdump/interface.h @@ -0,0 +1,400 @@ +/* + * Copyright (c) 1988-2002 + * 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/interface.h,v 1.285 2008-08-16 11:36:20 hannes Exp $ (LBL) + */ + +#ifndef tcpdump_interface_h +#define tcpdump_interface_h + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +/* snprintf et al */ + +#include <stdarg.h> + +#if HAVE_STDINT_H +#include <stdint.h> +#endif + +#if !defined(HAVE_SNPRINTF) +int snprintf(char *, size_t, const char *, ...) + __attribute__((format(printf, 3, 4))); +#endif + +#if !defined(HAVE_VSNPRINTF) +int vsnprintf(char *, size_t, const char *, va_list) + __attribute__((format(printf, 3, 0))); +#endif + +#ifndef HAVE_STRLCAT +extern size_t strlcat(char *, const char *, size_t); +#endif +#ifndef HAVE_STRLCPY +extern size_t strlcpy(char *, const char *, size_t); +#endif + +#ifndef HAVE_STRDUP +extern char *strdup(const char *); +#endif + +#ifndef HAVE_STRSEP +extern char *strsep(char **, const char *); +#endif + +#define PT_VAT 1 /* Visual Audio Tool */ +#define PT_WB 2 /* distributed White Board */ +#define PT_RPC 3 /* Remote Procedure Call */ +#define PT_RTP 4 /* Real-Time Applications protocol */ +#define PT_RTCP 5 /* Real-Time Applications control protocol */ +#define PT_SNMP 6 /* Simple Network Management Protocol */ +#define PT_CNFP 7 /* Cisco NetFlow protocol */ +#define PT_TFTP 8 /* trivial file transfer protocol */ +#define PT_AODV 9 /* Ad-hoc On-demand Distance Vector Protocol */ +#define PT_CARP 10 /* Common Address Redundancy Protocol */ +#define PT_RADIUS 11 /* RADIUS authentication Protocol */ +#define PT_ZMTP1 12 /* ZeroMQ Message Transport Protocol 1.0 */ +#define PT_VXLAN 13 /* Virtual eXtensible Local Area Network */ + +#ifndef min +#define min(a,b) ((a)>(b)?(b):(a)) +#endif +#ifndef max +#define max(a,b) ((b)>(a)?(b):(a)) +#endif + +#define ESRC(ep) ((ep)->ether_shost) +#define EDST(ep) ((ep)->ether_dhost) + +#ifndef NTOHL +#define NTOHL(x) (x) = ntohl(x) +#define NTOHS(x) (x) = ntohs(x) +#define HTONL(x) (x) = htonl(x) +#define HTONS(x) (x) = htons(x) +#endif +#endif + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif + +extern char *program_name; /* used to generate self-identifying messages */ + +extern int32_t thiszone; /* seconds offset from gmt to local time */ + +/* + * True if "l" bytes of "var" were captured. + * + * The "snapend - (l) <= snapend" checks to make sure "l" isn't so large + * that "snapend - (l)" underflows. + * + * The check is for <= rather than < because "l" might be 0. + */ +#define TTEST2(var, l) (snapend - (l) <= snapend && \ + (const u_char *)&(var) <= snapend - (l)) + +/* True if "var" was captured */ +#define TTEST(var) TTEST2(var, sizeof(var)) + +/* Bail if "l" bytes of "var" were not captured */ +#define TCHECK2(var, l) if (!TTEST2(var, l)) goto trunc + +/* Bail if "var" was not captured */ +#define TCHECK(var) TCHECK2(var, sizeof(var)) + +extern void ts_print(const struct timeval *); +extern void relts_print(int); + +extern int fn_print(const u_char *, const u_char *); +extern int fn_printn(const u_char *, u_int, const u_char *); +extern int fn_printzp(const u_char *, u_int, const u_char *); +extern int mask2plen(u_int32_t); +extern const char *tok2strary_internal(const char **, int, const char *, int); +#define tok2strary(a,f,i) tok2strary_internal(a, sizeof(a)/sizeof(a[0]),f,i) + +extern const char *dnaddr_string(u_short); + +extern void error(const char *, ...) + __attribute__((noreturn, format (printf, 1, 2))); +extern void warning(const char *, ...) __attribute__ ((format (printf, 1, 2))); + +extern char *read_infile(char *); +extern char *copy_argv(char **); + +extern void safeputchar(int); +extern void safeputs(const char *, int); + +extern const char *isonsap_string(const u_char *, register u_int); +extern const char *protoid_string(const u_char *); +extern const char *ipxsap_string(u_short); +extern const char *dnname_string(u_short); +extern const char *dnnum_string(u_short); + +/* checksum routines */ +extern void init_checksum(void); +extern u_int16_t verify_crc10_cksum(u_int16_t, const u_char *, int); +extern u_int16_t create_osi_cksum(const u_int8_t *, int, int); + +/* The printer routines. */ + +#include <pcap.h> + +extern int print_unknown_data(const u_char *, const char *,int); +extern void ascii_print(const u_char *, u_int); +extern void hex_and_ascii_print_with_offset(const char *, const u_char *, + u_int, u_int); +extern void hex_and_ascii_print(const char *, const u_char *, u_int); +extern void hex_print_with_offset(const char *, const u_char *, u_int, u_int); +extern void hex_print(const char *, const u_char *, u_int); +extern void telnet_print(const u_char *, u_int); +extern int llc_print(const u_char *, u_int, u_int, const u_char *, + const u_char *, u_short *); +extern int snap_print(const u_char *, u_int, u_int, u_int); +extern void aarp_print(const u_char *, u_int); +extern void aodv_print(const u_char *, u_int, int); +extern void atalk_print(const u_char *, u_int); +extern void atm_print(u_int, u_int, u_int, const u_char *, u_int, u_int); +extern u_int atm_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int sunatm_if_print(const struct pcap_pkthdr *, const u_char *); +extern int oam_print(const u_char *, u_int, u_int); +extern void bootp_print(const u_char *, u_int); +extern void bgp_print(const u_char *, int); +extern void beep_print(const u_char *, u_int); +extern void cnfp_print(const u_char *, const u_char *); +extern void decnet_print(const u_char *, u_int, u_int); +extern void default_print(const u_char *, u_int); +extern void dvmrp_print(const u_char *, u_int); +extern void egp_print(const u_char *, u_int); +extern u_int enc_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int pflog_if_print(const struct pcap_pkthdr *, const u_char *); +extern void pfsync_ip_print(const u_char *, u_int); +extern u_int arcnet_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int arcnet_linux_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int token_print(const u_char *, u_int, u_int); +extern u_int token_if_print(const struct pcap_pkthdr *, const u_char *); +extern void fddi_print(const u_char *, u_int, u_int); +extern u_int fddi_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int fr_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int mfr_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int fr_print(register const u_char *, u_int); +extern u_int mfr_print(register const u_char *, u_int); +extern char *q922_string(const u_char *); +extern u_int ieee802_11_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int ieee802_11_radio_if_print(const struct pcap_pkthdr *, + const u_char *); +extern u_int ap1394_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *, + const u_char *); +extern void gre_print(const u_char *, u_int); +extern void icmp_print(const u_char *, u_int, const u_char *, int); +extern void igmp_print(const u_char *, u_int); +extern void igrp_print(const u_char *, u_int, const u_char *); +extern void ipN_print(const u_char *, u_int); +extern u_int ipfc_if_print(const struct pcap_pkthdr *, const u_char *); +extern void ipx_print(const u_char *, u_int); +extern void isoclns_print(const u_char *, u_int, u_int); +extern void krb_print(const u_char *); +extern u_int llap_print(const u_char *, u_int); +extern u_int ltalk_if_print(const struct pcap_pkthdr *, const u_char *); +extern void msdp_print(const unsigned char *, u_int); +extern void nfsreply_print(const u_char *, u_int, const u_char *); +extern void nfsreq_print(const u_char *, u_int, const u_char *); +extern void ns_print(const u_char *, u_int, int); +extern const u_char * ns_nprint (register const u_char *, register const u_char *); +extern void ntp_print(const u_char *, u_int); +extern u_int null_if_print(const struct pcap_pkthdr *, const u_char *); +extern void ospf_print(const u_char *, u_int, const u_char *); +extern void olsr_print (const u_char *, u_int, int); +extern void pimv1_print(const u_char *, u_int); +extern void cisco_autorp_print(const u_char *, u_int); +extern void rsvp_print(const u_char *, u_int); +extern void ldp_print(const u_char *, u_int); +extern void lldp_print(const u_char *, u_int); +extern void rpki_rtr_print(const u_char *, u_int); +extern void lmp_print(const u_char *, u_int); +extern void lspping_print(const u_char *, u_int); +extern void lwapp_control_print(const u_char *, u_int, int); +extern void lwapp_data_print(const u_char *, u_int); +extern void eigrp_print(const u_char *, u_int); +extern void mobile_print(const u_char *, u_int); +extern void pim_print(const u_char *, u_int, u_int); +extern u_int pppoe_print(const u_char *, u_int); +extern u_int ppp_print(register const u_char *, u_int); +extern u_int ppp_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int ppp_hdlc_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int ppp_bsdos_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int pppoe_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int prism_if_print(const struct pcap_pkthdr *, const u_char *); +extern void q933_print(const u_char *, u_int); +extern int vjc_print(register const char *, u_short); +extern void vqp_print(register const u_char *, register u_int); +extern u_int raw_if_print(const struct pcap_pkthdr *, const u_char *); +extern void rip_print(const u_char *, u_int); +extern u_int sl_if_print(const struct pcap_pkthdr *, const u_char *); +extern void lane_print(const u_char *, u_int, u_int); +extern u_int lane_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int cip_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int sl_bsdos_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int chdlc_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int chdlc_print(register const u_char *, u_int); +extern u_int juniper_atm1_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_atm2_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_mfr_print(const struct pcap_pkthdr *, register const u_char *); +extern u_int juniper_mlfr_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_mlppp_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_pppoe_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_pppoe_atm_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_ggsn_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_es_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_monitor_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_services_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_ether_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_ppp_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_frelay_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_chdlc_print(const struct pcap_pkthdr *, const u_char *); +extern u_int sll_if_print(const struct pcap_pkthdr *, const u_char *); +extern void snmp_print(const u_char *, u_int); +extern void sunrpcrequest_print(const u_char *, u_int, const u_char *); +extern u_int symantec_if_print(const struct pcap_pkthdr *, const u_char *); +extern void tcp_print(const u_char *, u_int, const u_char *, int); +extern void tftp_print(const u_char *, u_int); +extern void timed_print(const u_char *); +extern void udld_print(const u_char *, u_int); +extern void udp_print(const u_char *, u_int, const u_char *, int); +extern void vtp_print(const u_char *, u_int); +extern void wb_print(const void *, u_int); +extern int ah_print(register const u_char *); +extern int ipcomp_print(register const u_char *, int *); +extern void rx_print(register const u_char *, int, int, int, u_char *); +extern void netbeui_print(u_short, const u_char *, int); +extern void ipx_netbios_print(const u_char *, u_int); +extern void nbt_tcp_print(const u_char *, int); +extern void nbt_udp137_print(const u_char *, int); +extern void nbt_udp138_print(const u_char *, int); +extern void smb_tcp_print(const u_char *, int); +extern char *smb_errstr(int, int); +extern const char *nt_errstr(u_int32_t); +extern void print_data(const unsigned char *, int); +extern void l2tp_print(const u_char *, u_int); +extern void vrrp_print(const u_char *, u_int, int); +extern void carp_print(const u_char *, u_int, int); +extern void slow_print(const u_char *, u_int); +extern void sflow_print(const u_char *, u_int); +extern void mpcp_print(const u_char *, u_int); +extern void cfm_print(const u_char *, u_int); +extern void pgm_print(const u_char *, u_int, const u_char *); +extern void cdp_print(const u_char *, u_int, u_int); +extern void dtp_print(const u_char *, u_int); +extern void stp_print(const u_char *, u_int); +extern void radius_print(const u_char *, u_int); +extern void lwres_print(const u_char *, u_int); +extern void pptp_print(const u_char *); +extern void dccp_print(const u_char *, const u_char *, u_int); +extern void sctp_print(const u_char *, const u_char *, u_int); +extern void forces_print(const u_char *, u_int); +extern void mpls_print(const u_char *, u_int); +extern void mpls_lsp_ping_print(const u_char *, u_int); +extern void zephyr_print(const u_char *, int); +extern void zmtp1_print(const u_char *, u_int); +extern void hsrp_print(const u_char *, u_int); +extern void bfd_print(const u_char *, u_int, u_int); +extern void sip_print(const u_char *, u_int); +extern void syslog_print(const u_char *, u_int); +extern u_int bt_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int usb_linux_48_byte_print(const struct pcap_pkthdr *, const u_char *); +extern u_int usb_linux_64_byte_print(const struct pcap_pkthdr *, const u_char *); +extern void vxlan_print(const u_char *, u_int); +extern void otv_print(const u_char *, u_int); + + +#ifdef INET6 +extern void ip6_opt_print(const u_char *, int); +extern int hbhopt_print(const u_char *); +extern int dstopt_print(const u_char *); +extern int frag6_print(const u_char *, const u_char *); +extern int mobility_print(const u_char *, const u_char *); +extern void ripng_print(const u_char *, unsigned int); +extern int rt6_print(const u_char *, const u_char *); +extern void ospf6_print(const u_char *, u_int); +extern void dhcp6_print(const u_char *, u_int); +extern void babel_print(const u_char *, u_int); +extern int mask62plen(const u_char *); +#endif /*INET6*/ + +struct cksum_vec { + const u_int8_t *ptr; + int len; +}; +extern u_int16_t in_cksum(const struct cksum_vec *, int); +extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t); + +#ifndef HAVE_BPF_DUMP +struct bpf_program; + +extern void bpf_dump(const struct bpf_program *, int); + +#endif + +#include "netdissect.h" + +/* forward compatibility */ + +#ifndef NETDISSECT_REWORKED +extern netdissect_options *gndo; + +#define bflag gndo->ndo_bflag +#define eflag gndo->ndo_eflag +#define fflag gndo->ndo_fflag +#define jflag gndo->ndo_jflag +#define Kflag gndo->ndo_Kflag +#define nflag gndo->ndo_nflag +#define Nflag gndo->ndo_Nflag +#define Oflag gndo->ndo_Oflag +#define pflag gndo->ndo_pflag +#define qflag gndo->ndo_qflag +#define Rflag gndo->ndo_Rflag +#define sflag gndo->ndo_sflag +#define Sflag gndo->ndo_Sflag +#define tflag gndo->ndo_tflag +#define Uflag gndo->ndo_Uflag +#define uflag gndo->ndo_uflag +#define vflag gndo->ndo_vflag +#define xflag gndo->ndo_xflag +#define Xflag gndo->ndo_Xflag +#define Cflag gndo->ndo_Cflag +#define Gflag gndo->ndo_Gflag +#define Aflag gndo->ndo_Aflag +#define Bflag gndo->ndo_Bflag +#define Iflag gndo->ndo_Iflag +#define suppress_default_print gndo->ndo_suppress_default_print +#define packettype gndo->ndo_packettype +#define sigsecret gndo->ndo_sigsecret +#define Wflag gndo->ndo_Wflag +#define WflagChars gndo->ndo_WflagChars +#define Cflag_count gndo->ndo_Cflag_count +#define Gflag_count gndo->ndo_Gflag_count +#define Gflag_time gndo->ndo_Gflag_time +#define Hflag gndo->ndo_Hflag +#define snaplen gndo->ndo_snaplen +#define snapend gndo->ndo_snapend + +#endif diff --git a/freebsd/contrib/tcpdump/ip.h b/freebsd/contrib/tcpdump/ip.h new file mode 100644 index 00000000..8a97632e --- /dev/null +++ b/freebsd/contrib/tcpdump/ip.h @@ -0,0 +1,164 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/ip.h,v 1.12 2007-09-14 01:29:28 guy 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. + * + * @(#)ip.h 8.2 (Berkeley) 6/1/94 + */ + +/* + * Definitions for internet protocol version 4. + * Per RFC 791, September 1981. + */ +#define IPVERSION 4 + +/* + * Structure of an internet header, naked of options. + * + * We declare ip_len and ip_off to be short, rather than u_short + * pragmatically since otherwise unsigned comparisons can result + * against negative integers quite easily, and fail in subtle ways. + */ +struct ip { + u_int8_t ip_vhl; /* header length, version */ +#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4) +#define IP_HL(ip) ((ip)->ip_vhl & 0x0f) + u_int8_t ip_tos; /* type of service */ + u_int16_t ip_len; /* total length */ + u_int16_t ip_id; /* identification */ + u_int16_t ip_off; /* fragment offset field */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_int8_t ip_ttl; /* time to live */ + u_int8_t ip_p; /* protocol */ + u_int16_t ip_sum; /* checksum */ + struct in_addr ip_src,ip_dst; /* source and dest address */ +} UNALIGNED; + +#define IP_MAXPACKET 65535 /* maximum packet size */ + +/* + * Definitions for IP type of service (ip_tos) + */ +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 + +/* + * Definitions for IP precedence (also in ip_tos) (hopefully unused) + */ +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 + +/* + * Definitions for options. + */ +#define IPOPT_COPIED(o) ((o)&0x80) +#define IPOPT_CLASS(o) ((o)&0x60) +#define IPOPT_NUMBER(o) ((o)&0x1f) + +#define IPOPT_CONTROL 0x00 +#define IPOPT_RESERVED1 0x20 +#define IPOPT_DEBMEAS 0x40 +#define IPOPT_RESERVED2 0x60 + +#define IPOPT_EOL 0 /* end of option list */ +#define IPOPT_NOP 1 /* no operation */ + +#define IPOPT_RR 7 /* record packet route */ +#define IPOPT_TS 68 /* timestamp */ +#define IPOPT_RFC1393 82 /* traceroute RFC 1393 */ +#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ +#define IPOPT_LSRR 131 /* loose source route */ +#define IPOPT_SATID 136 /* satnet id */ +#define IPOPT_SSRR 137 /* strict source route */ +#define IPOPT_RA 148 /* router-alert, rfc2113 */ + +/* + * Offsets to fields in options other than EOL and NOP. + */ +#define IPOPT_OPTVAL 0 /* option ID */ +#define IPOPT_OLEN 1 /* option length */ +#define IPOPT_OFFSET 2 /* offset within option */ +#define IPOPT_MINOFF 4 /* min value of above */ + +/* + * Time stamp option structure. + */ +struct ip_timestamp { + u_int8_t ipt_code; /* IPOPT_TS */ + u_int8_t ipt_len; /* size of structure (variable) */ + u_int8_t ipt_ptr; /* index of current entry */ + u_int8_t ipt_oflwflg; /* flags, overflow counter */ +#define IPTS_OFLW(ip) (((ipt)->ipt_oflwflg & 0xf0) >> 4) +#define IPTS_FLG(ip) ((ipt)->ipt_oflwflg & 0x0f) + union ipt_timestamp { + u_int32_t ipt_time[1]; + struct ipt_ta { + struct in_addr ipt_addr; + u_int32_t ipt_time; + } ipt_ta[1]; + } ipt_timestamp; +} UNALIGNED; + +/* flag bits for ipt_flg */ +#define IPOPT_TS_TSONLY 0 /* timestamps only */ +#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define IPOPT_TS_PRESPEC 3 /* specified modules only */ + +/* bits for security (not byte swapped) */ +#define IPOPT_SECUR_UNCLASS 0x0000 +#define IPOPT_SECUR_CONFID 0xf135 +#define IPOPT_SECUR_EFTO 0x789a +#define IPOPT_SECUR_MMMM 0xbc4d +#define IPOPT_SECUR_RESTR 0xaf13 +#define IPOPT_SECUR_SECRET 0xd788 +#define IPOPT_SECUR_TOPSECRET 0x6bc5 + +/* + * Internet implementation parameters. + */ +#define MAXTTL 255 /* maximum time to live (seconds) */ +#define IPDEFTTL 64 /* default ttl, from RFC 1340 */ +#define IPFRAGTTL 60 /* time to live for frags, slowhz */ +#define IPTTLDEC 1 /* subtracted when forwarding */ + +#define IP_MSS 576 /* default maximum segment size */ + +/* in print-ip.c */ +extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int); diff --git a/freebsd/contrib/tcpdump/ip6.h b/freebsd/contrib/tcpdump/ip6.h new file mode 100644 index 00000000..12c87ad2 --- /dev/null +++ b/freebsd/contrib/tcpdump/ip6.h @@ -0,0 +1,192 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/ip6.h,v 1.8 2007-08-29 02:31:44 mcr Exp $ (LBL) */ +/* NetBSD: ip6.h,v 1.9 2000/07/13 05:34:21 itojun Exp */ +/* $KAME: ip6.h,v 1.9 2000/07/02 21:01:32 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 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. + */ + +/* + * 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. + * + * @(#)ip.h 8.1 (Berkeley) 6/10/93 + */ + +#ifndef _NETINET_IP6_H_ +#define _NETINET_IP6_H_ + +/* + * Definition for internet protocol version 6. + * RFC 2460 + */ + +struct ip6_hdr { + union { + struct ip6_hdrctl { + u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */ + u_int16_t ip6_un1_plen; /* payload length */ + u_int8_t ip6_un1_nxt; /* next header */ + u_int8_t ip6_un1_hlim; /* hop limit */ + } ip6_un1; + u_int8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */ + } ip6_ctlun; + struct in6_addr ip6_src; /* source address */ + struct in6_addr ip6_dst; /* destination address */ +} UNALIGNED; + +#define ip6_vfc ip6_ctlun.ip6_un2_vfc +#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow +#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen +#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt +#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim +#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim + +/* in network endian */ +#define IPV6_FLOWINFO_MASK ((u_int32_t)htonl(0x0fffffff)) /* flow info (28 bits) */ +#define IPV6_FLOWLABEL_MASK ((u_int32_t)htonl(0x000fffff)) /* flow label (20 bits) */ +#if 1 +/* ECN bits proposed by Sally Floyd */ +#define IP6TOS_CE 0x01 /* congestion experienced */ +#define IP6TOS_ECT 0x02 /* ECN-capable transport */ +#endif + +/* + * Extension Headers + */ + +struct ip6_ext { + u_int8_t ip6e_nxt; + u_int8_t ip6e_len; +} UNALIGNED; + +/* Hop-by-Hop options header */ +struct ip6_hbh { + u_int8_t ip6h_nxt; /* next header */ + u_int8_t ip6h_len; /* length in units of 8 octets */ + /* followed by options */ +} UNALIGNED; + +/* Destination options header */ +struct ip6_dest { + u_int8_t ip6d_nxt; /* next header */ + u_int8_t ip6d_len; /* length in units of 8 octets */ + /* followed by options */ +} UNALIGNED; + +/* Option types and related macros */ +#define IP6OPT_PAD1 0x00 /* 00 0 00000 */ +#define IP6OPT_PADN 0x01 /* 00 0 00001 */ +#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ +#define IP6OPT_JUMBO_LEN 6 +#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */ + +#define IP6OPT_RTALERT_LEN 4 +#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ +#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ +#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ +#define IP6OPT_MINLEN 2 + +#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */ +#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */ +#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */ +#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */ +#define IP6OPT_EID 0x8a /* 10 0 01010 */ + +#define IP6OPT_TYPE(o) ((o) & 0xC0) +#define IP6OPT_TYPE_SKIP 0x00 +#define IP6OPT_TYPE_DISCARD 0x40 +#define IP6OPT_TYPE_FORCEICMP 0x80 +#define IP6OPT_TYPE_ICMP 0xC0 + +#define IP6OPT_MUTABLE 0x20 + +/* Routing header */ +struct ip6_rthdr { + u_int8_t ip6r_nxt; /* next header */ + u_int8_t ip6r_len; /* length in units of 8 octets */ + u_int8_t ip6r_type; /* routing type */ + u_int8_t ip6r_segleft; /* segments left */ + /* followed by routing type specific data */ +} UNALIGNED; + +/* Type 0 Routing header */ +struct ip6_rthdr0 { + u_int8_t ip6r0_nxt; /* next header */ + u_int8_t ip6r0_len; /* length in units of 8 octets */ + u_int8_t ip6r0_type; /* always zero */ + u_int8_t ip6r0_segleft; /* segments left */ + u_int8_t ip6r0_reserved; /* reserved field */ + u_int8_t ip6r0_slmap[3]; /* strict/loose bit map */ + struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */ +} UNALIGNED; + +/* Fragment header */ +struct ip6_frag { + u_int8_t ip6f_nxt; /* next header */ + u_int8_t ip6f_reserved; /* reserved field */ + u_int16_t ip6f_offlg; /* offset, reserved, and flag */ + u_int32_t ip6f_ident; /* identification */ +} UNALIGNED; + +#define IP6F_OFF_MASK 0xfff8 /* mask out offset from ip6f_offlg */ +#define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */ +#define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */ + +/* in print-ip6.c */ +extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int); + +#endif /* not _NETINET_IP6_H_ */ diff --git a/freebsd/contrib/tcpdump/ipfc.h b/freebsd/contrib/tcpdump/ipfc.h new file mode 100644 index 00000000..438d1156 --- /dev/null +++ b/freebsd/contrib/tcpdump/ipfc.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 1992, 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/ipfc.h,v 1.4 2002-12-11 07:13:53 guy Exp $ (LBL) + */ + +struct ipfc_header { + u_char ipfc_dhost[8]; + u_char ipfc_shost[8]; +}; + +#define IPFC_HDRLEN 16 diff --git a/freebsd/contrib/tcpdump/ipnet.h b/freebsd/contrib/tcpdump/ipnet.h new file mode 100644 index 00000000..ae692842 --- /dev/null +++ b/freebsd/contrib/tcpdump/ipnet.h @@ -0,0 +1,13 @@ +typedef struct ipnet_hdr { + uint8_t iph_version; + uint8_t iph_family; + uint16_t iph_htype; + uint32_t iph_pktlen; + uint32_t iph_ifindex; + uint32_t iph_grifindex; + uint32_t iph_zsrc; + uint32_t iph_zdst; +} ipnet_hdr_t; + +#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */ +#define IPH_AF_INET6 26 /* Matches Solaris's AF_INET6 */ diff --git a/freebsd/contrib/tcpdump/ipproto.c b/freebsd/contrib/tcpdump/ipproto.c new file mode 100644 index 00000000..a0ddf867 --- /dev/null +++ b/freebsd/contrib/tcpdump/ipproto.c @@ -0,0 +1,64 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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/ipproto.c,v 1.6 2005-09-20 06:01:22 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include "interface.h" +#include "ipproto.h" + +const struct tok ipproto_values[] = { + { IPPROTO_HOPOPTS, "Options" }, + { IPPROTO_ICMP, "ICMP" }, + { IPPROTO_IGMP, "IGMP" }, + { IPPROTO_IPV4, "IPIP" }, + { IPPROTO_TCP, "TCP" }, + { IPPROTO_EGP, "EGP" }, + { IPPROTO_PIGP, "IGRP" }, + { IPPROTO_UDP, "UDP" }, + { IPPROTO_DCCP, "DCCP" }, + { IPPROTO_IPV6, "IPv6" }, + { IPPROTO_ROUTING, "Routing" }, + { IPPROTO_FRAGMENT, "Fragment" }, + { IPPROTO_RSVP, "RSVP" }, + { IPPROTO_GRE, "GRE" }, + { IPPROTO_ESP, "ESP" }, + { IPPROTO_AH, "AH" }, + { IPPROTO_MOBILE, "Mobile IP" }, + { IPPROTO_ICMPV6, "ICMPv6" }, + { IPPROTO_MOBILITY_OLD, "Mobile IP (old)" }, + { IPPROTO_EIGRP, "EIGRP" }, + { IPPROTO_OSPF, "OSPF" }, + { IPPROTO_PIM, "PIM" }, + { IPPROTO_IPCOMP, "Compressed IP" }, + { IPPROTO_VRRP, "VRRP" }, + { IPPROTO_PGM, "PGM" }, + { IPPROTO_SCTP, "SCTP" }, + { IPPROTO_MOBILITY, "Mobility" }, + { IPPROTO_CARP, "CARP" }, + { IPPROTO_PFSYNC, "pfsync" }, + { 0, NULL } +}; + diff --git a/freebsd/contrib/tcpdump/ipproto.h b/freebsd/contrib/tcpdump/ipproto.h new file mode 100644 index 00000000..4b6bf51c --- /dev/null +++ b/freebsd/contrib/tcpdump/ipproto.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1982, 1986, 1990, 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. + * + * @(#) $Header: /tcpdump/master/tcpdump/ipproto.h,v 1.6 2005-09-20 06:01:22 guy Exp $ (LBL) + * + * From: + * @(#)in.h 8.3 (Berkeley) 1/3/94 + * $FreeBSD$ + * FreeBSD: src/sys/netinet/in.h,v 1.38.2.3 1999/08/29 16:29:34 peter Exp + */ + +extern const struct tok ipproto_values[]; + +#ifndef IPPROTO_IP +#define IPPROTO_IP 0 /* dummy for IP */ +#endif +#ifndef IPPROTO_HOPOPTS +#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ +#endif +#ifndef IPPROTO_ICMP +#define IPPROTO_ICMP 1 /* control message protocol */ +#endif +#ifndef IPPROTO_IGMP +#define IPPROTO_IGMP 2 /* group mgmt protocol */ +#endif +#ifndef IPPROTO_IPV4 +#define IPPROTO_IPV4 4 +#endif +#ifndef IPPROTO_TCP +#define IPPROTO_TCP 6 /* tcp */ +#endif +#ifndef IPPROTO_EGP +#define IPPROTO_EGP 8 /* exterior gateway protocol */ +#endif +#ifndef IPPROTO_PIGP +#define IPPROTO_PIGP 9 +#endif +#ifndef IPPROTO_UDP +#define IPPROTO_UDP 17 /* user datagram protocol */ +#endif +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 /* datagram congestion control protocol */ +#endif +#ifndef IPPROTO_IPV6 +#define IPPROTO_IPV6 41 +#endif +#ifndef IPPROTO_ROUTING +#define IPPROTO_ROUTING 43 /* IPv6 routing header */ +#endif +#ifndef IPPROTO_FRAGMENT +#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ +#endif +#ifndef IPPROTO_RSVP +#define IPPROTO_RSVP 46 /* resource reservation */ +#endif +#ifndef IPPROTO_GRE +#define IPPROTO_GRE 47 /* General Routing Encap. */ +#endif +#ifndef IPPROTO_ESP +#define IPPROTO_ESP 50 /* SIPP Encap Sec. Payload */ +#endif +#ifndef IPPROTO_AH +#define IPPROTO_AH 51 /* SIPP Auth Header */ +#endif +#ifndef IPPROTO_MOBILE +#define IPPROTO_MOBILE 55 +#endif +#ifndef IPPROTO_ICMPV6 +#define IPPROTO_ICMPV6 58 /* ICMPv6 */ +#endif +#ifndef IPPROTO_NONE +#define IPPROTO_NONE 59 /* IPv6 no next header */ +#endif +#ifndef IPPROTO_DSTOPTS +#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ +#endif +#ifndef IPPROTO_MOBILITY_OLD +/* + * The current Protocol Numbers list says that the IP protocol number for + * mobility headers is 135; it cites draft-ietf-mobileip-ipv6-24, but + * that draft doesn't actually give a number. + * + * It appears that 62 used to be used, even though that's assigned to + * a protocol called CFTP; however, the only reference for CFTP is a + * Network Message from BBN back in 1982, so, for now, we support 62, + * aas well as 135, as a protocol number for mobility headers. + */ +#define IPPROTO_MOBILITY_OLD 62 +#endif +#ifndef IPPROTO_ND +#define IPPROTO_ND 77 /* Sun net disk proto (temp.) */ +#endif +#ifndef IPPROTO_EIGRP +#define IPPROTO_EIGRP 88 /* Cisco/GXS IGRP */ +#endif +#ifndef IPPROTO_OSPF +#define IPPROTO_OSPF 89 +#endif +#ifndef IPPROTO_PIM +#define IPPROTO_PIM 103 +#endif +#ifndef IPPROTO_IPCOMP +#define IPPROTO_IPCOMP 108 +#endif +#ifndef IPPROTO_VRRP +#define IPPROTO_VRRP 112 +#endif +#ifndef IPPROTO_CARP +#define IPPROTO_CARP 112 +#endif +#ifndef IPPROTO_PGM +#define IPPROTO_PGM 113 +#endif +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif +#ifndef IPPROTO_MOBILITY +#define IPPROTO_MOBILITY 135 +#endif diff --git a/freebsd/contrib/tcpdump/ipsec_doi.h b/freebsd/contrib/tcpdump/ipsec_doi.h new file mode 100644 index 00000000..554a2586 --- /dev/null +++ b/freebsd/contrib/tcpdump/ipsec_doi.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 1995, 1996, 1997, and 1998 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. + */ +/* YIPS @(#)$Id: ipsec_doi.h,v 1.7 2002-12-11 07:13:53 guy Exp $ */ + +/* refer to RFC 2407 */ + +#if !defined(_IPSEC_DOI_H_) +#define _IPSEC_DOI_H_ + +#define IPSEC_DOI 1 + +/* 4.2 IPSEC Situation Definition */ +#define IPSECDOI_SIT_IDENTITY_ONLY 0x00000001 +#define IPSECDOI_SIT_SECRECY 0x00000002 +#define IPSECDOI_SIT_INTEGRITY 0x00000004 + +/* 4.4.1 IPSEC Security Protocol Identifiers */ + /* 4.4.2 IPSEC ISAKMP Transform Values */ +#define IPSECDOI_PROTO_ISAKMP 1 +#define IPSECDOI_KEY_IKE 1 + +/* 4.4.1 IPSEC Security Protocol Identifiers */ +#define IPSECDOI_PROTO_IPSEC_AH 2 + /* 4.4.3 IPSEC AH Transform Values */ +#define IPSECDOI_AH_MD5 2 +#define IPSECDOI_AH_SHA 3 +#define IPSECDOI_AH_DES 4 +#define IPSECDOI_AH_SHA2_256 5 +#define IPSECDOI_AH_SHA2_384 6 +#define IPSECDOI_AH_SHA2_512 7 + +/* 4.4.1 IPSEC Security Protocol Identifiers */ +#define IPSECDOI_PROTO_IPSEC_ESP 3 + /* 4.4.4 IPSEC ESP Transform Identifiers */ +#define IPSECDOI_ESP_DES_IV64 1 +#define IPSECDOI_ESP_DES 2 +#define IPSECDOI_ESP_3DES 3 +#define IPSECDOI_ESP_RC5 4 +#define IPSECDOI_ESP_IDEA 5 +#define IPSECDOI_ESP_CAST 6 +#define IPSECDOI_ESP_BLOWFISH 7 +#define IPSECDOI_ESP_3IDEA 8 +#define IPSECDOI_ESP_DES_IV32 9 +#define IPSECDOI_ESP_RC4 10 +#define IPSECDOI_ESP_NULL 11 +#define IPSECDOI_ESP_RIJNDAEL 12 +#define IPSECDOI_ESP_AES 12 + +/* 4.4.1 IPSEC Security Protocol Identifiers */ +#define IPSECDOI_PROTO_IPCOMP 4 + /* 4.4.5 IPSEC IPCOMP Transform Identifiers */ +#define IPSECDOI_IPCOMP_OUI 1 +#define IPSECDOI_IPCOMP_DEFLATE 2 +#define IPSECDOI_IPCOMP_LZS 3 + +/* 4.5 IPSEC Security Association Attributes */ +#define IPSECDOI_ATTR_SA_LTYPE 1 /* B */ +#define IPSECDOI_ATTR_SA_LTYPE_DEFAULT 1 +#define IPSECDOI_ATTR_SA_LTYPE_SEC 1 +#define IPSECDOI_ATTR_SA_LTYPE_KB 2 +#define IPSECDOI_ATTR_SA_LDUR 2 /* V */ +#define IPSECDOI_ATTR_SA_LDUR_DEFAULT 28800 /* 8 hours */ +#define IPSECDOI_ATTR_GRP_DESC 3 /* B */ +#define IPSECDOI_ATTR_ENC_MODE 4 /* B */ + /* default value: host dependent */ +#define IPSECDOI_ATTR_ENC_MODE_TUNNEL 1 +#define IPSECDOI_ATTR_ENC_MODE_TRNS 2 +#define IPSECDOI_ATTR_AUTH 5 /* B */ + /* 0 means not to use authentication. */ +#define IPSECDOI_ATTR_AUTH_HMAC_MD5 1 +#define IPSECDOI_ATTR_AUTH_HMAC_SHA1 2 +#define IPSECDOI_ATTR_AUTH_DES_MAC 3 +#define IPSECDOI_ATTR_AUTH_KPDK 4 /*RFC-1826(Key/Pad/Data/Key)*/ + /* + * When negotiating ESP without authentication, the Auth + * Algorithm attribute MUST NOT be included in the proposal. + * When negotiating ESP without confidentiality, the Auth + * Algorithm attribute MUST be included in the proposal and + * the ESP transform ID must be ESP_NULL. + */ +#define IPSECDOI_ATTR_KEY_LENGTH 6 /* B */ +#define IPSECDOI_ATTR_KEY_ROUNDS 7 /* B */ +#define IPSECDOI_ATTR_COMP_DICT_SIZE 8 /* B */ +#define IPSECDOI_ATTR_COMP_PRIVALG 9 /* V */ + +/* 4.6.1 Security Association Payload */ +struct ipsecdoi_sa { + struct isakmp_gen h; + u_int32_t doi; /* Domain of Interpretation */ + u_int32_t sit; /* Situation */ +}; + +struct ipsecdoi_secrecy_h { + u_int16_t len; + u_int16_t reserved; +}; + +/* 4.6.2.1 Identification Type Values */ +struct ipsecdoi_id { + struct isakmp_gen h; + u_int8_t type; /* ID Type */ + u_int8_t proto_id; /* Protocol ID */ + u_int16_t port; /* Port */ + /* Identification Data */ +}; + +#define IPSECDOI_ID_IPV4_ADDR 1 +#define IPSECDOI_ID_FQDN 2 +#define IPSECDOI_ID_USER_FQDN 3 +#define IPSECDOI_ID_IPV4_ADDR_SUBNET 4 +#define IPSECDOI_ID_IPV6_ADDR 5 +#define IPSECDOI_ID_IPV6_ADDR_SUBNET 6 +#define IPSECDOI_ID_IPV4_ADDR_RANGE 7 +#define IPSECDOI_ID_IPV6_ADDR_RANGE 8 +#define IPSECDOI_ID_DER_ASN1_DN 9 +#define IPSECDOI_ID_DER_ASN1_GN 10 +#define IPSECDOI_ID_KEY_ID 11 + +/* 4.6.3 IPSEC DOI Notify Message Types */ +/* Notify Messages - Status Types */ +#define IPSECDOI_NTYPE_RESPONDER_LIFETIME 24576 +#define IPSECDOI_NTYPE_REPLAY_STATUS 24577 +#define IPSECDOI_NTYPE_INITIAL_CONTACT 24578 + +#endif /* !defined(_IPSEC_DOI_H_) */ diff --git a/freebsd/contrib/tcpdump/ipx.h b/freebsd/contrib/tcpdump/ipx.h new file mode 100644 index 00000000..bfc30198 --- /dev/null +++ b/freebsd/contrib/tcpdump/ipx.h @@ -0,0 +1,31 @@ +/* + * IPX protocol formats + * + * @(#) $Header: /tcpdump/master/tcpdump/ipx.h,v 1.8 2002-12-11 07:13:54 guy Exp $ + */ + +/* well-known sockets */ +#define IPX_SKT_NCP 0x0451 +#define IPX_SKT_SAP 0x0452 +#define IPX_SKT_RIP 0x0453 +#define IPX_SKT_NETBIOS 0x0455 +#define IPX_SKT_DIAGNOSTICS 0x0456 +#define IPX_SKT_NWLINK_DGM 0x0553 /* NWLink datagram, may contain SMB */ +#define IPX_SKT_EIGRP 0x85be /* Cisco EIGRP over IPX */ + +/* IPX transport header */ +struct ipxHdr { + u_int16_t cksum; /* Checksum */ + u_int16_t length; /* Length, in bytes, including header */ + u_int8_t tCtl; /* Transport Control (i.e. hop count) */ + u_int8_t pType; /* Packet Type (i.e. level 2 protocol) */ + u_int16_t dstNet[2]; /* destination net */ + u_int8_t dstNode[6]; /* destination node */ + u_int16_t dstSkt; /* destination socket */ + u_int16_t srcNet[2]; /* source net */ + u_int8_t srcNode[6]; /* source node */ + u_int16_t srcSkt; /* source socket */ +}; + +#define ipxSize 30 + diff --git a/freebsd/contrib/tcpdump/isakmp.h b/freebsd/contrib/tcpdump/isakmp.h new file mode 100644 index 00000000..d628f7ae --- /dev/null +++ b/freebsd/contrib/tcpdump/isakmp.h @@ -0,0 +1,501 @@ +/* + * Copyright (C) 1995, 1996, 1997, and 1998 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. + */ +/* YIPS @(#)$Id: isakmp.h,v 1.12 2007-11-24 18:13:33 mcr Exp $ */ + +/* refer to RFC 2408 */ + +/* must include <netinet/in.h> */ + +#if !defined(_ISAKMP_H_) +#define _ISAKMP_H_ + +typedef u_char cookie_t[8]; +typedef u_char msgid_t[4]; + +typedef struct { /* i_cookie + r_cookie */ + cookie_t i_ck; + cookie_t r_ck; +} isakmp_index; + +#define INITIATOR 1 +#define RESPONDER 2 + +#define PORT_ISAKMP 500 + +#define GENERATE 1 +#define VALIDATE 0 + +/* Phase of oakley definition */ +/* + 0000 0000 0000 0000 + | |||| |||| + | |||| ++++--> negosiation number in phase + | ++++-------> phase number + +---------------> expire ? + */ +#define ISAKMP_PH1 0x0010 +#define ISAKMP_PH2 0x0020 +#define ISAKMP_EXPIRED 0x0100 + +#define ISAKMP_NGP_0 0x0000 +#define ISAKMP_NGP_1 0x0001 +#define ISAKMP_NGP_2 0x0002 +#define ISAKMP_NGP_3 0x0003 +#define ISAKMP_NGP_4 0x0004 + +#define ISAKMP_PH1_N (ISAKMP_PH1 | ISAKMP_NGP_0) /* i.e. spawn */ +#define ISAKMP_PH1_1 (ISAKMP_PH1 | ISAKMP_NGP_1) +#define ISAKMP_PH1_2 (ISAKMP_PH1 | ISAKMP_NGP_2) +#define ISAKMP_PH1_3 (ISAKMP_PH1 | ISAKMP_NGP_3) +#define ISAKMP_PH2_N (ISAKMP_PH2 | ISAKMP_NGP_0) +#define ISAKMP_PH2_1 (ISAKMP_PH2 | ISAKMP_NGP_1) +#define ISAKMP_PH2_2 (ISAKMP_PH2 | ISAKMP_NGP_2) +#define ISAKMP_PH2_3 (ISAKMP_PH2 | ISAKMP_NGP_3) + +#define ISAKMP_TIMER_DEFAULT 10 /* seconds */ +#define ISAKMP_TRY_DEFAULT 3 /* times */ + +/* 3.1 ISAKMP Header Format (IKEv1 and IKEv2) + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Initiator ! + ! Cookie ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Responder ! + ! Cookie ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Message ID ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +struct isakmp { + cookie_t i_ck; /* Initiator Cookie */ + cookie_t r_ck; /* Responder Cookie */ + u_int8_t np; /* Next Payload Type */ + u_int8_t vers; +#define ISAKMP_VERS_MAJOR 0xf0 +#define ISAKMP_VERS_MAJOR_SHIFT 4 +#define ISAKMP_VERS_MINOR 0x0f +#define ISAKMP_VERS_MINOR_SHIFT 0 + u_int8_t etype; /* Exchange Type */ + u_int8_t flags; /* Flags */ + msgid_t msgid; + u_int32_t len; /* Length */ +}; + +/* Next Payload Type */ +#define ISAKMP_NPTYPE_NONE 0 /* NONE*/ +#define ISAKMP_NPTYPE_SA 1 /* Security Association */ +#define ISAKMP_NPTYPE_P 2 /* Proposal */ +#define ISAKMP_NPTYPE_T 3 /* Transform */ +#define ISAKMP_NPTYPE_KE 4 /* Key Exchange */ +#define ISAKMP_NPTYPE_ID 5 /* Identification */ +#define ISAKMP_NPTYPE_CERT 6 /* Certificate */ +#define ISAKMP_NPTYPE_CR 7 /* Certificate Request */ +#define ISAKMP_NPTYPE_HASH 8 /* Hash */ +#define ISAKMP_NPTYPE_SIG 9 /* Signature */ +#define ISAKMP_NPTYPE_NONCE 10 /* Nonce */ +#define ISAKMP_NPTYPE_N 11 /* Notification */ +#define ISAKMP_NPTYPE_D 12 /* Delete */ +#define ISAKMP_NPTYPE_VID 13 /* Vendor ID */ +#define ISAKMP_NPTYPE_v2E 46 /* v2 Encrypted payload */ + +#define IKEv1_MAJOR_VERSION 1 +#define IKEv1_MINOR_VERSION 0 + +#define IKEv2_MAJOR_VERSION 2 +#define IKEv2_MINOR_VERSION 0 + +/* Exchange Type */ +#define ISAKMP_ETYPE_NONE 0 /* NONE */ +#define ISAKMP_ETYPE_BASE 1 /* Base */ +#define ISAKMP_ETYPE_IDENT 2 /* Identity Proteciton */ +#define ISAKMP_ETYPE_AUTH 3 /* Authentication Only */ +#define ISAKMP_ETYPE_AGG 4 /* Aggressive */ +#define ISAKMP_ETYPE_INF 5 /* Informational */ + +/* Flags */ +#define ISAKMP_FLAG_E 0x01 /* Encryption Bit */ +#define ISAKMP_FLAG_C 0x02 /* Commit Bit */ +#define ISAKMP_FLAG_extra 0x04 + +/* IKEv2 */ +#define ISAKMP_FLAG_I (1 << 3) /* (I)nitiator */ +#define ISAKMP_FLAG_V (1 << 4) /* (V)ersion */ +#define ISAKMP_FLAG_R (1 << 5) /* (R)esponse */ + + +/* 3.2 Payload Generic Header + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +struct isakmp_gen { + u_int8_t np; /* Next Payload */ + u_int8_t critical; /* bit 7 - critical, rest is RESERVED */ + u_int16_t len; /* Payload Length */ +}; + +/* 3.3 Data Attributes + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + !A! Attribute Type ! AF=0 Attribute Length ! + !F! ! AF=1 Attribute Value ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . AF=0 Attribute Value . + . AF=1 Not Transmitted . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +struct isakmp_data { + u_int16_t type; /* defined by DOI-spec, and Attribute Format */ + u_int16_t lorv; /* if f equal 1, Attribute Length */ + /* if f equal 0, Attribute Value */ + /* if f equal 1, Attribute Value */ +}; +#define ISAKMP_GEN_TLV 0x0000 +#define ISAKMP_GEN_TV 0x8000 + /* mask for type of attribute format */ +#define ISAKMP_GEN_MASK 0x8000 + +/* 3.4 Security Association Payload */ + /* MAY NOT be used, because of being defined in ipsec-doi. */ + /* + If the current payload is the last in the message, + then the value of the next payload field will be 0. + This field MUST NOT contain the + values for the Proposal or Transform payloads as they are considered + part of the security association negotiation. For example, this + field would contain the value "10" (Nonce payload) in the first + message of a Base Exchange (see Section 4.4) and the value "0" in the + first message of an Identity Protect Exchange (see Section 4.5). + */ +struct ikev1_pl_sa { + struct isakmp_gen h; + u_int32_t doi; /* Domain of Interpretation */ + u_int32_t sit; /* Situation */ +}; + +/* 3.5 Proposal Payload */ + /* + The value of the next payload field MUST only contain the value "2" + or "0". If there are additional Proposal payloads in the message, + then this field will be 2. If the current Proposal payload is the + last within the security association proposal, then this field will + be 0. + */ +struct ikev1_pl_p { + struct isakmp_gen h; + u_int8_t p_no; /* Proposal # */ + u_int8_t prot_id; /* Protocol */ + u_int8_t spi_size; /* SPI Size */ + u_int8_t num_t; /* Number of Transforms */ + /* SPI */ +}; + +/* 3.6 Transform Payload */ + /* + The value of the next payload field MUST only contain the value "3" + or "0". If there are additional Transform payloads in the proposal, + then this field will be 3. If the current Transform payload is the + last within the proposal, then this field will be 0. + */ +struct ikev1_pl_t { + struct isakmp_gen h; + u_int8_t t_no; /* Transform # */ + u_int8_t t_id; /* Transform-Id */ + u_int16_t reserved; /* RESERVED2 */ + /* SA Attributes */ +}; + +/* 3.7 Key Exchange Payload */ +struct ikev1_pl_ke { + struct isakmp_gen h; + /* Key Exchange Data */ +}; + +/* 3.8 Identification Payload */ + /* MUST NOT to be used, because of being defined in ipsec-doi. */ +struct ikev1_pl_id { + struct isakmp_gen h; + union { + u_int8_t id_type; /* ID Type */ + u_int32_t doi_data; /* DOI Specific ID Data */ + } d; + /* Identification Data */ +}; + +/* 3.9 Certificate Payload */ +struct ikev1_pl_cert { + struct isakmp_gen h; + u_int8_t encode; /* Cert Encoding */ + char cert; /* Certificate Data */ + /* + This field indicates the type of + certificate or certificate-related information contained in the + Certificate Data field. + */ +}; + +/* Certificate Type */ +#define ISAKMP_CERT_NONE 0 +#define ISAKMP_CERT_PKCS 1 +#define ISAKMP_CERT_PGP 2 +#define ISAKMP_CERT_DNS 3 +#define ISAKMP_CERT_SIGN 4 +#define ISAKMP_CERT_KE 5 +#define ISAKMP_CERT_KT 6 +#define ISAKMP_CERT_CRL 7 +#define ISAKMP_CERT_ARL 8 +#define ISAKMP_CERT_SPKI 9 + +/* 3.10 Certificate Request Payload */ +struct ikev1_pl_cr { + struct isakmp_gen h; + u_int8_t num_cert; /* # Cert. Types */ + /* + Certificate Types (variable length) + -- Contains a list of the types of certificates requested, + sorted in order of preference. Each individual certificate + type is 1 octet. This field is NOT requiredo + */ + /* # Certificate Authorities (1 octet) */ + /* Certificate Authorities (variable length) */ +}; + +/* 3.11 Hash Payload */ + /* may not be used, because of having only data. */ +struct ikev1_pl_hash { + struct isakmp_gen h; + /* Hash Data */ +}; + +/* 3.12 Signature Payload */ + /* may not be used, because of having only data. */ +struct ikev1_pl_sig { + struct isakmp_gen h; + /* Signature Data */ +}; + +/* 3.13 Nonce Payload */ + /* may not be used, because of having only data. */ +struct ikev1_pl_nonce { + struct isakmp_gen h; + /* Nonce Data */ +}; + +/* 3.14 Notification Payload */ +struct ikev1_pl_n { + struct isakmp_gen h; + u_int32_t doi; /* Domain of Interpretation */ + u_int8_t prot_id; /* Protocol-ID */ + u_int8_t spi_size; /* SPI Size */ + u_int16_t type; /* Notify Message Type */ + /* SPI */ + /* Notification Data */ +}; + +/* 3.14.1 Notify Message Types */ +/* NOTIFY MESSAGES - ERROR TYPES */ +#define ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE 1 +#define ISAKMP_NTYPE_DOI_NOT_SUPPORTED 2 +#define ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED 3 +#define ISAKMP_NTYPE_INVALID_COOKIE 4 +#define ISAKMP_NTYPE_INVALID_MAJOR_VERSION 5 +#define ISAKMP_NTYPE_INVALID_MINOR_VERSION 6 +#define ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE 7 +#define ISAKMP_NTYPE_INVALID_FLAGS 8 +#define ISAKMP_NTYPE_INVALID_MESSAGE_ID 9 +#define ISAKMP_NTYPE_INVALID_PROTOCOL_ID 10 +#define ISAKMP_NTYPE_INVALID_SPI 11 +#define ISAKMP_NTYPE_INVALID_TRANSFORM_ID 12 +#define ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED 13 +#define ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN 14 +#define ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX 15 +#define ISAKMP_NTYPE_PAYLOAD_MALFORMED 16 +#define ISAKMP_NTYPE_INVALID_KEY_INFORMATION 17 +#define ISAKMP_NTYPE_INVALID_ID_INFORMATION 18 +#define ISAKMP_NTYPE_INVALID_CERT_ENCODING 19 +#define ISAKMP_NTYPE_INVALID_CERTIFICATE 20 +#define ISAKMP_NTYPE_BAD_CERT_REQUEST_SYNTAX 21 +#define ISAKMP_NTYPE_INVALID_CERT_AUTHORITY 22 +#define ISAKMP_NTYPE_INVALID_HASH_INFORMATION 23 +#define ISAKMP_NTYPE_AUTHENTICATION_FAILED 24 +#define ISAKMP_NTYPE_INVALID_SIGNATURE 25 +#define ISAKMP_NTYPE_ADDRESS_NOTIFICATION 26 +/* NOTIFY MESSAGES - STATUS TYPES */ +#define ISAKMP_NTYPE_CONNECTED 16384 +/* using only to log */ +#define ISAKMP_LOG_RETRY_LIMIT_REACHED 65530 + +/* 3.15 Delete Payload */ +struct ikev1_pl_d { + struct isakmp_gen h; + u_int32_t doi; /* Domain of Interpretation */ + u_int8_t prot_id; /* Protocol-Id */ + u_int8_t spi_size; /* SPI Size */ + u_int16_t num_spi; /* # of SPIs */ + /* SPI(es) */ +}; + + +struct ikev1_ph1tab { + struct ikev1_ph1 *head; + struct ikev1_ph1 *tail; + int len; +}; + +struct isakmp_ph2tab { + struct ikev1_ph2 *head; + struct ikev1_ph2 *tail; + int len; +}; + +#define EXCHANGE_PROXY 1 +#define EXCHANGE_MYSELF 0 + +#define PFS_NEED 1 +#define PFS_NONEED 0 + +/* IKEv2 (RFC4306) */ + +/* 3.3 Security Association Payload -- generic header */ +/* 3.3.1. Proposal Substructure */ +struct ikev2_p { + struct isakmp_gen h; + u_int8_t p_no; /* Proposal # */ + u_int8_t prot_id; /* Protocol */ + u_int8_t spi_size; /* SPI Size */ + u_int8_t num_t; /* Number of Transforms */ +}; + +/* 3.3.2. Transform Substructure */ +struct ikev2_t { + struct isakmp_gen h; + u_int8_t t_type; /* Transform Type (ENCR,PRF,INTEG,etc.*/ + u_int8_t res2; /* reserved byte */ + u_int16_t t_id; /* Transform ID */ +}; + +enum ikev2_t_type { + IV2_T_ENCR = 1, + IV2_T_PRF = 2, + IV2_T_INTEG= 3, + IV2_T_DH = 4, + IV2_T_ESN = 5, +}; + +/* 3.4. Key Exchange Payload */ +struct ikev2_ke { + struct isakmp_gen h; + u_int16_t ke_group; + u_int16_t ke_res1; + /* KE data */ +}; + + +/* 3.5. Identification Payloads */ +enum ikev2_id_type { + ID_IPV4_ADDR=1, + ID_FQDN=2, + ID_RFC822_ADDR=3, + ID_IPV6_ADDR=5, + ID_DER_ASN1_DN=9, + ID_DER_ASN1_GN=10, + ID_KEY_ID=11, +}; +struct ikev2_id { + struct isakmp_gen h; + u_int8_t type; /* ID type */ + u_int8_t res1; + u_int16_t res2; + /* SPI */ + /* Notification Data */ +}; + +/* 3.10 Notification Payload */ +struct ikev2_n { + struct isakmp_gen h; + u_int8_t prot_id; /* Protocol-ID */ + u_int8_t spi_size; /* SPI Size */ + u_int16_t type; /* Notify Message Type */ +}; + +enum ikev2_n_type { + IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD = 1, + IV2_NOTIFY_INVALID_IKE_SPI = 4, + IV2_NOTIFY_INVALID_MAJOR_VERSION = 5, + IV2_NOTIFY_INVALID_SYNTAX = 7, + IV2_NOTIFY_INVALID_MESSAGE_ID = 9, + IV2_NOTIFY_INVALID_SPI =11, + IV2_NOTIFY_NO_PROPOSAL_CHOSEN =14, + IV2_NOTIFY_INVALID_KE_PAYLOAD =17, + IV2_NOTIFY_AUTHENTICATION_FAILED =24, + IV2_NOTIFY_SINGLE_PAIR_REQUIRED =34, + IV2_NOTIFY_NO_ADDITIONAL_SAS =35, + IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE =36, + IV2_NOTIFY_FAILED_CP_REQUIRED =37, + IV2_NOTIFY_INVALID_SELECTORS =39, + IV2_NOTIFY_INITIAL_CONTACT =16384, + IV2_NOTIFY_SET_WINDOW_SIZE =16385, + IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE =16386, + IV2_NOTIFY_IPCOMP_SUPPORTED =16387, + IV2_NOTIFY_NAT_DETECTION_SOURCE_IP =16388, + IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP =16389, + IV2_NOTIFY_COOKIE =16390, + IV2_NOTIFY_USE_TRANSPORT_MODE =16391, + IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED =16392, + IV2_NOTIFY_REKEY_SA =16393, + IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED =16394, + IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO =16395 +}; + +struct notify_messages { + u_int16_t type; + char *msg; +}; + +/* 3.8 Notification Payload */ +struct ikev2_auth { + struct isakmp_gen h; + u_int8_t auth_method; /* Protocol-ID */ + u_int8_t reserved[3]; + /* authentication data */ +}; + +enum ikev2_auth_type { + IV2_RSA_SIG = 1, + IV2_SHARED = 2, + IV2_DSS_SIG = 3, +}; + +#endif /* !defined(_ISAKMP_H_) */ diff --git a/freebsd/contrib/tcpdump/l2tp.h b/freebsd/contrib/tcpdump/l2tp.h new file mode 100644 index 00000000..5be24b9f --- /dev/null +++ b/freebsd/contrib/tcpdump/l2tp.h @@ -0,0 +1,62 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/l2tp.h,v 1.5 2001-11-05 10:03:27 guy Exp $ (LBL) */ +/* + * Copyright (c) 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. + * + * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net) + */ + + +#define L2TP_FLAG_TYPE 0x8000 /* Type (0=Data, 1=Control) */ +#define L2TP_FLAG_LENGTH 0x4000 /* Length */ +#define L2TP_FLAG_SEQUENCE 0x0800 /* Sequence */ +#define L2TP_FLAG_OFFSET 0x0200 /* Offset */ +#define L2TP_FLAG_PRIORITY 0x0100 /* Priority */ + +#define L2TP_VERSION_MASK 0x000f /* Version Mask */ +#define L2TP_VERSION_L2F 0x0001 /* L2F */ +#define L2TP_VERSION_L2TP 0x0002 /* L2TP */ + +#define L2TP_AVP_HDR_FLAG_MANDATORY 0x8000 /* Mandatory Flag */ +#define L2TP_AVP_HDR_FLAG_HIDDEN 0x4000 /* Hidden Flag */ +#define L2TP_AVP_HDR_LEN_MASK 0x03ff /* Length Mask */ + +#define L2TP_FRAMING_CAP_SYNC_MASK 0x00000001 /* Synchronous */ +#define L2TP_FRAMING_CAP_ASYNC_MASK 0x00000002 /* Asynchronous */ + +#define L2TP_FRAMING_TYPE_SYNC_MASK 0x00000001 /* Synchronous */ +#define L2TP_FRAMING_TYPE_ASYNC_MASK 0x00000002 /* Asynchronous */ + +#define L2TP_BEARER_CAP_DIGITAL_MASK 0x00000001 /* Digital */ +#define L2TP_BEARER_CAP_ANALOG_MASK 0x00000002 /* Analog */ + +#define L2TP_BEARER_TYPE_DIGITAL_MASK 0x00000001 /* Digital */ +#define L2TP_BEARER_TYPE_ANALOG_MASK 0x00000002 /* Analog */ + +/* Authen Type */ +#define L2TP_AUTHEN_TYPE_RESERVED 0x0000 /* Reserved */ +#define L2TP_AUTHEN_TYPE_TEXTUAL 0x0001 /* Textual username/password exchange */ +#define L2TP_AUTHEN_TYPE_CHAP 0x0002 /* PPP CHAP */ +#define L2TP_AUTHEN_TYPE_PAP 0x0003 /* PPP PAP */ +#define L2TP_AUTHEN_TYPE_NO_AUTH 0x0004 /* No Authentication */ +#define L2TP_AUTHEN_TYPE_MSCHAPv1 0x0005 /* MSCHAPv1 */ + +#define L2TP_PROXY_AUTH_ID_MASK 0x00ff + + diff --git a/freebsd/contrib/tcpdump/l2vpn.c b/freebsd/contrib/tcpdump/l2vpn.c new file mode 100644 index 00000000..f869242b --- /dev/null +++ b/freebsd/contrib/tcpdump/l2vpn.c @@ -0,0 +1,60 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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/l2vpn.c,v 1.1 2004-06-15 09:42:40 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> +#include "interface.h" +#include "l2vpn.h" + +/* draft-ietf-pwe3-iana-allocation-04 */ +const struct tok l2vpn_encaps_values[] = { + { 0x00, "Reserved"}, + { 0x01, "Frame Relay"}, + { 0x02, "ATM AAL5 VCC transport"}, + { 0x03, "ATM transparent cell transport"}, + { 0x04, "Ethernet VLAN"}, + { 0x05, "Ethernet"}, + { 0x06, "Cisco-HDLC"}, + { 0x07, "PPP"}, + { 0x08, "SONET/SDH Circuit Emulation Service over MPLS"}, + { 0x09, "ATM n-to-one VCC cell transport"}, + { 0x0a, "ATM n-to-one VPC cell transport"}, + { 0x0b, "IP Layer2 Transport"}, + { 0x0c, "ATM one-to-one VCC Cell Mode"}, + { 0x0d, "ATM one-to-one VPC Cell Mode"}, + { 0x0e, "ATM AAL5 PDU VCC transport"}, + { 0x0f, "Frame-Relay Port mode"}, + { 0x10, "SONET/SDH Circuit Emulation over Packet"}, + { 0x11, "Structure-agnostic E1 over Packet"}, + { 0x12, "Structure-agnostic T1 (DS1) over Packet"}, + { 0x13, "Structure-agnostic E3 over Packet"}, + { 0x14, "Structure-agnostic T3 (DS3) over Packet"}, + { 0x15, "CESoPSN basic mode"}, + { 0x16, "TDMoIP basic mode"}, + { 0x17, "CESoPSN TDM with CAS"}, + { 0x18, "TDMoIP TDM with CAS"}, + { 0x40, "IP-interworking"}, + { 0, NULL} +}; diff --git a/freebsd/contrib/tcpdump/l2vpn.h b/freebsd/contrib/tcpdump/l2vpn.h new file mode 100644 index 00000000..871eca0e --- /dev/null +++ b/freebsd/contrib/tcpdump/l2vpn.h @@ -0,0 +1,17 @@ +/* @(#) $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[]; diff --git a/freebsd/contrib/tcpdump/lane.h b/freebsd/contrib/tcpdump/lane.h new file mode 100644 index 00000000..76cc020e --- /dev/null +++ b/freebsd/contrib/tcpdump/lane.h @@ -0,0 +1,41 @@ +/* + * 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. + * + */ + +/* $Id: lane.h,v 1.7 2002-12-11 07:13:54 guy Exp $ */ + +#ifndef ETHER_ADDR_LEN +#define ETHER_ADDR_LEN 6 +#endif + +struct lecdatahdr_8023 { + u_int16_t le_header; + u_int8_t h_dest[ETHER_ADDR_LEN]; + u_int8_t h_source[ETHER_ADDR_LEN]; + u_int16_t h_type; +}; + +struct lane_controlhdr { + u_int16_t lec_header; + u_int8_t lec_proto; + u_int8_t lec_vers; + u_int16_t lec_opcode; +}; diff --git a/freebsd/contrib/tcpdump/llc.h b/freebsd/contrib/tcpdump/llc.h new file mode 100644 index 00000000..faa72561 --- /dev/null +++ b/freebsd/contrib/tcpdump/llc.h @@ -0,0 +1,123 @@ +/* + * 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+ */ + +/* + * 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 */ diff --git a/freebsd/contrib/tcpdump/machdep.c b/freebsd/contrib/tcpdump/machdep.c new file mode 100644 index 00000000..4d5e6b06 --- /dev/null +++ b/freebsd/contrib/tcpdump/machdep.c @@ -0,0 +1,69 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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/machdep.c,v 1.13 2003-12-15 03:53:21 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * XXX - all we need, on platforms other than DEC OSF/1 (a/k/a Digital UNIX, + * a/k/a Tru64 UNIX), is "size_t", which is a standard C type; what do we + * need to do to get it defined? This is clearly wrong, as we shouldn't + * have to include UNIX or Windows system header files to get it. + */ +#include <tcpdump-stdinc.h> + +#ifndef HAVE___ATTRIBUTE__ +#define __attribute__(x) +#endif /* HAVE___ATTRIBUTE__ */ + +#ifdef __osf__ +#include <sys/sysinfo.h> +#include <sys/proc.h> + +#if !defined(HAVE_SNPRINTF) +int snprintf(char *, size_t, const char *, ...) + __attribute__((format(printf, 3, 4))); +#endif /* !defined(HAVE_SNPRINTF) */ +#endif /* __osf__ */ + +#include "machdep.h" + +int +abort_on_misalignment(char *ebuf _U_, size_t ebufsiz _U_) +{ +#ifdef __osf__ + static int buf[2] = { SSIN_UACPROC, UAC_SIGBUS }; + + if (setsysinfo(SSI_NVPAIRS, (caddr_t)buf, 1, 0, 0) < 0) { + (void)snprintf(ebuf, ebufsiz, "setsysinfo: errno %d", errno); + return (-1); + } +#endif + return (0); +} diff --git a/freebsd/contrib/tcpdump/machdep.h b/freebsd/contrib/tcpdump/machdep.h new file mode 100644 index 00000000..6328c826 --- /dev/null +++ b/freebsd/contrib/tcpdump/machdep.h @@ -0,0 +1,27 @@ +/* + * 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 diff --git a/freebsd/contrib/tcpdump/mib.h b/freebsd/contrib/tcpdump/mib.h new file mode 100644 index 00000000..92c6c2c5 --- /dev/null +++ b/freebsd/contrib/tcpdump/mib.h @@ -0,0 +1,1460 @@ +/* + * This file was generated by tcpdump/makemib on Wed Sep 26 12:12:31 EDT 1990 + * You probably don't want to edit this by hand! + * + * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer +}; + */ + +/* parse problem: new name "mib" for mgmt.mib(1) ignored */ +/* parse problem: no parent for 0.nullSpecific(0) */ +struct obj +_proteon_obj = { + "proteon", 1, 0, + NULL, NULL +}, +_ibm_obj = { + "ibm", 2, 0, + NULL, &_proteon_obj +}, +_cmu_obj = { + "cmu", 3, 0, + NULL, &_ibm_obj +}, +_unix_obj = { + "unix", 4, 0, + NULL, &_cmu_obj +}, +_acc_obj = { + "acc", 5, 0, + NULL, &_unix_obj +}, +_twg_obj = { + "twg", 6, 0, + NULL, &_acc_obj +}, +_cayman_obj = { + "cayman", 7, 0, + NULL, &_twg_obj +}, +_nysernet_obj = { + "nysernet", 8, 0, + NULL, &_cayman_obj +}, +_cisco_obj = { + "cisco", 9, 0, + NULL, &_nysernet_obj +}, +_nsc_obj = { + "nsc", 10, 0, + NULL, &_cisco_obj +}, +_hp_obj = { + "hp", 11, 0, + NULL, &_nsc_obj +}, +_epilogue_obj = { + "epilogue", 12, 0, + NULL, &_hp_obj +}, +_utennessee_obj = { + "utennessee", 13, 0, + NULL, &_epilogue_obj +}, +_bbn_obj = { + "bbn", 14, 0, + NULL, &_utennessee_obj +}, +_xylogics_obj = { + "xylogics", 15, 0, + NULL, &_bbn_obj +}, +_unisys_obj = { + "unisys", 16, 0, + NULL, &_xylogics_obj +}, +_canstar_obj = { + "canstar", 17, 0, + NULL, &_unisys_obj +}, +_wellfleet_obj = { + "wellfleet", 18, 0, + NULL, &_canstar_obj +}, +_trw_obj = { + "trw", 19, 0, + NULL, &_wellfleet_obj +}, +_mit_obj = { + "mit", 20, 0, + NULL, &_trw_obj +}, +_eon_obj = { + "eon", 21, 0, + NULL, &_mit_obj +}, +_spartacus_obj = { + "spartacus", 22, 0, + NULL, &_eon_obj +}, +_excelan_obj = { + "excelan", 23, 0, + NULL, &_spartacus_obj +}, +_spider_obj = { + "spider", 24, 0, + NULL, &_excelan_obj +}, +_nsfnet_obj = { + "nsfnet", 25, 0, + NULL, &_spider_obj +}, +_sytek_obj = { + "sytek", 26, 0, + NULL, &_nsfnet_obj +}, +_intergraph_obj = { + "intergraph", 27, 0, + NULL, &_sytek_obj +}, +_interlan_obj = { + "interlan", 28, 0, + NULL, &_intergraph_obj +}, +_vitalink_obj = { + "vitalink", 29, 0, + NULL, &_interlan_obj +}, +_ulana_obj = { + "ulana", 30, 0, + NULL, &_vitalink_obj +}, +_nswc_obj = { + "nswc", 31, 0, + NULL, &_ulana_obj +}, +_santacruzoperation_obj = { + "santacruzoperation", 32, 0, + NULL, &_nswc_obj +}, +_xyplex_obj = { + "xyplex", 33, 0, + NULL, &_santacruzoperation_obj +}, +_cray_obj = { + "cray", 34, 0, + NULL, &_xyplex_obj +}, +_bellnorthernresearch_obj = { + "bellnorthernresearch", 35, 0, + NULL, &_cray_obj +}, +_dec_obj = { + "dec", 36, 0, + NULL, &_bellnorthernresearch_obj +}, +_touch_obj = { + "touch", 37, 0, + NULL, &_dec_obj +}, +_networkresearchcorp_obj = { + "networkresearchcorp", 38, 0, + NULL, &_touch_obj +}, +_baylor_obj = { + "baylor", 39, 0, + NULL, &_networkresearchcorp_obj +}, +_nmfeccllnl_obj = { + "nmfeccllnl", 40, 0, + NULL, &_baylor_obj +}, +_sri_obj = { + "sri", 41, 0, + NULL, &_nmfeccllnl_obj +}, +_sun_obj = { + "sun", 42, 0, + NULL, &_sri_obj +}, +_3com_obj = { + "3com", 43, 0, + NULL, &_sun_obj +}, +_cmc_obj = { + "cmc", 44, 0, + NULL, &_3com_obj +}, +_synoptics_obj = { + "synoptics", 45, 0, + NULL, &_cmc_obj +}, +_cheyenne_obj = { + "cheyenne", 46, 0, + NULL, &_synoptics_obj +}, +_prime_obj = { + "prime", 47, 0, + NULL, &_cheyenne_obj +}, +_mcnc_obj = { + "mcnc", 48, 0, + NULL, &_prime_obj +}, +_chipcom_obj = { + "chipcom", 49, 0, + NULL, &_mcnc_obj +}, +_opticaldatasystems_obj = { + "opticaldatasystems", 50, 0, + NULL, &_chipcom_obj +}, +_gated_obj = { + "gated", 51, 0, + NULL, &_opticaldatasystems_obj +}, +_cabletron_obj = { + "cabletron", 52, 0, + NULL, &_gated_obj +}, +_apollo_obj = { + "apollo", 53, 0, + NULL, &_cabletron_obj +}, +_desktalksystems_obj = { + "desktalksystems", 54, 0, + NULL, &_apollo_obj +}, +_ssds_obj = { + "ssds", 55, 0, + NULL, &_desktalksystems_obj +}, +_castlerock_obj = { + "castlerock", 56, 0, + NULL, &_ssds_obj +}, +_mips_obj = { + "mips", 57, 0, + NULL, &_castlerock_obj +}, +_tgv_obj = { + "tgv", 58, 0, + NULL, &_mips_obj +}, +_silicongraphics_obj = { + "silicongraphics", 59, 0, + NULL, &_tgv_obj +}, +_ubc_obj = { + "ubc", 60, 0, + NULL, &_silicongraphics_obj +}, +_merit_obj = { + "merit", 61, 0, + NULL, &_ubc_obj +}, +_fibercom_obj = { + "fibercom", 62, 0, + NULL, &_merit_obj +}, +_apple_obj = { + "apple", 63, 0, + NULL, &_fibercom_obj +}, +_gandalf_obj = { + "gandalf", 64, 0, + NULL, &_apple_obj +}, +_dartmouth_obj = { + "dartmouth", 65, 0, + NULL, &_gandalf_obj +}, +_davidsystems_obj = { + "davidsystems", 66, 0, + NULL, &_dartmouth_obj +}, +_reuter_obj = { + "reuter", 67, 0, + NULL, &_davidsystems_obj +}, +_cornell_obj = { + "cornell", 68, 0, + NULL, &_reuter_obj +}, +_tmac_obj = { + "tmac", 69, 0, + NULL, &_cornell_obj +}, +_locus_obj = { + "locus", 70, 0, + NULL, &_tmac_obj +}, +_nasa_obj = { + "nasa", 71, 0, + NULL, &_locus_obj +}, +_retix_obj = { + "retix", 72, 0, + NULL, &_nasa_obj +}, +_boeing_obj = { + "boeing", 73, 0, + NULL, &_retix_obj +}, +_att_obj = { + "att", 74, 0, + NULL, &_boeing_obj +}, +_ungermannbass_obj = { + "ungermannbass", 75, 0, + NULL, &_att_obj +}, +_digitalanalysis_obj = { + "digitalanalysis", 76, 0, + NULL, &_ungermannbass_obj +}, +_hplanman_obj = { + "hplanman", 77, 0, + NULL, &_digitalanalysis_obj +}, +_netlabs_obj = { + "netlabs", 78, 0, + NULL, &_hplanman_obj +}, +_icl_obj = { + "icl", 79, 0, + NULL, &_netlabs_obj +}, +_auspex_obj = { + "auspex", 80, 0, + NULL, &_icl_obj +}, +_lannet_obj = { + "lannet", 81, 0, + NULL, &_auspex_obj +}, +_ncd_obj = { + "ncd", 82, 0, + NULL, &_lannet_obj +}, +_raycom_obj = { + "raycom", 83, 0, + NULL, &_ncd_obj +}, +_pirellifocom_obj = { + "pirellifocom", 84, 0, + NULL, &_raycom_obj +}, +_datability_obj = { + "datability", 85, 0, + NULL, &_pirellifocom_obj +}, +_networkappltech_obj = { + "networkappltech", 86, 0, + NULL, &_datability_obj +}, +_link_obj = { + "link", 87, 0, + NULL, &_networkappltech_obj +}, +_nyu_obj = { + "nyu", 88, 0, + NULL, &_link_obj +}, +_rnd_obj = { + "rnd", 89, 0, + NULL, &_nyu_obj +}, +_intercon_obj = { + "intercon", 90, 0, + NULL, &_rnd_obj +}, +_learningtree_obj = { + "learningtree", 91, 0, + NULL, &_intercon_obj +}, +_webstercomputer_obj = { + "webstercomputer", 92, 0, + NULL, &_learningtree_obj +}, +_frontier_obj = { + "frontier", 93, 0, + NULL, &_webstercomputer_obj +}, +_nokia_obj = { + "nokia", 94, 0, + NULL, &_frontier_obj +}, +_allenbradley_obj = { + "allenbradley", 95, 0, + NULL, &_nokia_obj +}, +_cern_obj = { + "cern", 96, 0, + NULL, &_allenbradley_obj +}, +_sigma_obj = { + "sigma", 97, 0, + NULL, &_cern_obj +}, +_emergingtech_obj = { + "emergingtech", 98, 0, + NULL, &_sigma_obj +}, +_snmpresearch_obj = { + "snmpresearch", 99, 0, + NULL, &_emergingtech_obj +}, +_ohiostate_obj = { + "ohiostate", 100, 0, + NULL, &_snmpresearch_obj +}, +_ultra_obj = { + "ultra", 101, 0, + NULL, &_ohiostate_obj +}, +_ccur_obj = { + "ccur", 136, 0, + NULL, &_ultra_obj +}, +_enterprises_obj = { + "enterprises", 1, 0, + &_ccur_obj, NULL +}, +_snmpInPkts_obj = { + "snmpInPkts", 1, 0, + NULL, NULL +}, +_snmpOutPkts_obj = { + "snmpOutPkts", 2, 0, + NULL, &_snmpInPkts_obj +}, +_snmpInBadVersions_obj = { + "snmpInBadVersions", 3, 0, + NULL, &_snmpOutPkts_obj +}, +_snmpInBadCommunityNames_obj = { + "snmpInBadCommunityNames", 4, 0, + NULL, &_snmpInBadVersions_obj +}, +_snmpInBadCommunityUses_obj = { + "snmpInBadCommunityUses", 5, 0, + NULL, &_snmpInBadCommunityNames_obj +}, +_snmpInASNParseErrs_obj = { + "snmpInASNParseErrs", 6, 0, + NULL, &_snmpInBadCommunityUses_obj +}, +_snmpInBadTypes_obj = { + "snmpInBadTypes", 7, 0, + NULL, &_snmpInASNParseErrs_obj +}, +_snmpInTooBigs_obj = { + "snmpInTooBigs", 8, 0, + NULL, &_snmpInBadTypes_obj +}, +_snmpInNoSuchNames_obj = { + "snmpInNoSuchNames", 9, 0, + NULL, &_snmpInTooBigs_obj +}, +_snmpInBadValues_obj = { + "snmpInBadValues", 10, 0, + NULL, &_snmpInNoSuchNames_obj +}, +_snmpInReadOnlys_obj = { + "snmpInReadOnlys", 11, 0, + NULL, &_snmpInBadValues_obj +}, +_snmpInGenErrs_obj = { + "snmpInGenErrs", 12, 0, + NULL, &_snmpInReadOnlys_obj +}, +_snmpInTotalReqVars_obj = { + "snmpInTotalReqVars", 13, 0, + NULL, &_snmpInGenErrs_obj +}, +_snmpInTotalSetVars_obj = { + "snmpInTotalSetVars", 14, 0, + NULL, &_snmpInTotalReqVars_obj +}, +_snmpInGetRequests_obj = { + "snmpInGetRequests", 15, 0, + NULL, &_snmpInTotalSetVars_obj +}, +_snmpInGetNexts_obj = { + "snmpInGetNexts", 16, 0, + NULL, &_snmpInGetRequests_obj +}, +_snmpInSetRequests_obj = { + "snmpInSetRequests", 17, 0, + NULL, &_snmpInGetNexts_obj +}, +_snmpInGetResponses_obj = { + "snmpInGetResponses", 18, 0, + NULL, &_snmpInSetRequests_obj +}, +_snmpInTraps_obj = { + "snmpInTraps", 19, 0, + NULL, &_snmpInGetResponses_obj +}, +_snmpOutTooBigs_obj = { + "snmpOutTooBigs", 20, 0, + NULL, &_snmpInTraps_obj +}, +_snmpOutNoSuchNames_obj = { + "snmpOutNoSuchNames", 21, 0, + NULL, &_snmpOutTooBigs_obj +}, +_snmpOutBadValues_obj = { + "snmpOutBadValues", 22, 0, + NULL, &_snmpOutNoSuchNames_obj +}, +_snmpOutReadOnlys_obj = { + "snmpOutReadOnlys", 23, 0, + NULL, &_snmpOutBadValues_obj +}, +_snmpOutGenErrs_obj = { + "snmpOutGenErrs", 24, 0, + NULL, &_snmpOutReadOnlys_obj +}, +_snmpOutGetRequests_obj = { + "snmpOutGetRequests", 25, 0, + NULL, &_snmpOutGenErrs_obj +}, +_snmpOutGetNexts_obj = { + "snmpOutGetNexts", 26, 0, + NULL, &_snmpOutGetRequests_obj +}, +_snmpOutSetRequests_obj = { + "snmpOutSetRequests", 27, 0, + NULL, &_snmpOutGetNexts_obj +}, +_snmpOutGetResponses_obj = { + "snmpOutGetResponses", 28, 0, + NULL, &_snmpOutSetRequests_obj +}, +_snmpOutTraps_obj = { + "snmpOutTraps", 29, 0, + NULL, &_snmpOutGetResponses_obj +}, +_snmpEnableAuthTraps_obj = { + "snmpEnableAuthTraps", 30, 0, + NULL, &_snmpOutTraps_obj +}, +_egpNeighState_obj = { + "egpNeighState", 1, 0, + NULL, NULL +}, +_egpNeighAddr_obj = { + "egpNeighAddr", 2, 0, + NULL, &_egpNeighState_obj +}, +_egpNeighAs_obj = { + "egpNeighAs", 3, 0, + NULL, &_egpNeighAddr_obj +}, +_egpNeighInMsgs_obj = { + "egpNeighInMsgs", 4, 0, + NULL, &_egpNeighAs_obj +}, +_egpNeighInErrs_obj = { + "egpNeighInErrs", 5, 0, + NULL, &_egpNeighInMsgs_obj +}, +_egpNeighOutMsgs_obj = { + "egpNeighOutMsgs", 6, 0, + NULL, &_egpNeighInErrs_obj +}, +_egpNeighOutErrs_obj = { + "egpNeighOutErrs", 7, 0, + NULL, &_egpNeighOutMsgs_obj +}, +_egpNeighInErrMsgs_obj = { + "egpNeighInErrMsgs", 8, 0, + NULL, &_egpNeighOutErrs_obj +}, +_egpNeighOutErrMsgs_obj = { + "egpNeighOutErrMsgs", 9, 0, + NULL, &_egpNeighInErrMsgs_obj +}, +_egpNeighStateUps_obj = { + "egpNeighStateUps", 10, 0, + NULL, &_egpNeighOutErrMsgs_obj +}, +_egpNeighStateDowns_obj = { + "egpNeighStateDowns", 11, 0, + NULL, &_egpNeighStateUps_obj +}, +_egpNeighIntervalHello_obj = { + "egpNeighIntervalHello", 12, 0, + NULL, &_egpNeighStateDowns_obj +}, +_egpNeighIntervalPoll_obj = { + "egpNeighIntervalPoll", 13, 0, + NULL, &_egpNeighIntervalHello_obj +}, +_egpNeighMode_obj = { + "egpNeighMode", 14, 0, + NULL, &_egpNeighIntervalPoll_obj +}, +_egpNeighEventTrigger_obj = { + "egpNeighEventTrigger", 15, 0, + NULL, &_egpNeighMode_obj +}, +_egpNeighEntry_obj = { + "egpNeighEntry", 1, 0, + &_egpNeighEventTrigger_obj, NULL +}, +_egpInMsgs_obj = { + "egpInMsgs", 1, 0, + NULL, NULL +}, +_egpInErrors_obj = { + "egpInErrors", 2, 0, + NULL, &_egpInMsgs_obj +}, +_egpOutMsgs_obj = { + "egpOutMsgs", 3, 0, + NULL, &_egpInErrors_obj +}, +_egpOutErrors_obj = { + "egpOutErrors", 4, 0, + NULL, &_egpOutMsgs_obj +}, +_egpNeighTable_obj = { + "egpNeighTable", 5, 0, + &_egpNeighEntry_obj, &_egpOutErrors_obj +}, +_egpAs_obj = { + "egpAs", 6, 0, + NULL, &_egpNeighTable_obj +}, +_udpLocalAddress_obj = { + "udpLocalAddress", 1, 0, + NULL, NULL +}, +_udpLocalPort_obj = { + "udpLocalPort", 2, 0, + NULL, &_udpLocalAddress_obj +}, +_udpEntry_obj = { + "udpEntry", 1, 0, + &_udpLocalPort_obj, NULL +}, +_udpInDatagrams_obj = { + "udpInDatagrams", 1, 0, + NULL, NULL +}, +_udpNoPorts_obj = { + "udpNoPorts", 2, 0, + NULL, &_udpInDatagrams_obj +}, +_udpInErrors_obj = { + "udpInErrors", 3, 0, + NULL, &_udpNoPorts_obj +}, +_udpOutDatagrams_obj = { + "udpOutDatagrams", 4, 0, + NULL, &_udpInErrors_obj +}, +_udpTable_obj = { + "udpTable", 5, 0, + &_udpEntry_obj, &_udpOutDatagrams_obj +}, +_tcpConnState_obj = { + "tcpConnState", 1, 0, + NULL, NULL +}, +_tcpConnLocalAddress_obj = { + "tcpConnLocalAddress", 2, 0, + NULL, &_tcpConnState_obj +}, +_tcpConnLocalPort_obj = { + "tcpConnLocalPort", 3, 0, + NULL, &_tcpConnLocalAddress_obj +}, +_tcpConnRemAddress_obj = { + "tcpConnRemAddress", 4, 0, + NULL, &_tcpConnLocalPort_obj +}, +_tcpConnRemPort_obj = { + "tcpConnRemPort", 5, 0, + NULL, &_tcpConnRemAddress_obj +}, +_tcpConnEntry_obj = { + "tcpConnEntry", 1, 0, + &_tcpConnRemPort_obj, NULL +}, +_tcpRtoAlgorithm_obj = { + "tcpRtoAlgorithm", 1, 0, + NULL, NULL +}, +_tcpRtoMin_obj = { + "tcpRtoMin", 2, 0, + NULL, &_tcpRtoAlgorithm_obj +}, +_tcpRtoMax_obj = { + "tcpRtoMax", 3, 0, + NULL, &_tcpRtoMin_obj +}, +_tcpMaxConn_obj = { + "tcpMaxConn", 4, 0, + NULL, &_tcpRtoMax_obj +}, +_tcpActiveOpens_obj = { + "tcpActiveOpens", 5, 0, + NULL, &_tcpMaxConn_obj +}, +_tcpPassiveOpens_obj = { + "tcpPassiveOpens", 6, 0, + NULL, &_tcpActiveOpens_obj +}, +_tcpAttemptFails_obj = { + "tcpAttemptFails", 7, 0, + NULL, &_tcpPassiveOpens_obj +}, +_tcpEstabResets_obj = { + "tcpEstabResets", 8, 0, + NULL, &_tcpAttemptFails_obj +}, +_tcpCurrEstab_obj = { + "tcpCurrEstab", 9, 0, + NULL, &_tcpEstabResets_obj +}, +_tcpInSegs_obj = { + "tcpInSegs", 10, 0, + NULL, &_tcpCurrEstab_obj +}, +_tcpOutSegs_obj = { + "tcpOutSegs", 11, 0, + NULL, &_tcpInSegs_obj +}, +_tcpRetransSegs_obj = { + "tcpRetransSegs", 12, 0, + NULL, &_tcpOutSegs_obj +}, +_tcpConnTable_obj = { + "tcpConnTable", 13, 0, + &_tcpConnEntry_obj, &_tcpRetransSegs_obj +}, +_tcpInErrs_obj = { + "tcpInErrs", 14, 0, + NULL, &_tcpConnTable_obj +}, +_tcpOutRsts_obj = { + "tcpOutRsts", 15, 0, + NULL, &_tcpInErrs_obj +}, +_icmpInMsgs_obj = { + "icmpInMsgs", 1, 0, + NULL, NULL +}, +_icmpInErrors_obj = { + "icmpInErrors", 2, 0, + NULL, &_icmpInMsgs_obj +}, +_icmpInDestUnreachs_obj = { + "icmpInDestUnreachs", 3, 0, + NULL, &_icmpInErrors_obj +}, +_icmpInTimeExcds_obj = { + "icmpInTimeExcds", 4, 0, + NULL, &_icmpInDestUnreachs_obj +}, +_icmpInParmProbs_obj = { + "icmpInParmProbs", 5, 0, + NULL, &_icmpInTimeExcds_obj +}, +_icmpInSrcQuenchs_obj = { + "icmpInSrcQuenchs", 6, 0, + NULL, &_icmpInParmProbs_obj +}, +_icmpInRedirects_obj = { + "icmpInRedirects", 7, 0, + NULL, &_icmpInSrcQuenchs_obj +}, +_icmpInEchos_obj = { + "icmpInEchos", 8, 0, + NULL, &_icmpInRedirects_obj +}, +_icmpInEchoReps_obj = { + "icmpInEchoReps", 9, 0, + NULL, &_icmpInEchos_obj +}, +_icmpInTimestamps_obj = { + "icmpInTimestamps", 10, 0, + NULL, &_icmpInEchoReps_obj +}, +_icmpInTimestampReps_obj = { + "icmpInTimestampReps", 11, 0, + NULL, &_icmpInTimestamps_obj +}, +_icmpInAddrMasks_obj = { + "icmpInAddrMasks", 12, 0, + NULL, &_icmpInTimestampReps_obj +}, +_icmpInAddrMaskReps_obj = { + "icmpInAddrMaskReps", 13, 0, + NULL, &_icmpInAddrMasks_obj +}, +_icmpOutMsgs_obj = { + "icmpOutMsgs", 14, 0, + NULL, &_icmpInAddrMaskReps_obj +}, +_icmpOutErrors_obj = { + "icmpOutErrors", 15, 0, + NULL, &_icmpOutMsgs_obj +}, +_icmpOutDestUnreachs_obj = { + "icmpOutDestUnreachs", 16, 0, + NULL, &_icmpOutErrors_obj +}, +_icmpOutTimeExcds_obj = { + "icmpOutTimeExcds", 17, 0, + NULL, &_icmpOutDestUnreachs_obj +}, +_icmpOutParmProbs_obj = { + "icmpOutParmProbs", 18, 0, + NULL, &_icmpOutTimeExcds_obj +}, +_icmpOutSrcQuenchs_obj = { + "icmpOutSrcQuenchs", 19, 0, + NULL, &_icmpOutParmProbs_obj +}, +_icmpOutRedirects_obj = { + "icmpOutRedirects", 20, 0, + NULL, &_icmpOutSrcQuenchs_obj +}, +_icmpOutEchos_obj = { + "icmpOutEchos", 21, 0, + NULL, &_icmpOutRedirects_obj +}, +_icmpOutEchoReps_obj = { + "icmpOutEchoReps", 22, 0, + NULL, &_icmpOutEchos_obj +}, +_icmpOutTimestamps_obj = { + "icmpOutTimestamps", 23, 0, + NULL, &_icmpOutEchoReps_obj +}, +_icmpOutTimestampReps_obj = { + "icmpOutTimestampReps", 24, 0, + NULL, &_icmpOutTimestamps_obj +}, +_icmpOutAddrMasks_obj = { + "icmpOutAddrMasks", 25, 0, + NULL, &_icmpOutTimestampReps_obj +}, +_icmpOutAddrMaskReps_obj = { + "icmpOutAddrMaskReps", 26, 0, + NULL, &_icmpOutAddrMasks_obj +}, +_ipNetToMediaIfIndex_obj = { + "ipNetToMediaIfIndex", 1, 0, + NULL, NULL +}, +_ipNetToMediaPhysAddress_obj = { + "ipNetToMediaPhysAddress", 2, 0, + NULL, &_ipNetToMediaIfIndex_obj +}, +_ipNetToMediaNetAddress_obj = { + "ipNetToMediaNetAddress", 3, 0, + NULL, &_ipNetToMediaPhysAddress_obj +}, +_ipNetToMediaType_obj = { + "ipNetToMediaType", 4, 0, + NULL, &_ipNetToMediaNetAddress_obj +}, +_ipNetToMediaEntry_obj = { + "ipNetToMediaEntry", 1, 0, + &_ipNetToMediaType_obj, NULL +}, +_ipRouteDest_obj = { + "ipRouteDest", 1, 0, + NULL, NULL +}, +_ipRouteIfIndex_obj = { + "ipRouteIfIndex", 2, 0, + NULL, &_ipRouteDest_obj +}, +_ipRouteMetric1_obj = { + "ipRouteMetric1", 3, 0, + NULL, &_ipRouteIfIndex_obj +}, +_ipRouteMetric2_obj = { + "ipRouteMetric2", 4, 0, + NULL, &_ipRouteMetric1_obj +}, +_ipRouteMetric3_obj = { + "ipRouteMetric3", 5, 0, + NULL, &_ipRouteMetric2_obj +}, +_ipRouteMetric4_obj = { + "ipRouteMetric4", 6, 0, + NULL, &_ipRouteMetric3_obj +}, +_ipRouteNextHop_obj = { + "ipRouteNextHop", 7, 0, + NULL, &_ipRouteMetric4_obj +}, +_ipRouteType_obj = { + "ipRouteType", 8, 0, + NULL, &_ipRouteNextHop_obj +}, +_ipRouteProto_obj = { + "ipRouteProto", 9, 0, + NULL, &_ipRouteType_obj +}, +_ipRouteAge_obj = { + "ipRouteAge", 10, 0, + NULL, &_ipRouteProto_obj +}, +_ipRouteMask_obj = { + "ipRouteMask", 11, 0, + NULL, &_ipRouteAge_obj +}, +_ipRouteEntry_obj = { + "ipRouteEntry", 1, 0, + &_ipRouteMask_obj, NULL +}, +_ipAdEntAddr_obj = { + "ipAdEntAddr", 1, 0, + NULL, NULL +}, +_ipAdEntIfIndex_obj = { + "ipAdEntIfIndex", 2, 0, + NULL, &_ipAdEntAddr_obj +}, +_ipAdEntNetMask_obj = { + "ipAdEntNetMask", 3, 0, + NULL, &_ipAdEntIfIndex_obj +}, +_ipAdEntBcastAddr_obj = { + "ipAdEntBcastAddr", 4, 0, + NULL, &_ipAdEntNetMask_obj +}, +_ipAdEntReasmMaxSize_obj = { + "ipAdEntReasmMaxSize", 5, 0, + NULL, &_ipAdEntBcastAddr_obj +}, +_ipAddrEntry_obj = { + "ipAddrEntry", 1, 0, + &_ipAdEntReasmMaxSize_obj, NULL +}, +_ipForwarding_obj = { + "ipForwarding", 1, 0, + NULL, NULL +}, +_ipDefaultTTL_obj = { + "ipDefaultTTL", 2, 0, + NULL, &_ipForwarding_obj +}, +_ipInReceives_obj = { + "ipInReceives", 3, 0, + NULL, &_ipDefaultTTL_obj +}, +_ipInHdrErrors_obj = { + "ipInHdrErrors", 4, 0, + NULL, &_ipInReceives_obj +}, +_ipInAddrErrors_obj = { + "ipInAddrErrors", 5, 0, + NULL, &_ipInHdrErrors_obj +}, +_ipForwDatagrams_obj = { + "ipForwDatagrams", 6, 0, + NULL, &_ipInAddrErrors_obj +}, +_ipInUnknownProtos_obj = { + "ipInUnknownProtos", 7, 0, + NULL, &_ipForwDatagrams_obj +}, +_ipInDiscards_obj = { + "ipInDiscards", 8, 0, + NULL, &_ipInUnknownProtos_obj +}, +_ipInDelivers_obj = { + "ipInDelivers", 9, 0, + NULL, &_ipInDiscards_obj +}, +_ipOutRequests_obj = { + "ipOutRequests", 10, 0, + NULL, &_ipInDelivers_obj +}, +_ipOutDiscards_obj = { + "ipOutDiscards", 11, 0, + NULL, &_ipOutRequests_obj +}, +_ipOutNoRoutes_obj = { + "ipOutNoRoutes", 12, 0, + NULL, &_ipOutDiscards_obj +}, +_ipReasmTimeout_obj = { + "ipReasmTimeout", 13, 0, + NULL, &_ipOutNoRoutes_obj +}, +_ipReasmReqds_obj = { + "ipReasmReqds", 14, 0, + NULL, &_ipReasmTimeout_obj +}, +_ipReasmOKs_obj = { + "ipReasmOKs", 15, 0, + NULL, &_ipReasmReqds_obj +}, +_ipReasmFails_obj = { + "ipReasmFails", 16, 0, + NULL, &_ipReasmOKs_obj +}, +_ipFragOKs_obj = { + "ipFragOKs", 17, 0, + NULL, &_ipReasmFails_obj +}, +_ipFragFails_obj = { + "ipFragFails", 18, 0, + NULL, &_ipFragOKs_obj +}, +_ipFragCreates_obj = { + "ipFragCreates", 19, 0, + NULL, &_ipFragFails_obj +}, +_ipAddrTable_obj = { + "ipAddrTable", 20, 0, + &_ipAddrEntry_obj, &_ipFragCreates_obj +}, +_ipRoutingTable_obj = { + "ipRoutingTable", 21, 0, + &_ipRouteEntry_obj, &_ipAddrTable_obj +}, +_ipNetToMediaTable_obj = { + "ipNetToMediaTable", 22, 0, + &_ipNetToMediaEntry_obj, &_ipRoutingTable_obj +}, +_atIfIndex_obj = { + "atIfIndex", 1, 0, + NULL, NULL +}, +_atPhysAddress_obj = { + "atPhysAddress", 2, 0, + NULL, &_atIfIndex_obj +}, +_atNetAddress_obj = { + "atNetAddress", 3, 0, + NULL, &_atPhysAddress_obj +}, +_atEntry_obj = { + "atEntry", 1, 0, + &_atNetAddress_obj, NULL +}, +_atTable_obj = { + "atTable", 1, 0, + &_atEntry_obj, NULL +}, +_ifIndex_obj = { + "ifIndex", 1, 0, + NULL, NULL +}, +_ifDescr_obj = { + "ifDescr", 2, 0, + NULL, &_ifIndex_obj +}, +_ifType_obj = { + "ifType", 3, 0, + NULL, &_ifDescr_obj +}, +_ifMtu_obj = { + "ifMtu", 4, 0, + NULL, &_ifType_obj +}, +_ifSpeed_obj = { + "ifSpeed", 5, 0, + NULL, &_ifMtu_obj +}, +_ifPhysAddress_obj = { + "ifPhysAddress", 6, 0, + NULL, &_ifSpeed_obj +}, +_ifAdminStatus_obj = { + "ifAdminStatus", 7, 0, + NULL, &_ifPhysAddress_obj +}, +_ifOperStatus_obj = { + "ifOperStatus", 8, 0, + NULL, &_ifAdminStatus_obj +}, +_ifLastChange_obj = { + "ifLastChange", 9, 0, + NULL, &_ifOperStatus_obj +}, +_ifInOctets_obj = { + "ifInOctets", 10, 0, + NULL, &_ifLastChange_obj +}, +_ifInUcastPkts_obj = { + "ifInUcastPkts", 11, 0, + NULL, &_ifInOctets_obj +}, +_ifInNUcastPkts_obj = { + "ifInNUcastPkts", 12, 0, + NULL, &_ifInUcastPkts_obj +}, +_ifInDiscards_obj = { + "ifInDiscards", 13, 0, + NULL, &_ifInNUcastPkts_obj +}, +_ifInErrors_obj = { + "ifInErrors", 14, 0, + NULL, &_ifInDiscards_obj +}, +_ifInUnknownProtos_obj = { + "ifInUnknownProtos", 15, 0, + NULL, &_ifInErrors_obj +}, +_ifOutOctets_obj = { + "ifOutOctets", 16, 0, + NULL, &_ifInUnknownProtos_obj +}, +_ifOutUcastPkts_obj = { + "ifOutUcastPkts", 17, 0, + NULL, &_ifOutOctets_obj +}, +_ifOutNUcastPkts_obj = { + "ifOutNUcastPkts", 18, 0, + NULL, &_ifOutUcastPkts_obj +}, +_ifOutDiscards_obj = { + "ifOutDiscards", 19, 0, + NULL, &_ifOutNUcastPkts_obj +}, +_ifOutErrors_obj = { + "ifOutErrors", 20, 0, + NULL, &_ifOutDiscards_obj +}, +_ifOutQLen_obj = { + "ifOutQLen", 21, 0, + NULL, &_ifOutErrors_obj +}, +_ifSpecific_obj = { + "ifSpecific", 22, 0, + NULL, &_ifOutQLen_obj +}, +_ifEntry_obj = { + "ifEntry", 1, 0, + &_ifSpecific_obj, NULL +}, +_ifNumber_obj = { + "ifNumber", 1, 0, + NULL, NULL +}, +_ifTable_obj = { + "ifTable", 2, 0, + &_ifEntry_obj, &_ifNumber_obj +}, +_sysDescr_obj = { + "sysDescr", 1, 0, + NULL, NULL +}, +_sysObjectID_obj = { + "sysObjectID", 2, 0, + NULL, &_sysDescr_obj +}, +_sysUpTime_obj = { + "sysUpTime", 3, 0, + NULL, &_sysObjectID_obj +}, +_sysContact_obj = { + "sysContact", 4, 0, + NULL, &_sysUpTime_obj +}, +_sysName_obj = { + "sysName", 5, 0, + NULL, &_sysContact_obj +}, +_sysLocation_obj = { + "sysLocation", 6, 0, + NULL, &_sysName_obj +}, +_sysServices_obj = { + "sysServices", 7, 0, + NULL, &_sysLocation_obj +}, +_system_obj = { + "system", 1, 0, + &_sysServices_obj, NULL +}, +_interfaces_obj = { + "interfaces", 2, 0, + &_ifTable_obj, &_system_obj +}, +_at_obj = { + "at", 3, 0, + &_atTable_obj, &_interfaces_obj +}, +_ip_obj = { + "ip", 4, 0, + &_ipNetToMediaTable_obj, &_at_obj +}, +_icmp_obj = { + "icmp", 5, 0, + &_icmpOutAddrMaskReps_obj, &_ip_obj +}, +_tcp_obj = { + "tcp", 6, 0, + &_tcpOutRsts_obj, &_icmp_obj +}, +_udp_obj = { + "udp", 7, 0, + &_udpTable_obj, &_tcp_obj +}, +_egp_obj = { + "egp", 8, 0, + &_egpAs_obj, &_udp_obj +}, +_transmission_obj = { + "transmission", 10, 0, + NULL, &_egp_obj +}, +_snmp_obj = { + "snmp", 11, 0, + &_snmpEnableAuthTraps_obj, &_transmission_obj +}, +_usmMIBCompliances_obj = { + "usmMIBCompliances", 1, 0, + NULL, NULL +}, +_usmMIBGroups_obj = { + "usmMIBGroups", 2, 0, + NULL, &_usmMIBCompliances_obj +}, +_usmUserEngineID_obj = { + "usmUserEngineID", 1, 0, + NULL, NULL +}, +_usmUserName_obj = { + "usmUserName", 2, 0, + NULL, &_usmUserEngineID_obj +}, +_usmUserSecurityName_obj = { + "usmUserSecurityName", 3, 0, + NULL, &_usmUserName_obj +}, +_usmUserCloneFrom_obj = { + "usmUserCloneFrom", 4, 0, + NULL, &_usmUserSecurityName_obj +}, +_usmUserAuthProtocol_obj = { + "usmUserAuthProtocol", 5, 0, + NULL, &_usmUserCloneFrom_obj +}, +_usmUserAuthKeyChange_obj = { + "usmUserAuthKeyChange", 6, 0, + NULL, &_usmUserAuthProtocol_obj +}, +_usmUserOwnAuthKeyChange_obj = { + "usmUserOwnAuthKeyChange", 7, 0, + NULL, &_usmUserAuthKeyChange_obj +}, +_usmUserPrivProtocol_obj = { + "usmUserPrivProtocol", 8, 0, + NULL, &_usmUserOwnAuthKeyChange_obj +}, +_usmUserPrivKeyChange_obj = { + "usmUserPrivKeyChange", 9, 0, + NULL, &_usmUserPrivProtocol_obj +}, +_usmUserOwnPrivKeyChange_obj = { + "usmUserOwnPrivKeyChange", 10, 0, + NULL, &_usmUserPrivKeyChange_obj +}, +_usmUserPublic_obj = { + "usmUserPublic", 11, 0, + NULL, &_usmUserOwnPrivKeyChange_obj +}, +_usmUserStorageType_obj = { + "usmUserStorageType", 12, 0, + NULL, &_usmUserPublic_obj +}, +_usmUserStatus_obj = { + "usmUserStatus", 13, 0, + NULL, &_usmUserStorageType_obj +}, +_usmUserEntry_obj = { + "usmUserEntry", 1, 0, + &_usmUserStatus_obj, NULL +}, +_usmUserSpinLock_obj = { + "usmUserSpinLock", 1, 0, + NULL, NULL +}, +_usmUserTable_obj = { + "usmUserTable", 2, 0, + &_usmUserEntry_obj, &_usmUserSpinLock_obj +}, +_usmStatsUnsupportedSecLevels_obj = { + "usmStatsUnsupportedSecLevels", 1, 0, + NULL, NULL +}, +_usmStatsNotInTimeWindows_obj = { + "usmStatsNotInTimeWindows", 2, 0, + NULL, &_usmStatsUnsupportedSecLevels_obj +}, +_usmStatsUnknownUserNames_obj = { + "usmStatsUnknownUserNames", 3, 0, + NULL, &_usmStatsNotInTimeWindows_obj +}, +_usmStatsUnknownEngineIDs_obj = { + "usmStatsUnknownEngineIDs", 4, 0, + NULL, &_usmStatsUnknownUserNames_obj +}, +_usmStatsWrongDigests_obj = { + "usmStatsWrongDigests", 5, 0, + NULL, &_usmStatsUnknownEngineIDs_obj +}, +_usmStatsDecryptionErrors_obj = { + "usmStatsDecryptionErrors", 6, 0, + NULL, &_usmStatsWrongDigests_obj +}, +_usmStats_obj = { + "usmStats", 1, 0, + &_usmStatsDecryptionErrors_obj, NULL +}, +_usmUser_obj = { + "usmUser", 2, 0, + &_usmUserTable_obj, &_usmStats_obj +}, +_usmMIBObjects_obj = { + "usmMIBObjects", 1, 0, + &_usmUser_obj, NULL +}, +_usmMIBConformance_obj = { + "usmMIBConformance", 2, 0, + &_usmMIBGroups_obj, &_usmMIBObjects_obj +}, +_snmpMPDMIBCompliances_obj = { + "snmpMPDMIBCompliances", 1, 0, + NULL, NULL +}, +_snmpMPDMIBGroups_obj = { + "snmpMPDMIBGroups", 2, 0, + NULL, &_snmpMPDMIBCompliances_obj +}, +_snmpUnknownSecurityModels_obj = { + "snmpUnknownSecurityModels", 1, 0, + NULL, NULL +}, +_snmpInvalidMsgs_obj = { + "snmpInvalidMsgs", 2, 0, + NULL, &_snmpUnknownSecurityModels_obj +}, +_snmpUnknownPDUHandlers_obj = { + "snmpUnknownPDUHandlers", 3, 0, + NULL, &_snmpInvalidMsgs_obj +}, +_snmpMPDStats_obj = { + "snmpMPDStats", 1, 0, + &_snmpUnknownPDUHandlers_obj, NULL +}, +_snmpMPDAdmin_obj = { + "snmpMPDAdmin", 1, 0, + NULL, NULL +}, +_snmpMPDMIBObjects_obj = { + "snmpMPDMIBObjects", 2, 0, + &_snmpMPDStats_obj, &_snmpMPDAdmin_obj +}, +_snmpMPDMIBConformance_obj = { + "snmpMPDMIBConformance", 3, 0, + &_snmpMPDMIBGroups_obj, &_snmpMPDMIBObjects_obj +}, +_snmpEngineID_obj = { + "snmpEngineID", 1, 0, + NULL, NULL +}, +_snmpEngineBoots_obj = { + "snmpEngineBoots", 2, 0, + NULL, &_snmpEngineID_obj +}, +_snmpEngineTime_obj = { + "snmpEngineTime", 3, 0, + NULL, &_snmpEngineBoots_obj +}, +_snmpEngineMaxMessageSize_obj = { + "snmpEngineMaxMessageSize", 4, 0, + NULL, &_snmpEngineTime_obj +}, +_snmpEngine_obj = { + "snmpEngine", 1, 0, + &_snmpEngineMaxMessageSize_obj, NULL +}, +_snmpFrameworkAdmin_obj = { + "snmpFrameworkAdmin", 1, 0, + NULL, NULL +}, +_snmpFrameworkMIBObjects_obj = { + "snmpFrameworkMIBObjects", 2, 0, + &_snmpEngine_obj, &_snmpFrameworkAdmin_obj +}, +_snmpFrameworkMIBConformance_obj = { + "snmpFrameworkMIBConformance", 3, 0, + NULL, &_snmpFrameworkMIBObjects_obj +}, +_snmpFrameworkMIB_obj = { + "snmpFrameworkMIB", 10, 0, + &_snmpFrameworkMIBConformance_obj, NULL +}, +_snmpMPDMIB_obj = { + "snmpMPDMIB", 11, 0, + &_snmpMPDMIBConformance_obj, &_snmpFrameworkMIB_obj +}, +_snmpUsmMIB_obj = { + "snmpUsmMIB", 15, 0, + &_usmMIBConformance_obj, &_snmpMPDMIB_obj +}, +_snmpModules_obj = { + "snmpModules", 3, 0, + &_snmpUsmMIB_obj, NULL +}, +_mib_obj = { + "mib", 1, 0, + &_snmp_obj, NULL +}, +_directory_obj = { + "directory", 1, 0, + NULL, NULL +}, +_mgmt_obj = { + "mgmt", 2, 0, + &_mib_obj, &_directory_obj +}, +_experimental_obj = { + "experimental", 3, 0, + NULL, &_mgmt_obj +}, +_private_obj = { + "private", 4, 0, + &_enterprises_obj, &_experimental_obj +}, +_security_obj = { + "security", 5, 0, + NULL, &_private_obj +}, +_snmpV2_obj = { + "snmpV2", 6, 0, + &_snmpModules_obj, &_security_obj +}, +_internet_obj = { + "internet", 1, 0, + &_snmpV2_obj, NULL +}, +_dod_obj = { + "dod", 6, 0, + &_internet_obj, NULL +}, +_org_obj = { + "org", 3, 0, + &_dod_obj, NULL +}, +_iso_obj = { + "iso", 1, 0, + &_org_obj, NULL +}, +*mibroot = &_iso_obj; diff --git a/freebsd/contrib/tcpdump/mpls.h b/freebsd/contrib/tcpdump/mpls.h new file mode 100644 index 00000000..ae1c97e6 --- /dev/null +++ b/freebsd/contrib/tcpdump/mpls.h @@ -0,0 +1,41 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/mpls.h,v 1.1 2004-06-14 14:47:58 hannes Exp $ (LBL) + * 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. + */ + +#define LABEL_MASK 0xfffff000 +#define LABEL_SHIFT 12 +#define EXP_MASK 0x00000e00 +#define EXP_SHIFT 9 +#define STACK_MASK 0x00000100 +#define STACK_SHIFT 8 +#define TTL_MASK 0x000000ff +#define TTL_SHIFT 0 + +#define MPLS_LABEL(x) (((x) & LABEL_MASK) >> LABEL_SHIFT) +#define MPLS_EXP(x) (((x) & EXP_MASK) >> EXP_SHIFT) +#define MPLS_STACK(x) (((x) & STACK_MASK) >> STACK_SHIFT) +#define MPLS_TTL(x) (((x) & TTL_MASK) >> TTL_SHIFT) diff --git a/freebsd/contrib/tcpdump/nameser.h b/freebsd/contrib/tcpdump/nameser.h new file mode 100644 index 00000000..655afb42 --- /dev/null +++ b/freebsd/contrib/tcpdump/nameser.h @@ -0,0 +1,315 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/nameser.h,v 1.16 2006-11-10 03:18:21 guy Exp $ (LBL) */ +/* + * Copyright (c) 1983, 1989, 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. + * + * @(#)nameser.h 8.2 (Berkeley) 2/16/94 + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * 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. + * - + * --Copyright-- + */ + +#ifndef _NAMESER_H_ +#define _NAMESER_H_ + +#include <rtems/bsd/sys/types.h> + +/* + * Define constants based on rfc883 + */ +#define PACKETSZ 512 /* maximum packet size */ +#define MAXDNAME 256 /* maximum domain name */ +#define MAXCDNAME 255 /* maximum compressed domain name */ +#define MAXLABEL 63 /* maximum length of domain label */ + /* Number of bytes of fixed size data in query structure */ +#define QFIXEDSZ 4 + /* number of bytes of fixed size data in resource record */ +#define RRFIXEDSZ 10 + +/* + * Internet nameserver port number + */ +#define NAMESERVER_PORT 53 + +/* + * Port for multicast DNS; see + * + * http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt + * + * for the current mDNS spec. + */ +#define MULTICASTDNS_PORT 5353 + +/* + * Currently defined opcodes + */ +#define QUERY 0x0 /* standard query */ +#define IQUERY 0x1 /* inverse query */ +#define STATUS 0x2 /* nameserver status query */ +#if 0 +#define xxx 0x3 /* 0x3 reserved */ +#endif + /* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */ +#define UPDATEA 0x9 /* add resource record */ +#define UPDATED 0xa /* delete a specific resource record */ +#define UPDATEDA 0xb /* delete all named resource record */ +#define UPDATEM 0xc /* modify a specific resource record */ +#define UPDATEMA 0xd /* modify all named resource record */ + +#define ZONEINIT 0xe /* initial zone transfer */ +#define ZONEREF 0xf /* incremental zone referesh */ + +/* + * Undefine various #defines from various System V-flavored OSes (Solaris, + * SINIX, HP-UX) so the compiler doesn't whine that we redefine them. + */ +#ifdef T_NULL +#undef T_NULL +#endif +#ifdef T_OPT +#undef T_OPT +#endif +#ifdef T_UNSPEC +#undef T_UNSPEC +#endif +#ifdef NOERROR +#undef NOERROR +#endif + +/* + * Currently defined response codes + */ +#define NOERROR 0 /* no error */ +#define FORMERR 1 /* format error */ +#define SERVFAIL 2 /* server failure */ +#define NXDOMAIN 3 /* non existent domain */ +#define NOTIMP 4 /* not implemented */ +#define REFUSED 5 /* query refused */ + /* non standard */ +#define NOCHANGE 0xf /* update failed to change db */ + +/* + * Type values for resources and queries + */ +#define T_A 1 /* host address */ +#define T_NS 2 /* authoritative server */ +#define T_MD 3 /* mail destination */ +#define T_MF 4 /* mail forwarder */ +#define T_CNAME 5 /* connonical name */ +#define T_SOA 6 /* start of authority zone */ +#define T_MB 7 /* mailbox domain name */ +#define T_MG 8 /* mail group member */ +#define T_MR 9 /* mail rename name */ +#define T_NULL 10 /* null resource record */ +#define T_WKS 11 /* well known service */ +#define T_PTR 12 /* domain name pointer */ +#define T_HINFO 13 /* host information */ +#define T_MINFO 14 /* mailbox information */ +#define T_MX 15 /* mail routing information */ +#define T_TXT 16 /* text strings */ +#define T_RP 17 /* responsible person */ +#define T_AFSDB 18 /* AFS cell database */ +#define T_X25 19 /* X_25 calling address */ +#define T_ISDN 20 /* ISDN calling address */ +#define T_RT 21 /* router */ +#define T_NSAP 22 /* NSAP address */ +#define T_NSAP_PTR 23 /* reverse lookup for NSAP */ +#define T_SIG 24 /* security signature */ +#define T_KEY 25 /* security key */ +#define T_PX 26 /* X.400 mail mapping */ +#define T_GPOS 27 /* geographical position (withdrawn) */ +#define T_AAAA 28 /* IP6 Address */ +#define T_LOC 29 /* Location Information */ +#define T_NXT 30 /* Next Valid Name in Zone */ +#define T_EID 31 /* Endpoint identifier */ +#define T_NIMLOC 32 /* Nimrod locator */ +#define T_SRV 33 /* Server selection */ +#define T_ATMA 34 /* ATM Address */ +#define T_NAPTR 35 /* Naming Authority PoinTeR */ +#define T_KX 36 /* Key Exchanger */ +#define T_CERT 37 /* Certificates in the DNS */ +#define T_A6 38 /* IP6 address */ +#define T_DNAME 39 /* non-terminal redirection */ +#define T_SINK 40 /* unknown */ +#define T_OPT 41 /* EDNS0 option (meta-RR) */ +#define T_APL 42 /* lists of address prefixes */ +#define T_DS 43 /* Delegation Signer */ +#define T_SSHFP 44 /* SSH Fingerprint */ +#define T_IPSECKEY 45 /* IPsec keying material */ +#define T_RRSIG 46 /* new security signature */ +#define T_NSEC 47 /* provable insecure information */ +#define T_DNSKEY 48 /* new security key */ + /* non standard */ +#define T_SPF 99 /* sender policy framework */ +#define T_UINFO 100 /* user (finger) information */ +#define T_UID 101 /* user ID */ +#define T_GID 102 /* group ID */ +#define T_UNSPEC 103 /* Unspecified format (binary data) */ +#define T_UNSPECA 104 /* "unspecified ascii". Ugly MIT hack */ + /* Query type values which do not appear in resource records */ +#define T_TKEY 249 /* Transaction Key [RFC2930] */ +#define T_TSIG 250 /* Transaction Signature [RFC2845] */ +#define T_IXFR 251 /* incremental transfer [RFC1995] */ +#define T_AXFR 252 /* transfer zone of authority */ +#define T_MAILB 253 /* transfer mailbox records */ +#define T_MAILA 254 /* transfer mail agent records */ +#define T_ANY 255 /* wildcard match */ + +/* + * Values for class field + */ + +#define C_IN 1 /* the arpa internet */ +#define C_CHAOS 3 /* for chaos net (MIT) */ +#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */ + /* Query class values which do not appear in resource records */ +#define C_ANY 255 /* wildcard match */ +#define C_QU 0x8000 /* mDNS QU flag in queries */ +#define C_CACHE_FLUSH 0x8000 /* mDNS cache flush flag in replies */ + +/* + * Status return codes for T_UNSPEC conversion routines + */ +#define CONV_SUCCESS 0 +#define CONV_OVERFLOW -1 +#define CONV_BADFMT -2 +#define CONV_BADCKSUM -3 +#define CONV_BADBUFLEN -4 + +/* + * Structure for query header. + */ +typedef struct { + u_int16_t id; /* query identification number */ + u_int8_t flags1; /* first byte of flags */ + u_int8_t flags2; /* second byte of flags */ + u_int16_t qdcount; /* number of question entries */ + u_int16_t ancount; /* number of answer entries */ + u_int16_t nscount; /* number of authority entries */ + u_int16_t arcount; /* number of resource entries */ +} HEADER; + +/* + * Macros for subfields of flag fields. + */ +#define DNS_QR(np) ((np)->flags1 & 0x80) /* response flag */ +#define DNS_OPCODE(np) ((((np)->flags1) >> 3) & 0xF) /* purpose of message */ +#define DNS_AA(np) ((np)->flags1 & 0x04) /* authoritative answer */ +#define DNS_TC(np) ((np)->flags1 & 0x02) /* truncated message */ +#define DNS_RD(np) ((np)->flags1 & 0x01) /* recursion desired */ + +#define DNS_RA(np) ((np)->flags2 & 0x80) /* recursion available */ +#define DNS_AD(np) ((np)->flags2 & 0x20) /* authentic data from named */ +#define DNS_CD(np) ((np)->flags2 & 0x10) /* checking disabled by resolver */ +#define DNS_RCODE(np) ((np)->flags2 & 0xF) /* response code */ + +/* + * Defines for handling compressed domain names, EDNS0 labels, etc. + */ +#define INDIR_MASK 0xc0 /* 11.... */ +#define EDNS0_MASK 0x40 /* 01.... */ +# define EDNS0_ELT_BITLABEL 0x01 + +/* + * Structure for passing resource records around. + */ +struct rrec { + int16_t r_zone; /* zone number */ + int16_t r_class; /* class number */ + int16_t r_type; /* type number */ + u_int32_t r_ttl; /* time to live */ + int r_size; /* size of data area */ + char *r_data; /* pointer to data */ +}; + +/* + * Inline versions of get/put short/long. Pointer is advanced. + * We also assume that a "u_int16_t" holds 2 "chars" + * and that a "u_int32_t" holds 4 "chars". + * + * These macros demonstrate the property of C whereby it can be + * portable or it can be elegant but never both. + */ +#define GETSHORT(s, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) | (u_int16_t)t_cp[1]; \ + (cp) += 2; \ +} + +#define GETLONG(l, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (l) = (((u_int32_t)t_cp[0]) << 24) \ + | (((u_int32_t)t_cp[1]) << 16) \ + | (((u_int32_t)t_cp[2]) << 8) \ + | (((u_int32_t)t_cp[3])); \ + (cp) += 4; \ +} + +#define PUTSHORT(s, cp) { \ + register u_int16_t t_s = (u_int16_t)(s); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += 2; \ +} + +/* + * Warning: PUTLONG --no-longer-- destroys its first argument. if you + * were depending on this "feature", you will lose. + */ +#define PUTLONG(l, cp) { \ + register u_int32_t t_l = (u_int32_t)(l); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += 4; \ +} + +#endif /* !_NAMESER_H_ */ diff --git a/freebsd/contrib/tcpdump/netbios.h b/freebsd/contrib/tcpdump/netbios.h new file mode 100644 index 00000000..d3e2725f --- /dev/null +++ b/freebsd/contrib/tcpdump/netbios.h @@ -0,0 +1,16 @@ +/* + * NETBIOS protocol formats + * + * @(#) $Header: /tcpdump/master/tcpdump/netbios.h,v 1.3 2002-12-11 07:13:55 guy Exp $ + */ + +struct p8022Hdr { + u_char dsap; + u_char ssap; + u_char flags; +}; + +#define p8022Size 3 /* min 802.2 header size */ + +#define UI 0x03 /* 802.2 flags */ + diff --git a/freebsd/contrib/tcpdump/netdissect.h b/freebsd/contrib/tcpdump/netdissect.h new file mode 100644 index 00000000..d201d8c3 --- /dev/null +++ b/freebsd/contrib/tcpdump/netdissect.h @@ -0,0 +1,515 @@ +/* + * Copyright (c) 1988-1997 + * The Regents of the University of California. All rights reserved. + * + * Copyright (c) 1998-2012 Michael Richardson <mcr@tcpdump.org> + * 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, (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/netdissect.h,v 1.27 2008-08-16 11:36:20 hannes Exp $ (LBL) + */ + +#ifndef netdissect_h +#define netdissect_h + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif +#include <rtems/bsd/sys/types.h> + +#ifndef HAVE___ATTRIBUTE__ +#define __attribute__(x) +#endif + +/* snprintf et al */ + +#include <stdarg.h> + +#if !defined(HAVE_SNPRINTF) +int snprintf (char *str, size_t sz, const char *format, ...) + __attribute__ ((format (printf, 3, 4))); +#endif + +#if !defined(HAVE_VSNPRINTF) +int vsnprintf (char *str, size_t sz, const char *format, va_list ap) + __attribute__((format (printf, 3, 0))); +#endif + +#ifndef HAVE_STRLCAT +extern size_t strlcat (char *, const char *, size_t); +#endif +#ifndef HAVE_STRLCPY +extern size_t strlcpy (char *, const char *, size_t); +#endif + +#ifndef HAVE_STRDUP +extern char *strdup (const char *str); +#endif + +#ifndef HAVE_STRSEP +extern char *strsep(char **, const char *); +#endif + +struct tok { + int v; /* value */ + const char *s; /* string */ +}; + +#define TOKBUFSIZE 128 +extern const char *tok2strbuf(const struct tok *, const char *, int, + char *buf, size_t bufsize); + +/* tok2str is deprecated */ +extern const char *tok2str(const struct tok *, const char *, int); +extern char *bittok2str(const struct tok *, const char *, int); +extern char *bittok2str_nosep(const struct tok *, const char *, int); + + +typedef struct netdissect_options netdissect_options; + +struct netdissect_options { + int ndo_aflag; /* translate network and broadcast addresses */ + int ndo_bflag; /* print 4 byte ASes in ASDOT notation */ + int ndo_eflag; /* print ethernet header */ + int ndo_fflag; /* don't translate "foreign" IP address */ + int ndo_Kflag; /* don't check TCP checksums */ + int ndo_nflag; /* leave addresses as numbers */ + int ndo_Nflag; /* remove domains from printed host names */ + int ndo_qflag; /* quick (shorter) output */ + int ndo_Rflag; /* print sequence # field in AH/ESP*/ + int ndo_sflag; /* use the libsmi to translate OIDs */ + int ndo_Sflag; /* print raw TCP sequence numbers */ + int ndo_tflag; /* print packet arrival time */ + int ndo_Uflag; /* "unbuffered" output of dump files */ + int ndo_uflag; /* Print undecoded NFS handles */ + int ndo_vflag; /* verbose */ + int ndo_xflag; /* print packet in hex */ + int ndo_Xflag; /* print packet in hex/ascii */ + int ndo_Aflag; /* print packet only in ascii observing TAB, + * LF, CR and SPACE as graphical chars + */ + int ndo_Bflag; /* buffer size */ + int ndo_Iflag; /* rfmon (monitor) mode */ + int ndo_Oflag; /* run filter code optimizer */ + int ndo_dlt; /* if != -1, ask libpcap for the DLT it names*/ + int ndo_jflag; /* packet time stamp source */ + int ndo_pflag; /* don't go promiscuous */ + + int ndo_Cflag; /* rotate dump files after this many bytes */ + int ndo_Cflag_count; /* Keep track of which file number we're writing */ + int ndo_Gflag; /* rotate dump files after this many seconds */ + int ndo_Gflag_count; /* number of files created with Gflag rotation */ + time_t ndo_Gflag_time; /* The last time_t the dump file was rotated. */ + int ndo_Wflag; /* recycle output files after this number of files */ + int ndo_WflagChars; + int ndo_Hflag; /* dissect 802.11s draft mesh standard */ + int ndo_suppress_default_print; /* don't use default_print() for unknown packet types */ + const char *ndo_dltname; + + char *ndo_espsecret; + struct sa_list *ndo_sa_list_head; /* used by print-esp.c */ + struct sa_list *ndo_sa_default; + + char *ndo_sigsecret; /* Signature verification secret key */ + + struct esp_algorithm *ndo_espsecret_xform; /* cache of decoded */ + char *ndo_espsecret_key; + + int ndo_packettype; /* as specified by -T */ + + char *ndo_program_name; /*used to generate self-identifying messages */ + + int32_t ndo_thiszone; /* seconds offset from gmt to local time */ + + int ndo_snaplen; + + /*global pointers to beginning and end of current packet (during printing) */ + const u_char *ndo_packetp; + const u_char *ndo_snapend; + + /* bookkeeping for ^T output */ + int ndo_infodelay; + + /* pointer to void function to output stuff */ + void (*ndo_default_print)(netdissect_options *, + register const u_char *bp, register u_int length); + void (*ndo_info)(netdissect_options *, int verbose); + + int (*ndo_printf)(netdissect_options *, + const char *fmt, ...) +#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS + __attribute__ ((format (printf, 2, 3))) +#endif + ; + void (*ndo_error)(netdissect_options *, + const char *fmt, ...) +#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS + __attribute__ ((noreturn, format (printf, 2, 3))) +#endif + ; + void (*ndo_warning)(netdissect_options *, + const char *fmt, ...) +#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS + __attribute__ ((format (printf, 2, 3))) +#endif + ; +}; + +#define PT_VAT 1 /* Visual Audio Tool */ +#define PT_WB 2 /* distributed White Board */ +#define PT_RPC 3 /* Remote Procedure Call */ +#define PT_RTP 4 /* Real-Time Applications protocol */ +#define PT_RTCP 5 /* Real-Time Applications control protocol */ +#define PT_SNMP 6 /* Simple Network Management Protocol */ +#define PT_CNFP 7 /* Cisco NetFlow protocol */ +#define PT_TFTP 8 /* trivial file transfer protocol */ +#define PT_AODV 9 /* Ad-hoc On-demand Distance Vector Protocol */ +#define PT_CARP 10 /* Common Address Redundancy Protocol */ +#define PT_RADIUS 11 /* RADIUS authentication Protocol */ +#define PT_ZMTP1 12 /* ZeroMQ Message Transport Protocol 1.0 */ +#define PT_VXLAN 13 /* Virtual eXtensible Local Area Network */ + +#ifndef min +#define min(a,b) ((a)>(b)?(b):(a)) +#endif +#ifndef max +#define max(a,b) ((b)>(a)?(b):(a)) +#endif + +/* + * Maximum snapshot length. This should be enough to capture the full + * packet on most network interfaces. + * + * XXX - could it be larger? If so, should it? Some applications might + * use the snapshot length in a savefile header to control the size of + * the buffer they allocate, so a size of, say, 2^31-1 might not work + * well. + */ +#define MAXIMUM_SNAPLEN 65535 + +/* + * The default snapshot length is the maximum. + */ +#define DEFAULT_SNAPLEN MAXIMUM_SNAPLEN + +#define ESRC(ep) ((ep)->ether_shost) +#define EDST(ep) ((ep)->ether_dhost) + +#ifndef NTOHL +#define NTOHL(x) (x) = ntohl(x) +#define NTOHS(x) (x) = ntohs(x) +#define HTONL(x) (x) = htonl(x) +#define HTONS(x) (x) = htons(x) +#endif + +/* + * True if "l" bytes of "var" were captured. + * + * The "ndo->ndo_snapend - (l) <= ndo->ndo_snapend" checks to make sure + * "l" isn't so large that "ndo->ndo_snapend - (l)" underflows. + * + * The check is for <= rather than < because "l" might be 0. + */ +#define ND_TTEST2(var, l) (ndo->ndo_snapend - (l) <= ndo->ndo_snapend && \ + (const u_char *)&(var) <= ndo->ndo_snapend - (l)) + +/* True if "var" was captured */ +#define ND_TTEST(var) ND_TTEST2(var, sizeof(var)) + +/* Bail if "l" bytes of "var" were not captured */ +#define ND_TCHECK2(var, l) if (!ND_TTEST2(var, l)) goto trunc + +/* Bail if "var" was not captured */ +#define ND_TCHECK(var) ND_TCHECK2(var, sizeof(var)) + +#define ND_PRINT(STUFF) (*ndo->ndo_printf)STUFF +#define ND_DEFAULTPRINT(ap, length) (*ndo->ndo_default_print)(ndo, ap, length) + +#if 0 +extern void ts_print(netdissect_options *ipdo, + const struct timeval *); +extern void relts_print(int); +#endif + +extern int fn_print(const u_char *, const u_char *); +extern int fn_printn(const u_char *, u_int, const u_char *); +extern const char *tok2str(const struct tok *, const char *, int); + +extern void wrapup(int); + +#if 0 +extern char *read_infile(netdissect_options *, char *); +extern char *copy_argv(netdissect_options *, char **); +#endif + +extern void safeputchar(int); +extern void safeputs(const char *, int); + +#define PLURAL_SUFFIX(n) \ + (((n) != 1) ? "s" : "") + +#if 0 +extern const char *isonsap_string(netdissect_options *, const u_char *); +extern const char *protoid_string(netdissect_options *, const u_char *); +extern const char *dnname_string(netdissect_options *, u_short); +extern const char *dnnum_string(netdissect_options *, u_short); +#endif + +/* The printer routines. */ + +#include <pcap.h> + +typedef u_int (*if_ndo_printer)(struct netdissect_options *ndo, + const struct pcap_pkthdr *, const u_char *); +typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *); + +extern if_ndo_printer lookup_ndo_printer(int); +extern if_printer lookup_printer(int); + +extern void eap_print(netdissect_options *,const u_char *, u_int); +extern int esp_print(netdissect_options *, + register const u_char *bp, int len, register const u_char *bp2, + int *nhdr, int *padlen); +extern void arp_print(netdissect_options *,const u_char *, u_int, u_int); +extern void tipc_print(netdissect_options *, const u_char *, u_int, u_int); +extern void msnlb_print(netdissect_options *, const u_char *, u_int); +extern void icmp6_print(netdissect_options *ndo, const u_char *, + u_int, const u_char *, int); +extern void isakmp_print(netdissect_options *,const u_char *, + u_int, const u_char *); +extern void isakmp_rfc3948_print(netdissect_options *,const u_char *, + u_int, const u_char *); +extern void ip_print(netdissect_options *,const u_char *, u_int); +extern void ip_print_inner(netdissect_options *ndo, + const u_char *bp, u_int length, u_int nh, + const u_char *bp2); +extern void rrcp_print(netdissect_options *,const u_char *, u_int); + +extern void ether_print(netdissect_options *, + const u_char *, u_int, u_int, + void (*)(netdissect_options *, const u_char *), + const u_char *); + +extern u_int ether_if_print(netdissect_options *, + const struct pcap_pkthdr *,const u_char *); +extern u_int netanalyzer_if_print(netdissect_options *, + const struct pcap_pkthdr *,const u_char *); +extern u_int netanalyzer_transparent_if_print(netdissect_options *, + const struct pcap_pkthdr *, + const u_char *); + +extern int ethertype_print(netdissect_options *,u_short, const u_char *, + u_int, u_int); + +/* stuff that has not yet been rototiled */ +#if 0 +extern void ascii_print(netdissect_options *,u_int); +extern void hex_and_ascii_print_with_offset(netdissect_options *,const char *, + u_int, u_int); +extern void hex_and_ascii_print(netdissect_options *,const char *, u_int); +extern void hex_print_with_offset(netdissect_options *,const char *, + u_int, u_int); +extern void hex_print(netdissect_options *,const char *, u_int); +extern void telnet_print(netdissect_options *,const u_char *, u_int); +extern int llc_print(netdissect_options *, + const u_char *, u_int, u_int, const u_char *, + const u_char *, u_short *); +extern void aarp_print(netdissect_options *,const u_char *, u_int); +extern void atalk_print(netdissect_options *,const u_char *, u_int); +extern void atm_if_print(u_char *,const struct pcap_pkthdr *, const u_char *); +extern void bootp_print(netdissect_options *,const u_char *, + u_int, u_short, u_short); +extern void bgp_print(netdissect_options *,const u_char *, int); +extern void bxxp_print(netdissect_options *,const u_char *, u_int); +extern void chdlc_if_print(u_char *user, const struct pcap_pkthdr *h, + register const u_char *p); +extern void chdlc_print(netdissect_options *ndo, + register const u_char *p, u_int length, u_int caplen); +extern void cisco_autorp_print(netdissect_options *, + const u_char *, u_int); +extern void cnfp_print(netdissect_options *,const u_char *cp, + u_int len, const u_char *bp); +extern void decnet_print(netdissect_options *,const u_char *, + u_int, u_int); +extern void default_print(netdissect_options *,const u_char *, u_int); +extern void dvmrp_print(netdissect_options *,const u_char *, u_int); +extern void egp_print(netdissect_options *,const u_char *, u_int, + const u_char *); + +extern void arcnet_if_print(u_char*,const struct pcap_pkthdr *,const u_char *); +extern void token_if_print(u_char *,const struct pcap_pkthdr *,const u_char *); +extern void fddi_if_print(u_char *,const struct pcap_pkthdr *, const u_char *); + +extern void gre_print(netdissect_options *,const u_char *, u_int); +extern void icmp_print(netdissect_options *,const u_char *, u_int, + const u_char *); +extern void hsrp_print(netdissect_options *ndo, + register const u_char *bp, register u_int len); +extern void ieee802_11_if_print(u_char *,const struct pcap_pkthdr *, const u_char *); +extern void igmp_print(netdissect_options *, + register const u_char *, u_int); +extern void igrp_print(netdissect_options *,const u_char *, u_int, + const u_char *); +extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int); +extern void ipN_print(netdissect_options *,const u_char *, u_int); +extern void ipx_print(netdissect_options *,const u_char *, u_int); +extern void isoclns_print(netdissect_options *,const u_char *, + u_int, u_int, const u_char *, const u_char *); +extern void krb_print(netdissect_options *,const u_char *, u_int); +extern void llap_print(netdissect_options *,const u_char *, u_int); +extern const char *linkaddr_string(netdissect_options *ndo, + const u_char *ep, const unsigned int len); +extern void ltalk_if_print(netdissect_options *ndo, + u_char *user, const struct pcap_pkthdr *h, + const u_char *p); +extern void mpls_print(netdissect_options *ndo, + const u_char *bp, u_int length); +extern void msdp_print(netdissect_options *ndo, + const unsigned char *sp, u_int length); +extern void nfsreply_print(netdissect_options *,const u_char *, + u_int, const u_char *); +extern void nfsreq_print(netdissect_options *,const u_char *, + u_int, const u_char *); +extern void ns_print(netdissect_options *,const u_char *, u_int); +extern void ntp_print(netdissect_options *,const u_char *, u_int); +extern void null_if_print(u_char *,const struct pcap_pkthdr *, const u_char *); +extern void ospf_print(netdissect_options *,const u_char *, + u_int, const u_char *); +extern void pimv1_print(netdissect_options *,const u_char *, u_int); +extern void mobile_print(netdissect_options *,const u_char *, u_int); +extern void pim_print(netdissect_options *,const u_char *, u_int, u_int); +extern void pppoe_if_print(u_char *,const struct pcap_pkthdr *, const u_char *); +extern void pppoe_print(netdissect_options *,const u_char *, u_int); +extern void ppp_print(netdissect_options *, + register const u_char *, u_int); + +extern void ppp_if_print(u_char *,const struct pcap_pkthdr *, const u_char *); +extern void ppp_hdlc_if_print(u_char *, + const struct pcap_pkthdr *, const u_char *); +extern void ppp_bsdos_if_print(u_char *, + const struct pcap_pkthdr *, const u_char *); + +extern int vjc_print(netdissect_options *,register const char *, + register u_int, u_short); + +extern void raw_if_print(u_char *, + const struct pcap_pkthdr *, const u_char *); + +extern void rip_print(netdissect_options *,const u_char *, u_int); +extern void rpki_rtr_print(netdissect_options *,const u_char *, u_int); + +extern void sctp_print(netdissect_options *ndo, + const u_char *bp, const u_char *bp2, + u_int sctpPacketLength); + +extern void sl_if_print(u_char *,const struct pcap_pkthdr *, const u_char *); + +extern void lane_if_print(u_char *,const struct pcap_pkthdr *,const u_char *); +extern void cip_if_print(u_char *,const struct pcap_pkthdr *,const u_char *); +extern void sl_bsdos_if_print(u_char *, + const struct pcap_pkthdr *, const u_char *); +extern void sll_if_print(u_char *, + const struct pcap_pkthdr *, const u_char *); + +extern void snmp_print(netdissect_options *,const u_char *, u_int); +extern void sunrpcrequest_print(netdissect_options *,const u_char *, + u_int, const u_char *); +extern void tcp_print(netdissect_options *,const u_char *, u_int, + const u_char *, int); +extern void tftp_print(netdissect_options *,const u_char *, u_int); +extern void timed_print(netdissect_options *,const u_char *, u_int); +extern void udp_print(netdissect_options *,const u_char *, u_int, + const u_char *, int); +extern void wb_print(netdissect_options *,const void *, u_int); +extern int ah_print(netdissect_options *,register const u_char *, + register const u_char *); +extern void esp_print_decodesecret(netdissect_options *ndo); +extern int ipcomp_print(netdissect_options *,register const u_char *, + register const u_char *, int *); +extern void rx_print(netdissect_options *,register const u_char *, + int, int, int, u_char *); +extern void netbeui_print(netdissect_options *,u_short, + const u_char *, int); +extern void ipx_netbios_print(netdissect_options *,const u_char *, u_int); +extern void nbt_tcp_print(netdissect_options *,const u_char *, int); +extern void nbt_udp137_print(netdissect_options *, + const u_char *data, int); +extern void nbt_udp138_print(netdissect_options *, + const u_char *data, int); +extern char *smb_errstr(netdissect_options *,int, int); +extern const char *nt_errstr(netdissect_options *, u_int32_t); +extern void print_data(netdissect_options *,const unsigned char *, int); +extern void l2tp_print(netdissect_options *,const u_char *, u_int); +extern void lcp_print(netdissect_options *,const u_char *, u_int); +extern void vrrp_print(netdissect_options *,const u_char *bp, + u_int len, int ttl); +extern void carp_print(netdissect_options *,const u_char *bp, + u_int len, int ttl); +extern void cdp_print(netdissect_options *,const u_char *, + u_int, u_int, const u_char *, const u_char *); +extern void stp_print(netdissect_options *,const u_char *p, u_int length); +extern void radius_print(netdissect_options *,const u_char *, u_int); +extern void lwres_print(netdissect_options *,const u_char *, u_int); +extern void pptp_print(netdissect_options *,const u_char *, u_int); +#endif + +extern u_int ipnet_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); +extern u_int ppi_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); + +extern u_int ieee802_15_4_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *); + +#ifdef INET6 +extern void ip6_print(netdissect_options *,const u_char *, u_int); +#if 0 +extern void ip6_opt_print(netdissect_options *,const u_char *, int); +extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int); +extern int hbhopt_print(netdissect_options *,const u_char *); +extern int dstopt_print(netdissect_options *,const u_char *); +extern int frag6_print(netdissect_options *,const u_char *, + const u_char *); +extern void icmp6_print(netdissect_options *,const u_char *, + const u_char *); +extern void ripng_print(netdissect_options *,const u_char *, int); +extern int rt6_print(netdissect_options *,const u_char *, const u_char *); +extern void ospf6_print(netdissect_options *,const u_char *, u_int); +extern void dhcp6_print(netdissect_options *,const u_char *, + u_int, u_int16_t, u_int16_t); + +extern void zephyr_print(netdissect_options * ndo, + const u_char *cp, int length); +#endif /* 0 */ + +#endif /*INET6*/ + +#if 0 +struct cksum_vec { + const u_int8_t *ptr; + int len; +}; +extern u_int16_t in_cksum(const struct cksum_vec *, int); +extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t); +#endif + +extern void esp_print_decodesecret(netdissect_options *ndo); +extern int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, + int initiator, + u_char spii[8], u_char spir[8], + u_char *buf, u_char *end); + + +#endif /* netdissect_h */ diff --git a/freebsd/contrib/tcpdump/nfs.h b/freebsd/contrib/tcpdump/nfs.h new file mode 100644 index 00000000..b35e2cd5 --- /dev/null +++ b/freebsd/contrib/tcpdump/nfs.h @@ -0,0 +1,440 @@ +/* @(#) $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. + * + * $FreeBSD$ + * @(#)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; +}; diff --git a/freebsd/contrib/tcpdump/nfsfh.h b/freebsd/contrib/tcpdump/nfsfh.h new file mode 100644 index 00000000..82367132 --- /dev/null +++ b/freebsd/contrib/tcpdump/nfsfh.h @@ -0,0 +1,70 @@ +/* @(#) $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 + * $FreeBSD$ + * $NetBSD: nfsfh.h,v 1.1.1.2 1997/10/03 17:25:13 christos Exp $ + */ + +/* + * 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 *, ino_t *, const char **, const char **, int); diff --git a/freebsd/contrib/tcpdump/nlpid.c b/freebsd/contrib/tcpdump/nlpid.c new file mode 100644 index 00000000..83bfedf0 --- /dev/null +++ b/freebsd/contrib/tcpdump/nlpid.c @@ -0,0 +1,48 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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/nlpid.c,v 1.4 2004-10-19 15:27:55 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> +#include "interface.h" +#include "nlpid.h" + +const struct tok nlpid_values[] = { + { NLPID_NULLNS, "NULL" }, + { NLPID_Q933, "Q.933" }, + { NLPID_LMI, "LMI" }, + { NLPID_SNAP, "SNAP" }, + { NLPID_CLNP, "CLNP" }, + { NLPID_ESIS, "ES-IS" }, + { NLPID_ISIS, "IS-IS" }, + { NLPID_CONS, "CONS" }, + { NLPID_IDRP, "IDRP" }, + { NLPID_SPB, "ISIS_SPB" }, + { NLPID_MFR, "FRF.15" }, + { NLPID_IP, "IPv4" }, + { NLPID_PPP, "PPP" }, + { NLPID_X25_ESIS, "X25 ES-IS" }, + { NLPID_IP6, "IPv6" }, + { 0, NULL } +}; diff --git a/freebsd/contrib/tcpdump/nlpid.h b/freebsd/contrib/tcpdump/nlpid.h new file mode 100644 index 00000000..1546fc6e --- /dev/null +++ b/freebsd/contrib/tcpdump/nlpid.h @@ -0,0 +1,33 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/nlpid.h,v 1.4 2004-10-19 15:27:55 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 nlpid_values[]; + +#define NLPID_NULLNS 0x00 +#define NLPID_Q933 0x08 /* ANSI T1.617 Annex D or ITU-T Q.933 Annex A */ +#define NLPID_LMI 0x09 /* The original, aka Cisco, aka Gang of Four */ +#define NLPID_SNAP 0x80 +#define NLPID_CLNP 0x81 /* iso9577 */ +#define NLPID_ESIS 0x82 /* iso9577 */ +#define NLPID_ISIS 0x83 /* iso9577 */ +#define NLPID_CONS 0x84 +#define NLPID_IDRP 0x85 +#define NLPID_MFR 0xb1 /* FRF.15 */ +#define NLPID_SPB 0xc1 /* IEEE 802.1aq/D4.5 */ +#define NLPID_IP 0xcc +#define NLPID_PPP 0xcf +#define NLPID_X25_ESIS 0x8a +#define NLPID_IP6 0x8e diff --git a/freebsd/contrib/tcpdump/ntp.h b/freebsd/contrib/tcpdump/ntp.h new file mode 100644 index 00000000..0614f73b --- /dev/null +++ b/freebsd/contrib/tcpdump/ntp.h @@ -0,0 +1,127 @@ +/* $Header: /tcpdump/master/tcpdump/ntp.h,v 1.8 2004-01-28 14:34:50 hannes Exp $ */ + +/* + * Based on ntp.h from the U of MD implementation + * This file is based on Version 2 of the NTP spec (RFC1119). + */ + +/* + * Definitions for the masses + */ +#define JAN_1970 2208988800U /* 1970 - 1900 in seconds */ + +/* + * Structure definitions for NTP fixed point values + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Integer Part | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Fraction Part | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Integer Part | Fraction Part | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +struct l_fixedpt { + u_int32_t int_part; + u_int32_t fraction; +}; + +struct s_fixedpt { + u_int16_t int_part; + u_int16_t fraction; +}; + +/* rfc2030 + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |LI | VN |Mode | Stratum | Poll | Precision | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Root Delay | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Root Dispersion | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reference Identifier | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Reference Timestamp (64) | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Originate Timestamp (64) | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Receive Timestamp (64) | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Transmit Timestamp (64) | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key Identifier (optional) (32) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | | + * | Message Digest (optional) (128) | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct ntpdata { + u_char status; /* status of local clock and leap info */ + u_char stratum; /* Stratum level */ + u_char ppoll; /* poll value */ + int precision:8; + struct s_fixedpt root_delay; + struct s_fixedpt root_dispersion; + u_int32_t refid; + struct l_fixedpt ref_timestamp; + struct l_fixedpt org_timestamp; + struct l_fixedpt rec_timestamp; + struct l_fixedpt xmt_timestamp; + u_int32_t key_id; + u_int8_t message_digest[16]; +}; +/* + * Leap Second Codes (high order two bits) + */ +#define NO_WARNING 0x00 /* no warning */ +#define PLUS_SEC 0x40 /* add a second (61 seconds) */ +#define MINUS_SEC 0x80 /* minus a second (59 seconds) */ +#define ALARM 0xc0 /* alarm condition (clock unsynchronized) */ + +/* + * Clock Status Bits that Encode Version + */ +#define NTPVERSION_1 0x08 +#define VERSIONMASK 0x38 +#define LEAPMASK 0xc0 +#define MODEMASK 0x07 + +/* + * Code values + */ +#define MODE_UNSPEC 0 /* unspecified */ +#define MODE_SYM_ACT 1 /* symmetric active */ +#define MODE_SYM_PAS 2 /* symmetric passive */ +#define MODE_CLIENT 3 /* client */ +#define MODE_SERVER 4 /* server */ +#define MODE_BROADCAST 5 /* broadcast */ +#define MODE_RES1 6 /* reserved */ +#define MODE_RES2 7 /* reserved */ + +/* + * Stratum Definitions + */ +#define UNSPECIFIED 0 +#define PRIM_REF 1 /* radio clock */ +#define INFO_QUERY 62 /* **** THIS implementation dependent **** */ +#define INFO_REPLY 63 /* **** THIS implementation dependent **** */ diff --git a/freebsd/contrib/tcpdump/oakley.h b/freebsd/contrib/tcpdump/oakley.h new file mode 100644 index 00000000..ad328171 --- /dev/null +++ b/freebsd/contrib/tcpdump/oakley.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 1995, 1996, 1997, and 1998 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. + */ +/* YIPS @(#)$Id: oakley.h,v 1.4 2002-12-11 07:13:56 guy Exp $ */ + +/* refer to RFC 2409 */ + +#if !defined(_ISAKMP_OAKLEY_H_) +#define _ISAKMP_OAKLEY_H_ + +/* Attribute Classes */ +#define OAKLEY_ATTR_ENC_ALG 1 /* B */ +#define OAKLEY_ATTR_ENC_ALG_DES 1 +#define OAKLEY_ATTR_ENC_ALG_IDEA 2 +#define OAKLEY_ATTR_ENC_ALG_BL 3 +#define OAKLEY_ATTR_ENC_ALG_RC5 4 +#define OAKLEY_ATTR_ENC_ALG_3DES 5 +#define OAKLEY_ATTR_ENC_ALG_CAST 6 +#define OAKLEY_ATTR_HASH_ALG 2 /* B */ +#define OAKLEY_ATTR_HASH_ALG_MD5 1 +#define OAKLEY_ATTR_HASH_ALG_SHA 2 +#define OAKLEY_ATTR_HASH_ALG_TIGER 3 +#define OAKLEY_ATTR_AUTH_METHOD 3 /* B */ +#define OAKLEY_ATTR_AUTH_METHOD_PSKEY 1 +#define OAKLEY_ATTR_AUTH_METHOD_DSS 2 +#define OAKLEY_ATTR_AUTH_METHOD_RSA 3 +#define OAKLEY_ATTR_AUTH_METHOD_RSAENC 4 +#define OAKLEY_ATTR_AUTH_METHOD_RSAREV 5 +#define OAKLEY_ATTR_GRP_DESC 4 /* B */ +#define OAKLEY_ATTR_GRP_DESC_MODP768 1 +#define OAKLEY_ATTR_GRP_DESC_MODP1024 2 +#define OAKLEY_ATTR_GRP_DESC_EC2N155 3 +#define OAKLEY_ATTR_GRP_DESC_EC2N185 4 +#define OAKLEY_ATTR_GRP_TYPE 5 /* B */ +#define OAKLEY_ATTR_GRP_TYPE_MODP 1 +#define OAKLEY_ATTR_GRP_TYPE_ECP 2 +#define OAKLEY_ATTR_GRP_TYPE_EC2N 3 +#define OAKLEY_ATTR_GRP_PI 6 /* V */ +#define OAKLEY_ATTR_GRP_GEN_ONE 7 /* V */ +#define OAKLEY_ATTR_GRP_GEN_TWO 8 /* V */ +#define OAKLEY_ATTR_GRP_CURVE_A 9 /* V */ +#define OAKLEY_ATTR_GRP_CURVE_B 10 /* V */ +#define OAKLEY_ATTR_SA_LTYPE 11 /* B */ +#define OAKLEY_ATTR_SA_LTYPE_DEFAULT 1 +#define OAKLEY_ATTR_SA_LTYPE_SEC 1 +#define OAKLEY_ATTR_SA_LTYPE_KB 2 +#define OAKLEY_ATTR_SA_LDUR 12 /* V */ +#define OAKLEY_ATTR_SA_LDUR_DEFAULT 28800 /* 8 hours */ +#define OAKLEY_ATTR_PRF 13 /* B */ +#define OAKLEY_ATTR_KEY_LEN 14 /* B */ +#define OAKLEY_ATTR_FIELD_SIZE 15 /* B */ +#define OAKLEY_ATTR_GRP_ORDER 16 /* V */ + +#define OAKLEY_ID_IPV4_ADDR 0 +#define OAKLEY_ID_IPV4_ADDR_SUBNET 1 +#define OAKLEY_ID_IPV6_ADDR 2 +#define OAKLEY_ID_IPV6_ADDR_SUBNET 3 + +/* Additional Exchange Type */ +#define ISAKMP_ETYPE_QUICK 32 +#define ISAKMP_ETYPE_NEWGRP 33 + +/* The use for checking proposal payload. This is not exchange type. */ +#define OAKLEY_MAIN_MODE 0 +#define OAKLEY_QUICK_MODE 1 + +#define OAKLEY_PRIME_MODP768 "\ + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 \ + 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD \ + EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 \ + E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF" + +#define OAKLEY_PRIME_MODP1024 "\ + FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 \ + 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD \ + EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 \ + E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \ + EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \ + FFFFFFFF FFFFFFFF" + +#define DEFAULTSECRETSIZE ( 128 / 8 ) /* 128 bits */ +#define DEFAULTNONCESIZE ( 128 / 8 ) /* 128 bits */ + +#define MAXPADLWORD 20 + +#if 0 +/* isakmp sa structure */ +struct oakley_sa { + u_int8_t proto_id; /* OAKLEY */ + vchar_t *spi; /* spi */ + u_int8_t dhgrp; /* DH; group */ + u_int8_t auth_t; /* method of authentication */ + u_int8_t prf_t; /* type of prf */ + u_int8_t hash_t; /* type of hash */ + u_int8_t enc_t; /* type of cipher */ + u_int8_t life_t; /* type of duration of lifetime */ + u_int32_t ldur; /* life duration */ +}; +#endif + +#endif /* !defined(_ISAKMP_OAKLEY_H_) */ diff --git a/freebsd/contrib/tcpdump/ospf.h b/freebsd/contrib/tcpdump/ospf.h new file mode 100644 index 00000000..b86458ba --- /dev/null +++ b/freebsd/contrib/tcpdump/ospf.h @@ -0,0 +1,328 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/ospf.h,v 1.23 2007-10-08 07:53:21 hannes Exp $ (LBL) */ +/* + * Copyright (c) 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. + * + * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) + */ +#define OSPF_TYPE_UMD 0 /* UMd's special monitoring packets */ +#define OSPF_TYPE_HELLO 1 /* Hello */ +#define OSPF_TYPE_DD 2 /* Database Description */ +#define OSPF_TYPE_LS_REQ 3 /* Link State Request */ +#define OSPF_TYPE_LS_UPDATE 4 /* Link State Update */ +#define OSPF_TYPE_LS_ACK 5 /* Link State Ack */ + +/* Options field + * + * +------------------------------------+ + * | DN | O | DC | L | N/P | MC | E | T | + * +------------------------------------+ + * + */ + +#define OSPF_OPTION_T 0x01 /* T bit: TOS support */ +#define OSPF_OPTION_E 0x02 /* E bit: External routes advertised */ +#define OSPF_OPTION_MC 0x04 /* MC bit: Multicast capable */ +#define OSPF_OPTION_NP 0x08 /* N/P bit: NSSA capable */ +#define OSPF_OPTION_EA 0x10 /* EA bit: External Attribute capable */ +#define OSPF_OPTION_L 0x10 /* L bit: Packet contains LLS data block */ +#define OSPF_OPTION_DC 0x20 /* DC bit: Demand circuit capable */ +#define OSPF_OPTION_O 0x40 /* O bit: Opaque LSA capable */ +#define OSPF_OPTION_DN 0x80 /* DN bit: Up/Down Bit capable - draft-ietf-ospf-2547-dnbit-04 */ + +/* ospf_authtype */ +#define OSPF_AUTH_NONE 0 /* No auth-data */ +#define OSPF_AUTH_SIMPLE 1 /* Simple password */ +#define OSPF_AUTH_SIMPLE_LEN 8 /* max length of simple authentication */ +#define OSPF_AUTH_MD5 2 /* MD5 authentication */ +#define OSPF_AUTH_MD5_LEN 16 /* length of MD5 authentication */ + +/* db_flags */ +#define OSPF_DB_INIT 0x04 +#define OSPF_DB_MORE 0x02 +#define OSPF_DB_MASTER 0x01 +#define OSPF_DB_RESYNC 0x08 /* RFC4811 */ + +/* ls_type */ +#define LS_TYPE_ROUTER 1 /* router link */ +#define LS_TYPE_NETWORK 2 /* network link */ +#define LS_TYPE_SUM_IP 3 /* summary link */ +#define LS_TYPE_SUM_ABR 4 /* summary area link */ +#define LS_TYPE_ASE 5 /* ASE */ +#define LS_TYPE_GROUP 6 /* Group membership (multicast */ + /* extensions 23 July 1991) */ +#define LS_TYPE_NSSA 7 /* rfc3101 - Not so Stubby Areas */ +#define LS_TYPE_OPAQUE_LL 9 /* rfc2370 - Opaque Link Local */ +#define LS_TYPE_OPAQUE_AL 10 /* rfc2370 - Opaque Link Local */ +#define LS_TYPE_OPAQUE_DW 11 /* rfc2370 - Opaque Domain Wide */ + +#define LS_OPAQUE_TYPE_TE 1 /* rfc3630 */ +#define LS_OPAQUE_TYPE_GRACE 3 /* rfc3623 */ +#define LS_OPAQUE_TYPE_RI 4 /* draft-ietf-ospf-cap-03 */ + +#define LS_OPAQUE_TE_TLV_ROUTER 1 /* rfc3630 */ +#define LS_OPAQUE_TE_TLV_LINK 2 /* rfc3630 */ + +#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE 1 /* rfc3630 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID 2 /* rfc3630 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP 3 /* rfc3630 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP 4 /* rfc3630 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC 5 /* rfc3630 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW 6 /* rfc3630 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW 7 /* rfc3630 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW 8 /* rfc3630 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP 9 /* rfc3630 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID 11 /* rfc4203 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE 14 /* rfc4203 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR 15 /* rfc4203 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP 16 /* rfc4203 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS 17 /* rfc4124 */ + +#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP 1 /* rfc3630 */ +#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA 2 /* rfc3630 */ + +#define LS_OPAQUE_GRACE_TLV_PERIOD 1 /* rfc3623 */ +#define LS_OPAQUE_GRACE_TLV_REASON 2 /* rfc3623 */ +#define LS_OPAQUE_GRACE_TLV_INT_ADDRESS 3 /* rfc3623 */ + +#define LS_OPAQUE_GRACE_TLV_REASON_UNKNOWN 0 /* rfc3623 */ +#define LS_OPAQUE_GRACE_TLV_REASON_SW_RESTART 1 /* rfc3623 */ +#define LS_OPAQUE_GRACE_TLV_REASON_SW_UPGRADE 2 /* rfc3623 */ +#define LS_OPAQUE_GRACE_TLV_REASON_CP_SWITCH 3 /* rfc3623 */ + +#define LS_OPAQUE_RI_TLV_CAP 1 /* draft-ietf-ospf-cap-03 */ + + +/* rla_link.link_type */ +#define RLA_TYPE_ROUTER 1 /* point-to-point to another router */ +#define RLA_TYPE_TRANSIT 2 /* connection to transit network */ +#define RLA_TYPE_STUB 3 /* connection to stub network */ +#define RLA_TYPE_VIRTUAL 4 /* virtual link */ + +/* rla_flags */ +#define RLA_FLAG_B 0x01 +#define RLA_FLAG_E 0x02 +#define RLA_FLAG_W1 0x04 +#define RLA_FLAG_W2 0x08 + +/* sla_tosmetric breakdown */ +#define SLA_MASK_TOS 0x7f000000 +#define SLA_MASK_METRIC 0x00ffffff +#define SLA_SHIFT_TOS 24 + +/* asla_tosmetric breakdown */ +#define ASLA_FLAG_EXTERNAL 0x80000000 +#define ASLA_MASK_TOS 0x7f000000 +#define ASLA_SHIFT_TOS 24 +#define ASLA_MASK_METRIC 0x00ffffff + +/* multicast vertex type */ +#define MCLA_VERTEX_ROUTER 1 +#define MCLA_VERTEX_NETWORK 2 + +/* Link-Local-Signaling */ +#define OSPF_LLS_EO 1 /* RFC4811, RFC4812 */ +#define OSPF_LLS_MD5 2 /* RFC4813 */ + +#define OSPF_LLS_EO_LR 0x00000001 /* RFC4811 */ +#define OSPF_LLS_EO_RS 0x00000002 /* RFC4812 */ + +/* + * TOS metric struct (will be 0 or more in router links update) + */ +struct tos_metric { + u_int8_t tos_type; + u_int8_t reserved; + u_int8_t tos_metric[2]; +}; +struct tos_link { + u_int8_t link_type; + u_int8_t link_tos_count; + u_int8_t tos_metric[2]; +}; +union un_tos { + struct tos_link link; + struct tos_metric metrics; +}; + +/* link state advertisement header */ +struct lsa_hdr { + u_int16_t ls_age; + u_int8_t ls_options; + u_int8_t ls_type; + union { + struct in_addr lsa_id; + struct { /* opaque LSAs change the LSA-ID field */ + u_int8_t opaque_type; + u_int8_t opaque_id[3]; + } opaque_field; + } un_lsa_id; + struct in_addr ls_router; + u_int32_t ls_seq; + u_int16_t ls_chksum; + u_int16_t ls_length; +}; + +/* link state advertisement */ +struct lsa { + struct lsa_hdr ls_hdr; + + /* Link state types */ + union { + /* Router links advertisements */ + struct { + u_int8_t rla_flags; + u_int8_t rla_zero[1]; + u_int16_t rla_count; + struct rlalink { + struct in_addr link_id; + struct in_addr link_data; + union un_tos un_tos; + } rla_link[1]; /* may repeat */ + } un_rla; + + /* Network links advertisements */ + struct { + struct in_addr nla_mask; + struct in_addr nla_router[1]; /* may repeat */ + } un_nla; + + /* Summary links advertisements */ + struct { + struct in_addr sla_mask; + u_int32_t sla_tosmetric[1]; /* may repeat */ + } un_sla; + + /* AS external links advertisements */ + struct { + struct in_addr asla_mask; + struct aslametric { + u_int32_t asla_tosmetric; + struct in_addr asla_forward; + struct in_addr asla_tag; + } asla_metric[1]; /* may repeat */ + } un_asla; + + /* Multicast group membership */ + struct mcla { + u_int32_t mcla_vtype; + struct in_addr mcla_vid; + } un_mcla[1]; + + /* Opaque TE LSA */ + struct { + u_int16_t type; + u_int16_t length; + u_int8_t data[1]; /* may repeat */ + } un_te_lsa_tlv; + + /* Opaque Grace LSA */ + struct { + u_int16_t type; + u_int16_t length; + u_int8_t data[1]; /* may repeat */ + } un_grace_tlv; + + /* Opaque Router information LSA */ + struct { + u_int16_t type; + u_int16_t length; + u_int8_t data[1]; /* may repeat */ + } un_ri_tlv; + + /* Unknown LSA */ + struct unknown { + u_int8_t data[1]; /* may repeat */ + } un_unknown[1]; + + } lsa_un; +}; + +#define OSPF_AUTH_SIZE 8 + +/* + * the main header + */ +struct ospfhdr { + u_int8_t ospf_version; + u_int8_t ospf_type; + u_int16_t ospf_len; + struct in_addr ospf_routerid; + struct in_addr ospf_areaid; + u_int16_t ospf_chksum; + u_int16_t ospf_authtype; + u_int8_t ospf_authdata[OSPF_AUTH_SIZE]; + union { + + /* Hello packet */ + struct { + struct in_addr hello_mask; + u_int16_t hello_helloint; + u_int8_t hello_options; + u_int8_t hello_priority; + u_int32_t hello_deadint; + struct in_addr hello_dr; + struct in_addr hello_bdr; + struct in_addr hello_neighbor[1]; /* may repeat */ + } un_hello; + + /* Database Description packet */ + struct { + u_int16_t db_ifmtu; + u_int8_t db_options; + u_int8_t db_flags; + u_int32_t db_seq; + struct lsa_hdr db_lshdr[1]; /* may repeat */ + } un_db; + + /* Link State Request */ + struct lsr { + u_int8_t ls_type[4]; + union { + struct in_addr ls_stateid; + struct { /* opaque LSAs change the LSA-ID field */ + u_int8_t opaque_type; + u_int8_t opaque_id[3]; + } opaque_field; + } un_ls_stateid; + struct in_addr ls_router; + } un_lsr[1]; /* may repeat */ + + /* Link State Update */ + struct { + u_int32_t lsu_count; + struct lsa lsu_lsa[1]; /* may repeat */ + } un_lsu; + + /* Link State Acknowledgement */ + struct { + struct lsa_hdr lsa_lshdr[1]; /* may repeat */ + } un_lsa ; + } ospf_un ; +}; + +#define ospf_hello ospf_un.un_hello +#define ospf_db ospf_un.un_db +#define ospf_lsr ospf_un.un_lsr +#define ospf_lsu ospf_un.un_lsu +#define ospf_lsa ospf_un.un_lsa + +/* Functions shared by ospf and ospf6 */ +extern int ospf_print_te_lsa(const u_int8_t *, u_int); +extern int ospf_print_grace_lsa(const u_int8_t *, u_int); diff --git a/freebsd/contrib/tcpdump/ospf6.h b/freebsd/contrib/tcpdump/ospf6.h new file mode 100644 index 00000000..e2eabee1 --- /dev/null +++ b/freebsd/contrib/tcpdump/ospf6.h @@ -0,0 +1,265 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/ospf6.h,v 1.7 2006-09-05 15:50:26 hannes Exp $ (LBL) */ +/* + * Copyright (c) 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. + * + * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) + */ +#define OSPF_TYPE_HELLO 1 /* Hello */ +#define OSPF_TYPE_DD 2 /* Database Description */ +#define OSPF_TYPE_LS_REQ 3 /* Link State Request */ +#define OSPF_TYPE_LS_UPDATE 4 /* Link State Update */ +#define OSPF_TYPE_LS_ACK 5 /* Link State Ack */ + +/* Options *_options */ +#define OSPF6_OPTION_V6 0x01 /* V6 bit: A bit for peeping tom */ +#define OSPF6_OPTION_E 0x02 /* E bit: External routes advertised */ +#define OSPF6_OPTION_MC 0x04 /* MC bit: Multicast capable */ +#define OSPF6_OPTION_N 0x08 /* N bit: For type-7 LSA */ +#define OSPF6_OPTION_R 0x10 /* R bit: Router bit */ +#define OSPF6_OPTION_DC 0x20 /* DC bit: Demand circuits */ + + +/* db_flags */ +#define OSPF6_DB_INIT 0x04 /* */ +#define OSPF6_DB_MORE 0x02 +#define OSPF6_DB_MASTER 0x01 + +/* ls_type */ +#define LS_TYPE_ROUTER 1 /* router link */ +#define LS_TYPE_NETWORK 2 /* network link */ +#define LS_TYPE_INTER_AP 3 /* Inter-Area-Prefix */ +#define LS_TYPE_INTER_AR 4 /* Inter-Area-Router */ +#define LS_TYPE_ASE 5 /* ASE */ +#define LS_TYPE_GROUP 6 /* Group membership */ +#define LS_TYPE_NSSA 7 /* NSSA */ +#define LS_TYPE_LINK 8 /* Link LSA */ +#define LS_TYPE_INTRA_AP 9 /* Intra-Area-Prefix */ +#define LS_TYPE_INTRA_ATE 10 /* Intra-Area-TE */ +#define LS_TYPE_GRACE 11 /* Grace LSA */ +#define LS_TYPE_MASK 0x1fff + +#define LS_SCOPE_LINKLOCAL 0x0000 +#define LS_SCOPE_AREA 0x2000 +#define LS_SCOPE_AS 0x4000 +#define LS_SCOPE_MASK 0x6000 +#define LS_SCOPE_U 0x8000 + +/* rla_link.link_type */ +#define RLA_TYPE_ROUTER 1 /* point-to-point to another router */ +#define RLA_TYPE_TRANSIT 2 /* connection to transit network */ +#define RLA_TYPE_VIRTUAL 4 /* virtual link */ + +/* rla_flags */ +#define RLA_FLAG_B 0x01 +#define RLA_FLAG_E 0x02 +#define RLA_FLAG_V 0x04 +#define RLA_FLAG_W 0x08 +#define RLA_FLAG_N 0x10 + +/* lsa_prefix options */ +#define LSA_PREFIX_OPT_NU 0x01 +#define LSA_PREFIX_OPT_LA 0x02 +#define LSA_PREFIX_OPT_MC 0x04 +#define LSA_PREFIX_OPT_P 0x08 +#define LSA_PREFIX_OPT_DN 0x10 + +/* sla_tosmetric breakdown */ +#define SLA_MASK_TOS 0x7f000000 +#define SLA_MASK_METRIC 0x00ffffff +#define SLA_SHIFT_TOS 24 + +/* asla_metric */ +#define ASLA_FLAG_FWDADDR 0x02000000 +#define ASLA_FLAG_ROUTETAG 0x01000000 +#define ASLA_MASK_METRIC 0x00ffffff + +typedef u_int32_t rtrid_t; + +/* link state advertisement header */ +struct lsa6_hdr { + u_int16_t ls_age; + u_int16_t ls_type; + rtrid_t ls_stateid; + rtrid_t ls_router; + u_int32_t ls_seq; + u_int16_t ls_chksum; + u_int16_t ls_length; +}; + +struct lsa6_prefix { + u_int8_t lsa_p_len; + u_int8_t lsa_p_opt; + u_int16_t lsa_p_metric; + u_int8_t lsa_p_prefix[4]; +}; + +/* link state advertisement */ +struct lsa6 { + struct lsa6_hdr ls_hdr; + + /* Link state types */ + union { + /* Router links advertisements */ + struct { + union { + u_int8_t flg; + u_int32_t opt; + } rla_flgandopt; +#define rla_flags rla_flgandopt.flg +#define rla_options rla_flgandopt.opt + struct rlalink6 { + u_int8_t link_type; + u_int8_t link_zero[1]; + u_int16_t link_metric; + u_int32_t link_ifid; + u_int32_t link_nifid; + rtrid_t link_nrtid; + } rla_link[1]; /* may repeat */ + } un_rla; + + /* Network links advertisements */ + struct { + u_int32_t nla_options; + rtrid_t nla_router[1]; /* may repeat */ + } un_nla; + + /* Inter Area Prefix LSA */ + struct { + u_int32_t inter_ap_metric; + struct lsa6_prefix inter_ap_prefix[1]; + } un_inter_ap; + + /* AS external links advertisements */ + struct { + u_int32_t asla_metric; + struct lsa6_prefix asla_prefix[1]; + /* some optional fields follow */ + } un_asla; + +#if 0 + /* Summary links advertisements */ + struct { + struct in_addr sla_mask; + u_int32_t sla_tosmetric[1]; /* may repeat */ + } un_sla; + + /* Multicast group membership */ + struct mcla { + u_int32_t mcla_vtype; + struct in_addr mcla_vid; + } un_mcla[1]; +#endif + + /* Type 7 LSA */ + + /* Link LSA */ + struct llsa { + union { + u_int8_t pri; + u_int32_t opt; + } llsa_priandopt; +#define llsa_priority llsa_priandopt.pri +#define llsa_options llsa_priandopt.opt + struct in6_addr llsa_lladdr; + u_int32_t llsa_nprefix; + struct lsa6_prefix llsa_prefix[1]; + } un_llsa; + + /* Intra-Area-Prefix */ + struct { + u_int16_t intra_ap_nprefix; + u_int16_t intra_ap_lstype; + rtrid_t intra_ap_lsid; + rtrid_t intra_ap_rtid; + struct lsa6_prefix intra_ap_prefix[1]; + } un_intra_ap; + } lsa_un; +}; + + +#define OSPF_AUTH_SIZE 8 + +/* + * the main header + */ +struct ospf6hdr { + u_int8_t ospf6_version; + u_int8_t ospf6_type; + u_int16_t ospf6_len; + rtrid_t ospf6_routerid; + rtrid_t ospf6_areaid; + u_int16_t ospf6_chksum; + u_int8_t ospf6_instanceid; + u_int8_t ospf6_rsvd; + union { + + /* Hello packet */ + struct { + u_int32_t hello_ifid; + union { + u_int8_t pri; + u_int32_t opt; + } hello_priandopt; +#define hello_priority hello_priandopt.pri +#define hello_options hello_priandopt.opt + u_int16_t hello_helloint; + u_int16_t hello_deadint; + rtrid_t hello_dr; + rtrid_t hello_bdr; + rtrid_t hello_neighbor[1]; /* may repeat */ + } un_hello; + + /* Database Description packet */ + struct { + u_int32_t db_options; + u_int16_t db_mtu; + u_int8_t db_mbz; + u_int8_t db_flags; + u_int32_t db_seq; + struct lsa6_hdr db_lshdr[1]; /* may repeat */ + } un_db; + + /* Link State Request */ + struct lsr6 { + u_int16_t ls_mbz; + u_int16_t ls_type; + rtrid_t ls_stateid; + rtrid_t ls_router; + } un_lsr[1]; /* may repeat */ + + /* Link State Update */ + struct { + u_int32_t lsu_count; + struct lsa6 lsu_lsa[1]; /* may repeat */ + } un_lsu; + + /* Link State Acknowledgement */ + struct { + struct lsa6_hdr lsa_lshdr[1]; /* may repeat */ + } un_lsa ; + } ospf6_un ; +}; + +#define ospf6_hello ospf6_un.un_hello +#define ospf6_db ospf6_un.un_db +#define ospf6_lsr ospf6_un.un_lsr +#define ospf6_lsu ospf6_un.un_lsu +#define ospf6_lsa ospf6_un.un_lsa + diff --git a/freebsd/contrib/tcpdump/oui.c b/freebsd/contrib/tcpdump/oui.c new file mode 100644 index 00000000..07ba0943 --- /dev/null +++ b/freebsd/contrib/tcpdump/oui.c @@ -0,0 +1,101 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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/oui.c,v 1.9 2008-01-09 09:40:47 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> +#include "interface.h" +#include "oui.h" + +/* FIXME complete OUI list using a script */ + +const struct tok oui_values[] = { + { OUI_ENCAP_ETHER, "Ethernet" }, + { OUI_CISCO, "Cisco" }, + { OUI_NORTEL, "Nortel Networks SONMP" }, + { OUI_CISCO_90, "Cisco bridged" }, + { OUI_RFC2684, "Ethernet bridged" }, + { OUI_ATM_FORUM, "ATM Forum" }, + { OUI_CABLE_BPDU, "DOCSIS Spanning Tree" }, + { OUI_APPLETALK, "Appletalk" }, + { OUI_JUNIPER, "Juniper" }, + { OUI_HP, "Hewlett-Packard" }, + { OUI_IEEE_8021_PRIVATE, "IEEE 802.1 Private"}, + { OUI_IEEE_8023_PRIVATE, "IEEE 802.3 Private"}, + { OUI_TIA, "ANSI/TIA"}, + { OUI_DCBX, "DCBX"}, + { 0, NULL } +}; + +/* + * SMI Network Management Private Enterprise Codes for organizations. + * + * XXX - these also appear in FreeRadius dictionary files, with items such + * as + * + * VENDOR Cisco 9 + * + * List taken from Ethereal's epan/sminmpec.c. + */ +const struct tok smi_values[] = { + { SMI_IETF, "IETF (reserved)"}, + { SMI_ACC, "ACC"}, + { SMI_CISCO, "Cisco"}, + { SMI_HEWLETT_PACKARD, "Hewlett Packard"}, + { SMI_SUN_MICROSYSTEMS, "Sun Microsystems"}, + { SMI_MERIT, "Merit"}, + { SMI_SHIVA, "Shiva"}, + { SMI_ERICSSON, "Ericsson AB"}, + { SMI_CISCO_VPN5000, "Cisco VPN 5000"}, + { SMI_LIVINGSTON, "Livingston"}, + { SMI_MICROSOFT, "Microsoft"}, + { SMI_3COM, "3Com"}, + { SMI_ASCEND, "Ascend"}, + { SMI_BAY, "Bay Networks"}, + { SMI_FOUNDRY, "Foundry"}, + { SMI_VERSANET, "Versanet"}, + { SMI_REDBACK, "Redback"}, + { SMI_JUNIPER, "Juniper Networks"}, + { SMI_APTIS, "Aptis"}, + { SMI_CISCO_VPN3000, "Cisco VPN 3000"}, + { SMI_COSINE, "CoSine Communications"}, + { SMI_NETSCREEN, "Netscreen"}, + { SMI_SHASTA, "Shasta"}, + { SMI_NOMADIX, "Nomadix"}, + { SMI_SIEMENS, "Siemens"}, + { SMI_CABLELABS, "CableLabs"}, + { SMI_UNISPHERE, "Unisphere Networks"}, + { SMI_CISCO_BBSM, "Cisco BBSM"}, + { SMI_THE3GPP2, "3rd Generation Partnership Project 2 (3GPP2)"}, + { SMI_IP_UNPLUGGED, "ipUnplugged"}, + { SMI_ISSANNI, "Issanni Communications"}, + { SMI_QUINTUM, "Quintum"}, + { SMI_INTERLINK, "Interlink"}, + { SMI_COLUBRIS, "Colubris"}, + { SMI_COLUMBIA_UNIVERSITY, "Columbia University"}, + { SMI_THE3GPP, "3GPP"}, + { SMI_GEMTEK_SYSTEMS, "Gemtek-Systems"}, + { SMI_WIFI_ALLIANCE, "Wi-Fi Alliance"}, + { 0, NULL} +}; diff --git a/freebsd/contrib/tcpdump/oui.h b/freebsd/contrib/tcpdump/oui.h new file mode 100644 index 00000000..d39cb6ca --- /dev/null +++ b/freebsd/contrib/tcpdump/oui.h @@ -0,0 +1,82 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/oui.h,v 1.8 2008-01-09 09:40:47 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 oui_values[]; +extern const struct tok smi_values[]; + +#define OUI_ENCAP_ETHER 0x000000 /* encapsulated Ethernet */ +#define OUI_CISCO 0x00000c /* Cisco protocols */ +#define OUI_NORTEL 0x000081 /* Nortel SONMP */ +#define OUI_CISCO_90 0x0000f8 /* Cisco bridging */ +#define OUI_RFC2684 0x0080c2 /* RFC 2427/2684 bridged Ethernet */ +#define OUI_ATM_FORUM 0x00A03E /* ATM Forum */ +#define OUI_CABLE_BPDU 0x00E02F /* DOCSIS spanning tree BPDU */ +#define OUI_APPLETALK 0x080007 /* Appletalk */ +#define OUI_JUNIPER 0x009069 /* Juniper */ +#define OUI_HP 0x080009 /* Hewlett-Packard */ +#define OUI_IEEE_8021_PRIVATE 0x0080c2 /* IEEE 802.1 Organisation Specific - Annex F */ +#define OUI_IEEE_8023_PRIVATE 0x00120f /* IEEE 802.3 Organisation Specific - Annex G */ +#define OUI_TIA 0x0012bb /* TIA - Telecommunications Industry Association - ANSI/TIA-1057- 2006 */ +#define OUI_DCBX 0x001B21 /* DCBX */ + +/* + * These are SMI Network Management Private Enterprise Codes for + * organizations; see + * + * http://www.iana.org/assignments/enterprise-numbers + * + * for a list. + * + * List taken from Ethereal's epan/sminmpec.h. + */ +#define SMI_IETF 0 /* reserved - used by the IETF in L2TP? */ +#define SMI_ACC 5 +#define SMI_CISCO 9 +#define SMI_HEWLETT_PACKARD 11 +#define SMI_SUN_MICROSYSTEMS 42 +#define SMI_MERIT 61 +#define SMI_SHIVA 166 +#define SMI_ERICSSON 193 +#define SMI_CISCO_VPN5000 255 +#define SMI_LIVINGSTON 307 +#define SMI_MICROSOFT 311 +#define SMI_3COM 429 +#define SMI_ASCEND 529 +#define SMI_BAY 1584 +#define SMI_FOUNDRY 1991 +#define SMI_VERSANET 2180 +#define SMI_REDBACK 2352 +#define SMI_JUNIPER 2636 +#define SMI_APTIS 2637 +#define SMI_CISCO_VPN3000 3076 +#define SMI_COSINE 3085 +#define SMI_SHASTA 3199 +#define SMI_NETSCREEN 3224 +#define SMI_NOMADIX 3309 +#define SMI_SIEMENS 4329 +#define SMI_CABLELABS 4491 +#define SMI_UNISPHERE 4874 +#define SMI_CISCO_BBSM 5263 +#define SMI_THE3GPP2 5535 +#define SMI_IP_UNPLUGGED 5925 +#define SMI_ISSANNI 5948 +#define SMI_QUINTUM 6618 +#define SMI_INTERLINK 6728 +#define SMI_COLUBRIS 8744 +#define SMI_COLUMBIA_UNIVERSITY 11862 +#define SMI_THE3GPP 10415 +#define SMI_GEMTEK_SYSTEMS 10529 +#define SMI_WIFI_ALLIANCE 14122 diff --git a/freebsd/contrib/tcpdump/parsenfsfh.c b/freebsd/contrib/tcpdump/parsenfsfh.c new file mode 100644 index 00000000..a6025e6b --- /dev/null +++ b/freebsd/contrib/tcpdump/parsenfsfh.c @@ -0,0 +1,488 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + */ + +/* + * parsenfsfh.c - portable parser for NFS file handles + * uses all sorts of heuristics + * + * Jeffrey C. Mogul + * Digital Equipment Corporation + * Western Research Laboratory + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/parsenfsfh.c,v 1.29 2006-06-13 22:21:38 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "nfsfh.h" + +/* + * This routine attempts to parse a file handle (in network byte order), + * using heuristics to guess what kind of format it is in. See the + * file "fhandle_layouts" for a detailed description of the various + * patterns we know about. + * + * The file handle is parsed into our internal representation of a + * file-system id, and an internal representation of an inode-number. + */ + +#define FHT_UNKNOWN 0 +#define FHT_AUSPEX 1 +#define FHT_DECOSF 2 +#define FHT_IRIX4 3 +#define FHT_IRIX5 4 +#define FHT_SUNOS3 5 +#define FHT_SUNOS4 6 +#define FHT_ULTRIX 7 +#define FHT_VMSUCX 8 +#define FHT_SUNOS5 9 +#define FHT_AIX32 10 +#define FHT_HPUX9 11 +#define FHT_BSD44 12 + +#ifdef ultrix +/* Nasty hack to keep the Ultrix C compiler from emitting bogus warnings */ +#define XFF(x) ((u_int32_t)(x)) +#else +#define XFF(x) (x) +#endif + +#define make_uint32(msb,b,c,lsb)\ + (XFF(lsb) + (XFF(c)<<8) + (XFF(b)<<16) + (XFF(msb)<<24)) + +#define make_uint24(msb,b, lsb)\ + (XFF(lsb) + (XFF(b)<<8) + (XFF(msb)<<16)) + +#define make_uint16(msb,lsb)\ + (XFF(lsb) + (XFF(msb)<<8)) + +#ifdef __alpha + /* or other 64-bit systems */ +#define make_uint48(msb,b,c,d,e,lsb)\ + ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24) + ((b)<<32) + ((msb)<<40)) +#else + /* on 32-bit systems ignore high-order bits */ +#define make_uint48(msb,b,c,d,e,lsb)\ + ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24)) +#endif + +static int is_UCX(const unsigned char *); + +void +Parse_fh(fh, len, fsidp, inop, osnamep, fsnamep, ourself) +register const unsigned char *fh; +int len _U_; +my_fsid *fsidp; +ino_t *inop; +const char **osnamep; /* if non-NULL, return OS name here */ +const char **fsnamep; /* if non-NULL, return server fs name here (for VMS) */ +int ourself; /* true if file handle was generated on this host */ +{ + register const unsigned char *fhp = fh; + u_int32_t temp; + int fhtype = FHT_UNKNOWN; + int i; + + if (ourself) { + /* File handle generated on this host, no need for guessing */ +#if defined(IRIX40) + fhtype = FHT_IRIX4; +#endif +#if defined(IRIX50) + fhtype = FHT_IRIX5; +#endif +#if defined(IRIX51) + fhtype = FHT_IRIX5; +#endif +#if defined(SUNOS4) + fhtype = FHT_SUNOS4; +#endif +#if defined(SUNOS5) + fhtype = FHT_SUNOS5; +#endif +#if defined(ultrix) + fhtype = FHT_ULTRIX; +#endif +#if defined(__osf__) + fhtype = FHT_DECOSF; +#endif +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) \ + || defined(__OpenBSD__) + fhtype = FHT_BSD44; +#endif + } + /* + * This is basically a big decision tree + */ + else if ((fhp[0] == 0) && (fhp[1] == 0)) { + /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */ + /* probably rules out HP-UX, AIX unless they allow major=0 */ + if ((fhp[2] == 0) && (fhp[3] == 0)) { + /* bytes[2,3] == (0,0); must be Auspex */ + /* XXX or could be Ultrix+MASSBUS "hp" disk? */ + fhtype = FHT_AUSPEX; + } + else { + /* + * bytes[2,3] != (0,0); rules out Auspex, could be + * DECOSF, SUNOS4, or IRIX4 + */ + if ((fhp[4] != 0) && (fhp[5] == 0) && + (fhp[8] == 12) && (fhp[9] == 0)) { + /* seems to be DECOSF, with minor == 0 */ + fhtype = FHT_DECOSF; + } + else { + /* could be SUNOS4 or IRIX4 */ + /* XXX the test of fhp[5] == 8 could be wrong */ + if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) && + (fhp[7] == 0)) { + /* looks like a length, not a file system typecode */ + fhtype = FHT_IRIX4; + } + else { + /* by elimination */ + fhtype = FHT_SUNOS4; + } + } + } + } + else { + /* + * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4 + * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5 + * could be AIX, HP-UX + */ + if ((fhp[2] == 0) && (fhp[3] == 0)) { + /* + * bytes[2,3] == (0,0); rules out OSF, probably not UCX + * (unless the exported device name is just one letter!), + * could be Ultrix, IRIX5, AIX, or SUNOS5 + * might be HP-UX (depends on their values for minor devs) + */ + if ((fhp[6] == 0) && (fhp[7] == 0)) { + fhtype = FHT_BSD44; + } + /*XXX we probably only need to test of these two bytes */ + else if ((fhp[21] == 0) && (fhp[23] == 0)) { + fhtype = FHT_ULTRIX; + } + else { + /* Could be SUNOS5/IRIX5, maybe AIX */ + /* XXX no obvious difference between SUNOS5 and IRIX5 */ + if (fhp[9] == 10) + fhtype = FHT_SUNOS5; + /* XXX what about AIX? */ + } + } + else { + /* + * bytes[2,3] != (0,0); rules out Ultrix, could be + * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX + */ + if ((fhp[8] == 12) && (fhp[9] == 0)) { + fhtype = FHT_DECOSF; + } + else if ((fhp[8] == 0) && (fhp[9] == 10)) { + /* could be SUNOS5/IRIX5, AIX, HP-UX */ + if ((fhp[7] == 0) && (fhp[6] == 0) && + (fhp[5] == 0) && (fhp[4] == 0)) { + /* XXX is this always true of HP-UX? */ + fhtype = FHT_HPUX9; + } + else if (fhp[7] == 2) { + /* This would be MNT_NFS on AIX, which is impossible */ + fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ + } + else { + /* + * XXX Could be SUNOS5/IRIX5 or AIX. I don't + * XXX see any way to disambiguate these, so + * XXX I'm going with the more likely guess. + * XXX Sorry, Big Blue. + */ + fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ + } + } + else { + if (is_UCX(fhp)) { + fhtype = FHT_VMSUCX; + } + else { + fhtype = FHT_UNKNOWN; + } + } + } + } + + /* XXX still needs to handle SUNOS3 */ + + switch (fhtype) { + case FHT_AUSPEX: + fsidp->Fsid_dev.Minor = fhp[7]; + fsidp->Fsid_dev.Major = fhp[6]; + fsidp->fsid_code = 0; + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "Auspex"; + break; + + case FHT_BSD44: + fsidp->Fsid_dev.Minor = fhp[0]; + fsidp->Fsid_dev.Major = fhp[1]; + fsidp->fsid_code = 0; + + temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); + *inop = temp; + + if (osnamep) + *osnamep = "BSD 4.4"; + break; + + case FHT_DECOSF: + fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); + /* XXX could ignore 3 high-order bytes */ + + temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]); + fsidp->Fsid_dev.Minor = temp & 0xFFFFF; + fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF; + + temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); + *inop = temp; + if (osnamep) + *osnamep = "OSF"; + break; + + case FHT_IRIX4: + fsidp->Fsid_dev.Minor = fhp[3]; + fsidp->Fsid_dev.Major = fhp[2]; + fsidp->fsid_code = 0; + + temp = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]); + *inop = temp; + + if (osnamep) + *osnamep = "IRIX4"; + break; + + case FHT_IRIX5: + fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); + fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); + fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "IRIX5"; + break; + +#ifdef notdef + case FHT_SUNOS3: + /* + * XXX - none of the heuristics above return this. + * Are there any SunOS 3.x systems around to care about? + */ + if (osnamep) + *osnamep = "SUNOS3"; + break; +#endif + + case FHT_SUNOS4: + fsidp->Fsid_dev.Minor = fhp[3]; + fsidp->Fsid_dev.Major = fhp[2]; + fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "SUNOS4"; + break; + + case FHT_SUNOS5: + temp = make_uint16(fhp[0], fhp[1]); + fsidp->Fsid_dev.Major = (temp>>2) & 0x3FFF; + temp = make_uint24(fhp[1], fhp[2], fhp[3]); + fsidp->Fsid_dev.Minor = temp & 0x3FFFF; + fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "SUNOS5"; + break; + + case FHT_ULTRIX: + fsidp->fsid_code = 0; + fsidp->Fsid_dev.Minor = fhp[0]; + fsidp->Fsid_dev.Major = fhp[1]; + + temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); + *inop = temp; + if (osnamep) + *osnamep = "Ultrix"; + break; + + case FHT_VMSUCX: + /* No numeric file system ID, so hash on the device-name */ + if (sizeof(*fsidp) >= 14) { + if (sizeof(*fsidp) > 14) + memset((char *)fsidp, 0, sizeof(*fsidp)); + /* just use the whole thing */ + memcpy((char *)fsidp, (char *)fh, 14); + } + else { + u_int32_t tempa[4]; /* at least 16 bytes, maybe more */ + + memset((char *)tempa, 0, sizeof(tempa)); + memcpy((char *)tempa, (char *)fh, 14); /* ensure alignment */ + fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1); + fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1); + fsidp->fsid_code = 0; + } + + /* VMS file ID is: (RVN, FidHi, FidLo) */ + *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]); + + /* Caller must save (and null-terminate?) this value */ + if (fsnamep) + *fsnamep = (char *)&(fhp[1]); + + if (osnamep) + *osnamep = "VMS"; + break; + + case FHT_AIX32: + fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); + fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); + fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "AIX32"; + break; + + case FHT_HPUX9: + fsidp->Fsid_dev.Major = fhp[0]; + temp = make_uint24(fhp[1], fhp[2], fhp[3]); + fsidp->Fsid_dev.Minor = temp; + fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "HPUX9"; + break; + + case FHT_UNKNOWN: +#ifdef DEBUG + /* XXX debugging */ + for (i = 0; i < 32; i++) + (void)fprintf(stderr, "%x.", fhp[i]); + (void)fprintf(stderr, "\n"); +#endif + /* Save the actual handle, so it can be display with -u */ + for (i = 0; i < 32; i++) + (void)snprintf(&(fsidp->Opaque_Handle[i*2]), 3, "%.2X", fhp[i]); + + /* XXX for now, give "bogus" values to aid debugging */ + fsidp->fsid_code = 0; + fsidp->Fsid_dev.Minor = 257; + fsidp->Fsid_dev.Major = 257; + *inop = 1; + + /* display will show this string instead of (257,257) */ + if (fsnamep) + *fsnamep = "Unknown"; + + if (osnamep) + *osnamep = "Unknown"; + break; + + } +} + +/* + * Is this a VMS UCX file handle? + * Check for: + * (1) leading code byte [XXX not yet] + * (2) followed by string of printing chars & spaces + * (3) followed by string of nulls + */ +static int +is_UCX(fhp) +const unsigned char *fhp; +{ + register int i; + int seen_null = 0; + + for (i = 1; i < 14; i++) { + if (isprint(fhp[i])) { + if (seen_null) + return(0); + else + continue; + } + else if (fhp[i] == 0) { + seen_null = 1; + continue; + } + else + return(0); + } + + return(1); +} diff --git a/freebsd/contrib/tcpdump/pcap-missing.h b/freebsd/contrib/tcpdump/pcap-missing.h new file mode 100644 index 00000000..5c0ece25 --- /dev/null +++ b/freebsd/contrib/tcpdump/pcap-missing.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1988-2002 + * 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/pcap-missing.h,v 1.3 2005-06-03 22:08:52 guy Exp $ (LBL) + */ + +#ifndef tcpdump_pcap_missing_h +#define tcpdump_pcap_missing_h + +/* + * Declarations of functions that might be missing from libpcap. + */ + +#ifndef HAVE_PCAP_LIST_DATALINKS +extern int pcap_list_datalinks(pcap_t *, int **); +#endif + +#ifndef HAVE_PCAP_DATALINK_NAME_TO_VAL +/* + * We assume no platform has one but not the other. + */ +extern int pcap_datalink_name_to_val(const char *); +extern const char *pcap_datalink_val_to_name(int); +#endif + +#ifndef HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION +extern const char *pcap_datalink_val_to_description(int); +#endif + +#ifndef HAVE_PCAP_DUMP_FTELL +extern long pcap_dump_ftell(pcap_dumper_t *); +#endif + +#endif + + + + + + + + + diff --git a/freebsd/contrib/tcpdump/pmap_prot.h b/freebsd/contrib/tcpdump/pmap_prot.h new file mode 100644 index 00000000..949c3994 --- /dev/null +++ b/freebsd/contrib/tcpdump/pmap_prot.h @@ -0,0 +1,90 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/pmap_prot.h,v 1.3 2005-04-27 21:43:48 guy Exp $ (LBL) */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_prot.h 1.14 88/02/08 SMI + * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD$ + * FreeBSD: src/include/rpc/pmap_prot.h,v 1.9.2.1 1999/08/29 14:39:05 peter Exp + */ + +/* + * pmap_prot.h + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The following procedures are supported by the protocol: + * + * PMAPPROC_NULL() returns () + * takes nothing, returns nothing + * + * PMAPPROC_SET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Registers the tuple + * [prog, vers, prot, port]. + * + * PMAPPROC_UNSET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Un-registers pair + * [prog, vers]. prot and port are ignored. + * + * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). + * 0 is failure. Otherwise returns the port number where the pair + * [prog, vers] is registered. It may lie! + * + * PMAPPROC_DUMP() RETURNS (struct pmaplist *) + * + * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) + * RETURNS (port, string<>); + * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); + * Calls the procedure on the local machine. If it is not registered, + * this procedure is quite; ie it does not return error information!!! + * This procedure only is supported on rpc/udp and calls via + * rpc/udp. This routine only passes null authentication parameters. + * This file has no interface to xdr routines for PMAPPROC_CALLIT. + * + * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. + */ + +#define SUNRPC_PMAPPORT ((u_int16_t)111) +#define SUNRPC_PMAPPROG ((u_int32_t)100000) +#define SUNRPC_PMAPVERS ((u_int32_t)2) +#define SUNRPC_PMAPVERS_PROTO ((u_int32_t)2) +#define SUNRPC_PMAPVERS_ORIG ((u_int32_t)1) +#define SUNRPC_PMAPPROC_NULL ((u_int32_t)0) +#define SUNRPC_PMAPPROC_SET ((u_int32_t)1) +#define SUNRPC_PMAPPROC_UNSET ((u_int32_t)2) +#define SUNRPC_PMAPPROC_GETPORT ((u_int32_t)3) +#define SUNRPC_PMAPPROC_DUMP ((u_int32_t)4) +#define SUNRPC_PMAPPROC_CALLIT ((u_int32_t)5) + +struct sunrpc_pmap { + u_int32_t pm_prog; + u_int32_t pm_vers; + u_int32_t pm_prot; + u_int32_t pm_port; +}; diff --git a/freebsd/contrib/tcpdump/ppi.h b/freebsd/contrib/tcpdump/ppi.h new file mode 100644 index 00000000..733eb950 --- /dev/null +++ b/freebsd/contrib/tcpdump/ppi.h @@ -0,0 +1,9 @@ +typedef 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 + diff --git a/freebsd/contrib/tcpdump/ppp.h b/freebsd/contrib/tcpdump/ppp.h new file mode 100644 index 00000000..3ae519b6 --- /dev/null +++ b/freebsd/contrib/tcpdump/ppp.h @@ -0,0 +1,73 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/ppp.h,v 1.16 2004-10-20 16:14:16 hannes Exp $ (LBL) */ +/* + * Point to Point Protocol (PPP) RFC1331 + * + * Copyright 1989 by Carnegie Mellon. + * + * Permission to use, copy, modify, and distribute this program for any + * purpose and without fee is hereby granted, provided that this copyright + * and permission notice appear on all copies and supporting documentation, + * the name of Carnegie Mellon not be used in advertising or publicity + * pertaining to distribution of the program without specific prior + * permission, and notice be given in supporting documentation that copying + * and distribution is by permission of Carnegie Mellon and Stanford + * University. Carnegie Mellon makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * $FreeBSD$ + */ +#define PPP_HDRLEN 4 /* length of PPP header */ + +#define PPP_ADDRESS 0xff /* The address byte value */ +#define PPP_CONTROL 0x03 /* The control byte value */ + +#define PPP_WITHDIRECTION_IN 0x00 /* non-standard for DLT_PPP_WITHDIRECTION */ +#define PPP_WITHDIRECTION_OUT 0x01 /* non-standard for DLT_PPP_WITHDIRECTION */ + +/* Protocol numbers */ +#define PPP_IP 0x0021 /* Raw IP */ +#define PPP_OSI 0x0023 /* OSI Network Layer */ +#define PPP_NS 0x0025 /* Xerox NS IDP */ +#define PPP_DECNET 0x0027 /* DECnet Phase IV */ +#define PPP_APPLE 0x0029 /* Appletalk */ +#define PPP_IPX 0x002b /* Novell IPX */ +#define PPP_VJC 0x002d /* Van Jacobson Compressed TCP/IP */ +#define PPP_VJNC 0x002f /* Van Jacobson Uncompressed TCP/IP */ +#define PPP_BRPDU 0x0031 /* Bridging PDU */ +#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */ +#define PPP_VINES 0x0035 /* Banyan Vines */ +#define PPP_ML 0x003d /* Multi-Link PPP */ +#define PPP_IPV6 0x0057 /* IPv6 */ +#define PPP_COMP 0x00fd /* Compressed Datagram */ + +#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */ +#define PPP_LUXCOM 0x0231 /* Luxcom */ +#define PPP_SNS 0x0233 /* Sigma Network Systems */ +#define PPP_MPLS_UCAST 0x0281 /* rfc 3032 */ +#define PPP_MPLS_MCAST 0x0283 /* rfc 3022 */ + +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */ +#define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */ +#define PPP_DECNETCP 0x8027 /* DECnet Control Protocol */ +#define PPP_APPLECP 0x8029 /* Appletalk Control Protocol */ +#define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */ +#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */ +#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */ +#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ +#define PPP_CCP 0x80fd /* Compress Control Protocol */ +#define PPP_MPLSCP 0x8281 /* rfc 3022 */ + +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#define PPP_LQM 0xc025 /* Link Quality Monitoring */ +#define PPP_SPAP 0xc027 +#define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */ +#define PPP_BACP 0xc02b /* Bandwidth Allocation Control Protocol */ +#define PPP_BAP 0xc02d /* BAP */ +#define PPP_MPCP 0xc03d /* Multi-Link */ +#define PPP_SPAP_OLD 0xc123 +#define PPP_EAP 0xc227 + +extern struct tok ppptype2str[]; diff --git a/freebsd/contrib/tcpdump/print-802_11.c b/freebsd/contrib/tcpdump/print-802_11.c new file mode 100644 index 00000000..d0dee658 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-802_11.c @@ -0,0 +1,2389 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> +#include <string.h> + +#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"); + } + 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; + const u_char *iter; + 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; + } + for (last_presentp = &hdr->it_present; + IS_EXTENDED(last_presentp) && + (u_char*)(last_presentp + 1) <= p + len; + last_presentp++); + + /* are there more bitmap extensions than bytes in header? */ + if (IS_EXTENDED(last_presentp)) { + printf("[|802.11]"); + return caplen; + } + + iter = (u_char*)(last_presentp + 1); + + if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) { + /* XXX */ + 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); +} diff --git a/freebsd/contrib/tcpdump/print-802_15_4.c b/freebsd/contrib/tcpdump/print-802_15_4.c new file mode 100644 index 00000000..cd8ff8e6 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-802_15_4.c @@ -0,0 +1,185 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2009 + * Siemens AG, All rights reserved. + * Dmitry Eremin-Solenikov (dbaryshkov@gmail.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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" + +#include "extract.h" + +static const char *ftypes[] = { + "Beacon", /* 0 */ + "Data", /* 1 */ + "ACK", /* 2 */ + "Command", /* 3 */ + "Reserved", /* 4 */ + "Reserved", /* 5 */ + "Reserved", /* 6 */ + "Reserved", /* 7 */ +}; + +static int +extract_header_length(u_int16_t fc) +{ + int len = 0; + + switch ((fc >> 10) & 0x3) { + case 0x00: + if (fc & (1 << 6)) /* intra-PAN with none dest addr */ + return -1; + break; + case 0x01: + return -1; + case 0x02: + len += 4; + break; + case 0x03: + len += 10; + break; + } + + switch ((fc >> 14) & 0x3) { + case 0x00: + break; + case 0x01: + return -1; + case 0x02: + len += 4; + break; + case 0x03: + len += 10; + break; + } + + if (fc & (1 << 6)) { + if (len < 2) + return -1; + len -= 2; + } + + return len; +} + + +u_int +ieee802_15_4_if_print(struct netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + int hdrlen; + u_int16_t fc; + u_int8_t seq; + + if (caplen < 3) { + ND_PRINT((ndo, "[|802.15.4] %x", caplen)); + return caplen; + } + + fc = EXTRACT_LE_16BITS(p); + hdrlen = extract_header_length(fc); + + seq = EXTRACT_LE_8BITS(p + 2); + + p += 3; + caplen -= 3; + + ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[fc & 0x7])); + if (vflag) + ND_PRINT((ndo,"seq %02x ", seq)); + if (hdrlen == -1) { + ND_PRINT((ndo,"malformed! ")); + return caplen; + } + + + if (!vflag) { + p+= hdrlen; + caplen -= hdrlen; + } else { + u_int16_t panid = 0; + + switch ((fc >> 10) & 0x3) { + case 0x00: + ND_PRINT((ndo,"none ")); + break; + case 0x01: + ND_PRINT((ndo,"reserved destination addressing mode")); + return 0; + case 0x02: + panid = EXTRACT_LE_16BITS(p); + p += 2; + ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p))); + p += 2; + break; + case 0x03: + panid = EXTRACT_LE_16BITS(p); + p += 2; + ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(p))); + p += 8; + break; + } + ND_PRINT((ndo,"< "); + + switch ((fc >> 14) & 0x3) { + case 0x00: + ND_PRINT((ndo,"none ")); + break; + case 0x01: + ND_PRINT((ndo,"reserved source addressing mode")); + return 0; + case 0x02: + if (!(fc & (1 << 6))) { + panid = EXTRACT_LE_16BITS(p); + p += 2; + } + ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p))); + p += 2; + break; + case 0x03: + if (!(fc & (1 << 6))) { + panid = EXTRACT_LE_16BITS(p); + p += 2; + } + ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(p)))); + p += 8; + break; + } + + caplen -= hdrlen; + } + + if (!suppress_default_print) + (ndo->ndo_default_print)(ndo, p, caplen); + + return 0; +} diff --git a/freebsd/contrib/tcpdump/print-ah.c b/freebsd/contrib/tcpdump/print-ah.c new file mode 100644 index 00000000..0bc6b389 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ah.c @@ -0,0 +1,73 @@ +#include <machine/rtems-bsd-user-space.h> + +/* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */ + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ah.c,v 1.22 2003-11-19 00:36:06 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "ah.h" + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +int +ah_print(register const u_char *bp) +{ + register const struct ah *ah; + register const u_char *ep; + int sumlen; + u_int32_t spi; + + ah = (const struct ah *)bp; + ep = snapend; /* 'ep' points to the end of available data. */ + + TCHECK(*ah); + + sumlen = ah->ah_len << 2; + spi = EXTRACT_32BITS(&ah->ah_spi); + + printf("AH(spi=0x%08x", spi); + if (vflag) + printf(",sumlen=%d", sumlen); + printf(",seq=0x%x", EXTRACT_32BITS(ah + 1)); + if (bp + sizeof(struct ah) + sumlen > ep) + fputs("[truncated]", stdout); + fputs("): ", stdout); + + return sizeof(struct ah) + sumlen; + trunc: + fputs("[|AH]", stdout); + return -1; +} diff --git a/freebsd/contrib/tcpdump/print-aodv.c b/freebsd/contrib/tcpdump/print-aodv.c new file mode 100644 index 00000000..a585a95a --- /dev/null +++ b/freebsd/contrib/tcpdump/print-aodv.c @@ -0,0 +1,457 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org> + * 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 <tcpdump-stdinc.h> + +#include <stddef.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> + +#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); + } +} diff --git a/freebsd/contrib/tcpdump/print-ap1394.c b/freebsd/contrib/tcpdump/print-ap1394.c new file mode 100644 index 00000000..698b2123 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ap1394.c @@ -0,0 +1,121 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * 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-ap1394.c,v 1.5 2006-02-11 22:12:06 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" + +/* + * Structure of a header for Apple's IP-over-IEEE 1384 BPF header. + */ +#define FIREWIRE_EUI64_LEN 8 +struct firewire_header { + u_char firewire_dhost[FIREWIRE_EUI64_LEN]; + u_char firewire_shost[FIREWIRE_EUI64_LEN]; + u_short firewire_type; +}; + +/* + * Length of that header; note that some compilers may pad + * "struct firewire_header" to a multiple of 4 bytes, for example, so + * "sizeof (struct firewire_header)" may not give the right answer. + */ +#define FIREWIRE_HDRLEN 18 + +static inline void +ap1394_hdr_print(register const u_char *bp, u_int length) +{ + register const struct firewire_header *fp; + u_int16_t firewire_type; + + fp = (const struct firewire_header *)bp; + + (void)printf("%s > %s", + linkaddr_string(fp->firewire_dhost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN), + linkaddr_string(fp->firewire_shost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN)); + + firewire_type = EXTRACT_16BITS(&fp->firewire_type); + if (!qflag) { + (void)printf(", ethertype %s (0x%04x)", + tok2str(ethertype_values,"Unknown", firewire_type), + firewire_type); + } else { + (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", firewire_type)); + } + + (void)printf(", length %u: ", length); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether 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 +ap1394_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int length = h->len; + u_int caplen = h->caplen; + struct firewire_header *fp; + u_short ether_type; + + if (caplen < FIREWIRE_HDRLEN) { + printf("[|ap1394]"); + return FIREWIRE_HDRLEN; + } + + if (eflag) + ap1394_hdr_print(p, length); + + length -= FIREWIRE_HDRLEN; + caplen -= FIREWIRE_HDRLEN; + fp = (struct firewire_header *)p; + p += FIREWIRE_HDRLEN; + + ether_type = EXTRACT_16BITS(&fp->firewire_type); + if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + ap1394_hdr_print((u_char *)fp, length + FIREWIRE_HDRLEN); + + if (!suppress_default_print) + default_print(p, caplen); + } + + return FIREWIRE_HDRLEN; +} diff --git a/freebsd/contrib/tcpdump/print-arcnet.c b/freebsd/contrib/tcpdump/print-arcnet.c new file mode 100644 index 00000000..83bb8fb6 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-arcnet.c @@ -0,0 +1,300 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * From: NetBSD: print-arcnet.c,v 1.2 2000/04/24 13:02:28 itojun Exp + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-arcnet.c,v 1.20 2005-04-06 21:32:38 mcr Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> + +#include "interface.h" +#include "extract.h" +#include "arcnet.h" + +static int arcnet_encap_print(u_char arctype, const u_char *p, + u_int length, u_int caplen); + +struct tok arctypemap[] = { + { ARCTYPE_IP_OLD, "oldip" }, + { ARCTYPE_ARP_OLD, "oldarp" }, + { ARCTYPE_IP, "ip" }, + { ARCTYPE_ARP, "arp" }, + { ARCTYPE_REVARP, "rarp" }, + { ARCTYPE_ATALK, "atalk" }, + { ARCTYPE_BANIAN, "banyan" }, + { ARCTYPE_IPX, "ipx" }, + { ARCTYPE_INET6, "ipv6" }, + { ARCTYPE_DIAGNOSE, "diag" }, + { 0, 0 } +}; + +static inline void +arcnet_print(const u_char *bp, u_int length, int phds, int flag, u_int seqid) +{ + const struct arc_header *ap; + const char *arctypename; + + + ap = (const struct arc_header *)bp; + + + if (qflag) { + (void)printf("%02x %02x %d: ", + ap->arc_shost, + ap->arc_dhost, + length); + return; + } + + arctypename = tok2str(arctypemap, "%02x", ap->arc_type); + + if (!phds) { + (void)printf("%02x %02x %s %d: ", + ap->arc_shost, ap->arc_dhost, arctypename, + length); + return; + } + + if (flag == 0) { + (void)printf("%02x %02x %s seqid %04x %d: ", + ap->arc_shost, ap->arc_dhost, arctypename, seqid, + length); + return; + } + + if (flag & 1) + (void)printf("%02x %02x %s seqid %04x " + "(first of %d fragments) %d: ", + ap->arc_shost, ap->arc_dhost, arctypename, seqid, + (flag + 3) / 2, length); + else + (void)printf("%02x %02x %s seqid %04x " + "(fragment %d) %d: ", + ap->arc_shost, ap->arc_dhost, arctypename, seqid, + flag/2 + 1, length); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ARCNET 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 +arcnet_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + const struct arc_header *ap; + + int phds, flag = 0, archdrlen = 0; + u_int seqid = 0; + u_char arc_type; + + if (caplen < ARC_HDRLEN) { + printf("[|arcnet]"); + return (caplen); + } + + ap = (const struct arc_header *)p; + arc_type = ap->arc_type; + + switch (arc_type) { + default: + phds = 1; + break; + case ARCTYPE_IP_OLD: + case ARCTYPE_ARP_OLD: + case ARCTYPE_DIAGNOSE: + phds = 0; + archdrlen = ARC_HDRLEN; + break; + } + + if (phds) { + if (caplen < ARC_HDRNEWLEN) { + arcnet_print(p, length, 0, 0, 0); + printf("[|phds]"); + return (caplen); + } + + if (ap->arc_flag == 0xff) { + if (caplen < ARC_HDRNEWLEN_EXC) { + arcnet_print(p, length, 0, 0, 0); + printf("[|phds extended]"); + return (caplen); + } + flag = ap->arc_flag2; + seqid = EXTRACT_16BITS(&ap->arc_seqid2); + archdrlen = ARC_HDRNEWLEN_EXC; + } else { + flag = ap->arc_flag; + seqid = EXTRACT_16BITS(&ap->arc_seqid); + archdrlen = ARC_HDRNEWLEN; + } + } + + + if (eflag) + arcnet_print(p, length, phds, flag, seqid); + + /* + * Go past the ARCNET header. + */ + length -= archdrlen; + caplen -= archdrlen; + p += archdrlen; + + if (phds && flag && (flag & 1) == 0) { + /* + * This is a middle fragment. + */ + return (archdrlen); + } + + if (!arcnet_encap_print(arc_type, p, length, caplen)) + default_print(p, caplen); + + return (archdrlen); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ARCNET 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. It is quite similar + * to the non-Linux style printer except that Linux doesn't ever + * supply packets that look like exception frames, it always supplies + * reassembled packets rather than raw frames, and headers have an + * extra "offset" field between the src/dest and packet type. + */ +u_int +arcnet_linux_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + const struct arc_linux_header *ap; + + int archdrlen = 0; + u_char arc_type; + + if (caplen < ARC_LINUX_HDRLEN) { + printf("[|arcnet]"); + return (caplen); + } + + ap = (const struct arc_linux_header *)p; + arc_type = ap->arc_type; + + switch (arc_type) { + default: + archdrlen = ARC_LINUX_HDRNEWLEN; + if (caplen < ARC_LINUX_HDRNEWLEN) { + printf("[|arcnet]"); + return (caplen); + } + break; + case ARCTYPE_IP_OLD: + case ARCTYPE_ARP_OLD: + case ARCTYPE_DIAGNOSE: + archdrlen = ARC_LINUX_HDRLEN; + break; + } + + if (eflag) + arcnet_print(p, length, 0, 0, 0); + + /* + * Go past the ARCNET header. + */ + length -= archdrlen; + caplen -= archdrlen; + p += archdrlen; + + if (!arcnet_encap_print(arc_type, p, length, caplen)) + default_print(p, caplen); + + return (archdrlen); +} + +/* + * Prints the packet encapsulated in an ARCnet data field, + * given the ARCnet system code. + * + * Returns non-zero if it can do so, zero if the system code is unknown. + */ + + +static int +arcnet_encap_print(u_char arctype, const u_char *p, + u_int length, u_int caplen) +{ + switch (arctype) { + + case ARCTYPE_IP_OLD: + case ARCTYPE_IP: + ip_print(gndo, p, length); + return (1); + +#ifdef INET6 + case ARCTYPE_INET6: + ip6_print(gndo, p, length); + return (1); +#endif /*INET6*/ + + case ARCTYPE_ARP_OLD: + case ARCTYPE_ARP: + case ARCTYPE_REVARP: + arp_print(gndo, p, length, caplen); + return (1); + + case ARCTYPE_ATALK: /* XXX was this ever used? */ + if (vflag) + fputs("et1 ", stdout); + atalk_print(p, length); + return (1); + + case ARCTYPE_IPX: + ipx_print(p, length); + return (1); + + default: + return (0); + } +} + +/* + * Local Variables: + * c-style: bsd + * End: + */ + diff --git a/freebsd/contrib/tcpdump/print-arp.c b/freebsd/contrib/tcpdump/print-arp.c new file mode 100644 index 00000000..ac85cf96 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-arp.c @@ -0,0 +1,421 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * $FreeBSD$ + */ + +#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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#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)) + + +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 } +}; + +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, "<No address>")); + 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: + */ + diff --git a/freebsd/contrib/tcpdump/print-ascii.c b/freebsd/contrib/tcpdump/print-ascii.c new file mode 100644 index 00000000..70199afd --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ascii.c @@ -0,0 +1,185 @@ +#include <machine/rtems-bsd-user-space.h> + +/* $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 <tcpdump-stdinc.h> +#include <stdio.h> + +#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 */ diff --git a/freebsd/contrib/tcpdump/print-atalk.c b/freebsd/contrib/tcpdump/print-atalk.c new file mode 100644 index 00000000..f6a0dcc0 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-atalk.c @@ -0,0 +1,627 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * $FreeBSD$ + */ + +#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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pcap.h> + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "extract.h" /* must come after interface.h */ +#include "appletalk.h" + +static 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[MAXHOSTNAMELEN + 20]; + 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 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)); +} diff --git a/freebsd/contrib/tcpdump/print-atm.c b/freebsd/contrib/tcpdump/print-atm.c new file mode 100644 index 00000000..ecf03a86 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-atm.c @@ -0,0 +1,455 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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. + * + * $FreeBSD$ + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.49 2007-10-22 19:37:51 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "atm.h" +#include "atmuni31.h" +#include "llc.h" + +#include "ether.h" + +#define OAM_CRC10_MASK 0x3ff +#define OAM_PAYLOAD_LEN 48 +#define OAM_FUNCTION_SPECIFIC_LEN 45 /* this excludes crc10 and cell-type/function-type */ +#define OAM_CELLTYPE_FUNCTYPE_LEN 1 + +struct tok oam_f_values[] = { + { VCI_OAMF4SC, "OAM F4 (segment)" }, + { VCI_OAMF4EC, "OAM F4 (end)" }, + { 0, NULL } +}; + +struct tok atm_pty_values[] = { + { 0x0, "user data, uncongested, SDU 0" }, + { 0x1, "user data, uncongested, SDU 1" }, + { 0x2, "user data, congested, SDU 0" }, + { 0x3, "user data, congested, SDU 1" }, + { 0x4, "VCC OAM F5 flow segment" }, + { 0x5, "VCC OAM F5 flow end-to-end" }, + { 0x6, "Traffic Control and resource Mgmt" }, + { 0, NULL } +}; + +#define OAM_CELLTYPE_FM 0x1 +#define OAM_CELLTYPE_PM 0x2 +#define OAM_CELLTYPE_AD 0x8 +#define OAM_CELLTYPE_SM 0xf + +struct tok oam_celltype_values[] = { + { OAM_CELLTYPE_FM, "Fault Management" }, + { OAM_CELLTYPE_PM, "Performance Management" }, + { OAM_CELLTYPE_AD, "activate/deactivate" }, + { OAM_CELLTYPE_SM, "System Management" }, + { 0, NULL } +}; + +#define OAM_FM_FUNCTYPE_AIS 0x0 +#define OAM_FM_FUNCTYPE_RDI 0x1 +#define OAM_FM_FUNCTYPE_CONTCHECK 0x4 +#define OAM_FM_FUNCTYPE_LOOPBACK 0x8 + +struct tok oam_fm_functype_values[] = { + { OAM_FM_FUNCTYPE_AIS, "AIS" }, + { OAM_FM_FUNCTYPE_RDI, "RDI" }, + { OAM_FM_FUNCTYPE_CONTCHECK, "Continuity Check" }, + { OAM_FM_FUNCTYPE_LOOPBACK, "Loopback" }, + { 0, NULL } +}; + +struct tok oam_pm_functype_values[] = { + { 0x0, "Forward Monitoring" }, + { 0x1, "Backward Reporting" }, + { 0x2, "Monitoring and Reporting" }, + { 0, NULL } +}; + +struct tok oam_ad_functype_values[] = { + { 0x0, "Performance Monitoring" }, + { 0x1, "Continuity Check" }, + { 0, NULL } +}; + +#define OAM_FM_LOOPBACK_INDICATOR_MASK 0x1 + +struct tok oam_fm_loopback_indicator_values[] = { + { 0x0, "Reply" }, + { 0x1, "Request" }, + { 0, NULL } +}; + +static const struct tok *oam_functype_values[16] = { + NULL, + oam_fm_functype_values, /* 1 */ + oam_pm_functype_values, /* 2 */ + NULL, + NULL, + NULL, + NULL, + NULL, + oam_ad_functype_values, /* 8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +/* + * Print an RFC 1483 LLC-encapsulated ATM frame. + */ +static void +atm_llc_print(const u_char *p, int length, int caplen) +{ + u_short extracted_ethertype; + + if (!llc_print(p, length, caplen, NULL, NULL, + &extracted_ethertype)) { + /* ether_type not known, print raw packet */ + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + } +} + +/* + * Given a SAP value, generate the LLC header value for a UI packet + * with that SAP as the source and destination SAP. + */ +#define LLC_UI_HDR(sap) ((sap)<<16 | (sap<<8) | 0x03) + +/* + * This is the top level routine of the printer. 'p' points + * to the LLC/SNAP 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 +atm_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + u_int32_t llchdr; + u_int hdrlen = 0; + + if (caplen < 8) { + printf("[|atm]"); + return (caplen); + } + + /* Cisco Style NLPID ? */ + if (*p == LLC_UI) { + if (eflag) + printf("CNLPID "); + isoclns_print(p+1, length-1, caplen-1); + return hdrlen; + } + + /* + * Extract the presumed LLC header into a variable, for quick + * testing. + * Then check for a header that's neither a header for a SNAP + * packet nor an RFC 2684 routed NLPID-formatted PDU nor + * an 802.2-but-no-SNAP IP packet. + */ + llchdr = EXTRACT_24BITS(p); + if (llchdr != LLC_UI_HDR(LLCSAP_SNAP) && + llchdr != LLC_UI_HDR(LLCSAP_ISONS) && + llchdr != LLC_UI_HDR(LLCSAP_IP)) { + /* + * XXX - assume 802.6 MAC header from Fore driver. + * + * Unfortunately, the above list doesn't check for + * all known SAPs, doesn't check for headers where + * the source and destination SAP aren't the same, + * and doesn't check for non-UI frames. It also + * runs the risk of an 802.6 MAC header that happens + * to begin with one of those values being + * incorrectly treated as an 802.2 header. + * + * So is that Fore driver still around? And, if so, + * is it still putting 802.6 MAC headers on ATM + * packets? If so, could it be changed to use a + * new DLT_IEEE802_6 value if we added it? + */ + if (eflag) + printf("%08x%08x %08x%08x ", + EXTRACT_32BITS(p), + EXTRACT_32BITS(p+4), + EXTRACT_32BITS(p+8), + EXTRACT_32BITS(p+12)); + p += 20; + length -= 20; + caplen -= 20; + hdrlen += 20; + } + atm_llc_print(p, length, caplen); + return (hdrlen); +} + +/* + * ATM signalling. + */ +static struct tok msgtype2str[] = { + { CALL_PROCEED, "Call_proceeding" }, + { CONNECT, "Connect" }, + { CONNECT_ACK, "Connect_ack" }, + { SETUP, "Setup" }, + { RELEASE, "Release" }, + { RELEASE_DONE, "Release_complete" }, + { RESTART, "Restart" }, + { RESTART_ACK, "Restart_ack" }, + { STATUS, "Status" }, + { STATUS_ENQ, "Status_enquiry" }, + { ADD_PARTY, "Add_party" }, + { ADD_PARTY_ACK, "Add_party_ack" }, + { ADD_PARTY_REJ, "Add_party_reject" }, + { DROP_PARTY, "Drop_party" }, + { DROP_PARTY_ACK, "Drop_party_ack" }, + { 0, NULL } +}; + +static void +sig_print(const u_char *p, int caplen) +{ + bpf_u_int32 call_ref; + + if (caplen < PROTO_POS) { + printf("[|atm]"); + return; + } + if (p[PROTO_POS] == Q2931) { + /* + * protocol:Q.2931 for User to Network Interface + * (UNI 3.1) signalling + */ + printf("Q.2931"); + if (caplen < MSG_TYPE_POS) { + printf(" [|atm]"); + return; + } + printf(":%s ", + tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS])); + + /* + * The call reference comes before the message type, + * so if we know we have the message type, which we + * do from the caplen test above, we also know we have + * the call reference. + */ + call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]); + printf("CALL_REF:0x%06x", call_ref); + } else { + /* SCCOP with some unknown protocol atop it */ + printf("SSCOP, proto %d ", p[PROTO_POS]); + } +} + +/* + * Print an ATM PDU (such as an AAL5 PDU). + */ +void +atm_print(u_int vpi, u_int vci, u_int traftype, const u_char *p, u_int length, + u_int caplen) +{ + if (eflag) + printf("VPI:%u VCI:%u ", vpi, vci); + + if (vpi == 0) { + switch (vci) { + + case VCI_PPC: + sig_print(p, caplen); + return; + + case VCI_BCC: + printf("broadcast sig: "); + return; + + case VCI_OAMF4SC: /* fall through */ + case VCI_OAMF4EC: + oam_print(p, length, ATM_OAM_HEC); + return; + + case VCI_METAC: + printf("meta: "); + return; + + case VCI_ILMIC: + printf("ilmi: "); + snmp_print(p, length); + return; + } + } + + switch (traftype) { + + case ATM_LLC: + default: + /* + * Assumes traffic is LLC if unknown. + */ + atm_llc_print(p, length, caplen); + break; + + case ATM_LANE: + lane_print(p, length, caplen); + break; + } +} + +struct oam_fm_loopback_t { + u_int8_t loopback_indicator; + u_int8_t correlation_tag[4]; + u_int8_t loopback_id[12]; + u_int8_t source_id[12]; + u_int8_t unused[16]; +}; + +struct oam_fm_ais_rdi_t { + u_int8_t failure_type; + u_int8_t failure_location[16]; + u_int8_t unused[28]; +}; + +int +oam_print (const u_char *p, u_int length, u_int hec) { + + u_int32_t cell_header; + u_int16_t vpi, vci, cksum, cksum_shouldbe, idx; + u_int8_t cell_type, func_type, payload, clp; + + union { + const struct oam_fm_loopback_t *oam_fm_loopback; + const struct oam_fm_ais_rdi_t *oam_fm_ais_rdi; + } oam_ptr; + + + cell_header = EXTRACT_32BITS(p+hec); + cell_type = ((*(p+ATM_HDR_LEN_NOHEC+hec))>>4) & 0x0f; + func_type = (*(p+ATM_HDR_LEN_NOHEC+hec)) & 0x0f; + + vpi = (cell_header>>20)&0xff; + vci = (cell_header>>4)&0xffff; + payload = (cell_header>>1)&0x7; + clp = cell_header&0x1; + + printf("%s, vpi %u, vci %u, payload [ %s ], clp %u, length %u", + tok2str(oam_f_values, "OAM F5", vci), + vpi, vci, + tok2str(atm_pty_values, "Unknown", payload), + clp, length); + + if (!vflag) { + return 1; + } + + printf("\n\tcell-type %s (%u)", + tok2str(oam_celltype_values, "unknown", cell_type), + cell_type); + + if (oam_functype_values[cell_type] == NULL) + printf(", func-type unknown (%u)", func_type); + else + printf(", func-type %s (%u)", + tok2str(oam_functype_values[cell_type],"none",func_type), + func_type); + + p += ATM_HDR_LEN_NOHEC + hec; + + switch (cell_type << 4 | func_type) { + case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_LOOPBACK): + oam_ptr.oam_fm_loopback = (const struct oam_fm_loopback_t *)(p + OAM_CELLTYPE_FUNCTYPE_LEN); + printf("\n\tLoopback-Indicator %s, Correlation-Tag 0x%08x", + tok2str(oam_fm_loopback_indicator_values, + "Unknown", + oam_ptr.oam_fm_loopback->loopback_indicator & OAM_FM_LOOPBACK_INDICATOR_MASK), + EXTRACT_32BITS(&oam_ptr.oam_fm_loopback->correlation_tag)); + printf("\n\tLocation-ID "); + for (idx = 0; idx < sizeof(oam_ptr.oam_fm_loopback->loopback_id); idx++) { + if (idx % 2) { + printf("%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_loopback->loopback_id[idx])); + } + } + printf("\n\tSource-ID "); + for (idx = 0; idx < sizeof(oam_ptr.oam_fm_loopback->source_id); idx++) { + if (idx % 2) { + printf("%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_loopback->source_id[idx])); + } + } + break; + + case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_AIS): + case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_RDI): + oam_ptr.oam_fm_ais_rdi = (const struct oam_fm_ais_rdi_t *)(p + OAM_CELLTYPE_FUNCTYPE_LEN); + printf("\n\tFailure-type 0x%02x", oam_ptr.oam_fm_ais_rdi->failure_type); + printf("\n\tLocation-ID "); + for (idx = 0; idx < sizeof(oam_ptr.oam_fm_ais_rdi->failure_location); idx++) { + if (idx % 2) { + printf("%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_ais_rdi->failure_location[idx])); + } + } + break; + + case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_CONTCHECK): + /* FIXME */ + break; + + default: + break; + } + + /* crc10 checksum verification */ + cksum = EXTRACT_16BITS(p + OAM_CELLTYPE_FUNCTYPE_LEN + OAM_FUNCTION_SPECIFIC_LEN) + & OAM_CRC10_MASK; + cksum_shouldbe = verify_crc10_cksum(0, p, OAM_PAYLOAD_LEN); + + printf("\n\tcksum 0x%03x (%scorrect)", + cksum, + cksum_shouldbe == 0 ? "" : "in"); + + return 1; +} diff --git a/freebsd/contrib/tcpdump/print-babel.c b/freebsd/contrib/tcpdump/print-babel.c new file mode 100644 index 00000000..629c57e9 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-babel.c @@ -0,0 +1,449 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2007-2011 Grégoire Henry, Juliusz Chroboczek + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "addrtoname.h" +#include "interface.h" +#include "extract.h" + +static void babel_print_v2(const u_char *cp, u_int length); + +void +babel_print(const u_char *cp, u_int length) { + printf("babel"); + + TCHECK2(*cp, 4); + + if(cp[0] != 42) { + printf(" malformed header"); + return; + } else { + printf(" %d", cp[1]); + } + + switch(cp[1]) { + case 2: + babel_print_v2(cp,length); + break; + default: + printf(" unknown version"); + break; + } + + return; + + trunc: + printf(" [|babel]"); + return; +} + +#define MESSAGE_PAD1 0 +#define MESSAGE_PADN 1 +#define MESSAGE_ACK_REQ 2 +#define MESSAGE_ACK 3 +#define MESSAGE_HELLO 4 +#define MESSAGE_IHU 5 +#define MESSAGE_ROUTER_ID 6 +#define MESSAGE_NH 7 +#define MESSAGE_UPDATE 8 +#define MESSAGE_REQUEST 9 +#define MESSAGE_MH_REQUEST 10 +#define MESSAGE_TSPC 11 +#define MESSAGE_HMAC 12 + +static const char * +format_id(const u_char *id) +{ + static char buf[25]; + snprintf(buf, 25, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7]); + buf[24] = '\0'; + return buf; +} + +static const unsigned char v4prefix[16] = + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }; + +static const char * +format_prefix(const u_char *prefix, unsigned char plen) +{ + static char buf[50]; + if(plen >= 96 && memcmp(prefix, v4prefix, 12) == 0) + snprintf(buf, 50, "%s/%u", ipaddr_string(prefix + 12), plen - 96); + else +#ifdef INET6 + snprintf(buf, 50, "%s/%u", ip6addr_string(prefix), plen); +#else + snprintf(buf, 50, "IPv6 addresses not supported"); +#endif + buf[49] = '\0'; + return buf; +} + +static const char * +format_address(const u_char *prefix) +{ + if(memcmp(prefix, v4prefix, 12) == 0) + return ipaddr_string(prefix + 12); + else +#ifdef INET6 + return ip6addr_string(prefix); +#else + return "IPv6 addresses not supported"; +#endif +} + +static int +network_prefix(int ae, int plen, unsigned int omitted, + const unsigned char *p, const unsigned char *dp, + unsigned int len, unsigned char *p_r) +{ + unsigned pb; + unsigned char prefix[16]; + + if(plen >= 0) + pb = (plen + 7) / 8; + else if(ae == 1) + pb = 4; + else + pb = 16; + + if(pb > 16) + return -1; + + memset(prefix, 0, 16); + + switch(ae) { + case 0: break; + case 1: + if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted)) + return -1; + memcpy(prefix, v4prefix, 12); + if(omitted) { + if (dp == NULL) return -1; + memcpy(prefix, dp, 12 + omitted); + } + if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted); + break; + case 2: + if(omitted > 16 || (pb > omitted && len < pb - omitted)) + return -1; + if(omitted) { + if (dp == NULL) return -1; + memcpy(prefix, dp, omitted); + } + if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted); + break; + case 3: + if(pb > 8 && len < pb - 8) return -1; + prefix[0] = 0xfe; + prefix[1] = 0x80; + if(pb > 8) memcpy(prefix + 8, p, pb - 8); + break; + default: + return -1; + } + + memcpy(p_r, prefix, 16); + return 1; +} + +static int +network_address(int ae, const unsigned char *a, unsigned int len, + unsigned char *a_r) +{ + return network_prefix(ae, -1, 0, a, NULL, len, a_r); +} + +#define ICHECK(i, l) \ + if ((i) + (l) > bodylen || (i) + (l) > length) goto corrupt; + +static void +babel_print_v2(const u_char *cp, u_int length) { + u_int i; + u_short bodylen; + u_char v4_prefix[16] = + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }; + u_char v6_prefix[16] = {0}; + + TCHECK2(*cp, 4); + if (length < 4) + goto corrupt; + bodylen = EXTRACT_16BITS(cp + 2); + printf(" (%u)", bodylen); + + /* Process the TLVs in the body */ + i = 0; + while(i < bodylen) { + const u_char *message; + u_int type, len; + + message = cp + 4 + i; + TCHECK2(*message, 2); + ICHECK(i, 2); + type = message[0]; + len = message[1]; + + TCHECK2(*message, 2 + len); + ICHECK(i, 2 + len); + + switch(type) { + case MESSAGE_PAD1: { + if(!vflag) + printf(" pad1"); + else + printf("\n\tPad 1"); + } + break; + + case MESSAGE_PADN: { + if(!vflag) + printf(" padN"); + else + printf("\n\tPad %d", len + 2); + } + break; + + case MESSAGE_ACK_REQ: { + u_short nonce, interval; + if(!vflag) + printf(" ack-req"); + else { + printf("\n\tAcknowledgment Request "); + if(len < 6) goto corrupt; + nonce = EXTRACT_16BITS(message + 4); + interval = EXTRACT_16BITS(message + 6); + printf("%04x %d", nonce, interval); + } + } + break; + + case MESSAGE_ACK: { + u_short nonce; + if(!vflag) + printf(" ack"); + else { + printf("\n\tAcknowledgment "); + if(len < 2) goto corrupt; + nonce = EXTRACT_16BITS(message + 2); + printf("%04x", nonce); + } + } + break; + + case MESSAGE_HELLO: { + u_short seqno, interval; + if(!vflag) + printf(" hello"); + else { + printf("\n\tHello "); + if(len < 6) goto corrupt; + seqno = EXTRACT_16BITS(message + 4); + interval = EXTRACT_16BITS(message + 6); + printf("seqno %u interval %u", seqno, interval); + } + } + break; + + case MESSAGE_IHU: { + unsigned short txcost, interval; + if(!vflag) + printf(" ihu"); + else { + u_char address[16]; + int rc; + printf("\n\tIHU "); + if(len < 6) goto corrupt; + txcost = EXTRACT_16BITS(message + 4); + interval = EXTRACT_16BITS(message + 6); + rc = network_address(message[2], message + 8, len - 6, address); + if(rc < 0) { printf("[|babel]"); break; } + printf("%s txcost %u interval %d", + format_address(address), txcost, interval); + } + } + break; + + case MESSAGE_ROUTER_ID: { + if(!vflag) + printf(" router-id"); + else { + printf("\n\tRouter Id"); + if(len < 10) goto corrupt; + printf(" %s", format_id(message + 4)); + } + } + break; + + case MESSAGE_NH: { + if(!vflag) + printf(" nh"); + else { + int rc; + u_char nh[16]; + printf("\n\tNext Hop"); + if(len < 2) goto corrupt; + rc = network_address(message[2], message + 4, len - 2, nh); + if(rc < 0) goto corrupt; + printf(" %s", format_address(nh)); + } + } + break; + + case MESSAGE_UPDATE: { + if(!vflag) { + printf(" update"); + if(len < 1) + printf("/truncated"); + else + printf("%s%s%s", + (message[3] & 0x80) ? "/prefix": "", + (message[3] & 0x40) ? "/id" : "", + (message[3] & 0x3f) ? "/unknown" : ""); + } else { + u_short interval, seqno, metric; + u_char plen; + int rc; + u_char prefix[16]; + printf("\n\tUpdate"); + if(len < 10) goto corrupt; + plen = message[4] + (message[2] == 1 ? 96 : 0); + rc = network_prefix(message[2], message[4], message[5], + message + 12, + message[2] == 1 ? v4_prefix : v6_prefix, + len - 10, prefix); + if(rc < 0) goto corrupt; + interval = EXTRACT_16BITS(message + 6); + seqno = EXTRACT_16BITS(message + 8); + metric = EXTRACT_16BITS(message + 10); + printf("%s%s%s %s metric %u seqno %u interval %u", + (message[3] & 0x80) ? "/prefix": "", + (message[3] & 0x40) ? "/id" : "", + (message[3] & 0x3f) ? "/unknown" : "", + format_prefix(prefix, plen), + metric, seqno, interval); + if(message[3] & 0x80) { + if(message[2] == 1) + memcpy(v4_prefix, prefix, 16); + else + memcpy(v6_prefix, prefix, 16); + } + } + } + break; + + case MESSAGE_REQUEST: { + if(!vflag) + printf(" request"); + else { + int rc; + u_char prefix[16], plen; + printf("\n\tRequest "); + if(len < 2) goto corrupt; + plen = message[3] + (message[2] == 1 ? 96 : 0); + rc = network_prefix(message[2], message[3], 0, + message + 4, NULL, len - 2, prefix); + if(rc < 0) goto corrupt; + plen = message[3] + (message[2] == 1 ? 96 : 0); + printf("for %s", + message[2] == 0 ? "any" : format_prefix(prefix, plen)); + } + } + break; + + case MESSAGE_MH_REQUEST : { + if(!vflag) + printf(" mh-request"); + else { + int rc; + u_short seqno; + u_char prefix[16], plen; + printf("\n\tMH-Request "); + if(len < 14) goto corrupt; + seqno = EXTRACT_16BITS(message + 4); + rc = network_prefix(message[2], message[3], 0, + message + 16, NULL, len - 14, prefix); + if(rc < 0) goto corrupt; + plen = message[3] + (message[2] == 1 ? 96 : 0); + printf("(%u hops) for %s seqno %u id %s", + message[6], format_prefix(prefix, plen), + seqno, format_id(message + 8)); + } + } + break; + case MESSAGE_TSPC : + if(!vflag) + printf(" tspc"); + else { + printf("\n\tTS/PC "); + if(len < 6) goto corrupt; + printf("timestamp %u packetcounter %u", EXTRACT_32BITS (message + 4), + EXTRACT_16BITS(message + 2)); + } + break; + case MESSAGE_HMAC : { + if(!vflag) + printf(" hmac"); + else { + unsigned j; + printf("\n\tHMAC "); + if(len < 18) goto corrupt; + printf("key-id %u digest-%u ", EXTRACT_16BITS(message + 2), len - 2); + for (j = 0; j < len - 2; j++) + printf ("%02X", message[4 + j]); + } + } + break; + default: + if(!vflag) + printf(" unknown"); + else + printf("\n\tUnknown message type %d", type); + } + i += len + 2; + } + return; + + trunc: + printf(" [|babel]"); + return; + + corrupt: + printf(" (corrupt)"); + return; +} diff --git a/freebsd/contrib/tcpdump/print-beep.c b/freebsd/contrib/tcpdump/print-beep.c new file mode 100644 index 00000000..30b5cb0c --- /dev/null +++ b/freebsd/contrib/tcpdump/print-beep.c @@ -0,0 +1,73 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (C) 2000, Richard Sharpe + * + * This software may be distributed either under the terms of the + * BSD-style licence that accompanies tcpdump or under the GNU GPL + * version 2 or later. + * + * print-beep.c + * + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-beep.c,v 1.6 2003-11-16 09:36:13 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#ifdef HAVE_MEMORY_H +#include <memory.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" + +/* Check for a string but not go beyond length + * Return TRUE on match, FALSE otherwise + * + * Looks at the first few chars up to tl1 ... + */ + +static int l_strnstart(const char *, u_int, const char *, u_int); + +static int +l_strnstart(const char *tstr1, u_int tl1, const char *str2, u_int l2) +{ + + if (tl1 > l2) + return 0; + + return (strncmp(tstr1, str2, tl1) == 0 ? 1 : 0); +} + +void +beep_print(const u_char *bp, u_int length) +{ + + if (l_strnstart("MSG", 4, (const char *)bp, length)) /* A REQuest */ + printf(" BEEP MSG"); + else if (l_strnstart("RPY ", 4, (const char *)bp, length)) + printf(" BEEP RPY"); + else if (l_strnstart("ERR ", 4, (const char *)bp, length)) + printf(" BEEP ERR"); + else if (l_strnstart("ANS ", 4, (const char *)bp, length)) + printf(" BEEP ANS"); + else if (l_strnstart("NUL ", 4, (const char *)bp, length)) + printf(" BEEP NUL"); + else if (l_strnstart("SEQ ", 4, (const char *)bp, length)) + printf(" BEEP SEQ"); + else if (l_strnstart("END", 4, (const char *)bp, length)) + printf(" BEEP END"); + else + printf(" BEEP (payload or undecoded)"); +} diff --git a/freebsd/contrib/tcpdump/print-bfd.c b/freebsd/contrib/tcpdump/print-bfd.c new file mode 100644 index 00000000..e6f79e60 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-bfd.c @@ -0,0 +1,285 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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-bfd.c,v 1.10 2006-02-02 06:35:52 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#include "udp.h" + +/* + * Control packet, BFDv0, draft-katz-ward-bfd-01.txt + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Vers | Diag |H|D|P|F| Rsvd | Detect Mult | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | My Discriminator | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Your Discriminator | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Desired Min TX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Required Min RX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Required Min Echo RX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/* + * Control packet, BFDv1, draft-ietf-bfd-base-02.txt + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Vers | Diag |Sta|P|F|C|A|D|R| Detect Mult | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | My Discriminator | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Your Discriminator | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Desired Min TX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Required Min RX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Required Min Echo RX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct bfd_header_t { + u_int8_t version_diag; + u_int8_t flags; + u_int8_t detect_time_multiplier; + u_int8_t length; + u_int8_t my_discriminator[4]; + u_int8_t your_discriminator[4]; + u_int8_t desired_min_tx_interval[4]; + u_int8_t required_min_rx_interval[4]; + u_int8_t required_min_echo_interval[4]; +}; + +/* + * An optional Authentication Header may be present + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Auth Type | Auth Len | Authentication Data... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct bfd_auth_header_t { + u_int8_t auth_type; + u_int8_t auth_len; + u_int8_t auth_data; +}; + +static const struct tok bfd_v1_authentication_values[] = { + { 0, "Reserved" }, + { 1, "Simple Password" }, + { 2, "Keyed MD5" }, + { 3, "Meticulous Keyed MD5" }, + { 4, "Keyed SHA1" }, + { 5, "Meticulous Keyed SHA1" }, + { 0, NULL } +}; + +#define BFD_EXTRACT_VERSION(x) (((x)&0xe0)>>5) +#define BFD_EXTRACT_DIAG(x) ((x)&0x1f) + +static const struct tok bfd_port_values[] = { + { BFD_CONTROL_PORT, "Control" }, + { BFD_ECHO_PORT, "Echo" }, + { 0, NULL } +}; + + +static const struct tok bfd_diag_values[] = { + { 0, "No Diagnostic" }, + { 1, "Control Detection Time Expired" }, + { 2, "Echo Function Failed" }, + { 3, "Neighbor Signaled Session Down" }, + { 4, "Forwarding Plane Reset" }, + { 5, "Path Down" }, + { 6, "Concatenated Path Down" }, + { 7, "Administratively Down" }, + { 8, "Reverse Concatenated Path Down" }, + { 0, NULL } +}; + +static const struct tok bfd_v0_flag_values[] = { + { 0x80, "I Hear You" }, + { 0x40, "Demand" }, + { 0x20, "Poll" }, + { 0x10, "Final" }, + { 0x08, "Reserved" }, + { 0x04, "Reserved" }, + { 0x02, "Reserved" }, + { 0x01, "Reserved" }, + { 0, NULL } +}; + +#define BFD_FLAG_AUTH 0x04 + +static const struct tok bfd_v1_flag_values[] = { + { 0x20, "Poll" }, + { 0x10, "Final" }, + { 0x08, "Control Plane Independent" }, + { BFD_FLAG_AUTH, "Authentication Present" }, + { 0x02, "Demand" }, + { 0x01, "Reserved" }, + { 0, NULL } +}; + +static const struct tok bfd_v1_state_values[] = { + { 0, "AdminDown" }, + { 1, "Down" }, + { 2, "Init" }, + { 3, "Up" }, + { 0, NULL } +}; + +void +bfd_print(register const u_char *pptr, register u_int len, register u_int port) +{ + const struct bfd_header_t *bfd_header; + const struct bfd_auth_header_t *bfd_auth_header; + u_int8_t version = 0; + + bfd_header = (const struct bfd_header_t *)pptr; + if (port == BFD_CONTROL_PORT) { + TCHECK(*bfd_header); + version = BFD_EXTRACT_VERSION(bfd_header->version_diag); + } else if (port == BFD_ECHO_PORT) { + /* Echo is BFD v1 only */ + version = 1; + } + switch ((port << 8) | version) { + + /* BFDv0 */ + case (BFD_CONTROL_PORT << 8): + if (vflag < 1 ) + { + printf("BFDv%u, %s, Flags: [%s], length: %u", + version, + tok2str(bfd_port_values, "unknown (%u)", port), + bittok2str(bfd_v0_flag_values, "none", bfd_header->flags), + len); + return; + } + + printf("BFDv%u, length: %u\n\t%s, Flags: [%s], Diagnostic: %s (0x%02x)", + version, + len, + tok2str(bfd_port_values, "unknown (%u)", port), + bittok2str(bfd_v0_flag_values, "none", bfd_header->flags), + tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(bfd_header->version_diag)), + BFD_EXTRACT_DIAG(bfd_header->version_diag)); + + printf("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", + bfd_header->detect_time_multiplier, + bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000, + bfd_header->length); + + + printf("\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)); + printf(", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)); + printf("\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000); + printf("\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000); + printf("\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000); + break; + + /* BFDv1 */ + case (BFD_CONTROL_PORT << 8 | 1): + if (vflag < 1 ) + { + printf("BFDv%u, %s, State %s, Flags: [%s], length: %u", + version, + tok2str(bfd_port_values, "unknown (%u)", port), + tok2str(bfd_v1_state_values, "unknown (%u)", (bfd_header->flags & 0xc0) >> 6), + bittok2str(bfd_v1_flag_values, "none", bfd_header->flags & 0x3f), + len); + return; + } + + printf("BFDv%u, length: %u\n\t%s, State %s, Flags: [%s], Diagnostic: %s (0x%02x)", + version, + len, + tok2str(bfd_port_values, "unknown (%u)", port), + tok2str(bfd_v1_state_values, "unknown (%u)", (bfd_header->flags & 0xc0) >> 6), + bittok2str(bfd_v1_flag_values, "none", bfd_header->flags & 0x3f), + tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(bfd_header->version_diag)), + BFD_EXTRACT_DIAG(bfd_header->version_diag)); + + printf("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", + bfd_header->detect_time_multiplier, + bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000, + bfd_header->length); + + + printf("\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)); + printf(", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)); + printf("\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000); + printf("\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000); + printf("\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000); + + if (bfd_header->flags & BFD_FLAG_AUTH) { + pptr += sizeof (const struct bfd_header_t); + bfd_auth_header = (const struct bfd_auth_header_t *)pptr; + TCHECK2(*bfd_auth_header, sizeof(const struct bfd_auth_header_t)); + printf("\n\t%s (%u) Authentication, length %u present", + tok2str(bfd_v1_authentication_values,"Unknown",bfd_auth_header->auth_type), + bfd_auth_header->auth_type, + bfd_auth_header->auth_len); + } + break; + + /* BFDv0 */ + case (BFD_ECHO_PORT << 8): /* not yet supported - fall through */ + /* BFDv1 */ + case (BFD_ECHO_PORT << 8 | 1): + + default: + printf("BFD, %s, length: %u", + tok2str(bfd_port_values, "unknown (%u)", port), + len); + if (vflag >= 1) { + if(!print_unknown_data(pptr,"\n\t",len)) + return; + } + break; + } + return; + +trunc: + printf("[|BFD]"); +} diff --git a/freebsd/contrib/tcpdump/print-bgp.c b/freebsd/contrib/tcpdump/print-bgp.c new file mode 100644 index 00000000..f58bc316 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-bgp.c @@ -0,0 +1,2763 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#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 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 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 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 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 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 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 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 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 struct tok bgp_notify_minor_msg_values[] = { + { 1, "Connection Not Synchronized"}, + { 2, "Bad Message Length"}, + { 3, "Bad Message Type"}, + { 0, NULL} +}; + +static 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 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 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 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 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 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 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 struct tok bgp_extd_comm_flag_values[] = { + { 0x8000, "vendor-specific"}, + { 0x4000, "non-transitive"}, + { 0, NULL}, +}; + +static 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 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 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) + return; + + printf(", %s (%u)", + tok2strbuf(bgp_notify_major_values, "Unknown Error", + bgpn.bgpn_major, tokbuf, sizeof(tokbuf)), + bgpn.bgpn_major); + + switch (bgpn.bgpn_major) { + + case BGP_NOTIFY_MAJOR_MSG: + printf(", subcode %s (%u)", + tok2strbuf(bgp_notify_minor_msg_values, "Unknown", + bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), + bgpn.bgpn_minor); + break; + case BGP_NOTIFY_MAJOR_OPEN: + printf(", subcode %s (%u)", + tok2strbuf(bgp_notify_minor_open_values, "Unknown", + bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), + bgpn.bgpn_minor); + break; + case BGP_NOTIFY_MAJOR_UPDATE: + printf(", subcode %s (%u)", + tok2strbuf(bgp_notify_minor_update_values, "Unknown", + bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), + bgpn.bgpn_minor); + break; + case BGP_NOTIFY_MAJOR_CAP: + printf(" subcode %s (%u)", + tok2strbuf(bgp_notify_minor_cap_values, "Unknown", + bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), + bgpn.bgpn_minor); + case BGP_NOTIFY_MAJOR_CEASE: + printf(", subcode %s (%u)", + tok2strbuf(bgp_notify_minor_cease_values, "Unknown", + bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), + bgpn.bgpn_minor); + + /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes + * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES + */ + if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && 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 (len<BGP_ROUTE_REFRESH_SIZE) + return; + + bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr; + + printf("\n\t AFI %s (%u), SAFI %s (%u)", + tok2strbuf(af_values,"Unknown", + /* this stinks but the compiler pads the structure + * weird */ + EXTRACT_16BITS(&bgp_route_refresh_header->afi), + 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: + */ diff --git a/freebsd/contrib/tcpdump/print-bootp.c b/freebsd/contrib/tcpdump/print-bootp.c new file mode 100644 index 00000000..abf8efc0 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-bootp.c @@ -0,0 +1,829 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * Format and print bootp packets. + * + * $FreeBSD$ + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.89 2008-04-22 09:45:08 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "ether.h" +#include "bootp.h" + +static void rfc1048_print(const u_char *); +static void cmu_print(const u_char *); +static char *client_fqdn_flags(u_int flags); + +static char tstr[] = " [|bootp]"; + +static const struct tok bootp_flag_values[] = { + { 0x8000, "Broadcast" }, + { 0, NULL} +}; + +static const struct tok bootp_op_values[] = { + { BOOTPREQUEST, "Request" }, + { BOOTPREPLY, "Reply" }, + { 0, NULL} +}; + +/* + * Print bootp requests + */ +void +bootp_print(register const u_char *cp, u_int length) +{ + register const struct bootp *bp; + static const u_char vm_cmu[4] = VM_CMU; + static const u_char vm_rfc1048[4] = VM_RFC1048; + + bp = (const struct bootp *)cp; + TCHECK(bp->bp_op); + + printf("BOOTP/DHCP, %s", + tok2str(bootp_op_values, "unknown (0x%02x)", bp->bp_op)); + + if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { + TCHECK2(bp->bp_chaddr[0], 6); + printf(" from %s", etheraddr_string(bp->bp_chaddr)); + } + + printf(", length %u", length); + + if (!vflag) + return; + + TCHECK(bp->bp_secs); + + /* The usual hardware address type is 1 (10Mb Ethernet) */ + if (bp->bp_htype != 1) + printf(", htype %d", bp->bp_htype); + + /* The usual length for 10Mb Ethernet address is 6 bytes */ + if (bp->bp_htype != 1 || bp->bp_hlen != 6) + printf(", hlen %d", bp->bp_hlen); + + /* Only print interesting fields */ + if (bp->bp_hops) + printf(", hops %d", bp->bp_hops); + if (bp->bp_xid) + printf(", xid 0x%x", EXTRACT_32BITS(&bp->bp_xid)); + if (bp->bp_secs) + printf(", secs %d", EXTRACT_16BITS(&bp->bp_secs)); + + printf(", Flags [%s]", + bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags))); + if (vflag > 1) + printf(" (0x%04x)", EXTRACT_16BITS(&bp->bp_flags)); + + /* Client's ip address */ + TCHECK(bp->bp_ciaddr); + if (bp->bp_ciaddr.s_addr) + printf("\n\t Client-IP %s", ipaddr_string(&bp->bp_ciaddr)); + + /* 'your' ip address (bootp client) */ + TCHECK(bp->bp_yiaddr); + if (bp->bp_yiaddr.s_addr) + printf("\n\t Your-IP %s", ipaddr_string(&bp->bp_yiaddr)); + + /* Server's ip address */ + TCHECK(bp->bp_siaddr); + if (bp->bp_siaddr.s_addr) + printf("\n\t Server-IP %s", ipaddr_string(&bp->bp_siaddr)); + + /* Gateway's ip address */ + TCHECK(bp->bp_giaddr); + if (bp->bp_giaddr.s_addr) + printf("\n\t Gateway-IP %s", ipaddr_string(&bp->bp_giaddr)); + + /* Client's Ethernet address */ + if (bp->bp_htype == 1 && bp->bp_hlen == 6) { + TCHECK2(bp->bp_chaddr[0], 6); + printf("\n\t Client-Ethernet-Address %s", etheraddr_string(bp->bp_chaddr)); + } + + TCHECK2(bp->bp_sname[0], 1); /* check first char only */ + if (*bp->bp_sname) { + printf("\n\t sname \""); + if (fn_print(bp->bp_sname, snapend)) { + putchar('"'); + fputs(tstr + 1, stdout); + return; + } + putchar('"'); + } + TCHECK2(bp->bp_file[0], 1); /* check first char only */ + if (*bp->bp_file) { + printf("\n\t file \""); + if (fn_print(bp->bp_file, snapend)) { + putchar('"'); + fputs(tstr + 1, stdout); + return; + } + putchar('"'); + } + + /* Decode the vendor buffer */ + TCHECK(bp->bp_vend[0]); + if (memcmp((const char *)bp->bp_vend, vm_rfc1048, + sizeof(u_int32_t)) == 0) + rfc1048_print(bp->bp_vend); + else if (memcmp((const char *)bp->bp_vend, vm_cmu, + sizeof(u_int32_t)) == 0) + cmu_print(bp->bp_vend); + else { + u_int32_t ul; + + ul = EXTRACT_32BITS(&bp->bp_vend); + if (ul != 0) + printf("\n\t Vendor-#0x%x", ul); + } + + return; +trunc: + fputs(tstr, stdout); +} + +/* + * The first character specifies the format to print: + * i - ip address (32 bits) + * p - ip address pairs (32 bits + 32 bits) + * l - long (32 bits) + * L - unsigned long (32 bits) + * s - short (16 bits) + * b - period-seperated decimal bytes (variable length) + * x - colon-seperated hex bytes (variable length) + * a - ascii string (variable length) + * B - on/off (8 bits) + * $ - special (explicit code to handle) + */ +static struct tok tag2str[] = { +/* RFC1048 tags */ + { TAG_PAD, " PAD" }, + { TAG_SUBNET_MASK, "iSubnet-Mask" }, /* subnet mask (RFC950) */ + { TAG_TIME_OFFSET, "LTime-Zone" }, /* seconds from UTC */ + { TAG_GATEWAY, "iDefault-Gateway" }, /* default gateway */ + { TAG_TIME_SERVER, "iTime-Server" }, /* time servers (RFC868) */ + { TAG_NAME_SERVER, "iIEN-Name-Server" }, /* IEN name servers (IEN116) */ + { TAG_DOMAIN_SERVER, "iDomain-Name-Server" }, /* domain name (RFC1035) */ + { TAG_LOG_SERVER, "iLOG" }, /* MIT log servers */ + { TAG_COOKIE_SERVER, "iCS" }, /* cookie servers (RFC865) */ + { TAG_LPR_SERVER, "iLPR-Server" }, /* lpr server (RFC1179) */ + { TAG_IMPRESS_SERVER, "iIM" }, /* impress servers (Imagen) */ + { TAG_RLP_SERVER, "iRL" }, /* resource location (RFC887) */ + { TAG_HOSTNAME, "aHostname" }, /* ascii hostname */ + { TAG_BOOTSIZE, "sBS" }, /* 512 byte blocks */ + { TAG_END, " END" }, +/* RFC1497 tags */ + { TAG_DUMPPATH, "aDP" }, + { TAG_DOMAINNAME, "aDomain-Name" }, + { TAG_SWAP_SERVER, "iSS" }, + { TAG_ROOTPATH, "aRP" }, + { TAG_EXTPATH, "aEP" }, +/* RFC2132 tags */ + { TAG_IP_FORWARD, "BIPF" }, + { TAG_NL_SRCRT, "BSRT" }, + { TAG_PFILTERS, "pPF" }, + { TAG_REASS_SIZE, "sRSZ" }, + { TAG_DEF_TTL, "bTTL" }, + { TAG_MTU_TIMEOUT, "lMTU-Timeout" }, + { TAG_MTU_TABLE, "sMTU-Table" }, + { TAG_INT_MTU, "sMTU" }, + { TAG_LOCAL_SUBNETS, "BLSN" }, + { TAG_BROAD_ADDR, "iBR" }, + { TAG_DO_MASK_DISC, "BMD" }, + { TAG_SUPPLY_MASK, "BMS" }, + { TAG_DO_RDISC, "BRouter-Discovery" }, + { TAG_RTR_SOL_ADDR, "iRSA" }, + { TAG_STATIC_ROUTE, "pStatic-Route" }, + { TAG_USE_TRAILERS, "BUT" }, + { TAG_ARP_TIMEOUT, "lAT" }, + { TAG_ETH_ENCAP, "BIE" }, + { TAG_TCP_TTL, "bTT" }, + { TAG_TCP_KEEPALIVE, "lKI" }, + { TAG_KEEPALIVE_GO, "BKG" }, + { TAG_NIS_DOMAIN, "aYD" }, + { TAG_NIS_SERVERS, "iYS" }, + { TAG_NTP_SERVERS, "iNTP" }, + { TAG_VENDOR_OPTS, "bVendor-Option" }, + { TAG_NETBIOS_NS, "iNetbios-Name-Server" }, + { TAG_NETBIOS_DDS, "iWDD" }, + { TAG_NETBIOS_NODE, "$Netbios-Node" }, + { TAG_NETBIOS_SCOPE, "aNetbios-Scope" }, + { TAG_XWIN_FS, "iXFS" }, + { TAG_XWIN_DM, "iXDM" }, + { TAG_NIS_P_DOMAIN, "sN+D" }, + { TAG_NIS_P_SERVERS, "iN+S" }, + { TAG_MOBILE_HOME, "iMH" }, + { TAG_SMPT_SERVER, "iSMTP" }, + { TAG_POP3_SERVER, "iPOP3" }, + { TAG_NNTP_SERVER, "iNNTP" }, + { TAG_WWW_SERVER, "iWWW" }, + { TAG_FINGER_SERVER, "iFG" }, + { TAG_IRC_SERVER, "iIRC" }, + { TAG_STREETTALK_SRVR, "iSTS" }, + { TAG_STREETTALK_STDA, "iSTDA" }, + { TAG_REQUESTED_IP, "iRequested-IP" }, + { TAG_IP_LEASE, "lLease-Time" }, + { TAG_OPT_OVERLOAD, "$OO" }, + { TAG_TFTP_SERVER, "aTFTP" }, + { TAG_BOOTFILENAME, "aBF" }, + { TAG_DHCP_MESSAGE, " DHCP-Message" }, + { TAG_SERVER_ID, "iServer-ID" }, + { TAG_PARM_REQUEST, "bParameter-Request" }, + { TAG_MESSAGE, "aMSG" }, + { TAG_MAX_MSG_SIZE, "sMSZ" }, + { TAG_RENEWAL_TIME, "lRN" }, + { TAG_REBIND_TIME, "lRB" }, + { TAG_VENDOR_CLASS, "aVendor-Class" }, + { TAG_CLIENT_ID, "$Client-ID" }, +/* RFC 2485 */ + { TAG_OPEN_GROUP_UAP, "aUAP" }, +/* RFC 2563 */ + { TAG_DISABLE_AUTOCONF, "BNOAUTO" }, +/* RFC 2610 */ + { TAG_SLP_DA, "bSLP-DA" }, /*"b" is a little wrong */ + { TAG_SLP_SCOPE, "bSLP-SCOPE" }, /*"b" is a little wrong */ +/* RFC 2937 */ + { TAG_NS_SEARCH, "sNSSEARCH" }, /* XXX 's' */ +/* RFC 3011 */ + { TAG_IP4_SUBNET_SELECT, "iSUBNET" }, +/* RFC 3442 */ + { TAG_CLASSLESS_STATIC_RT, "$Classless-Static-Route" }, + { TAG_CLASSLESS_STA_RT_MS, "$Classless-Static-Route-Microsoft" }, +/* http://www.iana.org/assignments/bootp-dhcp-extensions/index.htm */ + { TAG_USER_CLASS, "aCLASS" }, + { TAG_SLP_NAMING_AUTH, "aSLP-NA" }, + { TAG_CLIENT_FQDN, "$FQDN" }, + { TAG_AGENT_CIRCUIT, "$Agent-Information" }, + { TAG_AGENT_REMOTE, "bARMT" }, + { TAG_AGENT_MASK, "bAMSK" }, + { TAG_TZ_STRING, "aTZSTR" }, + { TAG_FQDN_OPTION, "bFQDNS" }, /* XXX 'b' */ + { TAG_AUTH, "bAUTH" }, /* XXX 'b' */ + { TAG_VINES_SERVERS, "iVINES" }, + { TAG_SERVER_RANK, "sRANK" }, + { TAG_CLIENT_ARCH, "sARCH" }, + { TAG_CLIENT_NDI, "bNDI" }, /* XXX 'b' */ + { TAG_CLIENT_GUID, "bGUID" }, /* XXX 'b' */ + { TAG_LDAP_URL, "aLDAP" }, + { TAG_6OVER4, "i6o4" }, + { TAG_PRINTER_NAME, "aPRTR" }, + { TAG_MDHCP_SERVER, "bMDHCP" }, /* XXX 'b' */ + { TAG_IPX_COMPAT, "bIPX" }, /* XXX 'b' */ + { TAG_NETINFO_PARENT, "iNI" }, + { TAG_NETINFO_PARENT_TAG, "aNITAG" }, + { TAG_URL, "aURL" }, + { TAG_FAILOVER, "bFAIL" }, /* XXX 'b' */ + { 0, NULL } +}; +/* 2-byte extended tags */ +static struct tok xtag2str[] = { + { 0, NULL } +}; + +/* DHCP "options overload" types */ +static struct tok oo2str[] = { + { 1, "file" }, + { 2, "sname" }, + { 3, "file+sname" }, + { 0, NULL } +}; + +/* NETBIOS over TCP/IP node type options */ +static struct tok nbo2str[] = { + { 0x1, "b-node" }, + { 0x2, "p-node" }, + { 0x4, "m-node" }, + { 0x8, "h-node" }, + { 0, NULL } +}; + +/* ARP Hardware types, for Client-ID option */ +static struct tok arp2str[] = { + { 0x1, "ether" }, + { 0x6, "ieee802" }, + { 0x7, "arcnet" }, + { 0xf, "frelay" }, + { 0x17, "strip" }, + { 0x18, "ieee1394" }, + { 0, NULL } +}; + +static struct tok dhcp_msg_values[] = { + { DHCPDISCOVER, "Discover" }, + { DHCPOFFER, "Offer" }, + { DHCPREQUEST, "Request" }, + { DHCPDECLINE, "Decline" }, + { DHCPACK, "ACK" }, + { DHCPNAK, "NACK" }, + { DHCPRELEASE, "Release" }, + { DHCPINFORM, "Inform" }, + { 0, NULL } +}; + +#define AGENT_SUBOPTION_CIRCUIT_ID 1 /* RFC 3046 */ +#define AGENT_SUBOPTION_REMOTE_ID 2 /* RFC 3046 */ +#define AGENT_SUBOPTION_SUBSCRIBER_ID 6 /* RFC 3993 */ +static struct tok agent_suboption_values[] = { + { AGENT_SUBOPTION_CIRCUIT_ID, "Circuit-ID" }, + { AGENT_SUBOPTION_REMOTE_ID, "Remote-ID" }, + { AGENT_SUBOPTION_SUBSCRIBER_ID, "Subscriber-ID" }, + { 0, NULL } +}; + + +static void +rfc1048_print(register const u_char *bp) +{ + register u_int16_t tag; + register u_int len; + register const char *cp; + register char c; + int first, idx; + u_int32_t ul; + u_int16_t us; + u_int8_t uc, subopt, suboptlen; + + printf("\n\t Vendor-rfc1048 Extensions"); + + /* Step over magic cookie */ + printf("\n\t Magic Cookie 0x%08x", EXTRACT_32BITS(bp)); + bp += sizeof(int32_t); + + /* Loop while we there is a tag left in the buffer */ + while (TTEST2(*bp, 1)) { + tag = *bp++; + if (tag == TAG_PAD && vflag < 3) + continue; + if (tag == TAG_END && vflag < 3) + return; + if (tag == TAG_EXTENDED_OPTION) { + TCHECK2(*(bp + 1), 2); + tag = EXTRACT_16BITS(bp + 1); + /* XXX we don't know yet if the IANA will + * preclude overlap of 1-byte and 2-byte spaces. + * If not, we need to offset tag after this step. + */ + cp = tok2str(xtag2str, "?xT%u", tag); + } else + cp = tok2str(tag2str, "?T%u", tag); + c = *cp++; + + if (tag == TAG_PAD || tag == TAG_END) + len = 0; + else { + /* Get the length; check for truncation */ + TCHECK2(*bp, 1); + len = *bp++; + } + + printf("\n\t %s Option %u, length %u%s", cp, tag, len, + len > 0 ? ": " : ""); + + if (tag == TAG_PAD && vflag > 2) { + u_int ntag = 1; + while (TTEST2(*bp, 1) && *bp == TAG_PAD) { + bp++; + ntag++; + } + if (ntag > 1) + printf(", occurs %u", ntag); + } + + if (!TTEST2(*bp, len)) { + printf("[|rfc1048 %u]", len); + return; + } + + if (tag == TAG_DHCP_MESSAGE && len == 1) { + uc = *bp++; + printf("%s", tok2str(dhcp_msg_values, "Unknown (%u)", uc)); + continue; + } + + if (tag == TAG_PARM_REQUEST) { + idx = 0; + while (len-- > 0) { + uc = *bp++; + cp = tok2str(tag2str, "?Option %u", uc); + if (idx % 4 == 0) + printf("\n\t "); + else + printf(", "); + printf("%s", cp + 1); + idx++; + } + continue; + } + + if (tag == TAG_EXTENDED_REQUEST) { + first = 1; + while (len > 1) { + len -= 2; + us = EXTRACT_16BITS(bp); + bp += 2; + cp = tok2str(xtag2str, "?xT%u", us); + if (!first) + putchar('+'); + printf("%s", cp + 1); + first = 0; + } + continue; + } + + /* Print data */ + if (c == '?') { + /* Base default formats for unknown tags on data size */ + if (len & 1) + c = 'b'; + else if (len & 2) + c = 's'; + else + c = 'l'; + } + first = 1; + switch (c) { + + case 'a': + /* ascii strings */ + putchar('"'); + if (fn_printn(bp, len, snapend)) { + putchar('"'); + goto trunc; + } + putchar('"'); + bp += len; + len = 0; + break; + + case 'i': + case 'l': + case 'L': + /* ip addresses/32-bit words */ + while (len >= sizeof(ul)) { + if (!first) + putchar(','); + ul = EXTRACT_32BITS(bp); + if (c == 'i') { + ul = htonl(ul); + printf("%s", ipaddr_string(&ul)); + } else if (c == 'L') + printf("%d", ul); + else + printf("%u", ul); + bp += sizeof(ul); + len -= sizeof(ul); + first = 0; + } + break; + + case 'p': + /* IP address pairs */ + while (len >= 2*sizeof(ul)) { + if (!first) + putchar(','); + memcpy((char *)&ul, (const char *)bp, sizeof(ul)); + printf("(%s:", ipaddr_string(&ul)); + bp += sizeof(ul); + memcpy((char *)&ul, (const char *)bp, sizeof(ul)); + printf("%s)", ipaddr_string(&ul)); + bp += sizeof(ul); + len -= 2*sizeof(ul); + first = 0; + } + break; + + case 's': + /* shorts */ + while (len >= sizeof(us)) { + if (!first) + putchar(','); + us = EXTRACT_16BITS(bp); + printf("%u", us); + bp += sizeof(us); + len -= sizeof(us); + first = 0; + } + break; + + case 'B': + /* boolean */ + while (len > 0) { + if (!first) + putchar(','); + switch (*bp) { + case 0: + putchar('N'); + break; + case 1: + putchar('Y'); + break; + default: + printf("%u?", *bp); + break; + } + ++bp; + --len; + first = 0; + } + break; + + case 'b': + case 'x': + default: + /* Bytes */ + while (len > 0) { + if (!first) + putchar(c == 'x' ? ':' : '.'); + if (c == 'x') + printf("%02x", *bp); + else + printf("%u", *bp); + ++bp; + --len; + first = 0; + } + break; + + case '$': + /* Guys we can't handle with one of the usual cases */ + switch (tag) { + + case TAG_NETBIOS_NODE: + /* this option should be at least 1 byte long */ + if (len < 1) { + printf("ERROR: option %u len %u < 1 bytes", + TAG_NETBIOS_NODE, len); + break; + } + tag = *bp++; + --len; + fputs(tok2str(nbo2str, NULL, tag), stdout); + break; + + case TAG_OPT_OVERLOAD: + /* this option should be at least 1 byte long */ + if (len < 1) { + printf("ERROR: option %u len %u < 1 bytes", + TAG_OPT_OVERLOAD, len); + break; + } + tag = *bp++; + --len; + fputs(tok2str(oo2str, NULL, tag), stdout); + break; + + case TAG_CLIENT_FQDN: + /* this option should be at least 3 bytes long */ + if (len < 3) { + printf("ERROR: option %u len %u < 3 bytes", + TAG_CLIENT_FQDN, len); + bp += len; + len = 0; + break; + } + if (*bp) + printf("[%s] ", client_fqdn_flags(*bp)); + bp++; + if (*bp || *(bp+1)) + printf("%u/%u ", *bp, *(bp+1)); + bp += 2; + putchar('"'); + if (fn_printn(bp, len - 3, snapend)) { + putchar('"'); + goto trunc; + } + putchar('"'); + bp += len - 3; + len = 0; + break; + + case TAG_CLIENT_ID: + { int type; + + /* this option should be at least 1 byte long */ + if (len < 1) { + printf("ERROR: option %u len %u < 1 bytes", + TAG_CLIENT_ID, len); + break; + } + type = *bp++; + len--; + if (type == 0) { + putchar('"'); + if (fn_printn(bp, len, snapend)) { + putchar('"'); + goto trunc; + } + putchar('"'); + bp += len; + len = 0; + break; + } else { + printf("%s ", tok2str(arp2str, "hardware-type %u,", type)); + while (len > 0) { + if (!first) + putchar(':'); + printf("%02x", *bp); + ++bp; + --len; + first = 0; + } + } + break; + } + + case TAG_AGENT_CIRCUIT: + while (len >= 2) { + subopt = *bp++; + suboptlen = *bp++; + len -= 2; + if (suboptlen > len) { + printf("\n\t %s SubOption %u, length %u: length goes past end of option", + tok2str(agent_suboption_values, "Unknown", subopt), + subopt, + suboptlen); + bp += len; + len = 0; + break; + } + printf("\n\t %s SubOption %u, length %u: ", + tok2str(agent_suboption_values, "Unknown", subopt), + subopt, + suboptlen); + switch (subopt) { + + case AGENT_SUBOPTION_CIRCUIT_ID: /* fall through */ + case AGENT_SUBOPTION_REMOTE_ID: + case AGENT_SUBOPTION_SUBSCRIBER_ID: + fn_printn(bp, suboptlen, NULL); + break; + + default: + print_unknown_data(bp, "\n\t\t", suboptlen); + } + + len -= suboptlen; + bp += suboptlen; + } + break; + + case TAG_CLASSLESS_STATIC_RT: + case TAG_CLASSLESS_STA_RT_MS: + { + u_int mask_width, significant_octets, i; + + /* this option should be at least 5 bytes long */ + if (len < 5) { + printf("ERROR: option %u len %u < 5 bytes", + TAG_CLASSLESS_STATIC_RT, len); + bp += len; + len = 0; + break; + } + while (len > 0) { + if (!first) + putchar(','); + mask_width = *bp++; + len--; + /* mask_width <= 32 */ + if (mask_width > 32) { + printf("[ERROR: Mask width (%d) > 32]", mask_width); + bp += len; + len = 0; + break; + } + significant_octets = (mask_width + 7) / 8; + /* significant octets + router(4) */ + if (len < significant_octets + 4) { + printf("[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4); + bp += len; + len = 0; + break; + } + putchar('('); + if (mask_width == 0) + printf("default"); + else { + for (i = 0; i < significant_octets ; i++) { + if (i > 0) + putchar('.'); + printf("%d", *bp++); + } + for (i = significant_octets ; i < 4 ; i++) + printf(".0"); + printf("/%d", mask_width); + } + memcpy((char *)&ul, (const char *)bp, sizeof(ul)); + printf(":%s)", ipaddr_string(&ul)); + bp += sizeof(ul); + len -= (significant_octets + 4); + first = 0; + } + } + break; + + default: + printf("[unknown special tag %u, size %u]", + tag, len); + bp += len; + len = 0; + break; + } + break; + } + /* Data left over? */ + if (len) { + printf("\n\t trailing data length %u", len); + bp += len; + } + } + return; +trunc: + printf("|[rfc1048]"); +} + +static void +cmu_print(register const u_char *bp) +{ + register const struct cmu_vend *cmu; + +#define PRINTCMUADDR(m, s) { TCHECK(cmu->m); \ + if (cmu->m.s_addr != 0) \ + printf(" %s:%s", s, ipaddr_string(&cmu->m.s_addr)); } + + printf(" vend-cmu"); + cmu = (const struct cmu_vend *)bp; + + /* Only print if there are unknown bits */ + TCHECK(cmu->v_flags); + if ((cmu->v_flags & ~(VF_SMASK)) != 0) + printf(" F:0x%x", cmu->v_flags); + PRINTCMUADDR(v_dgate, "DG"); + PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*"); + PRINTCMUADDR(v_dns1, "NS1"); + PRINTCMUADDR(v_dns2, "NS2"); + PRINTCMUADDR(v_ins1, "IEN1"); + PRINTCMUADDR(v_ins2, "IEN2"); + PRINTCMUADDR(v_ts1, "TS1"); + PRINTCMUADDR(v_ts2, "TS2"); + return; + +trunc: + fputs(tstr, stdout); +#undef PRINTCMUADDR +} + +static char * +client_fqdn_flags(u_int flags) +{ + static char buf[8+1]; + int i = 0; + + if (flags & CLIENT_FQDN_FLAGS_S) + buf[i++] = 'S'; + if (flags & CLIENT_FQDN_FLAGS_O) + buf[i++] = 'O'; + if (flags & CLIENT_FQDN_FLAGS_E) + buf[i++] = 'E'; + if (flags & CLIENT_FQDN_FLAGS_N) + buf[i++] = 'N'; + buf[i] = '\0'; + + return buf; +} diff --git a/freebsd/contrib/tcpdump/print-bt.c b/freebsd/contrib/tcpdump/print-bt.c new file mode 100644 index 00000000..3fdee7aa --- /dev/null +++ b/freebsd/contrib/tcpdump/print-bt.c @@ -0,0 +1,81 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2007 + * paolo.abeni@email.it 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 Paolo Abeni.'' + * The name of author 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. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-bt.c,v 1.2 2008-09-25 21:45:50 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) +#include <pcap/bluetooth.h> + +#define BT_HDRLEN sizeof(pcap_bluetooth_h4_header) +/* + * This is the top level routine of the printer. 'p' points + * to the bluetooth 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 +bt_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int length = h->len; + u_int caplen = h->caplen; + const pcap_bluetooth_h4_header* hdr = (const pcap_bluetooth_h4_header*)p; + + if (caplen < BT_HDRLEN) { + printf("[|bt]"); + return (BT_HDRLEN); + } + caplen -= BT_HDRLEN; + length -= BT_HDRLEN; + p += BT_HDRLEN; + if (eflag) + (void)printf("hci length %d, direction %s, ", length, (EXTRACT_32BITS(&hdr->direction)&0x1)?"in":"out"); + + if (!suppress_default_print) + default_print(p, caplen); + + return (BT_HDRLEN); +} +#endif + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-carp.c b/freebsd/contrib/tcpdump/print-carp.c new file mode 100644 index 00000000..e58c4c85 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-carp.c @@ -0,0 +1,90 @@ +#include <machine/rtems-bsd-user-space.h> + +/* $OpenBSD: print-carp.c,v 1.6 2009/10/27 23:59:55 deraadt Exp $ */ + +/* + * Copyright (c) 2000 William C. Fenner. + * All rights reserved. + * + * Kevin Steves <ks@hp.se> July 2000 + * Modified to: + * - print version, type string and packet length + * - print IP address count if > 1 (-v) + * - verify checksum (-v) + * - print authentication string (-v) + * + * Copyright (c) 2011 Advanced Computing Technologies + * George V. Neille-Neil + * + * Modified to: + * - work correctly with CARP + * - compile into the latest tcpdump + * - print out the counter + * + * 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. + * The name of William C. Fenner 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. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <netinet/in.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +void +carp_print(register const u_char *bp, register u_int len, int ttl) +{ + int version, type; + const char *type_s; + + TCHECK(bp[0]); + version = (bp[0] & 0xf0) >> 4; + type = bp[0] & 0x0f; + if (type == 1) + type_s = "advertise"; + else + type_s = "unknown"; + printf("CARPv%d-%s %d: ", version, type_s, len); + if (ttl != 255) + printf("[ttl=%d!] ", ttl); + if (version != 2 || type != 1) + return; + TCHECK(bp[2]); + TCHECK(bp[5]); + printf("vhid=%d advbase=%d advskew=%d authlen=%d ", + bp[1], bp[5], bp[2], bp[3]); + if (vflag) { + struct cksum_vec vec[1]; + vec[0].ptr = (const u_int8_t *)bp; + vec[0].len = len; + if (TTEST2(bp[0], len) && in_cksum(vec, 1)) + printf(" (bad carp cksum %x!)", + EXTRACT_16BITS(&bp[6])); + } + printf("counter=%" PRIu64, EXTRACT_64BITS(&bp[8])); + + return; +trunc: + printf("[|carp]"); +} diff --git a/freebsd/contrib/tcpdump/print-cdp.c b/freebsd/contrib/tcpdump/print-cdp.c new file mode 100644 index 00000000..3370cdb5 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-cdp.c @@ -0,0 +1,381 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * Code by Gert Doering, SpaceNet GmbH, gert@space.net + * + * Reference documentation: + * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-cdp.c,v 1.25 2004-10-07 14:53:11 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ +#include "nlpid.h" + +#define CDP_HEADER_LEN 4 + +static struct tok cdp_tlv_values[] = { + { 0x01, "Device-ID"}, + { 0x02, "Address"}, + { 0x03, "Port-ID"}, + { 0x04, "Capability"}, + { 0x05, "Version String"}, + { 0x06, "Platform"}, + { 0x07, "Prefixes"}, + { 0x08, "Protocol-Hello option"}, + { 0x09, "VTP Management Domain"}, + { 0x0a, "Native VLAN ID"}, + { 0x0b, "Duplex"}, + { 0x0e, "ATA-186 VoIP VLAN request"}, + { 0x0f, "ATA-186 VoIP VLAN assignment"}, + { 0x10, "power consumption"}, + { 0x11, "MTU"}, + { 0x12, "AVVID trust bitmap"}, + { 0x13, "AVVID untrusted ports CoS"}, + { 0x14, "System Name"}, + { 0x15, "System Object ID (not decoded)"}, + { 0x16, "Management Addresses"}, + { 0x17, "Physical Location"}, + { 0, NULL} +}; + +static struct tok cdp_capability_values[] = { + { 0x01, "Router" }, + { 0x02, "Transparent Bridge" }, + { 0x04, "Source Route Bridge" }, + { 0x08, "L2 Switch" }, + { 0x10, "L3 capable" }, + { 0x20, "IGMP snooping" }, + { 0x40, "L1 capable" }, + { 0, NULL } +}; + +static int cdp_print_addr(const u_char *, int); +static int cdp_print_prefixes(const u_char *, int); +static unsigned long cdp_get_number(const u_char *, int); + +void +cdp_print(const u_char *pptr, u_int length, u_int caplen) +{ + int type, len, i, j; + const u_char *tptr; + + if (caplen < CDP_HEADER_LEN) { + (void)printf("[|cdp]"); + return; + } + + tptr = pptr; /* temporary pointer */ + + if (!TTEST2(*tptr, CDP_HEADER_LEN)) + goto trunc; + printf("CDPv%u, ttl: %us", *tptr, *(tptr+1)); + if (vflag) + printf(", checksum: %u (unverified), length %u", EXTRACT_16BITS(tptr), length); + tptr += CDP_HEADER_LEN; + + while (tptr < (pptr+length)) { + + if (!TTEST2(*tptr, 4)) /* read out Type and Length */ + goto trunc; + type = EXTRACT_16BITS(tptr); + len = EXTRACT_16BITS(tptr+2); /* object length includes the 4 bytes header length */ + tptr += 4; + len -= 4; + + if (!TTEST2(*tptr, len)) + goto trunc; + + if (vflag || type == 1) { /* in non-verbose mode just print Device-ID */ + + if (vflag) + printf("\n\t%s (0x%02x), length: %u byte%s: ", + tok2str(cdp_tlv_values,"unknown field type", type), + type, + len, + PLURAL_SUFFIX(len)); /* plural */ + + switch (type) { + + case 0x01: /* Device-ID */ + if (!vflag) + printf(", Device-ID "); + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); + break; + case 0x02: /* Address */ + if (cdp_print_addr(tptr, len) < 0) + goto trunc; + break; + case 0x03: /* Port-ID */ + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); + break; + case 0x04: /* Capabilities */ + printf("(0x%08x): %s", + EXTRACT_32BITS(tptr), + bittok2str(cdp_capability_values, "none",EXTRACT_32BITS(tptr))); + break; + case 0x05: /* Version */ + printf("\n\t "); + for (i=0;i<len;i++) { + j = *(tptr+i); + putchar(j); + if (j == 0x0a) /* lets rework the version string to get a nice identation */ + printf("\t "); + } + break; + case 0x06: /* Platform */ + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); + break; + case 0x07: /* Prefixes */ + if (cdp_print_prefixes(tptr, len) < 0) + goto trunc; + break; + case 0x08: /* Protocol Hello Option - not documented */ + break; + case 0x09: /* VTP Mgmt Domain - not documented */ + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); + break; + case 0x0a: /* Native VLAN ID - not documented */ + printf("%d",EXTRACT_16BITS(tptr)); + break; + case 0x0b: /* Duplex - not documented */ + printf("%s", *(tptr) ? "full": "half"); + break; + + /* http://www.cisco.com/univercd/cc/td/doc/product/voice/ata/atarn/186rn21m.htm + * plus more details from other sources + */ + case 0x0e: /* ATA-186 VoIP VLAN request - incomplete doc. */ + printf("app %d, vlan %d", + *(tptr), EXTRACT_16BITS(tptr+1)); + break; + case 0x10: /* ATA-186 VoIP VLAN assignment - incomplete doc. */ + printf("%1.2fW", + cdp_get_number(tptr, len)/1000.0 ); + break; + case 0x11: /* MTU - not documented */ + printf("%u bytes", EXTRACT_32BITS(tptr)); + break; + case 0x12: /* AVVID trust bitmap - not documented */ + printf("0x%02x", *(tptr) ); + break; + case 0x13: /* AVVID untrusted port CoS - not documented */ + printf("0x%02x", *(tptr)); + break; + case 0x14: /* System Name - not documented */ + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); + break; + case 0x16: /* System Object ID - not documented */ + if (cdp_print_addr(tptr, len) < 0) + goto trunc; + break; + case 0x17: /* Physical Location - not documented */ + printf("0x%02x", *(tptr)); + if (len > 1) { + printf("/"); + fn_printn(tptr + 1, len - 1, NULL); + } + break; + default: + print_unknown_data(tptr,"\n\t ",len); + break; + } + } + /* avoid infinite loop */ + if (len == 0) + break; + tptr = tptr+len; + } + if (vflag < 1) + printf(", length %u",caplen); + + return; +trunc: + printf("[|cdp]"); +} + +/* + * Protocol type values. + * + * PT_NLPID means that the protocol type field contains an OSI NLPID. + * + * PT_IEEE_802_2 means that the protocol type field contains an IEEE 802.2 + * LLC header that specifies that the payload is for that protocol. + */ +#define PT_NLPID 1 /* OSI NLPID */ +#define PT_IEEE_802_2 2 /* IEEE 802.2 LLC header */ + +static int +cdp_print_addr(const u_char * p, int l) +{ + int pt, pl, al, num; + const u_char *endp = p + l; +#ifdef INET6 + static u_char prot_ipv6[] = { + 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x86, 0xdd + }; +#endif + + TCHECK2(*p, 2); + num = EXTRACT_32BITS(p); + p += 4; + + while (p < endp && num >= 0) { + TCHECK2(*p, 2); + if (p + 2 > endp) + goto trunc; + pt = p[0]; /* type of "protocol" field */ + pl = p[1]; /* length of "protocol" field */ + p += 2; + + TCHECK2(p[pl], 2); + if (p + pl + 2 > endp) + goto trunc; + al = EXTRACT_16BITS(&p[pl]); /* address length */ + + if (pt == PT_NLPID && pl == 1 && *p == NLPID_IP && al == 4) { + /* + * IPv4: protocol type = NLPID, protocol length = 1 + * (1-byte NLPID), protocol = 0xcc (NLPID for IPv4), + * address length = 4 + */ + p += 3; + + TCHECK2(*p, 4); + if (p + 4 > endp) + goto trunc; + printf("IPv4 (%u) %s", + num, + ipaddr_string(p)); + p += 4; + } +#ifdef INET6 + else if (pt == PT_IEEE_802_2 && pl == 8 && + memcmp(p, prot_ipv6, 8) == 0 && al == 16) { + /* + * IPv6: protocol type = IEEE 802.2 header, + * protocol length = 8 (size of LLC+SNAP header), + * protocol = LLC+SNAP header with the IPv6 + * Ethertype, address length = 16 + */ + p += 10; + TCHECK2(*p, al); + if (p + al > endp) + goto trunc; + + printf("IPv6 (%u) %s", + num, + ip6addr_string(p)); + p += al; + } +#endif + else { + /* + * Generic case: just print raw data + */ + TCHECK2(*p, pl); + if (p + pl > endp) + goto trunc; + printf("pt=0x%02x, pl=%d, pb=", *(p - 2), pl); + while (pl-- > 0) + printf(" %02x", *p++); + TCHECK2(*p, 2); + if (p + 2 > endp) + goto trunc; + al = (*p << 8) + *(p + 1); + printf(", al=%d, a=", al); + p += 2; + TCHECK2(*p, al); + if (p + al > endp) + goto trunc; + while (al-- > 0) + printf(" %02x", *p++); + } + num--; + if (num) + printf(" "); + } + + return 0; + +trunc: + return -1; +} + + +static int +cdp_print_prefixes(const u_char * p, int l) +{ + if (l % 5) + goto trunc; + + printf(" IPv4 Prefixes (%d):", l / 5); + + while (l > 0) { + printf(" %u.%u.%u.%u/%u", p[0], p[1], p[2], p[3], p[4]); + l -= 5; + p += 5; + } + + return 0; + +trunc: + return -1; +} + +/* read in a <n>-byte number, MSB first + * (of course this can handle max sizeof(long)) + */ +static unsigned long cdp_get_number(const u_char * p, int l) +{ + unsigned long res=0; + while( l>0 ) + { + res = (res<<8) + *p; + p++; l--; + } + return res; +} diff --git a/freebsd/contrib/tcpdump/print-cfm.c b/freebsd/contrib/tcpdump/print-cfm.c new file mode 100644 index 00000000..4db453a4 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-cfm.c @@ -0,0 +1,647 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 Connectivity Fault Management Protocols as per 802.1ag. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-cfm.c,v 1.5 2007-07-24 16:01:42 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "ether.h" +#include "addrtoname.h" +#include "oui.h" +#include "af.h" + +/* + * Prototypes + */ +const char * cfm_egress_id_string(register const u_char *); +int cfm_mgmt_addr_print(register const u_char *); + +struct cfm_common_header_t { + u_int8_t mdlevel_version; + u_int8_t opcode; + u_int8_t flags; + u_int8_t first_tlv_offset; +}; + +#define CFM_VERSION 0 +#define CFM_EXTRACT_VERSION(x) (((x)&0x1f)) +#define CFM_EXTRACT_MD_LEVEL(x) (((x)&0xe0)>>5) + +#define CFM_OPCODE_CCM 1 +#define CFM_OPCODE_LBR 2 +#define CFM_OPCODE_LBM 3 +#define CFM_OPCODE_LTR 4 +#define CFM_OPCODE_LTM 5 + +static const struct tok cfm_opcode_values[] = { + { CFM_OPCODE_CCM, "Continouity Check Message"}, + { CFM_OPCODE_LBR, "Loopback Reply"}, + { CFM_OPCODE_LBM, "Loopback Message"}, + { CFM_OPCODE_LTR, "Linktrace Reply"}, + { CFM_OPCODE_LTM, "Linktrace Message"}, + { 0, NULL} +}; + +/* + * Message Formats. + */ +struct cfm_ccm_t { + u_int8_t sequence[4]; + u_int8_t ma_epi[2]; + u_int8_t md_nameformat; + u_int8_t md_namelength; + u_int8_t md_name[46]; /* md name and short ma name */ + u_int8_t reserved_itu[16]; + u_int8_t reserved[6]; +}; + +/* + * Timer Bases for the CCM Interval field. + * Expressed in units of seconds. + */ +const float ccm_interval_base[8] = {0, 0.003333, 0.01, 0.1, 1, 10, 60, 600}; +#define CCM_INTERVAL_MIN_MULTIPLIER 3.25 +#define CCM_INTERVAL_MAX_MULTIPLIER 3.5 + +#define CFM_CCM_RDI_FLAG 0x80 +#define CFM_EXTRACT_CCM_INTERVAL(x) (((x)&0x07)) + +#define CFM_CCM_MD_FORMAT_8021 0 +#define CFM_CCM_MD_FORMAT_NONE 1 +#define CFM_CCM_MD_FORMAT_DNS 2 +#define CFM_CCM_MD_FORMAT_MAC 3 +#define CFM_CCM_MD_FORMAT_CHAR 4 + +static const struct tok cfm_md_nameformat_values[] = { + { CFM_CCM_MD_FORMAT_8021, "IEEE 802.1"}, + { CFM_CCM_MD_FORMAT_NONE, "No MD Name present"}, + { CFM_CCM_MD_FORMAT_DNS, "DNS string"}, + { CFM_CCM_MD_FORMAT_MAC, "MAC + 16Bit Integer"}, + { CFM_CCM_MD_FORMAT_CHAR, "Character string"}, + { 0, NULL} +}; + +#define CFM_CCM_MA_FORMAT_8021 0 +#define CFM_CCM_MA_FORMAT_VID 1 +#define CFM_CCM_MA_FORMAT_CHAR 2 +#define CFM_CCM_MA_FORMAT_INT 3 +#define CFM_CCM_MA_FORMAT_VPN 4 + +static const struct tok cfm_ma_nameformat_values[] = { + { CFM_CCM_MA_FORMAT_8021, "IEEE 802.1"}, + { CFM_CCM_MA_FORMAT_VID, "Primary VID"}, + { CFM_CCM_MA_FORMAT_CHAR, "Character string"}, + { CFM_CCM_MA_FORMAT_INT, "16Bit Integer"}, + { CFM_CCM_MA_FORMAT_VPN, "RFC2685 VPN-ID"}, + { 0, NULL} +}; + +struct cfm_lbm_t { + u_int8_t transaction_id[4]; + u_int8_t reserved[4]; +}; + +struct cfm_ltm_t { + u_int8_t transaction_id[4]; + u_int8_t egress_id[8]; + u_int8_t ttl; + u_int8_t original_mac[ETHER_ADDR_LEN]; + u_int8_t target_mac[ETHER_ADDR_LEN]; + u_int8_t reserved[3]; +}; + +static const struct tok cfm_ltm_flag_values[] = { + { 0x80, "Use Forwarding-DB only"}, + { 0, NULL} +}; + +struct cfm_ltr_t { + u_int8_t transaction_id[4]; + u_int8_t last_egress_id[8]; + u_int8_t next_egress_id[8]; + u_int8_t ttl; + u_int8_t replay_action; + u_int8_t reserved[6]; +}; + +static const struct tok cfm_ltr_flag_values[] = { + { 0x80, "Forwarded"}, + { 0x40, "Terminal MEP"}, + { 0, NULL} +}; + +static const struct tok cfm_ltr_replay_action_values[] = { + { 1, "Exact Match"}, + { 2, "Filtering DB"}, + { 3, "MIP CCM DB"}, + { 0, NULL} +}; + + +#define CFM_TLV_END 0 +#define CFM_TLV_SENDER_ID 1 +#define CFM_TLV_PORT_STATUS 2 +#define CFM_TLV_INTERFACE_STATUS 3 +#define CFM_TLV_DATA 4 +#define CFM_TLV_REPLY_INGRESS 5 +#define CFM_TLV_REPLY_EGRESS 6 +#define CFM_TLV_PRIVATE 31 + +static const struct tok cfm_tlv_values[] = { + { CFM_TLV_END, "End"}, + { CFM_TLV_SENDER_ID, "Sender ID"}, + { CFM_TLV_PORT_STATUS, "Port status"}, + { CFM_TLV_INTERFACE_STATUS, "Interface status"}, + { CFM_TLV_DATA, "Data"}, + { CFM_TLV_REPLY_INGRESS, "Reply Ingress"}, + { CFM_TLV_REPLY_EGRESS, "Reply Egress"}, + { CFM_TLV_PRIVATE, "Organization Specific"}, + { 0, NULL} +}; + +/* + * TLVs + */ + +struct cfm_tlv_header_t { + u_int8_t type; + u_int8_t length[2]; +}; + +/* FIXME define TLV formats */ + +static const struct tok cfm_tlv_port_status_values[] = { + { 1, "Blocked"}, + { 2, "Up"}, + { 0, NULL} +}; + +static const struct tok cfm_tlv_interface_status_values[] = { + { 1, "Up"}, + { 2, "Down"}, + { 3, "Testing"}, + { 5, "Dormant"}, + { 6, "not present"}, + { 7, "lower Layer down"}, + { 0, NULL} +}; + +#define CFM_CHASSIS_ID_CHASSIS_COMPONENT 1 +#define CFM_CHASSIS_ID_INTERFACE_ALIAS 2 +#define CFM_CHASSIS_ID_PORT_COMPONENT 3 +#define CFM_CHASSIS_ID_MAC_ADDRESS 4 +#define CFM_CHASSIS_ID_NETWORK_ADDRESS 5 +#define CFM_CHASSIS_ID_INTERFACE_NAME 6 +#define CFM_CHASSIS_ID_LOCAL 7 + +static const struct tok cfm_tlv_senderid_chassisid_values[] = { + { 0, "Reserved"}, + { CFM_CHASSIS_ID_CHASSIS_COMPONENT, "Chassis component"}, + { CFM_CHASSIS_ID_INTERFACE_ALIAS, "Interface alias"}, + { CFM_CHASSIS_ID_PORT_COMPONENT, "Port component"}, + { CFM_CHASSIS_ID_MAC_ADDRESS, "MAC address"}, + { CFM_CHASSIS_ID_NETWORK_ADDRESS, "Network address"}, + { CFM_CHASSIS_ID_INTERFACE_NAME, "Interface name"}, + { CFM_CHASSIS_ID_LOCAL, "Locally assigned"}, + { 0, NULL} +}; + + +int +cfm_mgmt_addr_print(register const u_char *tptr) { + + u_int mgmt_addr_type; + u_int hexdump = FALSE; + + /* + * Altough AFIs are tpically 2 octects wide, + * 802.1ab specifies that this field width + * is only once octet + */ + mgmt_addr_type = *tptr; + printf("\n\t Management Address Type %s (%u)", + tok2str(af_values, "Unknown", mgmt_addr_type), + mgmt_addr_type); + + /* + * Resolve the passed in Address. + */ + switch(mgmt_addr_type) { + case AFNUM_INET: + printf(", %s", ipaddr_string(tptr + 1)); + break; + +#ifdef INET6 + case AFNUM_INET6: + printf(", %s", ip6addr_string(tptr + 1)); + break; +#endif + + default: + hexdump = TRUE; + break; + } + + return hexdump; +} + +/* + * The egress-ID string is a 16-Bit string plus a MAC address. + */ +const char * +cfm_egress_id_string(register const u_char *tptr) { + static char egress_id_buffer[80]; + + snprintf(egress_id_buffer, sizeof(egress_id_buffer), + "MAC %0x4x-%s", + EXTRACT_16BITS(tptr), + etheraddr_string(tptr+2)); + + return egress_id_buffer; +} + +void +cfm_print(register const u_char *pptr, register u_int length) { + + const struct cfm_common_header_t *cfm_common_header; + const struct cfm_tlv_header_t *cfm_tlv_header; + const u_int8_t *tptr, *tlv_ptr, *ma_name, *ma_nameformat, *ma_namelength; + u_int hexdump, tlen, cfm_tlv_len, cfm_tlv_type, ccm_interval; + + + union { + const struct cfm_ccm_t *cfm_ccm; + const struct cfm_lbm_t *cfm_lbm; + const struct cfm_ltm_t *cfm_ltm; + const struct cfm_ltr_t *cfm_ltr; + } msg_ptr; + + tptr=pptr; + cfm_common_header = (const struct cfm_common_header_t *)pptr; + TCHECK(*cfm_common_header); + + /* + * Sanity checking of the header. + */ + if (CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version) != CFM_VERSION) { + printf("CFMv%u not supported, length %u", + CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version), length); + return; + } + + printf("CFMv%u %s, MD Level %u, length %u", + CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version), + tok2str(cfm_opcode_values, "unknown (%u)", cfm_common_header->opcode), + CFM_EXTRACT_MD_LEVEL(cfm_common_header->mdlevel_version), + length); + + /* + * In non-verbose mode just print the opcode and md-level. + */ + if (vflag < 1) { + return; + } + + printf("\n\tFirst TLV offset %u", cfm_common_header->first_tlv_offset); + + tptr += sizeof(const struct cfm_common_header_t); + tlen = length - sizeof(struct cfm_common_header_t); + + switch (cfm_common_header->opcode) { + case CFM_OPCODE_CCM: + msg_ptr.cfm_ccm = (const struct cfm_ccm_t *)tptr; + + ccm_interval = CFM_EXTRACT_CCM_INTERVAL(cfm_common_header->flags); + printf(", Flags [CCM Interval %u%s]", + ccm_interval, + cfm_common_header->flags & CFM_CCM_RDI_FLAG ? + ", RDI" : ""); + + /* + * Resolve the CCM interval field. + */ + if (ccm_interval) { + printf("\n\t CCM Interval %.3fs" + ", min CCM Lifetime %.3fs, max CCM Lifetime %.3fs", + ccm_interval_base[ccm_interval], + ccm_interval_base[ccm_interval] * CCM_INTERVAL_MIN_MULTIPLIER, + ccm_interval_base[ccm_interval] * CCM_INTERVAL_MAX_MULTIPLIER); + } + + printf("\n\t Sequence Number 0x%08x, MA-End-Point-ID 0x%04x", + EXTRACT_32BITS(msg_ptr.cfm_ccm->sequence), + EXTRACT_16BITS(msg_ptr.cfm_ccm->ma_epi)); + + + /* + * Resolve the MD fields. + */ + printf("\n\t MD Name Format %s (%u), MD Name length %u", + tok2str(cfm_md_nameformat_values, "Unknown", + msg_ptr.cfm_ccm->md_nameformat), + msg_ptr.cfm_ccm->md_nameformat, + msg_ptr.cfm_ccm->md_namelength); + + if (msg_ptr.cfm_ccm->md_nameformat != CFM_CCM_MD_FORMAT_NONE) { + printf("\n\t MD Name: "); + switch (msg_ptr.cfm_ccm->md_nameformat) { + case CFM_CCM_MD_FORMAT_DNS: + case CFM_CCM_MD_FORMAT_CHAR: + safeputs((const char *)msg_ptr.cfm_ccm->md_name, msg_ptr.cfm_ccm->md_namelength); + break; + + case CFM_CCM_MD_FORMAT_MAC: + printf("\n\t MAC %s", etheraddr_string( + msg_ptr.cfm_ccm->md_name)); + break; + + /* FIXME add printers for those MD formats - hexdump for now */ + case CFM_CCM_MA_FORMAT_8021: + default: + print_unknown_data(msg_ptr.cfm_ccm->md_name, "\n\t ", + msg_ptr.cfm_ccm->md_namelength); + } + } + + + /* + * Resolve the MA fields. + */ + ma_nameformat = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength; + ma_namelength = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength + 1; + ma_name = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength + 2; + + printf("\n\t MA Name-Format %s (%u), MA name length %u", + tok2str(cfm_ma_nameformat_values, "Unknown", + *ma_nameformat), + *ma_nameformat, + *ma_namelength); + + printf("\n\t MA Name: "); + switch (*ma_nameformat) { + case CFM_CCM_MA_FORMAT_CHAR: + safeputs((const char *)ma_name, *ma_namelength); + break; + + /* FIXME add printers for those MA formats - hexdump for now */ + case CFM_CCM_MA_FORMAT_8021: + case CFM_CCM_MA_FORMAT_VID: + case CFM_CCM_MA_FORMAT_INT: + case CFM_CCM_MA_FORMAT_VPN: + default: + print_unknown_data(ma_name, "\n\t ", *ma_namelength); + } + break; + + case CFM_OPCODE_LTM: + msg_ptr.cfm_ltm = (const struct cfm_ltm_t *)tptr; + + printf(", Flags [%s]", + bittok2str(cfm_ltm_flag_values, "none", cfm_common_header->flags)); + + printf("\n\t Transaction-ID 0x%08x, Egress-ID %s, ttl %u", + EXTRACT_32BITS(msg_ptr.cfm_ltm->transaction_id), + cfm_egress_id_string(msg_ptr.cfm_ltm->egress_id), + msg_ptr.cfm_ltm->ttl); + + printf("\n\t Original-MAC %s, Target-MAC %s", + etheraddr_string(msg_ptr.cfm_ltm->original_mac), + etheraddr_string(msg_ptr.cfm_ltm->target_mac)); + break; + + case CFM_OPCODE_LTR: + msg_ptr.cfm_ltr = (const struct cfm_ltr_t *)tptr; + + printf(", Flags [%s]", + bittok2str(cfm_ltr_flag_values, "none", cfm_common_header->flags)); + + printf("\n\t Transaction-ID 0x%08x, Last-Egress-ID %s", + EXTRACT_32BITS(msg_ptr.cfm_ltr->transaction_id), + cfm_egress_id_string(msg_ptr.cfm_ltr->last_egress_id)); + + printf("\n\t Next-Egress-ID %s, ttl %u", + cfm_egress_id_string(msg_ptr.cfm_ltr->next_egress_id), + msg_ptr.cfm_ltr->ttl); + + printf("\n\t Replay-Action %s (%u)", + tok2str(cfm_ltr_replay_action_values, + "Unknown", + msg_ptr.cfm_ltr->replay_action), + msg_ptr.cfm_ltr->replay_action); + break; + + /* + * No message decoder yet. + * Hexdump everything up until the start of the TLVs + */ + case CFM_OPCODE_LBR: + case CFM_OPCODE_LBM: + default: + if (tlen > cfm_common_header->first_tlv_offset) { + print_unknown_data(tptr, "\n\t ", + tlen - cfm_common_header->first_tlv_offset); + } + break; + } + + /* + * Sanity check for not walking off. + */ + if (tlen <= cfm_common_header->first_tlv_offset) { + return; + } + + tptr += cfm_common_header->first_tlv_offset; + tlen -= cfm_common_header->first_tlv_offset; + + while (tlen > 0) { + cfm_tlv_header = (const struct cfm_tlv_header_t *)tptr; + + /* Enough to read the tlv type ? */ + TCHECK2(*tptr, 1); + cfm_tlv_type=cfm_tlv_header->type; + + if (cfm_tlv_type != CFM_TLV_END) { + /* did we capture enough for fully decoding the object header ? */ + TCHECK2(*tptr, sizeof(struct cfm_tlv_header_t)); + cfm_tlv_len=EXTRACT_16BITS(&cfm_tlv_header->length); + } else { + cfm_tlv_len = 0; + } + + printf("\n\t%s TLV (0x%02x), length %u", + tok2str(cfm_tlv_values, "Unknown", cfm_tlv_type), + cfm_tlv_type, + cfm_tlv_len); + + /* sanity check for not walking off and infinite loop check. */ + if ((cfm_tlv_type != CFM_TLV_END) && + ((cfm_tlv_len + sizeof(struct cfm_tlv_header_t) > tlen) || + (!cfm_tlv_len))) { + print_unknown_data(tptr,"\n\t ",tlen); + return; + } + + tptr += sizeof(struct cfm_tlv_header_t); + tlen -= sizeof(struct cfm_tlv_header_t); + tlv_ptr = tptr; + + /* did we capture enough for fully decoding the object ? */ + if (cfm_tlv_type != CFM_TLV_END) { + TCHECK2(*tptr, cfm_tlv_len); + } + hexdump = FALSE; + + switch(cfm_tlv_type) { + case CFM_TLV_END: + /* we are done - bail out */ + return; + + case CFM_TLV_PORT_STATUS: + printf(", Status: %s (%u)", + tok2str(cfm_tlv_port_status_values, "Unknown", *tptr), + *tptr); + break; + + case CFM_TLV_INTERFACE_STATUS: + printf(", Status: %s (%u)", + tok2str(cfm_tlv_interface_status_values, "Unknown", *tptr), + *tptr); + break; + + case CFM_TLV_PRIVATE: + printf(", Vendor: %s (%u), Sub-Type %u", + tok2str(oui_values,"Unknown", EXTRACT_24BITS(tptr)), + EXTRACT_24BITS(tptr), + *(tptr+3)); + hexdump = TRUE; + break; + + case CFM_TLV_SENDER_ID: + { + u_int chassis_id_type, chassis_id_length; + u_int mgmt_addr_length; + + /* + * Check if there is a Chassis-ID. + */ + chassis_id_length = *tptr; + if (chassis_id_length > tlen) { + hexdump = TRUE; + break; + } + + tptr++; + tlen--; + + if (chassis_id_length) { + chassis_id_type = *tptr; + printf("\n\t Chassis-ID Type %s (%u), Chassis-ID length %u", + tok2str(cfm_tlv_senderid_chassisid_values, + "Unknown", + chassis_id_type), + chassis_id_type, + chassis_id_length); + + switch (chassis_id_type) { + case CFM_CHASSIS_ID_MAC_ADDRESS: + printf("\n\t MAC %s", etheraddr_string(tptr+1)); + break; + + case CFM_CHASSIS_ID_NETWORK_ADDRESS: + hexdump |= cfm_mgmt_addr_print(tptr); + break; + + case CFM_CHASSIS_ID_INTERFACE_NAME: /* fall through */ + case CFM_CHASSIS_ID_INTERFACE_ALIAS: + case CFM_CHASSIS_ID_LOCAL: + case CFM_CHASSIS_ID_CHASSIS_COMPONENT: + case CFM_CHASSIS_ID_PORT_COMPONENT: + safeputs((const char *)tptr+1, chassis_id_length); + break; + + default: + hexdump = TRUE; + break; + } + } + + tptr += chassis_id_length; + tlen -= chassis_id_length; + + /* + * Check if there is a Management Address. + */ + mgmt_addr_length = *tptr; + if (mgmt_addr_length > tlen) { + hexdump = TRUE; + break; + } + + tptr++; + tlen--; + + if (mgmt_addr_length) { + hexdump |= cfm_mgmt_addr_print(tptr); + } + + tptr += mgmt_addr_length; + tlen -= mgmt_addr_length; + + } + break; + + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case CFM_TLV_DATA: + case CFM_TLV_REPLY_INGRESS: + case CFM_TLV_REPLY_EGRESS: + default: + hexdump = TRUE; + break; + } + /* do we want to see an additional hexdump ? */ + if (hexdump || vflag > 1) + print_unknown_data(tlv_ptr, "\n\t ", cfm_tlv_len); + + tptr+=cfm_tlv_len; + tlen-=cfm_tlv_len; + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} diff --git a/freebsd/contrib/tcpdump/print-chdlc.c b/freebsd/contrib/tcpdump/print-chdlc.c new file mode 100644 index 00000000..37414cb3 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-chdlc.c @@ -0,0 +1,217 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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/print-chdlc.c,v 1.43 2005-11-29 08:56:19 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "extract.h" +#include "ppp.h" +#include "chdlc.h" + +static void chdlc_slarp_print(const u_char *, u_int); + +const struct tok chdlc_cast_values[] = { + { CHDLC_UNICAST, "unicast" }, + { CHDLC_BCAST, "bcast" }, + { 0, NULL} +}; + + +/* Standard CHDLC printer */ +u_int +chdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + + if (caplen < CHDLC_HDRLEN) { + printf("[|chdlc]"); + return (caplen); + } + return (chdlc_print(p,length)); +} + +u_int +chdlc_print(register const u_char *p, u_int length) { + u_int proto; + + proto = EXTRACT_16BITS(&p[2]); + if (eflag) { + printf("%s, ethertype %s (0x%04x), length %u: ", + tok2str(chdlc_cast_values, "0x%02x", p[0]), + tok2str(ethertype_values, "Unknown", proto), + proto, + length); + } + + length -= CHDLC_HDRLEN; + p += CHDLC_HDRLEN; + + switch (proto) { + case ETHERTYPE_IP: + ip_print(gndo, p, length); + break; +#ifdef INET6 + case ETHERTYPE_IPV6: + ip6_print(gndo, p, length); + break; +#endif + case CHDLC_TYPE_SLARP: + chdlc_slarp_print(p, length); + break; +#if 0 + case CHDLC_TYPE_CDP: + chdlc_cdp_print(p, length); + break; +#endif + case ETHERTYPE_MPLS: + case ETHERTYPE_MPLS_MULTI: + mpls_print(p, length); + break; + case ETHERTYPE_ISO: + /* is the fudge byte set ? lets verify by spotting ISO headers */ + if (*(p+1) == 0x81 || + *(p+1) == 0x82 || + *(p+1) == 0x83) + isoclns_print(p+1, length-1, length-1); + else + isoclns_print(p, length, length); + break; + default: + if (!eflag) + printf("unknown CHDLC protocol (0x%04x)", proto); + break; + } + + return (CHDLC_HDRLEN); +} + +/* + * The fixed-length portion of a SLARP packet. + */ +struct cisco_slarp { + u_int8_t code[4]; +#define SLARP_REQUEST 0 +#define SLARP_REPLY 1 +#define SLARP_KEEPALIVE 2 + union { + struct { + u_int8_t addr[4]; + u_int8_t mask[4]; + } addr; + struct { + u_int8_t myseq[4]; + u_int8_t yourseq[4]; + u_int8_t rel[2]; + } keep; + } un; +}; + +#define SLARP_MIN_LEN 14 +#define SLARP_MAX_LEN 18 + +static void +chdlc_slarp_print(const u_char *cp, u_int length) +{ + const struct cisco_slarp *slarp; + u_int sec,min,hrs,days; + + printf("SLARP (length: %u), ",length); + if (length < SLARP_MIN_LEN) + goto trunc; + + slarp = (const struct cisco_slarp *)cp; + TCHECK2(*slarp, SLARP_MIN_LEN); + switch (EXTRACT_32BITS(&slarp->code)) { + case SLARP_REQUEST: + printf("request"); + /* + * At least according to William "Chops" Westfield's + * message in + * + * http://www.nethelp.no/net/cisco-hdlc.txt + * + * the address and mask aren't used in requests - + * they're just zero. + */ + break; + case SLARP_REPLY: + printf("reply %s/%s", + ipaddr_string(&slarp->un.addr.addr), + ipaddr_string(&slarp->un.addr.mask)); + break; + case SLARP_KEEPALIVE: + printf("keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x", + EXTRACT_32BITS(&slarp->un.keep.myseq), + EXTRACT_32BITS(&slarp->un.keep.yourseq), + EXTRACT_16BITS(&slarp->un.keep.rel)); + + if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */ + cp += SLARP_MIN_LEN; + if (!TTEST2(*cp, 4)) + goto trunc; + sec = EXTRACT_32BITS(cp) / 1000; + min = sec / 60; sec -= min * 60; + hrs = min / 60; min -= hrs * 60; + days = hrs / 24; hrs -= days * 24; + printf(", link uptime=%ud%uh%um%us",days,hrs,min,sec); + } + break; + default: + printf("0x%02x unknown", EXTRACT_32BITS(&slarp->code)); + if (vflag <= 1) + print_unknown_data(cp+4,"\n\t",length-4); + break; + } + + if (SLARP_MAX_LEN < length && vflag) + printf(", (trailing junk: %d bytes)", length - SLARP_MAX_LEN); + if (vflag > 1) + print_unknown_data(cp+4,"\n\t",length-4); + return; + +trunc: + printf("[|slarp]"); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-cip.c b/freebsd/contrib/tcpdump/print-cip.c new file mode 100644 index 00000000..3b9075af --- /dev/null +++ b/freebsd/contrib/tcpdump/print-cip.c @@ -0,0 +1,118 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <string.h> + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> + +#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: + */ diff --git a/freebsd/contrib/tcpdump/print-cnfp.c b/freebsd/contrib/tcpdump/print-cnfp.c new file mode 100644 index 00000000..ae4a3426 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-cnfp.c @@ -0,0 +1,192 @@ +#include <machine/rtems-bsd-user-space.h> + +/* $OpenBSD: print-cnfp.c,v 1.2 1998/06/25 20:26:59 mickey Exp $ */ + +/* + * Copyright (c) 1998 Michael Shalayeff + * 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 Michael Shalayeff. + * 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. + */ + +/* Cisco NetFlow protocol */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-cnfp.c,v 1.17 2005-04-20 20:53:18 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "tcp.h" +#include "ipproto.h" + +struct nfhdr { + u_int32_t ver_cnt; /* version [15], and # of records */ + u_int32_t msys_uptime; + u_int32_t utc_sec; + u_int32_t utc_nsec; + u_int32_t sequence; /* v5 flow sequence number */ + u_int32_t reserved; /* v5 only */ +}; + +struct nfrec { + struct in_addr src_ina; + struct in_addr dst_ina; + struct in_addr nhop_ina; + u_int32_t ifaces; /* src,dst ifaces */ + u_int32_t packets; + u_int32_t octets; + u_int32_t start_time; /* sys_uptime value */ + u_int32_t last_time; /* sys_uptime value */ + u_int32_t ports; /* src,dst ports */ + u_int32_t proto_tos; /* proto, tos, pad, flags(v5) */ + u_int32_t asses; /* v1: flags; v5: src,dst AS */ + u_int32_t masks; /* src,dst addr prefix; v6: encaps */ + struct in_addr peer_nexthop; /* v6: IP address of the nexthop within the peer (FIB)*/ +}; + +void +cnfp_print(const u_char *cp, const u_char *bp _U_) +{ + register const struct nfhdr *nh; + register const struct nfrec *nr; + struct protoent *pent; + int nrecs, ver; +#if 0 + time_t t; +#endif + + nh = (const struct nfhdr *)cp; + + if ((const u_char *)(nh + 1) > snapend) + return; + + nrecs = EXTRACT_32BITS(&nh->ver_cnt) & 0xffff; + ver = (EXTRACT_32BITS(&nh->ver_cnt) & 0xffff0000) >> 16; +#if 0 + /* + * This is seconds since the UN*X epoch, and is followed by + * nanoseconds. XXX - format it, rather than just dumping the + * raw seconds-since-the-Epoch. + */ + t = EXTRACT_32BITS(&nh->utc_sec); +#endif + + printf("NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver, + EXTRACT_32BITS(&nh->msys_uptime)/1000, + EXTRACT_32BITS(&nh->msys_uptime)%1000, + EXTRACT_32BITS(&nh->utc_sec), EXTRACT_32BITS(&nh->utc_nsec)); + + if (ver == 5 || ver == 6) { + printf("#%u, ", EXTRACT_32BITS(&nh->sequence)); + nr = (const struct nfrec *)&nh[1]; + snaplen -= 24; + } else { + nr = (const struct nfrec *)&nh->sequence; + snaplen -= 16; + } + + printf("%2u recs", nrecs); + + for (; nrecs-- && (const u_char *)(nr + 1) <= snapend; nr++) { + char buf[20]; + char asbuf[20]; + + printf("\n started %u.%03u, last %u.%03u", + EXTRACT_32BITS(&nr->start_time)/1000, + EXTRACT_32BITS(&nr->start_time)%1000, + EXTRACT_32BITS(&nr->last_time)/1000, + EXTRACT_32BITS(&nr->last_time)%1000); + + asbuf[0] = buf[0] = '\0'; + if (ver == 5 || ver == 6) { + snprintf(buf, sizeof(buf), "/%u", + (EXTRACT_32BITS(&nr->masks) >> 24) & 0xff); + snprintf(asbuf, sizeof(asbuf), ":%u", + (EXTRACT_32BITS(&nr->asses) >> 16) & 0xffff); + } + printf("\n %s%s%s:%u ", intoa(nr->src_ina.s_addr), buf, asbuf, + EXTRACT_32BITS(&nr->ports) >> 16); + + if (ver == 5 || ver ==6) { + snprintf(buf, sizeof(buf), "/%d", + (EXTRACT_32BITS(&nr->masks) >> 16) & 0xff); + snprintf(asbuf, sizeof(asbuf), ":%u", + EXTRACT_32BITS(&nr->asses) & 0xffff); + } + printf("> %s%s%s:%u ", intoa(nr->dst_ina.s_addr), buf, asbuf, + EXTRACT_32BITS(&nr->ports) & 0xffff); + + printf(">> %s\n ", intoa(nr->nhop_ina.s_addr)); + + pent = getprotobynumber((EXTRACT_32BITS(&nr->proto_tos) >> 8) & 0xff); + if (!pent || nflag) + printf("%u ", + (EXTRACT_32BITS(&nr->proto_tos) >> 8) & 0xff); + else + printf("%s ", pent->p_name); + + /* tcp flags for tcp only */ + if (pent && pent->p_proto == IPPROTO_TCP) { + int flags; + if (ver == 1) + flags = (EXTRACT_32BITS(&nr->asses) >> 24) & 0xff; + else + flags = (EXTRACT_32BITS(&nr->proto_tos) >> 16) & 0xff; + if (flags & TH_FIN) putchar('F'); + if (flags & TH_SYN) putchar('S'); + if (flags & TH_RST) putchar('R'); + if (flags & TH_PUSH) putchar('P'); + if (flags & TH_ACK) putchar('A'); + if (flags & TH_URG) putchar('U'); + if (flags) + putchar(' '); + } + + buf[0]='\0'; + if (ver == 6) { + snprintf(buf, sizeof(buf), "(%u<>%u encaps)", + (EXTRACT_32BITS(&nr->masks) >> 8) & 0xff, + (EXTRACT_32BITS(&nr->masks)) & 0xff); + } + printf("tos %u, %u (%u octets) %s", + EXTRACT_32BITS(&nr->proto_tos) & 0xff, + EXTRACT_32BITS(&nr->packets), + EXTRACT_32BITS(&nr->octets), buf); + } +} diff --git a/freebsd/contrib/tcpdump/print-dccp.c b/freebsd/contrib/tcpdump/print-dccp.c new file mode 100644 index 00000000..59417c58 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-dccp.c @@ -0,0 +1,466 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-dccp.c,v 1.8 2007-11-09 00:44:09 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include "dccp.h" + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "ipproto.h" + +static const char *dccp_reset_codes[] = { + "unspecified", + "closed", + "aborted", + "no_connection", + "packet_error", + "option_error", + "mandatory_error", + "connection_refused", + "bad_service_code", + "too_busy", + "bad_init_cookie", + "aggression_penalty", +}; + +static const char *dccp_feature_nums[] = { + "reserved", + "ccid", + "allow_short_seqno", + "sequence_window", + "ecn_incapable", + "ack_ratio", + "send_ack_vector", + "send_ndp_count", + "minimum checksum coverage", + "check data checksum", +}; + +static inline u_int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) +{ + u_int cov; + + if (DCCPH_CSCOV(dh) == 0) + return len; + cov = (dh->dccph_doff + DCCPH_CSCOV(dh) - 1) * sizeof(u_int32_t); + return (cov > len)? len : cov; +} + +static int dccp_cksum(const struct ip *ip, + const struct dccp_hdr *dh, u_int len) +{ + return nextproto4_cksum(ip, (const u_int8_t *)(void *)dh, + dccp_csum_coverage(dh, len), IPPROTO_DCCP); +} + +#ifdef INET6 +static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len) +{ + return nextproto6_cksum(ip6, (const u_int8_t *)(void *)dh, + dccp_csum_coverage(dh, len), IPPROTO_DCCP); +} +#endif + +static const char *dccp_reset_code(u_int8_t code) +{ + if (code >= __DCCP_RESET_CODE_LAST) + return "invalid"; + return dccp_reset_codes[code]; +} + +static u_int64_t dccp_seqno(const struct dccp_hdr *dh) +{ + u_int32_t seq_high = DCCPH_SEQ(dh); + u_int64_t seqno = EXTRACT_24BITS(&seq_high) & 0xFFFFFF; + + if (DCCPH_X(dh) != 0) { + const struct dccp_hdr_ext *dhx = (void *)(dh + 1); + u_int32_t seq_low = dhx->dccph_seq_low; + seqno &= 0x00FFFF; /* clear reserved field */ + seqno = (seqno << 32) + EXTRACT_32BITS(&seq_low); + } + + return seqno; +} + +static inline unsigned int dccp_basic_hdr_len(const struct dccp_hdr *dh) +{ + return sizeof(*dh) + (DCCPH_X(dh) ? sizeof(struct dccp_hdr_ext) : 0); +} + +static void dccp_print_ack_no(const u_char *bp) +{ + const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; + const struct dccp_hdr_ack_bits *dh_ack = + (struct dccp_hdr_ack_bits *)(bp + dccp_basic_hdr_len(dh)); + u_int32_t ack_high; + u_int64_t ackno; + + TCHECK2(*dh_ack,4); + ack_high = DCCPH_ACK(dh_ack); + ackno = EXTRACT_24BITS(&ack_high) & 0xFFFFFF; + + if (DCCPH_X(dh) != 0) { + u_int32_t ack_low; + + TCHECK2(*dh_ack,8); + ack_low = dh_ack->dccph_ack_nr_low; + + ackno &= 0x00FFFF; /* clear reserved field */ + ackno = (ackno << 32) + EXTRACT_32BITS(&ack_low); + } + + (void)printf("(ack=%" PRIu64 ") ", ackno); +trunc: + return; +} + +static inline unsigned int dccp_packet_hdr_len(const u_int8_t type) +{ + if (type == DCCP_PKT_DATA) + return 0; + if (type == DCCP_PKT_DATAACK || + type == DCCP_PKT_ACK || + type == DCCP_PKT_SYNC || + type == DCCP_PKT_SYNCACK || + type == DCCP_PKT_CLOSE || + type == DCCP_PKT_CLOSEREQ) + return sizeof(struct dccp_hdr_ack_bits); + if (type == DCCP_PKT_REQUEST) + return sizeof(struct dccp_hdr_request); + if (type == DCCP_PKT_RESPONSE) + return sizeof(struct dccp_hdr_response); + return sizeof(struct dccp_hdr_reset); +} + +static int dccp_print_option(const u_char *option); + +/** + * dccp_print - show dccp packet + * @bp - beginning of dccp packet + * @data2 - beginning of enclosing + * @len - lenght of ip packet + */ +void dccp_print(const u_char *bp, const u_char *data2, u_int len) +{ + const struct dccp_hdr *dh; + const struct ip *ip; +#ifdef INET6 + const struct ip6_hdr *ip6; +#endif + const u_char *cp; + u_short sport, dport; + u_int hlen; + u_int extlen = 0; + + dh = (const struct dccp_hdr *)bp; + + ip = (struct ip *)data2; +#ifdef INET6 + if (IP_V(ip) == 6) + ip6 = (const struct ip6_hdr *)data2; + else + ip6 = NULL; +#endif /*INET6*/ + cp = (const u_char *)(dh + 1); + if (cp > snapend) { + printf("[Invalid packet|dccp]"); + return; + } + + if (len < sizeof(struct dccp_hdr)) { + printf("truncated-dccp - %ld bytes missing!", + (long)len - sizeof(struct dccp_hdr)); + return; + } + + sport = EXTRACT_16BITS(&dh->dccph_sport); + dport = EXTRACT_16BITS(&dh->dccph_dport); + hlen = dh->dccph_doff * 4; + +#ifdef INET6 + if (ip6) { + (void)printf("%s.%d > %s.%d: ", + ip6addr_string(&ip6->ip6_src), sport, + ip6addr_string(&ip6->ip6_dst), dport); + } else +#endif /*INET6*/ + { + (void)printf("%s.%d > %s.%d: ", + ipaddr_string(&ip->ip_src), sport, + ipaddr_string(&ip->ip_dst), dport); + } + fflush(stdout); + + if (qflag) { + (void)printf(" %d", len - hlen); + if (hlen > len) { + (void)printf("dccp [bad hdr length %u - too long, > %u]", + hlen, len); + } + return; + } + + /* other variables in generic header */ + if (vflag) { + (void)printf("CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh)); + } + + /* checksum calculation */ + if (vflag && TTEST2(bp[0], len)) { + u_int16_t sum = 0, dccp_sum; + + dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum); + (void)printf("cksum 0x%04x ", dccp_sum); + if (IP_V(ip) == 4) + sum = dccp_cksum(ip, dh, len); +#ifdef INET6 + else if (IP_V(ip) == 6) + sum = dccp6_cksum(ip6, dh, len); +#endif + if (sum != 0) + (void)printf("(incorrect -> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum)); + else + (void)printf("(correct), "); + } + + switch (DCCPH_TYPE(dh)) { + case DCCP_PKT_REQUEST: { + struct dccp_hdr_request *dhr = + (struct dccp_hdr_request *)(bp + dccp_basic_hdr_len(dh)); + TCHECK(*dhr); + (void)printf("request (service=%d) ", + EXTRACT_32BITS(&dhr->dccph_req_service)); + extlen += 4; + break; + } + case DCCP_PKT_RESPONSE: { + struct dccp_hdr_response *dhr = + (struct dccp_hdr_response *)(bp + dccp_basic_hdr_len(dh)); + TCHECK(*dhr); + (void)printf("response (service=%d) ", + EXTRACT_32BITS(&dhr->dccph_resp_service)); + extlen += 12; + break; + } + case DCCP_PKT_DATA: + (void)printf("data "); + break; + case DCCP_PKT_ACK: { + (void)printf("ack "); + extlen += 8; + break; + } + case DCCP_PKT_DATAACK: { + (void)printf("dataack "); + extlen += 8; + break; + } + case DCCP_PKT_CLOSEREQ: + (void)printf("closereq "); + extlen += 8; + break; + case DCCP_PKT_CLOSE: + (void)printf("close "); + extlen += 8; + break; + case DCCP_PKT_RESET: { + struct dccp_hdr_reset *dhr = + (struct dccp_hdr_reset *)(bp + dccp_basic_hdr_len(dh)); + TCHECK(*dhr); + (void)printf("reset (code=%s) ", + dccp_reset_code(dhr->dccph_reset_code)); + extlen += 12; + break; + } + case DCCP_PKT_SYNC: + (void)printf("sync "); + extlen += 8; + break; + case DCCP_PKT_SYNCACK: + (void)printf("syncack "); + extlen += 8; + break; + default: + (void)printf("invalid "); + break; + } + + if ((DCCPH_TYPE(dh) != DCCP_PKT_DATA) && + (DCCPH_TYPE(dh) != DCCP_PKT_REQUEST)) + dccp_print_ack_no(bp); + + if (vflag < 2) + return; + + (void)printf("seq %" PRIu64, dccp_seqno(dh)); + + /* process options */ + if (hlen > dccp_basic_hdr_len(dh) + extlen){ + const u_char *cp; + u_int optlen; + cp = bp + dccp_basic_hdr_len(dh) + extlen; + printf(" <"); + + hlen -= dccp_basic_hdr_len(dh) + extlen; + while(1){ + TCHECK(*cp); + optlen = dccp_print_option(cp); + if (!optlen) goto trunc2; + if (hlen <= optlen) break; + hlen -= optlen; + cp += optlen; + printf(", "); + } + printf(">"); + } + return; +trunc: + printf("[|dccp]"); +trunc2: + return; +} + +static int dccp_print_option(const u_char *option) +{ + u_int8_t optlen, i; + + TCHECK(*option); + + if (*option >= 32) { + TCHECK(*(option+1)); + optlen = *(option +1); + if (optlen < 2) { + printf("Option %d optlen too short",*option); + return 1; + } + } else optlen = 1; + + TCHECK2(*option,optlen); + + switch (*option){ + case 0: + printf("nop"); + break; + case 1: + printf("mandatory"); + break; + case 2: + printf("slowreceiver"); + break; + case 32: + printf("change_l"); + if (*(option +2) < 10){ + printf(" %s", dccp_feature_nums[*(option +2)]); + for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i)); + } + break; + case 33: + printf("confirm_l"); + if (*(option +2) < 10){ + printf(" %s", dccp_feature_nums[*(option +2)]); + for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i)); + } + break; + case 34: + printf("change_r"); + if (*(option +2) < 10){ + printf(" %s", dccp_feature_nums[*(option +2)]); + for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i)); + } + break; + case 35: + printf("confirm_r"); + if (*(option +2) < 10){ + printf(" %s", dccp_feature_nums[*(option +2)]); + for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i)); + } + break; + case 36: + printf("initcookie 0x"); + for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i)); + break; + case 37: + printf("ndp_count"); + for (i = 0; i < optlen -2; i ++) printf(" %d", *(option +2 + i)); + break; + case 38: + printf("ack_vector0 0x"); + for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i)); + break; + case 39: + printf("ack_vector1 0x"); + for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i)); + break; + case 40: + printf("data_dropped 0x"); + for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i)); + break; + case 41: + printf("timestamp %u", EXTRACT_32BITS(option + 2)); + break; + case 42: + printf("timestamp_echo %u", EXTRACT_32BITS(option + 2)); + break; + case 43: + printf("elapsed_time "); + if (optlen == 6) + printf("%u", EXTRACT_32BITS(option + 2)); + else + printf("%u", EXTRACT_16BITS(option + 2)); + break; + case 44: + printf("data_checksum "); + for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i)); + break; + default : + if (*option >= 128) { + printf("CCID option %d",*option); + switch (optlen) { + case 4: + printf(" %u", EXTRACT_16BITS(option + 2)); + break; + case 6: + printf(" %u", EXTRACT_32BITS(option + 2)); + break; + default: + break; + } + break; + } + + printf("unknown_opt %d", *option); + break; + } + + return optlen; +trunc: + printf("[|dccp]"); + return 0; +} diff --git a/freebsd/contrib/tcpdump/print-decnet.c b/freebsd/contrib/tcpdump/print-decnet.c new file mode 100644 index 00000000..f453381c --- /dev/null +++ b/freebsd/contrib/tcpdump/print-decnet.c @@ -0,0 +1,897 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-decnet.c,v 1.39 2005-05-06 02:16:26 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +struct mbuf; +struct rtentry; + +#ifdef HAVE_NETDNET_DNETDB_H +#include <netdnet/dnetdb.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "decnet.h" +#include "extract.h" +#include "interface.h" +#include "addrtoname.h" + +/* Forwards */ +static int print_decnet_ctlmsg(const union routehdr *, u_int, u_int); +static void print_t_info(int); +static int print_l1_routes(const char *, u_int); +static int print_l2_routes(const char *, u_int); +static void print_i_info(int); +static int print_elist(const char *, u_int); +static int print_nsp(const u_char *, u_int); +static void print_reason(int); +#ifdef PRINT_NSPDATA +static void pdata(u_char *, int); +#endif + +#ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA +extern char *dnet_htoa(struct dn_naddr *); +#endif + +void +decnet_print(register const u_char *ap, register u_int length, + register u_int caplen) +{ + register const union routehdr *rhp; + register int mflags; + int dst, src, hops; + u_int nsplen, pktlen; + const u_char *nspp; + + if (length < sizeof(struct shorthdr)) { + (void)printf("[|decnet]"); + return; + } + + TCHECK2(*ap, sizeof(short)); + pktlen = EXTRACT_LE_16BITS(ap); + if (pktlen < sizeof(struct shorthdr)) { + (void)printf("[|decnet]"); + return; + } + if (pktlen > length) { + (void)printf("[|decnet]"); + return; + } + length = pktlen; + + rhp = (const union routehdr *)&(ap[sizeof(short)]); + TCHECK(rhp->rh_short.sh_flags); + mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); + + if (mflags & RMF_PAD) { + /* pad bytes of some sort in front of message */ + u_int padlen = mflags & RMF_PADMASK; + if (vflag) + (void) printf("[pad:%d] ", padlen); + if (length < padlen + 2) { + (void)printf("[|decnet]"); + return; + } + TCHECK2(ap[sizeof(short)], padlen); + ap += padlen; + length -= padlen; + caplen -= padlen; + rhp = (const union routehdr *)&(ap[sizeof(short)]); + mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); + } + + if (mflags & RMF_FVER) { + (void) printf("future-version-decnet"); + default_print(ap, min(length, caplen)); + return; + } + + /* is it a control message? */ + if (mflags & RMF_CTLMSG) { + if (!print_decnet_ctlmsg(rhp, length, caplen)) + goto trunc; + return; + } + + switch (mflags & RMF_MASK) { + case RMF_LONG: + if (length < sizeof(struct longhdr)) { + (void)printf("[|decnet]"); + return; + } + TCHECK(rhp->rh_long); + dst = + EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr); + src = + EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr); + hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits); + nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]); + nsplen = length - sizeof(struct longhdr); + break; + case RMF_SHORT: + TCHECK(rhp->rh_short); + dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst); + src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src); + hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1; + nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]); + nsplen = length - sizeof(struct shorthdr); + break; + default: + (void) printf("unknown message flags under mask"); + default_print((u_char *)ap, min(length, caplen)); + return; + } + + (void)printf("%s > %s %d ", + dnaddr_string(src), dnaddr_string(dst), pktlen); + if (vflag) { + if (mflags & RMF_RQR) + (void)printf("RQR "); + if (mflags & RMF_RTS) + (void)printf("RTS "); + if (mflags & RMF_IE) + (void)printf("IE "); + (void)printf("%d hops ", hops); + } + + if (!print_nsp(nspp, nsplen)) + goto trunc; + return; + +trunc: + (void)printf("[|decnet]"); + return; +} + +static int +print_decnet_ctlmsg(register const union routehdr *rhp, u_int length, + u_int caplen) +{ + int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); + register union controlmsg *cmp = (union controlmsg *)rhp; + int src, dst, info, blksize, eco, ueco, hello, other, vers; + etheraddr srcea, rtea; + int priority; + char *rhpx = (char *)rhp; + int ret; + + switch (mflags & RMF_CTLMASK) { + case RMF_INIT: + (void)printf("init "); + if (length < sizeof(struct initmsg)) + goto trunc; + TCHECK(cmp->cm_init); + src = EXTRACT_LE_16BITS(cmp->cm_init.in_src); + info = EXTRACT_LE_8BITS(cmp->cm_init.in_info); + blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize); + vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers); + eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco); + ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco); + hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello); + print_t_info(info); + (void)printf( + "src %sblksize %d vers %d eco %d ueco %d hello %d", + dnaddr_string(src), blksize, vers, eco, ueco, + hello); + ret = 1; + break; + case RMF_VER: + (void)printf("verification "); + if (length < sizeof(struct verifmsg)) + goto trunc; + TCHECK(cmp->cm_ver); + src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src); + other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval); + (void)printf("src %s fcnval %o", dnaddr_string(src), other); + ret = 1; + break; + case RMF_TEST: + (void)printf("test "); + if (length < sizeof(struct testmsg)) + goto trunc; + TCHECK(cmp->cm_test); + src = EXTRACT_LE_16BITS(cmp->cm_test.te_src); + other = EXTRACT_LE_8BITS(cmp->cm_test.te_data); + (void)printf("src %s data %o", dnaddr_string(src), other); + ret = 1; + break; + case RMF_L1ROUT: + (void)printf("lev-1-routing "); + if (length < sizeof(struct l1rout)) + goto trunc; + TCHECK(cmp->cm_l1rou); + src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src); + (void)printf("src %s ", dnaddr_string(src)); + ret = print_l1_routes(&(rhpx[sizeof(struct l1rout)]), + length - sizeof(struct l1rout)); + break; + case RMF_L2ROUT: + (void)printf("lev-2-routing "); + if (length < sizeof(struct l2rout)) + goto trunc; + TCHECK(cmp->cm_l2rout); + src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src); + (void)printf("src %s ", dnaddr_string(src)); + ret = print_l2_routes(&(rhpx[sizeof(struct l2rout)]), + length - sizeof(struct l2rout)); + break; + case RMF_RHELLO: + (void)printf("router-hello "); + if (length < sizeof(struct rhellomsg)) + goto trunc; + TCHECK(cmp->cm_rhello); + vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers); + eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco); + ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco); + memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src), + sizeof(srcea)); + src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); + info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info); + blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize); + priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority); + hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello); + print_i_info(info); + (void)printf( + "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d", + vers, eco, ueco, dnaddr_string(src), + blksize, priority, hello); + ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]), + length - sizeof(struct rhellomsg)); + break; + case RMF_EHELLO: + (void)printf("endnode-hello "); + if (length < sizeof(struct ehellomsg)) + goto trunc; + TCHECK(cmp->cm_ehello); + vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers); + eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco); + ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco); + memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src), + sizeof(srcea)); + src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); + info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info); + blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize); + /*seed*/ + memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router), + sizeof(rtea)); + dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr); + hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello); + other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data); + print_i_info(info); + (void)printf( + "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o", + vers, eco, ueco, dnaddr_string(src), + blksize, dnaddr_string(dst), hello, other); + ret = 1; + break; + + default: + (void)printf("unknown control message"); + default_print((u_char *)rhp, min(length, caplen)); + ret = 1; + break; + } + return (ret); + +trunc: + return (0); +} + +static void +print_t_info(int info) +{ + int ntype = info & 3; + switch (ntype) { + case 0: (void)printf("reserved-ntype? "); break; + case TI_L2ROUT: (void)printf("l2rout "); break; + case TI_L1ROUT: (void)printf("l1rout "); break; + case TI_ENDNODE: (void)printf("endnode "); break; + } + if (info & TI_VERIF) + (void)printf("verif "); + if (info & TI_BLOCK) + (void)printf("blo "); +} + +static int +print_l1_routes(const char *rp, u_int len) +{ + int count; + int id; + int info; + + /* The last short is a checksum */ + while (len > (3 * sizeof(short))) { + TCHECK2(*rp, 3 * sizeof(short)); + count = EXTRACT_LE_16BITS(rp); + if (count > 1024) + return (1); /* seems to be bogus from here on */ + rp += sizeof(short); + len -= sizeof(short); + id = EXTRACT_LE_16BITS(rp); + rp += sizeof(short); + len -= sizeof(short); + info = EXTRACT_LE_16BITS(rp); + rp += sizeof(short); + len -= sizeof(short); + (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count, + RI_COST(info), RI_HOPS(info)); + } + return (1); + +trunc: + return (0); +} + +static int +print_l2_routes(const char *rp, u_int len) +{ + int count; + int area; + int info; + + /* The last short is a checksum */ + while (len > (3 * sizeof(short))) { + TCHECK2(*rp, 3 * sizeof(short)); + count = EXTRACT_LE_16BITS(rp); + if (count > 1024) + return (1); /* seems to be bogus from here on */ + rp += sizeof(short); + len -= sizeof(short); + area = EXTRACT_LE_16BITS(rp); + rp += sizeof(short); + len -= sizeof(short); + info = EXTRACT_LE_16BITS(rp); + rp += sizeof(short); + len -= sizeof(short); + (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count, + RI_COST(info), RI_HOPS(info)); + } + return (1); + +trunc: + return (0); +} + +static void +print_i_info(int info) +{ + int ntype = info & II_TYPEMASK; + switch (ntype) { + case 0: (void)printf("reserved-ntype? "); break; + case II_L2ROUT: (void)printf("l2rout "); break; + case II_L1ROUT: (void)printf("l1rout "); break; + case II_ENDNODE: (void)printf("endnode "); break; + } + if (info & II_VERIF) + (void)printf("verif "); + if (info & II_NOMCAST) + (void)printf("nomcast "); + if (info & II_BLOCK) + (void)printf("blo "); +} + +static int +print_elist(const char *elp _U_, u_int len _U_) +{ + /* Not enough examples available for me to debug this */ + return (1); +} + +static int +print_nsp(const u_char *nspp, u_int nsplen) +{ + const struct nsphdr *nsphp = (struct nsphdr *)nspp; + int dst, src, flags; + + if (nsplen < sizeof(struct nsphdr)) + goto trunc; + TCHECK(*nsphp); + flags = EXTRACT_LE_8BITS(nsphp->nh_flags); + dst = EXTRACT_LE_16BITS(nsphp->nh_dst); + src = EXTRACT_LE_16BITS(nsphp->nh_src); + + switch (flags & NSP_TYPEMASK) { + case MFT_DATA: + switch (flags & NSP_SUBMASK) { + case MFS_BOM: + case MFS_MOM: + case MFS_EOM: + case MFS_BOM+MFS_EOM: + printf("data %d>%d ", src, dst); + { + struct seghdr *shp = (struct seghdr *)nspp; + int ack; +#ifdef PRINT_NSPDATA + u_char *dp; +#endif + u_int data_off = sizeof(struct minseghdr); + + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[0]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); + if (ack & SGQ_ACK) { /* acknum field */ + if ((ack & SGQ_NAK) == SGQ_NAK) + (void)printf("nak %d ", ack & SGQ_MASK); + else + (void)printf("ack %d ", ack & SGQ_MASK); + data_off += sizeof(short); + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[1]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); + if (ack & SGQ_OACK) { /* ackoth field */ + if ((ack & SGQ_ONAK) == SGQ_ONAK) + (void)printf("onak %d ", ack & SGQ_MASK); + else + (void)printf("oack %d ", ack & SGQ_MASK); + data_off += sizeof(short); + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[2]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); + } + } + (void)printf("seg %d ", ack & SGQ_MASK); +#ifdef PRINT_NSPDATA + if (nsplen > data_off) { + dp = &(nspp[data_off]); + TCHECK2(*dp, nsplen - data_off); + pdata(dp, nsplen - data_off); + } +#endif + } + break; + case MFS_ILS+MFS_INT: + printf("intr "); + { + struct seghdr *shp = (struct seghdr *)nspp; + int ack; +#ifdef PRINT_NSPDATA + u_char *dp; +#endif + u_int data_off = sizeof(struct minseghdr); + + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[0]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); + if (ack & SGQ_ACK) { /* acknum field */ + if ((ack & SGQ_NAK) == SGQ_NAK) + (void)printf("nak %d ", ack & SGQ_MASK); + else + (void)printf("ack %d ", ack & SGQ_MASK); + data_off += sizeof(short); + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[1]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); + if (ack & SGQ_OACK) { /* ackdat field */ + if ((ack & SGQ_ONAK) == SGQ_ONAK) + (void)printf("nakdat %d ", ack & SGQ_MASK); + else + (void)printf("ackdat %d ", ack & SGQ_MASK); + data_off += sizeof(short); + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[2]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); + } + } + (void)printf("seg %d ", ack & SGQ_MASK); +#ifdef PRINT_NSPDATA + if (nsplen > data_off) { + dp = &(nspp[data_off]); + TCHECK2(*dp, nsplen - data_off); + pdata(dp, nsplen - data_off); + } +#endif + } + break; + case MFS_ILS: + (void)printf("link-service %d>%d ", src, dst); + { + struct seghdr *shp = (struct seghdr *)nspp; + struct lsmsg *lsmp = + (struct lsmsg *)&(nspp[sizeof(struct seghdr)]); + int ack; + int lsflags, fcval; + + if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg)) + goto trunc; + TCHECK(shp->sh_seq[0]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); + if (ack & SGQ_ACK) { /* acknum field */ + if ((ack & SGQ_NAK) == SGQ_NAK) + (void)printf("nak %d ", ack & SGQ_MASK); + else + (void)printf("ack %d ", ack & SGQ_MASK); + TCHECK(shp->sh_seq[1]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); + if (ack & SGQ_OACK) { /* ackdat field */ + if ((ack & SGQ_ONAK) == SGQ_ONAK) + (void)printf("nakdat %d ", ack & SGQ_MASK); + else + (void)printf("ackdat %d ", ack & SGQ_MASK); + TCHECK(shp->sh_seq[2]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); + } + } + (void)printf("seg %d ", ack & SGQ_MASK); + TCHECK(*lsmp); + lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags); + fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval); + switch (lsflags & LSI_MASK) { + case LSI_DATA: + (void)printf("dat seg count %d ", fcval); + switch (lsflags & LSM_MASK) { + case LSM_NOCHANGE: + break; + case LSM_DONOTSEND: + (void)printf("donotsend-data "); + break; + case LSM_SEND: + (void)printf("send-data "); + break; + default: + (void)printf("reserved-fcmod? %x", lsflags); + break; + } + break; + case LSI_INTR: + (void)printf("intr req count %d ", fcval); + break; + default: + (void)printf("reserved-fcval-int? %x", lsflags); + break; + } + } + break; + default: + (void)printf("reserved-subtype? %x %d > %d", flags, src, dst); + break; + } + break; + case MFT_ACK: + switch (flags & NSP_SUBMASK) { + case MFS_DACK: + (void)printf("data-ack %d>%d ", src, dst); + { + struct ackmsg *amp = (struct ackmsg *)nspp; + int ack; + + if (nsplen < sizeof(struct ackmsg)) + goto trunc; + TCHECK(*amp); + ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); + if (ack & SGQ_ACK) { /* acknum field */ + if ((ack & SGQ_NAK) == SGQ_NAK) + (void)printf("nak %d ", ack & SGQ_MASK); + else + (void)printf("ack %d ", ack & SGQ_MASK); + ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); + if (ack & SGQ_OACK) { /* ackoth field */ + if ((ack & SGQ_ONAK) == SGQ_ONAK) + (void)printf("onak %d ", ack & SGQ_MASK); + else + (void)printf("oack %d ", ack & SGQ_MASK); + } + } + } + break; + case MFS_IACK: + (void)printf("ils-ack %d>%d ", src, dst); + { + struct ackmsg *amp = (struct ackmsg *)nspp; + int ack; + + if (nsplen < sizeof(struct ackmsg)) + goto trunc; + TCHECK(*amp); + ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); + if (ack & SGQ_ACK) { /* acknum field */ + if ((ack & SGQ_NAK) == SGQ_NAK) + (void)printf("nak %d ", ack & SGQ_MASK); + else + (void)printf("ack %d ", ack & SGQ_MASK); + TCHECK(amp->ak_acknum[1]); + ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); + if (ack & SGQ_OACK) { /* ackdat field */ + if ((ack & SGQ_ONAK) == SGQ_ONAK) + (void)printf("nakdat %d ", ack & SGQ_MASK); + else + (void)printf("ackdat %d ", ack & SGQ_MASK); + } + } + } + break; + case MFS_CACK: + (void)printf("conn-ack %d", dst); + break; + default: + (void)printf("reserved-acktype? %x %d > %d", flags, src, dst); + break; + } + break; + case MFT_CTL: + switch (flags & NSP_SUBMASK) { + case MFS_CI: + case MFS_RCI: + if ((flags & NSP_SUBMASK) == MFS_CI) + (void)printf("conn-initiate "); + else + (void)printf("retrans-conn-initiate "); + (void)printf("%d>%d ", src, dst); + { + struct cimsg *cimp = (struct cimsg *)nspp; + int services, info, segsize; +#ifdef PRINT_NSPDATA + u_char *dp; +#endif + + if (nsplen < sizeof(struct cimsg)) + goto trunc; + TCHECK(*cimp); + services = EXTRACT_LE_8BITS(cimp->ci_services); + info = EXTRACT_LE_8BITS(cimp->ci_info); + segsize = EXTRACT_LE_16BITS(cimp->ci_segsize); + + switch (services & COS_MASK) { + case COS_NONE: + break; + case COS_SEGMENT: + (void)printf("seg "); + break; + case COS_MESSAGE: + (void)printf("msg "); + break; + case COS_CRYPTSER: + (void)printf("crypt "); + break; + } + switch (info & COI_MASK) { + case COI_32: + (void)printf("ver 3.2 "); + break; + case COI_31: + (void)printf("ver 3.1 "); + break; + case COI_40: + (void)printf("ver 4.0 "); + break; + case COI_41: + (void)printf("ver 4.1 "); + break; + } + (void)printf("segsize %d ", segsize); +#ifdef PRINT_NSPDATA + if (nsplen > sizeof(struct cimsg)) { + dp = &(nspp[sizeof(struct cimsg)]); + TCHECK2(*dp, nsplen - sizeof(struct cimsg)); + pdata(dp, nsplen - sizeof(struct cimsg)); + } +#endif + } + break; + case MFS_CC: + (void)printf("conn-confirm %d>%d ", src, dst); + { + struct ccmsg *ccmp = (struct ccmsg *)nspp; + int services, info; + u_int segsize, optlen; +#ifdef PRINT_NSPDATA + u_char *dp; +#endif + + if (nsplen < sizeof(struct ccmsg)) + goto trunc; + TCHECK(*ccmp); + services = EXTRACT_LE_8BITS(ccmp->cc_services); + info = EXTRACT_LE_8BITS(ccmp->cc_info); + segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize); + optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen); + + switch (services & COS_MASK) { + case COS_NONE: + break; + case COS_SEGMENT: + (void)printf("seg "); + break; + case COS_MESSAGE: + (void)printf("msg "); + break; + case COS_CRYPTSER: + (void)printf("crypt "); + break; + } + switch (info & COI_MASK) { + case COI_32: + (void)printf("ver 3.2 "); + break; + case COI_31: + (void)printf("ver 3.1 "); + break; + case COI_40: + (void)printf("ver 4.0 "); + break; + case COI_41: + (void)printf("ver 4.1 "); + break; + } + (void)printf("segsize %d ", segsize); + if (optlen) { + (void)printf("optlen %d ", optlen); +#ifdef PRINT_NSPDATA + if (optlen > nsplen - sizeof(struct ccmsg)) + goto trunc; + dp = &(nspp[sizeof(struct ccmsg)]); + TCHECK2(*dp, optlen); + pdata(dp, optlen); +#endif + } + } + break; + case MFS_DI: + (void)printf("disconn-initiate %d>%d ", src, dst); + { + struct dimsg *dimp = (struct dimsg *)nspp; + int reason; + u_int optlen; +#ifdef PRINT_NSPDATA + u_char *dp; +#endif + + if (nsplen < sizeof(struct dimsg)) + goto trunc; + TCHECK(*dimp); + reason = EXTRACT_LE_16BITS(dimp->di_reason); + optlen = EXTRACT_LE_8BITS(dimp->di_optlen); + + print_reason(reason); + if (optlen) { + (void)printf("optlen %d ", optlen); +#ifdef PRINT_NSPDATA + if (optlen > nsplen - sizeof(struct dimsg)) + goto trunc; + dp = &(nspp[sizeof(struct dimsg)]); + TCHECK2(*dp, optlen); + pdata(dp, optlen); +#endif + } + } + break; + case MFS_DC: + (void)printf("disconn-confirm %d>%d ", src, dst); + { + struct dcmsg *dcmp = (struct dcmsg *)nspp; + int reason; + + TCHECK(*dcmp); + reason = EXTRACT_LE_16BITS(dcmp->dc_reason); + + print_reason(reason); + } + break; + default: + (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst); + break; + } + break; + default: + (void)printf("reserved-type? %x %d > %d", flags, src, dst); + break; + } + return (1); + +trunc: + return (0); +} + +static struct tok reason2str[] = { + { UC_OBJREJECT, "object rejected connect" }, + { UC_RESOURCES, "insufficient resources" }, + { UC_NOSUCHNODE, "unrecognized node name" }, + { DI_SHUT, "node is shutting down" }, + { UC_NOSUCHOBJ, "unrecognized object" }, + { UC_INVOBJFORMAT, "invalid object name format" }, + { UC_OBJTOOBUSY, "object too busy" }, + { DI_PROTOCOL, "protocol error discovered" }, + { DI_TPA, "third party abort" }, + { UC_USERABORT, "user abort" }, + { UC_INVNODEFORMAT, "invalid node name format" }, + { UC_LOCALSHUT, "local node shutting down" }, + { DI_LOCALRESRC, "insufficient local resources" }, + { DI_REMUSERRESRC, "insufficient remote user resources" }, + { UC_ACCESSREJECT, "invalid access control information" }, + { DI_BADACCNT, "bad ACCOUNT information" }, + { UC_NORESPONSE, "no response from object" }, + { UC_UNREACHABLE, "node unreachable" }, + { DC_NOLINK, "no link terminate" }, + { DC_COMPLETE, "disconnect complete" }, + { DI_BADIMAGE, "bad image data in connect" }, + { DI_SERVMISMATCH, "cryptographic service mismatch" }, + { 0, NULL } +}; + +static void +print_reason(register int reason) +{ + printf("%s ", tok2str(reason2str, "reason-%d", reason)); +} + +const char * +dnnum_string(u_short dnaddr) +{ + char *str; + size_t siz; + int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT; + int node = dnaddr & NODEMASK; + + str = (char *)malloc(siz = sizeof("00.0000")); + if (str == NULL) + error("dnnum_string: malloc"); + snprintf(str, siz, "%d.%d", area, node); + return(str); +} + +const char * +dnname_string(u_short dnaddr) +{ +#ifdef HAVE_DNET_HTOA + struct dn_naddr dna; + + dna.a_len = sizeof(short); + memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short)); + return (strdup(dnet_htoa(&dna))); +#else + return(dnnum_string(dnaddr)); /* punt */ +#endif +} + +#ifdef PRINT_NSPDATA +static void +pdata(u_char *dp, u_int maxlen) +{ + char c; + u_int x = maxlen; + + while (x-- > 0) { + c = *dp++; + safeputchar(c); + } +} +#endif diff --git a/freebsd/contrib/tcpdump/print-dhcp6.c b/freebsd/contrib/tcpdump/print-dhcp6.c new file mode 100644 index 00000000..fbb31261 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-dhcp6.c @@ -0,0 +1,871 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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, + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#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 23 +#define DH6OPT_DNSNAME 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_NTP_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_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: + return "DNS-server"; + case DH6OPT_DNSNAME: + return "DNS-search-list"; + case DH6OPT_IA_PD: + return "IA_PD"; + case DH6OPT_IA_PD_PREFIX: + return "IA_PD-prefix"; + case DH6OPT_NTP_SERVERS: + return "NTP-server"; + 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_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) +{ + struct dhcp6opt *dh6o; + u_char *tp; + size_t i; + u_int16_t opttype; + size_t optlen; + u_int8_t auth_proto; + u_int authinfolen, authrealmlen; + + 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: + case DH6OPT_NTP_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_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_AFTR_NAME: + if (optlen < 3) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + int remain_len = optlen; + printf(" "); + /* Encoding is described in section 3.1 of RFC 1035 */ + int label_len; /* Label length */ + 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]"); +} diff --git a/freebsd/contrib/tcpdump/print-domain.c b/freebsd/contrib/tcpdump/print-domain.c new file mode 100644 index 00000000..412e1308 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-domain.c @@ -0,0 +1,755 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.98 2007-12-09 01:40:32 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include "nameser.h" + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +static const char *ns_ops[] = { + "", " inv_q", " stat", " op3", " notify", " update", " op6", " op7", + " op8", " updataA", " updateD", " updateDA", + " updateM", " updateMA", " zoneInit", " zoneRef", +}; + +static const char *ns_resp[] = { + "", " FormErr", " ServFail", " NXDomain", + " NotImp", " Refused", " YXDomain", " YXRRSet", + " NXRRSet", " NotAuth", " NotZone", " Resp11", + " Resp12", " Resp13", " Resp14", " NoChange", +}; + +/* skip over a domain name */ +static const u_char * +ns_nskip(register const u_char *cp) +{ + register u_char i; + + if (!TTEST2(*cp, 1)) + return (NULL); + i = *cp++; + while (i) { + if ((i & INDIR_MASK) == INDIR_MASK) + return (cp + 1); + if ((i & INDIR_MASK) == EDNS0_MASK) { + int bitlen, bytelen; + + if ((i & ~INDIR_MASK) != EDNS0_ELT_BITLABEL) + return(NULL); /* unknown ELT */ + if (!TTEST2(*cp, 1)) + return (NULL); + if ((bitlen = *cp++) == 0) + bitlen = 256; + bytelen = (bitlen + 7) / 8; + cp += bytelen; + } else + cp += i; + if (!TTEST2(*cp, 1)) + return (NULL); + i = *cp++; + } + return (cp); +} + +/* print a <domain-name> */ +static const u_char * +blabel_print(const u_char *cp) +{ + int bitlen, slen, b; + const u_char *bitp, *lim; + char tc; + + if (!TTEST2(*cp, 1)) + return(NULL); + if ((bitlen = *cp) == 0) + bitlen = 256; + slen = (bitlen + 3) / 4; + lim = cp + 1 + slen; + + /* print the bit string as a hex string */ + printf("\\[x"); + for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++) { + TCHECK(*bitp); + printf("%02x", *bitp); + } + if (b > 4) { + TCHECK(*bitp); + tc = *bitp++; + printf("%02x", tc & (0xff << (8 - b))); + } else if (b > 0) { + TCHECK(*bitp); + tc = *bitp++; + printf("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b))); + } + printf("/%d]", bitlen); + return lim; +trunc: + printf(".../%d]", bitlen); + return NULL; +} + +static int +labellen(const u_char *cp) +{ + register u_int i; + + if (!TTEST2(*cp, 1)) + return(-1); + i = *cp; + if ((i & INDIR_MASK) == EDNS0_MASK) { + int bitlen, elt; + if ((elt = (i & ~INDIR_MASK)) != EDNS0_ELT_BITLABEL) { + printf("<ELT %d>", elt); + return(-1); + } + if (!TTEST2(*(cp + 1), 1)) + return(-1); + if ((bitlen = *(cp + 1)) == 0) + bitlen = 256; + return(((bitlen + 7) / 8) + 1); + } else + return(i); +} + +const u_char * +ns_nprint(register const u_char *cp, register const u_char *bp) +{ + register u_int i, l; + register const u_char *rp = NULL; + register int compress = 0; + int chars_processed; + int elt; + int data_size = snapend - bp; + + if ((l = labellen(cp)) == (u_int)-1) + return(NULL); + if (!TTEST2(*cp, 1)) + return(NULL); + chars_processed = 1; + if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) { + compress = 0; + rp = cp + l; + } + + if (i != 0) + while (i && cp < snapend) { + if ((i & INDIR_MASK) == INDIR_MASK) { + if (!compress) { + rp = cp + 1; + compress = 1; + } + if (!TTEST2(*cp, 1)) + return(NULL); + cp = bp + (((i << 8) | *cp) & 0x3fff); + if ((l = labellen(cp)) == (u_int)-1) + return(NULL); + if (!TTEST2(*cp, 1)) + return(NULL); + i = *cp++; + chars_processed++; + + /* + * If we've looked at every character in + * the message, this pointer will make + * us look at some character again, + * which means we're looping. + */ + if (chars_processed >= data_size) { + printf("<LOOP>"); + return (NULL); + } + continue; + } + if ((i & INDIR_MASK) == EDNS0_MASK) { + elt = (i & ~INDIR_MASK); + switch(elt) { + case EDNS0_ELT_BITLABEL: + if (blabel_print(cp) == NULL) + return (NULL); + break; + default: + /* unknown ELT */ + printf("<ELT %d>", elt); + return(NULL); + } + } else { + if (fn_printn(cp, l, snapend)) + return(NULL); + } + + cp += l; + chars_processed += l; + putchar('.'); + if ((l = labellen(cp)) == (u_int)-1) + return(NULL); + if (!TTEST2(*cp, 1)) + return(NULL); + i = *cp++; + chars_processed++; + if (!compress) + rp += l + 1; + } + else + putchar('.'); + return (rp); +} + +/* print a <character-string> */ +static const u_char * +ns_cprint(register const u_char *cp) +{ + register u_int i; + + if (!TTEST2(*cp, 1)) + return (NULL); + i = *cp++; + if (fn_printn(cp, i, snapend)) + return (NULL); + return (cp + i); +} + +/* http://www.iana.org/assignments/dns-parameters */ +struct tok ns_type2str[] = { + { T_A, "A" }, /* RFC 1035 */ + { T_NS, "NS" }, /* RFC 1035 */ + { T_MD, "MD" }, /* RFC 1035 */ + { T_MF, "MF" }, /* RFC 1035 */ + { T_CNAME, "CNAME" }, /* RFC 1035 */ + { T_SOA, "SOA" }, /* RFC 1035 */ + { T_MB, "MB" }, /* RFC 1035 */ + { T_MG, "MG" }, /* RFC 1035 */ + { T_MR, "MR" }, /* RFC 1035 */ + { T_NULL, "NULL" }, /* RFC 1035 */ + { T_WKS, "WKS" }, /* RFC 1035 */ + { T_PTR, "PTR" }, /* RFC 1035 */ + { T_HINFO, "HINFO" }, /* RFC 1035 */ + { T_MINFO, "MINFO" }, /* RFC 1035 */ + { T_MX, "MX" }, /* RFC 1035 */ + { T_TXT, "TXT" }, /* RFC 1035 */ + { T_RP, "RP" }, /* RFC 1183 */ + { T_AFSDB, "AFSDB" }, /* RFC 1183 */ + { T_X25, "X25" }, /* RFC 1183 */ + { T_ISDN, "ISDN" }, /* RFC 1183 */ + { T_RT, "RT" }, /* RFC 1183 */ + { T_NSAP, "NSAP" }, /* RFC 1706 */ + { T_NSAP_PTR, "NSAP_PTR" }, + { T_SIG, "SIG" }, /* RFC 2535 */ + { T_KEY, "KEY" }, /* RFC 2535 */ + { T_PX, "PX" }, /* RFC 2163 */ + { T_GPOS, "GPOS" }, /* RFC 1712 */ + { T_AAAA, "AAAA" }, /* RFC 1886 */ + { T_LOC, "LOC" }, /* RFC 1876 */ + { T_NXT, "NXT" }, /* RFC 2535 */ + { T_EID, "EID" }, /* Nimrod */ + { T_NIMLOC, "NIMLOC" }, /* Nimrod */ + { T_SRV, "SRV" }, /* RFC 2782 */ + { T_ATMA, "ATMA" }, /* ATM Forum */ + { T_NAPTR, "NAPTR" }, /* RFC 2168, RFC 2915 */ + { T_KX, "KX" }, /* RFC 2230 */ + { T_CERT, "CERT" }, /* RFC 2538 */ + { T_A6, "A6" }, /* RFC 2874 */ + { T_DNAME, "DNAME" }, /* RFC 2672 */ + { T_SINK, "SINK" }, + { T_OPT, "OPT" }, /* RFC 2671 */ + { T_APL, "APL" }, /* RFC 3123 */ + { T_DS, "DS" }, /* RFC 4034 */ + { T_SSHFP, "SSHFP" }, /* RFC 4255 */ + { T_IPSECKEY, "IPSECKEY" }, /* RFC 4025 */ + { T_RRSIG, "RRSIG" }, /* RFC 4034 */ + { T_NSEC, "NSEC" }, /* RFC 4034 */ + { T_DNSKEY, "DNSKEY" }, /* RFC 4034 */ + { T_SPF, "SPF" }, /* RFC-schlitt-spf-classic-02.txt */ + { T_UINFO, "UINFO" }, + { T_UID, "UID" }, + { T_GID, "GID" }, + { T_UNSPEC, "UNSPEC" }, + { T_UNSPECA, "UNSPECA" }, + { T_TKEY, "TKEY" }, /* RFC 2930 */ + { T_TSIG, "TSIG" }, /* RFC 2845 */ + { T_IXFR, "IXFR" }, /* RFC 1995 */ + { T_AXFR, "AXFR" }, /* RFC 1035 */ + { T_MAILB, "MAILB" }, /* RFC 1035 */ + { T_MAILA, "MAILA" }, /* RFC 1035 */ + { T_ANY, "ANY" }, + { 0, NULL } +}; + +struct tok ns_class2str[] = { + { C_IN, "IN" }, /* Not used */ + { C_CHAOS, "CHAOS" }, + { C_HS, "HS" }, + { C_ANY, "ANY" }, + { 0, NULL } +}; + +/* print a query */ +static const u_char * +ns_qprint(register const u_char *cp, register const u_char *bp, int is_mdns) +{ + register const u_char *np = cp; + register u_int i, class; + + cp = ns_nskip(cp); + + if (cp == NULL || !TTEST2(*cp, 4)) + return(NULL); + + /* print the qtype */ + i = EXTRACT_16BITS(cp); + cp += 2; + printf(" %s", tok2str(ns_type2str, "Type%d", i)); + /* print the qclass (if it's not IN) */ + i = EXTRACT_16BITS(cp); + cp += 2; + if (is_mdns) + class = (i & ~C_QU); + else + class = i; + if (class != C_IN) + printf(" %s", tok2str(ns_class2str, "(Class %d)", class)); + if (is_mdns) { + if (i & C_QU) + printf(" (QU)"); + else + printf(" (QM)"); + } + + fputs("? ", stdout); + cp = ns_nprint(np, bp); + return(cp ? cp + 4 : NULL); +} + +/* print a reply */ +static const u_char * +ns_rprint(register const u_char *cp, register const u_char *bp, int is_mdns) +{ + register u_int i, class, opt_flags = 0; + register u_short typ, len; + register const u_char *rp; + + if (vflag) { + putchar(' '); + if ((cp = ns_nprint(cp, bp)) == NULL) + return NULL; + } else + cp = ns_nskip(cp); + + if (cp == NULL || !TTEST2(*cp, 10)) + return (snapend); + + /* print the type/qtype */ + typ = EXTRACT_16BITS(cp); + cp += 2; + /* print the class (if it's not IN and the type isn't OPT) */ + i = EXTRACT_16BITS(cp); + cp += 2; + if (is_mdns) + class = (i & ~C_CACHE_FLUSH); + else + class = i; + if (class != C_IN && typ != T_OPT) + printf(" %s", tok2str(ns_class2str, "(Class %d)", class)); + if (is_mdns) { + if (i & C_CACHE_FLUSH) + printf(" (Cache flush)"); + } + + if (typ == T_OPT) { + /* get opt flags */ + cp += 2; + opt_flags = EXTRACT_16BITS(cp); + /* ignore rest of ttl field */ + cp += 2; + } else if (vflag > 2) { + /* print ttl */ + printf(" ["); + relts_print(EXTRACT_32BITS(cp)); + printf("]"); + cp += 4; + } else { + /* ignore ttl */ + cp += 4; + } + + len = EXTRACT_16BITS(cp); + cp += 2; + + rp = cp + len; + + printf(" %s", tok2str(ns_type2str, "Type%d", typ)); + if (rp > snapend) + return(NULL); + + switch (typ) { + case T_A: + if (!TTEST2(*cp, sizeof(struct in_addr))) + return(NULL); + printf(" %s", intoa(htonl(EXTRACT_32BITS(cp)))); + break; + + case T_NS: + case T_CNAME: + case T_PTR: +#ifdef T_DNAME + case T_DNAME: +#endif + putchar(' '); + if (ns_nprint(cp, bp) == NULL) + return(NULL); + break; + + case T_SOA: + if (!vflag) + break; + putchar(' '); + if ((cp = ns_nprint(cp, bp)) == NULL) + return(NULL); + putchar(' '); + if ((cp = ns_nprint(cp, bp)) == NULL) + return(NULL); + if (!TTEST2(*cp, 5 * 4)) + return(NULL); + printf(" %u", EXTRACT_32BITS(cp)); + cp += 4; + printf(" %u", EXTRACT_32BITS(cp)); + cp += 4; + printf(" %u", EXTRACT_32BITS(cp)); + cp += 4; + printf(" %u", EXTRACT_32BITS(cp)); + cp += 4; + printf(" %u", EXTRACT_32BITS(cp)); + cp += 4; + break; + case T_MX: + putchar(' '); + if (!TTEST2(*cp, 2)) + return(NULL); + if (ns_nprint(cp + 2, bp) == NULL) + return(NULL); + printf(" %d", EXTRACT_16BITS(cp)); + break; + + case T_TXT: + while (cp < rp) { + printf(" \""); + cp = ns_cprint(cp); + if (cp == NULL) + return(NULL); + putchar('"'); + } + break; + + case T_SRV: + putchar(' '); + if (!TTEST2(*cp, 6)) + return(NULL); + if (ns_nprint(cp + 6, bp) == NULL) + return(NULL); + printf(":%d %d %d", EXTRACT_16BITS(cp + 4), + EXTRACT_16BITS(cp), EXTRACT_16BITS(cp + 2)); + break; + +#ifdef INET6 + case T_AAAA: + { + struct in6_addr addr; + char ntop_buf[INET6_ADDRSTRLEN]; + + if (!TTEST2(*cp, sizeof(struct in6_addr))) + return(NULL); + memcpy(&addr, cp, sizeof(struct in6_addr)); + printf(" %s", + inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf))); + + break; + } + + case T_A6: + { + struct in6_addr a; + int pbit, pbyte; + char ntop_buf[INET6_ADDRSTRLEN]; + + if (!TTEST2(*cp, 1)) + return(NULL); + pbit = *cp; + pbyte = (pbit & ~7) / 8; + if (pbit > 128) { + printf(" %u(bad plen)", pbit); + break; + } else if (pbit < 128) { + if (!TTEST2(*(cp + 1), sizeof(a) - pbyte)) + return(NULL); + memset(&a, 0, sizeof(a)); + memcpy(&a.s6_addr[pbyte], cp + 1, sizeof(a) - pbyte); + printf(" %u %s", pbit, + inet_ntop(AF_INET6, &a, ntop_buf, sizeof(ntop_buf))); + } + if (pbit > 0) { + putchar(' '); + if (ns_nprint(cp + 1 + sizeof(a) - pbyte, bp) == NULL) + return(NULL); + } + break; + } +#endif /*INET6*/ + + case T_OPT: + printf(" UDPsize=%u", class); + if (opt_flags & 0x8000) + printf(" OK"); + break; + + case T_UNSPECA: /* One long string */ + if (!TTEST2(*cp, len)) + return(NULL); + if (fn_printn(cp, len, snapend)) + return(NULL); + break; + + case T_TSIG: + { + if (cp + len > snapend) + return(NULL); + if (!vflag) + break; + putchar(' '); + if ((cp = ns_nprint(cp, bp)) == NULL) + return(NULL); + cp += 6; + if (!TTEST2(*cp, 2)) + return(NULL); + printf(" fudge=%u", EXTRACT_16BITS(cp)); + cp += 2; + if (!TTEST2(*cp, 2)) + return(NULL); + printf(" maclen=%u", EXTRACT_16BITS(cp)); + cp += 2 + EXTRACT_16BITS(cp); + if (!TTEST2(*cp, 2)) + return(NULL); + printf(" origid=%u", EXTRACT_16BITS(cp)); + cp += 2; + if (!TTEST2(*cp, 2)) + return(NULL); + printf(" error=%u", EXTRACT_16BITS(cp)); + cp += 2; + if (!TTEST2(*cp, 2)) + return(NULL); + printf(" otherlen=%u", EXTRACT_16BITS(cp)); + cp += 2; + } + } + return (rp); /* XXX This isn't always right */ +} + +void +ns_print(register const u_char *bp, u_int length, int is_mdns) +{ + register const HEADER *np; + register int qdcount, ancount, nscount, arcount; + register const u_char *cp; + u_int16_t b2; + + np = (const HEADER *)bp; + TCHECK(*np); + /* get the byte-order right */ + qdcount = EXTRACT_16BITS(&np->qdcount); + ancount = EXTRACT_16BITS(&np->ancount); + nscount = EXTRACT_16BITS(&np->nscount); + arcount = EXTRACT_16BITS(&np->arcount); + + if (DNS_QR(np)) { + /* this is a response */ + printf("%d%s%s%s%s%s%s", + EXTRACT_16BITS(&np->id), + ns_ops[DNS_OPCODE(np)], + ns_resp[DNS_RCODE(np)], + DNS_AA(np)? "*" : "", + DNS_RA(np)? "" : "-", + DNS_TC(np)? "|" : "", + DNS_AD(np)? "$" : ""); + + if (qdcount != 1) + printf(" [%dq]", qdcount); + /* Print QUESTION section on -vv */ + cp = (const u_char *)(np + 1); + while (qdcount--) { + if (qdcount < EXTRACT_16BITS(&np->qdcount) - 1) + putchar(','); + if (vflag > 1) { + fputs(" q:", stdout); + if ((cp = ns_qprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } else { + if ((cp = ns_nskip(cp)) == NULL) + goto trunc; + cp += 4; /* skip QTYPE and QCLASS */ + } + } + printf(" %d/%d/%d", ancount, nscount, arcount); + if (ancount--) { + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (cp < snapend && ancount--) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (ancount > 0) + goto trunc; + /* Print NS and AR sections on -vv */ + if (vflag > 1) { + if (cp < snapend && nscount--) { + fputs(" ns:", stdout); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (cp < snapend && nscount--) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (nscount > 0) + goto trunc; + if (cp < snapend && arcount--) { + fputs(" ar:", stdout); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (cp < snapend && arcount--) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (arcount > 0) + goto trunc; + } + } + else { + /* this is a request */ + printf("%d%s%s%s", EXTRACT_16BITS(&np->id), ns_ops[DNS_OPCODE(np)], + DNS_RD(np) ? "+" : "", + DNS_CD(np) ? "%" : ""); + + /* any weirdness? */ + b2 = EXTRACT_16BITS(((u_short *)np)+1); + if (b2 & 0x6cf) + printf(" [b2&3=0x%x]", b2); + + if (DNS_OPCODE(np) == IQUERY) { + if (qdcount) + printf(" [%dq]", qdcount); + if (ancount != 1) + printf(" [%da]", ancount); + } + else { + if (ancount) + printf(" [%da]", ancount); + if (qdcount != 1) + printf(" [%dq]", qdcount); + } + if (nscount) + printf(" [%dn]", nscount); + if (arcount) + printf(" [%dau]", arcount); + + cp = (const u_char *)(np + 1); + if (qdcount--) { + cp = ns_qprint(cp, (const u_char *)np, is_mdns); + if (!cp) + goto trunc; + while (cp < snapend && qdcount--) { + cp = ns_qprint((const u_char *)cp, + (const u_char *)np, + is_mdns); + if (!cp) + goto trunc; + } + } + if (qdcount > 0) + goto trunc; + + /* Print remaining sections on -vv */ + if (vflag > 1) { + if (ancount--) { + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (cp < snapend && ancount--) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (ancount > 0) + goto trunc; + if (cp < snapend && nscount--) { + fputs(" ns:", stdout); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (nscount-- && cp < snapend) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (nscount > 0) + goto trunc; + if (cp < snapend && arcount--) { + fputs(" ar:", stdout); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (cp < snapend && arcount--) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (arcount > 0) + goto trunc; + } + } + printf(" (%d)", length); + return; + + trunc: + printf("[|domain]"); + return; +} diff --git a/freebsd/contrib/tcpdump/print-dtp.c b/freebsd/contrib/tcpdump/print-dtp.c new file mode 100644 index 00000000..f1471e86 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-dtp.c @@ -0,0 +1,125 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * Dynamic Trunk Protocol (DTP) + * + * Original code by Carles Kishimoto <carles.kishimoto@gmail.com> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "nlpid.h" + +#define DTP_HEADER_LEN 1 +#define DTP_DOMAIN_TLV 0x0001 +#define DTP_STATUS_TLV 0x0002 +#define DTP_DTP_TYPE_TLV 0x0003 +#define DTP_NEIGHBOR_TLV 0x0004 + +static struct tok dtp_tlv_values[] = { + { DTP_DOMAIN_TLV, "Domain TLV"}, + { DTP_STATUS_TLV, "Status TLV"}, + { DTP_DTP_TYPE_TLV, "DTP type TLV"}, + { DTP_NEIGHBOR_TLV, "Neighbor TLV"}, + { 0, NULL} +}; + +void +dtp_print (const u_char *pptr, u_int length) +{ + int type, len; + const u_char *tptr; + + if (length < DTP_HEADER_LEN) + goto trunc; + + tptr = pptr; + + if (!TTEST2(*tptr, DTP_HEADER_LEN)) + goto trunc; + + printf("DTPv%u, length %u", + (*tptr), + length); + + /* + * In non-verbose mode, just print version. + */ + if (vflag < 1) { + return; + } + + tptr += DTP_HEADER_LEN; + + while (tptr < (pptr+length)) { + + if (!TTEST2(*tptr, 4)) + goto trunc; + + type = EXTRACT_16BITS(tptr); + len = EXTRACT_16BITS(tptr+2); + + /* infinite loop check */ + if (type == 0 || len == 0) { + return; + } + + printf("\n\t%s (0x%04x) TLV, length %u", + tok2str(dtp_tlv_values, "Unknown", type), + type, len); + + switch (type) { + case DTP_DOMAIN_TLV: + printf(", %s", tptr+4); + break; + + case DTP_STATUS_TLV: + case DTP_DTP_TYPE_TLV: + printf(", 0x%x", *(tptr+4)); + break; + + case DTP_NEIGHBOR_TLV: + printf(", %s", etheraddr_string(tptr+4)); + break; + + default: + break; + } + tptr += len; + } + + return; + + trunc: + printf("[|dtp]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-dvmrp.c b/freebsd/contrib/tcpdump/print-dvmrp.c new file mode 100644 index 00000000..4f553b7d --- /dev/null +++ b/freebsd/contrib/tcpdump/print-dvmrp.c @@ -0,0 +1,371 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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-dvmrp.c,v 1.27 2003-11-19 09:42:04 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * DVMRP message types and flag values shamelessly stolen from + * mrouted/dvmrp.h. + */ +#define DVMRP_PROBE 1 /* for finding neighbors */ +#define DVMRP_REPORT 2 /* for reporting some or all routes */ +#define DVMRP_ASK_NEIGHBORS 3 /* sent by mapper, asking for a list */ + /* of this router's neighbors */ +#define DVMRP_NEIGHBORS 4 /* response to such a request */ +#define DVMRP_ASK_NEIGHBORS2 5 /* as above, want new format reply */ +#define DVMRP_NEIGHBORS2 6 +#define DVMRP_PRUNE 7 /* prune message */ +#define DVMRP_GRAFT 8 /* graft message */ +#define DVMRP_GRAFT_ACK 9 /* graft acknowledgement */ + +/* + * 'flags' byte values in DVMRP_NEIGHBORS2 reply. + */ +#define DVMRP_NF_TUNNEL 0x01 /* neighbors reached via tunnel */ +#define DVMRP_NF_SRCRT 0x02 /* tunnel uses IP source routing */ +#define DVMRP_NF_DOWN 0x10 /* kernel state of interface */ +#define DVMRP_NF_DISABLED 0x20 /* administratively disabled */ +#define DVMRP_NF_QUERIER 0x40 /* I am the subnet's querier */ + +static int print_probe(const u_char *, const u_char *, u_int); +static int print_report(const u_char *, const u_char *, u_int); +static int print_neighbors(const u_char *, const u_char *, u_int); +static int print_neighbors2(const u_char *, const u_char *, u_int); +static int print_prune(const u_char *); +static int print_graft(const u_char *); +static int print_graft_ack(const u_char *); + +static u_int32_t target_level; + +void +dvmrp_print(register const u_char *bp, register u_int len) +{ + register const u_char *ep; + register u_char type; + + ep = (const u_char *)snapend; + if (bp >= ep) + return; + + TCHECK(bp[1]); + type = bp[1]; + + /* Skip IGMP header */ + bp += 8; + len -= 8; + + switch (type) { + + case DVMRP_PROBE: + printf(" Probe"); + if (vflag) { + if (print_probe(bp, ep, len) < 0) + goto trunc; + } + break; + + case DVMRP_REPORT: + printf(" Report"); + if (vflag > 1) { + if (print_report(bp, ep, len) < 0) + goto trunc; + } + break; + + case DVMRP_ASK_NEIGHBORS: + printf(" Ask-neighbors(old)"); + break; + + case DVMRP_NEIGHBORS: + printf(" Neighbors(old)"); + if (print_neighbors(bp, ep, len) < 0) + goto trunc; + break; + + case DVMRP_ASK_NEIGHBORS2: + printf(" Ask-neighbors2"); + break; + + case DVMRP_NEIGHBORS2: + printf(" Neighbors2"); + /* + * extract version and capabilities from IGMP group + * address field + */ + bp -= 4; + TCHECK2(bp[0], 4); + target_level = (bp[0] << 24) | (bp[1] << 16) | + (bp[2] << 8) | bp[3]; + bp += 4; + if (print_neighbors2(bp, ep, len) < 0) + goto trunc; + break; + + case DVMRP_PRUNE: + printf(" Prune"); + if (print_prune(bp) < 0) + goto trunc; + break; + + case DVMRP_GRAFT: + printf(" Graft"); + if (print_graft(bp) < 0) + goto trunc; + break; + + case DVMRP_GRAFT_ACK: + printf(" Graft-ACK"); + if (print_graft_ack(bp) < 0) + goto trunc; + break; + + default: + printf(" [type %d]", type); + break; + } + return; + +trunc: + printf("[|dvmrp]"); + return; +} + +static int +print_report(register const u_char *bp, register const u_char *ep, + register u_int len) +{ + register u_int32_t mask, origin; + register int metric, done; + register u_int i, width; + + while (len > 0) { + if (len < 3) { + printf(" [|]"); + return (0); + } + TCHECK2(bp[0], 3); + mask = (u_int32_t)0xff << 24 | bp[0] << 16 | bp[1] << 8 | bp[2]; + width = 1; + if (bp[0]) + width = 2; + if (bp[1]) + width = 3; + if (bp[2]) + width = 4; + + printf("\n\tMask %s", intoa(htonl(mask))); + bp += 3; + len -= 3; + do { + if (bp + width + 1 > ep) { + printf(" [|]"); + return (0); + } + if (len < width + 1) { + printf("\n\t [Truncated Report]"); + return (0); + } + origin = 0; + for (i = 0; i < width; ++i) { + TCHECK(*bp); + origin = origin << 8 | *bp++; + } + for ( ; i < 4; ++i) + origin <<= 8; + + TCHECK(*bp); + metric = *bp++; + done = metric & 0x80; + metric &= 0x7f; + printf("\n\t %s metric %d", intoa(htonl(origin)), + metric); + len -= width + 1; + } while (!done); + } + return (0); +trunc: + return (-1); +} + +static int +print_probe(register const u_char *bp, register const u_char *ep, + register u_int len) +{ + register u_int32_t genid; + + TCHECK2(bp[0], 4); + if ((len < 4) || ((bp + 4) > ep)) { + /* { (ctags) */ + printf(" [|}"); + return (0); + } + genid = (bp[0] << 24) | (bp[1] << 16) | (bp[2] << 8) | bp[3]; + bp += 4; + len -= 4; + if (vflag > 1) + printf("\n\t"); + else + printf(" "); + printf("genid %u", genid); + if (vflag < 2) + return (0); + + while ((len > 0) && (bp < ep)) { + TCHECK2(bp[0], 4); + printf("\n\tneighbor %s", ipaddr_string(bp)); + bp += 4; len -= 4; + } + return (0); +trunc: + return (-1); +} + +static int +print_neighbors(register const u_char *bp, register const u_char *ep, + register u_int len) +{ + const u_char *laddr; + register u_char metric; + register u_char thresh; + register int ncount; + + while (len > 0 && bp < ep) { + TCHECK2(bp[0], 7); + laddr = bp; + bp += 4; + metric = *bp++; + thresh = *bp++; + ncount = *bp++; + len -= 7; + while (--ncount >= 0) { + TCHECK2(bp[0], 4); + printf(" [%s ->", ipaddr_string(laddr)); + printf(" %s, (%d/%d)]", + ipaddr_string(bp), metric, thresh); + bp += 4; + len -= 4; + } + } + return (0); +trunc: + return (-1); +} + +static int +print_neighbors2(register const u_char *bp, register const u_char *ep, + register u_int len) +{ + const u_char *laddr; + register u_char metric, thresh, flags; + register int ncount; + + printf(" (v %d.%d):", + (int)target_level & 0xff, + (int)(target_level >> 8) & 0xff); + + while (len > 0 && bp < ep) { + TCHECK2(bp[0], 8); + laddr = bp; + bp += 4; + metric = *bp++; + thresh = *bp++; + flags = *bp++; + ncount = *bp++; + len -= 8; + while (--ncount >= 0 && (len >= 4) && (bp + 4) <= ep) { + printf(" [%s -> ", ipaddr_string(laddr)); + printf("%s (%d/%d", ipaddr_string(bp), + metric, thresh); + if (flags & DVMRP_NF_TUNNEL) + printf("/tunnel"); + if (flags & DVMRP_NF_SRCRT) + printf("/srcrt"); + if (flags & DVMRP_NF_QUERIER) + printf("/querier"); + if (flags & DVMRP_NF_DISABLED) + printf("/disabled"); + if (flags & DVMRP_NF_DOWN) + printf("/down"); + printf(")]"); + bp += 4; + len -= 4; + } + if (ncount != -1) { + printf(" [|]"); + return (0); + } + } + return (0); +trunc: + return (-1); +} + +static int +print_prune(register const u_char *bp) +{ + TCHECK2(bp[0], 12); + printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4)); + bp += 8; + (void)printf(" timer "); + relts_print(EXTRACT_32BITS(bp)); + return (0); +trunc: + return (-1); +} + +static int +print_graft(register const u_char *bp) +{ + TCHECK2(bp[0], 8); + printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4)); + return (0); +trunc: + return (-1); +} + +static int +print_graft_ack(register const u_char *bp) +{ + TCHECK2(bp[0], 8); + printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4)); + return (0); +trunc: + return (-1); +} diff --git a/freebsd/contrib/tcpdump/print-eap.c b/freebsd/contrib/tcpdump/print-eap.c new file mode 100644 index 00000000..5730dbb7 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-eap.c @@ -0,0 +1,309 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2004 - Michael Richardson <mcr@xelerance.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. + * + * Format and print EAP packets. + * + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-eap.c,v 1.5 2007-10-04 16:41:33 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "netdissect.h" +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "ether.h" + +#define EAP_FRAME_TYPE_PACKET 0 +#define EAP_FRAME_TYPE_START 1 +#define EAP_FRAME_TYPE_LOGOFF 2 +#define EAP_FRAME_TYPE_KEY 3 +#define EAP_FRAME_TYPE_ENCAP_ASF_ALERT 4 + +struct eap_frame_t { + unsigned char version; + unsigned char type; + unsigned char length[2]; +}; + +static const struct tok eap_frame_type_values[] = { + { EAP_FRAME_TYPE_PACKET, "EAP packet" }, + { EAP_FRAME_TYPE_START, "EAPOL start" }, + { EAP_FRAME_TYPE_LOGOFF, "EAPOL logoff" }, + { EAP_FRAME_TYPE_KEY, "EAPOL key" }, + { EAP_FRAME_TYPE_ENCAP_ASF_ALERT, "Encapsulated ASF alert" }, + { 0, NULL} +}; + +/* RFC 3748 */ +struct eap_packet_t { + unsigned char code; + unsigned char id; + unsigned char length[2]; +}; + +#define EAP_REQUEST 1 +#define EAP_RESPONSE 2 +#define EAP_SUCCESS 3 +#define EAP_FAILURE 4 + +static const struct tok eap_code_values[] = { + { EAP_REQUEST, "Request" }, + { EAP_RESPONSE, "Response" }, + { EAP_SUCCESS, "Success" }, + { EAP_FAILURE, "Failure" }, + { 0, NULL} +}; + +#define EAP_TYPE_NO_PROPOSED 0 +#define EAP_TYPE_IDENTITY 1 +#define EAP_TYPE_NOTIFICATION 2 +#define EAP_TYPE_NAK 3 +#define EAP_TYPE_MD5_CHALLENGE 4 +#define EAP_TYPE_OTP 5 +#define EAP_TYPE_GTC 6 +#define EAP_TYPE_TLS 13 /* RFC 2716 */ +#define EAP_TYPE_SIM 18 /* RFC 4186 */ +#define EAP_TYPE_TTLS 21 /* draft-funk-eap-ttls-v0-01.txt */ +#define EAP_TYPE_AKA 23 /* RFC 4187 */ +#define EAP_TYPE_FAST 43 /* RFC 4851 */ +#define EAP_TYPE_EXPANDED_TYPES 254 +#define EAP_TYPE_EXPERIMENTAL 255 + +static const struct tok eap_type_values[] = { + { EAP_TYPE_NO_PROPOSED, "No proposed" }, + { EAP_TYPE_IDENTITY, "Identity" }, + { EAP_TYPE_NOTIFICATION, "Notification" }, + { EAP_TYPE_NAK, "Nak" }, + { EAP_TYPE_MD5_CHALLENGE, "MD5-challenge" }, + { EAP_TYPE_OTP, "OTP" }, + { EAP_TYPE_GTC, "GTC" }, + { EAP_TYPE_TLS, "TLS" }, + { EAP_TYPE_SIM, "SIM" }, + { EAP_TYPE_TTLS, "TTLS" }, + { EAP_TYPE_AKA, "AKA" }, + { EAP_TYPE_FAST, "FAST" }, + { EAP_TYPE_EXPANDED_TYPES, "Expanded types" }, + { EAP_TYPE_EXPERIMENTAL, "Experimental" }, + { 0, NULL} +}; + +#define EAP_TLS_EXTRACT_BIT_L(x) (((x)&0x80)>>7) + +/* RFC 2716 - EAP TLS bits */ +#define EAP_TLS_FLAGS_LEN_INCLUDED (1 << 7) +#define EAP_TLS_FLAGS_MORE_FRAGMENTS (1 << 6) +#define EAP_TLS_FLAGS_START (1 << 5) + +static const struct tok eap_tls_flags_values[] = { + { EAP_TLS_FLAGS_LEN_INCLUDED, "L bit" }, + { EAP_TLS_FLAGS_MORE_FRAGMENTS, "More fragments bit"}, + { EAP_TLS_FLAGS_START, "Start bit"}, + { 0, NULL} +}; + +#define EAP_TTLS_VERSION(x) ((x)&0x07) + +/* EAP-AKA and EAP-SIM - RFC 4187 */ +#define EAP_AKA_CHALLENGE 1 +#define EAP_AKA_AUTH_REJECT 2 +#define EAP_AKA_SYNC_FAILURE 4 +#define EAP_AKA_IDENTITY 5 +#define EAP_SIM_START 10 +#define EAP_SIM_CHALLENGE 11 +#define EAP_AKA_NOTIFICATION 12 +#define EAP_AKA_REAUTH 13 +#define EAP_AKA_CLIENT_ERROR 14 + +static const struct tok eap_aka_subtype_values[] = { + { EAP_AKA_CHALLENGE, "Challenge" }, + { EAP_AKA_AUTH_REJECT, "Auth reject" }, + { EAP_AKA_SYNC_FAILURE, "Sync failure" }, + { EAP_AKA_IDENTITY, "Identity" }, + { EAP_SIM_START, "Start" }, + { EAP_SIM_CHALLENGE, "Challenge" }, + { EAP_AKA_NOTIFICATION, "Notification" }, + { EAP_AKA_REAUTH, "Reauth" }, + { EAP_AKA_CLIENT_ERROR, "Client error" }, + { 0, NULL} +}; + +/* + * Print EAP requests / responses + */ +void +eap_print(netdissect_options *ndo _U_, + register const u_char *cp, + u_int length _U_) +{ + const struct eap_frame_t *eap; + const u_char *tptr; + u_int tlen, type, subtype; + int count=0, len; + + tptr = cp; + tlen = length; + eap = (const struct eap_frame_t *)cp; + TCHECK(*eap); + + /* in non-verbose mode just lets print the basic info */ + if (vflag < 1) { + printf("%s (%u) v%u, len %u", + tok2str(eap_frame_type_values, "unknown", eap->type), + eap->type, + eap->version, + EXTRACT_16BITS(eap->length)); + return; + } + + printf("%s (%u) v%u, len %u", + tok2str(eap_frame_type_values, "unknown", eap->type), + eap->type, + eap->version, + EXTRACT_16BITS(eap->length)); + + tptr += sizeof(const struct eap_frame_t); + tlen -= sizeof(const struct eap_frame_t); + + switch (eap->type) { + case EAP_FRAME_TYPE_PACKET: + type = *(tptr); + len = EXTRACT_16BITS(tptr+2); + printf(", %s (%u), id %u, len %u", + tok2str(eap_code_values, "unknown", type), + type, + *(tptr+1), + len); + + if (!TTEST2(*tptr, len)) + goto trunc; + + if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */ + subtype = *(tptr+4); + printf("\n\t\t Type %s (%u)", + tok2str(eap_type_values, "unknown", *(tptr+4)), + *(tptr+4)); + + switch (subtype) { + case EAP_TYPE_IDENTITY: + if (len - 5 > 0) { + printf(", Identity: "); + safeputs((const char *)tptr+5, len-5); + } + break; + + case EAP_TYPE_NOTIFICATION: + if (len - 5 > 0) { + printf(", Notification: "); + safeputs((const char *)tptr+5, len-5); + } + break; + + case EAP_TYPE_NAK: + count = 5; + + /* + * one or more octets indicating + * the desired authentication + * type one octet per type + */ + while (count < len) { + printf(" %s (%u),", + tok2str(eap_type_values, "unknown", *(tptr+count)), + *(tptr+count)); + count++; + } + break; + + case EAP_TYPE_TTLS: + printf(" TTLSv%u", + EAP_TTLS_VERSION(*(tptr+5))); /* fall through */ + case EAP_TYPE_TLS: + printf(" flags [%s] 0x%02x,", + bittok2str(eap_tls_flags_values, "none", *(tptr+5)), + *(tptr+5)); + + if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { + printf(" len %u", EXTRACT_32BITS(tptr+6)); + } + break; + + case EAP_TYPE_FAST: + printf(" FASTv%u", + EAP_TTLS_VERSION(*(tptr+5))); + printf(" flags [%s] 0x%02x,", + bittok2str(eap_tls_flags_values, "none", *(tptr+5)), + *(tptr+5)); + + if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { + printf(" len %u", EXTRACT_32BITS(tptr+6)); + } + + /* FIXME - TLV attributes follow */ + break; + + case EAP_TYPE_AKA: + case EAP_TYPE_SIM: + printf(" subtype [%s] 0x%02x,", + tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)), + *(tptr+5)); + + /* FIXME - TLV attributes follow */ + break; + + case EAP_TYPE_MD5_CHALLENGE: + case EAP_TYPE_OTP: + case EAP_TYPE_GTC: + case EAP_TYPE_EXPANDED_TYPES: + case EAP_TYPE_EXPERIMENTAL: + default: + break; + } + } + break; + + case EAP_FRAME_TYPE_LOGOFF: + case EAP_FRAME_TYPE_ENCAP_ASF_ALERT: + default: + break; + } + return; + + trunc: + printf("\n\t[|EAP]"); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-egp.c b/freebsd/contrib/tcpdump/print-egp.c new file mode 100644 index 00000000..1c90bd86 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-egp.c @@ -0,0 +1,364 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Lawrence Berkeley Laboratory, + * Berkeley, CA. The name of the University may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU). + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-egp.c,v 1.38 2006-02-11 22:13:24 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip.h" + +struct egp_packet { + u_int8_t egp_version; +#define EGP_VERSION 2 + u_int8_t egp_type; +#define EGPT_ACQUIRE 3 +#define EGPT_REACH 5 +#define EGPT_POLL 2 +#define EGPT_UPDATE 1 +#define EGPT_ERROR 8 + u_int8_t egp_code; +#define EGPC_REQUEST 0 +#define EGPC_CONFIRM 1 +#define EGPC_REFUSE 2 +#define EGPC_CEASE 3 +#define EGPC_CEASEACK 4 +#define EGPC_HELLO 0 +#define EGPC_HEARDU 1 + u_int8_t egp_status; +#define EGPS_UNSPEC 0 +#define EGPS_ACTIVE 1 +#define EGPS_PASSIVE 2 +#define EGPS_NORES 3 +#define EGPS_ADMIN 4 +#define EGPS_GODOWN 5 +#define EGPS_PARAM 6 +#define EGPS_PROTO 7 +#define EGPS_INDET 0 +#define EGPS_UP 1 +#define EGPS_DOWN 2 +#define EGPS_UNSOL 0x80 + u_int16_t egp_checksum; + u_int16_t egp_as; + u_int16_t egp_sequence; + union { + u_int16_t egpu_hello; + u_int8_t egpu_gws[2]; + u_int16_t egpu_reason; +#define EGPR_UNSPEC 0 +#define EGPR_BADHEAD 1 +#define EGPR_BADDATA 2 +#define EGPR_NOREACH 3 +#define EGPR_XSPOLL 4 +#define EGPR_NORESP 5 +#define EGPR_UVERSION 6 + } egp_handg; +#define egp_hello egp_handg.egpu_hello +#define egp_intgw egp_handg.egpu_gws[0] +#define egp_extgw egp_handg.egpu_gws[1] +#define egp_reason egp_handg.egpu_reason + union { + u_int16_t egpu_poll; + u_int32_t egpu_sourcenet; + } egp_pands; +#define egp_poll egp_pands.egpu_poll +#define egp_sourcenet egp_pands.egpu_sourcenet +}; + +const char *egp_acquire_codes[] = { + "request", + "confirm", + "refuse", + "cease", + "cease_ack" +}; + +const char *egp_acquire_status[] = { + "unspecified", + "active_mode", + "passive_mode", + "insufficient_resources", + "administratively_prohibited", + "going_down", + "parameter_violation", + "protocol_violation" +}; + +const char *egp_reach_codes[] = { + "hello", + "i-h-u" +}; + +const char *egp_status_updown[] = { + "indeterminate", + "up", + "down" +}; + +const char *egp_reasons[] = { + "unspecified", + "bad_EGP_header_format", + "bad_EGP_data_field_format", + "reachability_info_unavailable", + "excessive_polling_rate", + "no_response", + "unsupported_version" +}; + +static void +egpnrprint(register const struct egp_packet *egp) +{ + register const u_int8_t *cp; + u_int32_t addr; + register u_int32_t net; + register u_int netlen; + int gateways, distances, networks; + int t_gateways; + const char *comma; + + addr = egp->egp_sourcenet; + if (IN_CLASSA(addr)) { + net = addr & IN_CLASSA_NET; + netlen = 1; + } else if (IN_CLASSB(addr)) { + net = addr & IN_CLASSB_NET; + netlen = 2; + } else if (IN_CLASSC(addr)) { + net = addr & IN_CLASSC_NET; + netlen = 3; + } else { + net = 0; + netlen = 0; + } + cp = (u_int8_t *)(egp + 1); + + t_gateways = egp->egp_intgw + egp->egp_extgw; + for (gateways = 0; gateways < t_gateways; ++gateways) { + /* Pickup host part of gateway address */ + addr = 0; + TCHECK2(cp[0], 4 - netlen); + switch (netlen) { + + case 1: + addr = *cp++; + /* fall through */ + case 2: + addr = (addr << 8) | *cp++; + /* fall through */ + case 3: + addr = (addr << 8) | *cp++; + } + addr |= net; + TCHECK2(cp[0], 1); + distances = *cp++; + printf(" %s %s ", + gateways < (int)egp->egp_intgw ? "int" : "ext", + ipaddr_string(&addr)); + + comma = ""; + putchar('('); + while (--distances >= 0) { + TCHECK2(cp[0], 2); + printf("%sd%d:", comma, (int)*cp++); + comma = ", "; + networks = *cp++; + while (--networks >= 0) { + /* Pickup network number */ + TCHECK2(cp[0], 1); + addr = (u_int32_t)*cp++ << 24; + if (IN_CLASSB(addr)) { + TCHECK2(cp[0], 1); + addr |= (u_int32_t)*cp++ << 16; + } else if (!IN_CLASSA(addr)) { + TCHECK2(cp[0], 2); + addr |= (u_int32_t)*cp++ << 16; + addr |= (u_int32_t)*cp++ << 8; + } + printf(" %s", ipaddr_string(&addr)); + } + } + putchar(')'); + } + return; +trunc: + fputs("[|]", stdout); +} + +void +egp_print(register const u_int8_t *bp, register u_int length) +{ + register const struct egp_packet *egp; + register int status; + register int code; + register int type; + + egp = (struct egp_packet *)bp; + if (!TTEST2(*egp, length)) { + printf("[|egp]"); + return; + } + + if (!vflag) { + printf("EGPv%u, AS %u, seq %u, length %u", + egp->egp_version, + EXTRACT_16BITS(&egp->egp_as), + EXTRACT_16BITS(&egp->egp_sequence), + length); + return; + } else + printf("EGPv%u, length %u", + egp->egp_version, + length); + + if (egp->egp_version != EGP_VERSION) { + printf("[version %d]", egp->egp_version); + return; + } + + type = egp->egp_type; + code = egp->egp_code; + status = egp->egp_status; + + switch (type) { + case EGPT_ACQUIRE: + printf(" acquire"); + switch (code) { + case EGPC_REQUEST: + case EGPC_CONFIRM: + printf(" %s", egp_acquire_codes[code]); + switch (status) { + case EGPS_UNSPEC: + case EGPS_ACTIVE: + case EGPS_PASSIVE: + printf(" %s", egp_acquire_status[status]); + break; + + default: + printf(" [status %d]", status); + break; + } + printf(" hello:%d poll:%d", + EXTRACT_16BITS(&egp->egp_hello), + EXTRACT_16BITS(&egp->egp_poll)); + break; + + case EGPC_REFUSE: + case EGPC_CEASE: + case EGPC_CEASEACK: + printf(" %s", egp_acquire_codes[code]); + switch (status ) { + case EGPS_UNSPEC: + case EGPS_NORES: + case EGPS_ADMIN: + case EGPS_GODOWN: + case EGPS_PARAM: + case EGPS_PROTO: + printf(" %s", egp_acquire_status[status]); + break; + + default: + printf("[status %d]", status); + break; + } + break; + + default: + printf("[code %d]", code); + break; + } + break; + + case EGPT_REACH: + switch (code) { + + case EGPC_HELLO: + case EGPC_HEARDU: + printf(" %s", egp_reach_codes[code]); + if (status <= EGPS_DOWN) + printf(" state:%s", egp_status_updown[status]); + else + printf(" [status %d]", status); + break; + + default: + printf("[reach code %d]", code); + break; + } + break; + + case EGPT_POLL: + printf(" poll"); + if (egp->egp_status <= EGPS_DOWN) + printf(" state:%s", egp_status_updown[status]); + else + printf(" [status %d]", status); + printf(" net:%s", ipaddr_string(&egp->egp_sourcenet)); + break; + + case EGPT_UPDATE: + printf(" update"); + if (status & EGPS_UNSOL) { + status &= ~EGPS_UNSOL; + printf(" unsolicited"); + } + if (status <= EGPS_DOWN) + printf(" state:%s", egp_status_updown[status]); + else + printf(" [status %d]", status); + printf(" %s int %d ext %d", + ipaddr_string(&egp->egp_sourcenet), + egp->egp_intgw, + egp->egp_extgw); + if (vflag) + egpnrprint(egp); + break; + + case EGPT_ERROR: + printf(" error"); + if (status <= EGPS_DOWN) + printf(" state:%s", egp_status_updown[status]); + else + printf(" [status %d]", status); + + if (EXTRACT_16BITS(&egp->egp_reason) <= EGPR_UVERSION) + printf(" %s", egp_reasons[EXTRACT_16BITS(&egp->egp_reason)]); + else + printf(" [reason %d]", EXTRACT_16BITS(&egp->egp_reason)); + break; + + default: + printf("[type %d]", type); + break; + } +} diff --git a/freebsd/contrib/tcpdump/print-eigrp.c b/freebsd/contrib/tcpdump/print-eigrp.c new file mode 100644 index 00000000..599fe89a --- /dev/null +++ b/freebsd/contrib/tcpdump/print-eigrp.c @@ -0,0 +1,482 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org> + * 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. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-eigrp.c,v 1.7 2005-05-06 02:53:26 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * packet format documented at + * http://www.rhyshaden.com/eigrp.htm + */ + +struct eigrp_common_header { + u_int8_t version; + u_int8_t opcode; + u_int8_t checksum[2]; + u_int8_t flags[4]; + u_int8_t seq[4]; + u_int8_t ack[4]; + u_int8_t asn[4]; +}; + +#define EIGRP_VERSION 2 + +#define EIGRP_OPCODE_UPDATE 1 +#define EIGRP_OPCODE_QUERY 3 +#define EIGRP_OPCODE_REPLY 4 +#define EIGRP_OPCODE_HELLO 5 +#define EIGRP_OPCODE_IPXSAP 6 +#define EIGRP_OPCODE_PROBE 7 + +static const struct tok eigrp_opcode_values[] = { + { EIGRP_OPCODE_UPDATE, "Update" }, + { EIGRP_OPCODE_QUERY, "Query" }, + { EIGRP_OPCODE_REPLY, "Reply" }, + { EIGRP_OPCODE_HELLO, "Hello" }, + { EIGRP_OPCODE_IPXSAP, "IPX SAP" }, + { EIGRP_OPCODE_PROBE, "Probe" }, + { 0, NULL} +}; + +static const struct tok eigrp_common_header_flag_values[] = { + { 0x01, "Init" }, + { 0x02, "Conditionally Received" }, + { 0, NULL} +}; + +struct eigrp_tlv_header { + u_int8_t type[2]; + u_int8_t length[2]; +}; + +#define EIGRP_TLV_GENERAL_PARM 0x0001 +#define EIGRP_TLV_AUTH 0x0002 +#define EIGRP_TLV_SEQ 0x0003 +#define EIGRP_TLV_SW_VERSION 0x0004 +#define EIGRP_TLV_MCAST_SEQ 0x0005 +#define EIGRP_TLV_IP_INT 0x0102 +#define EIGRP_TLV_IP_EXT 0x0103 +#define EIGRP_TLV_AT_INT 0x0202 +#define EIGRP_TLV_AT_EXT 0x0203 +#define EIGRP_TLV_AT_CABLE_SETUP 0x0204 +#define EIGRP_TLV_IPX_INT 0x0302 +#define EIGRP_TLV_IPX_EXT 0x0303 + +static const struct tok eigrp_tlv_values[] = { + { EIGRP_TLV_GENERAL_PARM, "General Parameters"}, + { EIGRP_TLV_AUTH, "Authentication"}, + { EIGRP_TLV_SEQ, "Sequence"}, + { EIGRP_TLV_SW_VERSION, "Software Version"}, + { EIGRP_TLV_MCAST_SEQ, "Next Multicast Sequence"}, + { EIGRP_TLV_IP_INT, "IP Internal routes"}, + { EIGRP_TLV_IP_EXT, "IP External routes"}, + { EIGRP_TLV_AT_INT, "AppleTalk Internal routes"}, + { EIGRP_TLV_AT_EXT, "AppleTalk External routes"}, + { EIGRP_TLV_AT_CABLE_SETUP, "AppleTalk Cable setup"}, + { EIGRP_TLV_IPX_INT, "IPX Internal routes"}, + { EIGRP_TLV_IPX_EXT, "IPX External routes"}, + { 0, NULL} +}; + +struct eigrp_tlv_general_parm_t { + u_int8_t k1; + u_int8_t k2; + u_int8_t k3; + u_int8_t k4; + u_int8_t k5; + u_int8_t res; + u_int8_t holdtime[2]; +}; + +struct eigrp_tlv_sw_version_t { + u_int8_t ios_major; + u_int8_t ios_minor; + u_int8_t eigrp_major; + u_int8_t eigrp_minor; +}; + +struct eigrp_tlv_ip_int_t { + u_int8_t nexthop[4]; + u_int8_t delay[4]; + u_int8_t bandwidth[4]; + u_int8_t mtu[3]; + u_int8_t hopcount; + u_int8_t reliability; + u_int8_t load; + u_int8_t reserved[2]; + u_int8_t plen; + u_int8_t destination; /* variable length [1-4] bytes encoding */ +}; + +struct eigrp_tlv_ip_ext_t { + u_int8_t nexthop[4]; + u_int8_t origin_router[4]; + u_int8_t origin_as[4]; + u_int8_t tag[4]; + u_int8_t metric[4]; + u_int8_t reserved[2]; + u_int8_t proto_id; + u_int8_t flags; + u_int8_t delay[4]; + u_int8_t bandwidth[4]; + u_int8_t mtu[3]; + u_int8_t hopcount; + u_int8_t reliability; + u_int8_t load; + u_int8_t reserved2[2]; + u_int8_t plen; + u_int8_t destination; /* variable length [1-4] bytes encoding */ +}; + +struct eigrp_tlv_at_cable_setup_t { + u_int8_t cable_start[2]; + u_int8_t cable_end[2]; + u_int8_t router_id[4]; +}; + +struct eigrp_tlv_at_int_t { + u_int8_t nexthop[4]; + u_int8_t delay[4]; + u_int8_t bandwidth[4]; + u_int8_t mtu[3]; + u_int8_t hopcount; + u_int8_t reliability; + u_int8_t load; + u_int8_t reserved[2]; + u_int8_t cable_start[2]; + u_int8_t cable_end[2]; +}; + +struct eigrp_tlv_at_ext_t { + u_int8_t nexthop[4]; + u_int8_t origin_router[4]; + u_int8_t origin_as[4]; + u_int8_t tag[4]; + u_int8_t proto_id; + u_int8_t flags; + u_int8_t metric[2]; + u_int8_t delay[4]; + u_int8_t bandwidth[4]; + u_int8_t mtu[3]; + u_int8_t hopcount; + u_int8_t reliability; + u_int8_t load; + u_int8_t reserved2[2]; + u_int8_t cable_start[2]; + u_int8_t cable_end[2]; +}; + +static const struct tok eigrp_ext_proto_id_values[] = { + { 0x01, "IGRP" }, + { 0x02, "EIGRP" }, + { 0x03, "Static" }, + { 0x04, "RIP" }, + { 0x05, "Hello" }, + { 0x06, "OSPF" }, + { 0x07, "IS-IS" }, + { 0x08, "EGP" }, + { 0x09, "BGP" }, + { 0x0a, "IDRP" }, + { 0x0b, "Connected" }, + { 0, NULL} +}; + +void +eigrp_print(register const u_char *pptr, register u_int len) { + + const struct eigrp_common_header *eigrp_com_header; + const struct eigrp_tlv_header *eigrp_tlv_header; + const u_char *tptr,*tlv_tptr; + u_int tlen,eigrp_tlv_len,eigrp_tlv_type,tlv_tlen, byte_length, bit_length; + u_int8_t prefix[4]; + + union { + const struct eigrp_tlv_general_parm_t *eigrp_tlv_general_parm; + const struct eigrp_tlv_sw_version_t *eigrp_tlv_sw_version; + const struct eigrp_tlv_ip_int_t *eigrp_tlv_ip_int; + const struct eigrp_tlv_ip_ext_t *eigrp_tlv_ip_ext; + const struct eigrp_tlv_at_cable_setup_t *eigrp_tlv_at_cable_setup; + const struct eigrp_tlv_at_int_t *eigrp_tlv_at_int; + const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext; + } tlv_ptr; + + tptr=pptr; + eigrp_com_header = (const struct eigrp_common_header *)pptr; + TCHECK(*eigrp_com_header); + + /* + * Sanity checking of the header. + */ + if (eigrp_com_header->version != EIGRP_VERSION) { + printf("EIGRP version %u packet not supported",eigrp_com_header->version); + return; + } + + /* in non-verbose mode just lets print the basic Message Type*/ + if (vflag < 1) { + printf("EIGRP %s, length: %u", + tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + + tlen=len-sizeof(struct eigrp_common_header); + + /* FIXME print other header info */ + printf("\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]\n\tseq: 0x%08x, ack: 0x%08x, AS: %u, length: %u", + eigrp_com_header->version, + tok2str(eigrp_opcode_values, "unknown, type: %u",eigrp_com_header->opcode), + eigrp_com_header->opcode, + EXTRACT_16BITS(&eigrp_com_header->checksum), + tok2str(eigrp_common_header_flag_values, + "none", + EXTRACT_32BITS(&eigrp_com_header->flags)), + EXTRACT_32BITS(&eigrp_com_header->seq), + EXTRACT_32BITS(&eigrp_com_header->ack), + EXTRACT_32BITS(&eigrp_com_header->asn), + tlen); + + tptr+=sizeof(const struct eigrp_common_header); + + while(tlen>0) { + /* did we capture enough for fully decoding the object header ? */ + TCHECK2(*tptr, sizeof(struct eigrp_tlv_header)); + + eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr; + eigrp_tlv_len=EXTRACT_16BITS(&eigrp_tlv_header->length); + eigrp_tlv_type=EXTRACT_16BITS(&eigrp_tlv_header->type); + + + if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) || + eigrp_tlv_len > tlen) { + print_unknown_data(tptr+sizeof(struct eigrp_tlv_header),"\n\t ",tlen); + return; + } + + printf("\n\t %s TLV (0x%04x), length: %u", + tok2str(eigrp_tlv_values, + "Unknown", + eigrp_tlv_type), + eigrp_tlv_type, + eigrp_tlv_len); + + tlv_tptr=tptr+sizeof(struct eigrp_tlv_header); + tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header); + + /* did we capture enough for fully decoding the object ? */ + TCHECK2(*tptr, eigrp_tlv_len); + + switch(eigrp_tlv_type) { + + case EIGRP_TLV_GENERAL_PARM: + tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr; + + printf("\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u", + EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime), + tlv_ptr.eigrp_tlv_general_parm->k1, + tlv_ptr.eigrp_tlv_general_parm->k2, + tlv_ptr.eigrp_tlv_general_parm->k3, + tlv_ptr.eigrp_tlv_general_parm->k4, + tlv_ptr.eigrp_tlv_general_parm->k5); + break; + + case EIGRP_TLV_SW_VERSION: + tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr; + + printf("\n\t IOS version: %u.%u, EIGRP version %u.%u", + tlv_ptr.eigrp_tlv_sw_version->ios_major, + tlv_ptr.eigrp_tlv_sw_version->ios_minor, + tlv_ptr.eigrp_tlv_sw_version->eigrp_major, + tlv_ptr.eigrp_tlv_sw_version->eigrp_minor); + break; + + case EIGRP_TLV_IP_INT: + tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr; + + bit_length = tlv_ptr.eigrp_tlv_ip_int->plen; + if (bit_length > 32) { + printf("\n\t illegal prefix length %u",bit_length); + break; + } + byte_length = (bit_length + 7) / 8; /* variable length encoding */ + memset(prefix, 0, 4); + memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length); + + printf("\n\t IPv4 prefix: %15s/%u, nexthop: ", + ipaddr_string(prefix), + bit_length); + if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0) + printf("self"); + else + printf("%s",ipaddr_string(&tlv_ptr.eigrp_tlv_ip_int->nexthop)); + + printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->delay)/100), + EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->bandwidth), + EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_int->mtu), + tlv_ptr.eigrp_tlv_ip_int->hopcount, + tlv_ptr.eigrp_tlv_ip_int->reliability, + tlv_ptr.eigrp_tlv_ip_int->load); + break; + + case EIGRP_TLV_IP_EXT: + tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr; + + bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen; + if (bit_length > 32) { + printf("\n\t illegal prefix length %u",bit_length); + break; + } + byte_length = (bit_length + 7) / 8; /* variable length encoding */ + memset(prefix, 0, 4); + memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length); + + printf("\n\t IPv4 prefix: %15s/%u, nexthop: ", + ipaddr_string(prefix), + bit_length); + if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0) + printf("self"); + else + printf("%s",ipaddr_string(&tlv_ptr.eigrp_tlv_ip_ext->nexthop)); + + printf("\n\t origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", + ipaddr_string(tlv_ptr.eigrp_tlv_ip_ext->origin_router), + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->origin_as), + tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_ip_ext->proto_id), + tlv_ptr.eigrp_tlv_ip_ext->flags, + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->tag), + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->metric)); + + printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->delay)/100), + EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->bandwidth), + EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_ext->mtu), + tlv_ptr.eigrp_tlv_ip_ext->hopcount, + tlv_ptr.eigrp_tlv_ip_ext->reliability, + tlv_ptr.eigrp_tlv_ip_ext->load); + break; + + case EIGRP_TLV_AT_CABLE_SETUP: + tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr; + + printf("\n\t Cable-range: %u-%u, Router-ID %u", + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start), + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_end), + EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->router_id)); + break; + + case EIGRP_TLV_AT_INT: + tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr; + + printf("\n\t Cable-Range: %u-%u, nexthop: ", + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start), + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_end)); + + if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop) == 0) + printf("self"); + else + printf("%u.%u", + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop), + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop[2])); + + printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->delay)/100), + EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->bandwidth), + EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_int->mtu), + tlv_ptr.eigrp_tlv_at_int->hopcount, + tlv_ptr.eigrp_tlv_at_int->reliability, + tlv_ptr.eigrp_tlv_at_int->load); + break; + + case EIGRP_TLV_AT_EXT: + tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr; + + printf("\n\t Cable-Range: %u-%u, nexthop: ", + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start), + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_end)); + + if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0) + printf("self"); + else + printf("%u.%u", + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop), + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2])); + + printf("\n\t origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_router), + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_as), + tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_at_ext->proto_id), + tlv_ptr.eigrp_tlv_at_ext->flags, + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->tag), + EXTRACT_16BITS(tlv_ptr.eigrp_tlv_at_ext->metric)); + + printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->delay)/100), + EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->bandwidth), + EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_ext->mtu), + tlv_ptr.eigrp_tlv_at_ext->hopcount, + tlv_ptr.eigrp_tlv_at_ext->reliability, + tlv_ptr.eigrp_tlv_at_ext->load); + break; + + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case EIGRP_TLV_AUTH: + case EIGRP_TLV_SEQ: + case EIGRP_TLV_MCAST_SEQ: + case EIGRP_TLV_IPX_INT: + case EIGRP_TLV_IPX_EXT: + + default: + if (vflag <= 1) + print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag > 1) + print_unknown_data(tptr+sizeof(struct eigrp_tlv_header),"\n\t ", + eigrp_tlv_len-sizeof(struct eigrp_tlv_header)); + + tptr+=eigrp_tlv_len; + tlen-=eigrp_tlv_len; + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} diff --git a/freebsd/contrib/tcpdump/print-enc.c b/freebsd/contrib/tcpdump/print-enc.c new file mode 100644 index 00000000..db16f933 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-enc.c @@ -0,0 +1,100 @@ +#include <machine/rtems-bsd-user-space.h> + +/* $OpenBSD: print-enc.c,v 1.7 2002/02/19 19:39:40 millert Exp $ */ + +/* + * 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-enc.c,v 1.6 2008-11-18 07:35:32 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#include "enc.h" + +#define ENC_PRINT_TYPE(wh, xf, nam) \ + if ((wh) & (xf)) { \ + printf("%s%s", nam, (wh) == (xf) ? "): " : ","); \ + (wh) &= ~(xf); \ + } + +u_int +enc_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + int flags; + const struct enchdr *hdr; + + if (caplen < ENC_HDRLEN) { + printf("[|enc]"); + goto out; + } + + hdr = (struct enchdr *)p; + flags = hdr->flags; + if (flags == 0) + printf("(unprotected): "); + else + printf("("); + ENC_PRINT_TYPE(flags, M_AUTH, "authentic"); + ENC_PRINT_TYPE(flags, M_CONF, "confidential"); + /* ENC_PRINT_TYPE(flags, M_TUNNEL, "tunnel"); */ + printf("SPI 0x%08x: ", EXTRACT_32BITS(&hdr->spi)); + + length -= ENC_HDRLEN; + caplen -= ENC_HDRLEN; + p += ENC_HDRLEN; + + switch (hdr->af) { + case AF_INET: + ip_print(gndo, p, length); + break; +#ifdef INET6 + case AF_INET6: + ip6_print(gndo, p, length); + break; +#endif /*INET6*/ + } + +out: + return (ENC_HDRLEN); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-esp.c b/freebsd/contrib/tcpdump/print-esp.c new file mode 100644 index 00000000..6bf04dd0 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-esp.c @@ -0,0 +1,696 @@ +#include <machine/rtems-bsd-user-space.h> + +/* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */ + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.58 2007-12-07 00:03:07 mcr Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#include <tcpdump-stdinc.h> + +#include <stdlib.h> + +#ifdef HAVE_LIBCRYPTO +#ifdef HAVE_OPENSSL_EVP_H +#include <openssl/evp.h> +#endif +#endif + +#include <stdio.h> + +#include "ip.h" +#include "esp.h" +#ifdef INET6 +#include "ip6.h" +#endif + +#include "netdissect.h" +#include "addrtoname.h" +#include "extract.h" + +#ifndef HAVE_SOCKADDR_STORAGE +#ifdef INET6 +struct sockaddr_storage { + union { + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } un; +}; +#else +#define sockaddr_storage sockaddr +#endif +#endif /* HAVE_SOCKADDR_STORAGE */ + +#ifdef HAVE_LIBCRYPTO +struct sa_list { + struct sa_list *next; + struct sockaddr_storage daddr; + u_int32_t spi; /* if == 0, then IKEv2 */ + int initiator; + u_char spii[8]; /* for IKEv2 */ + u_char spir[8]; + const EVP_CIPHER *evp; + int ivlen; + int authlen; + u_char authsecret[256]; + int authsecret_len; + u_char secret[256]; /* is that big enough for all secrets? */ + int secretlen; +}; + +/* + * this will adjust ndo_packetp and ndo_snapend to new buffer! + */ +int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, + int initiator, + u_char spii[8], u_char spir[8], + u_char *buf, u_char *end) +{ + struct sa_list *sa; + u_char *iv; + int len; + EVP_CIPHER_CTX ctx; + + /* initiator arg is any non-zero value */ + if(initiator) initiator=1; + + /* see if we can find the SA, and if so, decode it */ + for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { + if (sa->spi == 0 + && initiator == sa->initiator + && memcmp(spii, sa->spii, 8) == 0 + && memcmp(spir, sa->spir, 8) == 0) + break; + } + + if(sa == NULL) return 0; + if(sa->evp == NULL) return 0; + + /* + * remove authenticator, and see if we still have something to + * work with + */ + end = end - sa->authlen; + iv = buf; + buf = buf + sa->ivlen; + len = end-buf; + + if(end <= buf) return 0; + + memset(&ctx, 0, sizeof(ctx)); + if (EVP_CipherInit(&ctx, sa->evp, sa->secret, NULL, 0) < 0) + (*ndo->ndo_warning)(ndo, "espkey init failed"); + EVP_CipherInit(&ctx, NULL, NULL, iv, 0); + EVP_Cipher(&ctx, buf, buf, len); + EVP_CIPHER_CTX_cleanup(&ctx); + + ndo->ndo_packetp = buf; + ndo->ndo_snapend = end; + + return 1; + +} + +static void esp_print_addsa(netdissect_options *ndo, + struct sa_list *sa, int sa_def) +{ + /* copy the "sa" */ + + struct sa_list *nsa; + + nsa = (struct sa_list *)malloc(sizeof(struct sa_list)); + if (nsa == NULL) + (*ndo->ndo_error)(ndo, "ran out of memory to allocate sa structure"); + + *nsa = *sa; + + if (sa_def) + ndo->ndo_sa_default = nsa; + + nsa->next = ndo->ndo_sa_list_head; + ndo->ndo_sa_list_head = nsa; +} + + +static u_int hexdigit(netdissect_options *ndo, char hex) +{ + if (hex >= '0' && hex <= '9') + return (hex - '0'); + else if (hex >= 'A' && hex <= 'F') + return (hex - 'A' + 10); + else if (hex >= 'a' && hex <= 'f') + return (hex - 'a' + 10); + else { + (*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex); + return 0; + } +} + +static u_int hex2byte(netdissect_options *ndo, char *hexstring) +{ + u_int byte; + + byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]); + return byte; +} + +/* + * returns size of binary, 0 on failure. + */ +static +int espprint_decode_hex(netdissect_options *ndo, + u_char *binbuf, unsigned int binbuf_len, + char *hex) +{ + unsigned int len; + int i; + + len = strlen(hex) / 2; + + if (len > binbuf_len) { + (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len); + return 0; + } + + i = 0; + while (hex[0] != '\0' && hex[1]!='\0') { + binbuf[i] = hex2byte(ndo, hex); + hex += 2; + i++; + } + + return i; +} + +/* + * decode the form: SPINUM@IP <tab> ALGONAME:0xsecret + */ + +static int +espprint_decode_encalgo(netdissect_options *ndo, + char *decode, struct sa_list *sa) +{ + int len; + size_t i; + const EVP_CIPHER *evp; + int authlen = 0; + char *colon, *p; + + colon = strchr(decode, ':'); + if (colon == NULL) { + (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode); + return 0; + } + *colon = '\0'; + + len = colon - decode; + if (strlen(decode) > strlen("-hmac96") && + !strcmp(decode + strlen(decode) - strlen("-hmac96"), + "-hmac96")) { + p = strstr(decode, "-hmac96"); + *p = '\0'; + authlen = 12; + } + if (strlen(decode) > strlen("-cbc") && + !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) { + p = strstr(decode, "-cbc"); + *p = '\0'; + } + evp = EVP_get_cipherbyname(decode); + + if (!evp) { + (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode); + sa->evp = NULL; + sa->authlen = 0; + sa->ivlen = 0; + return 0; + } + + sa->evp = evp; + sa->authlen = authlen; + sa->ivlen = EVP_CIPHER_iv_length(evp); + + colon++; + if (colon[0] == '0' && colon[1] == 'x') { + /* decode some hex! */ + + colon += 2; + sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon); + if(sa->secretlen == 0) return 0; + } else { + i = strlen(colon); + + if (i < sizeof(sa->secret)) { + memcpy(sa->secret, colon, i); + sa->secretlen = i; + } else { + memcpy(sa->secret, colon, sizeof(sa->secret)); + sa->secretlen = sizeof(sa->secret); + } + } + + return 1; +} + +/* + * for the moment, ignore the auth algorith, just hard code the authenticator + * length. Need to research how openssl looks up HMAC stuff. + */ +static int +espprint_decode_authalgo(netdissect_options *ndo, + char *decode, struct sa_list *sa) +{ + char *colon; + + colon = strchr(decode, ':'); + if (colon == NULL) { + (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode); + return 0; + } + *colon = '\0'; + + if(strcasecmp(colon,"sha1") == 0 || + strcasecmp(colon,"md5") == 0) { + sa->authlen = 12; + } + return 1; +} + +static void esp_print_decode_ikeline(netdissect_options *ndo, char *line, + const char *file, int lineno) +{ + /* it's an IKEv2 secret, store it instead */ + struct sa_list sa1; + + char *init; + char *icookie, *rcookie; + int ilen, rlen; + char *authkey; + char *enckey; + + init = strsep(&line, " \t"); + icookie = strsep(&line, " \t"); + rcookie = strsep(&line, " \t"); + authkey = strsep(&line, " \t"); + enckey = strsep(&line, " \t"); + + /* if any fields are missing */ + if(!init || !icookie || !rcookie || !authkey || !enckey) { + (*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u", + file, lineno); + + return; + } + + ilen = strlen(icookie); + rlen = strlen(rcookie); + + if((init[0]!='I' && init[0]!='R') + || icookie[0]!='0' || icookie[1]!='x' + || rcookie[0]!='0' || rcookie[1]!='x' + || ilen!=18 + || rlen!=18) { + (*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.", + file, lineno); + + (*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)", + init, icookie, ilen, rcookie, rlen); + + return; + } + + sa1.spi = 0; + sa1.initiator = (init[0] == 'I'); + if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8) + return; + + if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8) + return; + + if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return; + + if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return; + + esp_print_addsa(ndo, &sa1, FALSE); +} + +/* + * + * special form: file /name + * causes us to go read from this file instead. + * + */ +static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, + const char *file, int lineno) +{ + struct sa_list sa1; + int sa_def; + + char *spikey; + char *decode; + + spikey = strsep(&line, " \t"); + sa_def = 0; + memset(&sa1, 0, sizeof(struct sa_list)); + + /* if there is only one token, then it is an algo:key token */ + if (line == NULL) { + decode = spikey; + spikey = NULL; + /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */ + /* sa1.spi = 0; */ + sa_def = 1; + } else + decode = line; + + if (spikey && strcasecmp(spikey, "file") == 0) { + /* open file and read it */ + FILE *secretfile; + char fileline[1024]; + int lineno=0; + char *nl; + char *filename = line; + + secretfile = fopen(filename, FOPEN_READ_TXT); + if (secretfile == NULL) { + perror(filename); + exit(3); + } + + while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) { + lineno++; + /* remove newline from the line */ + nl = strchr(fileline, '\n'); + if (nl) + *nl = '\0'; + if (fileline[0] == '#') continue; + if (fileline[0] == '\0') continue; + + esp_print_decode_onesecret(ndo, fileline, filename, lineno); + } + fclose(secretfile); + + return; + } + + if (spikey && strcasecmp(spikey, "ikev2") == 0) { + esp_print_decode_ikeline(ndo, line, file, lineno); + return; + } + + if (spikey) { + + char *spistr, *foo; + u_int32_t spino; + struct sockaddr_in *sin; +#ifdef INET6 + struct sockaddr_in6 *sin6; +#endif + + spistr = strsep(&spikey, "@"); + + spino = strtoul(spistr, &foo, 0); + if (spistr == foo || !spikey) { + (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo); + return; + } + + sa1.spi = spino; + + sin = (struct sockaddr_in *)&sa1.daddr; +#ifdef INET6 + sin6 = (struct sockaddr_in6 *)&sa1.daddr; + if (inet_pton(AF_INET6, spikey, &sin6->sin6_addr) == 1) { +#ifdef HAVE_SOCKADDR_SA_LEN + sin6->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6->sin6_family = AF_INET6; + } else +#endif + if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) { +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(struct sockaddr_in); +#endif + sin->sin_family = AF_INET; + } else { + (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey); + return; + } + } + + if (decode) { + /* skip any blank spaces */ + while (isspace((unsigned char)*decode)) + decode++; + + if(!espprint_decode_encalgo(ndo, decode, &sa1)) { + return; + } + } + + esp_print_addsa(ndo, &sa1, sa_def); +} + +static void esp_init(netdissect_options *ndo _U_) +{ + + OpenSSL_add_all_algorithms(); + EVP_add_cipher_alias(SN_des_ede3_cbc, "3des"); +} + +void esp_print_decodesecret(netdissect_options *ndo) +{ + char *line; + char *p; + static int initialized = 0; + + if (!initialized) { + esp_init(ndo); + initialized = 1; + } + + p = ndo->ndo_espsecret; + + while (p && p[0] != '\0') { + /* pick out the first line or first thing until a comma */ + if ((line = strsep(&p, "\n,")) == NULL) { + line = p; + p = NULL; + } + + esp_print_decode_onesecret(ndo, line, "cmdline", 0); + } + + ndo->ndo_espsecret = NULL; +} + +#endif + +int +esp_print(netdissect_options *ndo, + const u_char *bp, const int length, const u_char *bp2 +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + , + int *nhdr +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + , + int *padlen +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + ) +{ + register const struct newesp *esp; + register const u_char *ep; +#ifdef HAVE_LIBCRYPTO + struct ip *ip; + struct sa_list *sa = NULL; + int espsecret_keylen; +#ifdef INET6 + struct ip6_hdr *ip6 = NULL; +#endif + int advance; + int len; + u_char *secret; + int ivlen = 0; + u_char *ivoff; + u_char *p; + EVP_CIPHER_CTX ctx; + int blocksz; +#endif + + esp = (struct newesp *)bp; + +#ifdef HAVE_LIBCRYPTO + secret = NULL; + advance = 0; +#endif + +#if 0 + /* keep secret out of a register */ + p = (u_char *)&secret; +#endif + + /* 'ep' points to the end of available data. */ + ep = ndo->ndo_snapend; + + if ((u_char *)(esp + 1) >= ep) { + fputs("[|ESP]", stdout); + goto fail; + } + (*ndo->ndo_printf)(ndo, "ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi)); + (*ndo->ndo_printf)(ndo, ",seq=0x%x)", EXTRACT_32BITS(&esp->esp_seq)); + (*ndo->ndo_printf)(ndo, ", length %u", length); + +#ifndef HAVE_LIBCRYPTO + goto fail; +#else + /* initiailize SAs */ + if (ndo->ndo_sa_list_head == NULL) { + if (!ndo->ndo_espsecret) + goto fail; + + esp_print_decodesecret(ndo); + } + + if (ndo->ndo_sa_list_head == NULL) + goto fail; + + ip = (struct ip *)bp2; + switch (IP_V(ip)) { +#ifdef INET6 + case 6: + ip6 = (struct ip6_hdr *)bp2; + /* we do not attempt to decrypt jumbograms */ + if (!EXTRACT_16BITS(&ip6->ip6_plen)) + goto fail; + /* if we can't get nexthdr, we do not need to decrypt it */ + len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen); + + /* see if we can find the SA, and if so, decode it */ + for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa->daddr; + if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) && + sin6->sin6_family == AF_INET6 && + memcmp(&sin6->sin6_addr, &ip6->ip6_dst, + sizeof(struct in6_addr)) == 0) { + break; + } + } + break; +#endif /*INET6*/ + case 4: + /* nexthdr & padding are in the last fragment */ + if (EXTRACT_16BITS(&ip->ip_off) & IP_MF) + goto fail; + len = EXTRACT_16BITS(&ip->ip_len); + + /* see if we can find the SA, and if so, decode it */ + for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { + struct sockaddr_in *sin = (struct sockaddr_in *)&sa->daddr; + if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) && + sin->sin_family == AF_INET && + sin->sin_addr.s_addr == ip->ip_dst.s_addr) { + break; + } + } + break; + default: + goto fail; + } + + /* if we didn't find the specific one, then look for + * an unspecified one. + */ + if (sa == NULL) + sa = ndo->ndo_sa_default; + + /* if not found fail */ + if (sa == NULL) + goto fail; + + /* if we can't get nexthdr, we do not need to decrypt it */ + if (ep - bp2 < len) + goto fail; + if (ep - bp2 > len) { + /* FCS included at end of frame (NetBSD 1.6 or later) */ + ep = bp2 + len; + } + + ivoff = (u_char *)(esp + 1) + 0; + ivlen = sa->ivlen; + secret = sa->secret; + espsecret_keylen = sa->secretlen; + ep = ep - sa->authlen; + + if (sa->evp) { + memset(&ctx, 0, sizeof(ctx)); + if (EVP_CipherInit(&ctx, sa->evp, secret, NULL, 0) < 0) + (*ndo->ndo_warning)(ndo, "espkey init failed"); + + blocksz = EVP_CIPHER_CTX_block_size(&ctx); + + p = ivoff; + EVP_CipherInit(&ctx, NULL, NULL, p, 0); + EVP_Cipher(&ctx, p + ivlen, p + ivlen, ep - (p + ivlen)); + EVP_CIPHER_CTX_cleanup(&ctx); + advance = ivoff - (u_char *)esp + ivlen; + } else + advance = sizeof(struct newesp); + + /* sanity check for pad length */ + if (ep - bp < *(ep - 2)) + goto fail; + + if (padlen) + *padlen = *(ep - 2) + 2; + + if (nhdr) + *nhdr = *(ep - 1); + + (ndo->ndo_printf)(ndo, ": "); + return advance; +#endif + +fail: + return -1; +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-ether.c b/freebsd/contrib/tcpdump/print-ether.c new file mode 100644 index 00000000..aaf067b1 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ether.c @@ -0,0 +1,441 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * 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. + * + * $FreeBSD$ + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.106 2008-02-06 10:47:53 guy Exp $ (LBL)"; +#endif + +#define NETDISSECT_REWORKED +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "ether.h" + +const struct tok ethertype_values[] = { + { ETHERTYPE_IP, "IPv4" }, + { ETHERTYPE_MPLS, "MPLS unicast" }, + { ETHERTYPE_MPLS_MULTI, "MPLS multicast" }, + { ETHERTYPE_IPV6, "IPv6" }, + { ETHERTYPE_8021Q, "802.1Q" }, + { ETHERTYPE_8021Q9100, "802.1Q-9100" }, + { ETHERTYPE_8021QinQ, "802.1Q-QinQ" }, + { ETHERTYPE_8021Q9200, "802.1Q-9200" }, + { ETHERTYPE_VMAN, "VMAN" }, + { ETHERTYPE_PUP, "PUP" }, + { ETHERTYPE_ARP, "ARP"}, + { ETHERTYPE_REVARP, "Reverse ARP"}, + { ETHERTYPE_NS, "NS" }, + { ETHERTYPE_SPRITE, "Sprite" }, + { ETHERTYPE_TRAIL, "Trail" }, + { ETHERTYPE_MOPDL, "MOP DL" }, + { ETHERTYPE_MOPRC, "MOP RC" }, + { ETHERTYPE_DN, "DN" }, + { ETHERTYPE_LAT, "LAT" }, + { ETHERTYPE_SCA, "SCA" }, + { ETHERTYPE_TEB, "TEB" }, + { ETHERTYPE_LANBRIDGE, "Lanbridge" }, + { ETHERTYPE_DECDNS, "DEC DNS" }, + { ETHERTYPE_DECDTS, "DEC DTS" }, + { ETHERTYPE_VEXP, "VEXP" }, + { ETHERTYPE_VPROD, "VPROD" }, + { ETHERTYPE_ATALK, "Appletalk" }, + { ETHERTYPE_AARP, "Appletalk ARP" }, + { ETHERTYPE_IPX, "IPX" }, + { ETHERTYPE_PPP, "PPP" }, + { ETHERTYPE_MPCP, "MPCP" }, + { ETHERTYPE_SLOW, "Slow Protocols" }, + { ETHERTYPE_PPPOED, "PPPoE D" }, + { ETHERTYPE_PPPOES, "PPPoE S" }, + { ETHERTYPE_EAPOL, "EAPOL" }, + { ETHERTYPE_RRCP, "RRCP" }, + { ETHERTYPE_MS_NLB_HB, "MS NLB heartbeat" }, + { ETHERTYPE_JUMBO, "Jumbo" }, + { ETHERTYPE_LOOPBACK, "Loopback" }, + { ETHERTYPE_ISO, "OSI" }, + { ETHERTYPE_GRE_ISO, "GRE-OSI" }, + { ETHERTYPE_CFM_OLD, "CFM (old)" }, + { ETHERTYPE_CFM, "CFM" }, + { ETHERTYPE_LLDP, "LLDP" }, + { ETHERTYPE_TIPC, "TIPC"}, + { 0, NULL} +}; + +static inline void +ether_hdr_print(netdissect_options *ndo, + const u_char *bp, u_int length) +{ + register const struct ether_header *ep; + u_int16_t ether_type; + + ep = (const struct ether_header *)bp; + + (void)ND_PRINT((ndo, "%s > %s", + etheraddr_string(ESRC(ep)), + etheraddr_string(EDST(ep)))); + + ether_type = EXTRACT_16BITS(&ep->ether_type); + if (!ndo->ndo_qflag) { + if (ether_type <= ETHERMTU) + (void)ND_PRINT((ndo, ", 802.3")); + else + (void)ND_PRINT((ndo, ", ethertype %s (0x%04x)", + tok2str(ethertype_values,"Unknown", ether_type), + ether_type)); + } else { + if (ether_type <= ETHERMTU) + (void)ND_PRINT((ndo, ", 802.3")); + else + (void)ND_PRINT((ndo, ", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ether_type))); + } + + (void)ND_PRINT((ndo, ", length %u: ", length)); +} + +/* + * Print an Ethernet frame. + * This might be encapsulated within another frame; we might be passed + * a pointer to a function that can print header information for that + * frame's protocol, and an argument to pass to that function. + */ +void +ether_print(netdissect_options *ndo, + const u_char *p, u_int length, u_int caplen, + void (*print_encap_header)(netdissect_options *ndo, const u_char *), const u_char *encap_header_arg) +{ + struct ether_header *ep; + u_int orig_length; + u_short ether_type; + u_short extracted_ether_type; + + if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) { + ND_PRINT((ndo, "[|ether]")); + return; + } + + if (ndo->ndo_eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(ndo, encap_header_arg); + ether_hdr_print(ndo, p, length); + } + orig_length = length; + + length -= ETHER_HDRLEN; + caplen -= ETHER_HDRLEN; + ep = (struct ether_header *)p; + p += ETHER_HDRLEN; + + ether_type = EXTRACT_16BITS(&ep->ether_type); + +recurse: + /* + * Is it (gag) an 802.3 encapsulation? + */ + if (ether_type <= ETHERMTU) { + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(ep), EDST(ep), + &extracted_ether_type) == 0) { + /* ether_type not known, print raw packet */ + if (!ndo->ndo_eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(ndo, encap_header_arg); + ether_hdr_print(ndo, (u_char *)ep, orig_length); + } + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + } + } else if (ether_type == ETHERTYPE_8021Q || + ether_type == ETHERTYPE_8021Q9100 || + ether_type == ETHERTYPE_8021Q9200 || + ether_type == ETHERTYPE_8021QinQ) { + /* + * Print VLAN information, and then go back and process + * the enclosed type field. + */ + if (caplen < 4 || length < 4) { + ND_PRINT((ndo, "[|vlan]")); + return; + } + if (ndo->ndo_eflag) { + u_int16_t tag = EXTRACT_16BITS(p); + + ND_PRINT((ndo, "vlan %u, p %u%s, ", + tag & 0xfff, + tag >> 13, + (tag & 0x1000) ? ", CFI" : "")); + } + + ether_type = EXTRACT_16BITS(p + 2); + if (ndo->ndo_eflag && ether_type > ETHERMTU) + ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type))); + p += 4; + length -= 4; + caplen -= 4; + goto recurse; + } else if (ether_type == ETHERTYPE_JUMBO) { + /* + * Alteon jumbo frames. + * See + * + * http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01 + * + * which indicates that, following the type field, + * there's an LLC header and payload. + */ + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(ep), EDST(ep), + &extracted_ether_type) == 0) { + /* ether_type not known, print raw packet */ + if (!ndo->ndo_eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(ndo, encap_header_arg); + ether_hdr_print(ndo, (u_char *)ep, orig_length); + } + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + } + } else { + if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) { + /* ether_type not known, print raw packet */ + if (!ndo->ndo_eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(ndo, encap_header_arg); + ether_hdr_print(ndo, (u_char *)ep, orig_length); + } + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + } + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether 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 +ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *p) +{ + ether_print(ndo, p, h->len, h->caplen, NULL, NULL); + + return (ETHER_HDRLEN); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether 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. + * + * This is for DLT_NETANALYZER, which has a 4-byte pseudo-header + * before the Ethernet header. + */ +u_int +netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *p) +{ + /* + * Fail if we don't have enough data for the Hilscher pseudo-header. + */ + if (h->len < 4 || h->caplen < 4) { + printf("[|netanalyzer]"); + return (h->caplen); + } + + /* Skip the pseudo-header. */ + ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL); + + return (4 + ETHER_HDRLEN); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether 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. + * + * This is for DLT_NETANALYZER_TRANSPARENT, which has a 4-byte + * pseudo-header, a 7-byte Ethernet preamble, and a 1-byte Ethernet SOF + * before the Ethernet header. + */ +u_int +netanalyzer_transparent_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, + const u_char *p) +{ + /* + * Fail if we don't have enough data for the Hilscher pseudo-header, + * preamble, and SOF. + */ + if (h->len < 12 || h->caplen < 12) { + printf("[|netanalyzer-transparent]"); + return (h->caplen); + } + + /* Skip the pseudo-header, preamble, and SOF. */ + ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL); + + return (12 + ETHER_HDRLEN); +} + +/* + * Prints the packet payload, given an Ethernet type code for the payload's + * protocol. + * + * Returns non-zero if it can do so, zero if the ethertype is unknown. + */ + +int +ethertype_print(netdissect_options *ndo, + u_short ether_type, const u_char *p, + u_int length, u_int caplen) +{ + switch (ether_type) { + + case ETHERTYPE_IP: + ip_print(ndo, p, length); + return (1); + +#ifdef INET6 + case ETHERTYPE_IPV6: + ip6_print(ndo, p, length); + return (1); +#endif /*INET6*/ + + case ETHERTYPE_ARP: + case ETHERTYPE_REVARP: + arp_print(ndo, p, length, caplen); + return (1); + + case ETHERTYPE_DN: + decnet_print(/*ndo,*/p, length, caplen); + return (1); + + case ETHERTYPE_ATALK: + if (ndo->ndo_vflag) + fputs("et1 ", stdout); + atalk_print(/*ndo,*/p, length); + return (1); + + case ETHERTYPE_AARP: + aarp_print(/*ndo,*/p, length); + return (1); + + case ETHERTYPE_IPX: + ND_PRINT((ndo, "(NOV-ETHII) ")); + ipx_print(/*ndo,*/p, length); + return (1); + + case ETHERTYPE_ISO: + isoclns_print(/*ndo,*/p+1, length-1, length-1); + return(1); + + case ETHERTYPE_PPPOED: + case ETHERTYPE_PPPOES: + case ETHERTYPE_PPPOED2: + case ETHERTYPE_PPPOES2: + pppoe_print(/*ndo,*/p, length); + return (1); + + case ETHERTYPE_EAPOL: + eap_print(ndo, p, length); + return (1); + + case ETHERTYPE_RRCP: + rrcp_print(ndo, p - 14 , length + 14); + return (1); + + case ETHERTYPE_PPP: + if (length) { + printf(": "); + ppp_print(/*ndo,*/p, length); + } + return (1); + + case ETHERTYPE_MPCP: + mpcp_print(/*ndo,*/p, length); + return (1); + + case ETHERTYPE_SLOW: + slow_print(/*ndo,*/p, length); + return (1); + + case ETHERTYPE_CFM: + case ETHERTYPE_CFM_OLD: + cfm_print(/*ndo,*/p, length); + return (1); + + case ETHERTYPE_LLDP: + lldp_print(/*ndo,*/p, length); + return (1); + + case ETHERTYPE_LOOPBACK: + return (1); + + case ETHERTYPE_MPLS: + case ETHERTYPE_MPLS_MULTI: + mpls_print(/*ndo,*/p, length); + return (1); + + case ETHERTYPE_TIPC: + tipc_print(ndo, p, length, caplen); + return (1); + + case ETHERTYPE_MS_NLB_HB: + msnlb_print(ndo, p, length); + return (1); + + case ETHERTYPE_LAT: + case ETHERTYPE_SCA: + case ETHERTYPE_MOPRC: + case ETHERTYPE_MOPDL: + /* default_print for now */ + default: + return (0); + } +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + diff --git a/freebsd/contrib/tcpdump/print-fddi.c b/freebsd/contrib/tcpdump/print-fddi.c new file mode 100644 index 00000000..9bca7077 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-fddi.c @@ -0,0 +1,313 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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. + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.66 2005-11-13 12:12:41 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" + +#include "ether.h" +#include "fddi.h" + +/* + * Some FDDI interfaces use bit-swapped addresses. + */ +#if defined(ultrix) || defined(__alpha) || defined(__bsdi) || defined(__NetBSD__) || defined(__linux__) +int fddi_bitswap = 0; +#else +int fddi_bitswap = 1; +#endif + +/* + * FDDI support for tcpdump, by Jeffrey Mogul [DECWRL], June 1992 + * + * Based in part on code by Van Jacobson, which bears this note: + * + * NOTE: This is a very preliminary hack for FDDI support. + * There are all sorts of wired in constants & nothing (yet) + * to print SMT packets as anything other than hex dumps. + * Most of the necessary changes are waiting on my redoing + * the "header" that a kernel fddi driver supplies to bpf: I + * want it to look like one byte of 'direction' (0 or 1 + * depending on whether the packet was inbound or outbound), + * two bytes of system/driver dependent data (anything an + * implementor thinks would be useful to filter on and/or + * save per-packet, then the real 21-byte FDDI header. + * Steve McCanne & I have also talked about adding the + * 'direction' byte to all bpf headers (e.g., in the two + * bytes of padding on an ethernet header). It's not clear + * we could do this in a backwards compatible way & we hate + * the idea of an incompatible bpf change. Discussions are + * proceeding. + * + * Also, to really support FDDI (and better support 802.2 + * over ethernet) we really need to re-think the rather simple + * minded assumptions about fixed length & fixed format link + * level headers made in gencode.c. One day... + * + * - vj + */ + +static u_char fddi_bit_swap[] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, +}; + +/* + * Print FDDI frame-control bits + */ +static inline void +print_fddi_fc(u_char fc) +{ + switch (fc) { + + case FDDIFC_VOID: /* Void frame */ + printf("void "); + break; + + case FDDIFC_NRT: /* Nonrestricted token */ + printf("nrt "); + break; + + case FDDIFC_RT: /* Restricted token */ + printf("rt "); + break; + + case FDDIFC_SMT_INFO: /* SMT Info */ + printf("info "); + break; + + case FDDIFC_SMT_NSA: /* SMT Next station adrs */ + printf("nsa "); + break; + + case FDDIFC_MAC_BEACON: /* MAC Beacon frame */ + printf("beacon "); + break; + + case FDDIFC_MAC_CLAIM: /* MAC Claim frame */ + printf("claim "); + break; + + default: + switch (fc & FDDIFC_CLFF) { + + case FDDIFC_MAC: + printf("mac%1x ", fc & FDDIFC_ZZZZ); + break; + + case FDDIFC_SMT: + printf("smt%1x ", fc & FDDIFC_ZZZZ); + break; + + case FDDIFC_LLC_ASYNC: + printf("async%1x ", fc & FDDIFC_ZZZZ); + break; + + case FDDIFC_LLC_SYNC: + printf("sync%1x ", fc & FDDIFC_ZZZZ); + break; + + case FDDIFC_IMP_ASYNC: + printf("imp_async%1x ", fc & FDDIFC_ZZZZ); + break; + + case FDDIFC_IMP_SYNC: + printf("imp_sync%1x ", fc & FDDIFC_ZZZZ); + break; + + default: + printf("%02x ", fc); + break; + } + } +} + +/* Extract src, dst addresses */ +static inline void +extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst) +{ + register int i; + + if (fddi_bitswap) { + /* + * bit-swap the fddi addresses (isn't the IEEE standards + * process wonderful!) then convert them to names. + */ + for (i = 0; i < 6; ++i) + fdst[i] = fddi_bit_swap[fddip->fddi_dhost[i]]; + for (i = 0; i < 6; ++i) + fsrc[i] = fddi_bit_swap[fddip->fddi_shost[i]]; + } + else { + memcpy(fdst, (const char *)fddip->fddi_dhost, 6); + memcpy(fsrc, (const char *)fddip->fddi_shost, 6); + } +} + +/* + * Print the FDDI MAC header + */ +static inline void +fddi_hdr_print(register const struct fddi_header *fddip, register u_int length, + register const u_char *fsrc, register const u_char *fdst) +{ + const char *srcname, *dstname; + + srcname = etheraddr_string(fsrc); + dstname = etheraddr_string(fdst); + + if (vflag) + (void) printf("%02x %s %s %d: ", + fddip->fddi_fc, + srcname, dstname, + length); + else if (qflag) + printf("%s %s %d: ", srcname, dstname, length); + else { + (void) print_fddi_fc(fddip->fddi_fc); + (void) printf("%s %s %d: ", srcname, dstname, length); + } +} + +static inline void +fddi_smt_print(const u_char *p _U_, u_int length _U_) +{ + printf("<SMT printer not yet implemented>"); +} + +void +fddi_print(const u_char *p, u_int length, u_int caplen) +{ + const struct fddi_header *fddip = (const struct fddi_header *)p; + struct ether_header ehdr; + u_short extracted_ethertype; + + if (caplen < FDDI_HDRLEN) { + printf("[|fddi]"); + return; + } + + /* + * Get the FDDI addresses into a canonical form + */ + extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr)); + + if (eflag) + fddi_hdr_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); + + /* Skip over FDDI MAC header */ + length -= FDDI_HDRLEN; + p += FDDI_HDRLEN; + caplen -= FDDI_HDRLEN; + + /* Frame Control field determines interpretation of packet */ + if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) { + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr), + &extracted_ethertype) == 0) { + /* + * Some kinds of LLC packet we cannot + * handle intelligently + */ + if (!eflag) + fddi_hdr_print(fddip, length + FDDI_HDRLEN, + ESRC(&ehdr), EDST(&ehdr)); + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + } + } else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT) + fddi_smt_print(p, caplen); + else { + /* Some kinds of FDDI packet we cannot handle intelligently */ + if (!eflag) + fddi_hdr_print(fddip, length + FDDI_HDRLEN, ESRC(&ehdr), + EDST(&ehdr)); + if (!suppress_default_print) + default_print(p, caplen); + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the FDDI 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 +fddi_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + fddi_print(p, h->len, h->caplen); + + return (FDDI_HDRLEN); +} diff --git a/freebsd/contrib/tcpdump/print-forces.c b/freebsd/contrib/tcpdump/print-forces.c new file mode 100644 index 00000000..4b9f52dd --- /dev/null +++ b/freebsd/contrib/tcpdump/print-forces.c @@ -0,0 +1,1057 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * Copyright (c) 2009 Mojatatu Networks, Inc + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "interface.h" +#include "extract.h" + +#include "forces.h" + +#define RESLEN 4 + +int +prestlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + struct res_val *r = (struct res_val *)tdp; + u_int dlen; + + /* + * pdatacnt_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen != RESLEN) { + printf("illegal RESULT-TLV: %d bytes!\n", dlen); + return -1; + } + + TCHECK(*r); + if (r->result >= 0x18 && r->result <= 0xFE) { + printf("illegal reserved result code: 0x%x!\n", r->result); + return -1; + } + + if (vflag >= 3) { + char *ib = indent_pr(indent, 0); + printf("%s Result: %s (code 0x%x)\n", ib, + tok2str(ForCES_errs, NULL, r->result), r->result); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +fdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + u_int rlen; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + u_int16_t type; + + /* + * pdatacnt_print() or pkeyitlv_print() has ensured that len + * (the TLV length) >= TLV_HDRL. + */ + rlen = len - TLV_HDRL; + TCHECK(*tlv); + type = EXTRACT_16BITS(&tlv->type); + if (type != F_TLV_FULD) { + printf("Error: expecting FULLDATA!\n"); + return -1; + } + + if (vflag >= 3) { + char *ib = indent_pr(indent + 2, 1); + printf("%s[", &ib[1]); + hex_print_with_offset(ib, tdp, rlen, 0); + printf("\n%s]\n", &ib[1]); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +sdatailv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int rlen; + const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + int invilv; + + if (len < ILV_HDRL) { + printf("Error: BAD SPARSEDATA-TLV!\n"); + return -1; + } + rlen = len; + indent += 1; + while (rlen != 0) { + char *ib = indent_pr(indent, 1); + register const u_char *tdp = (u_char *) ILV_DATA(ilv); + TCHECK(*ilv); + invilv = ilv_valid(ilv, rlen); + if (invilv) { + printf("%s[", &ib[1]); + hex_print_with_offset(ib, tdp, rlen, 0); + printf("\n%s]\n", &ib[1]); + return -1; + } + if (vflag >= 3) { + int ilvl = EXTRACT_32BITS(&ilv->length); + printf("\n%s ILV: type %x length %d\n", &ib[1], + EXTRACT_32BITS(&ilv->type), ilvl); + hex_print_with_offset("\t\t[", tdp, ilvl-ILV_HDRL, 0); + } + + ilv = GO_NXT_ILV(ilv, rlen); + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +sdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + u_int rlen; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + u_int16_t type; + + /* + * pdatacnt_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + rlen = len - TLV_HDRL; + TCHECK(*tlv); + type = EXTRACT_16BITS(&tlv->type); + if (type != F_TLV_SPAD) { + printf("Error: expecting SPARSEDATA!\n"); + return -1; + } + + return sdatailv_print(tdp, rlen, op_msk, indent); + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +pkeyitlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + register const u_char *dp = tdp + 4; + const struct forces_tlv *kdtlv = (struct forces_tlv *)dp; + u_int32_t id; + char *ib = indent_pr(indent, 0); + u_int16_t type, tll; + int invtlv; + + TCHECK(*tdp); + id = EXTRACT_32BITS(tdp); + printf("%sKeyinfo: Key 0x%x\n", ib, id); + TCHECK(*kdtlv); + type = EXTRACT_16BITS(&kdtlv->type); + invtlv = tlv_valid(kdtlv, len); + + if (invtlv) { + printf("%s TLV type 0x%x len %d\n", + tok2str(ForCES_TLV_err, NULL, invtlv), type, + EXTRACT_16BITS(&kdtlv->length)); + return -1; + } + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + tll = EXTRACT_16BITS(&kdtlv->length); + dp = (u_char *) TLV_DATA(kdtlv); + return fdatatlv_print(dp, tll, op_msk, indent); + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +pdatacnt_print(register const u_char * pptr, register u_int len, + u_int16_t IDcnt, u_int16_t op_msk, int indent) +{ + u_int i; + u_int32_t id; + char *ib = indent_pr(indent, 0); + + for (i = 0; i < IDcnt; i++) { + TCHECK2(*pptr, 4); + if (len < 4) + goto trunc; + id = EXTRACT_32BITS(pptr); + if (vflag >= 3) + printf("%s ID#%02u: %d\n", ib, i + 1, id); + len -= 4; + pptr += 4; + } + if (len) { + const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + u_int16_t type; + u_int16_t tll; + int pad = 0; + u_int aln; + int invtlv; + + TCHECK(*pdtlv); + type = EXTRACT_16BITS(&pdtlv->type); + invtlv = tlv_valid(pdtlv, len); + if (invtlv) { + printf + ("%s Outstanding bytes %d for TLV type 0x%x TLV len %d\n", + tok2str(ForCES_TLV_err, NULL, invtlv), len, type, + EXTRACT_16BITS(&pdtlv->length)); + goto pd_err; + } + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; + aln = F_ALN_LEN(EXTRACT_16BITS(&pdtlv->length)); + if (aln > EXTRACT_16BITS(&pdtlv->length)) { + if (aln > len) { + printf + ("Invalid padded pathdata TLV type 0x%x len %d missing %d pad bytes\n", + type, EXTRACT_16BITS(&pdtlv->length), aln - len); + } else { + pad = aln - EXTRACT_16BITS(&pdtlv->length); + } + } + if (pd_valid(type)) { + const struct pdata_ops *ops = get_forces_pd(type); + + if (vflag >= 3 && ops->v != F_TLV_PDAT) { + if (pad) + printf + ("%s %s (Length %d DataLen %d pad %d Bytes)\n", + ib, ops->s, EXTRACT_16BITS(&pdtlv->length), + tll, pad); + else + printf + ("%s %s (Length %d DataLen %d Bytes)\n", + ib, ops->s, EXTRACT_16BITS(&pdtlv->length), + tll); + } + + chk_op_type(type, op_msk, ops->op_msk); + + if (ops->print((const u_char *)pdtlv, + tll + pad + TLV_HDRL, op_msk, + indent + 2) == -1) + return -1; + len -= (TLV_HDRL + pad + tll); + } else { + printf("Invalid path data content type 0x%x len %d\n", + type, EXTRACT_16BITS(&pdtlv->length)); +pd_err: + if (EXTRACT_16BITS(&pdtlv->length)) { + hex_print_with_offset("Bad Data val\n\t [", + pptr, len, 0); + printf("]\n"); + + return -1; + } + } + } + return len; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +pdata_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct pathdata_h *pdh = (struct pathdata_h *)pptr; + char *ib = indent_pr(indent, 0); + u_int minsize = 0; + int more_pd = 0; + u_int16_t idcnt = 0; + + TCHECK(*pdh); + if (len < sizeof(struct pathdata_h)) + goto trunc; + if (vflag >= 3) { + printf("\n%sPathdata: Flags 0x%x ID count %d\n", + ib, EXTRACT_16BITS(&pdh->pflags), EXTRACT_16BITS(&pdh->pIDcnt)); + } + + if (EXTRACT_16BITS(&pdh->pflags) & F_SELKEY) { + op_msk |= B_KEYIN; + } + pptr += sizeof(struct pathdata_h); + len -= sizeof(struct pathdata_h); + idcnt = EXTRACT_16BITS(&pdh->pIDcnt); + minsize = idcnt * 4; + if (len < minsize) { + printf("\t\t\ttruncated IDs expected %uB got %uB\n", minsize, + len); + hex_print_with_offset("\t\t\tID Data[", pptr, len, 0); + printf("]\n"); + return -1; + } + more_pd = pdatacnt_print(pptr, len, idcnt, op_msk, indent); + if (more_pd > 0) { + int consumed = len - more_pd; + pptr += consumed; + len = more_pd; + /* XXX: Argh, recurse some more */ + return recpdoptlv_print(pptr, len, op_msk, indent+1); + } else + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +genoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + u_int16_t type; + int tll; + int invtlv; + char *ib = indent_pr(indent, 0); + + TCHECK(*pdtlv); + type = EXTRACT_16BITS(&pdtlv->type); + tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; + invtlv = tlv_valid(pdtlv, len); + printf("genoptlvprint - %s TLV type 0x%x len %d\n", + tok2str(ForCES_TLV, NULL, type), type, EXTRACT_16BITS(&pdtlv->length)); + if (!invtlv) { + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + register const u_char *dp = (u_char *) TLV_DATA(pdtlv); + if (!ttlv_valid(type)) { + printf("%s TLV type 0x%x len %d\n", + tok2str(ForCES_TLV_err, NULL, invtlv), type, + EXTRACT_16BITS(&pdtlv->length)); + return -1; + } + if (vflag >= 3) + printf("%s%s, length %d (data length %d Bytes)", + ib, tok2str(ForCES_TLV, NULL, type), + EXTRACT_16BITS(&pdtlv->length), tll); + + return pdata_print(dp, tll, op_msk, indent + 1); + } else { + printf("\t\t\tInvalid ForCES TLV type=%x", type); + return -1; + } + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +recpdoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + int tll; + int invtlv; + u_int16_t type; + register const u_char *dp; + char *ib; + + while (len != 0) { + TCHECK(*pdtlv); + invtlv = tlv_valid(pdtlv, len); + if (invtlv) { + break; + } + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + ib = indent_pr(indent, 0); + type = EXTRACT_16BITS(&pdtlv->type); + dp = (u_char *) TLV_DATA(pdtlv); + tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; + + if (vflag >= 3) + printf + ("%s%s, length %d (data encapsulated %d Bytes)", + ib, tok2str(ForCES_TLV, NULL, type), + EXTRACT_16BITS(&pdtlv->length), + EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL); + + if (pdata_print(dp, tll, op_msk, indent + 1) == -1) + return -1; + pdtlv = GO_NXT_TLV(pdtlv, len); + } + + if (len) { + printf + ("\n\t\tMessy PATHDATA TLV header, type (0x%x)\n\t\texcess of %d Bytes ", + EXTRACT_16BITS(&pdtlv->type), len - EXTRACT_16BITS(&pdtlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +invoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + char *ib = indent_pr(indent, 1); + + if (vflag >= 3) { + printf("%sData[", &ib[1]); + hex_print_with_offset(ib, pptr, len, 0); + printf("%s]\n", ib); + } + return -1; +} + +int otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk _U_, int indent) +{ + int rc = 0; + register const u_char *dp = (u_char *) TLV_DATA(otlv); + u_int16_t type; + int tll; + char *ib = indent_pr(indent, 0); + const struct optlv_h *ops; + + /* + * lfbselect_print() has ensured that EXTRACT_16BITS(&otlv->length) + * >= TLV_HDRL. + */ + TCHECK(*otlv); + type = EXTRACT_16BITS(&otlv->type); + tll = EXTRACT_16BITS(&otlv->length) - TLV_HDRL; + ops = get_forces_optlv_h(type); + if (vflag >= 3) { + printf("%sOper TLV %s(0x%x) length %d\n", ib, ops->s, type, + EXTRACT_16BITS(&otlv->length)); + } + /* empty TLVs like COMMIT and TRCOMMIT are empty, we stop here .. */ + if (!ops->flags & ZERO_TTLV) { + if (tll != 0) /* instead of "if (tll)" - for readability .. */ + printf("%s: Illegal - MUST be empty\n", ops->s); + return rc; + } + /* rest of ops must at least have 12B {pathinfo} */ + if (tll < OP_MIN_SIZ) { + printf("\t\tOper TLV %s(0x%x) length %d\n", ops->s, type, + EXTRACT_16BITS(&otlv->length)); + printf("\t\tTruncated data size %d minimum required %d\n", tll, + OP_MIN_SIZ); + return invoptlv_print(dp, tll, ops->op_msk, indent); + + } + + rc = ops->print(dp, tll, ops->op_msk, indent + 1); + return rc; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +#define ASTDLN 4 +#define ASTMCD 255 +int +asttlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int32_t rescode; + u_int dlen; + char *ib = indent_pr(indent, 0); + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen != ASTDLN) { + printf("illegal ASTresult-TLV: %d bytes!\n", dlen); + return -1; + } + TCHECK2(*pptr, 4); + rescode = EXTRACT_32BITS(pptr); + if (rescode > ASTMCD) { + printf("illegal ASTresult result code: %d!\n", rescode); + return -1; + } + + if (vflag >= 3) { + printf("Teardown reason:\n%s", ib); + switch (rescode) { + case 0: + printf("Normal Teardown"); + break; + case 1: + printf("Loss of Heartbeats"); + break; + case 2: + printf("Out of bandwidth"); + break; + case 3: + printf("Out of Memory"); + break; + case 4: + printf("Application Crash"); + break; + default: + printf("Unknown Teardown reason"); + break; + } + printf("(%x)\n%s", rescode, ib); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +#define ASRDLN 4 +#define ASRMCD 3 +int +asrtlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int32_t rescode; + u_int dlen; + char *ib = indent_pr(indent, 0); + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen != ASRDLN) { /* id, instance, oper tlv */ + printf("illegal ASRresult-TLV: %d bytes!\n", dlen); + return -1; + } + TCHECK2(*pptr, 4); + rescode = EXTRACT_32BITS(pptr); + + if (rescode > ASRMCD) { + printf("illegal ASRresult result code: %d!\n", rescode); + return -1; + } + + if (vflag >= 3) { + printf("\n%s", ib); + switch (rescode) { + case 0: + printf("Success "); + break; + case 1: + printf("FE ID invalid "); + break; + case 2: + printf("permission denied "); + break; + default: + printf("Unknown "); + break; + } + printf("(%x)\n%s", rescode, ib); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +/* + * XXX - not used. + */ +int +gentltlv_print(register const u_char * pptr _U_, register u_int len, + u_int16_t op_msk _U_, int indent _U_) +{ + u_int dlen = len - TLV_HDRL; + + if (dlen < 4) { /* at least 32 bits must exist */ + printf("truncated TLV: %d bytes missing! ", 4 - dlen); + return -1; + } + return 0; +} + +#define RD_MIN 8 +int +print_metailv(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int dlen; + u_int rlen; + char *ib = indent_pr(indent, 0); + /* XXX: check header length */ + const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + + /* + * print_metatlv() has ensured that len (what remains in the + * ILV) >= ILV_HDRL. + */ + dlen = len - ILV_HDRL; + rlen = dlen; + TCHECK(*ilv); + printf("\n%sMetaID 0x%x length %d\n", ib, EXTRACT_32BITS(&ilv->type), + EXTRACT_32BITS(&ilv->length)); + hex_print_with_offset("\n\t\t\t\t[", ILV_DATA(ilv), rlen, 0); + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +print_metatlv(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int dlen; + char *ib = indent_pr(indent, 0); + u_int rlen; + const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + int invilv; + + /* + * redirect_print() has ensured that len (what remains in the + * TLV) >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + rlen = dlen; + printf("\n%s METADATA\n", ib); + while (rlen != 0) { + TCHECK(*ilv); + invilv = ilv_valid(ilv, rlen); + if (invilv) + break; + + /* + * At this point, ilv_valid() has ensured that the ILV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + print_metailv((u_char *) ilv, rlen, 0, indent + 1); + + ilv = GO_NXT_ILV(ilv, rlen); + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +/* +*/ +int +print_reddata(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent _U_) +{ + u_int dlen; + u_int rlen; + int invtlv; + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + + /* + * redirect_print() has ensured that len (what remains in the + * TLV) >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + printf("\n\t\t Redirect DATA\n"); + if (dlen <= RD_MIN) { + printf("\n\t\ttruncated Redirect data: %d bytes missing! ", + RD_MIN - dlen); + return -1; + } + + rlen = dlen; + TCHECK(*tlv); + invtlv = tlv_valid(tlv, rlen); + + if (invtlv) { + printf("Redir data type 0x%x len %d\n", EXTRACT_16BITS(&tlv->type), + EXTRACT_16BITS(&tlv->length)); + return -1; + } + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + rlen -= TLV_HDRL; + hex_print_with_offset("\n\t\t\t[", TLV_DATA(tlv), rlen, 0); + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +redirect_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + u_int dlen; + u_int rlen; + int invtlv; + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen <= RD_MIN) { + printf("\n\t\ttruncated Redirect TLV: %d bytes missing! ", + RD_MIN - dlen); + return -1; + } + + rlen = dlen; + indent += 1; + while (rlen != 0) { + TCHECK(*tlv); + invtlv = tlv_valid(tlv, rlen); + if (invtlv) + break; + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + if (EXTRACT_16BITS(&tlv->type) == F_TLV_METD) { + print_metatlv((u_char *) TLV_DATA(tlv), rlen, 0, indent); + } else if ((EXTRACT_16BITS(&tlv->type) == F_TLV_REDD)) { + print_reddata((u_char *) TLV_DATA(tlv), rlen, 0, indent); + } else { + printf("Unknown REDIRECT TLV 0x%x len %d\n", + EXTRACT_16BITS(&tlv->type), EXTRACT_16BITS(&tlv->length)); + } + + tlv = GO_NXT_TLV(tlv, rlen); + } + + if (rlen) { + printf + ("\n\t\tMessy Redirect TLV header, type (0x%x)\n\t\texcess of %d Bytes ", + EXTRACT_16BITS(&tlv->type), rlen - EXTRACT_16BITS(&tlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +#define OP_OFF 8 +#define OP_MIN 12 + +int +lfbselect_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_lfbsh *lfbs; + const struct forces_tlv *otlv; + char *ib = indent_pr(indent, 0); + u_int dlen; + u_int rlen; + int invtlv; + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen <= OP_MIN) { /* id, instance, oper tlv header .. */ + printf("\n\t\ttruncated lfb selector: %d bytes missing! ", + OP_MIN - dlen); + return -1; + } + + /* + * At this point, we know that dlen > OP_MIN; OP_OFF < OP_MIN, so + * we also know that it's > OP_OFF. + */ + rlen = dlen - OP_OFF; + + lfbs = (const struct forces_lfbsh *)pptr; + TCHECK(*lfbs); + if (vflag >= 3) { + printf("\n%s%s(Classid %x) instance %x\n", + ib, tok2str(ForCES_LFBs, NULL, EXTRACT_32BITS(&lfbs->class)), + EXTRACT_32BITS(&lfbs->class), + EXTRACT_32BITS(&lfbs->instance)); + } + + otlv = (struct forces_tlv *)(lfbs + 1); + + indent += 1; + while (rlen != 0) { + TCHECK(*otlv); + invtlv = tlv_valid(otlv, rlen); + if (invtlv) + break; + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + if (op_valid(EXTRACT_16BITS(&otlv->type), op_msk)) { + otlv_print(otlv, 0, indent); + } else { + if (vflag < 3) + printf("\n"); + printf + ("\t\tINValid oper-TLV type 0x%x length %d for this ForCES message\n", + EXTRACT_16BITS(&otlv->type), EXTRACT_16BITS(&otlv->length)); + invoptlv_print((u_char *)otlv, rlen, 0, indent); + } + otlv = GO_NXT_TLV(otlv, rlen); + } + + if (rlen) { + printf + ("\n\t\tMessy oper TLV header, type (0x%x)\n\t\texcess of %d Bytes ", + EXTRACT_16BITS(&otlv->type), rlen - EXTRACT_16BITS(&otlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +forces_type_print(register const u_char * pptr, const struct forcesh *fhdr _U_, + register u_int mlen, const struct tom_h *tops) +{ + const struct forces_tlv *tltlv; + u_int rlen; + int invtlv; + int rc = 0; + int ttlv = 0; + + /* + * forces_print() has already checked that mlen >= ForCES_HDRL + * by calling ForCES_HLN_VALID(). + */ + rlen = mlen - ForCES_HDRL; + + if (rlen > TLV_HLN) { + if (tops->flags & ZERO_TTLV) { + printf("<0x%x>Illegal Top level TLV!\n", tops->flags); + return -1; + } + } else { + if (tops->flags & ZERO_MORE_TTLV) + return 0; + if (tops->flags & ONE_MORE_TTLV) { + printf("\tTop level TLV Data missing!\n"); + return -1; + } + } + + if (tops->flags & ZERO_TTLV) { + return 0; + } + + ttlv = tops->flags >> 4; + tltlv = GET_TOP_TLV(pptr); + + /*XXX: 15 top level tlvs will probably be fine + You are nuts if you send more ;-> */ + while (rlen != 0) { + TCHECK(*tltlv); + invtlv = tlv_valid(tltlv, rlen); + if (invtlv) + break; + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the packet). + */ + if (!ttlv_valid(EXTRACT_16BITS(&tltlv->type))) { + printf("\n\tInvalid ForCES Top TLV type=0x%x", + EXTRACT_16BITS(&tltlv->type)); + return -1; + } + + if (vflag >= 3) + printf("\t%s, length %d (data length %d Bytes)", + tok2str(ForCES_TLV, NULL, EXTRACT_16BITS(&tltlv->type)), + EXTRACT_16BITS(&tltlv->length), + EXTRACT_16BITS(&tltlv->length) - TLV_HDRL); + + rc = tops->print((u_char *) TLV_DATA(tltlv), + EXTRACT_16BITS(&tltlv->length), tops->op_msk, 9); + if (rc < 0) { + return -1; + } + tltlv = GO_NXT_TLV(tltlv, rlen); + ttlv--; + if (ttlv <= 0) + break; + } + /* + * XXX - if ttlv != 0, does that mean that the packet was too + * short, and didn't have *enough* TLVs in it? + */ + if (rlen) { + printf("\tMess TopTLV header: min %u, total %d advertised %d ", + TLV_HDRL, rlen, EXTRACT_16BITS(&tltlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +void forces_print(register const u_char * pptr, register u_int len) +{ + const struct forcesh *fhdr; + u_int mlen; + u_int32_t flg_raw; + const struct tom_h *tops; + int rc = 0; + + fhdr = (const struct forcesh *)pptr; + TCHECK(*fhdr); + if (!tom_valid(fhdr->fm_tom)) { + printf("Invalid ForCES message type %d\n", fhdr->fm_tom); + goto error; + } + + mlen = ForCES_BLN(fhdr); + + tops = get_forces_tom(fhdr->fm_tom); + if (tops->v == TOM_RSVD) { + printf("\n\tUnknown ForCES message type=0x%x", fhdr->fm_tom); + goto error; + } + + printf("\n\tForCES %s ", tops->s); + if (!ForCES_HLN_VALID(mlen, len)) { + printf + ("Illegal ForCES pkt len - min %u, total recvd %d, advertised %d ", + ForCES_HDRL, len, ForCES_BLN(fhdr)); + goto error; + } + + TCHECK2(*(pptr + 20), 4); + flg_raw = EXTRACT_32BITS(pptr + 20); + if (vflag >= 1) { + printf("\n\tForCES Version %d len %uB flags 0x%08x ", + ForCES_V(fhdr), mlen, flg_raw); + printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIx64, + ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)), + ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)), + EXTRACT_64BITS(fhdr->fm_cor)); + + } + if (vflag >= 2) { + printf + ("\n\tForCES flags:\n\t %s(0x%x), prio=%d, %s(0x%x),\n\t %s(0x%x), %s(0x%x)\n", + ForCES_ACKp(ForCES_ACK(fhdr)), ForCES_ACK(fhdr), + ForCES_PRI(fhdr), + ForCES_EMp(ForCES_EM(fhdr)), ForCES_EM(fhdr), + ForCES_ATp(ForCES_AT(fhdr)), ForCES_AT(fhdr), + ForCES_TPp(ForCES_TP(fhdr)), ForCES_TP(fhdr)); + printf + ("\t Extra flags: rsv(b5-7) 0x%x rsv(b13-31) 0x%x\n", + ForCES_RS1(fhdr), ForCES_RS2(fhdr)); + } + rc = forces_type_print(pptr, fhdr, mlen, tops); + if (rc < 0) { +error: + hex_print_with_offset("\n\t[", pptr, len, 0); + printf("\n\t]"); + return; + } + + if (vflag >= 4) { + printf("\n\t Raw ForCES message\n\t ["); + hex_print_with_offset("\n\t ", pptr, len, 0); + printf("\n\t ]"); + } + printf("\n"); + return; + +trunc: + fputs("[|forces]", stdout); +} diff --git a/freebsd/contrib/tcpdump/print-fr.c b/freebsd/contrib/tcpdump/print-fr.c new file mode 100644 index 00000000..73e056d4 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-fr.c @@ -0,0 +1,887 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * $FreeBSD$ + */ + +#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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> +#include <pcap.h> + +#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 + + +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 ) + +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 + +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 + +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 + +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 + +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 + +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 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; +} diff --git a/freebsd/contrib/tcpdump/print-frag6.c b/freebsd/contrib/tcpdump/print-frag6.c new file mode 100644 index 00000000..5401de13 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-frag6.c @@ -0,0 +1,84 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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-frag6.c,v 1.20 2005-04-20 22:33:06 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef INET6 + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "ip6.h" + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +int +frag6_print(register const u_char *bp, register const u_char *bp2) +{ + register const struct ip6_frag *dp; + register const struct ip6_hdr *ip6; + + dp = (const struct ip6_frag *)bp; + ip6 = (const struct ip6_hdr *)bp2; + + TCHECK(dp->ip6f_offlg); + + if (vflag) { + printf("frag (0x%08x:%d|%ld)", + EXTRACT_32BITS(&dp->ip6f_ident), + EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK, + sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen) - + (long)(bp - bp2) - sizeof(struct ip6_frag)); + } else { + printf("frag (%d|%ld)", + EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK, + sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen) - + (long)(bp - bp2) - sizeof(struct ip6_frag)); + } + +#if 1 + /* it is meaningless to decode non-first fragment */ + if ((EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK) != 0) + return -1; + else +#endif + { + fputs(" ", stdout); + return sizeof(struct ip6_frag); + } +trunc: + fputs("[|frag]", stdout); + return -1; +#undef TCHECK +} +#endif /* INET6 */ diff --git a/freebsd/contrib/tcpdump/print-gre.c b/freebsd/contrib/tcpdump/print-gre.c new file mode 100644 index 00000000..a3e6c315 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-gre.c @@ -0,0 +1,405 @@ +#include <machine/rtems-bsd-user-space.h> + +/* $OpenBSD: print-gre.c,v 1.6 2002/10/30 03:04:04 fgsch Exp $ */ + +/* + * Copyright (c) 2002 Jason L. Wright (jason@thought.net) + * 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 Jason L. Wright + * 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. + */ + +/* + * tcpdump filter for GRE - Generic Routing Encapsulation + * RFC1701 (GRE), RFC1702 (GRE IPv4), and RFC2637 (Enhanced GRE) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-gre.c,v 1.28 2005-04-06 21:32:39 mcr Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip.h" +#include "ethertype.h" + +#define GRE_CP 0x8000 /* checksum present */ +#define GRE_RP 0x4000 /* routing present */ +#define GRE_KP 0x2000 /* key present */ +#define GRE_SP 0x1000 /* sequence# present */ +#define GRE_sP 0x0800 /* source routing */ +#define GRE_RECRS 0x0700 /* recursion count */ +#define GRE_AP 0x0080 /* acknowledgment# present */ + +struct tok gre_flag_values[] = { + { GRE_CP, "checksum present"}, + { GRE_RP, "routing present"}, + { GRE_KP, "key present"}, + { GRE_SP, "sequence# present"}, + { GRE_sP, "source routing present"}, + { GRE_RECRS, "recursion count"}, + { GRE_AP, "ack present"}, + { 0, NULL } +}; + +#define GRE_VERS_MASK 0x0007 /* protocol version */ + +/* source route entry types */ +#define GRESRE_IP 0x0800 /* IP */ +#define GRESRE_ASN 0xfffe /* ASN */ + +void gre_print_0(const u_char *, u_int); +void gre_print_1(const u_char *, u_int); +void gre_sre_print(u_int16_t, u_int8_t, u_int8_t, const u_char *, u_int); +void gre_sre_ip_print(u_int8_t, u_int8_t, const u_char *, u_int); +void gre_sre_asn_print(u_int8_t, u_int8_t, const u_char *, u_int); + +void +gre_print(const u_char *bp, u_int length) +{ + u_int len = length, vers; + + if (len < 2) { + printf("[|gre]"); + return; + } + vers = EXTRACT_16BITS(bp) & GRE_VERS_MASK; + printf("GREv%u",vers); + + switch(vers) { + case 0: + gre_print_0(bp, len); + break; + case 1: + gre_print_1(bp, len); + break; + default: + printf(" ERROR: unknown-version"); + break; + } + return; + +} + +void +gre_print_0(const u_char *bp, u_int length) +{ + u_int len = length; + u_int16_t flags, prot; + + flags = EXTRACT_16BITS(bp); + if (vflag) + printf(", Flags [%s]", + bittok2str(gre_flag_values,"none",flags)); + + len -= 2; + bp += 2; + + if (len < 2) + goto trunc; + prot = EXTRACT_16BITS(bp); + len -= 2; + bp += 2; + + if ((flags & GRE_CP) | (flags & GRE_RP)) { + if (len < 2) + goto trunc; + if (vflag) + printf(", sum 0x%x", EXTRACT_16BITS(bp)); + bp += 2; + len -= 2; + + if (len < 2) + goto trunc; + printf(", off 0x%x", EXTRACT_16BITS(bp)); + bp += 2; + len -= 2; + } + + if (flags & GRE_KP) { + if (len < 4) + goto trunc; + printf(", key=0x%x", EXTRACT_32BITS(bp)); + bp += 4; + len -= 4; + } + + if (flags & GRE_SP) { + if (len < 4) + goto trunc; + printf(", seq %u", EXTRACT_32BITS(bp)); + bp += 4; + len -= 4; + } + + if (flags & GRE_RP) { + for (;;) { + u_int16_t af; + u_int8_t sreoff; + u_int8_t srelen; + + if (len < 4) + goto trunc; + af = EXTRACT_16BITS(bp); + sreoff = *(bp + 2); + srelen = *(bp + 3); + bp += 4; + len -= 4; + + if (af == 0 && srelen == 0) + break; + + gre_sre_print(af, sreoff, srelen, bp, len); + + if (len < srelen) + goto trunc; + bp += srelen; + len -= srelen; + } + } + + if (eflag) + printf(", proto %s (0x%04x)", + tok2str(ethertype_values,"unknown",prot), + prot); + + printf(", length %u",length); + + if (vflag < 1) + printf(": "); /* put in a colon as protocol demarc */ + else + printf("\n\t"); /* if verbose go multiline */ + + switch (prot) { + case ETHERTYPE_IP: + ip_print(gndo, bp, len); + break; +#ifdef INET6 + case ETHERTYPE_IPV6: + ip6_print(gndo, bp, len); + break; +#endif + case ETHERTYPE_MPLS: + mpls_print(bp, len); + break; + case ETHERTYPE_IPX: + ipx_print(bp, len); + break; + case ETHERTYPE_ATALK: + atalk_print(bp, len); + break; + case ETHERTYPE_GRE_ISO: + isoclns_print(bp, len, len); + break; + case ETHERTYPE_TEB: + ether_print(gndo, bp, len, len, NULL, NULL); + break; + default: + printf("gre-proto-0x%x", prot); + } + return; + +trunc: + printf("[|gre]"); +} + +void +gre_print_1(const u_char *bp, u_int length) +{ + u_int len = length; + u_int16_t flags, prot; + + flags = EXTRACT_16BITS(bp); + len -= 2; + bp += 2; + + if (vflag) + printf(", Flags [%s]", + bittok2str(gre_flag_values,"none",flags)); + + if (len < 2) + goto trunc; + prot = EXTRACT_16BITS(bp); + len -= 2; + bp += 2; + + + if (flags & GRE_KP) { + u_int32_t k; + + if (len < 4) + goto trunc; + k = EXTRACT_32BITS(bp); + printf(", call %d", k & 0xffff); + len -= 4; + bp += 4; + } + + if (flags & GRE_SP) { + if (len < 4) + goto trunc; + printf(", seq %u", EXTRACT_32BITS(bp)); + bp += 4; + len -= 4; + } + + if (flags & GRE_AP) { + if (len < 4) + goto trunc; + printf(", ack %u", EXTRACT_32BITS(bp)); + bp += 4; + len -= 4; + } + + if ((flags & GRE_SP) == 0) + printf(", no-payload"); + + if (eflag) + printf(", proto %s (0x%04x)", + tok2str(ethertype_values,"unknown",prot), + prot); + + printf(", length %u",length); + + if ((flags & GRE_SP) == 0) + return; + + if (vflag < 1) + printf(": "); /* put in a colon as protocol demarc */ + else + printf("\n\t"); /* if verbose go multiline */ + + switch (prot) { + case ETHERTYPE_PPP: + ppp_print(bp, len); + break; + default: + printf("gre-proto-0x%x", prot); + break; + } + return; + +trunc: + printf("[|gre]"); +} + +void +gre_sre_print(u_int16_t af, u_int8_t sreoff, u_int8_t srelen, + const u_char *bp, u_int len) +{ + switch (af) { + case GRESRE_IP: + printf(", (rtaf=ip"); + gre_sre_ip_print(sreoff, srelen, bp, len); + printf(") "); + break; + case GRESRE_ASN: + printf(", (rtaf=asn"); + gre_sre_asn_print(sreoff, srelen, bp, len); + printf(") "); + break; + default: + printf(", (rtaf=0x%x) ", af); + } +} +void +gre_sre_ip_print(u_int8_t sreoff, u_int8_t srelen, const u_char *bp, u_int len) +{ + struct in_addr a; + const u_char *up = bp; + + if (sreoff & 3) { + printf(", badoffset=%u", sreoff); + return; + } + if (srelen & 3) { + printf(", badlength=%u", srelen); + return; + } + if (sreoff >= srelen) { + printf(", badoff/len=%u/%u", sreoff, srelen); + return; + } + + for (;;) { + if (len < 4 || srelen == 0) + return; + + memcpy(&a, bp, sizeof(a)); + printf(" %s%s", + ((bp - up) == sreoff) ? "*" : "", + inet_ntoa(a)); + + bp += 4; + len -= 4; + srelen -= 4; + } +} + +void +gre_sre_asn_print(u_int8_t sreoff, u_int8_t srelen, const u_char *bp, u_int len) +{ + const u_char *up = bp; + + if (sreoff & 1) { + printf(", badoffset=%u", sreoff); + return; + } + if (srelen & 1) { + printf(", badlength=%u", srelen); + return; + } + if (sreoff >= srelen) { + printf(", badoff/len=%u/%u", sreoff, srelen); + return; + } + + for (;;) { + if (len < 2 || srelen == 0) + return; + + printf(" %s%x", + ((bp - up) == sreoff) ? "*" : "", + EXTRACT_16BITS(bp)); + + bp += 2; + len -= 2; + srelen -= 2; + } +} diff --git a/freebsd/contrib/tcpdump/print-hsrp.c b/freebsd/contrib/tcpdump/print-hsrp.c new file mode 100644 index 00000000..51d4b107 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-hsrp.c @@ -0,0 +1,142 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> + +#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 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]"); +} diff --git a/freebsd/contrib/tcpdump/print-icmp.c b/freebsd/contrib/tcpdump/print-icmp.c new file mode 100644 index 00000000..8cdc3651 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-icmp.c @@ -0,0 +1,699 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * $FreeBSD$ + */ + +#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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#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 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 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 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); +} diff --git a/freebsd/contrib/tcpdump/print-icmp6.c b/freebsd/contrib/tcpdump/print-icmp6.c new file mode 100644 index 00000000..69a4016c --- /dev/null +++ b/freebsd/contrib/tcpdump/print-icmp6.c @@ -0,0 +1,1388 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#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 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 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 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 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 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 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 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(", errorneous - 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 */ diff --git a/freebsd/contrib/tcpdump/print-igmp.c b/freebsd/contrib/tcpdump/print-igmp.c new file mode 100644 index 00000000..e2bc597e --- /dev/null +++ b/freebsd/contrib/tcpdump/print-igmp.c @@ -0,0 +1,346 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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-igmp.c,v 1.15 2004-03-24 00:59:16 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#ifndef IN_CLASSD +#define IN_CLASSD(i) (((int32_t)(i) & 0xf0000000) == 0xe0000000) +#endif + +/* (following from ipmulti/mrouted/prune.h) */ + +/* + * The packet format for a traceroute request. + */ +struct tr_query { + u_int32_t tr_src; /* traceroute source */ + u_int32_t tr_dst; /* traceroute destination */ + u_int32_t tr_raddr; /* traceroute response address */ + u_int32_t tr_rttlqid; /* response ttl and qid */ +}; + +#define TR_GETTTL(x) (int)(((x) >> 24) & 0xff) +#define TR_GETQID(x) ((x) & 0x00ffffff) + +/* + * Traceroute response format. A traceroute response has a tr_query at the + * beginning, followed by one tr_resp for each hop taken. + */ +struct tr_resp { + u_int32_t tr_qarr; /* query arrival time */ + u_int32_t tr_inaddr; /* incoming interface address */ + u_int32_t tr_outaddr; /* outgoing interface address */ + u_int32_t tr_rmtaddr; /* parent address in source tree */ + u_int32_t tr_vifin; /* input packet count on interface */ + u_int32_t tr_vifout; /* output packet count on interface */ + u_int32_t tr_pktcnt; /* total incoming packets for src-grp */ + u_int8_t tr_rproto; /* routing proto deployed on router */ + u_int8_t tr_fttl; /* ttl required to forward on outvif */ + u_int8_t tr_smask; /* subnet mask for src addr */ + u_int8_t tr_rflags; /* forwarding error codes */ +}; + +/* defs within mtrace */ +#define TR_QUERY 1 +#define TR_RESP 2 + +/* fields for tr_rflags (forwarding error codes) */ +#define TR_NO_ERR 0 +#define TR_WRONG_IF 1 +#define TR_PRUNED 2 +#define TR_OPRUNED 3 +#define TR_SCOPED 4 +#define TR_NO_RTE 5 +#define TR_NO_FWD 7 +#define TR_NO_SPACE 0x81 +#define TR_OLD_ROUTER 0x82 + +/* fields for tr_rproto (routing protocol) */ +#define TR_PROTO_DVMRP 1 +#define TR_PROTO_MOSPF 2 +#define TR_PROTO_PIM 3 +#define TR_PROTO_CBT 4 + +/* igmpv3 report types */ +static struct tok igmpv3report2str[] = { + { 1, "is_in" }, + { 2, "is_ex" }, + { 3, "to_in" }, + { 4, "to_ex" }, + { 5, "allow" }, + { 6, "block" }, + { 0, NULL } +}; + +static void +print_mtrace(register const u_char *bp, register u_int len) +{ + register const struct tr_query *tr = (const struct tr_query *)(bp + 8); + + TCHECK(*tr); + if (len < 8 + sizeof (struct tr_query)) { + (void)printf(" [invalid len %d]", len); + return; + } + printf("mtrace %u: %s to %s reply-to %s", + TR_GETQID(EXTRACT_32BITS(&tr->tr_rttlqid)), + ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst), + ipaddr_string(&tr->tr_raddr)); + if (IN_CLASSD(EXTRACT_32BITS(&tr->tr_raddr))) + printf(" with-ttl %d", TR_GETTTL(EXTRACT_32BITS(&tr->tr_rttlqid))); + return; +trunc: + (void)printf("[|igmp]"); + return; +} + +static void +print_mresp(register const u_char *bp, register u_int len) +{ + register const struct tr_query *tr = (const struct tr_query *)(bp + 8); + + TCHECK(*tr); + if (len < 8 + sizeof (struct tr_query)) { + (void)printf(" [invalid len %d]", len); + return; + } + printf("mresp %lu: %s to %s reply-to %s", + (u_long)TR_GETQID(EXTRACT_32BITS(&tr->tr_rttlqid)), + ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst), + ipaddr_string(&tr->tr_raddr)); + if (IN_CLASSD(EXTRACT_32BITS(&tr->tr_raddr))) + printf(" with-ttl %d", TR_GETTTL(EXTRACT_32BITS(&tr->tr_rttlqid))); + return; +trunc: + (void)printf("[|igmp]"); + return; +} + +static void +print_igmpv3_report(register const u_char *bp, register u_int len) +{ + u_int group, nsrcs, ngroups; + register u_int i, j; + + /* Minimum len is 16, and should be a multiple of 4 */ + if (len < 16 || len & 0x03) { + (void)printf(" [invalid len %d]", len); + return; + } + TCHECK2(bp[6], 2); + ngroups = EXTRACT_16BITS(&bp[6]); + (void)printf(", %d group record(s)", ngroups); + if (vflag > 0) { + /* Print the group records */ + group = 8; + for (i=0; i<ngroups; i++) { + if (len < group+8) { + (void)printf(" [invalid number of groups]"); + return; + } + TCHECK2(bp[group+4], 4); + (void)printf(" [gaddr %s", ipaddr_string(&bp[group+4])); + (void)printf(" %s", tok2str(igmpv3report2str, " [v3-report-#%d]", + bp[group])); + nsrcs = EXTRACT_16BITS(&bp[group+2]); + /* Check the number of sources and print them */ + if (len < group+8+(nsrcs<<2)) { + (void)printf(" [invalid number of sources %d]", nsrcs); + return; + } + if (vflag == 1) + (void)printf(", %d source(s)", nsrcs); + else { + /* Print the sources */ + (void)printf(" {"); + for (j=0; j<nsrcs; j++) { + TCHECK2(bp[group+8+(j<<2)], 4); + (void)printf(" %s", ipaddr_string(&bp[group+8+(j<<2)])); + } + (void)printf(" }"); + } + /* Next group record */ + group += 8 + (nsrcs << 2); + (void)printf("]"); + } + } + return; +trunc: + (void)printf("[|igmp]"); + return; +} + +static void +print_igmpv3_query(register const u_char *bp, register u_int len) +{ + u_int mrc; + int mrt; + u_int nsrcs; + register u_int i; + + (void)printf(" v3"); + /* Minimum len is 12, and should be a multiple of 4 */ + if (len < 12 || len & 0x03) { + (void)printf(" [invalid len %d]", len); + return; + } + TCHECK(bp[1]); + mrc = bp[1]; + if (mrc < 128) { + mrt = mrc; + } else { + mrt = ((mrc & 0x0f) | 0x10) << (((mrc & 0x70) >> 4) + 3); + } + if (mrc != 100) { + (void)printf(" [max resp time "); + if (mrt < 600) { + (void)printf("%.1fs", mrt * 0.1); + } else { + relts_print(mrt / 10); + } + (void)printf("]"); + } + TCHECK2(bp[4], 4); + if (EXTRACT_32BITS(&bp[4]) == 0) + return; + (void)printf(" [gaddr %s", ipaddr_string(&bp[4])); + TCHECK2(bp[10], 2); + nsrcs = EXTRACT_16BITS(&bp[10]); + if (nsrcs > 0) { + if (len < 12 + (nsrcs << 2)) + (void)printf(" [invalid number of sources]"); + else if (vflag > 1) { + (void)printf(" {"); + for (i=0; i<nsrcs; i++) { + TCHECK2(bp[12+(i<<2)], 4); + (void)printf(" %s", ipaddr_string(&bp[12+(i<<2)])); + } + (void)printf(" }"); + } else + (void)printf(", %d source(s)", nsrcs); + } + (void)printf("]"); + return; +trunc: + (void)printf("[|igmp]"); + return; +} + +void +igmp_print(register const u_char *bp, register u_int len) +{ + struct cksum_vec vec[1]; + + if (qflag) { + (void)printf("igmp"); + return; + } + + TCHECK(bp[0]); + switch (bp[0]) { + case 0x11: + (void)printf("igmp query"); + if (len >= 12) + print_igmpv3_query(bp, len); + else { + TCHECK(bp[1]); + if (bp[1]) { + (void)printf(" v2"); + if (bp[1] != 100) + (void)printf(" [max resp time %d]", bp[1]); + } else + (void)printf(" v1"); + TCHECK2(bp[4], 4); + if (EXTRACT_32BITS(&bp[4])) + (void)printf(" [gaddr %s]", ipaddr_string(&bp[4])); + if (len != 8) + (void)printf(" [len %d]", len); + } + break; + case 0x12: + TCHECK2(bp[4], 4); + (void)printf("igmp v1 report %s", ipaddr_string(&bp[4])); + if (len != 8) + (void)printf(" [len %d]", len); + break; + case 0x16: + TCHECK2(bp[4], 4); + (void)printf("igmp v2 report %s", ipaddr_string(&bp[4])); + break; + case 0x22: + (void)printf("igmp v3 report"); + print_igmpv3_report(bp, len); + break; + case 0x17: + TCHECK2(bp[4], 4); + (void)printf("igmp leave %s", ipaddr_string(&bp[4])); + break; + case 0x13: + (void)printf("igmp dvmrp"); + if (len < 8) + (void)printf(" [len %d]", len); + else + dvmrp_print(bp, len); + break; + case 0x14: + (void)printf("igmp pimv1"); + pimv1_print(bp, len); + break; + case 0x1e: + print_mresp(bp, len); + break; + case 0x1f: + print_mtrace(bp, len); + break; + default: + (void)printf("igmp-%d", bp[0]); + break; + } + + if (vflag && TTEST2(bp[0], len)) { + /* Check the IGMP checksum */ + vec[0].ptr = bp; + vec[0].len = len; + if (in_cksum(vec, 1)) + printf(" bad igmp cksum %x!", EXTRACT_16BITS(&bp[2])); + } + return; +trunc: + fputs("[|igmp]", stdout); +} diff --git a/freebsd/contrib/tcpdump/print-igrp.c b/freebsd/contrib/tcpdump/print-igrp.c new file mode 100644 index 00000000..77c63283 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-igrp.c @@ -0,0 +1,132 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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. + * + * Initial contribution from Francis Dupont (francis.dupont@inria.fr) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-igrp.c,v 1.21 2005-04-20 21:01:56 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "interface.h" +#include "addrtoname.h" +#include "igrp.h" +#include "ip.h" +#include "extract.h" /* must come after interface.h */ + +static void +igrp_entry_print(register struct igrprte *igr, register int is_interior, + register int is_exterior) +{ + register u_int delay, bandwidth; + u_int metric, mtu; + + if (is_interior) + printf(" *.%d.%d.%d", igr->igr_net[0], + igr->igr_net[1], igr->igr_net[2]); + else if (is_exterior) + printf(" X%d.%d.%d.0", igr->igr_net[0], + igr->igr_net[1], igr->igr_net[2]); + else + printf(" %d.%d.%d.0", igr->igr_net[0], + igr->igr_net[1], igr->igr_net[2]); + + delay = EXTRACT_24BITS(igr->igr_dly); + bandwidth = EXTRACT_24BITS(igr->igr_bw); + metric = bandwidth + delay; + if (metric > 0xffffff) + metric = 0xffffff; + mtu = EXTRACT_16BITS(igr->igr_mtu); + + printf(" d=%d b=%d r=%d l=%d M=%d mtu=%d in %d hops", + 10 * delay, bandwidth == 0 ? 0 : 10000000 / bandwidth, + igr->igr_rel, igr->igr_ld, metric, + mtu, igr->igr_hct); +} + +static struct tok op2str[] = { + { IGRP_UPDATE, "update" }, + { IGRP_REQUEST, "request" }, + { 0, NULL } +}; + +void +igrp_print(register const u_char *bp, u_int length, const u_char *bp2 _U_) +{ + register struct igrphdr *hdr; + register u_char *cp; + u_int nint, nsys, next; + + hdr = (struct igrphdr *)bp; + cp = (u_char *)(hdr + 1); + (void)printf("igrp:"); + + /* Header */ + TCHECK(*hdr); + nint = EXTRACT_16BITS(&hdr->ig_ni); + nsys = EXTRACT_16BITS(&hdr->ig_ns); + next = EXTRACT_16BITS(&hdr->ig_nx); + + (void)printf(" %s V%d edit=%d AS=%d (%d/%d/%d)", + tok2str(op2str, "op-#%d", IGRP_OP(hdr->ig_vop)), + IGRP_V(hdr->ig_vop), + hdr->ig_ed, + EXTRACT_16BITS(&hdr->ig_as), + nint, + nsys, + next); + + length -= sizeof(*hdr); + while (length >= IGRP_RTE_SIZE) { + if (nint > 0) { + TCHECK2(*cp, IGRP_RTE_SIZE); + igrp_entry_print((struct igrprte *)cp, 1, 0); + --nint; + } else if (nsys > 0) { + TCHECK2(*cp, IGRP_RTE_SIZE); + igrp_entry_print((struct igrprte *)cp, 0, 0); + --nsys; + } else if (next > 0) { + TCHECK2(*cp, IGRP_RTE_SIZE); + igrp_entry_print((struct igrprte *)cp, 0, 1); + --next; + } else { + (void)printf(" [extra bytes %d]", length); + break; + } + cp += IGRP_RTE_SIZE; + length -= IGRP_RTE_SIZE; + } + if (nint == 0 && nsys == 0 && next == 0) + return; +trunc: + fputs(" [|igrp]", stdout); +} diff --git a/freebsd/contrib/tcpdump/print-ip.c b/freebsd/contrib/tcpdump/print-ip.c new file mode 100644 index 00000000..947964cb --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ip.c @@ -0,0 +1,713 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * $FreeBSD$ + */ + +#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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "addrtoname.h" +#include "interface.h" +#include "extract.h" /* must come after interface.h */ + +#include "ip.h" +#include "ipproto.h" + +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 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 <netinet/in.h> 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; + + case IPPROTO_PFSYNC: + pfsync_ip_print(ipds->cp, ipds->len); + 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: + */ + + diff --git a/freebsd/contrib/tcpdump/print-ip6.c b/freebsd/contrib/tcpdump/print-ip6.c new file mode 100644 index 00000000..387067b7 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ip6.c @@ -0,0 +1,275 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.52 2007-09-21 07:05:33 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef INET6 + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "netdissect.h" +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip6.h" +#include "ipproto.h" + +/* + * Compute a V6-style checksum by building a pseudoheader. + */ +int +nextproto6_cksum(const struct ip6_hdr *ip6, const u_int8_t *data, + u_int len, u_int next_proto) +{ + struct { + struct in6_addr ph_src; + struct in6_addr ph_dst; + u_int32_t ph_len; + u_int8_t ph_zero[3]; + u_int8_t ph_nxt; + } ph; + struct cksum_vec vec[2]; + + /* pseudo-header */ + memset(&ph, 0, sizeof(ph)); + ph.ph_src = ip6->ip6_src; + ph.ph_dst = ip6->ip6_dst; + ph.ph_len = htonl(len); + ph.ph_nxt = next_proto; + + 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); +} + +/* + * print an IP6 datagram. + */ +void +ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) +{ + register const struct ip6_hdr *ip6; + register int advance; + u_int len; + const u_char *ipend; + register const u_char *cp; + register u_int payload_len; + int nh; + int fragmented = 0; + u_int flow; + + ip6 = (const struct ip6_hdr *)bp; + + TCHECK(*ip6); + if (length < sizeof (struct ip6_hdr)) { + (void)ND_PRINT((ndo, "truncated-ip6 %u", length)); + return; + } + + if (!ndo->ndo_eflag) + ND_PRINT((ndo, "IP6 ")); + + payload_len = EXTRACT_16BITS(&ip6->ip6_plen); + len = payload_len + sizeof(struct ip6_hdr); + if (length < len) + (void)ND_PRINT((ndo, "truncated-ip6 - %u bytes missing!", + len - length)); + + if (ndo->ndo_vflag) { + flow = EXTRACT_32BITS(&ip6->ip6_flow); + ND_PRINT((ndo, "(")); +#if 0 + /* rfc1883 */ + if (flow & 0x0f000000) + (void)ND_PRINT((ndo, "pri 0x%02x, ", (flow & 0x0f000000) >> 24)); + if (flow & 0x00ffffff) + (void)ND_PRINT((ndo, "flowlabel 0x%06x, ", flow & 0x00ffffff)); +#else + /* RFC 2460 */ + if (flow & 0x0ff00000) + (void)ND_PRINT((ndo, "class 0x%02x, ", (flow & 0x0ff00000) >> 20)); + if (flow & 0x000fffff) + (void)ND_PRINT((ndo, "flowlabel 0x%05x, ", flow & 0x000fffff)); +#endif + + (void)ND_PRINT((ndo, "hlim %u, next-header %s (%u) payload length: %u) ", + ip6->ip6_hlim, + tok2str(ipproto_values,"unknown",ip6->ip6_nxt), + ip6->ip6_nxt, + payload_len)); + } + + /* + * Cut off the snapshot length to the end of the IP payload. + */ + ipend = bp + len; + if (ipend < ndo->ndo_snapend) + ndo->ndo_snapend = ipend; + + cp = (const u_char *)ip6; + advance = sizeof(struct ip6_hdr); + nh = ip6->ip6_nxt; + while (cp < ndo->ndo_snapend && advance > 0) { + cp += advance; + len -= advance; + + if (cp == (const u_char *)(ip6 + 1) && + nh != IPPROTO_TCP && nh != IPPROTO_UDP && + nh != IPPROTO_DCCP && nh != IPPROTO_SCTP) { + (void)ND_PRINT((ndo, "%s > %s: ", ip6addr_string(&ip6->ip6_src), + ip6addr_string(&ip6->ip6_dst))); + } + + switch (nh) { + case IPPROTO_HOPOPTS: + advance = hbhopt_print(cp); + nh = *cp; + break; + case IPPROTO_DSTOPTS: + advance = dstopt_print(cp); + nh = *cp; + break; + case IPPROTO_FRAGMENT: + advance = frag6_print(cp, (const u_char *)ip6); + if (ndo->ndo_snapend <= cp + advance) + return; + nh = *cp; + fragmented = 1; + break; + + case IPPROTO_MOBILITY_OLD: + case IPPROTO_MOBILITY: + /* + * XXX - we don't use "advance"; the current + * "Mobility Support in IPv6" draft + * (draft-ietf-mobileip-ipv6-24) says that + * the next header field in a mobility header + * should be IPPROTO_NONE, but speaks of + * the possiblity of a future extension in + * which payload can be piggybacked atop a + * mobility header. + */ + advance = mobility_print(cp, (const u_char *)ip6); + nh = *cp; + return; + case IPPROTO_ROUTING: + advance = rt6_print(cp, (const u_char *)ip6); + nh = *cp; + break; + case IPPROTO_SCTP: + sctp_print(cp, (const u_char *)ip6, len); + return; + case IPPROTO_DCCP: + dccp_print(cp, (const u_char *)ip6, len); + return; + case IPPROTO_TCP: + tcp_print(cp, len, (const u_char *)ip6, fragmented); + return; + case IPPROTO_UDP: + udp_print(cp, len, (const u_char *)ip6, fragmented); + return; + case IPPROTO_ICMPV6: + icmp6_print(ndo, cp, len, (const u_char *)ip6, fragmented); + return; + case IPPROTO_AH: + advance = ah_print(cp); + nh = *cp; + break; + case IPPROTO_ESP: + { + int enh, padlen; + advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen); + nh = enh & 0xff; + len -= padlen; + break; + } + case IPPROTO_IPCOMP: + { + int enh; + advance = ipcomp_print(cp, &enh); + nh = enh & 0xff; + break; + } + + case IPPROTO_PIM: + pim_print(cp, len, nextproto6_cksum(ip6, cp, len, + IPPROTO_PIM)); + return; + + case IPPROTO_OSPF: + ospf6_print(cp, len); + return; + + case IPPROTO_IPV6: + ip6_print(ndo, cp, len); + return; + + case IPPROTO_IPV4: + ip_print(ndo, cp, len); + return; + + case IPPROTO_PGM: + pgm_print(cp, len, (const u_char *)ip6); + return; + + case IPPROTO_GRE: + gre_print(cp, len); + return; + + case IPPROTO_RSVP: + rsvp_print(cp, len); + return; + + case IPPROTO_NONE: + (void)ND_PRINT((ndo, "no next header")); + return; + + default: + (void)ND_PRINT((ndo, "ip-proto-%d %d", nh, len)); + return; + } + } + + return; +trunc: + (void)ND_PRINT((ndo, "[|ip6]")); +} + +#endif /* INET6 */ diff --git a/freebsd/contrib/tcpdump/print-ip6opts.c b/freebsd/contrib/tcpdump/print-ip6opts.c new file mode 100644 index 00000000..a01a86bc --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ip6opts.c @@ -0,0 +1,334 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (C) 1998 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ip6opts.c,v 1.18 2005-04-20 22:18:50 guy Exp $"; +#endif + +#ifdef INET6 +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "ip6.h" + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +/* items outside of rfc2292bis */ +#ifndef IP6OPT_MINLEN +#define IP6OPT_MINLEN 2 +#endif +#ifndef IP6OPT_RTALERT_LEN +#define IP6OPT_RTALERT_LEN 4 +#endif +#ifndef IP6OPT_JUMBO_LEN +#define IP6OPT_JUMBO_LEN 6 +#endif +#define IP6OPT_HOMEADDR_MINLEN 18 +#define IP6OPT_BU_MINLEN 10 +#define IP6OPT_BA_MINLEN 13 +#define IP6OPT_BR_MINLEN 2 +#define IP6SOPT_UI 0x2 +#define IP6SOPT_UI_MINLEN 4 +#define IP6SOPT_ALTCOA 0x3 +#define IP6SOPT_ALTCOA_MINLEN 18 +#define IP6SOPT_AUTH 0x4 +#define IP6SOPT_AUTH_MINLEN 6 + +static void ip6_sopt_print(const u_char *, int); + +static void +ip6_sopt_print(const u_char *bp, int len) +{ + int i; + int optlen; + + for (i = 0; i < len; i += optlen) { + if (bp[i] == IP6OPT_PAD1) + optlen = 1; + else { + if (i + 1 < len) + optlen = bp[i + 1] + 2; + else + goto trunc; + } + if (i + optlen > len) + goto trunc; + + switch (bp[i]) { + case IP6OPT_PAD1: + printf(", pad1"); + break; + case IP6OPT_PADN: + if (len - i < IP6OPT_MINLEN) { + printf(", padn: trunc"); + goto trunc; + } + printf(", padn"); + break; + case IP6SOPT_UI: + if (len - i < IP6SOPT_UI_MINLEN) { + printf(", ui: trunc"); + goto trunc; + } + printf(", ui: 0x%04x ", EXTRACT_16BITS(&bp[i + 2])); + break; + case IP6SOPT_ALTCOA: + if (len - i < IP6SOPT_ALTCOA_MINLEN) { + printf(", altcoa: trunc"); + goto trunc; + } + printf(", alt-CoA: %s", ip6addr_string(&bp[i+2])); + break; + case IP6SOPT_AUTH: + if (len - i < IP6SOPT_AUTH_MINLEN) { + printf(", auth: trunc"); + goto trunc; + } + printf(", auth spi: 0x%08x", EXTRACT_32BITS(&bp[i + 2])); + break; + default: + if (len - i < IP6OPT_MINLEN) { + printf(", sopt_type %d: trunc)", bp[i]); + goto trunc; + } + printf(", sopt_type 0x%02x: len=%d", bp[i], bp[i + 1]); + break; + } + } + return; + +trunc: + printf("[trunc] "); +} + +void +ip6_opt_print(const u_char *bp, int len) +{ + int i; + int optlen = 0; + + if (len == 0) + return; + for (i = 0; i < len; i += optlen) { + if (bp[i] == IP6OPT_PAD1) + optlen = 1; + else { + if (i + 1 < len) + optlen = bp[i + 1] + 2; + else + goto trunc; + } + if (i + optlen > len) + goto trunc; + + switch (bp[i]) { + case IP6OPT_PAD1: + printf("(pad1)"); + break; + case IP6OPT_PADN: + if (len - i < IP6OPT_MINLEN) { + printf("(padn: trunc)"); + goto trunc; + } + printf("(padn)"); + break; + case IP6OPT_ROUTER_ALERT: + if (len - i < IP6OPT_RTALERT_LEN) { + printf("(rtalert: trunc)"); + goto trunc; + } + if (bp[i + 1] != IP6OPT_RTALERT_LEN - 2) { + printf("(rtalert: invalid len %d)", bp[i + 1]); + goto trunc; + } + printf("(rtalert: 0x%04x) ", EXTRACT_16BITS(&bp[i + 2])); + break; + case IP6OPT_JUMBO: + if (len - i < IP6OPT_JUMBO_LEN) { + printf("(jumbo: trunc)"); + goto trunc; + } + if (bp[i + 1] != IP6OPT_JUMBO_LEN - 2) { + printf("(jumbo: invalid len %d)", bp[i + 1]); + goto trunc; + } + printf("(jumbo: %u) ", EXTRACT_32BITS(&bp[i + 2])); + break; + case IP6OPT_HOME_ADDRESS: + if (len - i < IP6OPT_HOMEADDR_MINLEN) { + printf("(homeaddr: trunc)"); + goto trunc; + } + if (bp[i + 1] < IP6OPT_HOMEADDR_MINLEN - 2) { + printf("(homeaddr: invalid len %d)", bp[i + 1]); + goto trunc; + } + printf("(homeaddr: %s", ip6addr_string(&bp[i + 2])); + if (bp[i + 1] > IP6OPT_HOMEADDR_MINLEN - 2) { + ip6_sopt_print(&bp[i + IP6OPT_HOMEADDR_MINLEN], + (optlen - IP6OPT_HOMEADDR_MINLEN)); + } + printf(")"); + break; + case IP6OPT_BINDING_UPDATE: + if (len - i < IP6OPT_BU_MINLEN) { + printf("(bu: trunc)"); + goto trunc; + } + if (bp[i + 1] < IP6OPT_BU_MINLEN - 2) { + printf("(bu: invalid len %d)", bp[i + 1]); + goto trunc; + } + printf("(bu: "); + if (bp[i + 2] & 0x80) + printf("A"); + if (bp[i + 2] & 0x40) + printf("H"); + if (bp[i + 2] & 0x20) + printf("S"); + if (bp[i + 2] & 0x10) + printf("D"); + if ((bp[i + 2] & 0x0f) || bp[i + 3] || bp[i + 4]) + printf("res"); + printf(", sequence: %u", bp[i + 5]); + printf(", lifetime: %u", EXTRACT_32BITS(&bp[i + 6])); + + if (bp[i + 1] > IP6OPT_BU_MINLEN - 2) { + ip6_sopt_print(&bp[i + IP6OPT_BU_MINLEN], + (optlen - IP6OPT_BU_MINLEN)); + } + printf(")"); + break; + case IP6OPT_BINDING_ACK: + if (len - i < IP6OPT_BA_MINLEN) { + printf("(ba: trunc)"); + goto trunc; + } + if (bp[i + 1] < IP6OPT_BA_MINLEN - 2) { + printf("(ba: invalid len %d)", bp[i + 1]); + goto trunc; + } + printf("(ba: "); + printf("status: %u", bp[i + 2]); + if (bp[i + 3]) + printf("res"); + printf(", sequence: %u", bp[i + 4]); + printf(", lifetime: %u", EXTRACT_32BITS(&bp[i + 5])); + printf(", refresh: %u", EXTRACT_32BITS(&bp[i + 9])); + + if (bp[i + 1] > IP6OPT_BA_MINLEN - 2) { + ip6_sopt_print(&bp[i + IP6OPT_BA_MINLEN], + (optlen - IP6OPT_BA_MINLEN)); + } + printf(")"); + break; + case IP6OPT_BINDING_REQ: + if (len - i < IP6OPT_BR_MINLEN) { + printf("(br: trunc)"); + goto trunc; + } + printf("(br"); + if (bp[i + 1] > IP6OPT_BR_MINLEN - 2) { + ip6_sopt_print(&bp[i + IP6OPT_BR_MINLEN], + (optlen - IP6OPT_BR_MINLEN)); + } + printf(")"); + break; + default: + if (len - i < IP6OPT_MINLEN) { + printf("(type %d: trunc)", bp[i]); + goto trunc; + } + printf("(opt_type 0x%02x: len=%d)", bp[i], bp[i + 1]); + break; + } + } + printf(" "); + +#if 0 +end: +#endif + return; + +trunc: + printf("[trunc] "); +} + +int +hbhopt_print(register const u_char *bp) +{ + const struct ip6_hbh *dp = (struct ip6_hbh *)bp; + int hbhlen = 0; + + TCHECK(dp->ip6h_len); + hbhlen = (int)((dp->ip6h_len + 1) << 3); + TCHECK2(*dp, hbhlen); + printf("HBH "); + if (vflag) + ip6_opt_print((const u_char *)dp + sizeof(*dp), hbhlen - sizeof(*dp)); + + return(hbhlen); + + trunc: + fputs("[|HBH]", stdout); + return(-1); +} + +int +dstopt_print(register const u_char *bp) +{ + const struct ip6_dest *dp = (struct ip6_dest *)bp; + int dstoptlen = 0; + + TCHECK(dp->ip6d_len); + dstoptlen = (int)((dp->ip6d_len + 1) << 3); + TCHECK2(*dp, dstoptlen); + printf("DSTOPT "); + if (vflag) { + ip6_opt_print((const u_char *)dp + sizeof(*dp), + dstoptlen - sizeof(*dp)); + } + + return(dstoptlen); + + trunc: + fputs("[|DSTOPT]", stdout); + return(-1); +} +#endif /* INET6 */ diff --git a/freebsd/contrib/tcpdump/print-ipcomp.c b/freebsd/contrib/tcpdump/print-ipcomp.c new file mode 100644 index 00000000..04f16b38 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ipcomp.c @@ -0,0 +1,93 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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-ipcomp.c,v 1.20 2003-11-19 00:36:08 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +struct ipcomp { + u_int8_t comp_nxt; /* Next Header */ + u_int8_t comp_flags; /* Length of data, in 32bit */ + u_int16_t comp_cpi; /* Compression parameter index */ +}; + +#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H) +#include <zlib.h> +#endif + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +int +ipcomp_print(register const u_char *bp, int *nhdr _U_) +{ + register const struct ipcomp *ipcomp; + register const u_char *ep; + u_int16_t cpi; +#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H) + int advance; +#endif + + ipcomp = (struct ipcomp *)bp; + cpi = EXTRACT_16BITS(&ipcomp->comp_cpi); + + /* 'ep' points to the end of available data. */ + ep = snapend; + + if ((u_char *)(ipcomp + 1) >= ep - sizeof(struct ipcomp)) { + fputs("[|IPCOMP]", stdout); + goto fail; + } + printf("IPComp(cpi=0x%04x)", cpi); + +#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H) + if (1) + goto fail; + + /* + * We may want to decompress the packet here. Packet buffer + * management is a headache (if we decompress, packet will become + * larger). + */ + if (nhdr) + *nhdr = ipcomp->comp_nxt; + advance = sizeof(struct ipcomp); + + printf(": "); + return advance; + +#endif +fail: + return -1; +} diff --git a/freebsd/contrib/tcpdump/print-ipfc.c b/freebsd/contrib/tcpdump/print-ipfc.c new file mode 100644 index 00000000..4e431d32 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ipfc.c @@ -0,0 +1,137 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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-ipfc.c,v 1.9 2005-11-13 12:12:42 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" + +#include "ether.h" +#include "ipfc.h" + +/* + * RFC 2625 IP-over-Fibre Channel. + */ + +/* Extract src, dst addresses */ +static inline void +extract_ipfc_addrs(const struct ipfc_header *ipfcp, char *ipfcsrc, + char *ipfcdst) +{ + /* + * We assume that, as per RFC 2625, the lower 48 bits of the + * source and destination addresses are MAC addresses. + */ + memcpy(ipfcdst, (const char *)&ipfcp->ipfc_dhost[2], 6); + memcpy(ipfcsrc, (const char *)&ipfcp->ipfc_shost[2], 6); +} + +/* + * Print the Network_Header + */ +static inline void +ipfc_hdr_print(register const struct ipfc_header *ipfcp _U_, + register u_int length, register const u_char *ipfcsrc, + register const u_char *ipfcdst) +{ + const char *srcname, *dstname; + + srcname = etheraddr_string(ipfcsrc); + dstname = etheraddr_string(ipfcdst); + + /* + * XXX - show the upper 16 bits? Do so only if "vflag" is set? + */ + (void) printf("%s %s %d: ", srcname, dstname, length); +} + +static void +ipfc_print(const u_char *p, u_int length, u_int caplen) +{ + const struct ipfc_header *ipfcp = (const struct ipfc_header *)p; + struct ether_header ehdr; + u_short extracted_ethertype; + + if (caplen < IPFC_HDRLEN) { + printf("[|ipfc]"); + return; + } + /* + * Get the network addresses into a canonical form + */ + extract_ipfc_addrs(ipfcp, (char *)ESRC(&ehdr), (char *)EDST(&ehdr)); + + if (eflag) + ipfc_hdr_print(ipfcp, length, ESRC(&ehdr), EDST(&ehdr)); + + /* Skip over Network_Header */ + length -= IPFC_HDRLEN; + p += IPFC_HDRLEN; + caplen -= IPFC_HDRLEN; + + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr), + &extracted_ethertype) == 0) { + /* + * Some kinds of LLC packet we cannot + * handle intelligently + */ + if (!eflag) + ipfc_hdr_print(ipfcp, length + IPFC_HDRLEN, + ESRC(&ehdr), EDST(&ehdr)); + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the Network_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 +ipfc_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + ipfc_print(p, h->len, h->caplen); + + return (IPFC_HDRLEN); +} diff --git a/freebsd/contrib/tcpdump/print-ipnet.c b/freebsd/contrib/tcpdump/print-ipnet.c new file mode 100644 index 00000000..75863458 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ipnet.c @@ -0,0 +1,111 @@ +#include <machine/rtems-bsd-user-space.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> + +#include "netdissect.h" +#include "interface.h" +#include "addrtoname.h" +#include "ipnet.h" + +#ifdef DLT_IPNET + +const struct tok ipnet_values[] = { + { IPH_AF_INET, "IPv4" }, + { IPH_AF_INET6, "IPv6" }, + { 0, NULL } +}; + +static inline void +ipnet_hdr_print(struct netdissect_options *ndo, const u_char *bp, u_int length) +{ + const ipnet_hdr_t *hdr; + hdr = (const ipnet_hdr_t *)bp; + + ND_PRINT((ndo, "%d > %d", hdr->iph_zsrc, hdr->iph_zdst)); + + if (!ndo->ndo_qflag) { + ND_PRINT((ndo,", family %s (%d)", + tok2str(ipnet_values, "Unknown", + hdr->iph_family), + hdr->iph_family)); + } else { + ND_PRINT((ndo,", %s", + tok2str(ipnet_values, + "Unknown Ethertype (0x%04x)", + hdr->iph_family))); + } + + ND_PRINT((ndo, ", length %u: ", length)); +} + +static void +ipnet_print(struct netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) +{ + ipnet_hdr_t *hdr; + + if (caplen < sizeof(ipnet_hdr_t)) { + ND_PRINT((ndo, "[|ipnet]")); + return; + } + + if (ndo->ndo_eflag) + ipnet_hdr_print(ndo, p, length); + + length -= sizeof(ipnet_hdr_t); + caplen -= sizeof(ipnet_hdr_t); + hdr = (ipnet_hdr_t *)p; + p += sizeof(ipnet_hdr_t); + + switch (hdr->iph_family) { + + case IPH_AF_INET: + ip_print(ndo, p, length); + break; + +#ifdef INET6 + case IPH_AF_INET6: + ip6_print(ndo, p, length); + break; +#endif /*INET6*/ + + default: + if (!ndo->ndo_eflag) + ipnet_hdr_print(ndo, (u_char *)hdr, + length + sizeof(ipnet_hdr_t)); + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + break; + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether 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 +ipnet_if_print(struct netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + ipnet_print(ndo, p, h->len, h->caplen); + + return (sizeof(ipnet_hdr_t)); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + +#endif /* DLT_IPNET */ diff --git a/freebsd/contrib/tcpdump/print-ipx.c b/freebsd/contrib/tcpdump/print-ipx.c new file mode 100644 index 00000000..ae136429 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ipx.c @@ -0,0 +1,225 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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). + * + * $FreeBSD$ + */ + +#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 <tcpdump-stdinc.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "ipx.h" +#include "extract.h" + + +static const char *ipxaddr_string(u_int32_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); +} diff --git a/freebsd/contrib/tcpdump/print-isakmp.c b/freebsd/contrib/tcpdump/print-isakmp.c new file mode 100644 index 00000000..8b9e3508 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-isakmp.c @@ -0,0 +1,2572 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 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-isakmp.c,v 1.61 2008-02-05 19:34:25 guy Exp $ (LBL)"; +#endif + +#define NETDISSECT_REWORKED +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <string.h> + +#include <stdio.h> + +#include "isakmp.h" +#include "ipsec_doi.h" +#include "oakley.h" +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif + +#ifndef HAVE_SOCKADDR_STORAGE +#define sockaddr_storage sockaddr +#endif + +#define DECLARE_PRINTER(func) static const u_char *ike##func##_print( \ + netdissect_options *ndo, u_char tpay, \ + const struct isakmp_gen *ext, \ + u_int item_len, \ + const u_char *end_pointer, \ + u_int32_t phase,\ + u_int32_t doi0, \ + u_int32_t proto0, int depth) + +DECLARE_PRINTER(v1_sa); +DECLARE_PRINTER(v1_p); +DECLARE_PRINTER(v1_t); +DECLARE_PRINTER(v1_ke); +DECLARE_PRINTER(v1_id); +DECLARE_PRINTER(v1_cert); +DECLARE_PRINTER(v1_cr); +DECLARE_PRINTER(v1_sig); +DECLARE_PRINTER(v1_hash); +DECLARE_PRINTER(v1_nonce); +DECLARE_PRINTER(v1_n); +DECLARE_PRINTER(v1_d); +DECLARE_PRINTER(v1_vid); + +DECLARE_PRINTER(v2_sa); +DECLARE_PRINTER(v2_ke); +DECLARE_PRINTER(v2_ID); +DECLARE_PRINTER(v2_cert); +DECLARE_PRINTER(v2_cr); +DECLARE_PRINTER(v2_auth); +DECLARE_PRINTER(v2_nonce); +DECLARE_PRINTER(v2_n); +DECLARE_PRINTER(v2_d); +DECLARE_PRINTER(v2_vid); +DECLARE_PRINTER(v2_TS); +DECLARE_PRINTER(v2_cp); +DECLARE_PRINTER(v2_eap); + +static const u_char *ikev2_e_print(netdissect_options *ndo, + struct isakmp *base, + u_char tpay, + const struct isakmp_gen *ext, + u_int item_len, + const u_char *end_pointer, + u_int32_t phase, + u_int32_t doi0, + u_int32_t proto0, int depth); + + +static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *, + const u_char *, u_int32_t, u_int32_t, u_int32_t, int); +static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *, + const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + +static const u_char *ikev2_sub_print(netdissect_options *ndo, + struct isakmp *base, + u_char np, const struct isakmp_gen *ext, + const u_char *ep, u_int32_t phase, + u_int32_t doi, u_int32_t proto, + int depth); + + +static char *numstr(int); +static void safememcpy(void *, const void *, size_t); + +static void +ikev1_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2, struct isakmp *base); + +#define MAXINITIATORS 20 +int ninitiator = 0; +struct { + cookie_t initiator; + struct sockaddr_storage iaddr; + struct sockaddr_storage raddr; +} cookiecache[MAXINITIATORS]; + +/* protocol id */ +static const char *protoidstr[] = { + NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp", +}; + +/* isakmp->np */ +static const char *npstr[] = { + "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */ + "sig", "nonce", "n", "d", "vid", /* 9 - 13 */ + "pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */ + "pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */ + "pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */ + "pay29", "pay30", "pay31", "pay32", /* 29- 32 */ + "v2sa", "v2ke", "v2IDi", "v2IDr", "v2cert",/* 33- 37 */ + "v2cr", "v2auth","v2nonce", "v2n", "v2d", /* 38- 42 */ + "v2vid", "v2TSi", "v2TSr", "v2e", "v2cp", /* 43- 47 */ + "v2eap", /* 48 */ + +}; + +/* isakmp->np */ +static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len, + const u_char *end_pointer, + u_int32_t phase, + u_int32_t doi0, + u_int32_t proto0, int depth) = { + NULL, + ikev1_sa_print, + ikev1_p_print, + ikev1_t_print, + ikev1_ke_print, + ikev1_id_print, + ikev1_cert_print, + ikev1_cr_print, + ikev1_hash_print, + ikev1_sig_print, + ikev1_nonce_print, + ikev1_n_print, + ikev1_d_print, + ikev1_vid_print, /* 13 */ + NULL, NULL, NULL, NULL, NULL, /* 14- 18 */ + NULL, NULL, NULL, NULL, NULL, /* 19- 23 */ + NULL, NULL, NULL, NULL, NULL, /* 24- 28 */ + NULL, NULL, NULL, NULL, /* 29- 32 */ + ikev2_sa_print, /* 33 */ + ikev2_ke_print, /* 34 */ + ikev2_ID_print, /* 35 */ + ikev2_ID_print, /* 36 */ + ikev2_cert_print, /* 37 */ + ikev2_cr_print, /* 38 */ + ikev2_auth_print, /* 39 */ + ikev2_nonce_print, /* 40 */ + ikev2_n_print, /* 41 */ + ikev2_d_print, /* 42 */ + ikev2_vid_print, /* 43 */ + ikev2_TS_print, /* 44 */ + ikev2_TS_print, /* 45 */ + NULL, /* ikev2_e_print,*/ /* 46 - special */ + ikev2_cp_print, /* 47 */ + ikev2_eap_print, /* 48 */ +}; + +/* isakmp->etype */ +static const char *etypestr[] = { +/* IKEv1 exchange types */ + "none", "base", "ident", "auth", "agg", "inf", NULL, NULL, /* 0-7 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 8-15 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 16-23 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 24-31 */ + "oakley-quick", "oakley-newgroup", /* 32-33 */ +/* IKEv2 exchange types */ + "ikev2_init", "ikev2_auth", "child_sa", "inf2" /* 34-37 */ +}; + +#define STR_OR_ID(x, tab) \ + (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) +#define PROTOIDSTR(x) STR_OR_ID(x, protoidstr) +#define NPSTR(x) STR_OR_ID(x, npstr) +#define ETYPESTR(x) STR_OR_ID(x, etypestr) + +#define CHECKLEN(p, np) \ + if (ep < (u_char *)(p)) { \ + ND_PRINT((ndo," [|%s]", NPSTR(np))); \ + goto done; \ + } + + +#define NPFUNC(x) \ + (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \ + ? npfunc[(x)] : NULL) + +static int +iszero(u_char *p, size_t l) +{ + while (l--) { + if (*p++) + return 0; + } + return 1; +} + +/* find cookie from initiator cache */ +static int +cookie_find(cookie_t *in) +{ + int i; + + for (i = 0; i < MAXINITIATORS; i++) { + if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0) + return i; + } + + return -1; +} + +/* record initiator */ +static void +cookie_record(cookie_t *in, const u_char *bp2) +{ + int i; + struct ip *ip; + struct sockaddr_in *sin; +#ifdef INET6 + struct ip6_hdr *ip6; + struct sockaddr_in6 *sin6; +#endif + + i = cookie_find(in); + if (0 <= i) { + ninitiator = (i + 1) % MAXINITIATORS; + return; + } + + ip = (struct ip *)bp2; + switch (IP_V(ip)) { + case 4: + memset(&cookiecache[ninitiator].iaddr, 0, + sizeof(cookiecache[ninitiator].iaddr)); + memset(&cookiecache[ninitiator].raddr, 0, + sizeof(cookiecache[ninitiator].raddr)); + + sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(struct sockaddr_in); +#endif + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); + sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(struct sockaddr_in); +#endif + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)); + break; +#ifdef INET6 + case 6: + memset(&cookiecache[ninitiator].iaddr, 0, + sizeof(cookiecache[ninitiator].iaddr)); + memset(&cookiecache[ninitiator].raddr, 0, + sizeof(cookiecache[ninitiator].raddr)); + + ip6 = (struct ip6_hdr *)bp2; + sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr; +#ifdef HAVE_SOCKADDR_SA_LEN + sin6->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6->sin6_family = AF_INET6; + memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); + sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr; +#ifdef HAVE_SOCKADDR_SA_LEN + sin6->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6->sin6_family = AF_INET6; + memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); + break; +#endif + default: + return; + } + memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in)); + ninitiator = (ninitiator + 1) % MAXINITIATORS; +} + +#define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1) +#define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0) +static int +cookie_sidecheck(int i, const u_char *bp2, int initiator) +{ + struct sockaddr_storage ss; + struct sockaddr *sa; + struct ip *ip; + struct sockaddr_in *sin; +#ifdef INET6 + struct ip6_hdr *ip6; + struct sockaddr_in6 *sin6; +#endif + int salen; + + memset(&ss, 0, sizeof(ss)); + ip = (struct ip *)bp2; + switch (IP_V(ip)) { + case 4: + sin = (struct sockaddr_in *)&ss; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(struct sockaddr_in); +#endif + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); + break; +#ifdef INET6 + case 6: + ip6 = (struct ip6_hdr *)bp2; + sin6 = (struct sockaddr_in6 *)&ss; +#ifdef HAVE_SOCKADDR_SA_LEN + sin6->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6->sin6_family = AF_INET6; + memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); + break; +#endif + default: + return 0; + } + + sa = (struct sockaddr *)&ss; + if (initiator) { + if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family) + return 0; +#ifdef HAVE_SOCKADDR_SA_LEN + salen = sa->sa_len; +#else +#ifdef INET6 + if (sa->sa_family == AF_INET6) + salen = sizeof(struct sockaddr_in6); + else + salen = sizeof(struct sockaddr); +#else + salen = sizeof(struct sockaddr); +#endif +#endif + if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0) + return 1; + } else { + if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family) + return 0; +#ifdef HAVE_SOCKADDR_SA_LEN + salen = sa->sa_len; +#else +#ifdef INET6 + if (sa->sa_family == AF_INET6) + salen = sizeof(struct sockaddr_in6); + else + salen = sizeof(struct sockaddr); +#else + salen = sizeof(struct sockaddr); +#endif +#endif + if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0) + return 1; + } + return 0; +} + +static void +hexprint(netdissect_options *ndo, caddr_t loc, size_t len) +{ + u_char *p; + size_t i; + + p = (u_char *)loc; + for (i = 0; i < len; i++) + ND_PRINT((ndo,"%02x", p[i] & 0xff)); +} + +static int +rawprint(netdissect_options *ndo, caddr_t loc, size_t len) +{ + ND_TCHECK2(*loc, len); + + hexprint(ndo, loc, len); + return 1; +trunc: + return 0; +} + + +/* + * returns false if we run out of data buffer + */ +static int ike_show_somedata(struct netdissect_options *ndo, + const u_char *cp, const u_char *ep) +{ + /* there is too much data, just show some of it */ + const u_char *end = ep - 20; + int elen = 20; + int len = ep - cp; + if(len > 10) { + len = 10; + } + + /* really shouldn't happen because of above */ + if(end < cp + len) { + end = cp+len; + elen = ep - end; + } + + ND_PRINT((ndo," data=(")); + if(!rawprint(ndo, (caddr_t)(cp), len)) goto trunc; + ND_PRINT((ndo, "...")); + if(elen) { + if(!rawprint(ndo, (caddr_t)(end), elen)) goto trunc; + } + ND_PRINT((ndo,")")); + return 1; + +trunc: + return 0; +} + +struct attrmap { + const char *type; + u_int nvalue; + const char *value[30]; /*XXX*/ +}; + +static const u_char * +ikev1_attrmap_print(netdissect_options *ndo, + const u_char *p, const u_char *ep, + const struct attrmap *map, size_t nmap) +{ + u_int16_t *q; + int totlen; + u_int32_t t, v; + + q = (u_int16_t *)p; + if (p[0] & 0x80) + totlen = 4; + else + totlen = 4 + EXTRACT_16BITS(&q[1]); + if (ep < p + totlen) { + ND_PRINT((ndo,"[|attr]")); + return ep + 1; + } + + ND_PRINT((ndo,"(")); + t = EXTRACT_16BITS(&q[0]) & 0x7fff; + if (map && t < nmap && map[t].type) + ND_PRINT((ndo,"type=%s ", map[t].type)); + else + ND_PRINT((ndo,"type=#%d ", t)); + if (p[0] & 0x80) { + ND_PRINT((ndo,"value=")); + v = EXTRACT_16BITS(&q[1]); + if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) + ND_PRINT((ndo,"%s", map[t].value[v])); + else + rawprint(ndo, (caddr_t)&q[1], 2); + } else { + ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1]))); + rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&q[1])); + } + ND_PRINT((ndo,")")); + return p + totlen; +} + +static const u_char * +ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep) +{ + u_int16_t *q; + int totlen; + u_int32_t t; + + q = (u_int16_t *)p; + if (p[0] & 0x80) + totlen = 4; + else + totlen = 4 + EXTRACT_16BITS(&q[1]); + if (ep < p + totlen) { + ND_PRINT((ndo,"[|attr]")); + return ep + 1; + } + + ND_PRINT((ndo,"(")); + t = EXTRACT_16BITS(&q[0]) & 0x7fff; + ND_PRINT((ndo,"type=#%d ", t)); + if (p[0] & 0x80) { + ND_PRINT((ndo,"value=")); + t = q[1]; + rawprint(ndo, (caddr_t)&q[1], 2); + } else { + ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1]))); + rawprint(ndo, (caddr_t)&p[2], EXTRACT_16BITS(&q[1])); + } + ND_PRINT((ndo,")")); + return p + totlen; +} + +static const u_char * +ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, + u_int item_len _U_, + const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, + u_int32_t proto0, int depth) +{ + const struct ikev1_pl_sa *p; + struct ikev1_pl_sa sa; + const u_int32_t *q; + u_int32_t doi, sit, ident; + const u_char *cp, *np; + int t; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA))); + + p = (struct ikev1_pl_sa *)ext; + ND_TCHECK(*p); + safememcpy(&sa, ext, sizeof(sa)); + doi = ntohl(sa.doi); + sit = ntohl(sa.sit); + if (doi != 1) { + ND_PRINT((ndo," doi=%d", doi)); + ND_PRINT((ndo," situation=%u", (u_int32_t)ntohl(sa.sit))); + return (u_char *)(p + 1); + } + + ND_PRINT((ndo," doi=ipsec")); + q = (u_int32_t *)&sa.sit; + ND_PRINT((ndo," situation=")); + t = 0; + if (sit & 0x01) { + ND_PRINT((ndo,"identity")); + t++; + } + if (sit & 0x02) { + ND_PRINT((ndo,"%ssecrecy", t ? "+" : "")); + t++; + } + if (sit & 0x04) + ND_PRINT((ndo,"%sintegrity", t ? "+" : "")); + + np = (u_char *)ext + sizeof(sa); + if (sit != 0x01) { + ND_TCHECK2(*(ext + 1), sizeof(ident)); + safememcpy(&ident, ext + 1, sizeof(ident)); + ND_PRINT((ndo," ident=%u", (u_int32_t)ntohl(ident))); + np += sizeof(ident); + } + + ext = (struct isakmp_gen *)np; + ND_TCHECK(*ext); + + cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, + depth); + + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA))); + return NULL; +} + +static const u_char * +ikev1_p_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep, u_int32_t phase, u_int32_t doi0, + u_int32_t proto0 _U_, int depth) +{ + const struct ikev1_pl_p *p; + struct ikev1_pl_p prop; + const u_char *cp; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P))); + + p = (struct ikev1_pl_p *)ext; + ND_TCHECK(*p); + safememcpy(&prop, ext, sizeof(prop)); + ND_PRINT((ndo," #%d protoid=%s transform=%d", + prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t)); + if (prop.spi_size) { + ND_PRINT((ndo," spi=")); + if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size)) + goto trunc; + } + + ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); + ND_TCHECK(*ext); + + cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, + prop.prot_id, depth); + + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); + return NULL; +} + +static const char *ikev1_p_map[] = { + NULL, "ike", +}; + +static const char *ikev2_t_type_map[]={ + NULL, "encr", "prf", "integ", "dh", "esn" +}; + +static const char *ah_p_map[] = { + NULL, "(reserved)", "md5", "sha", "1des", + "sha2-256", "sha2-384", "sha2-512", +}; + +static const char *prf_p_map[] = { + NULL, "hmac-md5", "hmac-sha", "hmac-tiger", + "aes128_xcbc" +}; + +static const char *integ_p_map[] = { + NULL, "hmac-md5", "hmac-sha", "dec-mac", + "kpdk-md5", "aes-xcbc" +}; + +static const char *esn_p_map[] = { + "no-esn", "esn" +}; + +static const char *dh_p_map[] = { + NULL, "modp768", + "modp1024", /* group 2 */ + "EC2N 2^155", /* group 3 */ + "EC2N 2^185", /* group 4 */ + "modp1536", /* group 5 */ + "iana-grp06", "iana-grp07", /* reserved */ + "iana-grp08", "iana-grp09", + "iana-grp10", "iana-grp11", + "iana-grp12", "iana-grp13", + "modp2048", /* group 14 */ + "modp3072", /* group 15 */ + "modp4096", /* group 16 */ + "modp6144", /* group 17 */ + "modp8192", /* group 18 */ +}; + +static const char *esp_p_map[] = { + NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast", + "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes" +}; + +static const char *ipcomp_p_map[] = { + NULL, "oui", "deflate", "lzs", +}; + +const struct attrmap ipsec_t_map[] = { + { NULL, 0, { NULL } }, + { "lifetype", 3, { NULL, "sec", "kb", }, }, + { "life", 0, { NULL } }, + { "group desc", 18, { NULL, "modp768", + "modp1024", /* group 2 */ + "EC2N 2^155", /* group 3 */ + "EC2N 2^185", /* group 4 */ + "modp1536", /* group 5 */ + "iana-grp06", "iana-grp07", /* reserved */ + "iana-grp08", "iana-grp09", + "iana-grp10", "iana-grp11", + "iana-grp12", "iana-grp13", + "modp2048", /* group 14 */ + "modp3072", /* group 15 */ + "modp4096", /* group 16 */ + "modp6144", /* group 17 */ + "modp8192", /* group 18 */ + }, }, + { "enc mode", 3, { NULL, "tunnel", "transport", }, }, + { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, }, + { "keylen", 0, { NULL } }, + { "rounds", 0, { NULL } }, + { "dictsize", 0, { NULL } }, + { "privalg", 0, { NULL } }, +}; + +const struct attrmap encr_t_map[] = { + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 0, 1 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 2, 3 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 4, 5 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 6, 7 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 8, 9 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 10,11*/ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 12,13*/ + { "keylen", 14, { NULL }}, +}; + +const struct attrmap oakley_t_map[] = { + { NULL, 0, { NULL } }, + { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5", + "3des", "cast", "aes", }, }, + { "hash", 7, { NULL, "md5", "sha1", "tiger", + "sha2-256", "sha2-384", "sha2-512", }, }, + { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc", + "rsa enc revised", }, }, + { "group desc", 18, { NULL, "modp768", + "modp1024", /* group 2 */ + "EC2N 2^155", /* group 3 */ + "EC2N 2^185", /* group 4 */ + "modp1536", /* group 5 */ + "iana-grp06", "iana-grp07", /* reserved */ + "iana-grp08", "iana-grp09", + "iana-grp10", "iana-grp11", + "iana-grp12", "iana-grp13", + "modp2048", /* group 14 */ + "modp3072", /* group 15 */ + "modp4096", /* group 16 */ + "modp6144", /* group 17 */ + "modp8192", /* group 18 */ + }, }, + { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, }, + { "group prime", 0, { NULL } }, + { "group gen1", 0, { NULL } }, + { "group gen2", 0, { NULL } }, + { "group curve A", 0, { NULL } }, + { "group curve B", 0, { NULL } }, + { "lifetype", 3, { NULL, "sec", "kb", }, }, + { "lifeduration", 0, { NULL } }, + { "prf", 0, { NULL } }, + { "keylen", 0, { NULL } }, + { "field", 0, { NULL } }, + { "order", 0, { NULL } }, +}; + +static const u_char * +ikev1_t_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len, + const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto, int depth _U_) +{ + const struct ikev1_pl_t *p; + struct ikev1_pl_t t; + const u_char *cp; + const char *idstr; + const struct attrmap *map; + size_t nmap; + const u_char *ep2; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T))); + + p = (struct ikev1_pl_t *)ext; + ND_TCHECK(*p); + safememcpy(&t, ext, sizeof(t)); + + switch (proto) { + case 1: + idstr = STR_OR_ID(t.t_id, ikev1_p_map); + map = oakley_t_map; + nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); + break; + case 2: + idstr = STR_OR_ID(t.t_id, ah_p_map); + map = ipsec_t_map; + nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); + break; + case 3: + idstr = STR_OR_ID(t.t_id, esp_p_map); + map = ipsec_t_map; + nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); + break; + case 4: + idstr = STR_OR_ID(t.t_id, ipcomp_p_map); + map = ipsec_t_map; + nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); + break; + default: + idstr = NULL; + map = NULL; + nmap = 0; + break; + } + + if (idstr) + ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr)); + else + ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id)); + cp = (u_char *)(p + 1); + ep2 = (u_char *)p + item_len; + while (cp < ep && cp < ep2) { + if (map && nmap) { + cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, + map, nmap); + } else + cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2); + } + if (ep < ep2) + ND_PRINT((ndo,"...")); + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T))); + return NULL; +} + +static const u_char * +ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE))); + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE))); + return NULL; +} + +static const u_char * +ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ +#define USE_IPSECDOI_IN_PHASE1 1 + const struct ikev1_pl_id *p; + struct ikev1_pl_id id; + static const char *idtypestr[] = { + "IPv4", "IPv4net", "IPv6", "IPv6net", + }; + static const char *ipsecidtypestr[] = { + NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6", + "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN", + "keyid", + }; + int len; + const u_char *data; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID))); + + p = (struct ikev1_pl_id *)ext; + ND_TCHECK(*p); + safememcpy(&id, ext, sizeof(id)); + if (sizeof(*p) < item_len) { + data = (u_char *)(p + 1); + len = item_len - sizeof(*p); + } else { + data = NULL; + len = 0; + } + +#if 0 /*debug*/ + ND_PRINT((ndo," [phase=%d doi=%d proto=%d]", phase, doi, proto)); +#endif + switch (phase) { +#ifndef USE_IPSECDOI_IN_PHASE1 + case 1: +#endif + default: + ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.d.id_type, idtypestr))); + ND_PRINT((ndo," doi_data=%u", + (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff))); + break; + +#ifdef USE_IPSECDOI_IN_PHASE1 + case 1: +#endif + case 2: + { + const struct ipsecdoi_id *p; + struct ipsecdoi_id id; + struct protoent *pe; + + p = (struct ipsecdoi_id *)ext; + ND_TCHECK(*p); + safememcpy(&id, ext, sizeof(id)); + ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr))); + if (id.proto_id) { +#ifndef WIN32 + setprotoent(1); +#endif /* WIN32 */ + pe = getprotobynumber(id.proto_id); + if (pe) + ND_PRINT((ndo," protoid=%s", pe->p_name)); +#ifndef WIN32 + endprotoent(); +#endif /* WIN32 */ + } else { + /* it DOES NOT mean IPPROTO_IP! */ + ND_PRINT((ndo," protoid=%s", "0")); + } + ND_PRINT((ndo," port=%d", ntohs(id.port))); + if (!len) + break; + if (data == NULL) + goto trunc; + ND_TCHECK2(*data, len); + switch (id.type) { + case IPSECDOI_ID_IPV4_ADDR: + if (len < 4) + ND_PRINT((ndo," len=%d [bad: < 4]", len)); + else + ND_PRINT((ndo," len=%d %s", len, ipaddr_string(data))); + len = 0; + break; + case IPSECDOI_ID_FQDN: + case IPSECDOI_ID_USER_FQDN: + { + int i; + ND_PRINT((ndo," len=%d ", len)); + for (i = 0; i < len; i++) + safeputchar(data[i]); + len = 0; + break; + } + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + { + const u_char *mask; + if (len < 8) + ND_PRINT((ndo," len=%d [bad: < 8]", len)); + else { + mask = data + sizeof(struct in_addr); + ND_PRINT((ndo," len=%d %s/%u.%u.%u.%u", len, + ipaddr_string(data), + mask[0], mask[1], mask[2], mask[3])); + } + len = 0; + break; + } +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + if (len < 16) + ND_PRINT((ndo," len=%d [bad: < 16]", len)); + else + ND_PRINT((ndo," len=%d %s", len, ip6addr_string(data))); + len = 0; + break; + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + { + const u_int32_t *mask; + if (len < 20) + ND_PRINT((ndo," len=%d [bad: < 20]", len)); + else { + mask = (u_int32_t *)(data + sizeof(struct in6_addr)); + /*XXX*/ + ND_PRINT((ndo," len=%d %s/0x%08x%08x%08x%08x", len, + ip6addr_string(data), + mask[0], mask[1], mask[2], mask[3])); + } + len = 0; + break; + } +#endif /*INET6*/ + case IPSECDOI_ID_IPV4_ADDR_RANGE: + if (len < 8) + ND_PRINT((ndo," len=%d [bad: < 8]", len)); + else { + ND_PRINT((ndo," len=%d %s-%s", len, + ipaddr_string(data), + ipaddr_string(data + sizeof(struct in_addr)))); + } + len = 0; + break; +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_RANGE: + if (len < 32) + ND_PRINT((ndo," len=%d [bad: < 32]", len)); + else { + ND_PRINT((ndo," len=%d %s-%s", len, + ip6addr_string(data), + ip6addr_string(data + sizeof(struct in6_addr)))); + } + len = 0; + break; +#endif /*INET6*/ + case IPSECDOI_ID_DER_ASN1_DN: + case IPSECDOI_ID_DER_ASN1_GN: + case IPSECDOI_ID_KEY_ID: + break; + } + break; + } + } + if (data && len) { + ND_PRINT((ndo," len=%d", len)); + if (2 < ndo->ndo_vflag) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)data, len)) + goto trunc; + } + } + return (u_char *)ext + item_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID))); + return NULL; +} + +static const u_char * +ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, + u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) +{ + const struct ikev1_pl_cert *p; + struct ikev1_pl_cert cert; + static const char *certstr[] = { + "none", "pkcs7", "pgp", "dns", + "x509sign", "x509ke", "kerberos", "crl", + "arl", "spki", "x509attr", + }; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT))); + + p = (struct ikev1_pl_cert *)ext; + ND_TCHECK(*p); + safememcpy(&cert, ext, sizeof(cert)); + ND_PRINT((ndo," len=%d", item_len - 4)); + ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); + if (2 < ndo->ndo_vflag && 4 < item_len) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4)) + goto trunc; + } + return (u_char *)ext + item_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT))); + return NULL; +} + +static const u_char * +ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) +{ + const struct ikev1_pl_cert *p; + struct ikev1_pl_cert cert; + static const char *certstr[] = { + "none", "pkcs7", "pgp", "dns", + "x509sign", "x509ke", "kerberos", "crl", + "arl", "spki", "x509attr", + }; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR))); + + p = (struct ikev1_pl_cert *)ext; + ND_TCHECK(*p); + safememcpy(&cert, ext, sizeof(cert)); + ND_PRINT((ndo," len=%d", item_len - 4)); + ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); + if (2 < ndo->ndo_vflag && 4 < item_len) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4)) + goto trunc; + } + return (u_char *)ext + item_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR))); + return NULL; +} + +static const u_char * +ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH))); + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH))); + return NULL; +} + +static const u_char * +ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG))); + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG))); + return NULL; +} + +static const u_char * +ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, + u_int item_len _U_, + const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE))); + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!ike_show_somedata(ndo, (u_char *)(caddr_t)(ext + 1), ep)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE))); + return NULL; +} + +static const u_char * +ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len, + const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth) +{ + struct ikev1_pl_n *p, n; + const u_char *cp; + u_char *ep2; + u_int32_t doi; + u_int32_t proto; + static const char *notify_error_str[] = { + NULL, "INVALID-PAYLOAD-TYPE", + "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED", + "INVALID-COOKIE", "INVALID-MAJOR-VERSION", + "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE", + "INVALID-FLAGS", "INVALID-MESSAGE-ID", + "INVALID-PROTOCOL-ID", "INVALID-SPI", + "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED", + "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX", + "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION", + "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING", + "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED", + "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION", + "AUTHENTICATION-FAILED", "INVALID-SIGNATURE", + "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME", + "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE", + "UNEQUAL-PAYLOAD-LENGTHS", + }; + static const char *ipsec_notify_error_str[] = { + "RESERVED", + }; + static const char *notify_status_str[] = { + "CONNECTED", + }; + static const char *ipsec_notify_status_str[] = { + "RESPONDER-LIFETIME", "REPLAY-STATUS", + "INITIAL-CONTACT", + }; +/* NOTE: these macro must be called with x in proper range */ + +/* 0 - 8191 */ +#define NOTIFY_ERROR_STR(x) \ + STR_OR_ID((x), notify_error_str) + +/* 8192 - 16383 */ +#define IPSEC_NOTIFY_ERROR_STR(x) \ + STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str) + +/* 16384 - 24575 */ +#define NOTIFY_STATUS_STR(x) \ + STR_OR_ID((u_int)((x) - 16384), notify_status_str) + +/* 24576 - 32767 */ +#define IPSEC_NOTIFY_STATUS_STR(x) \ + STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str) + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N))); + + p = (struct ikev1_pl_n *)ext; + ND_TCHECK(*p); + safememcpy(&n, ext, sizeof(n)); + doi = ntohl(n.doi); + proto = n.prot_id; + if (doi != 1) { + ND_PRINT((ndo," doi=%d", doi)); + ND_PRINT((ndo," proto=%d", proto)); + if (ntohs(n.type) < 8192) + ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type)))); + else if (ntohs(n.type) < 16384) + ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); + else if (ntohs(n.type) < 24576) + ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type)))); + else + ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); + if (n.spi_size) { + ND_PRINT((ndo," spi=")); + if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) + goto trunc; + } + return (u_char *)(p + 1) + n.spi_size; + } + + ND_PRINT((ndo," doi=ipsec")); + ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto))); + if (ntohs(n.type) < 8192) + ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type)))); + else if (ntohs(n.type) < 16384) + ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type)))); + else if (ntohs(n.type) < 24576) + ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type)))); + else if (ntohs(n.type) < 32768) + ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type)))); + else + ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); + if (n.spi_size) { + ND_PRINT((ndo," spi=")); + if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) + goto trunc; + } + + cp = (u_char *)(p + 1) + n.spi_size; + ep2 = (u_char *)p + item_len; + + if (cp < ep) { + ND_PRINT((ndo," orig=(")); + switch (ntohs(n.type)) { + case IPSECDOI_NTYPE_RESPONDER_LIFETIME: + { + const struct attrmap *map = oakley_t_map; + size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); + while (cp < ep && cp < ep2) { + cp = ikev1_attrmap_print(ndo, cp, + (ep < ep2) ? ep : ep2, map, nmap); + } + break; + } + case IPSECDOI_NTYPE_REPLAY_STATUS: + ND_PRINT((ndo,"replay detection %sabled", + (*(u_int32_t *)cp) ? "en" : "dis")); + break; + case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: + if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA, + (struct isakmp_gen *)cp, ep, phase, doi, proto, + depth) == NULL) + return NULL; + break; + default: + /* NULL is dummy */ + isakmp_print(ndo, cp, + item_len - sizeof(*p) - n.spi_size, + NULL); + } + ND_PRINT((ndo,")")); + } + return (u_char *)ext + item_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); + return NULL; +} + +static const u_char * +ikev1_d_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) +{ + const struct ikev1_pl_d *p; + struct ikev1_pl_d d; + const u_int8_t *q; + u_int32_t doi; + u_int32_t proto; + int i; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D))); + + p = (struct ikev1_pl_d *)ext; + ND_TCHECK(*p); + safememcpy(&d, ext, sizeof(d)); + doi = ntohl(d.doi); + proto = d.prot_id; + if (doi != 1) { + ND_PRINT((ndo," doi=%u", doi)); + ND_PRINT((ndo," proto=%u", proto)); + } else { + ND_PRINT((ndo," doi=ipsec")); + ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto))); + } + ND_PRINT((ndo," spilen=%u", d.spi_size)); + ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi))); + ND_PRINT((ndo," spi=")); + q = (u_int8_t *)(p + 1); + for (i = 0; i < ntohs(d.num_spi); i++) { + if (i != 0) + ND_PRINT((ndo,",")); + if (!rawprint(ndo, (caddr_t)q, d.spi_size)) + goto trunc; + q += d.spi_size; + } + return q; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_D))); + return NULL; +} + +static const u_char * +ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID))); + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID))); + return NULL; +} + +/************************************************************/ +/* */ +/* IKE v2 - rfc4306 - dissector */ +/* */ +/************************************************************/ + +static void +ikev2_pay_print(netdissect_options *ndo, const char *payname, int critical) +{ + ND_PRINT((ndo,"%s%s:", payname, critical&0x80 ? "[C]" : "")); +} + +static const u_char * +ikev2_gen_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext) +{ + struct isakmp_gen e; + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ikev2_pay_print(ndo, NPSTR(tpay), e.critical); + + ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount, + const struct isakmp_gen *ext, u_int item_len, + const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + const struct ikev2_t *p; + struct ikev2_t t; + u_int16_t t_id; + const u_char *cp; + const char *idstr; + const struct attrmap *map; + size_t nmap; + const u_char *ep2; + + p = (struct ikev2_t *)ext; + ND_TCHECK(*p); + safememcpy(&t, ext, sizeof(t)); + ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical); + + t_id = ntohs(t.t_id); + + map = NULL; + nmap = 0; + + switch (t.t_type) { + case IV2_T_ENCR: + idstr = STR_OR_ID(t_id, esp_p_map); + map = encr_t_map; + nmap = sizeof(encr_t_map)/sizeof(encr_t_map[0]); + break; + + case IV2_T_PRF: + idstr = STR_OR_ID(t_id, prf_p_map); + break; + + case IV2_T_INTEG: + idstr = STR_OR_ID(t_id, integ_p_map); + break; + + case IV2_T_DH: + idstr = STR_OR_ID(t_id, dh_p_map); + break; + + case IV2_T_ESN: + idstr = STR_OR_ID(t_id, esn_p_map); + break; + + default: + idstr = NULL; + break; + } + + if (idstr) + ND_PRINT((ndo," #%u type=%s id=%s ", pcount, + STR_OR_ID(t.t_type, ikev2_t_type_map), + idstr)); + else + ND_PRINT((ndo," #%u type=%s id=%u ", pcount, + STR_OR_ID(t.t_type, ikev2_t_type_map), + t.t_id)); + cp = (u_char *)(p + 1); + ep2 = (u_char *)p + item_len; + while (cp < ep && cp < ep2) { + if (map && nmap) { + cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, + map, nmap); + } else + cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2); + } + if (ep < ep2) + ND_PRINT((ndo,"...")); + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T))); + return NULL; +} + +static const u_char * +ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep, u_int32_t phase, u_int32_t doi0, + u_int32_t proto0 _U_, int depth) +{ + const struct ikev2_p *p; + struct ikev2_p prop; + const u_char *cp; + + p = (struct ikev2_p *)ext; + ND_TCHECK(*p); + safememcpy(&prop, ext, sizeof(prop)); + ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical); + + ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u", + prop.p_no, PROTOIDSTR(prop.prot_id), + prop.num_t, ntohs(prop.h.len))); + if (prop.spi_size) { + ND_PRINT((ndo," spi=")); + if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size)) + goto trunc; + } + + ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); + ND_TCHECK(*ext); + + cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, + prop.prot_id, depth); + + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); + return NULL; +} + +static const u_char * +ikev2_sa_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext1, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + int osa_length, sa_length; + + ND_TCHECK(*ext1); + safememcpy(&e, ext1, sizeof(e)); + ikev2_pay_print(ndo, "sa", e.critical); + + osa_length= ntohs(e.len); + sa_length = osa_length - 4; + ND_PRINT((ndo," len=%d", sa_length)); + + ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P, + ext1+1, ep, + 0, 0, 0, depth); + + return (u_char *)ext1 + osa_length; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_ke_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct ikev2_ke ke; + struct ikev2_ke *k; + + k = (struct ikev2_ke *)ext; + ND_TCHECK(*ext); + safememcpy(&ke, ext, sizeof(ke)); + ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical); + + ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8, + STR_OR_ID(ntohs(ke.ke_group), dh_p_map))); + + if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(k + 1), ntohs(ke.h.len) - 8)) + goto trunc; + } + return (u_char *)ext + ntohs(ke.h.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_ID_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct ikev2_id id; + int id_len, idtype_len, i; + unsigned int dumpascii, dumphex; + unsigned char *typedata; + + ND_TCHECK(*ext); + safememcpy(&id, ext, sizeof(id)); + ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical); + + id_len = ntohs(id.h.len); + + ND_PRINT((ndo," len=%d", id_len - 4)); + if (2 < ndo->ndo_vflag && 4 < id_len) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4)) + goto trunc; + } + + idtype_len =id_len - sizeof(struct ikev2_id); + dumpascii = 0; + dumphex = 0; + typedata = (unsigned char *)(ext)+sizeof(struct ikev2_id); + + switch(id.type) { + case ID_IPV4_ADDR: + ND_PRINT((ndo, " ipv4:")); + dumphex=1; + break; + case ID_FQDN: + ND_PRINT((ndo, " fqdn:")); + dumpascii=1; + break; + case ID_RFC822_ADDR: + ND_PRINT((ndo, " rfc822:")); + dumpascii=1; + break; + case ID_IPV6_ADDR: + ND_PRINT((ndo, " ipv6:")); + dumphex=1; + break; + case ID_DER_ASN1_DN: + ND_PRINT((ndo, " dn:")); + dumphex=1; + break; + case ID_DER_ASN1_GN: + ND_PRINT((ndo, " gn:")); + dumphex=1; + break; + case ID_KEY_ID: + ND_PRINT((ndo, " keyid:")); + dumphex=1; + break; + } + + if(dumpascii) { + ND_TCHECK2(*typedata, idtype_len); + for(i=0; i<idtype_len; i++) { + if(isprint(typedata[i])) { + ND_PRINT((ndo, "%c", typedata[i])); + } else { + ND_PRINT((ndo, ".")); + } + } + } + if(dumphex) { + if (!rawprint(ndo, (caddr_t)typedata, idtype_len)) + goto trunc; + } + + return (u_char *)ext + id_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_cert_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + return ikev2_gen_print(ndo, tpay, ext); +} + +static const u_char * +ikev2_cr_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + return ikev2_gen_print(ndo, tpay, ext); +} + +static const u_char * +ikev2_auth_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct ikev2_auth a; + const char *v2_auth[]={ "invalid", "rsasig", + "shared-secret", "dsssig" }; + u_char *authdata = (u_char*)ext + sizeof(a); + unsigned int len; + + ND_TCHECK(*ext); + safememcpy(&a, ext, sizeof(a)); + ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical); + len = ntohs(a.h.len); + + ND_PRINT((ndo," len=%d method=%s", len-4, + STR_OR_ID(a.auth_method, v2_auth))); + + if (1 < ndo->ndo_vflag && 4 < len) { + ND_PRINT((ndo," authdata=(")); + if (!rawprint(ndo, (caddr_t)authdata, len - sizeof(a))) + goto trunc; + ND_PRINT((ndo,") ")); + } else if(ndo->ndo_vflag && 4 < len) { + if(!ike_show_somedata(ndo, authdata, ep)) goto trunc; + } + + return (u_char *)ext + len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_nonce_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ikev2_pay_print(ndo, "nonce", e.critical); + + ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); + if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," nonce=(")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + ND_PRINT((ndo,") ")); + } else if(ndo->ndo_vflag && 4 < ntohs(e.len)) { + if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc; + } + + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +/* notify payloads */ +static const u_char * +ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct ikev2_n *p, n; + const u_char *cp; + u_char *ep2; + u_char showspi, showdata, showsomedata; + const char *notify_name; + u_int32_t type; + + p = (struct ikev2_n *)ext; + ND_TCHECK(*p); + safememcpy(&n, ext, sizeof(n)); + ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical); + + showspi = 1; + showdata = 0; + showsomedata=0; + notify_name=NULL; + + ND_PRINT((ndo," prot_id=%s", PROTOIDSTR(n.prot_id))); + + type = ntohs(n.type); + + /* notify space is annoying sparse */ + switch(type) { + case IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD: + notify_name = "unsupported_critical_payload"; + showspi = 0; + break; + + case IV2_NOTIFY_INVALID_IKE_SPI: + notify_name = "invalid_ike_spi"; + showspi = 1; + break; + + case IV2_NOTIFY_INVALID_MAJOR_VERSION: + notify_name = "invalid_major_version"; + showspi = 0; + break; + + case IV2_NOTIFY_INVALID_SYNTAX: + notify_name = "invalid_syntax"; + showspi = 1; + break; + + case IV2_NOTIFY_INVALID_MESSAGE_ID: + notify_name = "invalid_message_id"; + showspi = 1; + break; + + case IV2_NOTIFY_INVALID_SPI: + notify_name = "invalid_spi"; + showspi = 1; + break; + + case IV2_NOTIFY_NO_PROPOSAL_CHOSEN: + notify_name = "no_protocol_chosen"; + showspi = 1; + break; + + case IV2_NOTIFY_INVALID_KE_PAYLOAD: + notify_name = "invalid_ke_payload"; + showspi = 1; + break; + + case IV2_NOTIFY_AUTHENTICATION_FAILED: + notify_name = "authentication_failed"; + showspi = 1; + break; + + case IV2_NOTIFY_SINGLE_PAIR_REQUIRED: + notify_name = "single_pair_required"; + showspi = 1; + break; + + case IV2_NOTIFY_NO_ADDITIONAL_SAS: + notify_name = "no_additional_sas"; + showspi = 0; + break; + + case IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE: + notify_name = "internal_address_failure"; + showspi = 0; + break; + + case IV2_NOTIFY_FAILED_CP_REQUIRED: + notify_name = "failed:cp_required"; + showspi = 0; + break; + + case IV2_NOTIFY_INVALID_SELECTORS: + notify_name = "invalid_selectors"; + showspi = 0; + break; + + case IV2_NOTIFY_INITIAL_CONTACT: + notify_name = "initial_contact"; + showspi = 0; + break; + + case IV2_NOTIFY_SET_WINDOW_SIZE: + notify_name = "set_window_size"; + showspi = 0; + break; + + case IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE: + notify_name = "additional_ts_possible"; + showspi = 0; + break; + + case IV2_NOTIFY_IPCOMP_SUPPORTED: + notify_name = "ipcomp_supported"; + showspi = 0; + break; + + case IV2_NOTIFY_NAT_DETECTION_SOURCE_IP: + notify_name = "nat_detection_source_ip"; + showspi = 1; + break; + + case IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP: + notify_name = "nat_detection_destination_ip"; + showspi = 1; + break; + + case IV2_NOTIFY_COOKIE: + notify_name = "cookie"; + showspi = 1; + showsomedata= 1; + showdata= 0; + break; + + case IV2_NOTIFY_USE_TRANSPORT_MODE: + notify_name = "use_transport_mode"; + showspi = 0; + break; + + case IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED: + notify_name = "http_cert_lookup_supported"; + showspi = 0; + break; + + case IV2_NOTIFY_REKEY_SA: + notify_name = "rekey_sa"; + showspi = 1; + break; + + case IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED: + notify_name = "tfc_padding_not_supported"; + showspi = 0; + break; + + case IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO: + notify_name = "non_first_fragment_also"; + showspi = 0; + break; + + default: + if (type < 8192) { + notify_name="error"; + } else if(type < 16384) { + notify_name="private-error"; + } else if(type < 40960) { + notify_name="status"; + } else { + notify_name="private-status"; + } + } + + if(notify_name) { + ND_PRINT((ndo," type=%u(%s)", type, notify_name)); + } + + + if (showspi && n.spi_size) { + ND_PRINT((ndo," spi=")); + if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) + goto trunc; + } + + cp = (u_char *)(p + 1) + n.spi_size; + ep2 = (u_char *)p + item_len; + + if(3 < ndo->ndo_vflag) { + showdata = 1; + } + + if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) { + ND_PRINT((ndo," data=(")); + if (!rawprint(ndo, (caddr_t)(cp), ep - cp)) + goto trunc; + + ND_PRINT((ndo,")")); + + } else if(showsomedata && cp < ep) { + if(!ike_show_somedata(ndo, cp, ep)) goto trunc; + } + + return (u_char *)ext + item_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); + return NULL; +} + +static const u_char * +ikev2_d_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + return ikev2_gen_print(ndo, tpay, ext); +} + +static const u_char * +ikev2_vid_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + const u_char *vid; + int i, len; + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ikev2_pay_print(ndo, NPSTR(tpay), e.critical); + ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4)); + + vid = (const u_char *)(ext+1); + len = ntohs(e.len) - 4; + ND_TCHECK2(*vid, len); + for(i=0; i<len; i++) { + if(isprint(vid[i])) ND_PRINT((ndo, "%c", vid[i])); + else ND_PRINT((ndo, ".")); + } + if (2 < ndo->ndo_vflag && 4 < len) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_TS_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + return ikev2_gen_print(ndo, tpay, ext); +} + +static const u_char * +ikev2_e_print(netdissect_options *ndo, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + struct isakmp *base, + u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + u_int32_t phase, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + u_int32_t doi, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + u_int32_t proto, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + int depth) +{ + struct isakmp_gen e; + u_char *dat; + volatile int dlen; + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ikev2_pay_print(ndo, NPSTR(tpay), e.critical); + + dlen = ntohs(e.len)-4; + + ND_PRINT((ndo," len=%d", dlen)); + if (2 < ndo->ndo_vflag && 4 < dlen) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), dlen)) + goto trunc; + } + + dat = (u_char *)(ext+1); + ND_TCHECK2(*dat, dlen); + +#ifdef HAVE_LIBCRYPTO + /* try to decypt it! */ + if(esp_print_decrypt_buffer_by_ikev2(ndo, + base->flags & ISAKMP_FLAG_I, + base->i_ck, base->r_ck, + dat, dat+dlen)) { + + ext = (const struct isakmp_gen *)ndo->ndo_packetp; + + /* got it decrypted, print stuff inside. */ + ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend, + phase, doi, proto, depth+1); + } +#endif + + + /* always return NULL, because E must be at end, and NP refers + * to what was inside. + */ + return NULL; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_cp_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + return ikev2_gen_print(ndo, tpay, ext); +} + +static const u_char * +ikev2_eap_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + return ikev2_gen_print(ndo, tpay, ext); +} + +static const u_char * +ike_sub0_print(netdissect_options *ndo, + u_char np, const struct isakmp_gen *ext, const u_char *ep, + + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) +{ + const u_char *cp; + struct isakmp_gen e; + u_int item_len; + + cp = (u_char *)ext; + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + + /* + * Since we can't have a payload length of less than 4 bytes, + * we need to bail out here if the generic header is nonsensical + * or truncated, otherwise we could loop forever processing + * zero-length items or otherwise misdissect the packet. + */ + item_len = ntohs(e.len); + if (item_len <= 4) + return NULL; + + if (NPFUNC(np)) { + /* + * XXX - what if item_len is too short, or too long, + * for this payload type? + */ + cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth); + } else { + ND_PRINT((ndo,"%s", NPSTR(np))); + cp += item_len; + } + + return cp; +trunc: + ND_PRINT((ndo," [|isakmp]")); + return NULL; +} + +static const u_char * +ikev1_sub_print(netdissect_options *ndo, + u_char np, const struct isakmp_gen *ext, const u_char *ep, + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) +{ + const u_char *cp; + int i; + struct isakmp_gen e; + + cp = (const u_char *)ext; + + while (np) { + ND_TCHECK(*ext); + + safememcpy(&e, ext, sizeof(e)); + + ND_TCHECK2(*ext, ntohs(e.len)); + + depth++; + ND_PRINT((ndo,"\n")); + for (i = 0; i < depth; i++) + ND_PRINT((ndo," ")); + ND_PRINT((ndo,"(")); + cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth); + ND_PRINT((ndo,")")); + depth--; + + if (cp == NULL) { + /* Zero-length subitem */ + return NULL; + } + + np = e.np; + ext = (struct isakmp_gen *)cp; + } + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(np))); + return NULL; +} + +static char * +numstr(int x) +{ + static char buf[20]; + snprintf(buf, sizeof(buf), "#%d", x); + return buf; +} + +/* + * some compiler tries to optimize memcpy(), using the alignment constraint + * on the argument pointer type. by using this function, we try to avoid the + * optimization. + */ +static void +safememcpy(void *p, const void *q, size_t l) +{ + memcpy(p, q, l); +} + +static void +ikev1_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2, struct isakmp *base) +{ + const struct isakmp *p; + const u_char *ep; + u_char np; + int i; + int phase; + + p = (const struct isakmp *)bp; + ep = ndo->ndo_snapend; + + phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2; + if (phase == 1) + ND_PRINT((ndo," phase %d", phase)); + else + ND_PRINT((ndo," phase %d/others", phase)); + + i = cookie_find(&base->i_ck); + if (i < 0) { + if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) { + /* the first packet */ + ND_PRINT((ndo," I")); + if (bp2) + cookie_record(&base->i_ck, bp2); + } else + ND_PRINT((ndo," ?")); + } else { + if (bp2 && cookie_isinitiator(i, bp2)) + ND_PRINT((ndo," I")); + else if (bp2 && cookie_isresponder(i, bp2)) + ND_PRINT((ndo," R")); + else + ND_PRINT((ndo," ?")); + } + + ND_PRINT((ndo," %s", ETYPESTR(base->etype))); + if (base->flags) { + ND_PRINT((ndo,"[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "", + base->flags & ISAKMP_FLAG_C ? "C" : "")); + } + + if (ndo->ndo_vflag) { + const struct isakmp_gen *ext; + int nparen; + + ND_PRINT((ndo,":")); + + /* regardless of phase... */ + if (base->flags & ISAKMP_FLAG_E) { + /* + * encrypted, nothing we can do right now. + * we hope to decrypt the packet in the future... + */ + ND_PRINT((ndo," [encrypted %s]", NPSTR(base->np))); + goto done; + } + + nparen = 0; + CHECKLEN(p + 1, base->np); + np = base->np; + ext = (struct isakmp_gen *)(p + 1); + ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0); + } + +done: + if (ndo->ndo_vflag) { + if (ntohl(base->len) != length) { + ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)", + (u_int32_t)ntohl(base->len), length)); + } + } +} + +static const u_char * +ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, + u_char np, int pcount, + const struct isakmp_gen *ext, const u_char *ep, + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) +{ + const u_char *cp; + struct isakmp_gen e; + u_int item_len; + + cp = (u_char *)ext; + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + + /* + * Since we can't have a payload length of less than 4 bytes, + * we need to bail out here if the generic header is nonsensical + * or truncated, otherwise we could loop forever processing + * zero-length items or otherwise misdissect the packet. + */ + item_len = ntohs(e.len); + if (item_len <= 4) + return NULL; + + if(np == ISAKMP_NPTYPE_P) { + cp = ikev2_p_print(ndo, np, pcount, ext, item_len, + ep, phase, doi, proto, depth); + } else if(np == ISAKMP_NPTYPE_T) { + cp = ikev2_t_print(ndo, np, pcount, ext, item_len, + ep, phase, doi, proto, depth); + } else if(np == ISAKMP_NPTYPE_v2E) { + cp = ikev2_e_print(ndo, base, np, ext, item_len, + ep, phase, doi, proto, depth); + } else if (NPFUNC(np)) { + /* + * XXX - what if item_len is too short, or too long, + * for this payload type? + */ + cp = (*npfunc[np])(ndo, np, /*pcount,*/ ext, item_len, + ep, phase, doi, proto, depth); + } else { + ND_PRINT((ndo,"%s", NPSTR(np))); + cp += item_len; + } + + return cp; +trunc: + ND_PRINT((ndo," [|isakmp]")); + return NULL; +} + +static const u_char * +ikev2_sub_print(netdissect_options *ndo, + struct isakmp *base, + u_char np, const struct isakmp_gen *ext, const u_char *ep, + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) +{ + const u_char *cp; + int i; + int pcount; + struct isakmp_gen e; + + cp = (const u_char *)ext; + pcount = 0; + while (np) { + pcount++; + ND_TCHECK(*ext); + + safememcpy(&e, ext, sizeof(e)); + + ND_TCHECK2(*ext, ntohs(e.len)); + + depth++; + ND_PRINT((ndo,"\n")); + for (i = 0; i < depth; i++) + ND_PRINT((ndo," ")); + ND_PRINT((ndo,"(")); + cp = ikev2_sub0_print(ndo, base, np, pcount, + ext, ep, phase, doi, proto, depth); + ND_PRINT((ndo,")")); + depth--; + + if (cp == NULL) { + /* Zero-length subitem */ + return NULL; + } + + np = e.np; + ext = (struct isakmp_gen *)cp; + } + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(np))); + return NULL; +} + +static void +ikev2_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2 _U_, struct isakmp *base) +{ + const struct isakmp *p; + const u_char *ep; + u_char np; + int phase; + + p = (const struct isakmp *)bp; + ep = ndo->ndo_snapend; + + phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2; + if (phase == 1) + ND_PRINT((ndo, " parent_sa")); + else + ND_PRINT((ndo, " child_sa ")); + + ND_PRINT((ndo, " %s", ETYPESTR(base->etype))); + if (base->flags) { + ND_PRINT((ndo, "[%s%s%s]", + base->flags & ISAKMP_FLAG_I ? "I" : "", + base->flags & ISAKMP_FLAG_V ? "V" : "", + base->flags & ISAKMP_FLAG_R ? "R" : "")); + } + + if (ndo->ndo_vflag) { + const struct isakmp_gen *ext; + int nparen; + + ND_PRINT((ndo, ":")); + + /* regardless of phase... */ + if (base->flags & ISAKMP_FLAG_E) { + /* + * encrypted, nothing we can do right now. + * we hope to decrypt the packet in the future... + */ + ND_PRINT((ndo, " [encrypted %s]", NPSTR(base->np))); + goto done; + } + + nparen = 0; + CHECKLEN(p + 1, base->np) + + np = base->np; + ext = (struct isakmp_gen *)(p + 1); + ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0); + } + +done: + if (ndo->ndo_vflag) { + if (ntohl(base->len) != length) { + ND_PRINT((ndo, " (len mismatch: isakmp %u/ip %u)", + (u_int32_t)ntohl(base->len), length)); + } + } +} + +void +isakmp_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2) +{ + const struct isakmp *p; + struct isakmp base; + const u_char *ep; + int major, minor; + +#ifdef HAVE_LIBCRYPTO + /* initialize SAs */ + if (ndo->ndo_sa_list_head == NULL) { + if (ndo->ndo_espsecret) + esp_print_decodesecret(ndo); + } +#endif + + p = (const struct isakmp *)bp; + ep = ndo->ndo_snapend; + + if ((struct isakmp *)ep < p + 1) { + ND_PRINT((ndo,"[|isakmp]")); + return; + } + + safememcpy(&base, p, sizeof(base)); + + ND_PRINT((ndo,"isakmp")); + major = (base.vers & ISAKMP_VERS_MAJOR) + >> ISAKMP_VERS_MAJOR_SHIFT; + minor = (base.vers & ISAKMP_VERS_MINOR) + >> ISAKMP_VERS_MINOR_SHIFT; + + if (ndo->ndo_vflag) { + ND_PRINT((ndo," %d.%d", major, minor)); + } + + if (ndo->ndo_vflag) { + ND_PRINT((ndo," msgid ")); + hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid)); + } + + if (1 < ndo->ndo_vflag) { + ND_PRINT((ndo," cookie ")); + hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck)); + ND_PRINT((ndo,"->")); + hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck)); + } + ND_PRINT((ndo,":")); + + switch(major) { + case IKEv1_MAJOR_VERSION: + ikev1_print(ndo, bp, length, bp2, &base); + break; + + case IKEv2_MAJOR_VERSION: + ikev2_print(ndo, bp, length, bp2, &base); + break; + } +} + +void +isakmp_rfc3948_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2) +{ + const u_char *ep; + ep = ndo->ndo_snapend; + + if(length == 1 && bp[0]==0xff) { + ND_PRINT((ndo, "isakmp-nat-keep-alive")); + return; + } + + if(length < 4) { + goto trunc; + } + + /* + * see if this is an IKE packet + */ + if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) { + ND_PRINT((ndo, "NONESP-encap: ")); + isakmp_print(ndo, bp+4, length-4, bp2); + return; + } + + /* must be an ESP packet */ + { + int nh, enh, padlen; + int advance; + + ND_PRINT((ndo, "UDP-encap: ")); + + advance = esp_print(ndo, bp, length, bp2, &enh, &padlen); + if(advance <= 0) + return; + + bp += advance; + length -= advance + padlen; + nh = enh & 0xff; + + ip_print_inner(ndo, bp, length, nh, bp2); + return; + } + +trunc: + ND_PRINT((ndo,"[|isakmp]")); + return; +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + + + + diff --git a/freebsd/contrib/tcpdump/print-isoclns.c b/freebsd/contrib/tcpdump/print-isoclns.c new file mode 100644 index 00000000..a4b9fb95 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-isoclns.c @@ -0,0 +1,3117 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1992, 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. + * + * Original code by Matt Thomas, Digital Equipment Corporation + * + * Extensively modified by Hannes Gredler (hannes@juniper.net) for more + * complete IS-IS & CLNP support. + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.165 2008-08-16 13:38:15 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "ether.h" +#include "nlpid.h" +#include "extract.h" +#include "gmpls.h" +#include "oui.h" +#include "signature.h" + +/* + * IS-IS is defined in ISO 10589. Look there for protocol definitions. + */ + +#define SYSTEM_ID_LEN ETHER_ADDR_LEN +#define NODE_ID_LEN SYSTEM_ID_LEN+1 +#define LSP_ID_LEN SYSTEM_ID_LEN+2 + +#define ISIS_VERSION 1 +#define ESIS_VERSION 1 +#define CLNP_VERSION 1 + +#define ISIS_PDU_TYPE_MASK 0x1F +#define ESIS_PDU_TYPE_MASK 0x1F +#define CLNP_PDU_TYPE_MASK 0x1F +#define CLNP_FLAG_MASK 0xE0 +#define ISIS_LAN_PRIORITY_MASK 0x7F + +#define ISIS_PDU_L1_LAN_IIH 15 +#define ISIS_PDU_L2_LAN_IIH 16 +#define ISIS_PDU_PTP_IIH 17 +#define ISIS_PDU_L1_LSP 18 +#define ISIS_PDU_L2_LSP 20 +#define ISIS_PDU_L1_CSNP 24 +#define ISIS_PDU_L2_CSNP 25 +#define ISIS_PDU_L1_PSNP 26 +#define ISIS_PDU_L2_PSNP 27 + +static struct tok isis_pdu_values[] = { + { ISIS_PDU_L1_LAN_IIH, "L1 Lan IIH"}, + { ISIS_PDU_L2_LAN_IIH, "L2 Lan IIH"}, + { ISIS_PDU_PTP_IIH, "p2p IIH"}, + { ISIS_PDU_L1_LSP, "L1 LSP"}, + { ISIS_PDU_L2_LSP, "L2 LSP"}, + { ISIS_PDU_L1_CSNP, "L1 CSNP"}, + { ISIS_PDU_L2_CSNP, "L2 CSNP"}, + { ISIS_PDU_L1_PSNP, "L1 PSNP"}, + { ISIS_PDU_L2_PSNP, "L2 PSNP"}, + { 0, NULL} +}; + +/* + * A TLV is a tuple of a type, length and a value and is normally used for + * encoding information in all sorts of places. This is an enumeration of + * the well known types. + * + * list taken from rfc3359 plus some memory from veterans ;-) + */ + +#define ISIS_TLV_AREA_ADDR 1 /* iso10589 */ +#define ISIS_TLV_IS_REACH 2 /* iso10589 */ +#define ISIS_TLV_ESNEIGH 3 /* iso10589 */ +#define ISIS_TLV_PART_DIS 4 /* iso10589 */ +#define ISIS_TLV_PREFIX_NEIGH 5 /* iso10589 */ +#define ISIS_TLV_ISNEIGH 6 /* iso10589 */ +#define ISIS_TLV_ISNEIGH_VARLEN 7 /* iso10589 */ +#define ISIS_TLV_PADDING 8 /* iso10589 */ +#define ISIS_TLV_LSP 9 /* iso10589 */ +#define ISIS_TLV_AUTH 10 /* iso10589, rfc3567 */ +#define ISIS_TLV_CHECKSUM 12 /* rfc3358 */ +#define ISIS_TLV_CHECKSUM_MINLEN 2 +#define ISIS_TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */ +#define ISIS_TLV_LSP_BUFFERSIZE_MINLEN 2 +#define ISIS_TLV_EXT_IS_REACH 22 /* draft-ietf-isis-traffic-05 */ +#define ISIS_TLV_IS_ALIAS_ID 24 /* draft-ietf-isis-ext-lsp-frags-02 */ +#define ISIS_TLV_DECNET_PHASE4 42 +#define ISIS_TLV_LUCENT_PRIVATE 66 +#define ISIS_TLV_INT_IP_REACH 128 /* rfc1195, rfc2966 */ +#define ISIS_TLV_PROTOCOLS 129 /* rfc1195 */ +#define ISIS_TLV_EXT_IP_REACH 130 /* rfc1195, rfc2966 */ +#define ISIS_TLV_IDRP_INFO 131 /* rfc1195 */ +#define ISIS_TLV_IDRP_INFO_MINLEN 1 +#define ISIS_TLV_IPADDR 132 /* rfc1195 */ +#define ISIS_TLV_IPAUTH 133 /* rfc1195 */ +#define ISIS_TLV_TE_ROUTER_ID 134 /* draft-ietf-isis-traffic-05 */ +#define ISIS_TLV_EXTD_IP_REACH 135 /* draft-ietf-isis-traffic-05 */ +#define ISIS_TLV_HOSTNAME 137 /* rfc2763 */ +#define ISIS_TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */ +#define ISIS_TLV_MT_PORT_CAP 143 /* rfc6165 */ +#define ISIS_TLV_MT_CAPABILITY 144 /* rfc6329 */ +#define ISIS_TLV_NORTEL_PRIVATE1 176 +#define ISIS_TLV_NORTEL_PRIVATE2 177 +#define ISIS_TLV_RESTART_SIGNALING 211 /* rfc3847 */ +#define ISIS_TLV_RESTART_SIGNALING_FLAGLEN 1 +#define ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN 2 +#define ISIS_TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */ +#define ISIS_TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */ +#define ISIS_TLV_MT_SUPPORTED_MINLEN 2 +#define ISIS_TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */ +#define ISIS_TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */ +#define ISIS_TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */ +#define ISIS_TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */ +#define ISIS_TLV_PTP_ADJ 240 /* rfc3373 */ +#define ISIS_TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */ +#define ISIS_TLV_IIH_SEQNR_MINLEN 4 +#define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-experimental-tlv-01 */ +#define ISIS_TLV_VENDOR_PRIVATE_MINLEN 3 + +static struct tok isis_tlv_values[] = { + { ISIS_TLV_AREA_ADDR, "Area address(es)"}, + { ISIS_TLV_IS_REACH, "IS Reachability"}, + { ISIS_TLV_ESNEIGH, "ES Neighbor(s)"}, + { ISIS_TLV_PART_DIS, "Partition DIS"}, + { ISIS_TLV_PREFIX_NEIGH, "Prefix Neighbors"}, + { ISIS_TLV_ISNEIGH, "IS Neighbor(s)"}, + { ISIS_TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"}, + { ISIS_TLV_PADDING, "Padding"}, + { ISIS_TLV_LSP, "LSP entries"}, + { ISIS_TLV_AUTH, "Authentication"}, + { ISIS_TLV_CHECKSUM, "Checksum"}, + { ISIS_TLV_LSP_BUFFERSIZE, "LSP Buffersize"}, + { ISIS_TLV_EXT_IS_REACH, "Extended IS Reachability"}, + { ISIS_TLV_IS_ALIAS_ID, "IS Alias ID"}, + { ISIS_TLV_DECNET_PHASE4, "DECnet Phase IV"}, + { ISIS_TLV_LUCENT_PRIVATE, "Lucent Proprietary"}, + { ISIS_TLV_INT_IP_REACH, "IPv4 Internal Reachability"}, + { ISIS_TLV_PROTOCOLS, "Protocols supported"}, + { ISIS_TLV_EXT_IP_REACH, "IPv4 External Reachability"}, + { ISIS_TLV_IDRP_INFO, "Inter-Domain Information Type"}, + { ISIS_TLV_IPADDR, "IPv4 Interface address(es)"}, + { ISIS_TLV_IPAUTH, "IPv4 authentication (deprecated)"}, + { ISIS_TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"}, + { ISIS_TLV_EXTD_IP_REACH, "Extended IPv4 Reachability"}, + { ISIS_TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"}, + { ISIS_TLV_MT_PORT_CAP, "Multi-Topology-Aware Port Capability"}, + { ISIS_TLV_MT_CAPABILITY, "Multi-Topology Capability"}, + { ISIS_TLV_NORTEL_PRIVATE1, "Nortel Proprietary"}, + { ISIS_TLV_NORTEL_PRIVATE2, "Nortel Proprietary"}, + { ISIS_TLV_HOSTNAME, "Hostname"}, + { ISIS_TLV_RESTART_SIGNALING, "Restart Signaling"}, + { ISIS_TLV_MT_IS_REACH, "Multi Topology IS Reachability"}, + { ISIS_TLV_MT_SUPPORTED, "Multi Topology"}, + { ISIS_TLV_IP6ADDR, "IPv6 Interface address(es)"}, + { ISIS_TLV_MT_IP_REACH, "Multi-Topology IPv4 Reachability"}, + { ISIS_TLV_IP6_REACH, "IPv6 reachability"}, + { ISIS_TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"}, + { ISIS_TLV_PTP_ADJ, "Point-to-point Adjacency State"}, + { ISIS_TLV_IIH_SEQNR, "Hello PDU Sequence Number"}, + { ISIS_TLV_VENDOR_PRIVATE, "Vendor Private"}, + { 0, NULL } +}; + +#define ESIS_OPTION_PROTOCOLS 129 +#define ESIS_OPTION_QOS_MAINTENANCE 195 /* iso9542 */ +#define ESIS_OPTION_SECURITY 197 /* iso9542 */ +#define ESIS_OPTION_ES_CONF_TIME 198 /* iso9542 */ +#define ESIS_OPTION_PRIORITY 205 /* iso9542 */ +#define ESIS_OPTION_ADDRESS_MASK 225 /* iso9542 */ +#define ESIS_OPTION_SNPA_MASK 226 /* iso9542 */ + +static struct tok esis_option_values[] = { + { ESIS_OPTION_PROTOCOLS, "Protocols supported"}, + { ESIS_OPTION_QOS_MAINTENANCE, "QoS Maintenance" }, + { ESIS_OPTION_SECURITY, "Security" }, + { ESIS_OPTION_ES_CONF_TIME, "ES Configuration Time" }, + { ESIS_OPTION_PRIORITY, "Priority" }, + { ESIS_OPTION_ADDRESS_MASK, "Addressk Mask" }, + { ESIS_OPTION_SNPA_MASK, "SNPA Mask" }, + { 0, NULL } +}; + +#define CLNP_OPTION_DISCARD_REASON 193 +#define CLNP_OPTION_QOS_MAINTENANCE 195 /* iso8473 */ +#define CLNP_OPTION_SECURITY 197 /* iso8473 */ +#define CLNP_OPTION_SOURCE_ROUTING 200 /* iso8473 */ +#define CLNP_OPTION_ROUTE_RECORDING 203 /* iso8473 */ +#define CLNP_OPTION_PADDING 204 /* iso8473 */ +#define CLNP_OPTION_PRIORITY 205 /* iso8473 */ + +static struct tok clnp_option_values[] = { + { CLNP_OPTION_DISCARD_REASON, "Discard Reason"}, + { CLNP_OPTION_PRIORITY, "Priority"}, + { CLNP_OPTION_QOS_MAINTENANCE, "QoS Maintenance"}, + { CLNP_OPTION_SECURITY, "Security"}, + { CLNP_OPTION_SOURCE_ROUTING, "Source Routing"}, + { CLNP_OPTION_ROUTE_RECORDING, "Route Recording"}, + { CLNP_OPTION_PADDING, "Padding"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_class_values[] = { + { 0x0, "General"}, + { 0x8, "Address"}, + { 0x9, "Source Routeing"}, + { 0xa, "Lifetime"}, + { 0xb, "PDU Discarded"}, + { 0xc, "Reassembly"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_general_values[] = { + { 0x0, "Reason not specified"}, + { 0x1, "Protocol procedure error"}, + { 0x2, "Incorrect checksum"}, + { 0x3, "PDU discarded due to congestion"}, + { 0x4, "Header syntax error (cannot be parsed)"}, + { 0x5, "Segmentation needed but not permitted"}, + { 0x6, "Incomplete PDU received"}, + { 0x7, "Duplicate option"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_address_values[] = { + { 0x0, "Destination address unreachable"}, + { 0x1, "Destination address unknown"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_source_routeing_values[] = { + { 0x0, "Unspecified source routeing error"}, + { 0x1, "Syntax error in source routeing field"}, + { 0x2, "Unknown address in source routeing field"}, + { 0x3, "Path not acceptable"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_lifetime_values[] = { + { 0x0, "Lifetime expired while data unit in transit"}, + { 0x1, "Lifetime expired during reassembly"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_pdu_discard_values[] = { + { 0x0, "Unsupported option not specified"}, + { 0x1, "Unsupported protocol version"}, + { 0x2, "Unsupported security option"}, + { 0x3, "Unsupported source routeing option"}, + { 0x4, "Unsupported recording of route option"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_reassembly_values[] = { + { 0x0, "Reassembly interference"}, + { 0, NULL } +}; + +/* array of 16 error-classes */ +static struct tok *clnp_option_rfd_error_class[] = { + clnp_option_rfd_general_values, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + clnp_option_rfd_address_values, + clnp_option_rfd_source_routeing_values, + clnp_option_rfd_lifetime_values, + clnp_option_rfd_pdu_discard_values, + clnp_option_rfd_reassembly_values, + NULL, + NULL, + NULL +}; + +#define CLNP_OPTION_OPTION_QOS_MASK 0x3f +#define CLNP_OPTION_SCOPE_MASK 0xc0 +#define CLNP_OPTION_SCOPE_SA_SPEC 0x40 +#define CLNP_OPTION_SCOPE_DA_SPEC 0x80 +#define CLNP_OPTION_SCOPE_GLOBAL 0xc0 + +static struct tok clnp_option_scope_values[] = { + { CLNP_OPTION_SCOPE_SA_SPEC, "Source Address Specific"}, + { CLNP_OPTION_SCOPE_DA_SPEC, "Destination Address Specific"}, + { CLNP_OPTION_SCOPE_GLOBAL, "Globally unique"}, + { 0, NULL } +}; + +static struct tok clnp_option_sr_rr_values[] = { + { 0x0, "partial"}, + { 0x1, "complete"}, + { 0, NULL } +}; + +static struct tok clnp_option_sr_rr_string_values[] = { + { CLNP_OPTION_SOURCE_ROUTING, "source routing"}, + { CLNP_OPTION_ROUTE_RECORDING, "recording of route in progress"}, + { 0, NULL } +}; + +static struct tok clnp_option_qos_global_values[] = { + { 0x20, "reserved"}, + { 0x10, "sequencing vs. delay"}, + { 0x08, "congested"}, + { 0x04, "delay vs. cost"}, + { 0x02, "error vs. delay"}, + { 0x01, "error vs. cost"}, + { 0, NULL } +}; + +#define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* rfc4205 */ +#define ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* rfc4124 */ +#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD 12 /* draft-ietf-tewg-diff-te-proto-06 */ +#define ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE 19 /* draft-ietf-isis-link-attr-01 */ +#define ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* rfc4205 */ +#define ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* rfc4205 */ +#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS 22 /* rfc4124 */ + +#define ISIS_SUBTLV_SPB_METRIC 29 /* rfc6329 */ + +static struct tok isis_ext_is_reach_subtlv_values[] = { + { ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP, "Administrative groups" }, + { ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" }, + { ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID, "Link Remote Identifier" }, + { ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR, "IPv4 interface address" }, + { ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR, "IPv4 neighbor address" }, + { ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW, "Maximum link bandwidth" }, + { ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW, "Reservable link bandwidth" }, + { ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW, "Unreserved bandwidth" }, + { ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC, "Traffic Engineering Metric" }, + { ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE, "Link Attribute" }, + { ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE, "Link Protection Type" }, + { ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, + { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD, "Bandwidth Constraints (old)" }, + { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS, "Bandwidth Constraints" }, + { ISIS_SUBTLV_SPB_METRIC, "SPB Metric" }, + { 250, "Reserved for cisco specific extensions" }, + { 251, "Reserved for cisco specific extensions" }, + { 252, "Reserved for cisco specific extensions" }, + { 253, "Reserved for cisco specific extensions" }, + { 254, "Reserved for cisco specific extensions" }, + { 255, "Reserved for future expansion" }, + { 0, NULL } +}; + +#define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 /* draft-ietf-isis-admin-tags-01 */ +#define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 /* draft-ietf-isis-admin-tags-01 */ +#define ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR 117 /* draft-ietf-isis-wg-multi-topology-05 */ + +static struct tok isis_ext_ip_reach_subtlv_values[] = { + { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" }, + { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" }, + { ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR, "Management Prefix Color" }, + { 0, NULL } +}; + +static struct tok isis_subtlv_link_attribute_values[] = { + { 0x01, "Local Protection Available" }, + { 0x02, "Link excluded from local protection path" }, + { 0x04, "Local maintenance required"}, + { 0, NULL } +}; + +#define ISIS_SUBTLV_AUTH_SIMPLE 1 +#define ISIS_SUBTLV_AUTH_GENERIC 3 /* rfc 5310 */ +#define ISIS_SUBTLV_AUTH_MD5 54 +#define ISIS_SUBTLV_AUTH_MD5_LEN 16 +#define ISIS_SUBTLV_AUTH_PRIVATE 255 + +static struct tok isis_subtlv_auth_values[] = { + { ISIS_SUBTLV_AUTH_SIMPLE, "simple text password"}, + { ISIS_SUBTLV_AUTH_GENERIC, "Generic Crypto key-id"}, + { ISIS_SUBTLV_AUTH_MD5, "HMAC-MD5 password"}, + { ISIS_SUBTLV_AUTH_PRIVATE, "Routing Domain private password"}, + { 0, NULL } +}; + +#define ISIS_SUBTLV_IDRP_RES 0 +#define ISIS_SUBTLV_IDRP_LOCAL 1 +#define ISIS_SUBTLV_IDRP_ASN 2 + +static struct tok isis_subtlv_idrp_values[] = { + { ISIS_SUBTLV_IDRP_RES, "Reserved"}, + { ISIS_SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"}, + { ISIS_SUBTLV_IDRP_ASN, "AS Number Tag"}, + { 0, NULL} +}; + +#define ISIS_SUBTLV_SPB_MCID 4 +#define ISIS_SUBTLV_SPB_DIGEST 5 +#define ISIS_SUBTLV_SPB_BVID 6 + +#define ISIS_SUBTLV_SPB_INSTANCE 1 +#define ISIS_SUBTLV_SPBM_SI 3 + +#define ISIS_SPB_MCID_LEN 51 +#define ISIS_SUBTLV_SPB_MCID_MIN_LEN 102 +#define ISIS_SUBTLV_SPB_DIGEST_MIN_LEN 33 +#define ISIS_SUBTLV_SPB_BVID_MIN_LEN 6 +#define ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN 19 +#define ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN 8 + +static struct tok isis_mt_port_cap_subtlv_values[] = { + { ISIS_SUBTLV_SPB_MCID, "SPB MCID" }, + { ISIS_SUBTLV_SPB_DIGEST, "SPB Digest" }, + { ISIS_SUBTLV_SPB_BVID, "SPB BVID" }, + { 0, NULL } +}; + +static struct tok isis_mt_capability_subtlv_values[] = { + { ISIS_SUBTLV_SPB_INSTANCE, "SPB Instance" }, + { ISIS_SUBTLV_SPBM_SI, "SPBM Service Identifier and Unicast Address" }, + { 0, NULL } +}; + +struct isis_spb_mcid { + u_int8_t format_id; + u_int8_t name[32]; + u_int8_t revision_lvl[2]; + u_int8_t digest[16]; +}; + +struct isis_subtlv_spb_mcid { + struct isis_spb_mcid mcid; + struct isis_spb_mcid aux_mcid; +}; + +struct isis_subtlv_spb_instance { + u_int8_t cist_root_id[8]; + u_int8_t cist_external_root_path_cost[4]; + u_int8_t bridge_priority[2]; + u_int8_t spsourceid[4]; + u_int8_t no_of_trees; +}; + +#define CLNP_SEGMENT_PART 0x80 +#define CLNP_MORE_SEGMENTS 0x40 +#define CLNP_REQUEST_ER 0x20 + +static struct tok clnp_flag_values[] = { + { CLNP_SEGMENT_PART, "Segmentation permitted"}, + { CLNP_MORE_SEGMENTS, "more Segments"}, + { CLNP_REQUEST_ER, "request Error Report"}, + { 0, NULL} +}; + +#define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4) +#define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3) +#define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80) +#define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78) +#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40) +#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20) +#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10) +#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8) + +#define ISIS_MASK_MTID(x) ((x)&0x0fff) +#define ISIS_MASK_MTFLAGS(x) ((x)&0xf000) + +static struct tok isis_mt_flag_values[] = { + { 0x4000, "ATT bit set"}, + { 0x8000, "Overload bit set"}, + { 0, NULL} +}; + +#define ISIS_MASK_TLV_EXTD_IP_UPDOWN(x) ((x)&0x80) +#define ISIS_MASK_TLV_EXTD_IP_SUBTLV(x) ((x)&0x40) + +#define ISIS_MASK_TLV_EXTD_IP6_IE(x) ((x)&0x40) +#define ISIS_MASK_TLV_EXTD_IP6_SUBTLV(x) ((x)&0x20) + +#define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80) +#define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40) +#define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80) +#define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f) + +#define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1) + +static struct tok isis_mt_values[] = { + { 0, "IPv4 unicast"}, + { 1, "In-Band Management"}, + { 2, "IPv6 unicast"}, + { 3, "Multicast"}, + { 4095, "Development, Experimental or Proprietary"}, + { 0, NULL } +}; + +static struct tok isis_iih_circuit_type_values[] = { + { 1, "Level 1 only"}, + { 2, "Level 2 only"}, + { 3, "Level 1, Level 2"}, + { 0, NULL} +}; + +#define ISIS_LSP_TYPE_UNUSED0 0 +#define ISIS_LSP_TYPE_LEVEL_1 1 +#define ISIS_LSP_TYPE_UNUSED2 2 +#define ISIS_LSP_TYPE_LEVEL_2 3 + +static struct tok isis_lsp_istype_values[] = { + { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"}, + { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"}, + { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"}, + { ISIS_LSP_TYPE_LEVEL_2, "L2 IS"}, + { 0, NULL } +}; + +/* + * Katz's point to point adjacency TLV uses codes to tell us the state of + * the remote adjacency. Enumerate them. + */ + +#define ISIS_PTP_ADJ_UP 0 +#define ISIS_PTP_ADJ_INIT 1 +#define ISIS_PTP_ADJ_DOWN 2 + +static struct tok isis_ptp_adjancey_values[] = { + { ISIS_PTP_ADJ_UP, "Up" }, + { ISIS_PTP_ADJ_INIT, "Initializing" }, + { ISIS_PTP_ADJ_DOWN, "Down" }, + { 0, NULL} +}; + +struct isis_tlv_ptp_adj { + u_int8_t adjacency_state; + u_int8_t extd_local_circuit_id[4]; + u_int8_t neighbor_sysid[SYSTEM_ID_LEN]; + u_int8_t neighbor_extd_local_circuit_id[4]; +}; + +static void osi_print_cksum(const u_int8_t *pptr, u_int16_t checksum, + u_int checksum_offset, u_int length); +static int clnp_print(const u_int8_t *, u_int); +static void esis_print(const u_int8_t *, u_int); +static int isis_print(const u_int8_t *, u_int); + +struct isis_metric_block { + u_int8_t metric_default; + u_int8_t metric_delay; + u_int8_t metric_expense; + u_int8_t metric_error; +}; + +struct isis_tlv_is_reach { + struct isis_metric_block isis_metric_block; + u_int8_t neighbor_nodeid[NODE_ID_LEN]; +}; + +struct isis_tlv_es_reach { + struct isis_metric_block isis_metric_block; + u_int8_t neighbor_sysid[SYSTEM_ID_LEN]; +}; + +struct isis_tlv_ip_reach { + struct isis_metric_block isis_metric_block; + u_int8_t prefix[4]; + u_int8_t mask[4]; +}; + +static struct tok isis_is_reach_virtual_values[] = { + { 0, "IsNotVirtual"}, + { 1, "IsVirtual"}, + { 0, NULL } +}; + +static struct tok isis_restart_flag_values[] = { + { 0x1, "Restart Request"}, + { 0x2, "Restart Acknowledgement"}, + { 0x4, "Suppress adjacency advertisement"}, + { 0, NULL } +}; + +struct isis_common_header { + u_int8_t nlpid; + u_int8_t fixed_len; + u_int8_t version; /* Protocol version */ + u_int8_t id_length; + u_int8_t pdu_type; /* 3 MSbits are reserved */ + u_int8_t pdu_version; /* Packet format version */ + u_int8_t reserved; + u_int8_t max_area; +}; + +struct isis_iih_lan_header { + u_int8_t circuit_type; + u_int8_t source_id[SYSTEM_ID_LEN]; + u_int8_t holding_time[2]; + u_int8_t pdu_len[2]; + u_int8_t priority; + u_int8_t lan_id[NODE_ID_LEN]; +}; + +struct isis_iih_ptp_header { + u_int8_t circuit_type; + u_int8_t source_id[SYSTEM_ID_LEN]; + u_int8_t holding_time[2]; + u_int8_t pdu_len[2]; + u_int8_t circuit_id; +}; + +struct isis_lsp_header { + u_int8_t pdu_len[2]; + u_int8_t remaining_lifetime[2]; + u_int8_t lsp_id[LSP_ID_LEN]; + u_int8_t sequence_number[4]; + u_int8_t checksum[2]; + u_int8_t typeblock; +}; + +struct isis_csnp_header { + u_int8_t pdu_len[2]; + u_int8_t source_id[NODE_ID_LEN]; + u_int8_t start_lsp_id[LSP_ID_LEN]; + u_int8_t end_lsp_id[LSP_ID_LEN]; +}; + +struct isis_psnp_header { + u_int8_t pdu_len[2]; + u_int8_t source_id[NODE_ID_LEN]; +}; + +struct isis_tlv_lsp { + u_int8_t remaining_lifetime[2]; + u_int8_t lsp_id[LSP_ID_LEN]; + u_int8_t sequence_number[4]; + u_int8_t checksum[2]; +}; + +#define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header)) +#define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header)) +#define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header)) +#define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header)) +#define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header)) +#define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header)) + +void isoclns_print(const u_int8_t *p, u_int length, u_int caplen) +{ + if (caplen <= 1) { /* enough bytes on the wire ? */ + printf("|OSI"); + return; + } + + if (eflag) + printf("OSI NLPID %s (0x%02x): ", + tok2str(nlpid_values,"Unknown",*p), + *p); + + switch (*p) { + + case NLPID_CLNP: + if (!clnp_print(p, length)) + print_unknown_data(p,"\n\t",caplen); + break; + + case NLPID_ESIS: + esis_print(p, length); + return; + + case NLPID_ISIS: + if (!isis_print(p, length)) + print_unknown_data(p,"\n\t",caplen); + break; + + case NLPID_NULLNS: + (void)printf("%slength: %u", + eflag ? "" : ", ", + length); + break; + + case NLPID_Q933: + q933_print(p+1, length-1); + break; + + case NLPID_IP: + ip_print(gndo, p+1, length-1); + break; + +#ifdef INET6 + case NLPID_IP6: + ip6_print(gndo, p+1, length-1); + break; +#endif + + case NLPID_PPP: + ppp_print(p+1, length-1); + break; + + default: + if (!eflag) + printf("OSI NLPID 0x%02x unknown",*p); + (void)printf("%slength: %u", + eflag ? "" : ", ", + length); + if (caplen > 1) + print_unknown_data(p,"\n\t",caplen); + break; + } +} + +#define CLNP_PDU_ER 1 +#define CLNP_PDU_DT 28 +#define CLNP_PDU_MD 29 +#define CLNP_PDU_ERQ 30 +#define CLNP_PDU_ERP 31 + +static struct tok clnp_pdu_values[] = { + { CLNP_PDU_ER, "Error Report"}, + { CLNP_PDU_MD, "MD"}, + { CLNP_PDU_DT, "Data"}, + { CLNP_PDU_ERQ, "Echo Request"}, + { CLNP_PDU_ERP, "Echo Response"}, + { 0, NULL } +}; + +struct clnp_header_t { + u_int8_t nlpid; + u_int8_t length_indicator; + u_int8_t version; + u_int8_t lifetime; /* units of 500ms */ + u_int8_t type; + u_int8_t segment_length[2]; + u_int8_t cksum[2]; +}; + +struct clnp_segment_header_t { + u_int8_t data_unit_id[2]; + u_int8_t segment_offset[2]; + u_int8_t total_length[2]; +}; + +/* + * clnp_print + * Decode CLNP packets. Return 0 on error. + */ + +static int clnp_print (const u_int8_t *pptr, u_int length) +{ + const u_int8_t *optr,*source_address,*dest_address; + u_int li,tlen,nsap_offset,source_address_length,dest_address_length, clnp_pdu_type, clnp_flags; + const struct clnp_header_t *clnp_header; + const struct clnp_segment_header_t *clnp_segment_header; + u_int8_t rfd_error_major,rfd_error_minor; + + clnp_header = (const struct clnp_header_t *) pptr; + TCHECK(*clnp_header); + + li = clnp_header->length_indicator; + optr = pptr; + + if (!eflag) + printf("CLNP"); + + /* + * Sanity checking of the header. + */ + + if (clnp_header->version != CLNP_VERSION) { + printf("version %d packet not supported", clnp_header->version); + return (0); + } + + /* FIXME further header sanity checking */ + + clnp_pdu_type = clnp_header->type & CLNP_PDU_TYPE_MASK; + clnp_flags = clnp_header->type & CLNP_FLAG_MASK; + + pptr += sizeof(struct clnp_header_t); + li -= sizeof(struct clnp_header_t); + dest_address_length = *pptr; + dest_address = pptr + 1; + + pptr += (1 + dest_address_length); + li -= (1 + dest_address_length); + source_address_length = *pptr; + source_address = pptr +1; + + pptr += (1 + source_address_length); + li -= (1 + source_address_length); + + if (vflag < 1) { + printf("%s%s > %s, %s, length %u", + eflag ? "" : ", ", + isonsap_string(source_address, source_address_length), + isonsap_string(dest_address, dest_address_length), + tok2str(clnp_pdu_values,"unknown (%u)",clnp_pdu_type), + length); + return (1); + } + printf("%slength %u",eflag ? "" : ", ",length); + + printf("\n\t%s PDU, hlen: %u, v: %u, lifetime: %u.%us, Segment PDU length: %u, checksum: 0x%04x", + tok2str(clnp_pdu_values, "unknown (%u)",clnp_pdu_type), + clnp_header->length_indicator, + clnp_header->version, + clnp_header->lifetime/2, + (clnp_header->lifetime%2)*5, + EXTRACT_16BITS(clnp_header->segment_length), + EXTRACT_16BITS(clnp_header->cksum)); + + osi_print_cksum(optr, EXTRACT_16BITS(clnp_header->cksum), 7, + clnp_header->length_indicator); + + printf("\n\tFlags [%s]", + bittok2str(clnp_flag_values,"none",clnp_flags)); + + printf("\n\tsource address (length %u): %s\n\tdest address (length %u): %s", + source_address_length, + isonsap_string(source_address, source_address_length), + dest_address_length, + isonsap_string(dest_address,dest_address_length)); + + if (clnp_flags & CLNP_SEGMENT_PART) { + clnp_segment_header = (const struct clnp_segment_header_t *) pptr; + TCHECK(*clnp_segment_header); + printf("\n\tData Unit ID: 0x%04x, Segment Offset: %u, Total PDU Length: %u", + EXTRACT_16BITS(clnp_segment_header->data_unit_id), + EXTRACT_16BITS(clnp_segment_header->segment_offset), + EXTRACT_16BITS(clnp_segment_header->total_length)); + pptr+=sizeof(const struct clnp_segment_header_t); + li-=sizeof(const struct clnp_segment_header_t); + } + + /* now walk the options */ + while (li >= 2) { + u_int op, opli; + const u_int8_t *tptr; + + TCHECK2(*pptr, 2); + if (li < 2) { + printf(", bad opts/li"); + return (0); + } + op = *pptr++; + opli = *pptr++; + li -= 2; + TCHECK2(*pptr, opli); + if (opli > li) { + printf(", opt (%d) too long", op); + return (0); + } + li -= opli; + tptr = pptr; + tlen = opli; + + printf("\n\t %s Option #%u, length %u, value: ", + tok2str(clnp_option_values,"Unknown",op), + op, + opli); + + switch (op) { + + + case CLNP_OPTION_ROUTE_RECORDING: /* those two options share the format */ + case CLNP_OPTION_SOURCE_ROUTING: + printf("%s %s", + tok2str(clnp_option_sr_rr_values,"Unknown",*tptr), + tok2str(clnp_option_sr_rr_string_values,"Unknown Option %u",op)); + nsap_offset=*(tptr+1); + if (nsap_offset == 0) { + printf(" Bad NSAP offset (0)"); + break; + } + nsap_offset-=1; /* offset to nsap list */ + if (nsap_offset > tlen) { + printf(" Bad NSAP offset (past end of option)"); + break; + } + tptr+=nsap_offset; + tlen-=nsap_offset; + while (tlen > 0) { + source_address_length=*tptr; + if (tlen < source_address_length+1) { + printf("\n\t NSAP address goes past end of option"); + break; + } + if (source_address_length > 0) { + source_address=(tptr+1); + TCHECK2(*source_address, source_address_length); + printf("\n\t NSAP address (length %u): %s", + source_address_length, + isonsap_string(source_address, source_address_length)); + } + tlen-=source_address_length+1; + } + break; + + case CLNP_OPTION_PRIORITY: + printf("0x%1x", *tptr&0x0f); + break; + + case CLNP_OPTION_QOS_MAINTENANCE: + printf("\n\t Format Code: %s", + tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK)); + + if ((*tptr&CLNP_OPTION_SCOPE_MASK) == CLNP_OPTION_SCOPE_GLOBAL) + printf("\n\t QoS Flags [%s]", + bittok2str(clnp_option_qos_global_values, + "none", + *tptr&CLNP_OPTION_OPTION_QOS_MASK)); + break; + + case CLNP_OPTION_SECURITY: + printf("\n\t Format Code: %s, Security-Level %u", + tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK), + *(tptr+1)); + break; + + case CLNP_OPTION_DISCARD_REASON: + rfd_error_major = (*tptr&0xf0) >> 4; + rfd_error_minor = *tptr&0x0f; + printf("\n\t Class: %s Error (0x%01x), %s (0x%01x)", + tok2str(clnp_option_rfd_class_values,"Unknown",rfd_error_major), + rfd_error_major, + tok2str(clnp_option_rfd_error_class[rfd_error_major],"Unknown",rfd_error_minor), + rfd_error_minor); + break; + + case CLNP_OPTION_PADDING: + printf("padding data"); + break; + + /* + * FIXME those are the defined Options that lack a decoder + * you are welcome to contribute code ;-) + */ + + default: + print_unknown_data(tptr,"\n\t ",opli); + break; + } + if (vflag > 1) + print_unknown_data(pptr,"\n\t ",opli); + pptr += opli; + } + + switch (clnp_pdu_type) { + + case CLNP_PDU_ER: /* fall through */ + case CLNP_PDU_ERP: + TCHECK(*pptr); + if (*(pptr) == NLPID_CLNP) { + printf("\n\t-----original packet-----\n\t"); + /* FIXME recursion protection */ + clnp_print(pptr, length-clnp_header->length_indicator); + break; + } + + case CLNP_PDU_DT: + case CLNP_PDU_MD: + case CLNP_PDU_ERQ: + + default: + /* dump the PDU specific data */ + if (length-(pptr-optr) > 0) { + printf("\n\t undecoded non-header data, length %u",length-clnp_header->length_indicator); + print_unknown_data(pptr,"\n\t ",length-(pptr-optr)); + } + } + + return (1); + + trunc: + fputs("[|clnp]", stdout); + return (1); + +} + + +#define ESIS_PDU_REDIRECT 6 +#define ESIS_PDU_ESH 2 +#define ESIS_PDU_ISH 4 + +static struct tok esis_pdu_values[] = { + { ESIS_PDU_REDIRECT, "redirect"}, + { ESIS_PDU_ESH, "ESH"}, + { ESIS_PDU_ISH, "ISH"}, + { 0, NULL } +}; + +struct esis_header_t { + u_int8_t nlpid; + u_int8_t length_indicator; + u_int8_t version; + u_int8_t reserved; + u_int8_t type; + u_int8_t holdtime[2]; + u_int8_t cksum[2]; +}; + +static void +esis_print(const u_int8_t *pptr, u_int length) +{ + const u_int8_t *optr; + u_int li,esis_pdu_type,source_address_length, source_address_number; + const struct esis_header_t *esis_header; + + if (!eflag) + printf("ES-IS"); + + if (length <= 2) { + if (qflag) + printf("bad pkt!"); + else + printf("no header at all!"); + return; + } + + esis_header = (const struct esis_header_t *) pptr; + TCHECK(*esis_header); + li = esis_header->length_indicator; + optr = pptr; + + /* + * Sanity checking of the header. + */ + + if (esis_header->nlpid != NLPID_ESIS) { + printf(" nlpid 0x%02x packet not supported", esis_header->nlpid); + return; + } + + if (esis_header->version != ESIS_VERSION) { + printf(" version %d packet not supported", esis_header->version); + return; + } + + if (li > length) { + printf(" length indicator(%d) > PDU size (%d)!", li, length); + return; + } + + if (li < sizeof(struct esis_header_t) + 2) { + printf(" length indicator < min PDU size %d:", li); + while (--length != 0) + printf("%02X", *pptr++); + return; + } + + esis_pdu_type = esis_header->type & ESIS_PDU_TYPE_MASK; + + if (vflag < 1) { + printf("%s%s, length %u", + eflag ? "" : ", ", + tok2str(esis_pdu_values,"unknown type (%u)",esis_pdu_type), + length); + return; + } else + printf("%slength %u\n\t%s (%u)", + eflag ? "" : ", ", + length, + tok2str(esis_pdu_values,"unknown type: %u", esis_pdu_type), + esis_pdu_type); + + printf(", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" ); + printf(", checksum: 0x%04x", EXTRACT_16BITS(esis_header->cksum)); + + osi_print_cksum(pptr, EXTRACT_16BITS(esis_header->cksum), 7, li); + + printf(", holding time: %us, length indicator: %u",EXTRACT_16BITS(esis_header->holdtime),li); + + if (vflag > 1) + print_unknown_data(optr,"\n\t",sizeof(struct esis_header_t)); + + pptr += sizeof(struct esis_header_t); + li -= sizeof(struct esis_header_t); + + switch (esis_pdu_type) { + case ESIS_PDU_REDIRECT: { + const u_int8_t *dst, *snpa, *neta; + u_int dstl, snpal, netal; + + TCHECK(*pptr); + if (li < 1) { + printf(", bad redirect/li"); + return; + } + dstl = *pptr; + pptr++; + li--; + TCHECK2(*pptr, dstl); + if (li < dstl) { + printf(", bad redirect/li"); + return; + } + dst = pptr; + pptr += dstl; + li -= dstl; + printf("\n\t %s", isonsap_string(dst,dstl)); + + TCHECK(*pptr); + if (li < 1) { + printf(", bad redirect/li"); + return; + } + snpal = *pptr; + pptr++; + li--; + TCHECK2(*pptr, snpal); + if (li < snpal) { + printf(", bad redirect/li"); + return; + } + snpa = pptr; + pptr += snpal; + li -= snpal; + TCHECK(*pptr); + if (li < 1) { + printf(", bad redirect/li"); + return; + } + netal = *pptr; + pptr++; + TCHECK2(*pptr, netal); + if (li < netal) { + printf(", bad redirect/li"); + return; + } + neta = pptr; + pptr += netal; + li -= netal; + + if (netal == 0) + printf("\n\t %s", etheraddr_string(snpa)); + else + printf("\n\t %s", isonsap_string(neta,netal)); + break; + } + + case ESIS_PDU_ESH: + TCHECK(*pptr); + if (li < 1) { + printf(", bad esh/li"); + return; + } + source_address_number = *pptr; + pptr++; + li--; + + printf("\n\t Number of Source Addresses: %u", source_address_number); + + while (source_address_number > 0) { + TCHECK(*pptr); + if (li < 1) { + printf(", bad esh/li"); + return; + } + source_address_length = *pptr; + pptr++; + li--; + + TCHECK2(*pptr, source_address_length); + if (li < source_address_length) { + printf(", bad esh/li"); + return; + } + printf("\n\t NET (length: %u): %s", + source_address_length, + isonsap_string(pptr,source_address_length)); + pptr += source_address_length; + li -= source_address_length; + source_address_number--; + } + + break; + + case ESIS_PDU_ISH: { + TCHECK(*pptr); + if (li < 1) { + printf(", bad ish/li"); + return; + } + source_address_length = *pptr; + pptr++; + li--; + TCHECK2(*pptr, source_address_length); + if (li < source_address_length) { + printf(", bad ish/li"); + return; + } + printf("\n\t NET (length: %u): %s", source_address_length, isonsap_string(pptr, source_address_length)); + pptr += source_address_length; + li -= source_address_length; + break; + } + + default: + if (vflag <= 1) { + if (pptr < snapend) + print_unknown_data(pptr,"\n\t ",snapend-pptr); + } + return; + } + + /* now walk the options */ + while (li != 0) { + u_int op, opli; + const u_int8_t *tptr; + + if (li < 2) { + printf(", bad opts/li"); + return; + } + TCHECK2(*pptr, 2); + op = *pptr++; + opli = *pptr++; + li -= 2; + if (opli > li) { + printf(", opt (%d) too long", op); + return; + } + li -= opli; + tptr = pptr; + + printf("\n\t %s Option #%u, length %u, value: ", + tok2str(esis_option_values,"Unknown",op), + op, + opli); + + switch (op) { + + case ESIS_OPTION_ES_CONF_TIME: + if (opli == 2) { + TCHECK2(*pptr, 2); + printf("%us", EXTRACT_16BITS(tptr)); + } else + printf("(bad length)"); + break; + + case ESIS_OPTION_PROTOCOLS: + while (opli>0) { + TCHECK(*pptr); + printf("%s (0x%02x)", + tok2str(nlpid_values, + "unknown", + *tptr), + *tptr); + if (opli>1) /* further NPLIDs ? - put comma */ + printf(", "); + tptr++; + opli--; + } + break; + + /* + * FIXME those are the defined Options that lack a decoder + * you are welcome to contribute code ;-) + */ + + case ESIS_OPTION_QOS_MAINTENANCE: + case ESIS_OPTION_SECURITY: + case ESIS_OPTION_PRIORITY: + case ESIS_OPTION_ADDRESS_MASK: + case ESIS_OPTION_SNPA_MASK: + + default: + print_unknown_data(tptr,"\n\t ",opli); + break; + } + if (vflag > 1) + print_unknown_data(pptr,"\n\t ",opli); + pptr += opli; + } +trunc: + return; +} + + +static void +isis_print_mcid (const struct isis_spb_mcid *mcid) +{ + int i; + + printf( "ID: %d, Name: ", mcid->format_id); + + for(i=0; i<32; i++) + { + printf("%c", mcid->name[i]); + if(mcid->name[i] == '\0') + break; + } + + printf("\n\t Lvl: %d", + EXTRACT_16BITS(mcid->revision_lvl)); + + printf( ", Digest: "); + + for(i=0;i<16;i++) + printf("%.2x ",mcid->digest[i]); +} + +static int +isis_print_mt_port_cap_subtlv (const u_int8_t *tptr, int len) +{ + int stlv_type, stlv_len; + const struct isis_subtlv_spb_mcid *subtlv_spb_mcid; + int i; + + while (len > 0) + { + stlv_type = *(tptr++); + stlv_len = *(tptr++); + + /* first lets see if we know the subTLVs name*/ + printf("\n\t %s subTLV #%u, length: %u", + tok2str(isis_mt_port_cap_subtlv_values, "unknown", stlv_type), + stlv_type, + stlv_len); + + /*len -= TLV_TYPE_LEN_OFFSET;*/ + len = len -2; + + switch (stlv_type) + { + case ISIS_SUBTLV_SPB_MCID: + { + if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN)) + goto trunctlv; + + subtlv_spb_mcid = (struct isis_subtlv_spb_mcid *)tptr; + + printf( "\n\t MCID: "); + isis_print_mcid (&(subtlv_spb_mcid->mcid)); + + /*tptr += SPB_MCID_MIN_LEN; + len -= SPB_MCID_MIN_LEN; */ + + printf( "\n\t AUX-MCID: "); + isis_print_mcid (&(subtlv_spb_mcid->aux_mcid)); + + /*tptr += SPB_MCID_MIN_LEN; + len -= SPB_MCID_MIN_LEN; */ + tptr = tptr + sizeof(struct isis_subtlv_spb_mcid); + len = len - sizeof(struct isis_subtlv_spb_mcid); + + break; + } + + case ISIS_SUBTLV_SPB_DIGEST: + { + if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN)) + goto trunctlv; + + printf ("\n\t RES: %d V: %d A: %d D: %d", + (*(tptr) >> 5), (((*tptr)>> 4) & 0x01), + ((*(tptr) >> 2) & 0x03), ((*tptr) & 0x03)); + + tptr++; + + printf( "\n\t Digest: "); + + for(i=1;i<=8; i++) + { + printf("%08x ", EXTRACT_32BITS(tptr)); + if (i%4 == 0 && i != 8) + printf("\n\t "); + tptr = tptr + 4; + } + + len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN; + + break; + } + + case ISIS_SUBTLV_SPB_BVID: + { + if (!TTEST2(*(tptr), stlv_len)) + goto trunctlv; + + while (len) + { + if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN)) + goto trunctlv; + + printf("\n\t ECT: %08x", + EXTRACT_32BITS(tptr)); + + tptr = tptr+4; + + printf(" BVID: %d, U:%01x M:%01x ", + (EXTRACT_16BITS (tptr) >> 4) , + (EXTRACT_16BITS (tptr) >> 3) & 0x01, + (EXTRACT_16BITS (tptr) >> 2) & 0x01); + + tptr = tptr + 2; + len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN; + } + + break; + } + + default: + break; + } + } + + return 0; + + trunctlv: + printf("\n\t\t packet exceeded snapshot"); + return(1); +} + +static int +isis_print_mt_capability_subtlv (const u_int8_t *tptr, int len) +{ + int stlv_type, stlv_len, tmp; + + while (len > 0) + { + stlv_type = *(tptr++); + stlv_len = *(tptr++); + + /* first lets see if we know the subTLVs name*/ + printf("\n\t %s subTLV #%u, length: %u", + tok2str(isis_mt_capability_subtlv_values, "unknown", stlv_type), + stlv_type, + stlv_len); + + len = len - 2; + + switch (stlv_type) + { + case ISIS_SUBTLV_SPB_INSTANCE: + + if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN)) + goto trunctlv; + + printf("\n\t CIST Root-ID: %08x", EXTRACT_32BITS(tptr)); + tptr = tptr+4; + printf(" %08x", EXTRACT_32BITS(tptr)); + tptr = tptr+4; + printf(", Path Cost: %08x", EXTRACT_32BITS(tptr)); + tptr = tptr+4; + printf(", Prio: %d", EXTRACT_16BITS(tptr)); + tptr = tptr + 2; + printf("\n\t RES: %d", + EXTRACT_16BITS(tptr) >> 5); + printf(", V: %d", + (EXTRACT_16BITS(tptr) >> 4) & 0x0001); + printf(", SPSource-ID: %d", + (EXTRACT_32BITS(tptr) & 0x000fffff)); + tptr = tptr+4; + printf(", No of Trees: %x", *(tptr)); + + tmp = *(tptr++); + + len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN; + + while (tmp) + { + if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN)) + goto trunctlv; + + printf ("\n\t U:%d, M:%d, A:%d, RES:%d", + *(tptr) >> 7, (*(tptr) >> 6) & 0x01, + (*(tptr) >> 5) & 0x01, (*(tptr) & 0x1f)); + + tptr++; + + printf (", ECT: %08x", EXTRACT_32BITS(tptr)); + + tptr = tptr + 4; + + printf (", BVID: %d, SPVID: %d", + (EXTRACT_24BITS(tptr) >> 12) & 0x000fff, + EXTRACT_24BITS(tptr) & 0x000fff); + + tptr = tptr + 3; + len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN; + tmp--; + } + + break; + + case ISIS_SUBTLV_SPBM_SI: + + if (!TTEST2(*(tptr), 6)) + goto trunctlv; + + printf("\n\t BMAC: %08x", EXTRACT_32BITS(tptr)); + tptr = tptr+4; + printf("%04x", EXTRACT_16BITS(tptr)); + tptr = tptr+2; + + printf (", RES: %d, VID: %d", EXTRACT_16BITS(tptr) >> 12, + (EXTRACT_16BITS(tptr)) & 0x0fff); + + tptr = tptr+2; + len = len - 8; + stlv_len = stlv_len - 8; + + while (stlv_len) + { + printf("\n\t T: %d, R: %d, RES: %d, ISID: %d", + (EXTRACT_32BITS(tptr) >> 31), + (EXTRACT_32BITS(tptr) >> 30) & 0x01, + (EXTRACT_32BITS(tptr) >> 24) & 0x03f, + (EXTRACT_32BITS(tptr)) & 0x0ffffff); + + tptr = tptr + 4; + len = len - 4; + stlv_len = stlv_len - 4; + } + + break; + + default: + break; + } + } + return 0; + + trunctlv: + printf("\n\t\t packet exceeded snapshot"); + return(1); +} + + +/* shared routine for printing system, node and lsp-ids */ +static char * +isis_print_id(const u_int8_t *cp, int id_len) +{ + int i; + static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")]; + char *pos = id; + + for (i = 1; i <= SYSTEM_ID_LEN; i++) { + snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++); + pos += strlen(pos); + if (i == 2 || i == 4) + *pos++ = '.'; + } + if (id_len >= NODE_ID_LEN) { + snprintf(pos, sizeof(id) - (pos - id), ".%02x", *cp++); + pos += strlen(pos); + } + if (id_len == LSP_ID_LEN) + snprintf(pos, sizeof(id) - (pos - id), "-%02x", *cp); + return (id); +} + +/* print the 4-byte metric block which is common found in the old-style TLVs */ +static int +isis_print_metric_block (const struct isis_metric_block *isis_metric_block) +{ + printf(", Default Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal"); + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay)) + printf("\n\t\t Delay Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal"); + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense)) + printf("\n\t\t Expense Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal"); + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error)) + printf("\n\t\t Error Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal"); + + return(1); /* everything is ok */ +} + +static int +isis_print_tlv_ip_reach (const u_int8_t *cp, const char *ident, int length) +{ + int prefix_len; + const struct isis_tlv_ip_reach *tlv_ip_reach; + + tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp; + + while (length > 0) { + if ((size_t)length < sizeof(*tlv_ip_reach)) { + printf("short IPv4 Reachability (%d vs %lu)", + length, + (unsigned long)sizeof(*tlv_ip_reach)); + return (0); + } + + if (!TTEST(*tlv_ip_reach)) + return (0); + + prefix_len = mask2plen(EXTRACT_32BITS(tlv_ip_reach->mask)); + + if (prefix_len == -1) + printf("%sIPv4 prefix: %s mask %s", + ident, + ipaddr_string((tlv_ip_reach->prefix)), + ipaddr_string((tlv_ip_reach->mask))); + else + printf("%sIPv4 prefix: %15s/%u", + ident, + ipaddr_string((tlv_ip_reach->prefix)), + prefix_len); + + printf(", Distribution: %s, Metric: %u, %s", + ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up", + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal"); + + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay)) + printf("%s Delay Metric: %u, %s", + ident, + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal"); + + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense)) + printf("%s Expense Metric: %u, %s", + ident, + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal"); + + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error)) + printf("%s Error Metric: %u, %s", + ident, + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal"); + + length -= sizeof(struct isis_tlv_ip_reach); + tlv_ip_reach++; + } + return (1); +} + +/* + * this is the common IP-REACH subTLV decoder it is called + * from various EXTD-IP REACH TLVs (135,235,236,237) + */ + +static int +isis_print_ip_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) { + + /* first lets see if we know the subTLVs name*/ + printf("%s%s subTLV #%u, length: %u", + ident, + tok2str(isis_ext_ip_reach_subtlv_values, + "unknown", + subt), + subt, + subl); + + if (!TTEST2(*tptr,subl)) + goto trunctlv; + + switch(subt) { + case ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR: /* fall through */ + case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32: + while (subl >= 4) { + printf(", 0x%08x (=%u)", + EXTRACT_32BITS(tptr), + EXTRACT_32BITS(tptr)); + tptr+=4; + subl-=4; + } + break; + case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64: + while (subl >= 8) { + printf(", 0x%08x%08x", + EXTRACT_32BITS(tptr), + EXTRACT_32BITS(tptr+4)); + tptr+=8; + subl-=8; + } + break; + default: + if(!print_unknown_data(tptr,"\n\t\t ", + subl)) + return(0); + break; + } + return(1); + +trunctlv: + printf("%spacket exceeded snapshot",ident); + return(0); +} + +/* + * this is the common IS-REACH subTLV decoder it is called + * from isis_print_ext_is_reach() + */ + +static int +isis_print_is_reach_subtlv (const u_int8_t *tptr,u_int subt,u_int subl,const char *ident) { + + u_int te_class,priority_level,gmpls_switch_cap; + union { /* int to float conversion buffer for several subTLVs */ + float f; + u_int32_t i; + } bw; + + /* first lets see if we know the subTLVs name*/ + printf("%s%s subTLV #%u, length: %u", + ident, + tok2str(isis_ext_is_reach_subtlv_values, + "unknown", + subt), + subt, + subl); + + if (!TTEST2(*tptr,subl)) + goto trunctlv; + + switch(subt) { + case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP: + case ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID: + case ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID: + if (subl >= 4) { + printf(", 0x%08x", EXTRACT_32BITS(tptr)); + if (subl == 8) /* rfc4205 */ + printf(", 0x%08x", EXTRACT_32BITS(tptr+4)); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: + case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: + if (subl >= sizeof(struct in_addr)) + printf(", %s", ipaddr_string(tptr)); + break; + case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW : + case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW: + if (subl >= 4) { + bw.i = EXTRACT_32BITS(tptr); + printf(", %.3f Mbps", bw.f*8/1000000 ); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW : + if (subl >= 32) { + for (te_class = 0; te_class < 8; te_class++) { + bw.i = EXTRACT_32BITS(tptr); + printf("%s TE-Class %u: %.3f Mbps", + ident, + te_class, + bw.f*8/1000000 ); + tptr+=4; + } + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */ + case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD: + printf("%sBandwidth Constraints Model ID: %s (%u)", + ident, + tok2str(diffserv_te_bc_values, "unknown", *tptr), + *tptr); + tptr++; + /* decode BCs until the subTLV ends */ + for (te_class = 0; te_class < (subl-1)/4; te_class++) { + bw.i = EXTRACT_32BITS(tptr); + printf("%s Bandwidth constraint CT%u: %.3f Mbps", + ident, + te_class, + bw.f*8/1000000 ); + tptr+=4; + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC: + if (subl >= 3) + printf(", %u", EXTRACT_24BITS(tptr)); + break; + case ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE: + if (subl == 2) { + printf(", [ %s ] (0x%04x)", + bittok2str(isis_subtlv_link_attribute_values, + "Unknown", + EXTRACT_16BITS(tptr)), + EXTRACT_16BITS(tptr)); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE: + if (subl >= 2) { + printf(", %s, Priority %u", + bittok2str(gmpls_link_prot_values, "none", *tptr), + *(tptr+1)); + } + break; + case ISIS_SUBTLV_SPB_METRIC: + if (subl >= 6) { + printf (", LM: %u", EXTRACT_24BITS(tptr)); + tptr=tptr+3; + printf (", P: %u", *(tptr)); + printf (", P-ID: %u", EXTRACT_16BITS(++tptr)); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR: + if (subl >= 36) { + gmpls_switch_cap = *tptr; + printf("%s Interface Switching Capability:%s", + ident, + tok2str(gmpls_switch_cap_values, "Unknown", gmpls_switch_cap)); + printf(", LSP Encoding: %s", + tok2str(gmpls_encoding_values, "Unknown", *(tptr+1))); + tptr+=4; + printf("%s Max LSP Bandwidth:",ident); + for (priority_level = 0; priority_level < 8; priority_level++) { + bw.i = EXTRACT_32BITS(tptr); + printf("%s priority level %d: %.3f Mbps", + ident, + priority_level, + bw.f*8/1000000 ); + tptr+=4; + } + subl-=36; + switch (gmpls_switch_cap) { + case GMPLS_PSC1: + case GMPLS_PSC2: + case GMPLS_PSC3: + case GMPLS_PSC4: + bw.i = EXTRACT_32BITS(tptr); + printf("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f*8/1000000); + printf("%s Interface MTU: %u", ident, EXTRACT_16BITS(tptr+4)); + break; + case GMPLS_TSC: + bw.i = EXTRACT_32BITS(tptr); + printf("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f*8/1000000); + printf("%s Indication %s", ident, + tok2str(gmpls_switch_cap_tsc_indication_values, "Unknown (%u)", *(tptr+4))); + break; + default: + /* there is some optional stuff left to decode but this is as of yet + not specified so just lets hexdump what is left */ + if(subl>0){ + if(!print_unknown_data(tptr,"\n\t\t ", + subl)) + return(0); + } + } + } + break; + default: + if(!print_unknown_data(tptr,"\n\t\t ", + subl)) + return(0); + break; + } + return(1); + +trunctlv: + printf("%spacket exceeded snapshot",ident); + return(0); +} + + +/* + * this is the common IS-REACH decoder it is called + * from various EXTD-IS REACH style TLVs (22,24,222) + */ + +static int +isis_print_ext_is_reach (const u_int8_t *tptr,const char *ident, int tlv_type) { + + char ident_buffer[20]; + int subtlv_type,subtlv_len,subtlv_sum_len; + int proc_bytes = 0; /* how many bytes did we process ? */ + + if (!TTEST2(*tptr, NODE_ID_LEN)) + return(0); + + printf("%sIS Neighbor: %s", ident, isis_print_id(tptr, NODE_ID_LEN)); + tptr+=(NODE_ID_LEN); + + if (tlv_type != ISIS_TLV_IS_ALIAS_ID) { /* the Alias TLV Metric field is implicit 0 */ + if (!TTEST2(*tptr, 3)) /* and is therefore skipped */ + return(0); + printf(", Metric: %d",EXTRACT_24BITS(tptr)); + tptr+=3; + } + + if (!TTEST2(*tptr, 1)) + return(0); + subtlv_sum_len=*(tptr++); /* read out subTLV length */ + proc_bytes=NODE_ID_LEN+3+1; + printf(", %ssub-TLVs present",subtlv_sum_len ? "" : "no "); + if (subtlv_sum_len) { + printf(" (%u)",subtlv_sum_len); + while (subtlv_sum_len>0) { + if (!TTEST2(*tptr,2)) + return(0); + subtlv_type=*(tptr++); + subtlv_len=*(tptr++); + /* prepend the ident string */ + snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); + if(!isis_print_is_reach_subtlv(tptr,subtlv_type,subtlv_len,ident_buffer)) + return(0); + tptr+=subtlv_len; + subtlv_sum_len-=(subtlv_len+2); + proc_bytes+=(subtlv_len+2); + } + } + return(proc_bytes); +} + +/* + * this is the common Multi Topology ID decoder + * it is called from various MT-TLVs (222,229,235,237) + */ + +static int +isis_print_mtid (const u_int8_t *tptr,const char *ident) { + + if (!TTEST2(*tptr, 2)) + return(0); + + printf("%s%s", + ident, + tok2str(isis_mt_values, + "Reserved for IETF Consensus", + ISIS_MASK_MTID(EXTRACT_16BITS(tptr)))); + + printf(" Topology (0x%03x), Flags: [%s]", + ISIS_MASK_MTID(EXTRACT_16BITS(tptr)), + bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(EXTRACT_16BITS(tptr)))); + + return(2); +} + +/* + * this is the common extended IP reach decoder + * it is called from TLVs (135,235,236,237) + * we process the TLV and optional subTLVs and return + * the amount of processed bytes + */ + +static int +isis_print_extd_ip_reach (const u_int8_t *tptr, const char *ident, u_int16_t afi) { + + char ident_buffer[20]; +#ifdef INET6 + u_int8_t prefix[sizeof(struct in6_addr)]; /* shared copy buffer for IPv4 and IPv6 prefixes */ +#else + u_int8_t prefix[sizeof(struct in_addr)]; /* shared copy buffer for IPv4 prefixes */ +#endif + u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen; + + if (!TTEST2(*tptr, 4)) + return (0); + metric = EXTRACT_32BITS(tptr); + processed=4; + tptr+=4; + + if (afi == AF_INET) { + if (!TTEST2(*tptr, 1)) /* fetch status byte */ + return (0); + status_byte=*(tptr++); + bit_length = status_byte&0x3f; + if (bit_length > 32) { + printf("%sIPv4 prefix: bad bit length %u", + ident, + bit_length); + return (0); + } + processed++; +#ifdef INET6 + } else if (afi == AF_INET6) { + if (!TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */ + return (0); + status_byte=*(tptr++); + bit_length=*(tptr++); + if (bit_length > 128) { + printf("%sIPv6 prefix: bad bit length %u", + ident, + bit_length); + return (0); + } + processed+=2; +#endif + } else + return (0); /* somebody is fooling us */ + + byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */ + + if (!TTEST2(*tptr, byte_length)) + return (0); + memset(prefix, 0, sizeof prefix); /* clear the copy buffer */ + memcpy(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */ + tptr+=byte_length; + processed+=byte_length; + + if (afi == AF_INET) + printf("%sIPv4 prefix: %15s/%u", + ident, + ipaddr_string(prefix), + bit_length); +#ifdef INET6 + if (afi == AF_INET6) + printf("%sIPv6 prefix: %s/%u", + ident, + ip6addr_string(prefix), + bit_length); +#endif + + printf(", Distribution: %s, Metric: %u", + ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up", + metric); + + if (afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) + printf(", sub-TLVs present"); +#ifdef INET6 + if (afi == AF_INET6) + printf(", %s%s", + ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal", + ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : ""); +#endif + + if ((afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) +#ifdef INET6 + || (afi == AF_INET6 && ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte)) +#endif + ) { + /* assume that one prefix can hold more + than one subTLV - therefore the first byte must reflect + the aggregate bytecount of the subTLVs for this prefix + */ + if (!TTEST2(*tptr, 1)) + return (0); + sublen=*(tptr++); + processed+=sublen+1; + printf(" (%u)",sublen); /* print out subTLV length */ + + while (sublen>0) { + if (!TTEST2(*tptr,2)) + return (0); + subtlvtype=*(tptr++); + subtlvlen=*(tptr++); + /* prepend the ident string */ + snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); + if(!isis_print_ip_reach_subtlv(tptr,subtlvtype,subtlvlen,ident_buffer)) + return(0); + tptr+=subtlvlen; + sublen-=(subtlvlen+2); + } + } + return (processed); +} + +/* + * isis_print + * Decode IS-IS packets. Return 0 on error. + */ + +static int isis_print (const u_int8_t *p, u_int length) +{ + const struct isis_common_header *isis_header; + + const struct isis_iih_lan_header *header_iih_lan; + const struct isis_iih_ptp_header *header_iih_ptp; + struct isis_lsp_header *header_lsp; + const struct isis_csnp_header *header_csnp; + const struct isis_psnp_header *header_psnp; + + const struct isis_tlv_lsp *tlv_lsp; + const struct isis_tlv_ptp_adj *tlv_ptp_adj; + const struct isis_tlv_is_reach *tlv_is_reach; + const struct isis_tlv_es_reach *tlv_es_reach; + + u_int8_t pdu_type, max_area, id_length, tlv_type, tlv_len, tmp, alen, lan_alen, prefix_len; + u_int8_t ext_is_len, ext_ip_len, mt_len; + const u_int8_t *optr, *pptr, *tptr; + u_short packet_len,pdu_len, key_id; + u_int i,vendor_id; + int sigcheck; + + packet_len=length; + optr = p; /* initialize the _o_riginal pointer to the packet start - + need it for parsing the checksum TLV and authentication + TLV verification */ + isis_header = (const struct isis_common_header *)p; + TCHECK(*isis_header); + pptr = p+(ISIS_COMMON_HEADER_SIZE); + header_iih_lan = (const struct isis_iih_lan_header *)pptr; + header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; + header_lsp = (struct isis_lsp_header *)pptr; + header_csnp = (const struct isis_csnp_header *)pptr; + header_psnp = (const struct isis_psnp_header *)pptr; + + if (!eflag) + printf("IS-IS"); + + /* + * Sanity checking of the header. + */ + + if (isis_header->version != ISIS_VERSION) { + printf("version %d packet not supported", isis_header->version); + return (0); + } + + if ((isis_header->id_length != SYSTEM_ID_LEN) && (isis_header->id_length != 0)) { + printf("system ID length of %d is not supported", + isis_header->id_length); + return (0); + } + + if (isis_header->pdu_version != ISIS_VERSION) { + printf("version %d packet not supported", isis_header->pdu_version); + return (0); + } + + max_area = isis_header->max_area; + switch(max_area) { + case 0: + max_area = 3; /* silly shit */ + break; + case 255: + printf("bad packet -- 255 areas"); + return (0); + default: + break; + } + + id_length = isis_header->id_length; + switch(id_length) { + case 0: + id_length = 6; /* silly shit again */ + break; + case 1: /* 1-8 are valid sys-ID lenghts */ + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + break; + case 255: + id_length = 0; /* entirely useless */ + break; + default: + break; + } + + /* toss any non 6-byte sys-ID len PDUs */ + if (id_length != 6 ) { + printf("bad packet -- illegal sys-ID length (%u)", id_length); + return (0); + } + + pdu_type=isis_header->pdu_type; + + /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/ + if (vflag < 1) { + printf("%s%s", + eflag ? "" : ", ", + tok2str(isis_pdu_values,"unknown PDU-Type %u",pdu_type)); + + switch (pdu_type) { + + case ISIS_PDU_L1_LAN_IIH: + case ISIS_PDU_L2_LAN_IIH: + printf(", src-id %s", + isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN)); + printf(", lan-id %s, prio %u", + isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN), + header_iih_lan->priority); + break; + case ISIS_PDU_PTP_IIH: + printf(", src-id %s", isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN)); + break; + case ISIS_PDU_L1_LSP: + case ISIS_PDU_L2_LSP: + printf(", lsp-id %s, seq 0x%08x, lifetime %5us", + isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), + EXTRACT_32BITS(header_lsp->sequence_number), + EXTRACT_16BITS(header_lsp->remaining_lifetime)); + break; + case ISIS_PDU_L1_CSNP: + case ISIS_PDU_L2_CSNP: + printf(", src-id %s", isis_print_id(header_csnp->source_id,NODE_ID_LEN)); + break; + case ISIS_PDU_L1_PSNP: + case ISIS_PDU_L2_PSNP: + printf(", src-id %s", isis_print_id(header_psnp->source_id,NODE_ID_LEN)); + break; + + } + printf(", length %u", length); + + return(1); + } + + /* ok they seem to want to know everything - lets fully decode it */ + printf("%slength %u", eflag ? "" : ", ",length); + + printf("\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)", + tok2str(isis_pdu_values, + "unknown, type %u", + pdu_type), + isis_header->fixed_len, + isis_header->version, + isis_header->pdu_version, + id_length, + isis_header->id_length, + max_area, + isis_header->max_area); + + if (vflag > 1) { + if(!print_unknown_data(optr,"\n\t",8)) /* provide the _o_riginal pointer */ + return(0); /* for optionally debugging the common header */ + } + + switch (pdu_type) { + + case ISIS_PDU_L1_LAN_IIH: + case ISIS_PDU_L2_LAN_IIH: + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { + printf(", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE); + return (0); + } + + pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } + + TCHECK(*header_iih_lan); + printf("\n\t source-id: %s, holding time: %us, Flags: [%s]", + isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN), + EXTRACT_16BITS(header_iih_lan->holding_time), + tok2str(isis_iih_circuit_type_values, + "unknown circuit type 0x%02x", + header_iih_lan->circuit_type)); + + printf("\n\t lan-id: %s, Priority: %u, PDU length: %u", + isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN), + (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK, + pdu_len); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_LAN_HEADER_SIZE)) + return(0); + } + + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); + break; + + case ISIS_PDU_PTP_IIH: + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { + printf(", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE); + return (0); + } + + pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } + + TCHECK(*header_iih_ptp); + printf("\n\t source-id: %s, holding time: %us, Flags: [%s]", + isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN), + EXTRACT_16BITS(header_iih_ptp->holding_time), + tok2str(isis_iih_circuit_type_values, + "unknown circuit type 0x%02x", + header_iih_ptp->circuit_type)); + + printf("\n\t circuit-id: 0x%02x, PDU length: %u", + header_iih_ptp->circuit_id, + pdu_len); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_PTP_HEADER_SIZE)) + return(0); + } + + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); + break; + + case ISIS_PDU_L1_LSP: + case ISIS_PDU_L2_LSP: + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { + printf(", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE); + return (0); + } + + pdu_len=EXTRACT_16BITS(header_lsp->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } + + TCHECK(*header_lsp); + printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x", + isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), + EXTRACT_32BITS(header_lsp->sequence_number), + EXTRACT_16BITS(header_lsp->remaining_lifetime), + EXTRACT_16BITS(header_lsp->checksum)); + + + osi_print_cksum((u_int8_t *)header_lsp->lsp_id, + EXTRACT_16BITS(header_lsp->checksum), 12, length-12); + + /* + * Clear checksum and lifetime prior to signature verification. + */ + header_lsp->checksum[0] = 0; + header_lsp->checksum[1] = 0; + header_lsp->remaining_lifetime[0] = 0; + header_lsp->remaining_lifetime[1] = 0; + + + printf(", PDU length: %u, Flags: [ %s", + pdu_len, + ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); + + if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { + printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""); + printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""); + printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""); + printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""); + printf("ATT bit set, "); + } + printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""); + printf("%s ]", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_LSP_HEADER_SIZE)) + return(0); + } + + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); + break; + + case ISIS_PDU_L1_CSNP: + case ISIS_PDU_L2_CSNP: + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { + printf(", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE); + return (0); + } + + pdu_len=EXTRACT_16BITS(header_csnp->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } + + TCHECK(*header_csnp); + printf("\n\t source-id: %s, PDU length: %u", + isis_print_id(header_csnp->source_id, NODE_ID_LEN), + pdu_len); + printf("\n\t start lsp-id: %s", + isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN)); + printf("\n\t end lsp-id: %s", + isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN)); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_CSNP_HEADER_SIZE)) + return(0); + } + + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); + break; + + case ISIS_PDU_L1_PSNP: + case ISIS_PDU_L2_PSNP: + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { + printf("- bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE); + return (0); + } + + pdu_len=EXTRACT_16BITS(header_psnp->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } + + TCHECK(*header_psnp); + printf("\n\t source-id: %s, PDU length: %u", + isis_print_id(header_psnp->source_id, NODE_ID_LEN), + pdu_len); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_PSNP_HEADER_SIZE)) + return(0); + } + + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); + break; + + default: + if(!print_unknown_data(pptr,"\n\t ",length)) + return(0); + return (0); + } + + /* + * Now print the TLV's. + */ + + while (packet_len >= 2) { + if (pptr == snapend) { + return (1); + } + + if (!TTEST2(*pptr, 2)) { + printf("\n\t\t packet exceeded snapshot (%ld) bytes", + (long)(pptr-snapend)); + return (1); + } + tlv_type = *pptr++; + tlv_len = *pptr++; + tmp =tlv_len; /* copy temporary len & pointer to packet data */ + tptr = pptr; + packet_len -= 2; + if (tlv_len > packet_len) { + break; + } + + /* first lets see if we know the TLVs name*/ + printf("\n\t %s TLV #%u, length: %u", + tok2str(isis_tlv_values, + "unknown", + tlv_type), + tlv_type, + tlv_len); + + if (tlv_len == 0) /* something is malformed */ + continue; + + /* now check if we have a decoder otherwise do a hexdump at the end*/ + switch (tlv_type) { + case ISIS_TLV_AREA_ADDR: + if (!TTEST2(*tptr, 1)) + goto trunctlv; + alen = *tptr++; + while (tmp && alen < tmp) { + printf("\n\t Area address (length: %u): %s", + alen, + isonsap_string(tptr,alen)); + tptr += alen; + tmp -= alen + 1; + if (tmp==0) /* if this is the last area address do not attemt a boundary check */ + break; + if (!TTEST2(*tptr, 1)) + goto trunctlv; + alen = *tptr++; + } + break; + case ISIS_TLV_ISNEIGH: + while (tmp >= ETHER_ADDR_LEN) { + if (!TTEST2(*tptr, ETHER_ADDR_LEN)) + goto trunctlv; + printf("\n\t SNPA: %s",isis_print_id(tptr,ETHER_ADDR_LEN)); + tmp -= ETHER_ADDR_LEN; + tptr += ETHER_ADDR_LEN; + } + break; + + case ISIS_TLV_ISNEIGH_VARLEN: + if (!TTEST2(*tptr, 1) || tmp < 3) /* min. TLV length */ + goto trunctlv; + lan_alen = *tptr++; /* LAN address length */ + if (lan_alen == 0) { + printf("\n\t LAN address length 0 bytes (invalid)"); + break; + } + tmp --; + printf("\n\t LAN address length %u bytes ",lan_alen); + while (tmp >= lan_alen) { + if (!TTEST2(*tptr, lan_alen)) + goto trunctlv; + printf("\n\t\tIS Neighbor: %s",isis_print_id(tptr,lan_alen)); + tmp -= lan_alen; + tptr +=lan_alen; + } + break; + + case ISIS_TLV_PADDING: + break; + + case ISIS_TLV_MT_IS_REACH: + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=mt_len; + tmp-=mt_len; + while (tmp >= 2+NODE_ID_LEN+3+1) { + ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); + if (ext_is_len == 0) /* did something go wrong ? */ + goto trunctlv; + + tmp-=ext_is_len; + tptr+=ext_is_len; + } + break; + + case ISIS_TLV_IS_ALIAS_ID: + while (tmp >= NODE_ID_LEN+1) { /* is it worth attempting a decode ? */ + ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); + if (ext_is_len == 0) /* did something go wrong ? */ + goto trunctlv; + tmp-=ext_is_len; + tptr+=ext_is_len; + } + break; + + case ISIS_TLV_EXT_IS_REACH: + while (tmp >= NODE_ID_LEN+3+1) { /* is it worth attempting a decode ? */ + ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); + if (ext_is_len == 0) /* did something go wrong ? */ + goto trunctlv; + tmp-=ext_is_len; + tptr+=ext_is_len; + } + break; + case ISIS_TLV_IS_REACH: + if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */ + goto trunctlv; + printf("\n\t %s", + tok2str(isis_is_reach_virtual_values, + "bogus virtual flag 0x%02x", + *tptr++)); + tlv_is_reach = (const struct isis_tlv_is_reach *)tptr; + while (tmp >= sizeof(struct isis_tlv_is_reach)) { + if (!TTEST(*tlv_is_reach)) + goto trunctlv; + printf("\n\t IS Neighbor: %s", + isis_print_id(tlv_is_reach->neighbor_nodeid, NODE_ID_LEN)); + isis_print_metric_block(&tlv_is_reach->isis_metric_block); + tmp -= sizeof(struct isis_tlv_is_reach); + tlv_is_reach++; + } + break; + + case ISIS_TLV_ESNEIGH: + tlv_es_reach = (const struct isis_tlv_es_reach *)tptr; + while (tmp >= sizeof(struct isis_tlv_es_reach)) { + if (!TTEST(*tlv_es_reach)) + goto trunctlv; + printf("\n\t ES Neighbor: %s", + isis_print_id(tlv_es_reach->neighbor_sysid,SYSTEM_ID_LEN)); + isis_print_metric_block(&tlv_es_reach->isis_metric_block); + tmp -= sizeof(struct isis_tlv_es_reach); + tlv_es_reach++; + } + break; + + /* those two TLVs share the same format */ + case ISIS_TLV_INT_IP_REACH: + case ISIS_TLV_EXT_IP_REACH: + if (!isis_print_tlv_ip_reach(pptr, "\n\t ", tlv_len)) + return (1); + break; + + case ISIS_TLV_EXTD_IP_REACH: + while (tmp>0) { + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; + } + break; + + case ISIS_TLV_MT_IP_REACH: + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) { /* did something go wrong ? */ + goto trunctlv; + } + tptr+=mt_len; + tmp-=mt_len; + + while (tmp>0) { + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; + } + break; + +#ifdef INET6 + case ISIS_TLV_IP6_REACH: + while (tmp>0) { + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET6); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; + } + break; + + case ISIS_TLV_MT_IP6_REACH: + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) { /* did something go wrong ? */ + goto trunctlv; + } + tptr+=mt_len; + tmp-=mt_len; + + while (tmp>0) { + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET6); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; + } + break; + + case ISIS_TLV_IP6ADDR: + while (tmp>=sizeof(struct in6_addr)) { + if (!TTEST2(*tptr, sizeof(struct in6_addr))) + goto trunctlv; + + printf("\n\t IPv6 interface address: %s", + ip6addr_string(tptr)); + + tptr += sizeof(struct in6_addr); + tmp -= sizeof(struct in6_addr); + } + break; +#endif + case ISIS_TLV_AUTH: + if (!TTEST2(*tptr, 1)) + goto trunctlv; + + printf("\n\t %s: ", + tok2str(isis_subtlv_auth_values, + "unknown Authentication type 0x%02x", + *tptr)); + + switch (*tptr) { + case ISIS_SUBTLV_AUTH_SIMPLE: + for(i=1;i<tlv_len;i++) { + if (!TTEST2(*(tptr+i), 1)) + goto trunctlv; + printf("%c",*(tptr+i)); + } + break; + case ISIS_SUBTLV_AUTH_MD5: + for(i=1;i<tlv_len;i++) { + if (!TTEST2(*(tptr+i), 1)) + goto trunctlv; + printf("%02x",*(tptr+i)); + } + if (tlv_len != ISIS_SUBTLV_AUTH_MD5_LEN+1) + printf(", (malformed subTLV) "); + +#ifdef HAVE_LIBCRYPTO + sigcheck = signature_verify(optr, length, + (unsigned char *)tptr + 1); +#else + sigcheck = CANT_CHECK_SIGNATURE; +#endif + printf(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck)); + + break; + case ISIS_SUBTLV_AUTH_GENERIC: + key_id = EXTRACT_16BITS((tptr+1)); + printf("%u, password: ", key_id); + for(i=1 + sizeof(u_int16_t);i<tlv_len;i++) { + if (!TTEST2(*(tptr+i), 1)) + goto trunctlv; + printf("%02x",*(tptr+i)); + } + break; + case ISIS_SUBTLV_AUTH_PRIVATE: + default: + if(!print_unknown_data(tptr+1,"\n\t\t ",tlv_len-1)) + return(0); + break; + } + break; + + case ISIS_TLV_PTP_ADJ: + tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr; + if(tmp>=1) { + if (!TTEST2(*tptr, 1)) + goto trunctlv; + printf("\n\t Adjacency State: %s (%u)", + tok2str(isis_ptp_adjancey_values, "unknown", *tptr), + *tptr); + tmp--; + } + if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) { + if (!TTEST2(tlv_ptp_adj->extd_local_circuit_id, + sizeof(tlv_ptp_adj->extd_local_circuit_id))) + goto trunctlv; + printf("\n\t Extended Local circuit-ID: 0x%08x", + EXTRACT_32BITS(tlv_ptp_adj->extd_local_circuit_id)); + tmp-=sizeof(tlv_ptp_adj->extd_local_circuit_id); + } + if(tmp>=SYSTEM_ID_LEN) { + if (!TTEST2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN)) + goto trunctlv; + printf("\n\t Neighbor System-ID: %s", + isis_print_id(tlv_ptp_adj->neighbor_sysid,SYSTEM_ID_LEN)); + tmp-=SYSTEM_ID_LEN; + } + if(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) { + if (!TTEST2(tlv_ptp_adj->neighbor_extd_local_circuit_id, + sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id))) + goto trunctlv; + printf("\n\t Neighbor Extended Local circuit-ID: 0x%08x", + EXTRACT_32BITS(tlv_ptp_adj->neighbor_extd_local_circuit_id)); + } + break; + + case ISIS_TLV_PROTOCOLS: + printf("\n\t NLPID(s): "); + while (tmp>0) { + if (!TTEST2(*(tptr), 1)) + goto trunctlv; + printf("%s (0x%02x)", + tok2str(nlpid_values, + "unknown", + *tptr), + *tptr); + if (tmp>1) /* further NPLIDs ? - put comma */ + printf(", "); + tptr++; + tmp--; + } + break; + + case ISIS_TLV_MT_PORT_CAP: + { + if (!TTEST2(*(tptr), 2)) + goto trunctlv; + + printf("\n\t RES: %d, MTID(s): %d", + (EXTRACT_16BITS (tptr) >> 12), + (EXTRACT_16BITS (tptr) & 0x0fff)); + + tmp = tmp-2; + tptr = tptr+2; + + if (tmp) + isis_print_mt_port_cap_subtlv (tptr, tmp); + + break; + } + + case ISIS_TLV_MT_CAPABILITY: + + if (!TTEST2(*(tptr), 2)) + goto trunctlv; + + printf("\n\t O: %d, RES: %d, MTID(s): %d", + (EXTRACT_16BITS(tptr) >> 15) & 0x01, + (EXTRACT_16BITS(tptr) >> 12) & 0x07, + EXTRACT_16BITS(tptr) & 0x0fff); + + tmp = tmp-2; + tptr = tptr+2; + + if (tmp) + isis_print_mt_capability_subtlv (tptr, tmp); + + break; + + case ISIS_TLV_TE_ROUTER_ID: + if (!TTEST2(*pptr, sizeof(struct in_addr))) + goto trunctlv; + printf("\n\t Traffic Engineering Router ID: %s", ipaddr_string(pptr)); + break; + + case ISIS_TLV_IPADDR: + while (tmp>=sizeof(struct in_addr)) { + if (!TTEST2(*tptr, sizeof(struct in_addr))) + goto trunctlv; + printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr)); + tptr += sizeof(struct in_addr); + tmp -= sizeof(struct in_addr); + } + break; + + case ISIS_TLV_HOSTNAME: + printf("\n\t Hostname: "); + while (tmp>0) { + if (!TTEST2(*tptr, 1)) + goto trunctlv; + printf("%c",*tptr++); + tmp--; + } + break; + + case ISIS_TLV_SHARED_RISK_GROUP: + if (tmp < NODE_ID_LEN) + break; + if (!TTEST2(*tptr, NODE_ID_LEN)) + goto trunctlv; + printf("\n\t IS Neighbor: %s", isis_print_id(tptr, NODE_ID_LEN)); + tptr+=(NODE_ID_LEN); + tmp-=(NODE_ID_LEN); + + if (tmp < 1) + break; + if (!TTEST2(*tptr, 1)) + goto trunctlv; + printf(", Flags: [%s]", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered"); + tmp--; + + if (tmp < sizeof(struct in_addr)) + break; + if (!TTEST2(*tptr,sizeof(struct in_addr))) + goto trunctlv; + printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr)); + tptr+=sizeof(struct in_addr); + tmp-=sizeof(struct in_addr); + + if (tmp < sizeof(struct in_addr)) + break; + if (!TTEST2(*tptr,sizeof(struct in_addr))) + goto trunctlv; + printf("\n\t IPv4 neighbor address: %s", ipaddr_string(tptr)); + tptr+=sizeof(struct in_addr); + tmp-=sizeof(struct in_addr); + + while (tmp>=4) { + if (!TTEST2(*tptr, 4)) + goto trunctlv; + printf("\n\t Link-ID: 0x%08x", EXTRACT_32BITS(tptr)); + tptr+=4; + tmp-=4; + } + break; + + case ISIS_TLV_LSP: + tlv_lsp = (const struct isis_tlv_lsp *)tptr; + while(tmp>=sizeof(struct isis_tlv_lsp)) { + if (!TTEST((tlv_lsp->lsp_id)[LSP_ID_LEN-1])) + goto trunctlv; + printf("\n\t lsp-id: %s", + isis_print_id(tlv_lsp->lsp_id, LSP_ID_LEN)); + if (!TTEST2(tlv_lsp->sequence_number, 4)) + goto trunctlv; + printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number)); + if (!TTEST2(tlv_lsp->remaining_lifetime, 2)) + goto trunctlv; + printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime)); + if (!TTEST2(tlv_lsp->checksum, 2)) + goto trunctlv; + printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum)); + tmp-=sizeof(struct isis_tlv_lsp); + tlv_lsp++; + } + break; + + case ISIS_TLV_CHECKSUM: + if (tmp < ISIS_TLV_CHECKSUM_MINLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_CHECKSUM_MINLEN)) + goto trunctlv; + printf("\n\t checksum: 0x%04x ", EXTRACT_16BITS(tptr)); + /* do not attempt to verify the checksum if it is zero + * most likely a HMAC-MD5 TLV is also present and + * to avoid conflicts the checksum TLV is zeroed. + * see rfc3358 for details + */ + osi_print_cksum(optr, EXTRACT_16BITS(tptr), tptr-optr, length); + break; + + case ISIS_TLV_MT_SUPPORTED: + if (tmp < ISIS_TLV_MT_SUPPORTED_MINLEN) + break; + while (tmp>1) { + /* length can only be a multiple of 2, otherwise there is + something broken -> so decode down until length is 1 */ + if (tmp!=1) { + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=mt_len; + tmp-=mt_len; + } else { + printf("\n\t malformed MT-ID"); + break; + } + } + break; + + case ISIS_TLV_RESTART_SIGNALING: + /* first attempt to decode the flags */ + if (tmp < ISIS_TLV_RESTART_SIGNALING_FLAGLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN)) + goto trunctlv; + printf("\n\t Flags [%s]", + bittok2str(isis_restart_flag_values, "none", *tptr)); + tptr+=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; + tmp-=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; + + /* is there anything other than the flags field? */ + if (tmp == 0) + break; + + if (tmp < ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN)) + goto trunctlv; + + printf(", Remaining holding time %us", EXTRACT_16BITS(tptr)); + tptr+=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; + tmp-=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; + + /* is there an additional sysid field present ?*/ + if (tmp == SYSTEM_ID_LEN) { + if (!TTEST2(*tptr, SYSTEM_ID_LEN)) + goto trunctlv; + printf(", for %s",isis_print_id(tptr,SYSTEM_ID_LEN)); + } + break; + + case ISIS_TLV_IDRP_INFO: + if (tmp < ISIS_TLV_IDRP_INFO_MINLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_IDRP_INFO_MINLEN)) + goto trunctlv; + printf("\n\t Inter-Domain Information Type: %s", + tok2str(isis_subtlv_idrp_values, + "Unknown (0x%02x)", + *tptr)); + switch (*tptr++) { + case ISIS_SUBTLV_IDRP_ASN: + if (!TTEST2(*tptr, 2)) /* fetch AS number */ + goto trunctlv; + printf("AS Number: %u",EXTRACT_16BITS(tptr)); + break; + case ISIS_SUBTLV_IDRP_LOCAL: + case ISIS_SUBTLV_IDRP_RES: + default: + if(!print_unknown_data(tptr,"\n\t ",tlv_len-1)) + return(0); + break; + } + break; + + case ISIS_TLV_LSP_BUFFERSIZE: + if (tmp < ISIS_TLV_LSP_BUFFERSIZE_MINLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_LSP_BUFFERSIZE_MINLEN)) + goto trunctlv; + printf("\n\t LSP Buffersize: %u",EXTRACT_16BITS(tptr)); + break; + + case ISIS_TLV_PART_DIS: + while (tmp >= SYSTEM_ID_LEN) { + if (!TTEST2(*tptr, SYSTEM_ID_LEN)) + goto trunctlv; + printf("\n\t %s",isis_print_id(tptr,SYSTEM_ID_LEN)); + tptr+=SYSTEM_ID_LEN; + tmp-=SYSTEM_ID_LEN; + } + break; + + case ISIS_TLV_PREFIX_NEIGH: + if (tmp < sizeof(struct isis_metric_block)) + break; + if (!TTEST2(*tptr, sizeof(struct isis_metric_block))) + goto trunctlv; + printf("\n\t Metric Block"); + isis_print_metric_block((const struct isis_metric_block *)tptr); + tptr+=sizeof(struct isis_metric_block); + tmp-=sizeof(struct isis_metric_block); + + while(tmp>0) { + if (!TTEST2(*tptr, 1)) + goto trunctlv; + prefix_len=*tptr++; /* read out prefix length in semioctets*/ + if (prefix_len < 2) { + printf("\n\t\tAddress: prefix length %u < 2", prefix_len); + break; + } + tmp--; + if (tmp < prefix_len/2) + break; + if (!TTEST2(*tptr, prefix_len/2)) + goto trunctlv; + printf("\n\t\tAddress: %s/%u", + isonsap_string(tptr,prefix_len/2), + prefix_len*4); + tptr+=prefix_len/2; + tmp-=prefix_len/2; + } + break; + + case ISIS_TLV_IIH_SEQNR: + if (tmp < ISIS_TLV_IIH_SEQNR_MINLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_IIH_SEQNR_MINLEN)) /* check if four bytes are on the wire */ + goto trunctlv; + printf("\n\t Sequence number: %u", EXTRACT_32BITS(tptr) ); + break; + + case ISIS_TLV_VENDOR_PRIVATE: + if (tmp < ISIS_TLV_VENDOR_PRIVATE_MINLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_VENDOR_PRIVATE_MINLEN)) /* check if enough byte for a full oui */ + goto trunctlv; + vendor_id = EXTRACT_24BITS(tptr); + printf("\n\t Vendor: %s (%u)", + tok2str(oui_values,"Unknown",vendor_id), + vendor_id); + tptr+=3; + tmp-=3; + if (tmp > 0) /* hexdump the rest */ + if(!print_unknown_data(tptr,"\n\t\t",tmp)) + return(0); + break; + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case ISIS_TLV_DECNET_PHASE4: + case ISIS_TLV_LUCENT_PRIVATE: + case ISIS_TLV_IPAUTH: + case ISIS_TLV_NORTEL_PRIVATE1: + case ISIS_TLV_NORTEL_PRIVATE2: + + default: + if (vflag <= 1) { + if(!print_unknown_data(pptr,"\n\t\t",tlv_len)) + return(0); + } + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag> 1) { + if(!print_unknown_data(pptr,"\n\t ",tlv_len)) + return(0); + } + + pptr += tlv_len; + packet_len -= tlv_len; + } + + if (packet_len != 0) { + printf("\n\t %u straggler bytes", packet_len); + } + return (1); + + trunc: + fputs("[|isis]", stdout); + return (1); + + trunctlv: + printf("\n\t\t packet exceeded snapshot"); + return(1); +} + +static void +osi_print_cksum (const u_int8_t *pptr, u_int16_t checksum, + u_int checksum_offset, u_int length) +{ + u_int16_t calculated_checksum; + + /* do not attempt to verify the checksum if it is zero */ + if (!checksum) { + printf("(unverified)"); + } else { + calculated_checksum = create_osi_cksum(pptr, checksum_offset, length); + if (checksum == calculated_checksum) { + printf(" (correct)"); + } else { + printf(" (incorrect should be 0x%04x)", calculated_checksum); + } + } +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-juniper.c b/freebsd/contrib/tcpdump/print-juniper.c new file mode 100644 index 00000000..e221835f --- /dev/null +++ b/freebsd/contrib/tcpdump/print-juniper.c @@ -0,0 +1,1458 @@ +#include <machine/rtems-bsd-user-space.h> + +/* NetBSD: print-juniper.c,v 1.2 2007/07/24 11:53:45 drochner Exp */ + +/* + * 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-juniper.c,v 1.34 2007-08-29 02:31:44 mcr Exp $ (LBL)"; +#else +__RCSID("NetBSD: print-juniper.c,v 1.3 2007/07/25 06:31:32 dogcow Exp "); +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "ppp.h" +#include "llc.h" +#include "nlpid.h" +#include "ethertype.h" +#include "atm.h" + +#define JUNIPER_BPF_OUT 0 /* Outgoing packet */ +#define JUNIPER_BPF_IN 1 /* Incoming packet */ +#define JUNIPER_BPF_PKT_IN 0x1 /* Incoming packet */ +#define JUNIPER_BPF_NO_L2 0x2 /* L2 header stripped */ +#define JUNIPER_BPF_IIF 0x4 /* IIF is valid */ +#define JUNIPER_BPF_FILTER 0x40 /* BPF filtering is supported */ +#define JUNIPER_BPF_EXT 0x80 /* extensions present */ +#define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */ + +#define JUNIPER_LSQ_COOKIE_RE (1 << 3) +#define JUNIPER_LSQ_COOKIE_DIR (1 << 2) +#define JUNIPER_LSQ_L3_PROTO_SHIFT 4 +#define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define AS_PIC_COOKIE_LEN 8 + +#define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1 +#define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2 +#define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3 +#define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4 +#define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5 + +static struct tok juniper_ipsec_type_values[] = { + { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE, "ESP ENCR-AUTH" }, + { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE, "ESP ENCR-AH AUTH" }, + { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE, "ESP AUTH" }, + { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE, "AH AUTH" }, + { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE, "ESP ENCR" }, + { 0, NULL} +}; + +static struct tok juniper_direction_values[] = { + { JUNIPER_BPF_IN, "In"}, + { JUNIPER_BPF_OUT, "Out"}, + { 0, NULL} +}; + +/* codepoints for encoding extensions to a .pcap file */ +enum { + JUNIPER_EXT_TLV_IFD_IDX = 1, + JUNIPER_EXT_TLV_IFD_NAME = 2, + JUNIPER_EXT_TLV_IFD_MEDIATYPE = 3, + JUNIPER_EXT_TLV_IFL_IDX = 4, + JUNIPER_EXT_TLV_IFL_UNIT = 5, + JUNIPER_EXT_TLV_IFL_ENCAPS = 6, + JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE = 7, + JUNIPER_EXT_TLV_TTP_IFL_ENCAPS = 8 +}; + +/* 1 byte type and 1-byte length */ +#define JUNIPER_EXT_TLV_OVERHEAD 2 + +struct tok jnx_ext_tlv_values[] = { + { JUNIPER_EXT_TLV_IFD_IDX, "Device Interface Index" }, + { JUNIPER_EXT_TLV_IFD_NAME,"Device Interface Name" }, + { JUNIPER_EXT_TLV_IFD_MEDIATYPE, "Device Media Type" }, + { JUNIPER_EXT_TLV_IFL_IDX, "Logical Interface Index" }, + { JUNIPER_EXT_TLV_IFL_UNIT,"Logical Unit Number" }, + { JUNIPER_EXT_TLV_IFL_ENCAPS, "Logical Interface Encapsulation" }, + { JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE, "TTP derived Device Media Type" }, + { JUNIPER_EXT_TLV_TTP_IFL_ENCAPS, "TTP derived Logical Interface Encapsulation" }, + { 0, NULL } +}; + +struct tok jnx_flag_values[] = { + { JUNIPER_BPF_EXT, "Ext" }, + { JUNIPER_BPF_FILTER, "Filter" }, + { JUNIPER_BPF_IIF, "IIF" }, + { JUNIPER_BPF_NO_L2, "no-L2" }, + { JUNIPER_BPF_PKT_IN, "In" }, + { 0, NULL } +}; + +#define JUNIPER_IFML_ETHER 1 +#define JUNIPER_IFML_FDDI 2 +#define JUNIPER_IFML_TOKENRING 3 +#define JUNIPER_IFML_PPP 4 +#define JUNIPER_IFML_FRAMERELAY 5 +#define JUNIPER_IFML_CISCOHDLC 6 +#define JUNIPER_IFML_SMDSDXI 7 +#define JUNIPER_IFML_ATMPVC 8 +#define JUNIPER_IFML_PPP_CCC 9 +#define JUNIPER_IFML_FRAMERELAY_CCC 10 +#define JUNIPER_IFML_IPIP 11 +#define JUNIPER_IFML_GRE 12 +#define JUNIPER_IFML_PIM 13 +#define JUNIPER_IFML_PIMD 14 +#define JUNIPER_IFML_CISCOHDLC_CCC 15 +#define JUNIPER_IFML_VLAN_CCC 16 +#define JUNIPER_IFML_MLPPP 17 +#define JUNIPER_IFML_MLFR 18 +#define JUNIPER_IFML_ML 19 +#define JUNIPER_IFML_LSI 20 +#define JUNIPER_IFML_DFE 21 +#define JUNIPER_IFML_ATM_CELLRELAY_CCC 22 +#define JUNIPER_IFML_CRYPTO 23 +#define JUNIPER_IFML_GGSN 24 +#define JUNIPER_IFML_LSI_PPP 25 +#define JUNIPER_IFML_LSI_CISCOHDLC 26 +#define JUNIPER_IFML_PPP_TCC 27 +#define JUNIPER_IFML_FRAMERELAY_TCC 28 +#define JUNIPER_IFML_CISCOHDLC_TCC 29 +#define JUNIPER_IFML_ETHERNET_CCC 30 +#define JUNIPER_IFML_VT 31 +#define JUNIPER_IFML_EXTENDED_VLAN_CCC 32 +#define JUNIPER_IFML_ETHER_OVER_ATM 33 +#define JUNIPER_IFML_MONITOR 34 +#define JUNIPER_IFML_ETHERNET_TCC 35 +#define JUNIPER_IFML_VLAN_TCC 36 +#define JUNIPER_IFML_EXTENDED_VLAN_TCC 37 +#define JUNIPER_IFML_CONTROLLER 38 +#define JUNIPER_IFML_MFR 39 +#define JUNIPER_IFML_LS 40 +#define JUNIPER_IFML_ETHERNET_VPLS 41 +#define JUNIPER_IFML_ETHERNET_VLAN_VPLS 42 +#define JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS 43 +#define JUNIPER_IFML_LT 44 +#define JUNIPER_IFML_SERVICES 45 +#define JUNIPER_IFML_ETHER_VPLS_OVER_ATM 46 +#define JUNIPER_IFML_FR_PORT_CCC 47 +#define JUNIPER_IFML_FRAMERELAY_EXT_CCC 48 +#define JUNIPER_IFML_FRAMERELAY_EXT_TCC 49 +#define JUNIPER_IFML_FRAMERELAY_FLEX 50 +#define JUNIPER_IFML_GGSNI 51 +#define JUNIPER_IFML_ETHERNET_FLEX 52 +#define JUNIPER_IFML_COLLECTOR 53 +#define JUNIPER_IFML_AGGREGATOR 54 +#define JUNIPER_IFML_LAPD 55 +#define JUNIPER_IFML_PPPOE 56 +#define JUNIPER_IFML_PPP_SUBORDINATE 57 +#define JUNIPER_IFML_CISCOHDLC_SUBORDINATE 58 +#define JUNIPER_IFML_DFC 59 +#define JUNIPER_IFML_PICPEER 60 + +struct tok juniper_ifmt_values[] = { + { JUNIPER_IFML_ETHER, "Ethernet" }, + { JUNIPER_IFML_FDDI, "FDDI" }, + { JUNIPER_IFML_TOKENRING, "Token-Ring" }, + { JUNIPER_IFML_PPP, "PPP" }, + { JUNIPER_IFML_PPP_SUBORDINATE, "PPP-Subordinate" }, + { JUNIPER_IFML_FRAMERELAY, "Frame-Relay" }, + { JUNIPER_IFML_CISCOHDLC, "Cisco-HDLC" }, + { JUNIPER_IFML_SMDSDXI, "SMDS-DXI" }, + { JUNIPER_IFML_ATMPVC, "ATM-PVC" }, + { JUNIPER_IFML_PPP_CCC, "PPP-CCC" }, + { JUNIPER_IFML_FRAMERELAY_CCC, "Frame-Relay-CCC" }, + { JUNIPER_IFML_FRAMERELAY_EXT_CCC, "Extended FR-CCC" }, + { JUNIPER_IFML_IPIP, "IP-over-IP" }, + { JUNIPER_IFML_GRE, "GRE" }, + { JUNIPER_IFML_PIM, "PIM-Encapsulator" }, + { JUNIPER_IFML_PIMD, "PIM-Decapsulator" }, + { JUNIPER_IFML_CISCOHDLC_CCC, "Cisco-HDLC-CCC" }, + { JUNIPER_IFML_VLAN_CCC, "VLAN-CCC" }, + { JUNIPER_IFML_EXTENDED_VLAN_CCC, "Extended-VLAN-CCC" }, + { JUNIPER_IFML_MLPPP, "Multilink-PPP" }, + { JUNIPER_IFML_MLFR, "Multilink-FR" }, + { JUNIPER_IFML_MFR, "Multilink-FR-UNI-NNI" }, + { JUNIPER_IFML_ML, "Multilink" }, + { JUNIPER_IFML_LS, "LinkService" }, + { JUNIPER_IFML_LSI, "LSI" }, + { JUNIPER_IFML_ATM_CELLRELAY_CCC, "ATM-CCC-Cell-Relay" }, + { JUNIPER_IFML_CRYPTO, "IPSEC-over-IP" }, + { JUNIPER_IFML_GGSN, "GGSN" }, + { JUNIPER_IFML_PPP_TCC, "PPP-TCC" }, + { JUNIPER_IFML_FRAMERELAY_TCC, "Frame-Relay-TCC" }, + { JUNIPER_IFML_FRAMERELAY_EXT_TCC, "Extended FR-TCC" }, + { JUNIPER_IFML_CISCOHDLC_TCC, "Cisco-HDLC-TCC" }, + { JUNIPER_IFML_ETHERNET_CCC, "Ethernet-CCC" }, + { JUNIPER_IFML_VT, "VPN-Loopback-tunnel" }, + { JUNIPER_IFML_ETHER_OVER_ATM, "Ethernet-over-ATM" }, + { JUNIPER_IFML_ETHER_VPLS_OVER_ATM, "Ethernet-VPLS-over-ATM" }, + { JUNIPER_IFML_MONITOR, "Monitor" }, + { JUNIPER_IFML_ETHERNET_TCC, "Ethernet-TCC" }, + { JUNIPER_IFML_VLAN_TCC, "VLAN-TCC" }, + { JUNIPER_IFML_EXTENDED_VLAN_TCC, "Extended-VLAN-TCC" }, + { JUNIPER_IFML_CONTROLLER, "Controller" }, + { JUNIPER_IFML_ETHERNET_VPLS, "VPLS" }, + { JUNIPER_IFML_ETHERNET_VLAN_VPLS, "VLAN-VPLS" }, + { JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS, "Extended-VLAN-VPLS" }, + { JUNIPER_IFML_LT, "Logical-tunnel" }, + { JUNIPER_IFML_SERVICES, "General-Services" }, + { JUNIPER_IFML_PPPOE, "PPPoE" }, + { JUNIPER_IFML_ETHERNET_FLEX, "Flexible-Ethernet-Services" }, + { JUNIPER_IFML_FRAMERELAY_FLEX, "Flexible-FrameRelay" }, + { JUNIPER_IFML_COLLECTOR, "Flow-collection" }, + { JUNIPER_IFML_PICPEER, "PIC Peer" }, + { JUNIPER_IFML_DFC, "Dynamic-Flow-Capture" }, + {0, NULL} +}; + +#define JUNIPER_IFLE_ATM_SNAP 2 +#define JUNIPER_IFLE_ATM_NLPID 3 +#define JUNIPER_IFLE_ATM_VCMUX 4 +#define JUNIPER_IFLE_ATM_LLC 5 +#define JUNIPER_IFLE_ATM_PPP_VCMUX 6 +#define JUNIPER_IFLE_ATM_PPP_LLC 7 +#define JUNIPER_IFLE_ATM_PPP_FUNI 8 +#define JUNIPER_IFLE_ATM_CCC 9 +#define JUNIPER_IFLE_FR_NLPID 10 +#define JUNIPER_IFLE_FR_SNAP 11 +#define JUNIPER_IFLE_FR_PPP 12 +#define JUNIPER_IFLE_FR_CCC 13 +#define JUNIPER_IFLE_ENET2 14 +#define JUNIPER_IFLE_IEEE8023_SNAP 15 +#define JUNIPER_IFLE_IEEE8023_LLC 16 +#define JUNIPER_IFLE_PPP 17 +#define JUNIPER_IFLE_CISCOHDLC 18 +#define JUNIPER_IFLE_PPP_CCC 19 +#define JUNIPER_IFLE_IPIP_NULL 20 +#define JUNIPER_IFLE_PIM_NULL 21 +#define JUNIPER_IFLE_GRE_NULL 22 +#define JUNIPER_IFLE_GRE_PPP 23 +#define JUNIPER_IFLE_PIMD_DECAPS 24 +#define JUNIPER_IFLE_CISCOHDLC_CCC 25 +#define JUNIPER_IFLE_ATM_CISCO_NLPID 26 +#define JUNIPER_IFLE_VLAN_CCC 27 +#define JUNIPER_IFLE_MLPPP 28 +#define JUNIPER_IFLE_MLFR 29 +#define JUNIPER_IFLE_LSI_NULL 30 +#define JUNIPER_IFLE_AGGREGATE_UNUSED 31 +#define JUNIPER_IFLE_ATM_CELLRELAY_CCC 32 +#define JUNIPER_IFLE_CRYPTO 33 +#define JUNIPER_IFLE_GGSN 34 +#define JUNIPER_IFLE_ATM_TCC 35 +#define JUNIPER_IFLE_FR_TCC 36 +#define JUNIPER_IFLE_PPP_TCC 37 +#define JUNIPER_IFLE_CISCOHDLC_TCC 38 +#define JUNIPER_IFLE_ETHERNET_CCC 39 +#define JUNIPER_IFLE_VT 40 +#define JUNIPER_IFLE_ATM_EOA_LLC 41 +#define JUNIPER_IFLE_EXTENDED_VLAN_CCC 42 +#define JUNIPER_IFLE_ATM_SNAP_TCC 43 +#define JUNIPER_IFLE_MONITOR 44 +#define JUNIPER_IFLE_ETHERNET_TCC 45 +#define JUNIPER_IFLE_VLAN_TCC 46 +#define JUNIPER_IFLE_EXTENDED_VLAN_TCC 47 +#define JUNIPER_IFLE_MFR 48 +#define JUNIPER_IFLE_ETHERNET_VPLS 49 +#define JUNIPER_IFLE_ETHERNET_VLAN_VPLS 50 +#define JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS 51 +#define JUNIPER_IFLE_SERVICES 52 +#define JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC 53 +#define JUNIPER_IFLE_FR_PORT_CCC 54 +#define JUNIPER_IFLE_ATM_MLPPP_LLC 55 +#define JUNIPER_IFLE_ATM_EOA_CCC 56 +#define JUNIPER_IFLE_LT_VLAN 57 +#define JUNIPER_IFLE_COLLECTOR 58 +#define JUNIPER_IFLE_AGGREGATOR 59 +#define JUNIPER_IFLE_LAPD 60 +#define JUNIPER_IFLE_ATM_PPPOE_LLC 61 +#define JUNIPER_IFLE_ETHERNET_PPPOE 62 +#define JUNIPER_IFLE_PPPOE 63 +#define JUNIPER_IFLE_PPP_SUBORDINATE 64 +#define JUNIPER_IFLE_CISCOHDLC_SUBORDINATE 65 +#define JUNIPER_IFLE_DFC 66 +#define JUNIPER_IFLE_PICPEER 67 + +struct tok juniper_ifle_values[] = { + { JUNIPER_IFLE_AGGREGATOR, "Aggregator" }, + { JUNIPER_IFLE_ATM_CCC, "CCC over ATM" }, + { JUNIPER_IFLE_ATM_CELLRELAY_CCC, "ATM CCC Cell Relay" }, + { JUNIPER_IFLE_ATM_CISCO_NLPID, "CISCO compatible NLPID" }, + { JUNIPER_IFLE_ATM_EOA_CCC, "Ethernet over ATM CCC" }, + { JUNIPER_IFLE_ATM_EOA_LLC, "Ethernet over ATM LLC" }, + { JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC, "Ethernet VPLS over ATM LLC" }, + { JUNIPER_IFLE_ATM_LLC, "ATM LLC" }, + { JUNIPER_IFLE_ATM_MLPPP_LLC, "MLPPP over ATM LLC" }, + { JUNIPER_IFLE_ATM_NLPID, "ATM NLPID" }, + { JUNIPER_IFLE_ATM_PPPOE_LLC, "PPPoE over ATM LLC" }, + { JUNIPER_IFLE_ATM_PPP_FUNI, "PPP over FUNI" }, + { JUNIPER_IFLE_ATM_PPP_LLC, "PPP over ATM LLC" }, + { JUNIPER_IFLE_ATM_PPP_VCMUX, "PPP over ATM VCMUX" }, + { JUNIPER_IFLE_ATM_SNAP, "ATM SNAP" }, + { JUNIPER_IFLE_ATM_SNAP_TCC, "ATM SNAP TCC" }, + { JUNIPER_IFLE_ATM_TCC, "ATM VCMUX TCC" }, + { JUNIPER_IFLE_ATM_VCMUX, "ATM VCMUX" }, + { JUNIPER_IFLE_CISCOHDLC, "C-HDLC" }, + { JUNIPER_IFLE_CISCOHDLC_CCC, "C-HDLC CCC" }, + { JUNIPER_IFLE_CISCOHDLC_SUBORDINATE, "C-HDLC via dialer" }, + { JUNIPER_IFLE_CISCOHDLC_TCC, "C-HDLC TCC" }, + { JUNIPER_IFLE_COLLECTOR, "Collector" }, + { JUNIPER_IFLE_CRYPTO, "Crypto" }, + { JUNIPER_IFLE_ENET2, "Ethernet" }, + { JUNIPER_IFLE_ETHERNET_CCC, "Ethernet CCC" }, + { JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS, "Extended VLAN VPLS" }, + { JUNIPER_IFLE_ETHERNET_PPPOE, "PPPoE over Ethernet" }, + { JUNIPER_IFLE_ETHERNET_TCC, "Ethernet TCC" }, + { JUNIPER_IFLE_ETHERNET_VLAN_VPLS, "VLAN VPLS" }, + { JUNIPER_IFLE_ETHERNET_VPLS, "VPLS" }, + { JUNIPER_IFLE_EXTENDED_VLAN_CCC, "Extended VLAN CCC" }, + { JUNIPER_IFLE_EXTENDED_VLAN_TCC, "Extended VLAN TCC" }, + { JUNIPER_IFLE_FR_CCC, "FR CCC" }, + { JUNIPER_IFLE_FR_NLPID, "FR NLPID" }, + { JUNIPER_IFLE_FR_PORT_CCC, "FR CCC" }, + { JUNIPER_IFLE_FR_PPP, "FR PPP" }, + { JUNIPER_IFLE_FR_SNAP, "FR SNAP" }, + { JUNIPER_IFLE_FR_TCC, "FR TCC" }, + { JUNIPER_IFLE_GGSN, "GGSN" }, + { JUNIPER_IFLE_GRE_NULL, "GRE NULL" }, + { JUNIPER_IFLE_GRE_PPP, "PPP over GRE" }, + { JUNIPER_IFLE_IPIP_NULL, "IPIP" }, + { JUNIPER_IFLE_LAPD, "LAPD" }, + { JUNIPER_IFLE_LSI_NULL, "LSI Null" }, + { JUNIPER_IFLE_LT_VLAN, "LT VLAN" }, + { JUNIPER_IFLE_MFR, "MFR" }, + { JUNIPER_IFLE_MLFR, "MLFR" }, + { JUNIPER_IFLE_MLPPP, "MLPPP" }, + { JUNIPER_IFLE_MONITOR, "Monitor" }, + { JUNIPER_IFLE_PIMD_DECAPS, "PIMd" }, + { JUNIPER_IFLE_PIM_NULL, "PIM Null" }, + { JUNIPER_IFLE_PPP, "PPP" }, + { JUNIPER_IFLE_PPPOE, "PPPoE" }, + { JUNIPER_IFLE_PPP_CCC, "PPP CCC" }, + { JUNIPER_IFLE_PPP_SUBORDINATE, "" }, + { JUNIPER_IFLE_PPP_TCC, "PPP TCC" }, + { JUNIPER_IFLE_SERVICES, "General Services" }, + { JUNIPER_IFLE_VLAN_CCC, "VLAN CCC" }, + { JUNIPER_IFLE_VLAN_TCC, "VLAN TCC" }, + { JUNIPER_IFLE_VT, "VT" }, + {0, NULL} +}; + +struct juniper_cookie_table_t { + u_int32_t pictype; /* pic type */ + u_int8_t cookie_len; /* cookie len */ + const char *s; /* pic name */ +}; + +static struct juniper_cookie_table_t juniper_cookie_table[] = { +#ifdef DLT_JUNIPER_ATM1 + { DLT_JUNIPER_ATM1, 4, "ATM1"}, +#endif +#ifdef DLT_JUNIPER_ATM2 + { DLT_JUNIPER_ATM2, 8, "ATM2"}, +#endif +#ifdef DLT_JUNIPER_MLPPP + { DLT_JUNIPER_MLPPP, 2, "MLPPP"}, +#endif +#ifdef DLT_JUNIPER_MLFR + { DLT_JUNIPER_MLFR, 2, "MLFR"}, +#endif +#ifdef DLT_JUNIPER_MFR + { DLT_JUNIPER_MFR, 4, "MFR"}, +#endif +#ifdef DLT_JUNIPER_PPPOE + { DLT_JUNIPER_PPPOE, 0, "PPPoE"}, +#endif +#ifdef DLT_JUNIPER_PPPOE_ATM + { DLT_JUNIPER_PPPOE_ATM, 0, "PPPoE ATM"}, +#endif +#ifdef DLT_JUNIPER_GGSN + { DLT_JUNIPER_GGSN, 8, "GGSN"}, +#endif +#ifdef DLT_JUNIPER_MONITOR + { DLT_JUNIPER_MONITOR, 8, "MONITOR"}, +#endif +#ifdef DLT_JUNIPER_SERVICES + { DLT_JUNIPER_SERVICES, 8, "AS"}, +#endif +#ifdef DLT_JUNIPER_ES + { DLT_JUNIPER_ES, 0, "ES"}, +#endif + { 0, 0, NULL } +}; + +struct juniper_l2info_t { + u_int32_t length; + u_int32_t caplen; + u_int32_t pictype; + u_int8_t direction; + u_int8_t header_len; + u_int8_t cookie_len; + u_int8_t cookie_type; + u_int8_t cookie[8]; + u_int8_t bundle; + u_int16_t proto; + u_int8_t flags; +}; + +#define LS_COOKIE_ID 0x54 +#define AS_COOKIE_ID 0x47 +#define LS_MLFR_COOKIE_LEN 4 +#define ML_MLFR_COOKIE_LEN 2 +#define LS_MFR_COOKIE_LEN 6 +#define ATM1_COOKIE_LEN 4 +#define ATM2_COOKIE_LEN 8 + +#define ATM2_PKT_TYPE_MASK 0x70 +#define ATM2_GAP_COUNT_MASK 0x3F + +#define JUNIPER_PROTO_NULL 1 +#define JUNIPER_PROTO_IPV4 2 +#define JUNIPER_PROTO_IPV6 6 + +#define MFR_BE_MASK 0xc0 + +static struct tok juniper_protocol_values[] = { + { JUNIPER_PROTO_NULL, "Null" }, + { JUNIPER_PROTO_IPV4, "IPv4" }, + { JUNIPER_PROTO_IPV6, "IPv6" }, + { 0, NULL} +}; + +int ip_heuristic_guess(register const u_char *, u_int); +int juniper_ppp_heuristic_guess(register const u_char *, u_int); +int juniper_read_tlv_value(const u_char *, u_int, u_int); +static int juniper_parse_header (const u_char *, const struct pcap_pkthdr *, struct juniper_l2info_t *); + +#ifdef DLT_JUNIPER_GGSN +u_int +juniper_ggsn_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + struct juniper_ggsn_header { + u_int8_t svc_id; + u_int8_t flags_len; + u_int8_t proto; + u_int8_t flags; + u_int8_t vlan_id[2]; + u_int8_t res[2]; + }; + const struct juniper_ggsn_header *gh; + + l2info.pictype = DLT_JUNIPER_GGSN; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + gh = (struct juniper_ggsn_header *)&l2info.cookie; + + if (eflag) { + printf("proto %s (%u), vlan %u: ", + tok2str(juniper_protocol_values,"Unknown",gh->proto), + gh->proto, + EXTRACT_16BITS(&gh->vlan_id[0])); + } + + switch (gh->proto) { + case JUNIPER_PROTO_IPV4: + ip_print(gndo, p, l2info.length); + break; +#ifdef INET6 + case JUNIPER_PROTO_IPV6: + ip6_print(gndo, p, l2info.length); + break; +#endif /* INET6 */ + default: + if (!eflag) + printf("unknown GGSN proto (%u)", gh->proto); + } + + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_ES +u_int +juniper_es_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + struct juniper_ipsec_header { + u_int8_t sa_index[2]; + u_int8_t ttl; + u_int8_t type; + u_int8_t spi[4]; + u_int8_t src_ip[4]; + u_int8_t dst_ip[4]; + }; + u_int rewrite_len,es_type_bundle; + const struct juniper_ipsec_header *ih; + + l2info.pictype = DLT_JUNIPER_ES; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + ih = (struct juniper_ipsec_header *)p; + + switch (ih->type) { + case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE: + case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE: + rewrite_len = 0; + es_type_bundle = 1; + break; + case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE: + case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE: + case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE: + rewrite_len = 16; + es_type_bundle = 0; + default: + printf("ES Invalid type %u, length %u", + ih->type, + l2info.length); + return l2info.header_len; + } + + l2info.length-=rewrite_len; + p+=rewrite_len; + + if (eflag) { + if (!es_type_bundle) { + printf("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n", + EXTRACT_16BITS(&ih->sa_index), + ih->ttl, + tok2str(juniper_ipsec_type_values,"Unknown",ih->type), + ih->type, + EXTRACT_32BITS(&ih->spi), + ipaddr_string(&ih->src_ip), + ipaddr_string(&ih->dst_ip), + l2info.length); + } else { + printf("ES SA, index %u, ttl %u type %s (%u), length %u\n", + EXTRACT_16BITS(&ih->sa_index), + ih->ttl, + tok2str(juniper_ipsec_type_values,"Unknown",ih->type), + ih->type, + l2info.length); + } + } + + ip_print(gndo, p, l2info.length); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_MONITOR +u_int +juniper_monitor_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + struct juniper_monitor_header { + u_int8_t pkt_type; + u_int8_t padding; + u_int8_t iif[2]; + u_int8_t service_id[4]; + }; + const struct juniper_monitor_header *mh; + + l2info.pictype = DLT_JUNIPER_MONITOR; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + mh = (struct juniper_monitor_header *)p; + + if (eflag) + printf("service-id %u, iif %u, pkt-type %u: ", + EXTRACT_32BITS(&mh->service_id), + EXTRACT_16BITS(&mh->iif), + mh->pkt_type); + + /* no proto field - lets guess by first byte of IP header*/ + ip_heuristic_guess(p, l2info.length); + + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_SERVICES +u_int +juniper_services_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + struct juniper_services_header { + u_int8_t svc_id; + u_int8_t flags_len; + u_int8_t svc_set_id[2]; + u_int8_t dir_iif[4]; + }; + const struct juniper_services_header *sh; + + l2info.pictype = DLT_JUNIPER_SERVICES; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + sh = (struct juniper_services_header *)p; + + if (eflag) + printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ", + sh->svc_id, + sh->flags_len, + EXTRACT_16BITS(&sh->svc_set_id), + EXTRACT_24BITS(&sh->dir_iif[1])); + + /* no proto field - lets guess by first byte of IP header*/ + ip_heuristic_guess(p, l2info.length); + + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_PPPOE +u_int +juniper_pppoe_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_PPPOE; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw ethernet frames */ + ether_print(gndo, p, l2info.length, l2info.caplen, NULL, NULL); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_ETHER +u_int +juniper_ether_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_ETHER; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw Ethernet frames */ + ether_print(gndo, p, l2info.length, l2info.caplen, NULL, NULL); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_PPP +u_int +juniper_ppp_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_PPP; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw ppp frames */ + ppp_print(p, l2info.length); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_FRELAY +u_int +juniper_frelay_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_FRELAY; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw frame-relay frames */ + fr_print(p, l2info.length); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_CHDLC +u_int +juniper_chdlc_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_CHDLC; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw c-hdlc frames */ + chdlc_print(p, l2info.length); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_PPPOE_ATM +u_int +juniper_pppoe_atm_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + u_int16_t extracted_ethertype; + + l2info.pictype = DLT_JUNIPER_PPPOE_ATM; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + + extracted_ethertype = EXTRACT_16BITS(p); + /* this DLT contains nothing but raw PPPoE frames, + * prepended with a type field*/ + if (ethertype_print(gndo, extracted_ethertype, + p+ETHERTYPE_LEN, + l2info.length-ETHERTYPE_LEN, + l2info.caplen-ETHERTYPE_LEN) == 0) + /* ether_type not known, probably it wasn't one */ + printf("unknown ethertype 0x%04x", extracted_ethertype); + + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_MLPPP +u_int +juniper_mlppp_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_MLPPP; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + /* suppress Bundle-ID if frame was captured on a child-link + * best indicator if the cookie looks like a proto */ + if (eflag && + EXTRACT_16BITS(&l2info.cookie) != PPP_OSI && + EXTRACT_16BITS(&l2info.cookie) != (PPP_ADDRESS << 8 | PPP_CONTROL)) + printf("Bundle-ID %u: ",l2info.bundle); + + p+=l2info.header_len; + + /* first try the LSQ protos */ + switch(l2info.proto) { + case JUNIPER_LSQ_L3_PROTO_IPV4: + /* IP traffic going to the RE would not have a cookie + * -> this must be incoming IS-IS over PPP + */ + if (l2info.cookie[4] == (JUNIPER_LSQ_COOKIE_RE|JUNIPER_LSQ_COOKIE_DIR)) + ppp_print(p, l2info.length); + else + ip_print(gndo, p, l2info.length); + return l2info.header_len; +#ifdef INET6 + case JUNIPER_LSQ_L3_PROTO_IPV6: + ip6_print(gndo, p,l2info.length); + return l2info.header_len; +#endif + case JUNIPER_LSQ_L3_PROTO_MPLS: + mpls_print(p,l2info.length); + return l2info.header_len; + case JUNIPER_LSQ_L3_PROTO_ISO: + isoclns_print(p,l2info.length,l2info.caplen); + return l2info.header_len; + default: + break; + } + + /* zero length cookie ? */ + switch (EXTRACT_16BITS(&l2info.cookie)) { + case PPP_OSI: + ppp_print(p-2,l2info.length+2); + break; + case (PPP_ADDRESS << 8 | PPP_CONTROL): /* fall through */ + default: + ppp_print(p,l2info.length); + break; + } + + return l2info.header_len; +} +#endif + + +#ifdef DLT_JUNIPER_MFR +u_int +juniper_mfr_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_MFR; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + + /* child-link ? */ + if (l2info.cookie_len == 0) { + mfr_print(p,l2info.length); + return l2info.header_len; + } + + /* first try the LSQ protos */ + if (l2info.cookie_len == AS_PIC_COOKIE_LEN) { + switch(l2info.proto) { + case JUNIPER_LSQ_L3_PROTO_IPV4: + ip_print(gndo, p, l2info.length); + return l2info.header_len; +#ifdef INET6 + case JUNIPER_LSQ_L3_PROTO_IPV6: + ip6_print(gndo, p,l2info.length); + return l2info.header_len; +#endif + case JUNIPER_LSQ_L3_PROTO_MPLS: + mpls_print(p,l2info.length); + return l2info.header_len; + case JUNIPER_LSQ_L3_PROTO_ISO: + isoclns_print(p,l2info.length,l2info.caplen); + return l2info.header_len; + default: + break; + } + return l2info.header_len; + } + + /* suppress Bundle-ID if frame was captured on a child-link */ + if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle); + switch (l2info.proto) { + case (LLCSAP_ISONS<<8 | LLCSAP_ISONS): + isoclns_print(p+1, l2info.length-1, l2info.caplen-1); + break; + case (LLC_UI<<8 | NLPID_Q933): + case (LLC_UI<<8 | NLPID_IP): + case (LLC_UI<<8 | NLPID_IP6): + /* pass IP{4,6} to the OSI layer for proper link-layer printing */ + isoclns_print(p-1, l2info.length+1, l2info.caplen+1); + break; + default: + printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length); + } + + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_MLFR +u_int +juniper_mlfr_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_MLFR; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + + /* suppress Bundle-ID if frame was captured on a child-link */ + if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle); + switch (l2info.proto) { + case (LLC_UI): + case (LLC_UI<<8): + isoclns_print(p, l2info.length, l2info.caplen); + break; + case (LLC_UI<<8 | NLPID_Q933): + case (LLC_UI<<8 | NLPID_IP): + case (LLC_UI<<8 | NLPID_IP6): + /* pass IP{4,6} to the OSI layer for proper link-layer printing */ + isoclns_print(p-1, l2info.length+1, l2info.caplen+1); + break; + default: + printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length); + } + + return l2info.header_len; +} +#endif + +/* + * ATM1 PIC cookie format + * + * +-----+-------------------------+-------------------------------+ + * |fmtid| vc index | channel ID | + * +-----+-------------------------+-------------------------------+ + */ + +#ifdef DLT_JUNIPER_ATM1 +u_int +juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + u_int16_t extracted_ethertype; + + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_ATM1; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + + if (l2info.cookie[0] == 0x80) { /* OAM cell ? */ + oam_print(p,l2info.length,ATM_OAM_NOHEC); + return l2info.header_len; + } + + if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ + EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ + + if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL, + &extracted_ethertype) != 0) + return l2info.header_len; + } + + if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ + isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1); + /* FIXME check if frame was recognized */ + return l2info.header_len; + } + + if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */ + return l2info.header_len; + + return l2info.header_len; +} +#endif + +/* + * ATM2 PIC cookie format + * + * +-------------------------------+---------+---+-----+-----------+ + * | channel ID | reserv |AAL| CCRQ| gap cnt | + * +-------------------------------+---------+---+-----+-----------+ + */ + +#ifdef DLT_JUNIPER_ATM2 +u_int +juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + u_int16_t extracted_ethertype; + + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_ATM2; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + + if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */ + oam_print(p,l2info.length,ATM_OAM_NOHEC); + return l2info.header_len; + } + + if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ + EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ + + if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL, + &extracted_ethertype) != 0) + return l2info.header_len; + } + + if (l2info.direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */ + (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) { + ether_print(gndo, p, l2info.length, l2info.caplen, NULL, NULL); + return l2info.header_len; + } + + if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ + isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1); + /* FIXME check if frame was recognized */ + return l2info.header_len; + } + + if(juniper_ppp_heuristic_guess(p, l2info.length) != 0) /* PPPoA vcmux encaps ? */ + return l2info.header_len; + + if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */ + return l2info.header_len; + + return l2info.header_len; +} +#endif + + +/* try to guess, based on all PPP protos that are supported in + * a juniper router if the payload data is encapsulated using PPP */ +int +juniper_ppp_heuristic_guess(register const u_char *p, u_int length) { + + switch(EXTRACT_16BITS(p)) { + case PPP_IP : + case PPP_OSI : + case PPP_MPLS_UCAST : + case PPP_MPLS_MCAST : + case PPP_IPCP : + case PPP_OSICP : + case PPP_MPLSCP : + case PPP_LCP : + case PPP_PAP : + case PPP_CHAP : + case PPP_ML : +#ifdef INET6 + case PPP_IPV6 : + case PPP_IPV6CP : +#endif + ppp_print(p, length); + break; + + default: + return 0; /* did not find a ppp header */ + break; + } + return 1; /* we printed a ppp packet */ +} + +int +ip_heuristic_guess(register const u_char *p, u_int length) { + + switch(p[0]) { + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + ip_print(gndo, p, length); + break; +#ifdef INET6 + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + ip6_print(gndo, p, length); + break; +#endif + default: + return 0; /* did not find a ip header */ + break; + } + return 1; /* we printed an v4/v6 packet */ +} + +int +juniper_read_tlv_value(const u_char *p, u_int tlv_type, u_int tlv_len) { + + int tlv_value; + + /* TLVs < 128 are little endian encoded */ + if (tlv_type < 128) { + switch (tlv_len) { + case 1: + tlv_value = *p; + break; + case 2: + tlv_value = EXTRACT_LE_16BITS(p); + break; + case 3: + tlv_value = EXTRACT_LE_24BITS(p); + break; + case 4: + tlv_value = EXTRACT_LE_32BITS(p); + break; + default: + tlv_value = -1; + break; + } + } else { + /* TLVs >= 128 are big endian encoded */ + switch (tlv_len) { + case 1: + tlv_value = *p; + break; + case 2: + tlv_value = EXTRACT_16BITS(p); + break; + case 3: + tlv_value = EXTRACT_24BITS(p); + break; + case 4: + tlv_value = EXTRACT_32BITS(p); + break; + default: + tlv_value = -1; + break; + } + } + return tlv_value; +} + +static int +juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) { + + struct juniper_cookie_table_t *lp = juniper_cookie_table; + u_int idx, jnx_ext_len, jnx_header_len = 0; + u_int8_t tlv_type,tlv_len; + u_int32_t control_word; + int tlv_value; + const u_char *tptr; + + + l2info->header_len = 0; + l2info->cookie_len = 0; + l2info->proto = 0; + + + l2info->length = h->len; + l2info->caplen = h->caplen; + TCHECK2(p[0],4); + l2info->flags = p[3]; + l2info->direction = p[3]&JUNIPER_BPF_PKT_IN; + + if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */ + printf("no magic-number found!"); + return 0; + } + + if (eflag) /* print direction */ + printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction)); + + /* magic number + flags */ + jnx_header_len = 4; + + if (vflag>1) + printf("\n\tJuniper PCAP Flags [%s]", + bittok2str(jnx_flag_values, "none", l2info->flags)); + + /* extensions present ? - calculate how much bytes to skip */ + if ((l2info->flags & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) { + + tptr = p+jnx_header_len; + + /* ok to read extension length ? */ + TCHECK2(tptr[0], 2); + jnx_ext_len = EXTRACT_16BITS(tptr); + jnx_header_len += 2; + tptr +=2; + + /* nail up the total length - + * just in case something goes wrong + * with TLV parsing */ + jnx_header_len += jnx_ext_len; + + if (vflag>1) + printf(", PCAP Extension(s) total length %u", + jnx_ext_len); + + TCHECK2(tptr[0], jnx_ext_len); + while (jnx_ext_len > JUNIPER_EXT_TLV_OVERHEAD) { + tlv_type = *(tptr++); + tlv_len = *(tptr++); + tlv_value = 0; + + /* sanity check */ + if (tlv_type == 0 || tlv_len == 0) + break; + + if (vflag>1) + printf("\n\t %s Extension TLV #%u, length %u, value ", + tok2str(jnx_ext_tlv_values,"Unknown",tlv_type), + tlv_type, + tlv_len); + + tlv_value = juniper_read_tlv_value(tptr, tlv_type, tlv_len); + switch (tlv_type) { + case JUNIPER_EXT_TLV_IFD_NAME: + /* FIXME */ + break; + case JUNIPER_EXT_TLV_IFD_MEDIATYPE: + case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE: + if (tlv_value != -1) { + if (vflag>1) + printf("%s (%u)", + tok2str(juniper_ifmt_values, "Unknown", tlv_value), + tlv_value); + } + break; + case JUNIPER_EXT_TLV_IFL_ENCAPS: + case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS: + if (tlv_value != -1) { + if (vflag>1) + printf("%s (%u)", + tok2str(juniper_ifle_values, "Unknown", tlv_value), + tlv_value); + } + break; + case JUNIPER_EXT_TLV_IFL_IDX: /* fall through */ + case JUNIPER_EXT_TLV_IFL_UNIT: + case JUNIPER_EXT_TLV_IFD_IDX: + default: + if (tlv_value != -1) { + if (vflag>1) + printf("%u",tlv_value); + } + break; + } + + tptr+=tlv_len; + jnx_ext_len -= tlv_len+JUNIPER_EXT_TLV_OVERHEAD; + } + + if (vflag>1) + printf("\n\t-----original packet-----\n\t"); + } + + if ((l2info->flags & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) { + if (eflag) + printf("no-L2-hdr, "); + + /* there is no link-layer present - + * perform the v4/v6 heuristics + * to figure out what it is + */ + TCHECK2(p[jnx_header_len+4],1); + if(ip_heuristic_guess(p+jnx_header_len+4,l2info->length-(jnx_header_len+4)) == 0) + printf("no IP-hdr found!"); + + l2info->header_len=jnx_header_len+4; + return 0; /* stop parsing the output further */ + + } + l2info->header_len = jnx_header_len; + p+=l2info->header_len; + l2info->length -= l2info->header_len; + l2info->caplen -= l2info->header_len; + + /* search through the cookie table and copy values matching for our PIC type */ + while (lp->s != NULL) { + if (lp->pictype == l2info->pictype) { + + l2info->cookie_len += lp->cookie_len; + + switch (p[0]) { + case LS_COOKIE_ID: + l2info->cookie_type = LS_COOKIE_ID; + l2info->cookie_len += 2; + break; + case AS_COOKIE_ID: + l2info->cookie_type = AS_COOKIE_ID; + l2info->cookie_len = 8; + break; + + default: + l2info->bundle = l2info->cookie[0]; + break; + } + + +#ifdef DLT_JUNIPER_MFR + /* MFR child links don't carry cookies */ + if (l2info->pictype == DLT_JUNIPER_MFR && + (p[0] & MFR_BE_MASK) == MFR_BE_MASK) { + l2info->cookie_len = 0; + } +#endif + + l2info->header_len += l2info->cookie_len; + l2info->length -= l2info->cookie_len; + l2info->caplen -= l2info->cookie_len; + + if (eflag) + printf("%s-PIC, cookie-len %u", + lp->s, + l2info->cookie_len); + + if (l2info->cookie_len > 0) { + TCHECK2(p[0],l2info->cookie_len); + if (eflag) + printf(", cookie 0x"); + for (idx = 0; idx < l2info->cookie_len; idx++) { + l2info->cookie[idx] = p[idx]; /* copy cookie data */ + if (eflag) printf("%02x",p[idx]); + } + } + + if (eflag) printf(": "); /* print demarc b/w L2/L3*/ + + + l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); + break; + } + ++lp; + } + p+=l2info->cookie_len; + + /* DLT_ specific parsing */ + switch(l2info->pictype) { +#ifdef DLT_JUNIPER_MLPPP + case DLT_JUNIPER_MLPPP: + switch (l2info->cookie_type) { + case LS_COOKIE_ID: + l2info->bundle = l2info->cookie[1]; + break; + case AS_COOKIE_ID: + l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; + break; + default: + l2info->bundle = l2info->cookie[0]; + break; + } + break; +#endif +#ifdef DLT_JUNIPER_MLFR + case DLT_JUNIPER_MLFR: + switch (l2info->cookie_type) { + case LS_COOKIE_ID: + l2info->bundle = l2info->cookie[1]; + l2info->proto = EXTRACT_16BITS(p); + l2info->header_len += 2; + l2info->length -= 2; + l2info->caplen -= 2; + break; + case AS_COOKIE_ID: + l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; + break; + default: + l2info->bundle = l2info->cookie[0]; + l2info->header_len += 2; + l2info->length -= 2; + l2info->caplen -= 2; + break; + } + break; +#endif +#ifdef DLT_JUNIPER_MFR + case DLT_JUNIPER_MFR: + switch (l2info->cookie_type) { + case LS_COOKIE_ID: + l2info->bundle = l2info->cookie[1]; + l2info->proto = EXTRACT_16BITS(p); + l2info->header_len += 2; + l2info->length -= 2; + l2info->caplen -= 2; + break; + case AS_COOKIE_ID: + l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; + break; + default: + l2info->bundle = l2info->cookie[0]; + break; + } + break; +#endif +#ifdef DLT_JUNIPER_ATM2 + case DLT_JUNIPER_ATM2: + TCHECK2(p[0],4); + /* ATM cell relay control word present ? */ + if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) { + control_word = EXTRACT_32BITS(p); + /* some control word heuristics */ + switch(control_word) { + case 0: /* zero control word */ + case 0x08000000: /* < JUNOS 7.4 control-word */ + case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/ + l2info->header_len += 4; + break; + default: + break; + } + + if (eflag) + printf("control-word 0x%08x ", control_word); + } + break; +#endif +#ifdef DLT_JUNIPER_GGSN + case DLT_JUNIPER_GGSN: + break; +#endif +#ifdef DLT_JUNIPER_ATM1 + case DLT_JUNIPER_ATM1: + break; +#endif +#ifdef DLT_JUNIPER_PPP + case DLT_JUNIPER_PPP: + break; +#endif +#ifdef DLT_JUNIPER_CHDLC + case DLT_JUNIPER_CHDLC: + break; +#endif +#ifdef DLT_JUNIPER_ETHER + case DLT_JUNIPER_ETHER: + break; +#endif +#ifdef DLT_JUNIPER_FRELAY + case DLT_JUNIPER_FRELAY: + break; +#endif + + default: + printf("Unknown Juniper DLT_ type %u: ", l2info->pictype); + break; + } + + if (eflag > 1) + printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto); + + return 1; /* everything went ok so far. continue parsing */ + trunc: + printf("[|juniper_hdr], length %u",h->len); + return 0; +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-krb.c b/freebsd/contrib/tcpdump/print-krb.c new file mode 100644 index 00000000..b18203b1 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-krb.c @@ -0,0 +1,263 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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. + * + * Initial contribution from John Hawkinson (jhawk@mit.edu). + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-krb.c,v 1.23 2003-11-16 09:36:26 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +static const u_char *c_print(register const u_char *, register const u_char *); +static const u_char *krb4_print_hdr(const u_char *); +static void krb4_print(const u_char *); + +#define AUTH_MSG_KDC_REQUEST 1<<1 +#define AUTH_MSG_KDC_REPLY 2<<1 +#define AUTH_MSG_APPL_REQUEST 3<<1 +#define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1 +#define AUTH_MSG_ERR_REPLY 5<<1 +#define AUTH_MSG_PRIVATE 6<<1 +#define AUTH_MSG_SAFE 7<<1 +#define AUTH_MSG_APPL_ERR 8<<1 +#define AUTH_MSG_DIE 63<<1 + +#define KERB_ERR_OK 0 +#define KERB_ERR_NAME_EXP 1 +#define KERB_ERR_SERVICE_EXP 2 +#define KERB_ERR_AUTH_EXP 3 +#define KERB_ERR_PKT_VER 4 +#define KERB_ERR_NAME_MAST_KEY_VER 5 +#define KERB_ERR_SERV_MAST_KEY_VER 6 +#define KERB_ERR_BYTE_ORDER 7 +#define KERB_ERR_PRINCIPAL_UNKNOWN 8 +#define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9 +#define KERB_ERR_NULL_KEY 10 + +struct krb { + u_int8_t pvno; /* Protocol Version */ + u_int8_t type; /* Type+B */ +}; + +static char tstr[] = " [|kerberos]"; + +static struct tok type2str[] = { + { AUTH_MSG_KDC_REQUEST, "KDC_REQUEST" }, + { AUTH_MSG_KDC_REPLY, "KDC_REPLY" }, + { AUTH_MSG_APPL_REQUEST, "APPL_REQUEST" }, + { AUTH_MSG_APPL_REQUEST_MUTUAL, "APPL_REQUEST_MUTUAL" }, + { AUTH_MSG_ERR_REPLY, "ERR_REPLY" }, + { AUTH_MSG_PRIVATE, "PRIVATE" }, + { AUTH_MSG_SAFE, "SAFE" }, + { AUTH_MSG_APPL_ERR, "APPL_ERR" }, + { AUTH_MSG_DIE, "DIE" }, + { 0, NULL } +}; + +static struct tok kerr2str[] = { + { KERB_ERR_OK, "OK" }, + { KERB_ERR_NAME_EXP, "NAME_EXP" }, + { KERB_ERR_SERVICE_EXP, "SERVICE_EXP" }, + { KERB_ERR_AUTH_EXP, "AUTH_EXP" }, + { KERB_ERR_PKT_VER, "PKT_VER" }, + { KERB_ERR_NAME_MAST_KEY_VER, "NAME_MAST_KEY_VER" }, + { KERB_ERR_SERV_MAST_KEY_VER, "SERV_MAST_KEY_VER" }, + { KERB_ERR_BYTE_ORDER, "BYTE_ORDER" }, + { KERB_ERR_PRINCIPAL_UNKNOWN, "PRINCIPAL_UNKNOWN" }, + { KERB_ERR_PRINCIPAL_NOT_UNIQUE,"PRINCIPAL_NOT_UNIQUE" }, + { KERB_ERR_NULL_KEY, "NULL_KEY"}, + { 0, NULL} +}; + +static const u_char * +c_print(register const u_char *s, register const u_char *ep) +{ + register u_char c; + register int flag; + + flag = 1; + while (s < ep) { + c = *s++; + if (c == '\0') { + flag = 0; + break; + } + if (!isascii(c)) { + c = toascii(c); + putchar('M'); + putchar('-'); + } + if (!isprint(c)) { + c ^= 0x40; /* DEL to ?, others to alpha */ + putchar('^'); + } + putchar(c); + } + if (flag) + return NULL; + return (s); +} + +static const u_char * +krb4_print_hdr(const u_char *cp) +{ + cp += 2; + +#define PRINT if ((cp = c_print(cp, snapend)) == NULL) goto trunc + + PRINT; + putchar('.'); + PRINT; + putchar('@'); + PRINT; + return (cp); + +trunc: + fputs(tstr, stdout); + return (NULL); + +#undef PRINT +} + +static void +krb4_print(const u_char *cp) +{ + register const struct krb *kp; + u_char type; + u_short len; + +#define PRINT if ((cp = c_print(cp, snapend)) == NULL) goto trunc +/* True if struct krb is little endian */ +#define IS_LENDIAN(kp) (((kp)->type & 0x01) != 0) +#define KTOHSP(kp, cp) (IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp)) + + kp = (struct krb *)cp; + + if ((&kp->type) >= snapend) { + fputs(tstr, stdout); + return; + } + + type = kp->type & (0xFF << 1); + + printf(" %s %s: ", + IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type)); + + switch (type) { + + case AUTH_MSG_KDC_REQUEST: + if ((cp = krb4_print_hdr(cp)) == NULL) + return; + cp += 4; /* ctime */ + TCHECK(*cp); + printf(" %dmin ", *cp++ * 5); + PRINT; + putchar('.'); + PRINT; + break; + + case AUTH_MSG_APPL_REQUEST: + cp += 2; + TCHECK(*cp); + printf("v%d ", *cp++); + PRINT; + TCHECK(*cp); + printf(" (%d)", *cp++); + TCHECK(*cp); + printf(" (%d)", *cp); + break; + + case AUTH_MSG_KDC_REPLY: + if ((cp = krb4_print_hdr(cp)) == NULL) + return; + cp += 10; /* timestamp + n + exp + kvno */ + TCHECK2(*cp, sizeof(short)); + len = KTOHSP(kp, cp); + printf(" (%d)", len); + break; + + case AUTH_MSG_ERR_REPLY: + if ((cp = krb4_print_hdr(cp)) == NULL) + return; + cp += 4; /* timestamp */ + TCHECK2(*cp, sizeof(short)); + printf(" %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp))); + cp += 4; + PRINT; + break; + + default: + fputs("(unknown)", stdout); + break; + } + + return; +trunc: + fputs(tstr, stdout); +} + +void +krb_print(const u_char *dat) +{ + register const struct krb *kp; + + kp = (struct krb *)dat; + + if (dat >= snapend) { + fputs(tstr, stdout); + return; + } + + switch (kp->pvno) { + + case 1: + case 2: + case 3: + printf(" v%d", kp->pvno); + break; + + case 4: + printf(" v%d", kp->pvno); + krb4_print((const u_char *)kp); + break; + + case 106: + case 107: + fputs(" v5", stdout); + /* Decode ASN.1 here "someday" */ + break; + } + return; +} diff --git a/freebsd/contrib/tcpdump/print-l2tp.c b/freebsd/contrib/tcpdump/print-l2tp.c new file mode 100644 index 00000000..d62e1c8e --- /dev/null +++ b/freebsd/contrib/tcpdump/print-l2tp.c @@ -0,0 +1,721 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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. + * + * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.20 2006-06-23 02:03:09 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "l2tp.h" +#include "interface.h" +#include "extract.h" + +static char tstr[] = " [|l2tp]"; + +#define L2TP_MSGTYPE_SCCRQ 1 /* Start-Control-Connection-Request */ +#define L2TP_MSGTYPE_SCCRP 2 /* Start-Control-Connection-Reply */ +#define L2TP_MSGTYPE_SCCCN 3 /* Start-Control-Connection-Connected */ +#define L2TP_MSGTYPE_STOPCCN 4 /* Stop-Control-Connection-Notification */ +#define L2TP_MSGTYPE_HELLO 6 /* Hello */ +#define L2TP_MSGTYPE_OCRQ 7 /* Outgoing-Call-Request */ +#define L2TP_MSGTYPE_OCRP 8 /* Outgoing-Call-Reply */ +#define L2TP_MSGTYPE_OCCN 9 /* Outgoing-Call-Connected */ +#define L2TP_MSGTYPE_ICRQ 10 /* Incoming-Call-Request */ +#define L2TP_MSGTYPE_ICRP 11 /* Incoming-Call-Reply */ +#define L2TP_MSGTYPE_ICCN 12 /* Incoming-Call-Connected */ +#define L2TP_MSGTYPE_CDN 14 /* Call-Disconnect-Notify */ +#define L2TP_MSGTYPE_WEN 15 /* WAN-Error-Notify */ +#define L2TP_MSGTYPE_SLI 16 /* Set-Link-Info */ + +static struct tok l2tp_msgtype2str[] = { + { L2TP_MSGTYPE_SCCRQ, "SCCRQ" }, + { L2TP_MSGTYPE_SCCRP, "SCCRP" }, + { L2TP_MSGTYPE_SCCCN, "SCCCN" }, + { L2TP_MSGTYPE_STOPCCN, "StopCCN" }, + { L2TP_MSGTYPE_HELLO, "HELLO" }, + { L2TP_MSGTYPE_OCRQ, "OCRQ" }, + { L2TP_MSGTYPE_OCRP, "OCRP" }, + { L2TP_MSGTYPE_OCCN, "OCCN" }, + { L2TP_MSGTYPE_ICRQ, "ICRQ" }, + { L2TP_MSGTYPE_ICRP, "ICRP" }, + { L2TP_MSGTYPE_ICCN, "ICCN" }, + { L2TP_MSGTYPE_CDN, "CDN" }, + { L2TP_MSGTYPE_WEN, "WEN" }, + { L2TP_MSGTYPE_SLI, "SLI" }, + { 0, NULL } +}; + +#define L2TP_AVP_MSGTYPE 0 /* Message Type */ +#define L2TP_AVP_RESULT_CODE 1 /* Result Code */ +#define L2TP_AVP_PROTO_VER 2 /* Protocol Version */ +#define L2TP_AVP_FRAMING_CAP 3 /* Framing Capabilities */ +#define L2TP_AVP_BEARER_CAP 4 /* Bearer Capabilities */ +#define L2TP_AVP_TIE_BREAKER 5 /* Tie Breaker */ +#define L2TP_AVP_FIRM_VER 6 /* Firmware Revision */ +#define L2TP_AVP_HOST_NAME 7 /* Host Name */ +#define L2TP_AVP_VENDOR_NAME 8 /* Vendor Name */ +#define L2TP_AVP_ASSND_TUN_ID 9 /* Assigned Tunnel ID */ +#define L2TP_AVP_RECV_WIN_SIZE 10 /* Receive Window Size */ +#define L2TP_AVP_CHALLENGE 11 /* Challenge */ +#define L2TP_AVP_Q931_CC 12 /* Q.931 Cause Code */ +#define L2TP_AVP_CHALLENGE_RESP 13 /* Challenge Response */ +#define L2TP_AVP_ASSND_SESS_ID 14 /* Assigned Session ID */ +#define L2TP_AVP_CALL_SER_NUM 15 /* Call Serial Number */ +#define L2TP_AVP_MINIMUM_BPS 16 /* Minimum BPS */ +#define L2TP_AVP_MAXIMUM_BPS 17 /* Maximum BPS */ +#define L2TP_AVP_BEARER_TYPE 18 /* Bearer Type */ +#define L2TP_AVP_FRAMING_TYPE 19 /* Framing Type */ +#define L2TP_AVP_PACKET_PROC_DELAY 20 /* Packet Processing Delay (OBSOLETE) */ +#define L2TP_AVP_CALLED_NUMBER 21 /* Called Number */ +#define L2TP_AVP_CALLING_NUMBER 22 /* Calling Number */ +#define L2TP_AVP_SUB_ADDRESS 23 /* Sub-Address */ +#define L2TP_AVP_TX_CONN_SPEED 24 /* (Tx) Connect Speed */ +#define L2TP_AVP_PHY_CHANNEL_ID 25 /* Physical Channel ID */ +#define L2TP_AVP_INI_RECV_LCP 26 /* Initial Received LCP CONFREQ */ +#define L2TP_AVP_LAST_SENT_LCP 27 /* Last Sent LCP CONFREQ */ +#define L2TP_AVP_LAST_RECV_LCP 28 /* Last Received LCP CONFREQ */ +#define L2TP_AVP_PROXY_AUTH_TYPE 29 /* Proxy Authen Type */ +#define L2TP_AVP_PROXY_AUTH_NAME 30 /* Proxy Authen Name */ +#define L2TP_AVP_PROXY_AUTH_CHAL 31 /* Proxy Authen Challenge */ +#define L2TP_AVP_PROXY_AUTH_ID 32 /* Proxy Authen ID */ +#define L2TP_AVP_PROXY_AUTH_RESP 33 /* Proxy Authen Response */ +#define L2TP_AVP_CALL_ERRORS 34 /* Call Errors */ +#define L2TP_AVP_ACCM 35 /* ACCM */ +#define L2TP_AVP_RANDOM_VECTOR 36 /* Random Vector */ +#define L2TP_AVP_PRIVATE_GRP_ID 37 /* Private Group ID */ +#define L2TP_AVP_RX_CONN_SPEED 38 /* (Rx) Connect Speed */ +#define L2TP_AVP_SEQ_REQUIRED 39 /* Sequencing Required */ +#define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code */ + +static struct tok l2tp_avp2str[] = { + { L2TP_AVP_MSGTYPE, "MSGTYPE" }, + { L2TP_AVP_RESULT_CODE, "RESULT_CODE" }, + { L2TP_AVP_PROTO_VER, "PROTO_VER" }, + { L2TP_AVP_FRAMING_CAP, "FRAMING_CAP" }, + { L2TP_AVP_BEARER_CAP, "BEARER_CAP" }, + { L2TP_AVP_TIE_BREAKER, "TIE_BREAKER" }, + { L2TP_AVP_FIRM_VER, "FIRM_VER" }, + { L2TP_AVP_HOST_NAME, "HOST_NAME" }, + { L2TP_AVP_VENDOR_NAME, "VENDOR_NAME" }, + { L2TP_AVP_ASSND_TUN_ID, "ASSND_TUN_ID" }, + { L2TP_AVP_RECV_WIN_SIZE, "RECV_WIN_SIZE" }, + { L2TP_AVP_CHALLENGE, "CHALLENGE" }, + { L2TP_AVP_Q931_CC, "Q931_CC", }, + { L2TP_AVP_CHALLENGE_RESP, "CHALLENGE_RESP" }, + { L2TP_AVP_ASSND_SESS_ID, "ASSND_SESS_ID" }, + { L2TP_AVP_CALL_SER_NUM, "CALL_SER_NUM" }, + { L2TP_AVP_MINIMUM_BPS, "MINIMUM_BPS" }, + { L2TP_AVP_MAXIMUM_BPS, "MAXIMUM_BPS" }, + { L2TP_AVP_BEARER_TYPE, "BEARER_TYPE" }, + { L2TP_AVP_FRAMING_TYPE, "FRAMING_TYPE" }, + { L2TP_AVP_PACKET_PROC_DELAY, "PACKET_PROC_DELAY" }, + { L2TP_AVP_CALLED_NUMBER, "CALLED_NUMBER" }, + { L2TP_AVP_CALLING_NUMBER, "CALLING_NUMBER" }, + { L2TP_AVP_SUB_ADDRESS, "SUB_ADDRESS" }, + { L2TP_AVP_TX_CONN_SPEED, "TX_CONN_SPEED" }, + { L2TP_AVP_PHY_CHANNEL_ID, "PHY_CHANNEL_ID" }, + { L2TP_AVP_INI_RECV_LCP, "INI_RECV_LCP" }, + { L2TP_AVP_LAST_SENT_LCP, "LAST_SENT_LCP" }, + { L2TP_AVP_LAST_RECV_LCP, "LAST_RECV_LCP" }, + { L2TP_AVP_PROXY_AUTH_TYPE, "PROXY_AUTH_TYPE" }, + { L2TP_AVP_PROXY_AUTH_NAME, "PROXY_AUTH_NAME" }, + { L2TP_AVP_PROXY_AUTH_CHAL, "PROXY_AUTH_CHAL" }, + { L2TP_AVP_PROXY_AUTH_ID, "PROXY_AUTH_ID" }, + { L2TP_AVP_PROXY_AUTH_RESP, "PROXY_AUTH_RESP" }, + { L2TP_AVP_CALL_ERRORS, "CALL_ERRORS" }, + { L2TP_AVP_ACCM, "ACCM" }, + { L2TP_AVP_RANDOM_VECTOR, "RANDOM_VECTOR" }, + { L2TP_AVP_PRIVATE_GRP_ID, "PRIVATE_GRP_ID" }, + { L2TP_AVP_RX_CONN_SPEED, "RX_CONN_SPEED" }, + { L2TP_AVP_SEQ_REQUIRED, "SEQ_REQUIRED" }, + { L2TP_AVP_PPP_DISCON_CC, "PPP_DISCON_CC" }, + { 0, NULL } +}; + +static struct tok l2tp_authentype2str[] = { + { L2TP_AUTHEN_TYPE_RESERVED, "Reserved" }, + { L2TP_AUTHEN_TYPE_TEXTUAL, "Textual" }, + { L2TP_AUTHEN_TYPE_CHAP, "CHAP" }, + { L2TP_AUTHEN_TYPE_PAP, "PAP" }, + { L2TP_AUTHEN_TYPE_NO_AUTH, "No Auth" }, + { L2TP_AUTHEN_TYPE_MSCHAPv1, "MS-CHAPv1" }, + { 0, NULL } +}; + +#define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL 0 +#define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER 1 +#define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL 2 + +static struct tok l2tp_cc_direction2str[] = { + { L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL, "global error" }, + { L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER, "at peer" }, + { L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" }, + { 0, NULL } +}; + +#if 0 +static char *l2tp_result_code_StopCCN[] = { + "Reserved", + "General request to clear control connection", + "General error--Error Code indicates the problem", + "Control channel already exists", + "Requester is not authorized to establish a control channel", + "The protocol version of the requester is not supported", + "Requester is being shut down", + "Finite State Machine error" +#define L2TP_MAX_RESULT_CODE_STOPCC_INDEX 8 +}; +#endif + +#if 0 +static char *l2tp_result_code_CDN[] = { + "Reserved", + "Call disconnected due to loss of carrier", + "Call disconnected for the reason indicated in error code", + "Call disconnected for administrative reasons", + "Call failed due to lack of appropriate facilities being " \ + "available (temporary condition)", + "Call failed due to lack of appropriate facilities being " \ + "available (permanent condition)", + "Invalid destination", + "Call failed due to no carrier detected", + "Call failed due to detection of a busy signal", + "Call failed due to lack of a dial tone", + "Call was not established within time allotted by LAC", + "Call was connected but no appropriate framing was detected" +#define L2TP_MAX_RESULT_CODE_CDN_INDEX 12 +}; +#endif + +#if 0 +static char *l2tp_error_code_general[] = { + "No general error", + "No control connection exists yet for this LAC-LNS pair", + "Length is wrong", + "One of the field values was out of range or " \ + "reserved field was non-zero" + "Insufficient resources to handle this operation now", + "The Session ID is invalid in this context", + "A generic vendor-specific error occurred in the LAC", + "Try another" +#define L2TP_MAX_ERROR_CODE_GENERAL_INDEX 8 +}; +#endif + +/******************************/ +/* generic print out routines */ +/******************************/ +static void +print_string(const u_char *dat, u_int length) +{ + u_int i; + for (i=0; i<length; i++) { + printf("%c", *dat++); + } +} + +static void +print_octets(const u_char *dat, u_int length) +{ + u_int i; + for (i=0; i<length; i++) { + printf("%02x", *dat++); + } +} + +static void +print_16bits_val(const u_int16_t *dat) +{ + printf("%u", EXTRACT_16BITS(dat)); +} + +static void +print_32bits_val(const u_int32_t *dat) +{ + printf("%lu", (u_long)EXTRACT_32BITS(dat)); +} + +/***********************************/ +/* AVP-specific print out routines */ +/***********************************/ +static void +l2tp_msgtype_print(const u_char *dat) +{ + u_int16_t *ptr = (u_int16_t*)dat; + + printf("%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u", + EXTRACT_16BITS(ptr))); +} + +static void +l2tp_result_code_print(const u_char *dat, u_int length) +{ + u_int16_t *ptr = (u_int16_t *)dat; + + printf("%u", EXTRACT_16BITS(ptr)); ptr++; /* Result Code */ + if (length > 2) { /* Error Code (opt) */ + printf("/%u", EXTRACT_16BITS(ptr)); ptr++; + } + if (length > 4) { /* Error Message (opt) */ + printf(" "); + print_string((u_char *)ptr, length - 4); + } +} + +static void +l2tp_proto_ver_print(const u_int16_t *dat) +{ + printf("%u.%u", (EXTRACT_16BITS(dat) >> 8), + (EXTRACT_16BITS(dat) & 0xff)); +} + +static void +l2tp_framing_cap_print(const u_char *dat) +{ + u_int32_t *ptr = (u_int32_t *)dat; + + if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) { + printf("A"); + } + if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_SYNC_MASK) { + printf("S"); + } +} + +static void +l2tp_bearer_cap_print(const u_char *dat) +{ + u_int32_t *ptr = (u_int32_t *)dat; + + if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) { + printf("A"); + } + if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_DIGITAL_MASK) { + printf("D"); + } +} + +static void +l2tp_q931_cc_print(const u_char *dat, u_int length) +{ + print_16bits_val((u_int16_t *)dat); + printf(", %02x", dat[2]); + if (length > 3) { + printf(" "); + print_string(dat+3, length-3); + } +} + +static void +l2tp_bearer_type_print(const u_char *dat) +{ + u_int32_t *ptr = (u_int32_t *)dat; + + if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) { + printf("A"); + } + if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_DIGITAL_MASK) { + printf("D"); + } +} + +static void +l2tp_framing_type_print(const u_char *dat) +{ + u_int32_t *ptr = (u_int32_t *)dat; + + if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) { + printf("A"); + } + if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_SYNC_MASK) { + printf("S"); + } +} + +static void +l2tp_packet_proc_delay_print(void) +{ + printf("obsolete"); +} + +static void +l2tp_proxy_auth_type_print(const u_char *dat) +{ + u_int16_t *ptr = (u_int16_t *)dat; + + printf("%s", tok2str(l2tp_authentype2str, + "AuthType-#%u", EXTRACT_16BITS(ptr))); +} + +static void +l2tp_proxy_auth_id_print(const u_char *dat) +{ + u_int16_t *ptr = (u_int16_t *)dat; + + printf("%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK); +} + +static void +l2tp_call_errors_print(const u_char *dat) +{ + u_int16_t *ptr = (u_int16_t *)dat; + u_int16_t val_h, val_l; + + ptr++; /* skip "Reserved" */ + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("CRCErr=%u ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("FrameErr=%u ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("HardOver=%u ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("BufOver=%u ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("Timeout=%u ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("AlignErr=%u ", (val_h<<16) + val_l); +} + +static void +l2tp_accm_print(const u_char *dat) +{ + u_int16_t *ptr = (u_int16_t *)dat; + u_int16_t val_h, val_l; + + ptr++; /* skip "Reserved" */ + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("send=%08x ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("recv=%08x ", (val_h<<16) + val_l); +} + +static void +l2tp_ppp_discon_cc_print(const u_char *dat, u_int length) +{ + u_int16_t *ptr = (u_int16_t *)dat; + + printf("%04x, ", EXTRACT_16BITS(ptr)); ptr++; /* Disconnect Code */ + printf("%04x ", EXTRACT_16BITS(ptr)); ptr++; /* Control Protocol Number */ + printf("%s", tok2str(l2tp_cc_direction2str, + "Direction-#%u", *((u_char *)ptr++))); + + if (length > 5) { + printf(" "); + print_string((const u_char *)ptr, length-5); + } +} + +static void +l2tp_avp_print(const u_char *dat, int length) +{ + u_int len; + const u_int16_t *ptr = (u_int16_t *)dat; + u_int16_t attr_type; + int hidden = FALSE; + + if (length <= 0) { + return; + } + + printf(" "); + + TCHECK(*ptr); /* Flags & Length */ + len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK; + + /* If it is not long enough to contain the header, we'll give up. */ + if (len < 6) + goto trunc; + + /* If it goes past the end of the remaining length of the packet, + we'll give up. */ + if (len > (u_int)length) + goto trunc; + + /* If it goes past the end of the remaining length of the captured + data, we'll give up. */ + TCHECK2(*ptr, len); + /* After this point, no need to worry about truncation */ + + if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) { + printf("*"); + } + if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) { + hidden = TRUE; + printf("?"); + } + ptr++; + + if (EXTRACT_16BITS(ptr)) { + /* Vendor Specific Attribute */ + printf("VENDOR%04x:", EXTRACT_16BITS(ptr)); ptr++; + printf("ATTR%04x", EXTRACT_16BITS(ptr)); ptr++; + printf("("); + print_octets((u_char *)ptr, len-6); + printf(")"); + } else { + /* IETF-defined Attributes */ + ptr++; + attr_type = EXTRACT_16BITS(ptr); ptr++; + printf("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type)); + printf("("); + if (hidden) { + printf("???"); + } else { + switch (attr_type) { + case L2TP_AVP_MSGTYPE: + l2tp_msgtype_print((u_char *)ptr); + break; + case L2TP_AVP_RESULT_CODE: + l2tp_result_code_print((u_char *)ptr, len-6); + break; + case L2TP_AVP_PROTO_VER: + l2tp_proto_ver_print(ptr); + break; + case L2TP_AVP_FRAMING_CAP: + l2tp_framing_cap_print((u_char *)ptr); + break; + case L2TP_AVP_BEARER_CAP: + l2tp_bearer_cap_print((u_char *)ptr); + break; + case L2TP_AVP_TIE_BREAKER: + print_octets((u_char *)ptr, 8); + break; + case L2TP_AVP_FIRM_VER: + case L2TP_AVP_ASSND_TUN_ID: + case L2TP_AVP_RECV_WIN_SIZE: + case L2TP_AVP_ASSND_SESS_ID: + print_16bits_val(ptr); + break; + case L2TP_AVP_HOST_NAME: + case L2TP_AVP_VENDOR_NAME: + case L2TP_AVP_CALLING_NUMBER: + case L2TP_AVP_CALLED_NUMBER: + case L2TP_AVP_SUB_ADDRESS: + case L2TP_AVP_PROXY_AUTH_NAME: + case L2TP_AVP_PRIVATE_GRP_ID: + print_string((u_char *)ptr, len-6); + break; + case L2TP_AVP_CHALLENGE: + case L2TP_AVP_INI_RECV_LCP: + case L2TP_AVP_LAST_SENT_LCP: + case L2TP_AVP_LAST_RECV_LCP: + case L2TP_AVP_PROXY_AUTH_CHAL: + case L2TP_AVP_PROXY_AUTH_RESP: + case L2TP_AVP_RANDOM_VECTOR: + print_octets((u_char *)ptr, len-6); + break; + case L2TP_AVP_Q931_CC: + l2tp_q931_cc_print((u_char *)ptr, len-6); + break; + case L2TP_AVP_CHALLENGE_RESP: + print_octets((u_char *)ptr, 16); + break; + case L2TP_AVP_CALL_SER_NUM: + case L2TP_AVP_MINIMUM_BPS: + case L2TP_AVP_MAXIMUM_BPS: + case L2TP_AVP_TX_CONN_SPEED: + case L2TP_AVP_PHY_CHANNEL_ID: + case L2TP_AVP_RX_CONN_SPEED: + print_32bits_val((u_int32_t *)ptr); + break; + case L2TP_AVP_BEARER_TYPE: + l2tp_bearer_type_print((u_char *)ptr); + break; + case L2TP_AVP_FRAMING_TYPE: + l2tp_framing_type_print((u_char *)ptr); + break; + case L2TP_AVP_PACKET_PROC_DELAY: + l2tp_packet_proc_delay_print(); + break; + case L2TP_AVP_PROXY_AUTH_TYPE: + l2tp_proxy_auth_type_print((u_char *)ptr); + break; + case L2TP_AVP_PROXY_AUTH_ID: + l2tp_proxy_auth_id_print((u_char *)ptr); + break; + case L2TP_AVP_CALL_ERRORS: + l2tp_call_errors_print((u_char *)ptr); + break; + case L2TP_AVP_ACCM: + l2tp_accm_print((u_char *)ptr); + break; + case L2TP_AVP_SEQ_REQUIRED: + break; /* No Attribute Value */ + case L2TP_AVP_PPP_DISCON_CC: + l2tp_ppp_discon_cc_print((u_char *)ptr, len-6); + break; + default: + break; + } + } + printf(")"); + } + + l2tp_avp_print(dat+len, length-len); + return; + + trunc: + printf("|..."); +} + + +void +l2tp_print(const u_char *dat, u_int length) +{ + const u_char *ptr = dat; + u_int cnt = 0; /* total octets consumed */ + u_int16_t pad; + int flag_t, flag_l, flag_s, flag_o; + u_int16_t l2tp_len; + + flag_t = flag_l = flag_s = flag_o = FALSE; + + TCHECK2(*ptr, 2); /* Flags & Version */ + if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) { + printf(" l2tp:"); + } else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) { + printf(" l2f:"); + return; /* nothing to do */ + } else { + printf(" Unknown Version, neither L2F(1) nor L2TP(2)"); + return; /* nothing we can do */ + } + + printf("["); + if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) { + flag_t = TRUE; + printf("T"); + } + if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) { + flag_l = TRUE; + printf("L"); + } + if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) { + flag_s = TRUE; + printf("S"); + } + if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) { + flag_o = TRUE; + printf("O"); + } + if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY) + printf("P"); + printf("]"); + + ptr += 2; + cnt += 2; + + if (flag_l) { + TCHECK2(*ptr, 2); /* Length */ + l2tp_len = EXTRACT_16BITS(ptr); + ptr += 2; + cnt += 2; + } else { + l2tp_len = 0; + } + + TCHECK2(*ptr, 2); /* Tunnel ID */ + printf("(%u/", EXTRACT_16BITS(ptr)); + ptr += 2; + cnt += 2; + TCHECK2(*ptr, 2); /* Session ID */ + printf("%u)", EXTRACT_16BITS(ptr)); + ptr += 2; + cnt += 2; + + if (flag_s) { + TCHECK2(*ptr, 2); /* Ns */ + printf("Ns=%u,", EXTRACT_16BITS(ptr)); + ptr += 2; + cnt += 2; + TCHECK2(*ptr, 2); /* Nr */ + printf("Nr=%u", EXTRACT_16BITS(ptr)); + ptr += 2; + cnt += 2; + } + + if (flag_o) { + TCHECK2(*ptr, 2); /* Offset Size */ + pad = EXTRACT_16BITS(ptr); + ptr += (2 + pad); + cnt += (2 + pad); + } + + if (flag_l) { + if (length < l2tp_len) { + printf(" Length %u larger than packet", l2tp_len); + return; + } + length = l2tp_len; + } + if (length < cnt) { + printf(" Length %u smaller than header length", length); + return; + } + if (flag_t) { + if (!flag_l) { + printf(" No length"); + return; + } + if (length - cnt == 0) { + printf(" ZLB"); + } else { + l2tp_avp_print(ptr, length - cnt); + } + } else { + printf(" {"); + ppp_print(ptr, length - cnt); + printf("}"); + } + + return; + + trunc: + printf("%s", tstr); +} diff --git a/freebsd/contrib/tcpdump/print-lane.c b/freebsd/contrib/tcpdump/print-lane.c new file mode 100644 index 00000000..b637b984 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-lane.c @@ -0,0 +1,120 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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-lane.c,v 1.25 2005-11-13 12:12:42 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "ether.h" +#include "lane.h" + +static const struct tok lecop2str[] = { + { 0x0001, "configure request" }, + { 0x0101, "configure response" }, + { 0x0002, "join request" }, + { 0x0102, "join response" }, + { 0x0003, "ready query" }, + { 0x0103, "ready indication" }, + { 0x0004, "register request" }, + { 0x0104, "register response" }, + { 0x0005, "unregister request" }, + { 0x0105, "unregister response" }, + { 0x0006, "ARP request" }, + { 0x0106, "ARP response" }, + { 0x0007, "flush request" }, + { 0x0107, "flush response" }, + { 0x0008, "NARP request" }, + { 0x0009, "topology request" }, + { 0, NULL } +}; + +static void +lane_hdr_print(netdissect_options *ndo, const u_char *bp) +{ + (void)ND_PRINT((ndo, "lecid:%x ", EXTRACT_16BITS(bp))); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the LANE 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. + * + * This assumes 802.3, not 802.5, LAN emulation. + */ +void +lane_print(const u_char *p, u_int length, u_int caplen) +{ + struct lane_controlhdr *lec; + + if (caplen < sizeof(struct lane_controlhdr)) { + printf("[|lane]"); + return; + } + + lec = (struct lane_controlhdr *)p; + if (EXTRACT_16BITS(&lec->lec_header) == 0xff00) { + /* + * LE Control. + */ + printf("lec: proto %x vers %x %s", + lec->lec_proto, lec->lec_vers, + tok2str(lecop2str, "opcode-#%u", EXTRACT_16BITS(&lec->lec_opcode))); + return; + } + + /* + * Go past the LE header. + */ + length -= 2; + caplen -= 2; + p += 2; + + /* + * Now print the encapsulated frame, under the assumption + * that it's an Ethernet frame. + */ + ether_print(gndo, p, length, caplen, lane_hdr_print, p - 2); +} + +u_int +lane_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + lane_print(p, h->len, h->caplen); + + return (sizeof(struct lecdatahdr_8023)); +} diff --git a/freebsd/contrib/tcpdump/print-ldp.c b/freebsd/contrib/tcpdump/print-ldp.c new file mode 100644 index 00000000..a02f1271 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ldp.c @@ -0,0 +1,678 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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) + * and Steinar Haug (sthaug@nethelp.no) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ldp.c,v 1.20 2006-06-23 02:03:09 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "decode_prefix.h" +#include "extract.h" +#include "addrtoname.h" + +#include "l2vpn.h" +#include "af.h" + +/* + * ldp 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 | PDU Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | LDP Identifier | + * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +struct ldp_common_header { + u_int8_t version[2]; + u_int8_t pdu_length[2]; + u_int8_t lsr_id[4]; + u_int8_t label_space[2]; +}; + +#define LDP_VERSION 1 + +/* + * ldp message 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |U| Message Type | Message Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + + + * | Mandatory Parameters | + * + + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + + + * | Optional Parameters | + * + + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct ldp_msg_header { + u_int8_t type[2]; + u_int8_t length[2]; + u_int8_t id[4]; +}; + +#define LDP_MASK_MSG_TYPE(x) ((x)&0x7fff) +#define LDP_MASK_U_BIT(x) ((x)&0x8000) + +#define LDP_MSG_NOTIF 0x0001 +#define LDP_MSG_HELLO 0x0100 +#define LDP_MSG_INIT 0x0200 +#define LDP_MSG_KEEPALIVE 0x0201 +#define LDP_MSG_ADDRESS 0x0300 +#define LDP_MSG_ADDRESS_WITHDRAW 0x0301 +#define LDP_MSG_LABEL_MAPPING 0x0400 +#define LDP_MSG_LABEL_REQUEST 0x0401 +#define LDP_MSG_LABEL_WITHDRAW 0x0402 +#define LDP_MSG_LABEL_RELEASE 0x0403 +#define LDP_MSG_LABEL_ABORT_REQUEST 0x0404 + +#define LDP_VENDOR_PRIVATE_MIN 0x3e00 +#define LDP_VENDOR_PRIVATE_MAX 0x3eff +#define LDP_EXPERIMENTAL_MIN 0x3f00 +#define LDP_EXPERIMENTAL_MAX 0x3fff + +static const struct tok ldp_msg_values[] = { + { LDP_MSG_NOTIF, "Notification" }, + { LDP_MSG_HELLO, "Hello" }, + { LDP_MSG_INIT, "Initialization" }, + { LDP_MSG_KEEPALIVE, "Keepalive" }, + { LDP_MSG_ADDRESS, "Address" }, + { LDP_MSG_ADDRESS_WITHDRAW, "Address Withdraw" }, + { LDP_MSG_LABEL_MAPPING, "Label Mapping" }, + { LDP_MSG_LABEL_REQUEST, "Label Request" }, + { LDP_MSG_LABEL_WITHDRAW, "Label Withdraw" }, + { LDP_MSG_LABEL_RELEASE, "Label Release" }, + { LDP_MSG_LABEL_ABORT_REQUEST, "Label Abort Request" }, + { 0, NULL} +}; + +#define LDP_MASK_TLV_TYPE(x) ((x)&0x3fff) +#define LDP_MASK_F_BIT(x) ((x)&0x4000) + +#define LDP_TLV_FEC 0x0100 +#define LDP_TLV_ADDRESS_LIST 0x0101 +#define LDP_TLV_ADDRESS_LIST_AFNUM_LEN 2 +#define LDP_TLV_HOP_COUNT 0x0103 +#define LDP_TLV_PATH_VECTOR 0x0104 +#define LDP_TLV_GENERIC_LABEL 0x0200 +#define LDP_TLV_ATM_LABEL 0x0201 +#define LDP_TLV_FR_LABEL 0x0202 +#define LDP_TLV_STATUS 0x0300 +#define LDP_TLV_EXTD_STATUS 0x0301 +#define LDP_TLV_RETURNED_PDU 0x0302 +#define LDP_TLV_RETURNED_MSG 0x0303 +#define LDP_TLV_COMMON_HELLO 0x0400 +#define LDP_TLV_IPV4_TRANSPORT_ADDR 0x0401 +#define LDP_TLV_CONFIG_SEQ_NUMBER 0x0402 +#define LDP_TLV_IPV6_TRANSPORT_ADDR 0x0403 +#define LDP_TLV_COMMON_SESSION 0x0500 +#define LDP_TLV_ATM_SESSION_PARM 0x0501 +#define LDP_TLV_FR_SESSION_PARM 0x0502 +#define LDP_TLV_FT_SESSION 0x0503 +#define LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600 +#define LDP_TLV_MTU 0x0601 /* rfc 3988 */ + +static const struct tok ldp_tlv_values[] = { + { LDP_TLV_FEC, "FEC" }, + { LDP_TLV_ADDRESS_LIST, "Address List" }, + { LDP_TLV_HOP_COUNT, "Hop Count" }, + { LDP_TLV_PATH_VECTOR, "Path Vector" }, + { LDP_TLV_GENERIC_LABEL, "Generic Label" }, + { LDP_TLV_ATM_LABEL, "ATM Label" }, + { LDP_TLV_FR_LABEL, "Frame-Relay Label" }, + { LDP_TLV_STATUS, "Status" }, + { LDP_TLV_EXTD_STATUS, "Extended Status" }, + { LDP_TLV_RETURNED_PDU, "Returned PDU" }, + { LDP_TLV_RETURNED_MSG, "Returned Message" }, + { LDP_TLV_COMMON_HELLO, "Common Hello Parameters" }, + { LDP_TLV_IPV4_TRANSPORT_ADDR, "IPv4 Transport Address" }, + { LDP_TLV_CONFIG_SEQ_NUMBER, "Configuration Sequence Number" }, + { LDP_TLV_IPV6_TRANSPORT_ADDR, "IPv6 Transport Address" }, + { LDP_TLV_COMMON_SESSION, "Common Session Parameters" }, + { LDP_TLV_ATM_SESSION_PARM, "ATM Session Parameters" }, + { LDP_TLV_FR_SESSION_PARM, "Frame-Relay Session Parameters" }, + { LDP_TLV_FT_SESSION, "Fault-Tolerant Session Parameters" }, + { LDP_TLV_LABEL_REQUEST_MSG_ID, "Label Request Message ID" }, + { LDP_TLV_MTU, "MTU" }, + { 0, NULL} +}; + +#define LDP_FEC_WILDCARD 0x01 +#define LDP_FEC_PREFIX 0x02 +#define LDP_FEC_HOSTADDRESS 0x03 +/* From RFC 4906; should probably be updated to RFC 4447 (e.g., VC -> PW) */ +#define LDP_FEC_MARTINI_VC 0x80 + +static const struct tok ldp_fec_values[] = { + { LDP_FEC_WILDCARD, "Wildcard" }, + { LDP_FEC_PREFIX, "Prefix" }, + { LDP_FEC_HOSTADDRESS, "Host address" }, + { LDP_FEC_MARTINI_VC, "Martini VC" }, + { 0, NULL} +}; + +#define LDP_FEC_MARTINI_IFPARM_MTU 0x01 +#define LDP_FEC_MARTINI_IFPARM_DESC 0x03 +#define LDP_FEC_MARTINI_IFPARM_VCCV 0x0c + +static const struct tok ldp_fec_martini_ifparm_values[] = { + { LDP_FEC_MARTINI_IFPARM_MTU, "MTU" }, + { LDP_FEC_MARTINI_IFPARM_DESC, "Description" }, + { LDP_FEC_MARTINI_IFPARM_VCCV, "VCCV" }, + { 0, NULL} +}; + +/* draft-ietf-pwe3-vccv-04.txt */ +static const struct tok ldp_fec_martini_ifparm_vccv_cc_values[] = { + { 0x01, "PWE3 control word" }, + { 0x02, "MPLS Router Alert Label" }, + { 0x04, "MPLS inner label TTL = 1" }, + { 0, NULL} +}; + +/* draft-ietf-pwe3-vccv-04.txt */ +static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = { + { 0x01, "ICMP Ping" }, + { 0x02, "LSP Ping" }, + { 0x04, "BFD" }, + { 0, NULL} +}; + +int ldp_msg_print(register const u_char *); +int ldp_tlv_print(register const u_char *); + +/* + * ldp 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |U|F| Type | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Value | + * ~ ~ + * | | + * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define TLV_TCHECK(minlen) \ + TCHECK2(*tptr, minlen); if (tlv_tlen < minlen) goto badtlv; + +int +ldp_tlv_print(register const u_char *tptr) { + + struct ldp_tlv_header { + u_int8_t type[2]; + u_int8_t length[2]; + }; + + const struct ldp_tlv_header *ldp_tlv_header; + u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags; + u_char fec_type; + u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx; + char buf[100]; + int i; + + ldp_tlv_header = (const struct ldp_tlv_header *)tptr; + tlv_len=EXTRACT_16BITS(ldp_tlv_header->length); + tlv_tlen=tlv_len; + tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type)); + + /* FIXME vendor private / experimental check */ + printf("\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]", + tok2str(ldp_tlv_values, + "Unknown", + tlv_type), + tlv_type, + tlv_len, + LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "continue processing" : "ignore", + LDP_MASK_F_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "do" : "don't"); + + tptr+=sizeof(struct ldp_tlv_header); + + switch(tlv_type) { + + case LDP_TLV_COMMON_HELLO: + TLV_TCHECK(4); + printf("\n\t Hold Time: %us, Flags: [%s Hello%s]", + EXTRACT_16BITS(tptr), + (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link", + (EXTRACT_16BITS(tptr+2)&0x4000) ? ", Request for targeted Hellos" : ""); + break; + + case LDP_TLV_IPV4_TRANSPORT_ADDR: + TLV_TCHECK(4); + printf("\n\t IPv4 Transport Address: %s", ipaddr_string(tptr)); + break; +#ifdef INET6 + case LDP_TLV_IPV6_TRANSPORT_ADDR: + TLV_TCHECK(16); + printf("\n\t IPv6 Transport Address: %s", ip6addr_string(tptr)); + break; +#endif + case LDP_TLV_CONFIG_SEQ_NUMBER: + TLV_TCHECK(4); + printf("\n\t Sequence Number: %u", EXTRACT_32BITS(tptr)); + break; + + case LDP_TLV_ADDRESS_LIST: + TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN); + af = EXTRACT_16BITS(tptr); + tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; + tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN; + printf("\n\t Address Family: %s, addresses", + tok2str(af_values, "Unknown (%u)", af)); + switch (af) { + case AFNUM_INET: + while(tlv_tlen >= sizeof(struct in_addr)) { + TCHECK2(*tptr, sizeof(struct in_addr)); + printf(" %s",ipaddr_string(tptr)); + tlv_tlen-=sizeof(struct in_addr); + tptr+=sizeof(struct in_addr); + } + break; +#ifdef INET6 + case AFNUM_INET6: + while(tlv_tlen >= sizeof(struct in6_addr)) { + TCHECK2(*tptr, sizeof(struct in6_addr)); + printf(" %s",ip6addr_string(tptr)); + tlv_tlen-=sizeof(struct in6_addr); + tptr+=sizeof(struct in6_addr); + } + break; +#endif + default: + /* unknown AF */ + break; + } + break; + + case LDP_TLV_COMMON_SESSION: + TLV_TCHECK(8); + printf("\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]", + EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2), + (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited", + (EXTRACT_16BITS(tptr+6)&0x4000) ? "Enabled" : "Disabled" + ); + break; + + case LDP_TLV_FEC: + TLV_TCHECK(1); + fec_type = *tptr; + printf("\n\t %s FEC (0x%02x)", + tok2str(ldp_fec_values, "Unknown", fec_type), + fec_type); + + tptr+=1; + tlv_tlen-=1; + switch(fec_type) { + + case LDP_FEC_WILDCARD: + break; + case LDP_FEC_PREFIX: + TLV_TCHECK(2); + af = EXTRACT_16BITS(tptr); + tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; + tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; + if (af == AFNUM_INET) { + i=decode_prefix4(tptr,tlv_tlen,buf,sizeof(buf)); + if (i == -2) + goto trunc; + if (i == -3) + printf(": IPv4 prefix (goes past end of TLV)"); + else if (i == -1) + printf(": IPv4 prefix (invalid length)"); + else + printf(": IPv4 prefix %s",buf); + } +#ifdef INET6 + else if (af == AFNUM_INET6) { + i=decode_prefix6(tptr,tlv_tlen,buf,sizeof(buf)); + if (i == -2) + goto trunc; + if (i == -3) + printf(": IPv4 prefix (goes past end of TLV)"); + else if (i == -1) + printf(": IPv6 prefix (invalid length)"); + else + printf(": IPv6 prefix %s",buf); + } +#endif + else + printf(": Address family %u prefix", af); + break; + case LDP_FEC_HOSTADDRESS: + break; + case LDP_FEC_MARTINI_VC: + /* + * According to RFC 4908, the VC info Length field can be zero, + * in which case not only are there no interface parameters, + * there's no VC ID. + */ + TLV_TCHECK(7); + vc_info_len = *(tptr+2); + + if (vc_info_len == 0) { + printf(": %s, %scontrol word, group-ID %u, VC-info-length: %u", + tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), + EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", + EXTRACT_32BITS(tptr+3), + vc_info_len); + break; + } + + /* Make sure we have the VC ID as well */ + TLV_TCHECK(11); + printf(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u", + tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), + EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", + EXTRACT_32BITS(tptr+3), + EXTRACT_32BITS(tptr+7), + vc_info_len); + if (vc_info_len < 4) + goto trunc; /* minimum 4, for the VC ID */ + vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */ + + /* Skip past the fixed information and the VC ID */ + tptr+=11; + tlv_tlen-=11; + TLV_TCHECK(vc_info_len); + + while (vc_info_len > 2) { + vc_info_tlv_type = *tptr; + vc_info_tlv_len = *(tptr+1); + if (vc_info_tlv_len < 2) + break; + if (vc_info_len < vc_info_tlv_len) + break; + + printf("\n\t\tInterface Parameter: %s (0x%02x), len %u", + tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type), + vc_info_tlv_type, + vc_info_tlv_len); + + switch(vc_info_tlv_type) { + case LDP_FEC_MARTINI_IFPARM_MTU: + printf(": %u",EXTRACT_16BITS(tptr+2)); + break; + + case LDP_FEC_MARTINI_IFPARM_DESC: + printf(": "); + for (idx = 2; idx < vc_info_tlv_len; idx++) + safeputchar(*(tptr+idx)); + break; + + case LDP_FEC_MARTINI_IFPARM_VCCV: + printf("\n\t\t Control Channels (0x%02x) = [%s]", + *(tptr+2), + bittok2str(ldp_fec_martini_ifparm_vccv_cc_values,"none",*(tptr+2))); + printf("\n\t\t CV Types (0x%02x) = [%s]", + *(tptr+3), + bittok2str(ldp_fec_martini_ifparm_vccv_cv_values,"none",*(tptr+3))); + break; + + default: + print_unknown_data(tptr+2,"\n\t\t ",vc_info_tlv_len-2); + break; + } + + vc_info_len -= vc_info_tlv_len; + tptr += vc_info_tlv_len; + } + break; + } + + break; + + case LDP_TLV_GENERIC_LABEL: + TLV_TCHECK(4); + printf("\n\t Label: %u", EXTRACT_32BITS(tptr) & 0xfffff); + break; + + case LDP_TLV_STATUS: + TLV_TCHECK(8); + ui = EXTRACT_32BITS(tptr); + tptr+=4; + printf("\n\t Status: 0x%02x, Flags: [%s and %s forward]", + ui&0x3fffffff, + ui&0x80000000 ? "Fatal error" : "Advisory Notification", + ui&0x40000000 ? "do" : "don't"); + ui = EXTRACT_32BITS(tptr); + tptr+=4; + if (ui) + printf(", causing Message ID: 0x%08x", ui); + break; + + case LDP_TLV_FT_SESSION: + TLV_TCHECK(8); + ft_flags = EXTRACT_16BITS(tptr); + printf("\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]", + ft_flags&0x8000 ? "" : "No ", + ft_flags&0x8 ? "" : "Don't ", + ft_flags&0x4 ? "" : "No ", + ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels", + ft_flags&0x1 ? "" : "Don't "); + tptr+=4; + ui = EXTRACT_32BITS(tptr); + if (ui) + printf(", Reconnect Timeout: %ums", ui); + tptr+=4; + ui = EXTRACT_32BITS(tptr); + if (ui) + printf(", Recovery Time: %ums", ui); + break; + + case LDP_TLV_MTU: + TLV_TCHECK(2); + printf("\n\t MTU: %u", EXTRACT_16BITS(tptr)); + break; + + + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case LDP_TLV_HOP_COUNT: + case LDP_TLV_PATH_VECTOR: + case LDP_TLV_ATM_LABEL: + case LDP_TLV_FR_LABEL: + case LDP_TLV_EXTD_STATUS: + case LDP_TLV_RETURNED_PDU: + case LDP_TLV_RETURNED_MSG: + case LDP_TLV_ATM_SESSION_PARM: + case LDP_TLV_FR_SESSION_PARM: + case LDP_TLV_LABEL_REQUEST_MSG_ID: + + default: + if (vflag <= 1) + print_unknown_data(tptr,"\n\t ",tlv_tlen); + break; + } + return(tlv_len+4); /* Type & Length fields not included */ + +trunc: + printf("\n\t\t packet exceeded snapshot"); + return 0; + +badtlv: + printf("\n\t\t TLV contents go past end of TLV"); + return(tlv_len+4); /* Type & Length fields not included */ +} + +void +ldp_print(register const u_char *pptr, register u_int len) { + + int processed; + while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) { + processed = ldp_msg_print(pptr); + if (processed == 0) + return; + len -= processed; + pptr += processed; + } +} + + +int +ldp_msg_print(register const u_char *pptr) { + + const struct ldp_common_header *ldp_com_header; + const struct ldp_msg_header *ldp_msg_header; + const u_char *tptr,*msg_tptr; + u_short tlen; + u_short pdu_len,msg_len,msg_type,msg_tlen; + int hexdump,processed; + + tptr=pptr; + ldp_com_header = (const struct ldp_common_header *)pptr; + TCHECK(*ldp_com_header); + + /* + * Sanity checking of the header. + */ + if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) { + printf("%sLDP version %u packet not supported", + (vflag < 1) ? "" : "\n\t", + EXTRACT_16BITS(&ldp_com_header->version)); + return 0; + } + + /* print the LSR-ID, label-space & length */ + pdu_len = EXTRACT_16BITS(&ldp_com_header->pdu_length); + printf("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u", + (vflag < 1) ? "" : "\n\t", + ipaddr_string(&ldp_com_header->lsr_id), + EXTRACT_16BITS(&ldp_com_header->label_space), + pdu_len); + + /* bail out if non-verbose */ + if (vflag < 1) + return 0; + + /* ok they seem to want to know everything - lets fully decode it */ + tlen=pdu_len; + + tptr += sizeof(const struct ldp_common_header); + tlen -= sizeof(const struct ldp_common_header)-4; /* Type & Length fields not included */ + + while(tlen>0) { + /* did we capture enough for fully decoding the msg header ? */ + TCHECK2(*tptr, sizeof(struct ldp_msg_header)); + + ldp_msg_header = (const struct ldp_msg_header *)tptr; + msg_len=EXTRACT_16BITS(ldp_msg_header->length); + msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type)); + + /* FIXME vendor private / experimental check */ + printf("\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]", + tok2str(ldp_msg_values, + "Unknown", + msg_type), + msg_type, + msg_len, + EXTRACT_32BITS(&ldp_msg_header->id), + LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore"); + + if (msg_len == 0) /* infinite loop protection */ + return 0; + + msg_tptr=tptr+sizeof(struct ldp_msg_header); + msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */ + + /* did we capture enough for fully decoding the message ? */ + TCHECK2(*tptr, msg_len); + hexdump=FALSE; + + switch(msg_type) { + + case LDP_MSG_NOTIF: + case LDP_MSG_HELLO: + case LDP_MSG_INIT: + case LDP_MSG_KEEPALIVE: + case LDP_MSG_ADDRESS: + case LDP_MSG_LABEL_MAPPING: + case LDP_MSG_ADDRESS_WITHDRAW: + case LDP_MSG_LABEL_WITHDRAW: + while(msg_tlen >= 4) { + processed = ldp_tlv_print(msg_tptr); + if (processed == 0) + break; + msg_tlen-=processed; + msg_tptr+=processed; + } + break; + + /* + * FIXME those are the defined messages that lack a decoder + * you are welcome to contribute code ;-) + */ + + case LDP_MSG_LABEL_REQUEST: + case LDP_MSG_LABEL_RELEASE: + case LDP_MSG_LABEL_ABORT_REQUEST: + + default: + if (vflag <= 1) + print_unknown_data(msg_tptr,"\n\t ",msg_tlen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag > 1 || hexdump==TRUE) + print_unknown_data(tptr+sizeof(struct ldp_msg_header),"\n\t ", + msg_len); + + tptr += msg_len+4; + tlen -= msg_len+4; + } + return pdu_len+4; +trunc: + printf("\n\t\t packet exceeded snapshot"); + return 0; +} + diff --git a/freebsd/contrib/tcpdump/print-llc.c b/freebsd/contrib/tcpdump/print-llc.c new file mode 100644 index 00000000..f8801d39 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-llc.c @@ -0,0 +1,549 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * Code by Matt Thomas, Digital Equipment Corporation + * with an awful lot of hacking by Jeffrey Mogul, DECWRL + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.75 2007-04-13 09:43:11 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#include "llc.h" +#include "ethertype.h" +#include "oui.h" + +static struct tok llc_values[] = { + { LLCSAP_NULL, "Null" }, + { LLCSAP_GLOBAL, "Global" }, + { LLCSAP_8021B_I, "802.1B I" }, + { LLCSAP_8021B_G, "802.1B G" }, + { LLCSAP_IP, "IP" }, + { LLCSAP_SNA, "SNA" }, + { LLCSAP_PROWAYNM, "ProWay NM" }, + { LLCSAP_8021D, "STP" }, + { LLCSAP_RS511, "RS511" }, + { LLCSAP_ISO8208, "ISO8208" }, + { LLCSAP_PROWAY, "ProWay" }, + { LLCSAP_SNAP, "SNAP" }, + { LLCSAP_IPX, "IPX" }, + { LLCSAP_NETBEUI, "NetBeui" }, + { LLCSAP_ISONS, "OSI" }, + { 0, NULL }, +}; + +static struct tok llc_cmd_values[] = { + { LLC_UI, "ui" }, + { LLC_TEST, "test" }, + { LLC_XID, "xid" }, + { LLC_UA, "ua" }, + { LLC_DISC, "disc" }, + { LLC_DM, "dm" }, + { LLC_SABME, "sabme" }, + { LLC_FRMR, "frmr" }, + { 0, NULL } +}; + +static const struct tok llc_flag_values[] = { + { 0, "Command" }, + { LLC_GSAP, "Response" }, + { LLC_U_POLL, "Poll" }, + { LLC_GSAP|LLC_U_POLL, "Final" }, + { LLC_IS_POLL, "Poll" }, + { LLC_GSAP|LLC_IS_POLL, "Final" }, + { 0, NULL } +}; + + +static const struct tok llc_ig_flag_values[] = { + { 0, "Individual" }, + { LLC_IG, "Group" }, + { 0, NULL } +}; + + +static const struct tok llc_supervisory_values[] = { + { 0, "Receiver Ready" }, + { 1, "Receiver not Ready" }, + { 2, "Reject" }, + { 0, NULL } +}; + + +static const struct tok cisco_values[] = { + { PID_CISCO_CDP, "CDP" }, + { PID_CISCO_VTP, "VTP" }, + { PID_CISCO_DTP, "DTP" }, + { PID_CISCO_UDLD, "UDLD" }, + { PID_CISCO_PVST, "PVST" }, + { 0, NULL } +}; + +static const struct tok bridged_values[] = { + { PID_RFC2684_ETH_FCS, "Ethernet + FCS" }, + { PID_RFC2684_ETH_NOFCS, "Ethernet w/o FCS" }, + { PID_RFC2684_802_4_FCS, "802.4 + FCS" }, + { PID_RFC2684_802_4_NOFCS, "802.4 w/o FCS" }, + { PID_RFC2684_802_5_FCS, "Token Ring + FCS" }, + { PID_RFC2684_802_5_NOFCS, "Token Ring w/o FCS" }, + { PID_RFC2684_FDDI_FCS, "FDDI + FCS" }, + { PID_RFC2684_FDDI_NOFCS, "FDDI w/o FCS" }, + { PID_RFC2684_802_6_FCS, "802.6 + FCS" }, + { PID_RFC2684_802_6_NOFCS, "802.6 w/o FCS" }, + { PID_RFC2684_BPDU, "BPDU" }, + { 0, NULL }, +}; + +static const struct tok null_values[] = { + { 0, NULL } +}; + +struct oui_tok { + u_int32_t oui; + const struct tok *tok; +}; + +static const struct oui_tok oui_to_tok[] = { + { OUI_ENCAP_ETHER, ethertype_values }, + { OUI_CISCO_90, ethertype_values }, /* uses some Ethertype values */ + { OUI_APPLETALK, ethertype_values }, /* uses some Ethertype values */ + { OUI_CISCO, cisco_values }, + { OUI_RFC2684, bridged_values }, /* bridged, RFC 2427 FR or RFC 2864 ATM */ + { 0, NULL } +}; + +/* + * Returns non-zero IFF it succeeds in printing the header + */ +int +llc_print(const u_char *p, u_int length, u_int caplen, + const u_char *esrc, const u_char *edst, u_short *extracted_ethertype) +{ + u_int8_t dsap_field, dsap, ssap_field, ssap; + u_int16_t control; + int is_u; + register int ret; + + *extracted_ethertype = 0; + + if (caplen < 3) { + (void)printf("[|llc]"); + default_print((u_char *)p, caplen); + return(0); + } + + dsap_field = *p; + ssap_field = *(p + 1); + + /* + * OK, what type of LLC frame is this? The length + * of the control field depends on that - I frames + * have a two-byte control field, and U frames have + * a one-byte control field. + */ + control = *(p + 2); + if ((control & LLC_U_FMT) == LLC_U_FMT) { + /* + * U frame. + */ + is_u = 1; + } else { + /* + * The control field in I and S frames is + * 2 bytes... + */ + if (caplen < 4) { + (void)printf("[|llc]"); + default_print((u_char *)p, caplen); + return(0); + } + + /* + * ...and is little-endian. + */ + control = EXTRACT_LE_16BITS(p + 2); + is_u = 0; + } + + if (ssap_field == LLCSAP_GLOBAL && dsap_field == LLCSAP_GLOBAL) { + /* + * This is an Ethernet_802.3 IPX frame; it has an + * 802.3 header (i.e., an Ethernet header where the + * type/length field is <= ETHERMTU, i.e. it's a length + * field, not a type field), but has no 802.2 header - + * the IPX packet starts right after the Ethernet header, + * with a signature of two bytes of 0xFF (which is + * LLCSAP_GLOBAL). + * + * (It might also have been an Ethernet_802.3 IPX at + * one time, but got bridged onto another network, + * such as an 802.11 network; this has appeared in at + * least one capture file.) + */ + + if (eflag) + printf("IPX 802.3: "); + + ipx_print(p, length); + return (1); + } + + dsap = dsap_field & ~LLC_IG; + ssap = ssap_field & ~LLC_GSAP; + + if (eflag) { + printf("LLC, dsap %s (0x%02x) %s, ssap %s (0x%02x) %s", + tok2str(llc_values, "Unknown", dsap), + dsap, + tok2str(llc_ig_flag_values, "Unknown", dsap_field & LLC_IG), + tok2str(llc_values, "Unknown", ssap), + ssap, + tok2str(llc_flag_values, "Unknown", ssap_field & LLC_GSAP)); + + if (is_u) { + printf(", ctrl 0x%02x: ", control); + } else { + printf(", ctrl 0x%04x: ", control); + } + } + + if (ssap == LLCSAP_8021D && dsap == LLCSAP_8021D && + control == LLC_UI) { + stp_print(p+3, length-3); + return (1); + } + + if (ssap == LLCSAP_IP && dsap == LLCSAP_IP && + control == LLC_UI) { + ip_print(gndo, p+4, length-4); + return (1); + } + + if (ssap == LLCSAP_IPX && dsap == LLCSAP_IPX && + control == LLC_UI) { + /* + * This is an Ethernet_802.2 IPX frame, with an 802.3 + * header and an 802.2 LLC header with the source and + * destination SAPs being the IPX SAP. + * + * Skip DSAP, LSAP, and control field. + */ + if (eflag) + printf("IPX 802.2: "); + + ipx_print(p+3, length-3); + return (1); + } + +#ifdef TCPDUMP_DO_SMB + if (ssap == LLCSAP_NETBEUI && dsap == LLCSAP_NETBEUI + && (!(control & LLC_S_FMT) || control == LLC_U_FMT)) { + /* + * we don't actually have a full netbeui parser yet, but the + * smb parser can handle many smb-in-netbeui packets, which + * is very useful, so we call that + * + * We don't call it for S frames, however, just I frames + * (which are frames that don't have the low-order bit, + * LLC_S_FMT, set in the first byte of the control field) + * and UI frames (whose control field is just 3, LLC_U_FMT). + */ + + /* + * Skip the LLC header. + */ + if (is_u) { + p += 3; + length -= 3; + caplen -= 3; + } else { + p += 4; + length -= 4; + caplen -= 4; + } + netbeui_print(control, p, length); + return (1); + } +#endif + if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS + && control == LLC_UI) { + isoclns_print(p + 3, length - 3, caplen - 3); + return (1); + } + + if (ssap == LLCSAP_SNAP && dsap == LLCSAP_SNAP + && control == LLC_UI) { + /* + * XXX - what *is* the right bridge pad value here? + * Does anybody ever bridge one form of LAN traffic + * over a networking type that uses 802.2 LLC? + */ + ret = snap_print(p+3, length-3, caplen-3, 2); + if (ret) + return (ret); + } + + if (!eflag) { + if (ssap == dsap) { + if (esrc == NULL || edst == NULL) + (void)printf("%s ", tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); + else + (void)printf("%s > %s %s ", + etheraddr_string(esrc), + etheraddr_string(edst), + tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); + } else { + if (esrc == NULL || edst == NULL) + (void)printf("%s > %s ", + tok2str(llc_values, "Unknown SSAP 0x%02x", ssap), + tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); + else + (void)printf("%s %s > %s %s ", + etheraddr_string(esrc), + tok2str(llc_values, "Unknown SSAP 0x%02x", ssap), + etheraddr_string(edst), + tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); + } + } + + if (is_u) { + printf("Unnumbered, %s, Flags [%s], length %u", + tok2str(llc_cmd_values, "%02x", LLC_U_CMD(control)), + tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_U_POLL)), + length); + + p += 3; + length -= 3; + caplen -= 3; + + if ((control & ~LLC_U_POLL) == LLC_XID) { + if (*p == LLC_XID_FI) { + printf(": %02x %02x", p[1], p[2]); + p += 3; + length -= 3; + caplen -= 3; + } + } + } else { + if ((control & LLC_S_FMT) == LLC_S_FMT) { + (void)printf("Supervisory, %s, rcv seq %u, Flags [%s], length %u", + tok2str(llc_supervisory_values,"?",LLC_S_CMD(control)), + LLC_IS_NR(control), + tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)), + length); + } else { + (void)printf("Information, send seq %u, rcv seq %u, Flags [%s], length %u", + LLC_I_NS(control), + LLC_IS_NR(control), + tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)), + length); + } + p += 4; + length -= 4; + caplen -= 4; + } + return(1); +} + +int +snap_print(const u_char *p, u_int length, u_int caplen, u_int bridge_pad) +{ + u_int32_t orgcode; + register u_short et; + register int ret; + + TCHECK2(*p, 5); + orgcode = EXTRACT_24BITS(p); + et = EXTRACT_16BITS(p + 3); + + if (eflag) { + const struct tok *tok = null_values; + const struct oui_tok *otp; + + for (otp = &oui_to_tok[0]; otp->tok != NULL; otp++) { + if (otp->oui == orgcode) { + tok = otp->tok; + break; + } + } + (void)printf("oui %s (0x%06x), %s %s (0x%04x): ", + tok2str(oui_values, "Unknown", orgcode), + orgcode, + (orgcode == 0x000000 ? "ethertype" : "pid"), + tok2str(tok, "Unknown", et), + et); + } + p += 5; + length -= 5; + caplen -= 5; + + switch (orgcode) { + case OUI_ENCAP_ETHER: + case OUI_CISCO_90: + /* + * This is an encapsulated Ethernet packet, + * or a packet bridged by some piece of + * Cisco hardware; the protocol ID is + * an Ethernet protocol type. + */ + ret = ethertype_print(gndo, et, p, length, caplen); + if (ret) + return (ret); + break; + + case OUI_APPLETALK: + if (et == ETHERTYPE_ATALK) { + /* + * No, I have no idea why Apple used one + * of their own OUIs, rather than + * 0x000000, and an Ethernet packet + * type, for Appletalk data packets, + * but used 0x000000 and an Ethernet + * packet type for AARP packets. + */ + ret = ethertype_print(gndo, et, p, length, caplen); + if (ret) + return (ret); + } + break; + + case OUI_CISCO: + switch (et) { + case PID_CISCO_CDP: + cdp_print(p, length, caplen); + return (1); + case PID_CISCO_DTP: + dtp_print(p, length); + return (1); + case PID_CISCO_UDLD: + udld_print(p, length); + return (1); + case PID_CISCO_VTP: + vtp_print(p, length); + return (1); + case PID_CISCO_PVST: + stp_print(p, length); + return (1); + default: + break; + } + + case OUI_RFC2684: + switch (et) { + + case PID_RFC2684_ETH_FCS: + case PID_RFC2684_ETH_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding. + */ + TCHECK2(*p, bridge_pad); + caplen -= bridge_pad; + length -= bridge_pad; + p += bridge_pad; + + /* + * What remains is an Ethernet packet. + */ + ether_print(gndo, p, length, caplen, NULL, NULL); + return (1); + + case PID_RFC2684_802_5_FCS: + case PID_RFC2684_802_5_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding, but not the Access + * Control field. + */ + TCHECK2(*p, bridge_pad); + caplen -= bridge_pad; + length -= bridge_pad; + p += bridge_pad; + + /* + * What remains is an 802.5 Token Ring + * packet. + */ + token_print(p, length, caplen); + return (1); + + case PID_RFC2684_FDDI_FCS: + case PID_RFC2684_FDDI_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding. + */ + TCHECK2(*p, bridge_pad + 1); + caplen -= bridge_pad + 1; + length -= bridge_pad + 1; + p += bridge_pad + 1; + + /* + * What remains is an FDDI packet. + */ + fddi_print(p, length, caplen); + return (1); + + case PID_RFC2684_BPDU: + stp_print(p, length); + return (1); + } + } + return (0); + +trunc: + (void)printf("[|snap]"); + return (1); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-lldp.c b/freebsd/contrib/tcpdump/print-lldp.c new file mode 100644 index 00000000..24e1c860 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-lldp.c @@ -0,0 +1,1415 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * support for the IEEE Link Discovery Protocol as per 802.1AB + * + * Original code by Hannes Gredler (hannes@juniper.net) + * IEEE and TIA extensions by Carles Kishimoto <carles.kishimoto@gmail.com> + * DCBX extensions by Kaladhar Musunuru <kaladharm@sourceforge.net> + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-lldp.c,v 1.10 2008-03-20 09:30:56 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "af.h" +#include "oui.h" + +#define LLDP_EXTRACT_TYPE(x) (((x)&0xfe00)>>9) +#define LLDP_EXTRACT_LEN(x) ((x)&0x01ff) + +/* + * TLV type codes + */ +#define LLDP_END_TLV 0 +#define LLDP_CHASSIS_ID_TLV 1 +#define LLDP_PORT_ID_TLV 2 +#define LLDP_TTL_TLV 3 +#define LLDP_PORT_DESCR_TLV 4 +#define LLDP_SYSTEM_NAME_TLV 5 +#define LLDP_SYSTEM_DESCR_TLV 6 +#define LLDP_SYSTEM_CAP_TLV 7 +#define LLDP_MGMT_ADDR_TLV 8 +#define LLDP_PRIVATE_TLV 127 + +static const struct tok lldp_tlv_values[] = { + { LLDP_END_TLV, "End" }, + { LLDP_CHASSIS_ID_TLV, "Chassis ID" }, + { LLDP_PORT_ID_TLV, "Port ID" }, + { LLDP_TTL_TLV, "Time to Live" }, + { LLDP_PORT_DESCR_TLV, "Port Description" }, + { LLDP_SYSTEM_NAME_TLV, "System Name" }, + { LLDP_SYSTEM_DESCR_TLV, "System Description" }, + { LLDP_SYSTEM_CAP_TLV, "System Capabilities" }, + { LLDP_MGMT_ADDR_TLV, "Management Address" }, + { LLDP_PRIVATE_TLV, "Organization specific" }, + { 0, NULL} +}; + +/* + * Chassis ID subtypes + */ +#define LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE 1 +#define LLDP_CHASSIS_INTF_ALIAS_SUBTYPE 2 +#define LLDP_CHASSIS_PORT_COMP_SUBTYPE 3 +#define LLDP_CHASSIS_MAC_ADDR_SUBTYPE 4 +#define LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE 5 +#define LLDP_CHASSIS_INTF_NAME_SUBTYPE 6 +#define LLDP_CHASSIS_LOCAL_SUBTYPE 7 + +static const struct tok lldp_chassis_subtype_values[] = { + { LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE, "Chassis component"}, + { LLDP_CHASSIS_INTF_ALIAS_SUBTYPE, "Interface alias"}, + { LLDP_CHASSIS_PORT_COMP_SUBTYPE, "Port component"}, + { LLDP_CHASSIS_MAC_ADDR_SUBTYPE, "MAC address"}, + { LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE, "Network address"}, + { LLDP_CHASSIS_INTF_NAME_SUBTYPE, "Interface name"}, + { LLDP_CHASSIS_LOCAL_SUBTYPE, "Local"}, + { 0, NULL} +}; + +/* + * Port ID subtypes + */ +#define LLDP_PORT_INTF_ALIAS_SUBTYPE 1 +#define LLDP_PORT_PORT_COMP_SUBTYPE 2 +#define LLDP_PORT_MAC_ADDR_SUBTYPE 3 +#define LLDP_PORT_NETWORK_ADDR_SUBTYPE 4 +#define LLDP_PORT_INTF_NAME_SUBTYPE 5 +#define LLDP_PORT_AGENT_CIRC_ID_SUBTYPE 6 +#define LLDP_PORT_LOCAL_SUBTYPE 7 + +static const struct tok lldp_port_subtype_values[] = { + { LLDP_PORT_INTF_ALIAS_SUBTYPE, "Interface alias"}, + { LLDP_PORT_PORT_COMP_SUBTYPE, "Port component"}, + { LLDP_PORT_MAC_ADDR_SUBTYPE, "MAC address"}, + { LLDP_PORT_NETWORK_ADDR_SUBTYPE, "Network Address"}, + { LLDP_PORT_INTF_NAME_SUBTYPE, "Interface Name"}, + { LLDP_PORT_AGENT_CIRC_ID_SUBTYPE, "Agent circuit ID"}, + { LLDP_PORT_LOCAL_SUBTYPE, "Local"}, + { 0, NULL} +}; + +/* + * System Capabilities + */ +#define LLDP_CAP_OTHER (1 << 0) +#define LLDP_CAP_REPEATER (1 << 1) +#define LLDP_CAP_BRIDGE (1 << 2) +#define LLDP_CAP_WLAN_AP (1 << 3) +#define LLDP_CAP_ROUTER (1 << 4) +#define LLDP_CAP_PHONE (1 << 5) +#define LLDP_CAP_DOCSIS (1 << 6) +#define LLDP_CAP_STATION_ONLY (1 << 7) + +static const struct tok lldp_cap_values[] = { + { LLDP_CAP_OTHER, "Other"}, + { LLDP_CAP_REPEATER, "Repeater"}, + { LLDP_CAP_BRIDGE, "Bridge"}, + { LLDP_CAP_WLAN_AP, "WLAN AP"}, + { LLDP_CAP_ROUTER, "Router"}, + { LLDP_CAP_PHONE, "Telephone"}, + { LLDP_CAP_DOCSIS, "Docsis"}, + { LLDP_CAP_STATION_ONLY, "Station Only"}, + { 0, NULL} +}; + +#define LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID 1 +#define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID 2 +#define LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME 3 +#define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY 4 + +static const struct tok lldp_8021_subtype_values[] = { + { LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID, "Port VLAN Id"}, + { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID, "Port and Protocol VLAN ID"}, + { LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME, "VLAN name"}, + { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY, "Protocol Identity"}, + { 0, NULL} +}; + +#define LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT (1 << 1) +#define LLDP_8021_PORT_PROTOCOL_VLAN_STATUS (1 << 2) + +static const struct tok lldp_8021_port_protocol_id_values[] = { + { LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT, "supported"}, + { LLDP_8021_PORT_PROTOCOL_VLAN_STATUS, "enabled"}, + { 0, NULL} +}; + +#define LLDP_PRIVATE_8023_SUBTYPE_MACPHY 1 +#define LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER 2 +#define LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR 3 +#define LLDP_PRIVATE_8023_SUBTYPE_MTU 4 + +static const struct tok lldp_8023_subtype_values[] = { + { LLDP_PRIVATE_8023_SUBTYPE_MACPHY, "MAC/PHY configuration/status"}, + { LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER, "Power via MDI"}, + { LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR, "Link aggregation"}, + { LLDP_PRIVATE_8023_SUBTYPE_MTU, "Max frame size"}, + { 0, NULL} +}; + +#define LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES 1 +#define LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY 2 +#define LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID 3 +#define LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI 4 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV 5 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV 6 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV 7 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER 8 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME 9 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME 10 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID 11 + +static const struct tok lldp_tia_subtype_values[] = { + { LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES, "LLDP-MED Capabilities" }, + { LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY, "Network policy" }, + { LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID, "Location identification" }, + { LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI, "Extended power-via-MDI" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Inventory - hardware revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Inventory - firmware revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Inventory - software revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Inventory - serial number" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Inventory - manufacturer name" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Inventory - model name" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Inventory - asset ID" }, + { 0, NULL} +}; + +#define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS 1 +#define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS 2 + +static const struct tok lldp_tia_location_altitude_type_values[] = { + { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS, "meters"}, + { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS, "floors"}, + { 0, NULL} +}; + +/* ANSI/TIA-1057 - Annex B */ +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1 1 +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2 2 +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3 3 +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4 4 +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5 5 +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6 6 + +static const struct tok lldp_tia_location_lci_catype_values[] = { + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1, "national subdivisions (state,canton,region,province,prefecture)"}, + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2, "county, parish, gun, district"}, + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3, "city, township, shi"}, + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4, "city division, borough, city district, ward chou"}, + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5, "neighborhood, block"}, + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6, "street"}, + { 0, NULL} +}; + +static const struct tok lldp_tia_location_lci_what_values[] = { + { 0, "location of DHCP server"}, + { 1, "location of the network element believed to be closest to the client"}, + { 2, "location of the client"}, + { 0, NULL} +}; + +/* + * From RFC 3636 - dot3MauType + */ +#define LLDP_MAU_TYPE_UNKNOWN 0 +#define LLDP_MAU_TYPE_AUI 1 +#define LLDP_MAU_TYPE_10BASE_5 2 +#define LLDP_MAU_TYPE_FOIRL 3 +#define LLDP_MAU_TYPE_10BASE_2 4 +#define LLDP_MAU_TYPE_10BASE_T 5 +#define LLDP_MAU_TYPE_10BASE_FP 6 +#define LLDP_MAU_TYPE_10BASE_FB 7 +#define LLDP_MAU_TYPE_10BASE_FL 8 +#define LLDP_MAU_TYPE_10BROAD36 9 +#define LLDP_MAU_TYPE_10BASE_T_HD 10 +#define LLDP_MAU_TYPE_10BASE_T_FD 11 +#define LLDP_MAU_TYPE_10BASE_FL_HD 12 +#define LLDP_MAU_TYPE_10BASE_FL_FD 13 +#define LLDP_MAU_TYPE_100BASE_T4 14 +#define LLDP_MAU_TYPE_100BASE_TX_HD 15 +#define LLDP_MAU_TYPE_100BASE_TX_FD 16 +#define LLDP_MAU_TYPE_100BASE_FX_HD 17 +#define LLDP_MAU_TYPE_100BASE_FX_FD 18 +#define LLDP_MAU_TYPE_100BASE_T2_HD 19 +#define LLDP_MAU_TYPE_100BASE_T2_FD 20 +#define LLDP_MAU_TYPE_1000BASE_X_HD 21 +#define LLDP_MAU_TYPE_1000BASE_X_FD 22 +#define LLDP_MAU_TYPE_1000BASE_LX_HD 23 +#define LLDP_MAU_TYPE_1000BASE_LX_FD 24 +#define LLDP_MAU_TYPE_1000BASE_SX_HD 25 +#define LLDP_MAU_TYPE_1000BASE_SX_FD 26 +#define LLDP_MAU_TYPE_1000BASE_CX_HD 27 +#define LLDP_MAU_TYPE_1000BASE_CX_FD 28 +#define LLDP_MAU_TYPE_1000BASE_T_HD 29 +#define LLDP_MAU_TYPE_1000BASE_T_FD 30 +#define LLDP_MAU_TYPE_10GBASE_X 31 +#define LLDP_MAU_TYPE_10GBASE_LX4 32 +#define LLDP_MAU_TYPE_10GBASE_R 33 +#define LLDP_MAU_TYPE_10GBASE_ER 34 +#define LLDP_MAU_TYPE_10GBASE_LR 35 +#define LLDP_MAU_TYPE_10GBASE_SR 36 +#define LLDP_MAU_TYPE_10GBASE_W 37 +#define LLDP_MAU_TYPE_10GBASE_EW 38 +#define LLDP_MAU_TYPE_10GBASE_LW 39 +#define LLDP_MAU_TYPE_10GBASE_SW 40 + +static const struct tok lldp_mau_types_values[] = { + { LLDP_MAU_TYPE_UNKNOWN, "Unknown"}, + { LLDP_MAU_TYPE_AUI, "AUI"}, + { LLDP_MAU_TYPE_10BASE_5, "10BASE_5"}, + { LLDP_MAU_TYPE_FOIRL, "FOIRL"}, + { LLDP_MAU_TYPE_10BASE_2, "10BASE2"}, + { LLDP_MAU_TYPE_10BASE_T, "10BASET duplex mode unknown"}, + { LLDP_MAU_TYPE_10BASE_FP, "10BASEFP"}, + { LLDP_MAU_TYPE_10BASE_FB, "10BASEFB"}, + { LLDP_MAU_TYPE_10BASE_FL, "10BASEFL duplex mode unknown"}, + { LLDP_MAU_TYPE_10BROAD36, "10BROAD36"}, + { LLDP_MAU_TYPE_10BASE_T_HD, "10BASET hdx"}, + { LLDP_MAU_TYPE_10BASE_T_FD, "10BASET fdx"}, + { LLDP_MAU_TYPE_10BASE_FL_HD, "10BASEFL hdx"}, + { LLDP_MAU_TYPE_10BASE_FL_FD, "10BASEFL fdx"}, + { LLDP_MAU_TYPE_100BASE_T4, "100BASET4"}, + { LLDP_MAU_TYPE_100BASE_TX_HD, "100BASETX hdx"}, + { LLDP_MAU_TYPE_100BASE_TX_FD, "100BASETX fdx"}, + { LLDP_MAU_TYPE_100BASE_FX_HD, "100BASEFX hdx"}, + { LLDP_MAU_TYPE_100BASE_FX_FD, "100BASEFX fdx"}, + { LLDP_MAU_TYPE_100BASE_T2_HD, "100BASET2 hdx"}, + { LLDP_MAU_TYPE_100BASE_T2_FD, "100BASET2 fdx"}, + { LLDP_MAU_TYPE_1000BASE_X_HD, "1000BASEX hdx"}, + { LLDP_MAU_TYPE_1000BASE_X_FD, "1000BASEX fdx"}, + { LLDP_MAU_TYPE_1000BASE_LX_HD, "1000BASELX hdx"}, + { LLDP_MAU_TYPE_1000BASE_LX_FD, "1000BASELX fdx"}, + { LLDP_MAU_TYPE_1000BASE_SX_HD, "1000BASESX hdx"}, + { LLDP_MAU_TYPE_1000BASE_SX_FD, "1000BASESX fdx"}, + { LLDP_MAU_TYPE_1000BASE_CX_HD, "1000BASECX hdx"}, + { LLDP_MAU_TYPE_1000BASE_CX_FD, "1000BASECX fdx"}, + { LLDP_MAU_TYPE_1000BASE_T_HD, "1000BASET hdx"}, + { LLDP_MAU_TYPE_1000BASE_T_FD, "1000BASET fdx"}, + { LLDP_MAU_TYPE_10GBASE_X, "10GBASEX"}, + { LLDP_MAU_TYPE_10GBASE_LX4, "10GBASELX4"}, + { LLDP_MAU_TYPE_10GBASE_R, "10GBASER"}, + { LLDP_MAU_TYPE_10GBASE_ER, "10GBASEER"}, + { LLDP_MAU_TYPE_10GBASE_LR, "10GBASELR"}, + { LLDP_MAU_TYPE_10GBASE_SR, "10GBASESR"}, + { LLDP_MAU_TYPE_10GBASE_W, "10GBASEW"}, + { LLDP_MAU_TYPE_10GBASE_EW, "10GBASEEW"}, + { LLDP_MAU_TYPE_10GBASE_LW, "10GBASELW"}, + { LLDP_MAU_TYPE_10GBASE_SW, "10GBASESW"}, + { 0, NULL} +}; + +#define LLDP_8023_AUTONEGOTIATION_SUPPORT (1 << 0) +#define LLDP_8023_AUTONEGOTIATION_STATUS (1 << 1) + +static const struct tok lldp_8023_autonegotiation_values[] = { + { LLDP_8023_AUTONEGOTIATION_SUPPORT, "supported"}, + { LLDP_8023_AUTONEGOTIATION_STATUS, "enabled"}, + { 0, NULL} +}; + +#define LLDP_TIA_CAPABILITY_MED (1 << 0) +#define LLDP_TIA_CAPABILITY_NETWORK_POLICY (1 << 1) +#define LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION (1 << 2) +#define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE (1 << 3) +#define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD (1 << 4) +#define LLDP_TIA_CAPABILITY_INVENTORY (1 << 5) + +static const struct tok lldp_tia_capabilities_values[] = { + { LLDP_TIA_CAPABILITY_MED, "LLDP-MED capabilities"}, + { LLDP_TIA_CAPABILITY_NETWORK_POLICY, "network policy"}, + { LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION, "location identification"}, + { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE, "extended power via MDI-PSE"}, + { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD, "extended power via MDI-PD"}, + { LLDP_TIA_CAPABILITY_INVENTORY, "Inventory"}, + { 0, NULL} +}; + +#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1 1 +#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2 2 +#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3 3 +#define LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY 4 + +static const struct tok lldp_tia_device_type_values[] = { + { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1, "endpoint class 1"}, + { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2, "endpoint class 2"}, + { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3, "endpoint class 3"}, + { LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY, "network connectivity"}, + { 0, NULL} +}; + +#define LLDP_TIA_APPLICATION_TYPE_VOICE 1 +#define LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING 2 +#define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE 3 +#define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING 4 +#define LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE 5 +#define LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING 6 +#define LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO 7 +#define LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING 8 + +static const struct tok lldp_tia_application_type_values[] = { + { LLDP_TIA_APPLICATION_TYPE_VOICE, "voice"}, + { LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING, "voice signaling"}, + { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE, "guest voice"}, + { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING, "guest voice signaling"}, + { LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE, "softphone voice"}, + { LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING, "video conferencing"}, + { LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO, "streaming video"}, + { LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING, "video signaling"}, + { 0, NULL} +}; + +#define LLDP_TIA_NETWORK_POLICY_X_BIT (1 << 5) +#define LLDP_TIA_NETWORK_POLICY_T_BIT (1 << 6) +#define LLDP_TIA_NETWORK_POLICY_U_BIT (1 << 7) + +static const struct tok lldp_tia_network_policy_bits_values[] = { + { LLDP_TIA_NETWORK_POLICY_U_BIT, "Unknown"}, + { LLDP_TIA_NETWORK_POLICY_T_BIT, "Tagged"}, + { LLDP_TIA_NETWORK_POLICY_X_BIT, "reserved"}, + { 0, NULL} +}; + +#define LLDP_EXTRACT_NETWORK_POLICY_VLAN(x) (((x)&0x1ffe)>>1) +#define LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(x) (((x)&0x01ff)>>6) +#define LLDP_EXTRACT_NETWORK_POLICY_DSCP(x) ((x)&0x003f) + +#define LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED 1 +#define LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS 2 +#define LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN 3 + +static const struct tok lldp_tia_location_data_format_values[] = { + { LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED, "coordinate-based LCI"}, + { LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS, "civic address LCI"}, + { LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN, "ECS ELIN"}, + { 0, NULL} +}; + +#define LLDP_TIA_LOCATION_DATUM_WGS_84 1 +#define LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88 2 +#define LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW 3 + +static const struct tok lldp_tia_location_datum_type_values[] = { + { LLDP_TIA_LOCATION_DATUM_WGS_84, "World Geodesic System 1984"}, + { LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88, "North American Datum 1983 (NAVD88)"}, + { LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW, "North American Datum 1983 (MLLW)"}, + { 0, NULL} +}; + +#define LLDP_TIA_POWER_SOURCE_PSE 1 +#define LLDP_TIA_POWER_SOURCE_LOCAL 2 +#define LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL 3 + +static const struct tok lldp_tia_power_source_values[] = { + { LLDP_TIA_POWER_SOURCE_PSE, "PSE - primary power source"}, + { LLDP_TIA_POWER_SOURCE_LOCAL, "local - backup power source"}, + { LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL, "PSE+local - reserved"}, + { 0, NULL} +}; + +#define LLDP_TIA_POWER_PRIORITY_CRITICAL 1 +#define LLDP_TIA_POWER_PRIORITY_HIGH 2 +#define LLDP_TIA_POWER_PRIORITY_LOW 3 + +static const struct tok lldp_tia_power_priority_values[] = { + { LLDP_TIA_POWER_PRIORITY_CRITICAL, "critical"}, + { LLDP_TIA_POWER_PRIORITY_HIGH, "high"}, + { LLDP_TIA_POWER_PRIORITY_LOW, "low"}, + { 0, NULL} +}; + +#define LLDP_TIA_POWER_VAL_MAX 1024 + +static const struct tok lldp_tia_inventory_values[] = { + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Hardware revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Firmware revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Software revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Serial number" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Manufacturer name" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Model name" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Asset ID" }, + { 0, NULL} +}; + +/* + * From RFC 3636 - ifMauAutoNegCapAdvertisedBits + */ +#define LLDP_MAU_PMD_OTHER (1 << 15) +#define LLDP_MAU_PMD_10BASE_T (1 << 14) +#define LLDP_MAU_PMD_10BASE_T_FD (1 << 13) +#define LLDP_MAU_PMD_100BASE_T4 (1 << 12) +#define LLDP_MAU_PMD_100BASE_TX (1 << 11) +#define LLDP_MAU_PMD_100BASE_TX_FD (1 << 10) +#define LLDP_MAU_PMD_100BASE_T2 (1 << 9) +#define LLDP_MAU_PMD_100BASE_T2_FD (1 << 8) +#define LLDP_MAU_PMD_FDXPAUSE (1 << 7) +#define LLDP_MAU_PMD_FDXAPAUSE (1 << 6) +#define LLDP_MAU_PMD_FDXSPAUSE (1 << 5) +#define LLDP_MAU_PMD_FDXBPAUSE (1 << 4) +#define LLDP_MAU_PMD_1000BASE_X (1 << 3) +#define LLDP_MAU_PMD_1000BASE_X_FD (1 << 2) +#define LLDP_MAU_PMD_1000BASE_T (1 << 1) +#define LLDP_MAU_PMD_1000BASE_T_FD (1 << 0) + +static const struct tok lldp_pmd_capability_values[] = { + { LLDP_MAU_PMD_10BASE_T, "10BASE-T hdx"}, + { LLDP_MAU_PMD_10BASE_T_FD, "10BASE-T fdx"}, + { LLDP_MAU_PMD_100BASE_T4, "100BASE-T4"}, + { LLDP_MAU_PMD_100BASE_TX, "100BASE-TX hdx"}, + { LLDP_MAU_PMD_100BASE_TX_FD, "100BASE-TX fdx"}, + { LLDP_MAU_PMD_100BASE_T2, "100BASE-T2 hdx"}, + { LLDP_MAU_PMD_100BASE_T2_FD, "100BASE-T2 fdx"}, + { LLDP_MAU_PMD_FDXPAUSE, "Pause for fdx links"}, + { LLDP_MAU_PMD_FDXAPAUSE, "Asym PAUSE for fdx"}, + { LLDP_MAU_PMD_FDXSPAUSE, "Sym PAUSE for fdx"}, + { LLDP_MAU_PMD_FDXBPAUSE, "Asym and Sym PAUSE for fdx"}, + { LLDP_MAU_PMD_1000BASE_X, "1000BASE-{X LX SX CX} hdx"}, + { LLDP_MAU_PMD_1000BASE_X_FD, "1000BASE-{X LX SX CX} fdx"}, + { LLDP_MAU_PMD_1000BASE_T, "1000BASE-T hdx"}, + { LLDP_MAU_PMD_1000BASE_T_FD, "1000BASE-T fdx"}, + { 0, NULL} +}; + +#define LLDP_MDI_PORT_CLASS (1 << 0) +#define LLDP_MDI_POWER_SUPPORT (1 << 1) +#define LLDP_MDI_POWER_STATE (1 << 2) +#define LLDP_MDI_PAIR_CONTROL_ABILITY (1 << 3) + +static const struct tok lldp_mdi_values[] = { + { LLDP_MDI_PORT_CLASS, "PSE"}, + { LLDP_MDI_POWER_SUPPORT, "supported"}, + { LLDP_MDI_POWER_STATE, "enabled"}, + { LLDP_MDI_PAIR_CONTROL_ABILITY, "can be controlled"}, + { 0, NULL} +}; + +#define LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL 1 +#define LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE 2 + +static const struct tok lldp_mdi_power_pairs_values[] = { + { LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL, "signal"}, + { LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE, "spare"}, + { 0, NULL} +}; + +#define LLDP_MDI_POWER_CLASS0 1 +#define LLDP_MDI_POWER_CLASS1 2 +#define LLDP_MDI_POWER_CLASS2 3 +#define LLDP_MDI_POWER_CLASS3 4 +#define LLDP_MDI_POWER_CLASS4 5 + +static const struct tok lldp_mdi_power_class_values[] = { + { LLDP_MDI_POWER_CLASS0, "class0"}, + { LLDP_MDI_POWER_CLASS1, "class1"}, + { LLDP_MDI_POWER_CLASS2, "class2"}, + { LLDP_MDI_POWER_CLASS3, "class3"}, + { LLDP_MDI_POWER_CLASS4, "class4"}, + { 0, NULL} +}; + +#define LLDP_AGGREGATION_CAPABILTIY (1 << 0) +#define LLDP_AGGREGATION_STATUS (1 << 1) + +static const struct tok lldp_aggregation_values[] = { + { LLDP_AGGREGATION_CAPABILTIY, "supported"}, + { LLDP_AGGREGATION_STATUS, "enabled"}, + { 0, NULL} +}; + +/* + * DCBX protocol subtypes. + */ +#define LLDP_DCBX_SUBTYPE_1 1 +#define LLDP_DCBX_SUBTYPE_2 2 + +static const struct tok lldp_dcbx_subtype_values[] = { + { LLDP_DCBX_SUBTYPE_1, "DCB Capability Exchange Protocol Rev 1" }, + { LLDP_DCBX_SUBTYPE_2, "DCB Capability Exchange Protocol Rev 1.01" }, + { 0, NULL} +}; + +#define LLDP_DCBX_CONTROL_TLV 1 +#define LLDP_DCBX_PRIORITY_GROUPS_TLV 2 +#define LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV 3 +#define LLDP_DCBX_APPLICATION_TLV 4 + +/* + * Interface numbering subtypes. + */ +#define LLDP_INTF_NUMB_IFX_SUBTYPE 2 +#define LLDP_INTF_NUMB_SYSPORT_SUBTYPE 3 + +static const struct tok lldp_intf_numb_subtype_values[] = { + { LLDP_INTF_NUMB_IFX_SUBTYPE, "Interface Index" }, + { LLDP_INTF_NUMB_SYSPORT_SUBTYPE, "System Port Number" }, + { 0, NULL} +}; + +#define LLDP_INTF_NUM_LEN 5 + +/* + * Print IEEE 802.1 private extensions. (802.1AB annex E) + */ +static int +lldp_private_8021_print(const u_char *tptr, u_int tlv_len) +{ + int subtype, hexdump = FALSE; + u_int sublen; + + if (tlv_len < 4) { + return hexdump; + } + subtype = *(tptr+3); + + printf("\n\t %s Subtype (%u)", + tok2str(lldp_8021_subtype_values, "unknown", subtype), + subtype); + + switch (subtype) { + case LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID: + if (tlv_len < 6) { + return hexdump; + } + printf("\n\t port vlan id (PVID): %u", + EXTRACT_16BITS(tptr+4)); + break; + case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID: + if (tlv_len < 7) { + return hexdump; + } + printf("\n\t port and protocol vlan id (PPVID): %u, flags [%s] (0x%02x)", + EXTRACT_16BITS(tptr+5), + bittok2str(lldp_8021_port_protocol_id_values, "none", *(tptr+4)), + *(tptr+4)); + break; + case LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME: + if (tlv_len < 6) { + return hexdump; + } + printf("\n\t vlan id (VID): %u", + EXTRACT_16BITS(tptr+4)); + if (tlv_len < 7) { + return hexdump; + } + sublen = *(tptr+6); + if (tlv_len < 7+sublen) { + return hexdump; + } + printf("\n\t vlan name: "); + safeputs((const char *)tptr+7, sublen); + break; + case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY: + if (tlv_len < 5) { + return hexdump; + } + sublen = *(tptr+4); + if (tlv_len < 5+sublen) { + return hexdump; + } + printf("\n\t protocol identity: "); + safeputs((const char *)tptr+5, sublen); + break; + + default: + hexdump = TRUE; + break; + } + + return hexdump; +} + +/* + * Print IEEE 802.3 private extensions. (802.3bc) + */ +static int +lldp_private_8023_print(const u_char *tptr, u_int tlv_len) +{ + int subtype, hexdump = FALSE; + + if (tlv_len < 4) { + return hexdump; + } + subtype = *(tptr+3); + + printf("\n\t %s Subtype (%u)", + tok2str(lldp_8023_subtype_values, "unknown", subtype), + subtype); + + switch (subtype) { + case LLDP_PRIVATE_8023_SUBTYPE_MACPHY: + if (tlv_len < 9) { + return hexdump; + } + printf("\n\t autonegotiation [%s] (0x%02x)", + bittok2str(lldp_8023_autonegotiation_values, "none", *(tptr+4)), + *(tptr+4)); + printf("\n\t PMD autoneg capability [%s] (0x%04x)", + bittok2str(lldp_pmd_capability_values,"unknown", EXTRACT_16BITS(tptr+5)), + EXTRACT_16BITS(tptr+5)); + printf("\n\t MAU type %s (0x%04x)", + tok2str(lldp_mau_types_values, "unknown", EXTRACT_16BITS(tptr+7)), + EXTRACT_16BITS(tptr+7)); + break; + + case LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER: + if (tlv_len < 7) { + return hexdump; + } + printf("\n\t MDI power support [%s], power pair %s, power class %s", + bittok2str(lldp_mdi_values, "none", *(tptr+4)), + tok2str(lldp_mdi_power_pairs_values, "unknown", *(tptr+5)), + tok2str(lldp_mdi_power_class_values, "unknown", *(tptr+6))); + break; + + case LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR: + if (tlv_len < 9) { + return hexdump; + } + printf("\n\t aggregation status [%s], aggregation port ID %u", + bittok2str(lldp_aggregation_values, "none", *(tptr+4)), + EXTRACT_32BITS(tptr+5)); + break; + + case LLDP_PRIVATE_8023_SUBTYPE_MTU: + printf("\n\t MTU size %u", EXTRACT_16BITS(tptr+4)); + break; + + default: + hexdump = TRUE; + break; + } + + return hexdump; +} + +/* + * Extract 34bits of latitude/longitude coordinates. + */ +static u_int64_t +lldp_extract_latlon(const u_char *tptr) +{ + u_int64_t latlon; + + latlon = *tptr & 0x3; + latlon = (latlon << 32) | EXTRACT_32BITS(tptr+1); + + return latlon; +} + +/* + * Print private TIA extensions. + */ +static int +lldp_private_tia_print(const u_char *tptr, u_int tlv_len) +{ + int subtype, hexdump = FALSE; + u_int8_t location_format; + u_int16_t power_val; + u_int lci_len; + u_int8_t ca_type, ca_len; + + if (tlv_len < 4) { + return hexdump; + } + subtype = *(tptr+3); + + printf("\n\t %s Subtype (%u)", + tok2str(lldp_tia_subtype_values, "unknown", subtype), + subtype); + + switch (subtype) { + case LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES: + if (tlv_len < 7) { + return hexdump; + } + printf("\n\t Media capabilities [%s] (0x%04x)", + bittok2str(lldp_tia_capabilities_values, "none", + EXTRACT_16BITS(tptr+4)), EXTRACT_16BITS(tptr+4)); + printf("\n\t Device type [%s] (0x%02x)", + tok2str(lldp_tia_device_type_values, "unknown", *(tptr+6)), + *(tptr+6)); + break; + + case LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY: + if (tlv_len < 8) { + return hexdump; + } + printf("\n\t Application type [%s] (0x%02x)", + tok2str(lldp_tia_application_type_values, "none", *(tptr+4)), + *(tptr+4)); + printf(", Flags [%s]", bittok2str( + lldp_tia_network_policy_bits_values, "none", *(tptr+5))); + printf("\n\t Vlan id %u", + LLDP_EXTRACT_NETWORK_POLICY_VLAN(EXTRACT_16BITS(tptr+5))); + printf(", L2 priority %u", + LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(EXTRACT_16BITS(tptr+6))); + printf(", DSCP value %u", + LLDP_EXTRACT_NETWORK_POLICY_DSCP(EXTRACT_16BITS(tptr+6))); + break; + + case LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID: + if (tlv_len < 5) { + return hexdump; + } + location_format = *(tptr+4); + printf("\n\t Location data format %s (0x%02x)", + tok2str(lldp_tia_location_data_format_values, "unknown", location_format), + location_format); + + switch (location_format) { + case LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED: + if (tlv_len < 21) { + return hexdump; + } + printf("\n\t Latitude resolution %u, latitude value %" PRIu64, + (*(tptr+5)>>2), lldp_extract_latlon(tptr+5)); + printf("\n\t Longitude resolution %u, longitude value %" PRIu64, + (*(tptr+10)>>2), lldp_extract_latlon(tptr+10)); + printf("\n\t Altitude type %s (%u)", + tok2str(lldp_tia_location_altitude_type_values, "unknown",(*(tptr+15)>>4)), + (*(tptr+15)>>4)); + printf("\n\t Altitude resolution %u, altitude value 0x%x", + (EXTRACT_16BITS(tptr+15)>>6)&0x3f, + ((EXTRACT_32BITS(tptr+16)&0x3fffffff))); + printf("\n\t Datum %s (0x%02x)", + tok2str(lldp_tia_location_datum_type_values, "unknown", *(tptr+20)), + *(tptr+20)); + break; + + case LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS: + if (tlv_len < 6) { + return hexdump; + } + lci_len = *(tptr+5); + if (lci_len < 3) { + return hexdump; + } + if (tlv_len < 7+lci_len) { + return hexdump; + } + printf("\n\t LCI length %u, LCI what %s (0x%02x), Country-code ", + lci_len, + tok2str(lldp_tia_location_lci_what_values, "unknown", *(tptr+6)), + *(tptr+6)); + + /* Country code */ + safeputs((const char *)(tptr+7), 2); + + lci_len = lci_len-3; + tptr = tptr + 9; + + /* Decode each civic address element */ + while (lci_len > 0) { + if (lci_len < 2) { + return hexdump; + } + ca_type = *(tptr); + ca_len = *(tptr+1); + + tptr += 2; + lci_len -= 2; + + printf("\n\t CA type \'%s\' (%u), length %u: ", + tok2str(lldp_tia_location_lci_catype_values, "unknown", ca_type), + ca_type, ca_len); + + /* basic sanity check */ + if ( ca_type == 0 || ca_len == 0) { + return hexdump; + } + if (lci_len < ca_len) { + return hexdump; + } + + safeputs((const char *)tptr, ca_len); + tptr += ca_len; + lci_len -= ca_len; + } + break; + + case LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN: + printf("\n\t ECS ELIN id "); + safeputs((const char *)tptr+5, tlv_len-5); + break; + + default: + printf("\n\t Location ID "); + print_unknown_data(tptr+5, "\n\t ", tlv_len-5); + } + break; + + case LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI: + if (tlv_len < 7) { + return hexdump; + } + printf("\n\t Power type [%s]", + (*(tptr+4)&0xC0>>6) ? "PD device" : "PSE device"); + printf(", Power source [%s]", + tok2str(lldp_tia_power_source_values, "none", (*(tptr+4)&0x30)>>4)); + printf("\n\t Power priority [%s] (0x%02x)", + tok2str(lldp_tia_power_priority_values, "none", *(tptr+4)&0x0f), + *(tptr+4)&0x0f); + power_val = EXTRACT_16BITS(tptr+5); + if (power_val < LLDP_TIA_POWER_VAL_MAX) { + printf(", Power %.1f Watts", ((float)power_val)/10); + } else { + printf(", Power %u (Reserved)", power_val); + } + break; + + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID: + printf("\n\t %s ", + tok2str(lldp_tia_inventory_values, "unknown", subtype)); + safeputs((const char *)tptr+4, tlv_len-4); + break; + + default: + hexdump = TRUE; + break; + } + + return hexdump; +} + +/* + * Print DCBX Protocol fields (V 1.01). + */ +static int +lldp_private_dcbx_print(const u_char *pptr, u_int len) +{ + int subtype, hexdump = FALSE; + u_int8_t tval; + u_int16_t tlv; + u_int32_t i, pgval, uval; + u_int tlen, tlv_type, tlv_len; + const u_char *tptr, *mptr; + + if (len < 4) { + return hexdump; + } + subtype = *(pptr+3); + + printf("\n\t %s Subtype (%u)", + tok2str(lldp_dcbx_subtype_values, "unknown", subtype), + subtype); + + /* by passing old version */ + if (subtype == LLDP_DCBX_SUBTYPE_1) + return TRUE; + + tptr = pptr + 4; + tlen = len - 4; + + while (tlen >= sizeof(tlv)) { + + TCHECK2(*tptr, sizeof(tlv)); + + tlv = EXTRACT_16BITS(tptr); + + tlv_type = LLDP_EXTRACT_TYPE(tlv); + tlv_len = LLDP_EXTRACT_LEN(tlv); + hexdump = FALSE; + + tlen -= sizeof(tlv); + tptr += sizeof(tlv); + + /* loop check */ + if (!tlv_type || !tlv_len) { + break; + } + + TCHECK2(*tptr, tlv_len); + if (tlen < tlv_len) { + goto trunc; + } + + /* decode every tlv */ + switch (tlv_type) { + case LLDP_DCBX_CONTROL_TLV: + if (tlv_len < 10) { + goto trunc; + } + printf("\n\t Control - Protocol Control (type 0x%x, length %d)", + LLDP_DCBX_CONTROL_TLV, tlv_len); + printf("\n\t Oper_Version: %d", *tptr); + printf("\n\t Max_Version: %d", *(tptr+1)); + printf("\n\t Sequence Number: %d", EXTRACT_32BITS(tptr+2)); + printf("\n\t Acknowledgement Number: %d", + EXTRACT_32BITS(tptr+6)); + break; + case LLDP_DCBX_PRIORITY_GROUPS_TLV: + if (tlv_len < 17) { + goto trunc; + } + printf("\n\t Feature - Priority Group (type 0x%x, length %d)", + LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len); + printf("\n\t Oper_Version: %d", *tptr); + printf("\n\t Max_Version: %d", *(tptr+1)); + printf("\n\t Info block(0x%02X): ", *(tptr+2)); + tval = *(tptr+2); + printf("Enable bit: %d, Willing bit: %d, Error Bit: %d", + (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, + (tval & 0x20) ? 1 : 0); + printf("\n\t SubType: %d", *(tptr+3)); + printf("\n\t Priority Allocation"); + + pgval = EXTRACT_32BITS(tptr+4); + for (i = 0; i <= 7; i++) { + tval = *(tptr+4+(i/2)); + printf("\n\t PgId_%d: %d", + i, (pgval >> (28-4*i)) & 0xF); + } + printf("\n\t Priority Group Allocation"); + for (i = 0; i <= 7; i++) + printf("\n\t Pg percentage[%d]: %d", i, *(tptr+8+i)); + printf("\n\t NumTCsSupported: %d", *(tptr+8+8)); + break; + case LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV: + if (tlv_len < 6) { + goto trunc; + } + printf("\n\t Feature - Priority Flow Control"); + printf(" (type 0x%x, length %d)", + LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len); + printf("\n\t Oper_Version: %d", *tptr); + printf("\n\t Max_Version: %d", *(tptr+1)); + printf("\n\t Info block(0x%02X): ", *(tptr+2)); + tval = *(tptr+2); + printf("Enable bit: %d, Willing bit: %d, Error Bit: %d", + (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, + (tval & 0x20) ? 1 : 0); + printf("\n\t SubType: %d", *(tptr+3)); + tval = *(tptr+4); + printf("\n\t PFC Config (0x%02X)", *(tptr+4)); + for (i = 0; i <= 7; i++) + printf("\n\t Priority Bit %d: %s", + i, (tval & (1 << i)) ? "Enabled" : "Disabled"); + printf("\n\t NumTCPFCSupported: %d", *(tptr+5)); + break; + case LLDP_DCBX_APPLICATION_TLV: + if (tlv_len < 4) { + goto trunc; + } + printf("\n\t Feature - Application (type 0x%x, length %d)", + LLDP_DCBX_APPLICATION_TLV, tlv_len); + printf("\n\t Oper_Version: %d", *tptr); + printf("\n\t Max_Version: %d", *(tptr+1)); + printf("\n\t Info block(0x%02X): ", *(tptr+2)); + tval = *(tptr+2); + printf("Enable bit: %d, Willing bit: %d, Error Bit: %d", + (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, + (tval & 0x20) ? 1 : 0); + printf("\n\t SubType: %d", *(tptr+3)); + tval = tlv_len - 4; + mptr = tptr + 4; + while (tval >= 6) { + printf("\n\t Application Value"); + printf("\n\t Application Protocol ID: 0x%04x", + EXTRACT_16BITS(mptr)); + uval = EXTRACT_24BITS(mptr+2); + printf("\n\t SF (0x%x) Application Protocol ID is %s", + (uval >> 22), + (uval >> 22) ? "Socket Number" : "L2 EtherType"); + printf("\n\t OUI: 0x%06x", uval & 0x3fffff); + printf("\n\t User Priority Map: 0x%02x", *(mptr+5)); + tval = tval - 6; + mptr = mptr + 6; + } + break; + default: + hexdump = TRUE; + break; + } + + /* do we also want to see a hex dump ? */ + if (vflag > 1 || (vflag && hexdump)) { + print_unknown_data(tptr,"\n\t ", tlv_len); + } + + tlen -= tlv_len; + tptr += tlv_len; + } + + trunc: + return hexdump; +} + +static char * +lldp_network_addr_print(const u_char *tptr, u_int len) { + + u_int8_t af; + static char buf[BUFSIZE]; + const char * (*pfunc)(const u_char *); + + if (len < 1) + return NULL; + len--; + af = *tptr; + switch (af) { + case AFNUM_INET: + if (len < 4) + return NULL; + pfunc = getname; + break; +#ifdef INET6 + case AFNUM_INET6: + if (len < 16) + return NULL; + pfunc = getname6; + break; +#endif + case AFNUM_802: + if (len < 6) + return NULL; + pfunc = etheraddr_string; + break; + default: + pfunc = NULL; + break; + } + + if (!pfunc) { + snprintf(buf, sizeof(buf), "AFI %s (%u), no AF printer !", + tok2str(af_values, "Unknown", af), af); + } else { + snprintf(buf, sizeof(buf), "AFI %s (%u): %s", + tok2str(af_values, "Unknown", af), af, (*pfunc)(tptr+1)); + } + + return buf; +} + +static int +lldp_mgmt_addr_tlv_print(const u_char *pptr, u_int len) { + + u_int8_t mgmt_addr_len, intf_num_subtype, oid_len; + const u_char *tptr; + u_int tlen; + char *mgmt_addr; + + tlen = len; + tptr = pptr; + + if (tlen < 1) { + return 0; + } + mgmt_addr_len = *tptr++; + tlen--; + + if (tlen < mgmt_addr_len) { + return 0; + } + + mgmt_addr = lldp_network_addr_print(tptr, mgmt_addr_len); + if (mgmt_addr == NULL) { + return 0; + } + printf("\n\t Management Address length %u, %s", + mgmt_addr_len, mgmt_addr); + tptr += mgmt_addr_len; + tlen -= mgmt_addr_len; + + if (tlen < LLDP_INTF_NUM_LEN) { + return 0; + } + + intf_num_subtype = *tptr; + printf("\n\t %s Interface Numbering (%u): %u", + tok2str(lldp_intf_numb_subtype_values, "Unknown", intf_num_subtype), + intf_num_subtype, + EXTRACT_32BITS(tptr+1)); + + tptr += LLDP_INTF_NUM_LEN; + tlen -= LLDP_INTF_NUM_LEN; + + /* + * The OID is optional. + */ + if (tlen) { + oid_len = *tptr; + + if (tlen < oid_len) { + return 0; + } + if (oid_len) { + printf("\n\t OID length %u", oid_len); + safeputs((const char *)tptr+1, oid_len); + } + } + + return 1; +} + +void +lldp_print(register const u_char *pptr, register u_int len) { + + u_int8_t subtype; + u_int16_t tlv, cap, ena_cap; + u_int oui, tlen, hexdump, tlv_type, tlv_len; + const u_char *tptr; + char *network_addr; + + tptr = pptr; + tlen = len; + + printf("LLDP, length %u", len); + + while (tlen >= sizeof(tlv)) { + + TCHECK2(*tptr, sizeof(tlv)); + + tlv = EXTRACT_16BITS(tptr); + + tlv_type = LLDP_EXTRACT_TYPE(tlv); + tlv_len = LLDP_EXTRACT_LEN(tlv); + hexdump = FALSE; + + tlen -= sizeof(tlv); + tptr += sizeof(tlv); + + if (vflag) { + printf("\n\t%s TLV (%u), length %u", + tok2str(lldp_tlv_values, "Unknown", tlv_type), + tlv_type, tlv_len); + } + + /* infinite loop check */ + if (!tlv_type || !tlv_len) { + break; + } + + TCHECK2(*tptr, tlv_len); + if (tlen < tlv_len) { + goto trunc; + } + + switch (tlv_type) { + + case LLDP_CHASSIS_ID_TLV: + if (vflag) { + if (tlv_len < 2) { + goto trunc; + } + subtype = *tptr; + printf("\n\t Subtype %s (%u): ", + tok2str(lldp_chassis_subtype_values, "Unknown", subtype), + subtype); + + switch (subtype) { + case LLDP_CHASSIS_MAC_ADDR_SUBTYPE: + if (tlv_len < 1+6) { + goto trunc; + } + printf("%s", etheraddr_string(tptr+1)); + break; + + case LLDP_CHASSIS_INTF_NAME_SUBTYPE: /* fall through */ + case LLDP_CHASSIS_LOCAL_SUBTYPE: + case LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE: + case LLDP_CHASSIS_INTF_ALIAS_SUBTYPE: + case LLDP_CHASSIS_PORT_COMP_SUBTYPE: + safeputs((const char *)tptr+1, tlv_len-1); + break; + + case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE: + network_addr = lldp_network_addr_print(tptr+1, tlv_len-1); + if (network_addr == NULL) { + goto trunc; + } + printf("%s", network_addr); + break; + + default: + hexdump = TRUE; + break; + } + } + break; + + case LLDP_PORT_ID_TLV: + if (vflag) { + if (tlv_len < 2) { + goto trunc; + } + subtype = *tptr; + printf("\n\t Subtype %s (%u): ", + tok2str(lldp_port_subtype_values, "Unknown", subtype), + subtype); + + switch (subtype) { + case LLDP_PORT_MAC_ADDR_SUBTYPE: + if (tlv_len < 1+6) { + goto trunc; + } + printf("%s", etheraddr_string(tptr+1)); + break; + + case LLDP_PORT_INTF_NAME_SUBTYPE: /* fall through */ + case LLDP_PORT_LOCAL_SUBTYPE: + case LLDP_PORT_AGENT_CIRC_ID_SUBTYPE: + case LLDP_PORT_INTF_ALIAS_SUBTYPE: + case LLDP_PORT_PORT_COMP_SUBTYPE: + safeputs((const char *)tptr+1, tlv_len-1); + break; + + case LLDP_PORT_NETWORK_ADDR_SUBTYPE: + network_addr = lldp_network_addr_print(tptr+1, tlv_len-1); + if (network_addr == NULL) { + goto trunc; + } + printf("%s", network_addr); + break; + + default: + hexdump = TRUE; + break; + } + } + break; + + case LLDP_TTL_TLV: + if (vflag) { + if (tlv_len < 2) { + goto trunc; + } + printf(": TTL %us", EXTRACT_16BITS(tptr)); + } + break; + + case LLDP_PORT_DESCR_TLV: + if (vflag) { + printf(": "); + safeputs((const char *)tptr, tlv_len); + } + break; + + case LLDP_SYSTEM_NAME_TLV: + /* + * The system name is also print in non-verbose mode + * similar to the CDP printer. + */ + printf(": "); + safeputs((const char *)tptr, tlv_len); + break; + + case LLDP_SYSTEM_DESCR_TLV: + if (vflag) { + printf("\n\t "); + safeputs((const char *)tptr, tlv_len); + } + break; + + case LLDP_SYSTEM_CAP_TLV: + if (vflag) { + /* + * XXX - IEEE Std 802.1AB-2009 says the first octet + * if a chassis ID subtype, with the system + * capabilities and enabled capabilities following + * it. + */ + if (tlv_len < 4) { + goto trunc; + } + cap = EXTRACT_16BITS(tptr); + ena_cap = EXTRACT_16BITS(tptr+2); + printf("\n\t System Capabilities [%s] (0x%04x)", + bittok2str(lldp_cap_values, "none", cap), cap); + printf("\n\t Enabled Capabilities [%s] (0x%04x)", + bittok2str(lldp_cap_values, "none", ena_cap), ena_cap); + } + break; + + case LLDP_MGMT_ADDR_TLV: + if (vflag) { + if (!lldp_mgmt_addr_tlv_print(tptr, tlv_len)) { + goto trunc; + } + } + break; + + case LLDP_PRIVATE_TLV: + if (vflag) { + if (tlv_len < 3) { + goto trunc; + } + oui = EXTRACT_24BITS(tptr); + printf(": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui); + + switch (oui) { + case OUI_IEEE_8021_PRIVATE: + hexdump = lldp_private_8021_print(tptr, tlv_len); + break; + case OUI_IEEE_8023_PRIVATE: + hexdump = lldp_private_8023_print(tptr, tlv_len); + break; + case OUI_TIA: + hexdump = lldp_private_tia_print(tptr, tlv_len); + break; + case OUI_DCBX: + hexdump = lldp_private_dcbx_print(tptr, tlv_len); + break; + default: + hexdump = TRUE; + break; + } + } + break; + + default: + hexdump = TRUE; + break; + } + + /* do we also want to see a hex dump ? */ + if (vflag > 1 || (vflag && hexdump)) { + print_unknown_data(tptr,"\n\t ", tlv_len); + } + + tlen -= tlv_len; + tptr += tlv_len; + } + return; + trunc: + printf("\n\t[|LLDP]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-lmp.c b/freebsd/contrib/tcpdump/print-lmp.c new file mode 100644 index 00000000..d6774409 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-lmp.c @@ -0,0 +1,885 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 Link Management Protocol as per rfc 4204. + * + * Original code by Hannes Gredler (hannes@juniper.net) + * Support for LMP service discovery extensions (defined by UNI 1.0) added + * by Manu Pathak (mapathak@cisco.com), May 2005 + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-lmp.c,v 1.11 2007-08-02 17:32:49 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "gmpls.h" + +/* + * LMP 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Vers | (Reserved) | Flags | Msg Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | LMP Length | (Reserved) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct lmp_common_header { + u_int8_t version_res[2]; + u_int8_t flags; + u_int8_t msg_type; + u_int8_t length[2]; + u_int8_t reserved[2]; +}; + +#define LMP_VERSION 1 +#define LMP_EXTRACT_VERSION(x) (((x)&0xf0)>>4) + +static const struct tok lmp_header_flag_values[] = { + { 0x01, "Control Channel Down"}, + { 0x02, "LMP restart"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_te_link_flag_values[] = { + { 0x01, "Fault Management Supported"}, + { 0x02, "Link Verification Supported"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_data_link_flag_values[] = { + { 0x01, "Data Link Port"}, + { 0x02, "Allocated for user traffic"}, + { 0x04, "Failed link"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_channel_status_values[] = { + { 1, "Signal Okay"}, + { 2, "Signal Degraded"}, + { 3, "Signal Fail"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_begin_verify_flag_values[] = { + { 0x0001, "Verify all links"}, + { 0x0002, "Data link type"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_begin_verify_error_values[] = { + { 0x01, "Link Verification Procedure Not supported"}, + { 0x02, "Unwilling to verify"}, + { 0x04, "Unsupported verification transport mechanism"}, + { 0x08, "Link-Id configuration error"}, + { 0x10, "Unknown object c-type"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_link_summary_error_values[] = { + { 0x01, "Unacceptable non-negotiable LINK-SUMMARY parameters"}, + { 0x02, "Renegotiate LINK-SUMMARY parameters"}, + { 0x04, "Invalid TE-LINK Object"}, + { 0x08, "Invalid DATA-LINK Object"}, + { 0x10, "Unknown TE-LINK Object c-type"}, + { 0x20, "Unknown DATA-LINK Object c-type"}, + { 0, NULL} +}; + +/* Service Config Supported Protocols Flags */ +static const struct tok lmp_obj_service_config_sp_flag_values[] = { + { 0x01, "RSVP Supported"}, + { 0x02, "LDP Supported"}, + { 0, NULL} +}; + +/* Service Config Client Port Service Attribute Transparency Flags */ +static const struct tok lmp_obj_service_config_cpsa_tp_flag_values[] = { + { 0x01, "Path/VC Overhead Transparency Supported"}, + { 0x02, "Line/MS Overhead Transparency Supported"}, + { 0x04, "Section/RS Overhead Transparency Supported"}, + { 0, NULL} +}; + +/* Service Config Client Port Service Attribute Contiguous Concatenation Types Flags */ +static const struct tok lmp_obj_service_config_cpsa_cct_flag_values[] = { + { 0x01, "Contiguous Concatenation Types Supported"}, + { 0, NULL} +}; + +/* Service Config Network Service Attributes Transparency Flags */ +static const struct tok lmp_obj_service_config_nsa_transparency_flag_values[] = { + { 0x01, "Standard SOH/RSOH Transparency Supported"}, + { 0x02, "Standard LOH/MSOH Transparency Supported"}, + { 0, NULL} +}; + +/* Service Config Network Service Attributes TCM Monitoring Flags */ +static const struct tok lmp_obj_service_config_nsa_tcm_flag_values[] = { + { 0x01, "Transparent Tandem Connection Monitoring Supported"}, + { 0, NULL} +}; + +/* Network Service Attributes Network Diversity Flags */ +static const struct tok lmp_obj_service_config_nsa_network_diversity_flag_values[] = { + { 0x01, "Node Diversity Supported"}, + { 0x02, "Link Diversity Supported"}, + { 0x04, "SRLG Diversity Supported"}, + { 0, NULL} +}; + +#define LMP_MSGTYPE_CONFIG 1 +#define LMP_MSGTYPE_CONFIG_ACK 2 +#define LMP_MSGTYPE_CONFIG_NACK 3 +#define LMP_MSGTYPE_HELLO 4 +#define LMP_MSGTYPE_VERIFY_BEGIN 5 +#define LMP_MSGTYPE_VERIFY_BEGIN_ACK 6 +#define LMP_MSGTYPE_VERIFY_BEGIN_NACK 7 +#define LMP_MSGTYPE_VERIFY_END 8 +#define LMP_MSGTYPE_VERIFY_END_ACK 9 +#define LMP_MSGTYPE_TEST 10 +#define LMP_MSGTYPE_TEST_STATUS_SUCCESS 11 +#define LMP_MSGTYPE_TEST_STATUS_FAILURE 12 +#define LMP_MSGTYPE_TEST_STATUS_ACK 13 +#define LMP_MSGTYPE_LINK_SUMMARY 14 +#define LMP_MSGTYPE_LINK_SUMMARY_ACK 15 +#define LMP_MSGTYPE_LINK_SUMMARY_NACK 16 +#define LMP_MSGTYPE_CHANNEL_STATUS 17 +#define LMP_MSGTYPE_CHANNEL_STATUS_ACK 18 +#define LMP_MSGTYPE_CHANNEL_STATUS_REQ 19 +#define LMP_MSGTYPE_CHANNEL_STATUS_RESP 20 +/* LMP Service Discovery message types defined by UNI 1.0 */ +#define LMP_MSGTYPE_SERVICE_CONFIG 50 +#define LMP_MSGTYPE_SERVICE_CONFIG_ACK 51 +#define LMP_MSGTYPE_SERVICE_CONFIG_NACK 52 + +static const struct tok lmp_msg_type_values[] = { + { LMP_MSGTYPE_CONFIG, "Config"}, + { LMP_MSGTYPE_CONFIG_ACK, "Config ACK"}, + { LMP_MSGTYPE_CONFIG_NACK, "Config NACK"}, + { LMP_MSGTYPE_HELLO, "Hello"}, + { LMP_MSGTYPE_VERIFY_BEGIN, "Begin Verify"}, + { LMP_MSGTYPE_VERIFY_BEGIN_ACK, "Begin Verify ACK"}, + { LMP_MSGTYPE_VERIFY_BEGIN_NACK, "Begin Verify NACK"}, + { LMP_MSGTYPE_VERIFY_END, "End Verify"}, + { LMP_MSGTYPE_VERIFY_END_ACK, "End Verify ACK"}, + { LMP_MSGTYPE_TEST, "Test"}, + { LMP_MSGTYPE_TEST_STATUS_SUCCESS, "Test Status Success"}, + { LMP_MSGTYPE_TEST_STATUS_FAILURE, "Test Status Failure"}, + { LMP_MSGTYPE_TEST_STATUS_ACK, "Test Status ACK"}, + { LMP_MSGTYPE_LINK_SUMMARY, "Link Summary"}, + { LMP_MSGTYPE_LINK_SUMMARY_ACK, "Link Summary ACK"}, + { LMP_MSGTYPE_LINK_SUMMARY_NACK, "Link Summary NACK"}, + { LMP_MSGTYPE_CHANNEL_STATUS, "Channel Status"}, + { LMP_MSGTYPE_CHANNEL_STATUS_ACK, "Channel Status ACK"}, + { LMP_MSGTYPE_CHANNEL_STATUS_REQ, "Channel Status Request"}, + { LMP_MSGTYPE_CHANNEL_STATUS_RESP, "Channel Status Response"}, + { LMP_MSGTYPE_SERVICE_CONFIG, "Service Config"}, + { LMP_MSGTYPE_SERVICE_CONFIG_ACK, "Service Config ACK"}, + { LMP_MSGTYPE_SERVICE_CONFIG_NACK, "Service Config NACK"}, + { 0, NULL} +}; + +/* + * LMP object 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |N| C-Type | Class | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * // (object contents) // + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct lmp_object_header { + u_int8_t ctype; + u_int8_t class_num; + u_int8_t length[2]; +}; + +#define LMP_OBJ_CC_ID 1 +#define LMP_OBJ_NODE_ID 2 +#define LMP_OBJ_LINK_ID 3 +#define LMP_OBJ_INTERFACE_ID 4 +#define LMP_OBJ_MESSAGE_ID 5 +#define LMP_OBJ_CONFIG 6 +#define LMP_OBJ_HELLO 7 +#define LMP_OBJ_VERIFY_BEGIN 8 +#define LMP_OBJ_VERIFY_BEGIN_ACK 9 +#define LMP_OBJ_VERIFY_ID 10 +#define LMP_OBJ_TE_LINK 11 +#define LMP_OBJ_DATA_LINK 12 +#define LMP_OBJ_CHANNEL_STATUS 13 +#define LMP_OBJ_CHANNEL_STATUS_REQ 14 +#define LMP_OBJ_ERROR_CODE 20 + +#define LMP_OBJ_SERVICE_CONFIG 51 /* defined in UNI 1.0 */ + +static const struct tok lmp_obj_values[] = { + { LMP_OBJ_CC_ID, "Control Channel ID" }, + { LMP_OBJ_NODE_ID, "Node ID" }, + { LMP_OBJ_LINK_ID, "Link ID" }, + { LMP_OBJ_INTERFACE_ID, "Interface ID" }, + { LMP_OBJ_MESSAGE_ID, "Message ID" }, + { LMP_OBJ_CONFIG, "Configuration" }, + { LMP_OBJ_HELLO, "Hello" }, + { LMP_OBJ_VERIFY_BEGIN, "Verify Begin" }, + { LMP_OBJ_VERIFY_BEGIN_ACK, "Verify Begin ACK" }, + { LMP_OBJ_VERIFY_ID, "Verify ID" }, + { LMP_OBJ_TE_LINK, "TE Link" }, + { LMP_OBJ_DATA_LINK, "Data Link" }, + { LMP_OBJ_CHANNEL_STATUS, "Channel Status" }, + { LMP_OBJ_CHANNEL_STATUS_REQ, "Channel Status Request" }, + { LMP_OBJ_ERROR_CODE, "Error Code" }, + { LMP_OBJ_SERVICE_CONFIG, "Service Config" }, + + { 0, NULL} +}; + +#define INT_SWITCHING_TYPE_SUBOBJ 1 +#define WAVELENGTH_SUBOBJ 2 + +static const struct tok lmp_data_link_subobj[] = { + { INT_SWITCHING_TYPE_SUBOBJ, "Interface Switching Type" }, + { WAVELENGTH_SUBOBJ , "Wavelength" }, + { 0, NULL} +}; + +#define LMP_CTYPE_IPV4 1 +#define LMP_CTYPE_IPV6 2 + +#define LMP_CTYPE_LOC 1 +#define LMP_CTYPE_RMT 2 +#define LMP_CTYPE_UNMD 3 + +#define LMP_CTYPE_IPV4_LOC 1 +#define LMP_CTYPE_IPV4_RMT 2 +#define LMP_CTYPE_IPV6_LOC 3 +#define LMP_CTYPE_IPV6_RMT 4 +#define LMP_CTYPE_UNMD_LOC 5 +#define LMP_CTYPE_UNMD_RMT 6 + +#define LMP_CTYPE_1 1 +#define LMP_CTYPE_2 2 + +#define LMP_CTYPE_HELLO_CONFIG 1 +#define LMP_CTYPE_HELLO 1 + +#define LMP_CTYPE_BEGIN_VERIFY_ERROR 1 +#define LMP_CTYPE_LINK_SUMMARY_ERROR 2 + +/* C-Types for Service Config Object */ +#define LMP_CTYPE_SERVICE_CONFIG_SP 1 +#define LMP_CTYPE_SERVICE_CONFIG_CPSA 2 +#define LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM 3 +#define LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY 4 + +/* + * Different link types allowed in the Client Port Service Attributes + * subobject defined for LMP Service Discovery in the UNI 1.0 spec + */ +#define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH 5 /* UNI 1.0 Sec 9.4.2 */ +#define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET 6 /* UNI 1.0 Sec 9.4.2 */ + +/* + * the ctypes are not globally unique so for + * translating it to strings we build a table based + * on objects offsetted by the ctype + */ + +static const struct tok lmp_ctype_values[] = { + { 256*LMP_OBJ_CC_ID+LMP_CTYPE_LOC, "Local" }, + { 256*LMP_OBJ_CC_ID+LMP_CTYPE_RMT, "Remote" }, + { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_LOC, "Local" }, + { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_RMT, "Remote" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" }, + { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_2, "2" }, + { 256*LMP_OBJ_CONFIG+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_HELLO+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_VERIFY_BEGIN+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_VERIFY_BEGIN_ACK+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_VERIFY_ID+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV4, "IPv4" }, + { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV6, "IPv6" }, + { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_UNMD, "Unnumbered" }, + { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV4, "IPv4" }, + { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV6, "IPv6" }, + { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_UNMD, "Unnumbered" }, + { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV4, "IPv4" }, + { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV6, "IPv6" }, + { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_UNMD, "Unnumbered" }, + { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV4, "IPv4" }, + { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV6, "IPv6" }, + { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_UNMD, "Unnumbered" }, + { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_2, "2" }, + { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_SP, "1" }, + { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_CPSA, "2" }, + { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM, "3" }, + { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY, "4" }, + { 0, NULL} +}; + +void +lmp_print(register const u_char *pptr, register u_int len) { + + const struct lmp_common_header *lmp_com_header; + const struct lmp_object_header *lmp_obj_header; + const u_char *tptr,*obj_tptr; + int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen; + int hexdump; + int offset,subobj_type,subobj_len,total_subobj_len; + int link_type; + + union { /* int to float conversion buffer */ + float f; + u_int32_t i; + } bw; + + tptr=pptr; + lmp_com_header = (const struct lmp_common_header *)pptr; + TCHECK(*lmp_com_header); + + /* + * Sanity checking of the header. + */ + if (LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]) != LMP_VERSION) { + printf("LMP version %u packet not supported", + LMP_EXTRACT_VERSION(lmp_com_header->version_res[0])); + return; + } + + /* in non-verbose mode just lets print the basic Message Type*/ + if (vflag < 1) { + printf("LMPv%u %s Message, length: %u", + LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]), + tok2str(lmp_msg_type_values, "unknown (%u)",lmp_com_header->msg_type), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + + tlen=EXTRACT_16BITS(lmp_com_header->length); + + printf("\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u", + LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]), + tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type), + bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags), + tlen); + + tptr+=sizeof(const struct lmp_common_header); + tlen-=sizeof(const struct lmp_common_header); + + while(tlen>0) { + /* did we capture enough for fully decoding the object header ? */ + if (!TTEST2(*tptr, sizeof(struct lmp_object_header))) + goto trunc; + + lmp_obj_header = (const struct lmp_object_header *)tptr; + lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length); + lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f; + + if(lmp_obj_len % 4 || lmp_obj_len < 4) + return; + + printf("\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u", + tok2str(lmp_obj_values, + "Unknown", + lmp_obj_header->class_num), + lmp_obj_header->class_num, + tok2str(lmp_ctype_values, + "Unknown", + ((lmp_obj_header->class_num)<<8)+lmp_obj_ctype), + lmp_obj_ctype, + (lmp_obj_header->ctype)&0x80 ? "" : "non-", + lmp_obj_len); + + obj_tptr=tptr+sizeof(struct lmp_object_header); + obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header); + + /* did we capture enough for fully decoding the object ? */ + if (!TTEST2(*tptr, lmp_obj_len)) + goto trunc; + hexdump=FALSE; + + switch(lmp_obj_header->class_num) { + + case LMP_OBJ_CC_ID: + switch(lmp_obj_ctype) { + case LMP_CTYPE_LOC: + case LMP_CTYPE_RMT: + printf("\n\t Control Channel ID: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_LINK_ID: + case LMP_OBJ_INTERFACE_ID: + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4_LOC: + case LMP_CTYPE_IPV4_RMT: + printf("\n\t IPv4 Link ID: %s (0x%08x)", + ipaddr_string(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; +#ifdef INET6 + case LMP_CTYPE_IPV6_LOC: + case LMP_CTYPE_IPV6_RMT: + printf("\n\t IPv6 Link ID: %s (0x%08x)", + ip6addr_string(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; +#endif + case LMP_CTYPE_UNMD_LOC: + case LMP_CTYPE_UNMD_RMT: + printf("\n\t Link ID: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_MESSAGE_ID: + switch(lmp_obj_ctype) { + case LMP_CTYPE_1: + printf("\n\t Message ID: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; + case LMP_CTYPE_2: + printf("\n\t Message ID Ack: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_NODE_ID: + switch(lmp_obj_ctype) { + case LMP_CTYPE_LOC: + case LMP_CTYPE_RMT: + printf("\n\t Node ID: %s (0x%08x)", + ipaddr_string(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_CONFIG: + switch(lmp_obj_ctype) { + case LMP_CTYPE_HELLO_CONFIG: + printf("\n\t Hello Interval: %u\n\t Hello Dead Interval: %u", + EXTRACT_16BITS(obj_tptr), + EXTRACT_16BITS(obj_tptr+2)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_HELLO: + switch(lmp_obj_ctype) { + case LMP_CTYPE_HELLO: + printf("\n\t Tx Seq: %u, Rx Seq: %u", + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr+4)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_TE_LINK: + printf("\n\t Flags: [%s]", + bittok2str(lmp_obj_te_link_flag_values, + "none", + EXTRACT_16BITS(obj_tptr)>>8)); + + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4: + printf("\n\t Local Link-ID: %s (0x%08x) \ + \n\t Remote Link-ID: %s (0x%08x)", + ipaddr_string(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+4), + ipaddr_string(obj_tptr+8), + EXTRACT_32BITS(obj_tptr+8)); + break; + +#ifdef INET6 + case LMP_CTYPE_IPV6: +#endif + case LMP_CTYPE_UNMD: + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_DATA_LINK: + printf("\n\t Flags: [%s]", + bittok2str(lmp_obj_data_link_flag_values, + "none", + EXTRACT_16BITS(obj_tptr)>>8)); + + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4: + case LMP_CTYPE_UNMD: + printf("\n\t Local Interface ID: %s (0x%08x) \ + \n\t Remote Interface ID: %s (0x%08x)", + ipaddr_string(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+4), + ipaddr_string(obj_tptr+8), + EXTRACT_32BITS(obj_tptr+8)); + + total_subobj_len = lmp_obj_len - 16; + offset = 12; + while (total_subobj_len > 0 && hexdump == FALSE ) { + subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8; + subobj_len = EXTRACT_16BITS(obj_tptr+offset)&0x00FF; + printf("\n\t Subobject, Type: %s (%u), Length: %u", + tok2str(lmp_data_link_subobj, + "Unknown", + subobj_type), + subobj_type, + subobj_len); + switch(subobj_type) { + case INT_SWITCHING_TYPE_SUBOBJ: + printf("\n\t Switching Type: %s (%u)", + tok2str(gmpls_switch_cap_values, + "Unknown", + EXTRACT_16BITS(obj_tptr+offset+2)>>8), + EXTRACT_16BITS(obj_tptr+offset+2)>>8); + printf("\n\t Encoding Type: %s (%u)", + tok2str(gmpls_encoding_values, + "Unknown", + EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF), + EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF); + bw.i = EXTRACT_32BITS(obj_tptr+offset+4); + printf("\n\t Min Reservable Bandwidth: %.3f Mbps", + bw.f*8/1000000); + bw.i = EXTRACT_32BITS(obj_tptr+offset+8); + printf("\n\t Max Reservable Bandwidth: %.3f Mbps", + bw.f*8/1000000); + break; + case WAVELENGTH_SUBOBJ: + printf("\n\t Wavelength: %u", + EXTRACT_32BITS(obj_tptr+offset+4)); + break; + default: + /* Any Unknown Subobject ==> Exit loop */ + hexdump=TRUE; + break; + } + total_subobj_len-=subobj_len; + offset+=subobj_len; + } + + break; +#ifdef INET6 + case LMP_CTYPE_IPV6: +#endif + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_VERIFY_BEGIN: + switch(lmp_obj_ctype) { + case LMP_CTYPE_1: + printf("\n\t Flags: %s", + bittok2str(lmp_obj_begin_verify_flag_values, + "none", + EXTRACT_16BITS(obj_tptr))); + printf("\n\t Verify Interval: %u", + EXTRACT_16BITS(obj_tptr+2)); + printf("\n\t Data links: %u", + EXTRACT_32BITS(obj_tptr+4)); + printf("\n\t Encoding type: %s", + tok2str(gmpls_encoding_values, "Unknown", *(obj_tptr+8))); + printf("\n\t Verify Tranport Mechanism: %u (0x%x) %s", + EXTRACT_16BITS(obj_tptr+10), + EXTRACT_16BITS(obj_tptr+10), + EXTRACT_16BITS(obj_tptr+10)&8000 ? "(Payload test messages capable)" : ""); + bw.i = EXTRACT_32BITS(obj_tptr+12); + printf("\n\t Transmission Rate: %.3f Mbps",bw.f*8/1000000); + printf("\n\t Wavelength: %u", + EXTRACT_32BITS(obj_tptr+16)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_VERIFY_BEGIN_ACK: + switch(lmp_obj_ctype) { + case LMP_CTYPE_1: + printf("\n\t Verify Dead Interval: %u \ + \n\t Verify Transport Response: %u", + EXTRACT_16BITS(obj_tptr), + EXTRACT_16BITS(obj_tptr+2)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_VERIFY_ID: + switch(lmp_obj_ctype) { + case LMP_CTYPE_1: + printf("\n\t Verify ID: %u", + EXTRACT_32BITS(obj_tptr)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_CHANNEL_STATUS: + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4: + case LMP_CTYPE_UNMD: + offset = 0; + /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */ + while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) { + printf("\n\t Interface ID: %s (0x%08x)", + ipaddr_string(obj_tptr+offset), + EXTRACT_32BITS(obj_tptr+offset)); + + printf("\n\t\t Active: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ? + "Allocated" : "Non-allocated", + (EXTRACT_32BITS(obj_tptr+offset+4)>>31)); + + printf("\n\t\t Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ? + "Transmit" : "Receive", + (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1); + + printf("\n\t\t Channel Status: %s (%u)", + tok2str(lmp_obj_channel_status_values, + "Unknown", + EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF), + EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF); + offset+=8; + } + break; +#ifdef INET6 + case LMP_CTYPE_IPV6: +#endif + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_CHANNEL_STATUS_REQ: + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4: + case LMP_CTYPE_UNMD: + offset = 0; + while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) { + printf("\n\t Interface ID: %s (0x%08x)", + ipaddr_string(obj_tptr+offset), + EXTRACT_32BITS(obj_tptr+offset)); + offset+=4; + } + break; +#ifdef INET6 + case LMP_CTYPE_IPV6: +#endif + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_ERROR_CODE: + switch(lmp_obj_ctype) { + case LMP_CTYPE_BEGIN_VERIFY_ERROR: + printf("\n\t Error Code: %s", + bittok2str(lmp_obj_begin_verify_error_values, + "none", + EXTRACT_32BITS(obj_tptr))); + break; + + case LMP_CTYPE_LINK_SUMMARY_ERROR: + printf("\n\t Error Code: %s", + bittok2str(lmp_obj_link_summary_error_values, + "none", + EXTRACT_32BITS(obj_tptr))); + break; + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_SERVICE_CONFIG: + switch (lmp_obj_ctype) { + case LMP_CTYPE_SERVICE_CONFIG_SP: + + printf("\n\t Flags: %s", + bittok2str(lmp_obj_service_config_sp_flag_values, + "none", + EXTRACT_16BITS(obj_tptr)>>8)); + + printf("\n\t UNI Version: %u", + EXTRACT_16BITS(obj_tptr) & 0x00FF); + + break; + + case LMP_CTYPE_SERVICE_CONFIG_CPSA: + + link_type = EXTRACT_16BITS(obj_tptr)>>8; + + printf("\n\t Link Type: %s (%u)", + tok2str(lmp_sd_service_config_cpsa_link_type_values, + "Unknown", link_type), + link_type); + + if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH) { + printf("\n\t Signal Type: %s (%u)", + tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values, + "Unknown", + EXTRACT_16BITS(obj_tptr) & 0x00FF), + EXTRACT_16BITS(obj_tptr) & 0x00FF); + } + + if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET) { + printf("\n\t Signal Type: %s (%u)", + tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values, + "Unknown", + EXTRACT_16BITS(obj_tptr) & 0x00FF), + EXTRACT_16BITS(obj_tptr) & 0x00FF); + } + + printf("\n\t Transparency: %s", + bittok2str(lmp_obj_service_config_cpsa_tp_flag_values, + "none", + EXTRACT_16BITS(obj_tptr+2)>>8)); + + printf("\n\t Contiguous Concatenation Types: %s", + bittok2str(lmp_obj_service_config_cpsa_cct_flag_values, + "none", + EXTRACT_16BITS(obj_tptr+2)>>8 & 0x00FF)); + + printf("\n\t Minimum NCC: %u", + EXTRACT_16BITS(obj_tptr+4)); + + printf("\n\t Maximum NCC: %u", + EXTRACT_16BITS(obj_tptr+6)); + + printf("\n\t Minimum NVC:%u", + EXTRACT_16BITS(obj_tptr+8)); + + printf("\n\t Maximum NVC:%u", + EXTRACT_16BITS(obj_tptr+10)); + + printf("\n\t Local Interface ID: %s (0x%08x)", + ipaddr_string(obj_tptr+12), + EXTRACT_32BITS(obj_tptr+12)); + + break; + + case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM: + + printf("\n\t Transparency Flags: %s", + bittok2str( + lmp_obj_service_config_nsa_transparency_flag_values, + "none", + EXTRACT_32BITS(obj_tptr))); + + printf("\n\t TCM Monitoring Flags: %s", + bittok2str( + lmp_obj_service_config_nsa_tcm_flag_values, + "none", + EXTRACT_16BITS(obj_tptr+6) & 0x00FF)); + + break; + + case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY: + + printf("\n\t Diversity: Flags: %s", + bittok2str( + lmp_obj_service_config_nsa_network_diversity_flag_values, + "none", + EXTRACT_16BITS(obj_tptr+2) & 0x00FF)); + break; + + default: + hexdump = TRUE; + }; + + break; + + default: + if (vflag <= 1) + print_unknown_data(obj_tptr,"\n\t ",obj_tlen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag > 1 || hexdump==TRUE) + print_unknown_data(tptr+sizeof(struct lmp_object_header),"\n\t ", + lmp_obj_len-sizeof(struct lmp_object_header)); + + tptr+=lmp_obj_len; + tlen-=lmp_obj_len; + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} diff --git a/freebsd/contrib/tcpdump/print-lspping.c b/freebsd/contrib/tcpdump/print-lspping.c new file mode 100644 index 00000000..aac0ca25 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-lspping.c @@ -0,0 +1,898 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#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"); +} diff --git a/freebsd/contrib/tcpdump/print-lwapp.c b/freebsd/contrib/tcpdump/print-lwapp.c new file mode 100644 index 00000000..fb76203f --- /dev/null +++ b/freebsd/contrib/tcpdump/print-lwapp.c @@ -0,0 +1,361 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * Support for the Light Weight Access Point Protocol as per draft-ohara-capwap-lwapp-04 + * + * Original code by Carles Kishimoto <carles.kishimoto@gmail.com> + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-lwapp.c,v 1.1 2007-07-24 16:07:30 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * LWAPP transport (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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |VER| RID |C|F|L| Frag ID | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Status/WLANs | Payload... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +struct lwapp_transport_header { + u_int8_t version; + u_int8_t frag_id; + u_int8_t length[2]; + u_int16_t status; +}; + +/* + * LWAPP control 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Type | Seq Num | Msg Element Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Session ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Msg Element [0..N] | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct lwapp_control_header { + u_int8_t msg_type; + u_int8_t seq_num; + u_int8_t len[2]; + u_int8_t session_id[4]; +}; + +#define LWAPP_VERSION 0 +#define LWAPP_EXTRACT_VERSION(x) (((x)&0xC0)>>6) +#define LWAPP_EXTRACT_RID(x) (((x)&0x38)>>3) +#define LWAPP_EXTRACT_CONTROL_BIT(x) (((x)&0x04)>>2) + +static const struct tok lwapp_header_bits_values[] = { + { 0x01, "Last Fragment Bit"}, + { 0x02, "Fragment Bit"}, + { 0x04, "Control Bit"}, + { 0, NULL} +}; + +#define LWAPP_MSGTYPE_DISCOVERY_REQUEST 1 +#define LWAPP_MSGTYPE_DISCOVERY_RESPONSE 2 +#define LWAPP_MSGTYPE_JOIN_REQUEST 3 +#define LWAPP_MSGTYPE_JOIN_RESPONSE 4 +#define LWAPP_MSGTYPE_JOIN_ACK 5 +#define LWAPP_MSGTYPE_JOIN_CONFIRM 6 +#define LWAPP_MSGTYPE_CONFIGURE_REQUEST 10 +#define LWAPP_MSGTYPE_CONFIGURE_RESPONSE 11 +#define LWAPP_MSGTYPE_CONF_UPDATE_REQUEST 12 +#define LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE 13 +#define LWAPP_MSGTYPE_WTP_EVENT_REQUEST 14 +#define LWAPP_MSGTYPE_WTP_EVENT_RESPONSE 15 +#define LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST 16 +#define LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE 17 +#define LWAPP_MSGTYPE_ECHO_REQUEST 22 +#define LWAPP_MSGTYPE_ECHO_RESPONSE 23 +#define LWAPP_MSGTYPE_IMAGE_DATA_REQUEST 24 +#define LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE 25 +#define LWAPP_MSGTYPE_RESET_REQUEST 26 +#define LWAPP_MSGTYPE_RESET_RESPONSE 27 +#define LWAPP_MSGTYPE_KEY_UPDATE_REQUEST 30 +#define LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE 31 +#define LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST 32 +#define LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE 33 +#define LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST 34 +#define LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE 35 +#define LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION 36 +#define LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST 37 +#define LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE 38 +#define LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST 39 +#define LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE 40 + +static const struct tok lwapp_msg_type_values[] = { + { LWAPP_MSGTYPE_DISCOVERY_REQUEST, "Discovery req"}, + { LWAPP_MSGTYPE_DISCOVERY_RESPONSE, "Discovery resp"}, + { LWAPP_MSGTYPE_JOIN_REQUEST, "Join req"}, + { LWAPP_MSGTYPE_JOIN_RESPONSE, "Join resp"}, + { LWAPP_MSGTYPE_JOIN_ACK, "Join ack"}, + { LWAPP_MSGTYPE_JOIN_CONFIRM, "Join confirm"}, + { LWAPP_MSGTYPE_CONFIGURE_REQUEST, "Configure req"}, + { LWAPP_MSGTYPE_CONFIGURE_RESPONSE, "Configure resp"}, + { LWAPP_MSGTYPE_CONF_UPDATE_REQUEST, "Update req"}, + { LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE, "Update resp"}, + { LWAPP_MSGTYPE_WTP_EVENT_REQUEST, "WTP event req"}, + { LWAPP_MSGTYPE_WTP_EVENT_RESPONSE, "WTP event resp"}, + { LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST, "Change state event req"}, + { LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE, "Change state event resp"}, + { LWAPP_MSGTYPE_ECHO_REQUEST, "Echo req"}, + { LWAPP_MSGTYPE_ECHO_RESPONSE, "Echo resp"}, + { LWAPP_MSGTYPE_IMAGE_DATA_REQUEST, "Image data req"}, + { LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE, "Image data resp"}, + { LWAPP_MSGTYPE_RESET_REQUEST, "Channel status req"}, + { LWAPP_MSGTYPE_RESET_RESPONSE, "Channel status resp"}, + { LWAPP_MSGTYPE_KEY_UPDATE_REQUEST, "Key update req"}, + { LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE, "Key update resp"}, + { LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST, "Primary discovery req"}, + { LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE, "Primary discovery resp"}, + { LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST, "Data transfer req"}, + { LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE, "Data transfer resp"}, + { LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION, "Clear config ind"}, + { LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST, "Wlan config req"}, + { LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE, "Wlan config resp"}, + { LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST, "Mobile config req"}, + { LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE, "Mobile config resp"}, + { 0, NULL} +}; + +/* + * LWAPP message elements + * + * 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 lwapp_message_header { + u_int8_t type; + u_int8_t length[2]; +}; + +void +lwapp_control_print(const u_char *pptr, u_int len, int has_ap_ident) { + + const struct lwapp_transport_header *lwapp_trans_header; + const struct lwapp_control_header *lwapp_control_header; + const u_char *tptr; + int tlen; + int msg_tlen; + + tptr=pptr; + + if (has_ap_ident) { + /* check if enough bytes for AP identity */ + if (!TTEST2(*tptr, 6)) + goto trunc; + lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6); + } else { + lwapp_trans_header = (const struct lwapp_transport_header *)pptr; + } + TCHECK(*lwapp_trans_header); + + /* + * Sanity checking of the header. + */ + if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) { + printf("LWAPP version %u packet not supported", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version)); + return; + } + + /* non-verbose */ + if (vflag < 1) { + printf("LWAPPv%u, %s frame, Flags [%s], length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + tlen=EXTRACT_16BITS(lwapp_trans_header->length); + + printf("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + LWAPP_EXTRACT_RID(lwapp_trans_header->version), + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + lwapp_trans_header->frag_id, + tlen); + + if (has_ap_ident) { + printf("\n\tAP identity: %s", + etheraddr_string(tptr)); + tptr+=sizeof(const struct lwapp_transport_header)+6; + } else { + tptr+=sizeof(const struct lwapp_transport_header); + } + + while(tlen>0) { + + /* did we capture enough for fully decoding the object header ? */ + if (!TTEST2(*tptr, sizeof(struct lwapp_control_header))) + goto trunc; + + lwapp_control_header = (const struct lwapp_control_header *)tptr; + msg_tlen = EXTRACT_16BITS(lwapp_control_header->len); + + /* print message header */ + printf("\n\t Msg type: %s (%u), Seqnum: %u, Msg len: %d, Session: 0x%08x", + tok2str(lwapp_msg_type_values,"Unknown",lwapp_control_header->msg_type), + lwapp_control_header->msg_type, + lwapp_control_header->seq_num, + msg_tlen, + EXTRACT_32BITS(lwapp_control_header->session_id)); + + /* did we capture enough for fully decoding the message */ + if (!TTEST2(*tptr, msg_tlen)) + goto trunc; + + /* XXX - Decode sub messages for each message */ + switch(lwapp_control_header->msg_type) { + case LWAPP_MSGTYPE_DISCOVERY_REQUEST: + case LWAPP_MSGTYPE_DISCOVERY_RESPONSE: + case LWAPP_MSGTYPE_JOIN_REQUEST: + case LWAPP_MSGTYPE_JOIN_RESPONSE: + case LWAPP_MSGTYPE_JOIN_ACK: + case LWAPP_MSGTYPE_JOIN_CONFIRM: + case LWAPP_MSGTYPE_CONFIGURE_REQUEST: + case LWAPP_MSGTYPE_CONFIGURE_RESPONSE: + case LWAPP_MSGTYPE_CONF_UPDATE_REQUEST: + case LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE: + case LWAPP_MSGTYPE_WTP_EVENT_REQUEST: + case LWAPP_MSGTYPE_WTP_EVENT_RESPONSE: + case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST: + case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE: + case LWAPP_MSGTYPE_ECHO_REQUEST: + case LWAPP_MSGTYPE_ECHO_RESPONSE: + case LWAPP_MSGTYPE_IMAGE_DATA_REQUEST: + case LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE: + case LWAPP_MSGTYPE_RESET_REQUEST: + case LWAPP_MSGTYPE_RESET_RESPONSE: + case LWAPP_MSGTYPE_KEY_UPDATE_REQUEST: + case LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE: + case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST: + case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE: + case LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST: + case LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE: + case LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION: + case LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST: + case LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE: + case LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST: + case LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE: + default: + break; + } + + tptr += sizeof(struct lwapp_control_header) + msg_tlen; + tlen -= sizeof(struct lwapp_control_header) + msg_tlen; + } + return; + + trunc: + printf("\n\t\t packet exceeded snapshot"); +} + +void +lwapp_data_print(const u_char *pptr, u_int len) { + + const struct lwapp_transport_header *lwapp_trans_header; + const u_char *tptr; + int tlen; + + tptr=pptr; + + /* check if enough bytes for AP identity */ + if (!TTEST2(*tptr, 6)) + goto trunc; + lwapp_trans_header = (const struct lwapp_transport_header *)pptr; + TCHECK(*lwapp_trans_header); + + /* + * Sanity checking of the header. + */ + if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) { + printf("LWAPP version %u packet not supported", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version)); + return; + } + + /* non-verbose */ + if (vflag < 1) { + printf("LWAPPv%u, %s frame, Flags [%s], length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + tlen=EXTRACT_16BITS(lwapp_trans_header->length); + + printf("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + LWAPP_EXTRACT_RID(lwapp_trans_header->version), + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + lwapp_trans_header->frag_id, + tlen); + + tptr+=sizeof(const struct lwapp_transport_header); + tlen-=sizeof(const struct lwapp_transport_header); + + /* FIX - An IEEE 802.11 frame follows - hexdump for now */ + print_unknown_data(tptr, "\n\t", tlen); + + return; + + trunc: + printf("\n\t\t packet exceeded snapshot"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-lwres.c b/freebsd/contrib/tcpdump/print-lwres.c new file mode 100644 index 00000000..a68a67a4 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-lwres.c @@ -0,0 +1,603 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include "nameser.h" + +#include <stdio.h> +#include <string.h> + +#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 */ + +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 struct tok ns_type2str[]; +extern 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; +} diff --git a/freebsd/contrib/tcpdump/print-mobile.c b/freebsd/contrib/tcpdump/print-mobile.c new file mode 100644 index 00000000..b13ab43d --- /dev/null +++ b/freebsd/contrib/tcpdump/print-mobile.c @@ -0,0 +1,114 @@ +#include <machine/rtems-bsd-user-space.h> + +/* $NetBSD: print-mobile.c,v 1.2 1998/09/30 08:57:01 hwr Exp $ */ + +/* + * (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Heiko W.Rupp <hwr@pilhuhn.de> + * + * 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-mobile.c,v 1.15 2004-03-24 01:58:14 guy Exp $"; +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#define MOBILE_SIZE (8) + +struct mobile_ip { + u_int16_t proto; + u_int16_t hcheck; + u_int32_t odst; + u_int32_t osrc; +}; + +#define OSRC_PRES 0x0080 /* old source is present */ + +/* + * Deencapsulate and print a mobile-tunneled IP datagram + */ +void +mobile_print(const u_char *bp, u_int length) +{ + const u_char *cp = bp +8 ; + const struct mobile_ip *mob; + struct cksum_vec vec[1]; + u_short proto,crc; + u_char osp =0; /* old source address present */ + + mob = (const struct mobile_ip *)bp; + + if (length < MOBILE_SIZE || !TTEST(*mob)) { + fputs("[|mobile]", stdout); + return; + } + fputs("mobile: ", stdout); + + proto = EXTRACT_16BITS(&mob->proto); + crc = EXTRACT_16BITS(&mob->hcheck); + if (proto & OSRC_PRES) { + osp=1; + cp +=4 ; + } + + if (osp) { + fputs("[S] ",stdout); + if (vflag) + (void)printf("%s ",ipaddr_string(&mob->osrc)); + } else { + fputs("[] ",stdout); + } + if (vflag) { + (void)printf("> %s ",ipaddr_string(&mob->odst)); + (void)printf("(oproto=%d)",proto>>8); + } + vec[0].ptr = (const u_int8_t *)(void *)mob; + vec[0].len = osp ? 12 : 8; + if (in_cksum(vec, 1)!=0) { + (void)printf(" (bad checksum %d)",crc); + } + + return; +} diff --git a/freebsd/contrib/tcpdump/print-mobility.c b/freebsd/contrib/tcpdump/print-mobility.c new file mode 100644 index 00000000..3f564e79 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-mobility.c @@ -0,0 +1,314 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (C) 2002 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-mobility.c,v 1.12 2005-04-20 22:21:00 guy Exp $"; +#endif + +#ifdef INET6 +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "ip6.h" + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +/* Mobility header */ +struct ip6_mobility { + u_int8_t ip6m_pproto; /* following payload protocol (for PG) */ + u_int8_t ip6m_len; /* length in units of 8 octets */ + u_int8_t ip6m_type; /* message type */ + u_int8_t reserved; /* reserved */ + u_int16_t ip6m_cksum; /* sum of IPv6 pseudo-header and MH */ + union { + u_int16_t ip6m_un_data16[1]; /* type-specific field */ + u_int8_t ip6m_un_data8[2]; /* type-specific fiedl */ + } ip6m_dataun; +}; + +#define ip6m_data16 ip6m_dataun.ip6m_un_data16 +#define ip6m_data8 ip6m_dataun.ip6m_un_data8 + +#define IP6M_MINLEN 8 + +/* message type */ +#define IP6M_BINDING_REQUEST 0 /* Binding Refresh Request */ +#define IP6M_HOME_TEST_INIT 1 /* Home Test Init */ +#define IP6M_CAREOF_TEST_INIT 2 /* Care-of Test Init */ +#define IP6M_HOME_TEST 3 /* Home Test */ +#define IP6M_CAREOF_TEST 4 /* Care-of Test */ +#define IP6M_BINDING_UPDATE 5 /* Binding Update */ +#define IP6M_BINDING_ACK 6 /* Binding Acknowledgement */ +#define IP6M_BINDING_ERROR 7 /* Binding Error */ + +/* Mobility Header Options */ +#define IP6MOPT_MINLEN 2 +#define IP6MOPT_PAD1 0x0 /* Pad1 */ +#define IP6MOPT_PADN 0x1 /* PadN */ +#define IP6MOPT_REFRESH 0x2 /* Binding Refresh Advice */ +#define IP6MOPT_REFRESH_MINLEN 4 +#define IP6MOPT_ALTCOA 0x3 /* Alternate Care-of Address */ +#define IP6MOPT_ALTCOA_MINLEN 18 +#define IP6MOPT_NONCEID 0x4 /* Nonce Indices */ +#define IP6MOPT_NONCEID_MINLEN 6 +#define IP6MOPT_AUTH 0x5 /* Binding Authorization Data */ +#define IP6MOPT_AUTH_MINLEN 12 + +static void +mobility_opt_print(const u_char *bp, int len) +{ + int i; + int optlen; + + for (i = 0; i < len; i += optlen) { + if (bp[i] == IP6MOPT_PAD1) + optlen = 1; + else { + if (i + 1 < len) + optlen = bp[i + 1] + 2; + else + goto trunc; + } + if (i + optlen > len) + goto trunc; + + switch (bp[i]) { + case IP6MOPT_PAD1: + printf("(pad1)"); + break; + case IP6MOPT_PADN: + if (len - i < IP6MOPT_MINLEN) { + printf("(padn: trunc)"); + goto trunc; + } + printf("(padn)"); + break; + case IP6MOPT_REFRESH: + if (len - i < IP6MOPT_REFRESH_MINLEN) { + printf("(refresh: trunc)"); + goto trunc; + } + /* units of 4 secs */ + printf("(refresh: %d)", + EXTRACT_16BITS(&bp[i+2]) << 2); + break; + case IP6MOPT_ALTCOA: + if (len - i < IP6MOPT_ALTCOA_MINLEN) { + printf("(altcoa: trunc)"); + goto trunc; + } + printf("(alt-CoA: %s)", ip6addr_string(&bp[i+2])); + break; + case IP6MOPT_NONCEID: + if (len - i < IP6MOPT_NONCEID_MINLEN) { + printf("(ni: trunc)"); + goto trunc; + } + printf("(ni: ho=0x%04x co=0x%04x)", + EXTRACT_16BITS(&bp[i+2]), + EXTRACT_16BITS(&bp[i+4])); + break; + case IP6MOPT_AUTH: + if (len - i < IP6MOPT_AUTH_MINLEN) { + printf("(auth: trunc)"); + goto trunc; + } + printf("(auth)"); + break; + default: + if (len - i < IP6MOPT_MINLEN) { + printf("(sopt_type %d: trunc)", bp[i]); + goto trunc; + } + printf("(type-0x%02x: len=%d)", bp[i], bp[i + 1]); + break; + } + } + return; + +trunc: + printf("[trunc] "); +} + +/* + * Mobility Header + */ +int +mobility_print(const u_char *bp, const u_char *bp2 _U_) +{ + const struct ip6_mobility *mh; + const u_char *ep; + int mhlen, hlen, type; + + mh = (struct ip6_mobility *)bp; + + /* 'ep' points to the end of available data. */ + ep = snapend; + + if (!TTEST(mh->ip6m_len)) { + /* + * There's not enough captured data to include the + * mobility header length. + * + * Our caller expects us to return the length, however, + * so return a value that will run to the end of the + * captured data. + * + * XXX - "ip6_print()" doesn't do anything with the + * returned length, however, as it breaks out of the + * header-processing loop. + */ + mhlen = ep - bp; + goto trunc; + } + mhlen = (int)((mh->ip6m_len + 1) << 3); + + /* XXX ip6m_cksum */ + + TCHECK(mh->ip6m_type); + type = mh->ip6m_type; + switch (type) { + case IP6M_BINDING_REQUEST: + printf("mobility: BRR"); + hlen = IP6M_MINLEN; + break; + case IP6M_HOME_TEST_INIT: + case IP6M_CAREOF_TEST_INIT: + printf("mobility: %soTI", + type == IP6M_HOME_TEST_INIT ? "H" : "C"); + hlen = IP6M_MINLEN; + if (vflag) { + TCHECK2(*mh, hlen + 8); + printf(" %s Init Cookie=%08x:%08x", + type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of", + EXTRACT_32BITS(&bp[hlen]), + EXTRACT_32BITS(&bp[hlen + 4])); + } + hlen += 8; + break; + case IP6M_HOME_TEST: + case IP6M_CAREOF_TEST: + printf("mobility: %soT", + type == IP6M_HOME_TEST ? "H" : "C"); + TCHECK(mh->ip6m_data16[0]); + printf(" nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0])); + hlen = IP6M_MINLEN; + if (vflag) { + TCHECK2(*mh, hlen + 8); + printf(" %s Init Cookie=%08x:%08x", + type == IP6M_HOME_TEST ? "Home" : "Care-of", + EXTRACT_32BITS(&bp[hlen]), + EXTRACT_32BITS(&bp[hlen + 4])); + } + hlen += 8; + if (vflag) { + TCHECK2(*mh, hlen + 8); + printf(" %s Keygen Token=%08x:%08x", + type == IP6M_HOME_TEST ? "Home" : "Care-of", + EXTRACT_32BITS(&bp[hlen]), + EXTRACT_32BITS(&bp[hlen + 4])); + } + hlen += 8; + break; + case IP6M_BINDING_UPDATE: + printf("mobility: BU"); + TCHECK(mh->ip6m_data16[0]); + printf(" seq#=%d", EXTRACT_16BITS(&mh->ip6m_data16[0])); + hlen = IP6M_MINLEN; + TCHECK2(*mh, hlen + 1); + if (bp[hlen] & 0xf0) + printf(" "); + if (bp[hlen] & 0x80) + printf("A"); + if (bp[hlen] & 0x40) + printf("H"); + if (bp[hlen] & 0x20) + printf("L"); + if (bp[hlen] & 0x10) + printf("K"); + /* Reserved (4bits) */ + hlen += 1; + /* Reserved (8bits) */ + hlen += 1; + TCHECK2(*mh, hlen + 2); + /* units of 4 secs */ + printf(" lifetime=%d", EXTRACT_16BITS(&bp[hlen]) << 2); + hlen += 2; + break; + case IP6M_BINDING_ACK: + printf("mobility: BA"); + TCHECK(mh->ip6m_data8[0]); + printf(" status=%d", mh->ip6m_data8[0]); + if (mh->ip6m_data8[1] & 0x80) + printf(" K"); + /* Reserved (7bits) */ + hlen = IP6M_MINLEN; + TCHECK2(*mh, hlen + 2); + printf(" seq#=%d", EXTRACT_16BITS(&bp[hlen])); + hlen += 2; + TCHECK2(*mh, hlen + 2); + /* units of 4 secs */ + printf(" lifetime=%d", EXTRACT_16BITS(&bp[hlen]) << 2); + hlen += 2; + break; + case IP6M_BINDING_ERROR: + printf("mobility: BE"); + TCHECK(mh->ip6m_data8[0]); + printf(" status=%d", mh->ip6m_data8[0]); + /* Reserved */ + hlen = IP6M_MINLEN; + TCHECK2(*mh, hlen + 16); + printf(" homeaddr %s", ip6addr_string(&bp[hlen])); + hlen += 16; + break; + default: + printf("mobility: type-#%d len=%d", type, mh->ip6m_len); + return(mhlen); + break; + } + if (vflag) + mobility_opt_print(&bp[hlen], mhlen - hlen); + + return(mhlen); + + trunc: + fputs("[|MOBILITY]", stdout); + return(mhlen); +} +#endif /* INET6 */ diff --git a/freebsd/contrib/tcpdump/print-mpcp.c b/freebsd/contrib/tcpdump/print-mpcp.c new file mode 100644 index 00000000..f9ea1683 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-mpcp.c @@ -0,0 +1,276 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 MPCP protocol as per 802.3ah + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-mpcp.c,v 1.2 2006-02-10 17:24:55 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ether.h" + +#define MPCP_TIMESTAMP_LEN 4 +#define MPCP_TIMESTAMP_DURATION_LEN 2 + +struct mpcp_common_header_t { + u_int8_t opcode[2]; + u_int8_t timestamp[MPCP_TIMESTAMP_LEN]; +}; + +#define MPCP_OPCODE_PAUSE 0x0001 +#define MPCP_OPCODE_GATE 0x0002 +#define MPCP_OPCODE_REPORT 0x0003 +#define MPCP_OPCODE_REG_REQ 0x0004 +#define MPCP_OPCODE_REG 0x0005 +#define MPCP_OPCODE_REG_ACK 0x0006 + +static const struct tok mpcp_opcode_values[] = { + { MPCP_OPCODE_PAUSE, "Pause" }, + { MPCP_OPCODE_GATE, "Gate" }, + { MPCP_OPCODE_REPORT, "Report" }, + { MPCP_OPCODE_REG_REQ, "Register Request" }, + { MPCP_OPCODE_REG, "Register" }, + { MPCP_OPCODE_REG_ACK, "Register ACK" }, + { 0, NULL} +}; + +#define MPCP_GRANT_NUMBER_LEN 1 +#define MPCP_GRANT_NUMBER_MASK 0x7 +static const struct tok mpcp_grant_flag_values[] = { + { 0x08, "Discovery" }, + { 0x10, "Force Grant #1" }, + { 0x20, "Force Grant #2" }, + { 0x40, "Force Grant #3" }, + { 0x80, "Force Grant #4" }, + { 0, NULL} +}; + +struct mpcp_grant_t { + u_int8_t starttime[MPCP_TIMESTAMP_LEN]; + u_int8_t duration[MPCP_TIMESTAMP_DURATION_LEN]; +}; + +struct mpcp_reg_req_t { + u_int8_t flags; + u_int8_t pending_grants; +}; + + +static const struct tok mpcp_reg_req_flag_values[] = { + { 1, "Register" }, + { 3, "De-Register" }, + { 0, NULL} +}; + +struct mpcp_reg_t { + u_int8_t assigned_port[2]; + u_int8_t flags; + u_int8_t sync_time[MPCP_TIMESTAMP_DURATION_LEN]; + u_int8_t echoed_pending_grants; +}; + +static const struct tok mpcp_reg_flag_values[] = { + { 1, "Re-Register" }, + { 2, "De-Register" }, + { 3, "ACK" }, + { 4, "NACK" }, + { 0, NULL} +}; + +#define MPCP_REPORT_QUEUESETS_LEN 1 +#define MPCP_REPORT_REPORTBITMAP_LEN 1 +static const struct tok mpcp_report_bitmap_values[] = { + { 0x01, "Q0" }, + { 0x02, "Q1" }, + { 0x04, "Q2" }, + { 0x08, "Q3" }, + { 0x10, "Q4" }, + { 0x20, "Q5" }, + { 0x40, "Q6" }, + { 0x80, "Q7" }, + { 0, NULL} +}; + +struct mpcp_reg_ack_t { + u_int8_t flags; + u_int8_t echoed_assigned_port[2]; + u_int8_t echoed_sync_time[MPCP_TIMESTAMP_DURATION_LEN]; +}; + +static const struct tok mpcp_reg_ack_flag_values[] = { + { 0, "NACK" }, + { 1, "ACK" }, + { 0, NULL} +}; + +void +mpcp_print(register const u_char *pptr, register u_int length) { + + union { + const struct mpcp_common_header_t *common_header; + const struct mpcp_grant_t *grant; + const struct mpcp_reg_req_t *reg_req; + const struct mpcp_reg_t *reg; + const struct mpcp_reg_ack_t *reg_ack; + } mpcp; + + + const u_char *tptr; + u_int16_t opcode; + u_int8_t grant_numbers, grant; + u_int8_t queue_sets, queue_set, report_bitmap, report; + + tptr=pptr; + mpcp.common_header = (const struct mpcp_common_header_t *)pptr; + + if (!TTEST2(*tptr, sizeof(const struct mpcp_common_header_t))) + goto trunc; + opcode = EXTRACT_16BITS(mpcp.common_header->opcode); + printf("MPCP, Opcode %s", tok2str(mpcp_opcode_values, "Unknown (%u)", opcode)); + if (opcode != MPCP_OPCODE_PAUSE) { + printf(", Timestamp %u ticks", EXTRACT_32BITS(mpcp.common_header->timestamp)); + } + printf(", length %u", length); + + if (!vflag) + return; + + tptr += sizeof(const struct mpcp_common_header_t); + + switch (opcode) { + case MPCP_OPCODE_PAUSE: + break; + + case MPCP_OPCODE_GATE: + if (!TTEST2(*tptr, MPCP_GRANT_NUMBER_LEN)) + goto trunc; + grant_numbers = *tptr & MPCP_GRANT_NUMBER_MASK; + printf("\n\tGrant Numbers %u, Flags [ %s ]", + grant_numbers, + bittok2str(mpcp_grant_flag_values, + "?", + *tptr &~ MPCP_GRANT_NUMBER_MASK)); + tptr++; + + for (grant = 1; grant <= grant_numbers; grant++) { + if (!TTEST2(*tptr, sizeof(const struct mpcp_grant_t))) + goto trunc; + mpcp.grant = (const struct mpcp_grant_t *)tptr; + printf("\n\tGrant #%u, Start-Time %u ticks, duration %u ticks", + grant, + EXTRACT_32BITS(mpcp.grant->starttime), + EXTRACT_16BITS(mpcp.grant->duration)); + tptr += sizeof(const struct mpcp_grant_t); + } + + if (!TTEST2(*tptr, MPCP_TIMESTAMP_DURATION_LEN)) + goto trunc; + printf("\n\tSync-Time %u ticks", EXTRACT_16BITS(tptr)); + break; + + + case MPCP_OPCODE_REPORT: + if (!TTEST2(*tptr, MPCP_REPORT_QUEUESETS_LEN)) + goto trunc; + queue_sets = *tptr; + tptr+=MPCP_REPORT_QUEUESETS_LEN; + printf("\n\tTotal Queue-Sets %u", queue_sets); + + for (queue_set = 1; queue_set < queue_sets; queue_set++) { + if (!TTEST2(*tptr, MPCP_REPORT_REPORTBITMAP_LEN)) + goto trunc; + report_bitmap = *(tptr); + printf("\n\t Queue-Set #%u, Report-Bitmap [ %s ]", + queue_sets, + bittok2str(mpcp_report_bitmap_values, "Unknown", report_bitmap)); + tptr++; + + report=1; + while (report_bitmap != 0) { + if (report_bitmap & 1) { + if (!TTEST2(*tptr, MPCP_TIMESTAMP_DURATION_LEN)) + goto trunc; + printf("\n\t Q%u Report, Duration %u ticks", + report, + EXTRACT_16BITS(tptr)); + tptr+=MPCP_TIMESTAMP_DURATION_LEN; + } + report++; + report_bitmap = report_bitmap >> 1; + } + } + break; + + case MPCP_OPCODE_REG_REQ: + if (!TTEST2(*tptr, sizeof(const struct mpcp_reg_req_t))) + goto trunc; + mpcp.reg_req = (const struct mpcp_reg_req_t *)tptr; + printf("\n\tFlags [ %s ], Pending-Grants %u", + bittok2str(mpcp_reg_req_flag_values, "Reserved", mpcp.reg_req->flags), + mpcp.reg_req->pending_grants); + break; + + case MPCP_OPCODE_REG: + if (!TTEST2(*tptr, sizeof(const struct mpcp_reg_t))) + goto trunc; + mpcp.reg = (const struct mpcp_reg_t *)tptr; + printf("\n\tAssigned-Port %u, Flags [ %s ]" \ + "\n\tSync-Time %u ticks, Echoed-Pending-Grants %u", + EXTRACT_16BITS(mpcp.reg->assigned_port), + bittok2str(mpcp_reg_flag_values, "Reserved", mpcp.reg->flags), + EXTRACT_16BITS(mpcp.reg->sync_time), + mpcp.reg->echoed_pending_grants); + break; + + case MPCP_OPCODE_REG_ACK: + if (!TTEST2(*tptr, sizeof(const struct mpcp_reg_ack_t))) + goto trunc; + mpcp.reg_ack = (const struct mpcp_reg_ack_t *)tptr; + printf("\n\tEchoed-Assigned-Port %u, Flags [ %s ]" \ + "\n\tEchoed-Sync-Time %u ticks", + EXTRACT_16BITS(mpcp.reg_ack->echoed_assigned_port), + bittok2str(mpcp_reg_ack_flag_values, "Reserved", mpcp.reg_ack->flags), + EXTRACT_16BITS(mpcp.reg_ack->echoed_sync_time)); + break; + + default: + /* unknown opcode - hexdump for now */ + print_unknown_data(pptr, "\n\t", length); + break; + } + + return; + +trunc: + printf("\n\t[|MPCP]"); +} diff --git a/freebsd/contrib/tcpdump/print-mpls.c b/freebsd/contrib/tcpdump/print-mpls.c new file mode 100644 index 00000000..3a755f77 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-mpls.c @@ -0,0 +1,229 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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-mpls.c,v 1.14 2005-07-05 09:38:19 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "addrtoname.h" +#include "interface.h" +#include "extract.h" /* must come after interface.h */ +#include "mpls.h" + +static const char *mpls_labelname[] = { +/*0*/ "IPv4 explicit NULL", "router alert", "IPv6 explicit NULL", + "implicit NULL", "rsvd", +/*5*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", +/*10*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", +/*15*/ "rsvd", +}; + +enum mpls_packet_type { + PT_UNKNOWN, + PT_IPV4, + PT_IPV6, + PT_OSI +}; + +/* + * RFC3032: MPLS label stack encoding + */ +void +mpls_print(const u_char *bp, u_int length) +{ + const u_char *p; + u_int32_t label_entry; + u_int16_t label_stack_depth = 0; + enum mpls_packet_type pt = PT_UNKNOWN; + + p = bp; + printf("MPLS"); + do { + TCHECK2(*p, sizeof(label_entry)); + label_entry = EXTRACT_32BITS(p); + printf("%s(label %u", + (label_stack_depth && vflag) ? "\n\t" : " ", + MPLS_LABEL(label_entry)); + label_stack_depth++; + if (vflag && + MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0])) + printf(" (%s)", mpls_labelname[MPLS_LABEL(label_entry)]); + printf(", exp %u", MPLS_EXP(label_entry)); + if (MPLS_STACK(label_entry)) + printf(", [S]"); + printf(", ttl %u)", MPLS_TTL(label_entry)); + + p += sizeof(label_entry); + } while (!MPLS_STACK(label_entry)); + + /* + * Try to figure out the packet type. + */ + switch (MPLS_LABEL(label_entry)) { + + case 0: /* IPv4 explicit NULL label */ + case 3: /* IPv4 implicit NULL label */ + pt = PT_IPV4; + break; + + case 2: /* IPv6 explicit NULL label */ + pt = PT_IPV6; + break; + + default: + /* + * Generally there's no indication of protocol in MPLS label + * encoding. + * + * However, draft-hsmit-isis-aal5mux-00.txt describes a + * technique for encapsulating IS-IS and IP traffic on the + * same ATM virtual circuit; you look at the first payload + * byte to determine the network layer protocol, based on + * the fact that + * + * 1) the first byte of an IP header is 0x45-0x4f + * for IPv4 and 0x60-0x6f for IPv6; + * + * 2) the first byte of an OSI CLNP packet is 0x81, + * the first byte of an OSI ES-IS packet is 0x82, + * and the first byte of an OSI IS-IS packet is + * 0x83; + * + * so the network layer protocol can be inferred from the + * first byte of the packet, if the protocol is one of the + * ones listed above. + * + * Cisco sends control-plane traffic MPLS-encapsulated in + * this fashion. + */ + switch(*p) { + + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + pt = PT_IPV4; + break; + + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + pt = PT_IPV6; + break; + + case 0x81: + case 0x82: + case 0x83: + pt = PT_OSI; + break; + + default: + /* ok bail out - we did not figure out what it is*/ + break; + } + } + + /* + * Print the payload. + */ + if (pt == PT_UNKNOWN) { + if (!suppress_default_print) + default_print(p, length - (p - bp)); + return; + } + if (vflag) + printf("\n\t"); + else + printf(" "); + switch (pt) { + + case PT_IPV4: + ip_print(gndo, p, length - (p - bp)); + break; + + case PT_IPV6: +#ifdef INET6 + ip6_print(gndo, p, length - (p - bp)); +#else + printf("IPv6, length: %u", length); +#endif + break; + + case PT_OSI: + isoclns_print(p, length - (p - bp), length - (p - bp)); + break; + + default: + break; + } + return; + +trunc: + printf("[|MPLS]"); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-msdp.c b/freebsd/contrib/tcpdump/print-msdp.c new file mode 100644 index 00000000..6269c2c2 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-msdp.c @@ -0,0 +1,110 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2001 William C. Fenner. + * 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, 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. + * The name of William C. Fenner 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. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-msdp.c,v 1.7 2005-04-06 21:32:41 mcr Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#define MSDP_TYPE_MAX 7 + +void +msdp_print(const unsigned char *sp, u_int length) +{ + unsigned int type, len; + + TCHECK2(*sp, 3); + /* See if we think we're at the beginning of a compound packet */ + type = *sp; + len = EXTRACT_16BITS(sp + 1); + if (len > 1500 || len < 3 || type == 0 || type > MSDP_TYPE_MAX) + goto trunc; /* not really truncated, but still not decodable */ + (void)printf(" msdp:"); + while (length > 0) { + TCHECK2(*sp, 3); + type = *sp; + len = EXTRACT_16BITS(sp + 1); + if (len > 1400 || vflag) + printf(" [len %u]", len); + if (len < 3) + goto trunc; + sp += 3; + length -= 3; + switch (type) { + case 1: /* IPv4 Source-Active */ + case 3: /* IPv4 Source-Active Response */ + if (type == 1) + (void)printf(" SA"); + else + (void)printf(" SA-Response"); + TCHECK(*sp); + (void)printf(" %u entries", *sp); + if ((u_int)((*sp * 12) + 8) < len) { + (void)printf(" [w/data]"); + if (vflag > 1) { + (void)printf(" "); + ip_print(gndo, sp + *sp * 12 + 8 - 3, + len - (*sp * 12 + 8)); + } + } + break; + case 2: + (void)printf(" SA-Request"); + TCHECK2(*sp, 5); + (void)printf(" for %s", ipaddr_string(sp + 1)); + break; + case 4: + (void)printf(" Keepalive"); + if (len != 3) + (void)printf("[len=%d] ", len); + break; + case 5: + (void)printf(" Notification"); + break; + default: + (void)printf(" [type=%d len=%d]", type, len); + break; + } + sp += (len - 3); + length -= (len - 3); + } + return; +trunc: + (void)printf(" [|msdp]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-msnlb.c b/freebsd/contrib/tcpdump/print-msnlb.c new file mode 100644 index 00000000..c0274a4f --- /dev/null +++ b/freebsd/contrib/tcpdump/print-msnlb.c @@ -0,0 +1,68 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2013 Romain Francoise <romain@orebokech.com> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "netdissect.h" +#include "addrtoname.h" +#include "extract.h" + +struct msnlb_heartbeat_pkt { + u_int32_t unknown1; + u_int32_t unknown2; + u_int32_t host_prio; /* little-endian */ + u_int32_t virtual_ip; + u_int32_t host_ip; + /* the protocol is undocumented so we ignore the rest */ +}; + +void +msnlb_print(netdissect_options *ndo, const u_char *bp, u_int length) +{ + const struct msnlb_heartbeat_pkt *hb; + + hb = (struct msnlb_heartbeat_pkt *)bp; + ND_TCHECK(*hb); + + ND_PRINT((ndo, "MS NLB heartbeat, host priority: %u,", + EXTRACT_LE_32BITS(&(hb->host_prio)))); + ND_PRINT((ndo, " cluster IP: %s,", ipaddr_string(&(hb->virtual_ip)))); + ND_PRINT((ndo, " host IP: %s", ipaddr_string(&(hb->host_ip)))); + return; +trunc: + ND_PRINT((ndo, "[|MS NLB]")); +} diff --git a/freebsd/contrib/tcpdump/print-netbios.c b/freebsd/contrib/tcpdump/print-netbios.c new file mode 100644 index 00000000..fa32d146 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-netbios.c @@ -0,0 +1,93 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 NETBIOS packets. + * Contributed by Brad Parker (brad@fcr.com). + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-netbios.c,v 1.20 2003-11-16 09:36:29 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "netbios.h" +#include "extract.h" + +/* + * Print NETBIOS packets. + */ +void +netbios_print(struct p8022Hdr *nb, u_int length) +{ + if (length < p8022Size) { + (void)printf(" truncated-netbios %d", length); + return; + } + + if (nb->flags == UI) { + (void)printf("802.1 UI "); + } else { + (void)printf("802.1 CONN "); + } + + if ((u_char *)(nb + 1) > snapend) { + printf(" [|netbios]"); + return; + } + +/* + netbios_decode(nb, (u_char *)nb + p8022Size, length - p8022Size); +*/ +} + +#ifdef never + (void)printf("%s.%d > ", + ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode), + EXTRACT_16BITS(ipx->srcSkt)); + + (void)printf("%s.%d:", + ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode), + EXTRACT_16BITS(ipx->dstSkt)); + + if ((u_char *)(ipx + 1) > snapend) { + printf(" [|ipx]"); + return; + } + + /* take length from ipx header */ + length = EXTRACT_16BITS(&ipx->length); + + ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize); +#endif + diff --git a/freebsd/contrib/tcpdump/print-nfs.c b/freebsd/contrib/tcpdump/print-nfs.c new file mode 100644 index 00000000..34dbfa6c --- /dev/null +++ b/freebsd/contrib/tcpdump/print-nfs.c @@ -0,0 +1,1855 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.111 2007-12-22 03:08:04 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "nfs.h" +#include "nfsfh.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "rpc_auth.h" +#include "rpc_msg.h" + +static void nfs_printfh(const u_int32_t *, const u_int); +static int xid_map_enter(const struct sunrpc_msg *, const u_char *); +static int32_t xid_map_find(const struct sunrpc_msg *, const u_char *, + u_int32_t *, u_int32_t *); +static void interp_reply(const struct sunrpc_msg *, u_int32_t, u_int32_t, int); +static const u_int32_t *parse_post_op_attr(const u_int32_t *, int); +static void print_sattr3(const struct nfsv3_sattr *sa3, int verbose); +static void print_nfsaddr(const u_char *, const char *, const char *); + +/* + * Mapping of old NFS Version 2 RPC numbers to generic numbers. + */ +u_int32_t nfsv3_procid[NFS_NPROCS] = { + NFSPROC_NULL, + NFSPROC_GETATTR, + NFSPROC_SETATTR, + NFSPROC_NOOP, + NFSPROC_LOOKUP, + NFSPROC_READLINK, + NFSPROC_READ, + NFSPROC_NOOP, + NFSPROC_WRITE, + NFSPROC_CREATE, + NFSPROC_REMOVE, + NFSPROC_RENAME, + NFSPROC_LINK, + NFSPROC_SYMLINK, + NFSPROC_MKDIR, + NFSPROC_RMDIR, + NFSPROC_READDIR, + NFSPROC_FSSTAT, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP +}; + +/* + * NFS V2 and V3 status values. + * + * Some of these come from the RFCs for NFS V2 and V3, with the message + * strings taken from the FreeBSD C library "errlst.c". + * + * Others are errors that are not in the RFC but that I suspect some + * NFS servers could return; the values are FreeBSD errno values, as + * the first NFS server was the SunOS 2.0 one, and until 5.0 SunOS + * was primarily BSD-derived. + */ +static struct tok status2str[] = { + { 1, "Operation not permitted" }, /* EPERM */ + { 2, "No such file or directory" }, /* ENOENT */ + { 5, "Input/output error" }, /* EIO */ + { 6, "Device not configured" }, /* ENXIO */ + { 11, "Resource deadlock avoided" }, /* EDEADLK */ + { 12, "Cannot allocate memory" }, /* ENOMEM */ + { 13, "Permission denied" }, /* EACCES */ + { 17, "File exists" }, /* EEXIST */ + { 18, "Cross-device link" }, /* EXDEV */ + { 19, "Operation not supported by device" }, /* ENODEV */ + { 20, "Not a directory" }, /* ENOTDIR */ + { 21, "Is a directory" }, /* EISDIR */ + { 22, "Invalid argument" }, /* EINVAL */ + { 26, "Text file busy" }, /* ETXTBSY */ + { 27, "File too large" }, /* EFBIG */ + { 28, "No space left on device" }, /* ENOSPC */ + { 30, "Read-only file system" }, /* EROFS */ + { 31, "Too many links" }, /* EMLINK */ + { 45, "Operation not supported" }, /* EOPNOTSUPP */ + { 62, "Too many levels of symbolic links" }, /* ELOOP */ + { 63, "File name too long" }, /* ENAMETOOLONG */ + { 66, "Directory not empty" }, /* ENOTEMPTY */ + { 69, "Disc quota exceeded" }, /* EDQUOT */ + { 70, "Stale NFS file handle" }, /* ESTALE */ + { 71, "Too many levels of remote in path" }, /* EREMOTE */ + { 99, "Write cache flushed to disk" }, /* NFSERR_WFLUSH (not used) */ + { 10001, "Illegal NFS file handle" }, /* NFS3ERR_BADHANDLE */ + { 10002, "Update synchronization mismatch" }, /* NFS3ERR_NOT_SYNC */ + { 10003, "READDIR/READDIRPLUS cookie is stale" }, /* NFS3ERR_BAD_COOKIE */ + { 10004, "Operation not supported" }, /* NFS3ERR_NOTSUPP */ + { 10005, "Buffer or request is too small" }, /* NFS3ERR_TOOSMALL */ + { 10006, "Unspecified error on server" }, /* NFS3ERR_SERVERFAULT */ + { 10007, "Object of that type not supported" }, /* NFS3ERR_BADTYPE */ + { 10008, "Request couldn't be completed in time" }, /* NFS3ERR_JUKEBOX */ + { 0, NULL } +}; + +static struct tok nfsv3_writemodes[] = { + { 0, "unstable" }, + { 1, "datasync" }, + { 2, "filesync" }, + { 0, NULL } +}; + +static struct tok type2str[] = { + { NFNON, "NON" }, + { NFREG, "REG" }, + { NFDIR, "DIR" }, + { NFBLK, "BLK" }, + { NFCHR, "CHR" }, + { NFLNK, "LNK" }, + { NFFIFO, "FIFO" }, + { 0, NULL } +}; + +static void +print_nfsaddr(const u_char *bp, const char *s, const char *d) +{ + struct ip *ip; +#ifdef INET6 + struct ip6_hdr *ip6; + char srcaddr[INET6_ADDRSTRLEN], dstaddr[INET6_ADDRSTRLEN]; +#else +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + char srcaddr[INET_ADDRSTRLEN], dstaddr[INET_ADDRSTRLEN]; +#endif + + srcaddr[0] = dstaddr[0] = '\0'; + switch (IP_V((struct ip *)bp)) { + case 4: + ip = (struct ip *)bp; + strlcpy(srcaddr, ipaddr_string(&ip->ip_src), sizeof(srcaddr)); + strlcpy(dstaddr, ipaddr_string(&ip->ip_dst), sizeof(dstaddr)); + break; +#ifdef INET6 + case 6: + ip6 = (struct ip6_hdr *)bp; + strlcpy(srcaddr, ip6addr_string(&ip6->ip6_src), + sizeof(srcaddr)); + strlcpy(dstaddr, ip6addr_string(&ip6->ip6_dst), + sizeof(dstaddr)); + break; +#endif + default: + strlcpy(srcaddr, "?", sizeof(srcaddr)); + strlcpy(dstaddr, "?", sizeof(dstaddr)); + break; + } + + (void)printf("%s.%s > %s.%s: ", srcaddr, s, dstaddr, d); +} + +static const u_int32_t * +parse_sattr3(const u_int32_t *dp, struct nfsv3_sattr *sa3) +{ + TCHECK(dp[0]); + sa3->sa_modeset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_modeset) { + TCHECK(dp[0]); + sa3->sa_mode = EXTRACT_32BITS(dp); + dp++; + } + + TCHECK(dp[0]); + sa3->sa_uidset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_uidset) { + TCHECK(dp[0]); + sa3->sa_uid = EXTRACT_32BITS(dp); + dp++; + } + + TCHECK(dp[0]); + sa3->sa_gidset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_gidset) { + TCHECK(dp[0]); + sa3->sa_gid = EXTRACT_32BITS(dp); + dp++; + } + + TCHECK(dp[0]); + sa3->sa_sizeset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_sizeset) { + TCHECK(dp[0]); + sa3->sa_size = EXTRACT_32BITS(dp); + dp++; + } + + TCHECK(dp[0]); + sa3->sa_atimetype = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) { + TCHECK(dp[1]); + sa3->sa_atime.nfsv3_sec = EXTRACT_32BITS(dp); + dp++; + sa3->sa_atime.nfsv3_nsec = EXTRACT_32BITS(dp); + dp++; + } + + TCHECK(dp[0]); + sa3->sa_mtimetype = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) { + TCHECK(dp[1]); + sa3->sa_mtime.nfsv3_sec = EXTRACT_32BITS(dp); + dp++; + sa3->sa_mtime.nfsv3_nsec = EXTRACT_32BITS(dp); + dp++; + } + + return dp; +trunc: + return NULL; +} + +static int nfserr; /* true if we error rather than trunc */ + +static void +print_sattr3(const struct nfsv3_sattr *sa3, int verbose) +{ + if (sa3->sa_modeset) + printf(" mode %o", sa3->sa_mode); + if (sa3->sa_uidset) + printf(" uid %u", sa3->sa_uid); + if (sa3->sa_gidset) + printf(" gid %u", sa3->sa_gid); + if (verbose > 1) { + if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) + printf(" atime %u.%06u", sa3->sa_atime.nfsv3_sec, + sa3->sa_atime.nfsv3_nsec); + if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) + printf(" mtime %u.%06u", sa3->sa_mtime.nfsv3_sec, + sa3->sa_mtime.nfsv3_nsec); + } +} + +void +nfsreply_print(register const u_char *bp, u_int length, + register const u_char *bp2) +{ + register const struct sunrpc_msg *rp; + u_int32_t proc, vers, reply_stat; + char srcid[20], dstid[20]; /*fits 32bit*/ + enum sunrpc_reject_stat rstat; + u_int32_t rlow; + u_int32_t rhigh; + enum sunrpc_auth_stat rwhy; + + nfserr = 0; /* assume no error */ + rp = (const struct sunrpc_msg *)bp; + + TCHECK(rp->rm_xid); + if (!nflag) { + strlcpy(srcid, "nfs", sizeof(srcid)); + snprintf(dstid, sizeof(dstid), "%u", + EXTRACT_32BITS(&rp->rm_xid)); + } else { + snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); + snprintf(dstid, sizeof(dstid), "%u", + EXTRACT_32BITS(&rp->rm_xid)); + } + print_nfsaddr(bp2, srcid, dstid); + TCHECK(rp->rm_reply.rp_stat); + reply_stat = EXTRACT_32BITS(&rp->rm_reply.rp_stat); + switch (reply_stat) { + + case SUNRPC_MSG_ACCEPTED: + (void)printf("reply ok %u", length); + if (xid_map_find(rp, bp2, &proc, &vers) >= 0) + interp_reply(rp, proc, vers, length); + break; + + case SUNRPC_MSG_DENIED: + (void)printf("reply ERR %u: ", length); + TCHECK(rp->rm_reply.rp_reject.rj_stat); + rstat = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_stat); + switch (rstat) { + + case SUNRPC_RPC_MISMATCH: + TCHECK(rp->rm_reply.rp_reject.rj_vers.high); + rlow = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.low); + rhigh = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.high); + (void)printf("RPC Version mismatch (%u-%u)", + rlow, rhigh); + break; + + case SUNRPC_AUTH_ERROR: + TCHECK(rp->rm_reply.rp_reject.rj_why); + rwhy = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_why); + (void)printf("Auth "); + switch (rwhy) { + + case SUNRPC_AUTH_OK: + (void)printf("OK"); + break; + + case SUNRPC_AUTH_BADCRED: + (void)printf("Bogus Credentials (seal broken)"); + break; + + case SUNRPC_AUTH_REJECTEDCRED: + (void)printf("Rejected Credentials (client should begin new session)"); + break; + + case SUNRPC_AUTH_BADVERF: + (void)printf("Bogus Verifier (seal broken)"); + break; + + case SUNRPC_AUTH_REJECTEDVERF: + (void)printf("Verifier expired or was replayed"); + break; + + case SUNRPC_AUTH_TOOWEAK: + (void)printf("Credentials are too weak"); + break; + + case SUNRPC_AUTH_INVALIDRESP: + (void)printf("Bogus response verifier"); + break; + + case SUNRPC_AUTH_FAILED: + (void)printf("Unknown failure"); + break; + + default: + (void)printf("Invalid failure code %u", + (unsigned int)rwhy); + break; + } + break; + + default: + (void)printf("Unknown reason for rejecting rpc message %u", + (unsigned int)rstat); + break; + } + break; + + default: + (void)printf("reply Unknown rpc response code=%u %u", + reply_stat, length); + break; + } + return; + +trunc: + if (!nfserr) + fputs(" [|nfs]", stdout); +} + +/* + * Return a pointer to the first file handle in the packet. + * If the packet was truncated, return 0. + */ +static const u_int32_t * +parsereq(register const struct sunrpc_msg *rp, register u_int length) +{ + register const u_int32_t *dp; + register u_int len; + + /* + * find the start of the req data (if we captured it) + */ + dp = (u_int32_t *)&rp->rm_call.cb_cred; + TCHECK(dp[1]); + len = EXTRACT_32BITS(&dp[1]); + if (len < length) { + dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); + TCHECK(dp[1]); + len = EXTRACT_32BITS(&dp[1]); + if (len < length) { + dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); + TCHECK2(dp[0], 0); + return (dp); + } + } +trunc: + return (NULL); +} + +/* + * Print out an NFS file handle and return a pointer to following word. + * If packet was truncated, return 0. + */ +static const u_int32_t * +parsefh(register const u_int32_t *dp, int v3) +{ + u_int len; + + if (v3) { + TCHECK(dp[0]); + len = EXTRACT_32BITS(dp) / 4; + dp++; + } else + len = NFSX_V2FH / 4; + + if (TTEST2(*dp, len * sizeof(*dp))) { + nfs_printfh(dp, len); + return (dp + len); + } +trunc: + return (NULL); +} + +/* + * Print out a file name and return pointer to 32-bit word past it. + * If packet was truncated, return 0. + */ +static const u_int32_t * +parsefn(register const u_int32_t *dp) +{ + register u_int32_t len; + register const u_char *cp; + + /* Bail if we don't have the string length */ + TCHECK(*dp); + + /* Fetch string length; convert to host order */ + len = *dp++; + NTOHL(len); + + TCHECK2(*dp, ((len + 3) & ~3)); + + cp = (u_char *)dp; + /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */ + dp += ((len + 3) & ~3) / sizeof(*dp); + putchar('"'); + if (fn_printn(cp, len, snapend)) { + putchar('"'); + goto trunc; + } + putchar('"'); + + return (dp); +trunc: + return NULL; +} + +/* + * Print out file handle and file name. + * Return pointer to 32-bit word past file name. + * If packet was truncated (or there was some other error), return 0. + */ +static const u_int32_t * +parsefhn(register const u_int32_t *dp, int v3) +{ + dp = parsefh(dp, v3); + if (dp == NULL) + return (NULL); + putchar(' '); + return (parsefn(dp)); +} + +void +nfsreq_print(register const u_char *bp, u_int length, + register const u_char *bp2) +{ + register const struct sunrpc_msg *rp; + register const u_int32_t *dp; + nfs_type type; + int v3; + u_int32_t proc; + u_int32_t access_flags; + struct nfsv3_sattr sa3; + char srcid[20], dstid[20]; /*fits 32bit*/ + + nfserr = 0; /* assume no error */ + rp = (const struct sunrpc_msg *)bp; + + TCHECK(rp->rm_xid); + if (!nflag) { + snprintf(srcid, sizeof(srcid), "%u", + EXTRACT_32BITS(&rp->rm_xid)); + strlcpy(dstid, "nfs", sizeof(dstid)); + } else { + snprintf(srcid, sizeof(srcid), "%u", + EXTRACT_32BITS(&rp->rm_xid)); + snprintf(dstid, sizeof(dstid), "%u", NFS_PORT); + } + print_nfsaddr(bp2, srcid, dstid); + (void)printf("%d", length); + + if (!xid_map_enter(rp, bp2)) /* record proc number for later on */ + goto trunc; + + v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3); + proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); + + if (!v3 && proc < NFS_NPROCS) + proc = nfsv3_procid[proc]; + + switch (proc) { + case NFSPROC_NOOP: + printf(" nop"); + return; + case NFSPROC_NULL: + printf(" null"); + return; + + case NFSPROC_GETATTR: + printf(" getattr"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_SETATTR: + printf(" setattr"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_LOOKUP: + printf(" lookup"); + if ((dp = parsereq(rp, length)) != NULL && + parsefhn(dp, v3) != NULL) + return; + break; + + case NFSPROC_ACCESS: + printf(" access"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + TCHECK(dp[0]); + access_flags = EXTRACT_32BITS(&dp[0]); + if (access_flags & ~NFSV3ACCESS_FULL) { + /* NFSV3ACCESS definitions aren't up to date */ + printf(" %04x", access_flags); + } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) { + printf(" NFS_ACCESS_FULL"); + } else { + char separator = ' '; + if (access_flags & NFSV3ACCESS_READ) { + printf(" NFS_ACCESS_READ"); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_LOOKUP) { + printf("%cNFS_ACCESS_LOOKUP", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_MODIFY) { + printf("%cNFS_ACCESS_MODIFY", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_EXTEND) { + printf("%cNFS_ACCESS_EXTEND", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_DELETE) { + printf("%cNFS_ACCESS_DELETE", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_EXECUTE) + printf("%cNFS_ACCESS_EXECUTE", separator); + } + return; + } + break; + + case NFSPROC_READLINK: + printf(" readlink"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_READ: + printf(" read"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + if (v3) { + TCHECK(dp[2]); + printf(" %u bytes @ %" PRIu64, + EXTRACT_32BITS(&dp[2]), + EXTRACT_64BITS(&dp[0])); + } else { + TCHECK(dp[1]); + printf(" %u bytes @ %u", + EXTRACT_32BITS(&dp[1]), + EXTRACT_32BITS(&dp[0])); + } + return; + } + break; + + case NFSPROC_WRITE: + printf(" write"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + if (v3) { + TCHECK(dp[2]); + printf(" %u (%u) bytes @ %" PRIu64, + EXTRACT_32BITS(&dp[4]), + EXTRACT_32BITS(&dp[2]), + EXTRACT_64BITS(&dp[0])); + if (vflag) { + dp += 3; + TCHECK(dp[0]); + printf(" <%s>", + tok2str(nfsv3_writemodes, + NULL, EXTRACT_32BITS(dp))); + } + } else { + TCHECK(dp[3]); + printf(" %u (%u) bytes @ %u (%u)", + EXTRACT_32BITS(&dp[3]), + EXTRACT_32BITS(&dp[2]), + EXTRACT_32BITS(&dp[1]), + EXTRACT_32BITS(&dp[0])); + } + return; + } + break; + + case NFSPROC_CREATE: + printf(" create"); + if ((dp = parsereq(rp, length)) != NULL && + parsefhn(dp, v3) != NULL) + return; + break; + + case NFSPROC_MKDIR: + printf(" mkdir"); + if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp, v3) != 0) + return; + break; + + case NFSPROC_SYMLINK: + printf(" symlink"); + if ((dp = parsereq(rp, length)) != 0 && + (dp = parsefhn(dp, v3)) != 0) { + fputs(" ->", stdout); + if (v3 && (dp = parse_sattr3(dp, &sa3)) == 0) + break; + if (parsefn(dp) == 0) + break; + if (v3 && vflag) + print_sattr3(&sa3, vflag); + return; + } + break; + + case NFSPROC_MKNOD: + printf(" mknod"); + if ((dp = parsereq(rp, length)) != 0 && + (dp = parsefhn(dp, v3)) != 0) { + TCHECK(*dp); + type = (nfs_type)EXTRACT_32BITS(dp); + dp++; + if ((dp = parse_sattr3(dp, &sa3)) == 0) + break; + printf(" %s", tok2str(type2str, "unk-ft %d", type)); + if (vflag && (type == NFCHR || type == NFBLK)) { + TCHECK(dp[1]); + printf(" %u/%u", + EXTRACT_32BITS(&dp[0]), + EXTRACT_32BITS(&dp[1])); + dp += 2; + } + if (vflag) + print_sattr3(&sa3, vflag); + return; + } + break; + + case NFSPROC_REMOVE: + printf(" remove"); + if ((dp = parsereq(rp, length)) != NULL && + parsefhn(dp, v3) != NULL) + return; + break; + + case NFSPROC_RMDIR: + printf(" rmdir"); + if ((dp = parsereq(rp, length)) != NULL && + parsefhn(dp, v3) != NULL) + return; + break; + + case NFSPROC_RENAME: + printf(" rename"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefhn(dp, v3)) != NULL) { + fputs(" ->", stdout); + if (parsefhn(dp, v3) != NULL) + return; + } + break; + + case NFSPROC_LINK: + printf(" link"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + fputs(" ->", stdout); + if (parsefhn(dp, v3) != NULL) + return; + } + break; + + case NFSPROC_READDIR: + printf(" readdir"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + if (v3) { + TCHECK(dp[4]); + /* + * We shouldn't really try to interpret the + * offset cookie here. + */ + printf(" %u bytes @ %" PRId64, + EXTRACT_32BITS(&dp[4]), + EXTRACT_64BITS(&dp[0])); + if (vflag) + printf(" verf %08x%08x", dp[2], + dp[3]); + } else { + TCHECK(dp[1]); + /* + * Print the offset as signed, since -1 is + * common, but offsets > 2^31 aren't. + */ + printf(" %u bytes @ %d", + EXTRACT_32BITS(&dp[1]), + EXTRACT_32BITS(&dp[0])); + } + return; + } + break; + + case NFSPROC_READDIRPLUS: + printf(" readdirplus"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + TCHECK(dp[4]); + /* + * We don't try to interpret the offset + * cookie here. + */ + printf(" %u bytes @ %" PRId64, + EXTRACT_32BITS(&dp[4]), + EXTRACT_64BITS(&dp[0])); + if (vflag) { + TCHECK(dp[5]); + printf(" max %u verf %08x%08x", + EXTRACT_32BITS(&dp[5]), dp[2], dp[3]); + } + return; + } + break; + + case NFSPROC_FSSTAT: + printf(" fsstat"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_FSINFO: + printf(" fsinfo"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_PATHCONF: + printf(" pathconf"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_COMMIT: + printf(" commit"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + TCHECK(dp[2]); + printf(" %u bytes @ %" PRIu64, + EXTRACT_32BITS(&dp[2]), + EXTRACT_64BITS(&dp[0])); + return; + } + break; + + default: + printf(" proc-%u", EXTRACT_32BITS(&rp->rm_call.cb_proc)); + return; + } + +trunc: + if (!nfserr) + fputs(" [|nfs]", stdout); +} + +/* + * Print out an NFS file handle. + * We assume packet was not truncated before the end of the + * file handle pointed to by dp. + * + * Note: new version (using portable file-handle parser) doesn't produce + * generation number. It probably could be made to do that, with some + * additional hacking on the parser code. + */ +static void +nfs_printfh(register const u_int32_t *dp, const u_int len) +{ + my_fsid fsid; + ino_t ino; + const char *sfsname = NULL; + char *spacep; + + if (uflag) { + u_int i; + char const *sep = ""; + + printf(" fh["); + for (i=0; i<len; i++) { + (void)printf("%s%x", sep, dp[i]); + sep = ":"; + } + printf("]"); + return; + } + + Parse_fh((const u_char *)dp, len, &fsid, &ino, NULL, &sfsname, 0); + + if (sfsname) { + /* file system ID is ASCII, not numeric, for this server OS */ + static char temp[NFSX_V3FHMAX+1]; + + /* Make sure string is null-terminated */ + strncpy(temp, sfsname, NFSX_V3FHMAX); + temp[sizeof(temp) - 1] = '\0'; + /* Remove trailing spaces */ + spacep = strchr(temp, ' '); + if (spacep) + *spacep = '\0'; + + (void)printf(" fh %s/", temp); + } else { + (void)printf(" fh %d,%d/", + fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor); + } + + if(fsid.Fsid_dev.Minor == 257) + /* Print the undecoded handle */ + (void)printf("%s", fsid.Opaque_Handle); + else + (void)printf("%ld", (long) ino); +} + +/* + * Maintain a small cache of recent client.XID.server/proc pairs, to allow + * us to match up replies with requests and thus to know how to parse + * the reply. + */ + +struct xid_map_entry { + u_int32_t xid; /* transaction ID (net order) */ + int ipver; /* IP version (4 or 6) */ +#ifdef INET6 + struct in6_addr client; /* client IP address (net order) */ + struct in6_addr server; /* server IP address (net order) */ +#else + struct in_addr client; /* client IP address (net order) */ + struct in_addr server; /* server IP address (net order) */ +#endif + u_int32_t proc; /* call proc number (host order) */ + u_int32_t vers; /* program version (host order) */ +}; + +/* + * Map entries are kept in an array that we manage as a ring; + * new entries are always added at the tail of the ring. Initially, + * all the entries are zero and hence don't match anything. + */ + +#define XIDMAPSIZE 64 + +struct xid_map_entry xid_map[XIDMAPSIZE]; + +int xid_map_next = 0; +int xid_map_hint = 0; + +static int +xid_map_enter(const struct sunrpc_msg *rp, const u_char *bp) +{ + struct ip *ip = NULL; +#ifdef INET6 + struct ip6_hdr *ip6 = NULL; +#endif + struct xid_map_entry *xmep; + + if (!TTEST(rp->rm_call.cb_vers)) + return (0); + switch (IP_V((struct ip *)bp)) { + case 4: + ip = (struct ip *)bp; + break; +#ifdef INET6 + case 6: + ip6 = (struct ip6_hdr *)bp; + break; +#endif + default: + return (1); + } + + xmep = &xid_map[xid_map_next]; + + if (++xid_map_next >= XIDMAPSIZE) + xid_map_next = 0; + + xmep->xid = rp->rm_xid; + if (ip) { + xmep->ipver = 4; + memcpy(&xmep->client, &ip->ip_src, sizeof(ip->ip_src)); + memcpy(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst)); + } +#ifdef INET6 + else if (ip6) { + xmep->ipver = 6; + memcpy(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src)); + memcpy(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); + } +#endif + xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); + xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers); + return (1); +} + +/* + * Returns 0 and puts NFSPROC_xxx in proc return and + * version in vers return, or returns -1 on failure + */ +static int32_t +xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, u_int32_t *proc, + u_int32_t *vers) +{ + int i; + struct xid_map_entry *xmep; + u_int32_t xid = rp->rm_xid; + struct ip *ip = (struct ip *)bp; +#ifdef INET6 + struct ip6_hdr *ip6 = (struct ip6_hdr *)bp; +#endif + int cmp; + + /* Start searching from where we last left off */ + i = xid_map_hint; + do { + xmep = &xid_map[i]; + cmp = 1; + if (xmep->ipver != IP_V(ip) || xmep->xid != xid) + goto nextitem; + switch (xmep->ipver) { + case 4: + if (memcmp(&ip->ip_src, &xmep->server, + sizeof(ip->ip_src)) != 0 || + memcmp(&ip->ip_dst, &xmep->client, + sizeof(ip->ip_dst)) != 0) { + cmp = 0; + } + break; +#ifdef INET6 + case 6: + if (memcmp(&ip6->ip6_src, &xmep->server, + sizeof(ip6->ip6_src)) != 0 || + memcmp(&ip6->ip6_dst, &xmep->client, + sizeof(ip6->ip6_dst)) != 0) { + cmp = 0; + } + break; +#endif + default: + cmp = 0; + break; + } + if (cmp) { + /* match */ + xid_map_hint = i; + *proc = xmep->proc; + *vers = xmep->vers; + return 0; + } + nextitem: + if (++i >= XIDMAPSIZE) + i = 0; + } while (i != xid_map_hint); + + /* search failed */ + return (-1); +} + +/* + * Routines for parsing reply packets + */ + +/* + * Return a pointer to the beginning of the actual results. + * If the packet was truncated, return 0. + */ +static const u_int32_t * +parserep(register const struct sunrpc_msg *rp, register u_int length) +{ + register const u_int32_t *dp; + u_int len; + enum sunrpc_accept_stat astat; + + /* + * Portability note: + * Here we find the address of the ar_verf credentials. + * Originally, this calculation was + * dp = (u_int32_t *)&rp->rm_reply.rp_acpt.ar_verf + * On the wire, the rp_acpt field starts immediately after + * the (32 bit) rp_stat field. However, rp_acpt (which is a + * "struct accepted_reply") contains a "struct opaque_auth", + * whose internal representation contains a pointer, so on a + * 64-bit machine the compiler inserts 32 bits of padding + * before rp->rm_reply.rp_acpt.ar_verf. So, we cannot use + * the internal representation to parse the on-the-wire + * representation. Instead, we skip past the rp_stat field, + * which is an "enum" and so occupies one 32-bit word. + */ + dp = ((const u_int32_t *)&rp->rm_reply) + 1; + TCHECK(dp[1]); + len = EXTRACT_32BITS(&dp[1]); + if (len >= length) + return (NULL); + /* + * skip past the ar_verf credentials. + */ + dp += (len + (2*sizeof(u_int32_t) + 3)) / sizeof(u_int32_t); + TCHECK2(dp[0], 0); + + /* + * now we can check the ar_stat field + */ + astat = (enum sunrpc_accept_stat) EXTRACT_32BITS(dp); + switch (astat) { + + case SUNRPC_SUCCESS: + break; + + case SUNRPC_PROG_UNAVAIL: + printf(" PROG_UNAVAIL"); + nfserr = 1; /* suppress trunc string */ + return (NULL); + + case SUNRPC_PROG_MISMATCH: + printf(" PROG_MISMATCH"); + nfserr = 1; /* suppress trunc string */ + return (NULL); + + case SUNRPC_PROC_UNAVAIL: + printf(" PROC_UNAVAIL"); + nfserr = 1; /* suppress trunc string */ + return (NULL); + + case SUNRPC_GARBAGE_ARGS: + printf(" GARBAGE_ARGS"); + nfserr = 1; /* suppress trunc string */ + return (NULL); + + case SUNRPC_SYSTEM_ERR: + printf(" SYSTEM_ERR"); + nfserr = 1; /* suppress trunc string */ + return (NULL); + + default: + printf(" ar_stat %d", astat); + nfserr = 1; /* suppress trunc string */ + return (NULL); + } + /* successful return */ + TCHECK2(*dp, sizeof(astat)); + return ((u_int32_t *) (sizeof(astat) + ((char *)dp))); +trunc: + return (0); +} + +static const u_int32_t * +parsestatus(const u_int32_t *dp, int *er) +{ + int errnum; + + TCHECK(dp[0]); + + errnum = EXTRACT_32BITS(&dp[0]); + if (er) + *er = errnum; + if (errnum != 0) { + if (!qflag) + printf(" ERROR: %s", + tok2str(status2str, "unk %d", errnum)); + nfserr = 1; + } + return (dp + 1); +trunc: + return NULL; +} + +static const u_int32_t * +parsefattr(const u_int32_t *dp, int verbose, int v3) +{ + const struct nfs_fattr *fap; + + fap = (const struct nfs_fattr *)dp; + TCHECK(fap->fa_gid); + if (verbose) { + printf(" %s %o ids %d/%d", + tok2str(type2str, "unk-ft %d ", + EXTRACT_32BITS(&fap->fa_type)), + EXTRACT_32BITS(&fap->fa_mode), + EXTRACT_32BITS(&fap->fa_uid), + EXTRACT_32BITS(&fap->fa_gid)); + if (v3) { + TCHECK(fap->fa3_size); + printf(" sz %" PRIu64, + EXTRACT_64BITS((u_int32_t *)&fap->fa3_size)); + } else { + TCHECK(fap->fa2_size); + printf(" sz %d", EXTRACT_32BITS(&fap->fa2_size)); + } + } + /* print lots more stuff */ + if (verbose > 1) { + if (v3) { + TCHECK(fap->fa3_ctime); + printf(" nlink %d rdev %d/%d", + EXTRACT_32BITS(&fap->fa_nlink), + EXTRACT_32BITS(&fap->fa3_rdev.specdata1), + EXTRACT_32BITS(&fap->fa3_rdev.specdata2)); + printf(" fsid %" PRIx64, + EXTRACT_64BITS((u_int32_t *)&fap->fa3_fsid)); + printf(" fileid %" PRIx64, + EXTRACT_64BITS((u_int32_t *)&fap->fa3_fileid)); + printf(" a/m/ctime %u.%06u", + EXTRACT_32BITS(&fap->fa3_atime.nfsv3_sec), + EXTRACT_32BITS(&fap->fa3_atime.nfsv3_nsec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_sec), + EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_nsec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_sec), + EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_nsec)); + } else { + TCHECK(fap->fa2_ctime); + printf(" nlink %d rdev %x fsid %x nodeid %x a/m/ctime", + EXTRACT_32BITS(&fap->fa_nlink), + EXTRACT_32BITS(&fap->fa2_rdev), + EXTRACT_32BITS(&fap->fa2_fsid), + EXTRACT_32BITS(&fap->fa2_fileid)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa2_atime.nfsv2_sec), + EXTRACT_32BITS(&fap->fa2_atime.nfsv2_usec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_sec), + EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_usec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_sec), + EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_usec)); + } + } + return ((const u_int32_t *)((unsigned char *)dp + + (v3 ? NFSX_V3FATTR : NFSX_V2FATTR))); +trunc: + return (NULL); +} + +static int +parseattrstat(const u_int32_t *dp, int verbose, int v3) +{ + int er; + + dp = parsestatus(dp, &er); + if (dp == NULL) + return (0); + if (er) + return (1); + + return (parsefattr(dp, verbose, v3) != NULL); +} + +static int +parsediropres(const u_int32_t *dp) +{ + int er; + + if (!(dp = parsestatus(dp, &er))) + return (0); + if (er) + return (1); + + dp = parsefh(dp, 0); + if (dp == NULL) + return (0); + + return (parsefattr(dp, vflag, 0) != NULL); +} + +static int +parselinkres(const u_int32_t *dp, int v3) +{ + int er; + + dp = parsestatus(dp, &er); + if (dp == NULL) + return(0); + if (er) + return(1); + if (v3 && !(dp = parse_post_op_attr(dp, vflag))) + return (0); + putchar(' '); + return (parsefn(dp) != NULL); +} + +static int +parsestatfs(const u_int32_t *dp, int v3) +{ + const struct nfs_statfs *sfsp; + int er; + + dp = parsestatus(dp, &er); + if (dp == NULL) + return (0); + if (!v3 && er) + return (1); + + if (qflag) + return(1); + + if (v3) { + if (vflag) + printf(" POST:"); + if (!(dp = parse_post_op_attr(dp, vflag))) + return (0); + } + + TCHECK2(*dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); + + sfsp = (const struct nfs_statfs *)dp; + + if (v3) { + printf(" tbytes %" PRIu64 " fbytes %" PRIu64 " abytes %" PRIu64, + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_tbytes), + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_fbytes), + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_abytes)); + if (vflag) { + printf(" tfiles %" PRIu64 " ffiles %" PRIu64 " afiles %" PRIu64 " invar %u", + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_tfiles), + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_ffiles), + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_afiles), + EXTRACT_32BITS(&sfsp->sf_invarsec)); + } + } else { + printf(" tsize %d bsize %d blocks %d bfree %d bavail %d", + EXTRACT_32BITS(&sfsp->sf_tsize), + EXTRACT_32BITS(&sfsp->sf_bsize), + EXTRACT_32BITS(&sfsp->sf_blocks), + EXTRACT_32BITS(&sfsp->sf_bfree), + EXTRACT_32BITS(&sfsp->sf_bavail)); + } + + return (1); +trunc: + return (0); +} + +static int +parserddires(const u_int32_t *dp) +{ + int er; + + dp = parsestatus(dp, &er); + if (dp == NULL) + return (0); + if (er) + return (1); + if (qflag) + return (1); + + TCHECK(dp[2]); + printf(" offset %x size %d ", + EXTRACT_32BITS(&dp[0]), EXTRACT_32BITS(&dp[1])); + if (dp[2] != 0) + printf(" eof"); + + return (1); +trunc: + return (0); +} + +static const u_int32_t * +parse_wcc_attr(const u_int32_t *dp) +{ + printf(" sz %" PRIu64, EXTRACT_64BITS(&dp[0])); + printf(" mtime %u.%06u ctime %u.%06u", + EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]), + EXTRACT_32BITS(&dp[4]), EXTRACT_32BITS(&dp[5])); + return (dp + 6); +} + +/* + * Pre operation attributes. Print only if vflag > 1. + */ +static const u_int32_t * +parse_pre_op_attr(const u_int32_t *dp, int verbose) +{ + TCHECK(dp[0]); + if (!EXTRACT_32BITS(&dp[0])) + return (dp + 1); + dp++; + TCHECK2(*dp, 24); + if (verbose > 1) { + return parse_wcc_attr(dp); + } else { + /* If not verbose enough, just skip over wcc_attr */ + return (dp + 6); + } +trunc: + return (NULL); +} + +/* + * Post operation attributes are printed if vflag >= 1 + */ +static const u_int32_t * +parse_post_op_attr(const u_int32_t *dp, int verbose) +{ + TCHECK(dp[0]); + if (!EXTRACT_32BITS(&dp[0])) + return (dp + 1); + dp++; + if (verbose) { + return parsefattr(dp, verbose, 1); + } else + return (dp + (NFSX_V3FATTR / sizeof (u_int32_t))); +trunc: + return (NULL); +} + +static const u_int32_t * +parse_wcc_data(const u_int32_t *dp, int verbose) +{ + if (verbose > 1) + printf(" PRE:"); + if (!(dp = parse_pre_op_attr(dp, verbose))) + return (0); + + if (verbose) + printf(" POST:"); + return parse_post_op_attr(dp, verbose); +} + +static const u_int32_t * +parsecreateopres(const u_int32_t *dp, int verbose) +{ + int er; + + if (!(dp = parsestatus(dp, &er))) + return (0); + if (er) + dp = parse_wcc_data(dp, verbose); + else { + TCHECK(dp[0]); + if (!EXTRACT_32BITS(&dp[0])) + return (dp + 1); + dp++; + if (!(dp = parsefh(dp, 1))) + return (0); + if (verbose) { + if (!(dp = parse_post_op_attr(dp, verbose))) + return (0); + if (vflag > 1) { + printf(" dir attr:"); + dp = parse_wcc_data(dp, verbose); + } + } + } + return (dp); +trunc: + return (NULL); +} + +static int +parsewccres(const u_int32_t *dp, int verbose) +{ + int er; + + if (!(dp = parsestatus(dp, &er))) + return (0); + return parse_wcc_data(dp, verbose) != 0; +} + +static const u_int32_t * +parsev3rddirres(const u_int32_t *dp, int verbose) +{ + int er; + + if (!(dp = parsestatus(dp, &er))) + return (0); + if (vflag) + printf(" POST:"); + if (!(dp = parse_post_op_attr(dp, verbose))) + return (0); + if (er) + return dp; + if (vflag) { + TCHECK(dp[1]); + printf(" verf %08x%08x", dp[0], dp[1]); + dp += 2; + } + return dp; +trunc: + return (NULL); +} + +static int +parsefsinfo(const u_int32_t *dp) +{ + struct nfsv3_fsinfo *sfp; + int er; + + if (!(dp = parsestatus(dp, &er))) + return (0); + if (vflag) + printf(" POST:"); + if (!(dp = parse_post_op_attr(dp, vflag))) + return (0); + if (er) + return (1); + + sfp = (struct nfsv3_fsinfo *)dp; + TCHECK(*sfp); + printf(" rtmax %u rtpref %u wtmax %u wtpref %u dtpref %u", + EXTRACT_32BITS(&sfp->fs_rtmax), + EXTRACT_32BITS(&sfp->fs_rtpref), + EXTRACT_32BITS(&sfp->fs_wtmax), + EXTRACT_32BITS(&sfp->fs_wtpref), + EXTRACT_32BITS(&sfp->fs_dtpref)); + if (vflag) { + printf(" rtmult %u wtmult %u maxfsz %" PRIu64, + EXTRACT_32BITS(&sfp->fs_rtmult), + EXTRACT_32BITS(&sfp->fs_wtmult), + EXTRACT_64BITS((u_int32_t *)&sfp->fs_maxfilesize)); + printf(" delta %u.%06u ", + EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_sec), + EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_nsec)); + } + return (1); +trunc: + return (0); +} + +static int +parsepathconf(const u_int32_t *dp) +{ + int er; + struct nfsv3_pathconf *spp; + + if (!(dp = parsestatus(dp, &er))) + return (0); + if (vflag) + printf(" POST:"); + if (!(dp = parse_post_op_attr(dp, vflag))) + return (0); + if (er) + return (1); + + spp = (struct nfsv3_pathconf *)dp; + TCHECK(*spp); + + printf(" linkmax %u namemax %u %s %s %s %s", + EXTRACT_32BITS(&spp->pc_linkmax), + EXTRACT_32BITS(&spp->pc_namemax), + EXTRACT_32BITS(&spp->pc_notrunc) ? "notrunc" : "", + EXTRACT_32BITS(&spp->pc_chownrestricted) ? "chownres" : "", + EXTRACT_32BITS(&spp->pc_caseinsensitive) ? "igncase" : "", + EXTRACT_32BITS(&spp->pc_casepreserving) ? "keepcase" : ""); + return (1); +trunc: + return (0); +} + +static void +interp_reply(const struct sunrpc_msg *rp, u_int32_t proc, u_int32_t vers, int length) +{ + register const u_int32_t *dp; + register int v3; + int er; + + v3 = (vers == NFS_VER3); + + if (!v3 && proc < NFS_NPROCS) + proc = nfsv3_procid[proc]; + + switch (proc) { + + case NFSPROC_NOOP: + printf(" nop"); + return; + + case NFSPROC_NULL: + printf(" null"); + return; + + case NFSPROC_GETATTR: + printf(" getattr"); + dp = parserep(rp, length); + if (dp != NULL && parseattrstat(dp, !qflag, v3) != 0) + return; + break; + + case NFSPROC_SETATTR: + printf(" setattr"); + if (!(dp = parserep(rp, length))) + return; + if (v3) { + if (parsewccres(dp, vflag)) + return; + } else { + if (parseattrstat(dp, !qflag, 0) != 0) + return; + } + break; + + case NFSPROC_LOOKUP: + printf(" lookup"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (!(dp = parsestatus(dp, &er))) + break; + if (er) { + if (vflag > 1) { + printf(" post dattr:"); + dp = parse_post_op_attr(dp, vflag); + } + } else { + if (!(dp = parsefh(dp, v3))) + break; + if ((dp = parse_post_op_attr(dp, vflag)) && + vflag > 1) { + printf(" post dattr:"); + dp = parse_post_op_attr(dp, vflag); + } + } + if (dp) + return; + } else { + if (parsediropres(dp) != 0) + return; + } + break; + + case NFSPROC_ACCESS: + printf(" access"); + if (!(dp = parserep(rp, length))) + break; + if (!(dp = parsestatus(dp, &er))) + break; + if (vflag) + printf(" attr:"); + if (!(dp = parse_post_op_attr(dp, vflag))) + break; + if (!er) + printf(" c %04x", EXTRACT_32BITS(&dp[0])); + return; + + case NFSPROC_READLINK: + printf(" readlink"); + dp = parserep(rp, length); + if (dp != NULL && parselinkres(dp, v3) != 0) + return; + break; + + case NFSPROC_READ: + printf(" read"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (!(dp = parsestatus(dp, &er))) + break; + if (!(dp = parse_post_op_attr(dp, vflag))) + break; + if (er) + return; + if (vflag) { + TCHECK(dp[1]); + printf(" %u bytes", EXTRACT_32BITS(&dp[0])); + if (EXTRACT_32BITS(&dp[1])) + printf(" EOF"); + } + return; + } else { + if (parseattrstat(dp, vflag, 0) != 0) + return; + } + break; + + case NFSPROC_WRITE: + printf(" write"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (!(dp = parsestatus(dp, &er))) + break; + if (!(dp = parse_wcc_data(dp, vflag))) + break; + if (er) + return; + if (vflag) { + TCHECK(dp[0]); + printf(" %u bytes", EXTRACT_32BITS(&dp[0])); + if (vflag > 1) { + TCHECK(dp[1]); + printf(" <%s>", + tok2str(nfsv3_writemodes, + NULL, EXTRACT_32BITS(&dp[1]))); + } + return; + } + } else { + if (parseattrstat(dp, vflag, v3) != 0) + return; + } + break; + + case NFSPROC_CREATE: + printf(" create"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsecreateopres(dp, vflag) != 0) + return; + } else { + if (parsediropres(dp) != 0) + return; + } + break; + + case NFSPROC_MKDIR: + printf(" mkdir"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsecreateopres(dp, vflag) != 0) + return; + } else { + if (parsediropres(dp) != 0) + return; + } + break; + + case NFSPROC_SYMLINK: + printf(" symlink"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsecreateopres(dp, vflag) != 0) + return; + } else { + if (parsestatus(dp, &er) != 0) + return; + } + break; + + case NFSPROC_MKNOD: + printf(" mknod"); + if (!(dp = parserep(rp, length))) + break; + if (parsecreateopres(dp, vflag) != 0) + return; + break; + + case NFSPROC_REMOVE: + printf(" remove"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsewccres(dp, vflag)) + return; + } else { + if (parsestatus(dp, &er) != 0) + return; + } + break; + + case NFSPROC_RMDIR: + printf(" rmdir"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsewccres(dp, vflag)) + return; + } else { + if (parsestatus(dp, &er) != 0) + return; + } + break; + + case NFSPROC_RENAME: + printf(" rename"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (!(dp = parsestatus(dp, &er))) + break; + if (vflag) { + printf(" from:"); + if (!(dp = parse_wcc_data(dp, vflag))) + break; + printf(" to:"); + if (!(dp = parse_wcc_data(dp, vflag))) + break; + } + return; + } else { + if (parsestatus(dp, &er) != 0) + return; + } + break; + + case NFSPROC_LINK: + printf(" link"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (!(dp = parsestatus(dp, &er))) + break; + if (vflag) { + printf(" file POST:"); + if (!(dp = parse_post_op_attr(dp, vflag))) + break; + printf(" dir:"); + if (!(dp = parse_wcc_data(dp, vflag))) + break; + return; + } + } else { + if (parsestatus(dp, &er) != 0) + return; + } + break; + + case NFSPROC_READDIR: + printf(" readdir"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsev3rddirres(dp, vflag)) + return; + } else { + if (parserddires(dp) != 0) + return; + } + break; + + case NFSPROC_READDIRPLUS: + printf(" readdirplus"); + if (!(dp = parserep(rp, length))) + break; + if (parsev3rddirres(dp, vflag)) + return; + break; + + case NFSPROC_FSSTAT: + printf(" fsstat"); + dp = parserep(rp, length); + if (dp != NULL && parsestatfs(dp, v3) != 0) + return; + break; + + case NFSPROC_FSINFO: + printf(" fsinfo"); + dp = parserep(rp, length); + if (dp != NULL && parsefsinfo(dp) != 0) + return; + break; + + case NFSPROC_PATHCONF: + printf(" pathconf"); + dp = parserep(rp, length); + if (dp != NULL && parsepathconf(dp) != 0) + return; + break; + + case NFSPROC_COMMIT: + printf(" commit"); + dp = parserep(rp, length); + if (dp != NULL && parsewccres(dp, vflag) != 0) + return; + break; + + default: + printf(" proc-%u", proc); + return; + } +trunc: + if (!nfserr) + fputs(" [|nfs]", stdout); +} diff --git a/freebsd/contrib/tcpdump/print-ntp.c b/freebsd/contrib/tcpdump/print-ntp.c new file mode 100644 index 00000000..9c37de1d --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ntp.c @@ -0,0 +1,312 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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 ntp packets. + * By Jeffrey Mogul/DECWRL + * loosely based on print-bootp.c + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.43 2007-11-30 13:45:10 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> +#ifdef HAVE_STRFTIME +#include <time.h> +#endif + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#ifdef MODEMASK +#undef MODEMASK /* Solaris sucks */ +#endif +#include "ntp.h" + +static void p_sfix(const struct s_fixedpt *); +static void p_ntp_time(const struct l_fixedpt *); +static void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *); + +static struct tok ntp_mode_values[] = { + { MODE_UNSPEC, "unspecified" }, + { MODE_SYM_ACT, "symmetric active" }, + { MODE_SYM_PAS, "symmetric passive" }, + { MODE_CLIENT, "Client" }, + { MODE_SERVER, "Server" }, + { MODE_BROADCAST, "Broadcast" }, + { MODE_RES1, "Reserved" }, + { MODE_RES2, "Reserved" }, + { 0, NULL } +}; + +static struct tok ntp_leapind_values[] = { + { NO_WARNING, "" }, + { PLUS_SEC, "+1s" }, + { MINUS_SEC, "-1s" }, + { ALARM, "clock unsynchronized" }, + { 0, NULL } +}; + +static struct tok ntp_stratum_values[] = { + { UNSPECIFIED, "unspecified" }, + { PRIM_REF, "primary reference" }, + { 0, NULL } +}; + +/* + * Print ntp requests + */ +void +ntp_print(register const u_char *cp, u_int length) +{ + register const struct ntpdata *bp; + int mode, version, leapind; + + bp = (struct ntpdata *)cp; + + TCHECK(bp->status); + + version = (int)(bp->status & VERSIONMASK) >> 3; + printf("NTPv%d", version); + + mode = bp->status & MODEMASK; + if (!vflag) { + printf (", %s, length %u", + tok2str(ntp_mode_values, "Unknown mode", mode), + length); + return; + } + + printf (", length %u\n\t%s", + length, + tok2str(ntp_mode_values, "Unknown mode", mode)); + + leapind = bp->status & LEAPMASK; + printf (", Leap indicator: %s (%u)", + tok2str(ntp_leapind_values, "Unknown", leapind), + leapind); + + TCHECK(bp->stratum); + printf(", Stratum %u (%s)", + bp->stratum, + tok2str(ntp_stratum_values, (bp->stratum >=2 && bp->stratum<=15) ? "secondary reference" : "reserved", bp->stratum)); + + TCHECK(bp->ppoll); + printf(", poll %u (%us)", bp->ppoll, 1 << bp->ppoll); + + /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */ + TCHECK2(bp->root_delay, 0); + printf(", precision %d", bp->precision); + + TCHECK(bp->root_delay); + fputs("\n\tRoot Delay: ", stdout); + p_sfix(&bp->root_delay); + + TCHECK(bp->root_dispersion); + fputs(", Root dispersion: ", stdout); + p_sfix(&bp->root_dispersion); + + TCHECK(bp->refid); + fputs(", Reference-ID: ", stdout); + /* Interpretation depends on stratum */ + switch (bp->stratum) { + + case UNSPECIFIED: + printf("(unspec)"); + break; + + case PRIM_REF: + if (fn_printn((u_char *)&(bp->refid), 4, snapend)) + goto trunc; + break; + + case INFO_QUERY: + printf("%s INFO_QUERY", ipaddr_string(&(bp->refid))); + /* this doesn't have more content */ + return; + + case INFO_REPLY: + printf("%s INFO_REPLY", ipaddr_string(&(bp->refid))); + /* this is too complex to be worth printing */ + return; + + default: + printf("%s", ipaddr_string(&(bp->refid))); + break; + } + + TCHECK(bp->ref_timestamp); + fputs("\n\t Reference Timestamp: ", stdout); + p_ntp_time(&(bp->ref_timestamp)); + + TCHECK(bp->org_timestamp); + fputs("\n\t Originator Timestamp: ", stdout); + p_ntp_time(&(bp->org_timestamp)); + + TCHECK(bp->rec_timestamp); + fputs("\n\t Receive Timestamp: ", stdout); + p_ntp_time(&(bp->rec_timestamp)); + + TCHECK(bp->xmt_timestamp); + fputs("\n\t Transmit Timestamp: ", stdout); + p_ntp_time(&(bp->xmt_timestamp)); + + fputs("\n\t Originator - Receive Timestamp: ", stdout); + p_ntp_delta(&(bp->org_timestamp), &(bp->rec_timestamp)); + + fputs("\n\t Originator - Transmit Timestamp: ", stdout); + p_ntp_delta(&(bp->org_timestamp), &(bp->xmt_timestamp)); + + if ( (sizeof(struct ntpdata) - length) == 16) { /* Optional: key-id */ + TCHECK(bp->key_id); + printf("\n\tKey id: %u", bp->key_id); + } else if ( (sizeof(struct ntpdata) - length) == 0) { /* Optional: key-id + authentication */ + TCHECK(bp->key_id); + printf("\n\tKey id: %u", bp->key_id); + TCHECK2(bp->message_digest, sizeof (bp->message_digest)); + printf("\n\tAuthentication: %08x%08x%08x%08x", + EXTRACT_32BITS(bp->message_digest), + EXTRACT_32BITS(bp->message_digest + 4), + EXTRACT_32BITS(bp->message_digest + 8), + EXTRACT_32BITS(bp->message_digest + 12)); + } + return; + +trunc: + fputs(" [|ntp]", stdout); +} + +static void +p_sfix(register const struct s_fixedpt *sfp) +{ + register int i; + register int f; + register float ff; + + i = EXTRACT_16BITS(&sfp->int_part); + f = EXTRACT_16BITS(&sfp->fraction); + ff = f / 65536.0; /* shift radix point by 16 bits */ + f = ff * 1000000.0; /* Treat fraction as parts per million */ + printf("%d.%06d", i, f); +} + +#define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */ + +static void +p_ntp_time(register const struct l_fixedpt *lfp) +{ + register int32_t i; + register u_int32_t uf; + register u_int32_t f; + register float ff; + + i = EXTRACT_32BITS(&lfp->int_part); + uf = EXTRACT_32BITS(&lfp->fraction); + ff = uf; + if (ff < 0.0) /* some compilers are buggy */ + ff += FMAXINT; + ff = ff / FMAXINT; /* shift radix point by 32 bits */ + f = ff * 1000000000.0; /* treat fraction as parts per billion */ + printf("%u.%09d", i, f); + +#ifdef HAVE_STRFTIME + /* + * print the time in human-readable format. + */ + if (i) { + time_t seconds = i - JAN_1970; + struct tm *tm; + char time_buf[128]; + + tm = localtime(&seconds); + strftime(time_buf, sizeof (time_buf), "%Y/%m/%d %H:%M:%S", tm); + printf (" (%s)", time_buf); + } +#endif +} + +/* Prints time difference between *lfp and *olfp */ +static void +p_ntp_delta(register const struct l_fixedpt *olfp, + register const struct l_fixedpt *lfp) +{ + register int32_t i; + register u_int32_t u, uf; + register u_int32_t ou, ouf; + register u_int32_t f; + register float ff; + int signbit; + + u = EXTRACT_32BITS(&lfp->int_part); + ou = EXTRACT_32BITS(&olfp->int_part); + uf = EXTRACT_32BITS(&lfp->fraction); + ouf = EXTRACT_32BITS(&olfp->fraction); + if (ou == 0 && ouf == 0) { + p_ntp_time(lfp); + return; + } + + i = u - ou; + + if (i > 0) { /* new is definitely greater than old */ + signbit = 0; + f = uf - ouf; + if (ouf > uf) /* must borrow from high-order bits */ + i -= 1; + } else if (i < 0) { /* new is definitely less than old */ + signbit = 1; + f = ouf - uf; + if (uf > ouf) /* must carry into the high-order bits */ + i += 1; + i = -i; + } else { /* int_part is zero */ + if (uf > ouf) { + signbit = 0; + f = uf - ouf; + } else { + signbit = 1; + f = ouf - uf; + } + } + + ff = f; + if (ff < 0.0) /* some compilers are buggy */ + ff += FMAXINT; + ff = ff / FMAXINT; /* shift radix point by 32 bits */ + f = ff * 1000000000.0; /* treat fraction as parts per billion */ + if (signbit) + putchar('-'); + else + putchar('+'); + printf("%d.%09d", i, f); +} + diff --git a/freebsd/contrib/tcpdump/print-null.c b/freebsd/contrib/tcpdump/print-null.c new file mode 100644 index 00000000..ac727077 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-null.c @@ -0,0 +1,164 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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. + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.57 2006-03-23 14:58:44 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "af.h" + +/* + * The DLT_NULL packet header is 4 bytes long. It contains a host-byte-order + * 32-bit integer that specifies the family, e.g. AF_INET. + * + * Note here that "host" refers to the host on which the packets were + * captured; that isn't necessarily *this* host. + * + * The OpenBSD DLT_LOOP packet header is the same, except that the integer + * is in network byte order. + */ +#define NULL_HDRLEN 4 + +/* + * Byte-swap a 32-bit number. + * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on + * big-endian platforms.) + */ +#define SWAPLONG(y) \ +((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) + +static inline void +null_hdr_print(u_int family, u_int length) +{ + if (!qflag) { + (void)printf("AF %s (%u)", + tok2str(bsd_af_values,"Unknown",family),family); + } else { + (void)printf("%s", + tok2str(bsd_af_values,"Unknown AF %u",family)); + } + + (void)printf(", length %u: ", length); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether 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 +null_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int length = h->len; + u_int caplen = h->caplen; + u_int family; + + if (caplen < NULL_HDRLEN) { + printf("[|null]"); + return (NULL_HDRLEN); + } + + memcpy((char *)&family, (char *)p, sizeof(family)); + + /* + * This isn't necessarily in our host byte order; if this is + * a DLT_LOOP capture, it's in network byte order, and if + * this is a DLT_NULL capture from a machine with the opposite + * byte-order, it's in the opposite byte order from ours. + * + * If the upper 16 bits aren't all zero, assume it's byte-swapped. + */ + if ((family & 0xFFFF0000) != 0) + family = SWAPLONG(family); + + if (eflag) + null_hdr_print(family, length); + + length -= NULL_HDRLEN; + caplen -= NULL_HDRLEN; + p += NULL_HDRLEN; + + switch (family) { + + case BSD_AFNUM_INET: + ip_print(gndo, p, length); + break; + +#ifdef INET6 + case BSD_AFNUM_INET6_BSD: + case BSD_AFNUM_INET6_FREEBSD: + case BSD_AFNUM_INET6_DARWIN: + ip6_print(gndo, p, length); + break; +#endif + + case BSD_AFNUM_ISO: + isoclns_print(p, length, caplen); + break; + + case BSD_AFNUM_APPLETALK: + atalk_print(p, length); + break; + + case BSD_AFNUM_IPX: + ipx_print(p, length); + break; + + default: + /* unknown AF_ value */ + if (!eflag) + null_hdr_print(family, length + NULL_HDRLEN); + if (!suppress_default_print) + default_print(p, caplen); + } + + return (NULL_HDRLEN); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-olsr.c b/freebsd/contrib/tcpdump/print-olsr.c new file mode 100644 index 00000000..962c4d0e --- /dev/null +++ b/freebsd/contrib/tcpdump/print-olsr.c @@ -0,0 +1,628 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1998-2007 The TCPDUMP project + * Copyright (c) 2009 Florian Forster + * + * 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. + * + * Optimized Link State Protocl (OLSR) as per rfc3626 + * + * Original code by Hannes Gredler <hannes@juniper.net> + * IPv6 additions by Florian Forster <octo at verplant.org> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "ip.h" + +/* + * RFC 3626 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Packet Length | Packet Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Type | Vtime | Message Size | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Originator Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Time To Live | Hop Count | Message Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * : MESSAGE : + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Type | Vtime | Message Size | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Originator Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Time To Live | Hop Count | Message Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * : MESSAGE : + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * : : + */ + +struct olsr_common { + u_int8_t packet_len[2]; + u_int8_t packet_seq[2]; +}; + +#define OLSR_HELLO_MSG 1 /* rfc3626 */ +#define OLSR_TC_MSG 2 /* rfc3626 */ +#define OLSR_MID_MSG 3 /* rfc3626 */ +#define OLSR_HNA_MSG 4 /* rfc3626 */ +#define OLSR_POWERINFO_MSG 128 +#define OLSR_NAMESERVICE_MSG 130 +#define OLSR_HELLO_LQ_MSG 201 /* LQ extensions olsr.org */ +#define OLSR_TC_LQ_MSG 202 /* LQ extensions olsr.org */ + +static struct tok olsr_msg_values[] = { + { OLSR_HELLO_MSG, "Hello" }, + { OLSR_TC_MSG, "TC" }, + { OLSR_MID_MSG, "MID" }, + { OLSR_HNA_MSG, "HNA" }, + { OLSR_POWERINFO_MSG, "Powerinfo" }, + { OLSR_NAMESERVICE_MSG, "Nameservice" }, + { OLSR_HELLO_LQ_MSG, "Hello-LQ" }, + { OLSR_TC_LQ_MSG, "TC-LQ" }, + { 0, NULL} +}; + +struct olsr_msg4 { + u_int8_t msg_type; + u_int8_t vtime; + u_int8_t msg_len[2]; + u_int8_t originator[4]; + u_int8_t ttl; + u_int8_t hopcount; + u_int8_t msg_seq[2]; +}; + +struct olsr_msg6 { + u_int8_t msg_type; + u_int8_t vtime; + u_int8_t msg_len[2]; + u_int8_t originator[16]; + u_int8_t ttl; + u_int8_t hopcount; + u_int8_t msg_seq[2]; +}; + +struct olsr_hello { + u_int8_t res[2]; + u_int8_t htime; + u_int8_t will; +}; + +struct olsr_hello_link { + u_int8_t link_code; + u_int8_t res; + u_int8_t len[2]; +}; + +struct olsr_tc { + u_int8_t ans_seq[2]; + u_int8_t res[2]; +}; + +struct olsr_hna4 { + u_int8_t network[4]; + u_int8_t mask[4]; +}; + +struct olsr_hna6 { + u_int8_t network[16]; + u_int8_t mask[16]; +}; + + +#define OLSR_EXTRACT_LINK_TYPE(link_code) (link_code & 0x3) +#define OLSR_EXTRACT_NEIGHBOR_TYPE(link_code) (link_code >> 2) + +static struct tok olsr_link_type_values[] = { + { 0, "Unspecified" }, + { 1, "Asymmetric" }, + { 2, "Symmetric" }, + { 3, "Lost" }, + { 0, NULL} +}; + +static struct tok olsr_neighbor_type_values[] = { + { 0, "Not-Neighbor" }, + { 1, "Symmetric" }, + { 2, "Symmetric-MPR" }, + { 0, NULL} +}; + +struct olsr_lq_neighbor4 { + u_int8_t neighbor[4]; + u_int8_t link_quality; + u_int8_t neighbor_link_quality; + u_int8_t res[2]; +}; + +struct olsr_lq_neighbor6 { + u_int8_t neighbor[16]; + u_int8_t link_quality; + u_int8_t neighbor_link_quality; + u_int8_t res[2]; +}; + +/* + * macro to convert the 8-bit mantissa/exponent to a double float + * taken from olsr.org. + */ +#define VTIME_SCALE_FACTOR 0.0625 +#define ME_TO_DOUBLE(me) \ + (double)(VTIME_SCALE_FACTOR*(1+(double)(me>>4)/16)*(double)(1<<(me&0x0F))) + +/* + * print a neighbor list with LQ extensions. + */ +static void +olsr_print_lq_neighbor4 (const u_char *msg_data, u_int hello_len) +{ + struct olsr_lq_neighbor4 *lq_neighbor; + + while (hello_len >= sizeof(struct olsr_lq_neighbor4)) { + + lq_neighbor = (struct olsr_lq_neighbor4 *)msg_data; + + printf("\n\t neighbor %s, link-quality %.2lf%%" + ", neighbor-link-quality %.2lf%%", + ipaddr_string(lq_neighbor->neighbor), + ((double)lq_neighbor->link_quality/2.55), + ((double)lq_neighbor->neighbor_link_quality/2.55)); + + msg_data += sizeof(struct olsr_lq_neighbor4); + hello_len -= sizeof(struct olsr_lq_neighbor4); + } +} + +#if INET6 +static void +olsr_print_lq_neighbor6 (const u_char *msg_data, u_int hello_len) +{ + struct olsr_lq_neighbor6 *lq_neighbor; + + while (hello_len >= sizeof(struct olsr_lq_neighbor6)) { + + lq_neighbor = (struct olsr_lq_neighbor6 *)msg_data; + + printf("\n\t neighbor %s, link-quality %.2lf%%" + ", neighbor-link-quality %.2lf%%", + ip6addr_string(lq_neighbor->neighbor), + ((double)lq_neighbor->link_quality/2.55), + ((double)lq_neighbor->neighbor_link_quality/2.55)); + + msg_data += sizeof(struct olsr_lq_neighbor6); + hello_len -= sizeof(struct olsr_lq_neighbor6); + } +} +#endif /* INET6 */ + +/* + * print a neighbor list. + */ +static void +olsr_print_neighbor (const u_char *msg_data, u_int hello_len) +{ + int neighbor; + + printf("\n\t neighbor\n\t\t"); + neighbor = 1; + + while (hello_len >= sizeof(struct in_addr)) { + + /* print 4 neighbors per line */ + + printf("%s%s", ipaddr_string(msg_data), + neighbor % 4 == 0 ? "\n\t\t" : " "); + + msg_data += sizeof(struct in_addr); + hello_len -= sizeof(struct in_addr); + } +} + + +void +olsr_print (const u_char *pptr, u_int length, int is_ipv6) +{ + union { + const struct olsr_common *common; + const struct olsr_msg4 *msg4; + const struct olsr_msg6 *msg6; + const struct olsr_hello *hello; + const struct olsr_hello_link *hello_link; + const struct olsr_tc *tc; + const struct olsr_hna4 *hna; + } ptr; + + u_int msg_type, msg_len, msg_tlen, hello_len; + u_int16_t name_entry_type, name_entry_len; + u_int name_entry_padding; + u_int8_t link_type, neighbor_type; + const u_char *tptr, *msg_data; + + tptr = pptr; + + if (length < sizeof(struct olsr_common)) { + goto trunc; + } + + if (!TTEST2(*tptr, sizeof(struct olsr_common))) { + goto trunc; + } + + ptr.common = (struct olsr_common *)tptr; + length = MIN(length, EXTRACT_16BITS(ptr.common->packet_len)); + + printf("OLSRv%i, seq 0x%04x, length %u", + (is_ipv6 == 0) ? 4 : 6, + EXTRACT_16BITS(ptr.common->packet_seq), + length); + + tptr += sizeof(struct olsr_common); + + /* + * In non-verbose mode, just print version. + */ + if (vflag < 1) { + return; + } + + while (tptr < (pptr+length)) { + union + { + struct olsr_msg4 *v4; + struct olsr_msg6 *v6; + } msgptr; + int msg_len_valid = 0; + + if (!TTEST2(*tptr, sizeof(struct olsr_msg4))) + goto trunc; + +#if INET6 + if (is_ipv6) + { + msgptr.v6 = (struct olsr_msg6 *) tptr; + msg_type = msgptr.v6->msg_type; + msg_len = EXTRACT_16BITS(msgptr.v6->msg_len); + if ((msg_len >= sizeof (struct olsr_msg6)) + && (msg_len <= length)) + msg_len_valid = 1; + + /* infinite loop check */ + if (msg_type == 0 || msg_len == 0) { + return; + } + + printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" + "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u%s", + tok2str(olsr_msg_values, "Unknown", msg_type), + msg_type, ip6addr_string(msgptr.v6->originator), + msgptr.v6->ttl, + msgptr.v6->hopcount, + ME_TO_DOUBLE(msgptr.v6->vtime), + EXTRACT_16BITS(msgptr.v6->msg_seq), + msg_len, (msg_len_valid == 0) ? " (invalid)" : ""); + + msg_tlen = msg_len - sizeof(struct olsr_msg6); + msg_data = tptr + sizeof(struct olsr_msg6); + } + else /* (!is_ipv6) */ +#endif /* INET6 */ + { + msgptr.v4 = (struct olsr_msg4 *) tptr; + msg_type = msgptr.v4->msg_type; + msg_len = EXTRACT_16BITS(msgptr.v4->msg_len); + if ((msg_len >= sizeof (struct olsr_msg4)) + && (msg_len <= length)) + msg_len_valid = 1; + + /* infinite loop check */ + if (msg_type == 0 || msg_len == 0) { + return; + } + + printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" + "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u%s", + tok2str(olsr_msg_values, "Unknown", msg_type), + msg_type, ipaddr_string(msgptr.v4->originator), + msgptr.v4->ttl, + msgptr.v4->hopcount, + ME_TO_DOUBLE(msgptr.v4->vtime), + EXTRACT_16BITS(msgptr.v4->msg_seq), + msg_len, (msg_len_valid == 0) ? " (invalid)" : ""); + + msg_tlen = msg_len - sizeof(struct olsr_msg4); + msg_data = tptr + sizeof(struct olsr_msg4); + } + + switch (msg_type) { + case OLSR_HELLO_MSG: + case OLSR_HELLO_LQ_MSG: + if (!TTEST2(*msg_data, sizeof(struct olsr_hello))) + goto trunc; + + ptr.hello = (struct olsr_hello *)msg_data; + printf("\n\t hello-time %.3lfs, MPR willingness %u", + ME_TO_DOUBLE(ptr.hello->htime), ptr.hello->will); + msg_data += sizeof(struct olsr_hello); + msg_tlen -= sizeof(struct olsr_hello); + + while (msg_tlen >= sizeof(struct olsr_hello_link)) { + int hello_len_valid = 0; + + /* + * link-type. + */ + if (!TTEST2(*msg_data, sizeof(struct olsr_hello_link))) + goto trunc; + + ptr.hello_link = (struct olsr_hello_link *)msg_data; + + hello_len = EXTRACT_16BITS(ptr.hello_link->len); + link_type = OLSR_EXTRACT_LINK_TYPE(ptr.hello_link->link_code); + neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(ptr.hello_link->link_code); + + if ((hello_len <= msg_tlen) + && (hello_len >= sizeof(struct olsr_hello_link))) + hello_len_valid = 1; + + printf("\n\t link-type %s, neighbor-type %s, len %u%s", + tok2str(olsr_link_type_values, "Unknown", link_type), + tok2str(olsr_neighbor_type_values, "Unknown", neighbor_type), + hello_len, + (hello_len_valid == 0) ? " (invalid)" : ""); + + if (hello_len_valid == 0) + break; + + msg_data += sizeof(struct olsr_hello_link); + msg_tlen -= sizeof(struct olsr_hello_link); + hello_len -= sizeof(struct olsr_hello_link); + + if (msg_type == OLSR_HELLO_MSG) { + olsr_print_neighbor(msg_data, hello_len); + } else { +#if INET6 + if (is_ipv6) + olsr_print_lq_neighbor6(msg_data, hello_len); + else +#endif + olsr_print_lq_neighbor4(msg_data, hello_len); + } + + msg_data += hello_len; + msg_tlen -= hello_len; + } + break; + + case OLSR_TC_MSG: + case OLSR_TC_LQ_MSG: + if (!TTEST2(*msg_data, sizeof(struct olsr_tc))) + goto trunc; + + ptr.tc = (struct olsr_tc *)msg_data; + printf("\n\t advertised neighbor seq 0x%04x", + EXTRACT_16BITS(ptr.tc->ans_seq)); + msg_data += sizeof(struct olsr_tc); + msg_tlen -= sizeof(struct olsr_tc); + + if (msg_type == OLSR_TC_MSG) { + olsr_print_neighbor(msg_data, msg_tlen); + } else { +#if INET6 + if (is_ipv6) + olsr_print_lq_neighbor6(msg_data, msg_tlen); + else +#endif + olsr_print_lq_neighbor4(msg_data, msg_tlen); + } + break; + + case OLSR_MID_MSG: + { + size_t addr_size = sizeof(struct in_addr); + +#if INET6 + if (is_ipv6) + addr_size = sizeof(struct in6_addr); +#endif + + while (msg_tlen >= addr_size) { + if (!TTEST2(*msg_data, addr_size)) + goto trunc; + + printf("\n\t interface address %s", +#if INET6 + is_ipv6 ? ip6addr_string(msg_data) : +#endif + ipaddr_string(msg_data)); + msg_data += addr_size; + msg_tlen -= addr_size; + } + break; + } + + case OLSR_HNA_MSG: + printf("\n\t Advertised networks (total %u)", + (unsigned int) (msg_tlen / sizeof(struct olsr_hna6))); +#if INET6 + if (is_ipv6) + { + int i = 0; + while (msg_tlen >= sizeof(struct olsr_hna6)) { + struct olsr_hna6 *hna6; + + if (!TTEST2(*msg_data, sizeof(struct olsr_hna6))) + goto trunc; + + hna6 = (struct olsr_hna6 *)msg_data; + + printf("\n\t #%i: %s/%u", + i, ip6addr_string(hna6->network), + mask62plen (hna6->mask)); + + msg_data += sizeof(struct olsr_hna6); + msg_tlen -= sizeof(struct olsr_hna6); + } + } + else +#endif + { + int col = 0; + while (msg_tlen >= sizeof(struct olsr_hna4)) { + if (!TTEST2(*msg_data, sizeof(struct olsr_hna4))) + goto trunc; + + ptr.hna = (struct olsr_hna4 *)msg_data; + + /* print 4 prefixes per line */ + if (col == 0) + printf ("\n\t "); + else + printf (", "); + + printf("%s/%u", + ipaddr_string(ptr.hna->network), + mask2plen(EXTRACT_32BITS(ptr.hna->mask))); + + msg_data += sizeof(struct olsr_hna4); + msg_tlen -= sizeof(struct olsr_hna4); + + col = (col + 1) % 4; + } + } + break; + + case OLSR_NAMESERVICE_MSG: + { + u_int name_entries = EXTRACT_16BITS(msg_data+2); + u_int addr_size = 4; + int name_entries_valid = 0; + u_int i; + + if (is_ipv6) + addr_size = 16; + + if ((name_entries > 0) + && ((name_entries * (4 + addr_size)) <= msg_tlen)) + name_entries_valid = 1; + + if (msg_tlen < 4) + goto trunc; + if (!TTEST2(*msg_data, 4)) + goto trunc; + + printf("\n\t Version %u, Entries %u%s", + EXTRACT_16BITS(msg_data), + name_entries, (name_entries_valid == 0) ? " (invalid)" : ""); + + if (name_entries_valid == 0) + break; + + msg_data += 4; + msg_tlen -= 4; + + for (i = 0; i < name_entries; i++) { + int name_entry_len_valid = 0; + + if (msg_tlen < 4) + break; + if (!TTEST2(*msg_data, 4)) + goto trunc; + + name_entry_type = EXTRACT_16BITS(msg_data); + name_entry_len = EXTRACT_16BITS(msg_data+2); + + msg_data += 4; + msg_tlen -= 4; + + if ((name_entry_len > 0) && ((addr_size + name_entry_len) <= msg_tlen)) + name_entry_len_valid = 1; + + printf("\n\t #%u: type %#06x, length %u%s", + (unsigned int) i, name_entry_type, + name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : ""); + + if (name_entry_len_valid == 0) + break; + + /* 32-bit alignment */ + name_entry_padding = 0; + if (name_entry_len%4 != 0) + name_entry_padding = 4-(name_entry_len%4); + + if (msg_tlen < addr_size + name_entry_len + name_entry_padding) + goto trunc; + + if (!TTEST2(*msg_data, addr_size + name_entry_len + name_entry_padding)) + goto trunc; + +#if INET6 + if (is_ipv6) + printf(", address %s, name \"", + ip6addr_string(msg_data)); + else +#endif + printf(", address %s, name \"", + ipaddr_string(msg_data)); + fn_printn(msg_data + addr_size, name_entry_len, NULL); + printf("\""); + + msg_data += addr_size + name_entry_len + name_entry_padding; + msg_tlen -= addr_size + name_entry_len + name_entry_padding; + } /* for (i = 0; i < name_entries; i++) */ + break; + } /* case OLSR_NAMESERVICE_MSG */ + + /* + * FIXME those are the defined messages that lack a decoder + * you are welcome to contribute code ;-) + */ + case OLSR_POWERINFO_MSG: + default: + print_unknown_data(msg_data, "\n\t ", msg_tlen); + break; + } /* switch (msg_type) */ + tptr += msg_len; + } /* while (tptr < (pptr+length)) */ + + return; + + trunc: + printf("[|olsr]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-ospf.c b/freebsd/contrib/tcpdump/print-ospf.c new file mode 100644 index 00000000..769a29f0 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ospf.c @@ -0,0 +1,1159 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "gmpls.h" + +#include "ospf.h" + +#include "ip.h" + +static 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 struct tok ospf_authtype_values[] = { + { OSPF_AUTH_NONE, "none" }, + { OSPF_AUTH_SIMPLE, "simple" }, + { OSPF_AUTH_MD5, "MD5" }, + { 0, NULL } +}; + +static 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 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 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 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 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 struct tok lsa_opaque_te_tlv_values[] = { + { LS_OPAQUE_TE_TLV_ROUTER, "Router Address" }, + { LS_OPAQUE_TE_TLV_LINK, "Link" }, + { 0, NULL } +}; + +static 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 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 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 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 struct tok lsa_opaque_ri_tlv_values[] = { + { LS_OPAQUE_RI_TLV_CAP, "Router Capabilities" }, + { 0, NULL } +}; + +static 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 struct tok ospf_lls_tlv_values[] = { + { OSPF_LLS_EO, "Extended Options" }, + { OSPF_LLS_MD5, "MD5 Authentication" }, + { 0, NULL } +}; + +static struct tok ospf_lls_eo_options[] = { + { OSPF_LLS_EO_LR, "LSDB resync" }, + { OSPF_LLS_EO_RS, "Restart" }, + { 0, NULL } +}; + +static char tstr[] = " [|ospf2]"; + +#ifdef WIN32 +#define inline __inline +#endif /* WIN32 */ + +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 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); +} diff --git a/freebsd/contrib/tcpdump/print-ospf6.c b/freebsd/contrib/tcpdump/print-ospf6.c new file mode 100644 index 00000000..419cf705 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ospf6.c @@ -0,0 +1,646 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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-ospf6.c,v 1.15 2006-09-13 06:31:11 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ospf.h" +#include "ospf6.h" + +static const struct tok ospf6_option_values[] = { + { OSPF6_OPTION_V6, "V6" }, + { OSPF6_OPTION_E, "External" }, + { OSPF6_OPTION_MC, "Multicast" }, + { OSPF6_OPTION_N, "NSSA" }, + { OSPF6_OPTION_R, "Router" }, + { OSPF6_OPTION_DC, "Demand Circuit" }, + { 0, NULL } +}; + +static const struct tok ospf6_rla_flag_values[] = { + { RLA_FLAG_B, "ABR" }, + { RLA_FLAG_E, "External" }, + { RLA_FLAG_V, "Virtual-Link Endpoint" }, + { RLA_FLAG_W, "Wildcard Receiver" }, + { RLA_FLAG_N, "NSSA Translator" }, + { 0, NULL } +}; + +static const struct tok ospf6_asla_flag_values[] = { + { ASLA_FLAG_EXTERNAL, "External Type 2" }, + { ASLA_FLAG_FWDADDR, "Fforwarding" }, + { ASLA_FLAG_ROUTETAG, "Tag" }, + { 0, NULL } +}; + +static struct tok ospf6_type_values[] = { + { 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 struct tok ospf6_lsa_values[] = { + { LS_TYPE_ROUTER, "Router" }, + { LS_TYPE_NETWORK, "Network" }, + { LS_TYPE_INTER_AP, "Inter-Area Prefix" }, + { LS_TYPE_INTER_AR, "Inter-Area Router" }, + { LS_TYPE_ASE, "External" }, + { LS_TYPE_GROUP, "Multicast Group" }, + { LS_TYPE_NSSA, "NSSA" }, + { LS_TYPE_LINK, "Link" }, + { LS_TYPE_INTRA_AP, "Intra-Area Prefix" }, + { LS_TYPE_INTRA_ATE, "Intra-Area TE" }, + { LS_TYPE_GRACE, "Grace" }, + { 0, NULL } +}; + +static struct tok ospf6_ls_scope_values[] = { + { LS_SCOPE_LINKLOCAL, "Link Local" }, + { LS_SCOPE_AREA, "Area Local" }, + { LS_SCOPE_AS, "Domain Wide" }, + { 0, NULL } +}; + +static struct tok ospf6_dd_flag_values[] = { + { OSPF6_DB_INIT, "Init" }, + { OSPF6_DB_MORE, "More" }, + { OSPF6_DB_MASTER, "Master" }, + { 0, NULL } +}; + +static struct tok ospf6_lsa_prefix_option_values[] = { + { LSA_PREFIX_OPT_NU, "No Unicast" }, + { LSA_PREFIX_OPT_LA, "Local address" }, + { LSA_PREFIX_OPT_MC, "Multicast" }, + { LSA_PREFIX_OPT_P, "Propagate" }, + { LSA_PREFIX_OPT_DN, "Down" }, + { 0, NULL } +}; + +static char tstr[] = " [|ospf3]"; + +#ifdef WIN32 +#define inline __inline +#endif /* WIN32 */ + +/* Forwards */ +static void ospf6_print_ls_type(u_int, const rtrid_t *); +static int ospf6_print_lshdr(const struct lsa6_hdr *); +static int ospf6_print_lsa(const struct lsa6 *); +static int ospf6_decode_v3(const struct ospf6hdr *, const u_char *); + + +static void +ospf6_print_ls_type(register u_int ls_type, register const rtrid_t *ls_stateid) +{ + printf("\n\t %s LSA (%d), %s Scope%s, LSA-ID %s", + tok2str(ospf6_lsa_values, "Unknown", ls_type & LS_TYPE_MASK), + ls_type & LS_TYPE_MASK, + tok2str(ospf6_ls_scope_values, "Unknown", ls_type & LS_SCOPE_MASK), + ls_type &0x8000 ? ", transitive" : "", /* U-bit */ + ipaddr_string(ls_stateid)); +} + +static int +ospf6_print_lshdr(register const struct lsa6_hdr *lshp) +{ + + TCHECK(lshp->ls_type); + TCHECK(lshp->ls_seq); + + 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), + EXTRACT_16BITS(&lshp->ls_length)-(u_int)sizeof(struct lsa6_hdr)); + + ospf6_print_ls_type(EXTRACT_16BITS(&lshp->ls_type), &lshp->ls_stateid); + + return (0); +trunc: + return (1); +} + +static int +ospf6_print_lsaprefix(const u_int8_t *tptr, u_int lsa_length) +{ + const struct lsa6_prefix *lsapp = (struct lsa6_prefix *)tptr; + u_int wordlen; + struct in6_addr prefix; + + if (lsa_length < sizeof (*lsapp) - 4) + goto trunc; + lsa_length -= sizeof (*lsapp) - 4; + TCHECK2(*lsapp, sizeof (*lsapp) - 4); + wordlen = (lsapp->lsa_p_len + 31) / 32; + if (wordlen * 4 > sizeof(struct in6_addr)) { + printf(" bogus prefixlen /%d", lsapp->lsa_p_len); + goto trunc; + } + if (lsa_length < wordlen * 4) + goto trunc; + lsa_length -= wordlen * 4; + TCHECK2(lsapp->lsa_p_prefix, wordlen * 4); + memset(&prefix, 0, sizeof(prefix)); + memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4); + printf("\n\t\t%s/%d", ip6addr_string(&prefix), + lsapp->lsa_p_len); + if (lsapp->lsa_p_opt) { + printf(", Options [%s]", + bittok2str(ospf6_lsa_prefix_option_values, + "none", lsapp->lsa_p_opt)); + } + printf(", metric %u", EXTRACT_16BITS(&lsapp->lsa_p_metric)); + return sizeof(*lsapp) - 4 + wordlen * 4; + +trunc: + return -1; +} + + +/* + * Print a single link state advertisement. If truncated return 1, else 0. + */ +static int +ospf6_print_lsa(register const struct lsa6 *lsap) +{ + register const struct rlalink6 *rlp; +#if 0 + register const struct tos_metric *tosp; +#endif + register const rtrid_t *ap; +#if 0 + register const struct aslametric *almp; + register const struct mcla *mcp; +#endif + register const struct llsa *llsap; + register const struct lsa6_prefix *lsapp; +#if 0 + register const u_int32_t *lp; +#endif + register u_int prefixes; + register int bytelen; + register u_int length, lsa_length; + u_int32_t flags32; + const u_int8_t *tptr; + + if (ospf6_print_lshdr(&lsap->ls_hdr)) + return (1); + TCHECK(lsap->ls_hdr.ls_length); + length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length); + + /* + * The LSA length includes the length of the header; + * it must have a value that's at least that length. + * If it does, find the length of what follows the + * header. + */ + if (length < sizeof(struct lsa6_hdr)) + return (1); + lsa_length = length - sizeof(struct lsa6_hdr); + tptr = (u_int8_t *)lsap+sizeof(struct lsa6_hdr); + + switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) { + case LS_TYPE_ROUTER | LS_SCOPE_AREA: + if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options); + TCHECK(lsap->lsa_un.un_rla.rla_options); + printf("\n\t Options [%s]", + bittok2str(ospf6_option_values, "none", + EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options))); + printf(", RLA-Flags [%s]", + bittok2str(ospf6_rla_flag_values, "none", + lsap->lsa_un.un_rla.rla_flags)); + + rlp = lsap->lsa_un.un_rla.rla_link; + while (lsa_length != 0) { + if (lsa_length < sizeof (*rlp)) + return (1); + lsa_length -= sizeof (*rlp); + TCHECK(*rlp); + switch (rlp->link_type) { + + case RLA_TYPE_VIRTUAL: + printf("\n\t Virtual Link: Neighbor Router-ID %s" + "\n\t Neighbor Interface-ID %s, Interface %s", + ipaddr_string(&rlp->link_nrtid), + ipaddr_string(&rlp->link_nifid), + ipaddr_string(&rlp->link_ifid)); + break; + + case RLA_TYPE_ROUTER: + printf("\n\t Neighbor Router-ID %s" + "\n\t Neighbor Interface-ID %s, Interface %s", + ipaddr_string(&rlp->link_nrtid), + ipaddr_string(&rlp->link_nifid), + ipaddr_string(&rlp->link_ifid)); + break; + + case RLA_TYPE_TRANSIT: + printf("\n\t Neighbor Network-ID %s" + "\n\t Neighbor Interface-ID %s, Interface %s", + ipaddr_string(&rlp->link_nrtid), + ipaddr_string(&rlp->link_nifid), + ipaddr_string(&rlp->link_ifid)); + break; + + default: + printf("\n\t Unknown Router Links Type 0x%02x", + rlp->link_type); + return (0); + } + printf(", metric %d", EXTRACT_16BITS(&rlp->link_metric)); + rlp++; + } + break; + + case LS_TYPE_NETWORK | LS_SCOPE_AREA: + if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options); + TCHECK(lsap->lsa_un.un_nla.nla_options); + printf("\n\t Options [%s]", + bittok2str(ospf6_option_values, "none", + EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options))); + + printf("\n\t Connected Routers:"); + ap = lsap->lsa_un.un_nla.nla_router; + while (lsa_length != 0) { + if (lsa_length < sizeof (*ap)) + return (1); + lsa_length -= sizeof (*ap); + TCHECK(*ap); + printf("\n\t\t%s", ipaddr_string(ap)); + ++ap; + } + break; + + case LS_TYPE_INTER_AP | LS_SCOPE_AREA: + if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric); + TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric); + printf(", metric %u", + EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC); + + tptr = (u_int8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix; + while (lsa_length != 0) { + bytelen = ospf6_print_lsaprefix(tptr, lsa_length); + if (bytelen < 0) + goto trunc; + lsa_length -= bytelen; + tptr += bytelen; + } + break; + + case LS_TYPE_ASE | LS_SCOPE_AS: + if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric); + TCHECK(lsap->lsa_un.un_asla.asla_metric); + flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric); + printf("\n\t Flags [%s]", + bittok2str(ospf6_asla_flag_values, "none", flags32)); + printf(" metric %u", + EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) & + ASLA_MASK_METRIC); + + tptr = (u_int8_t *)lsap->lsa_un.un_asla.asla_prefix; + lsapp = (struct lsa6_prefix *)tptr; + bytelen = ospf6_print_lsaprefix(tptr, lsa_length); + if (bytelen < 0) + goto trunc; + lsa_length -= bytelen; + tptr += bytelen; + + if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { + struct in6_addr *fwdaddr6; + + fwdaddr6 = (struct in6_addr *)tptr; + if (lsa_length < sizeof (*fwdaddr6)) + return (1); + lsa_length -= sizeof (*fwdaddr6); + TCHECK(*fwdaddr6); + printf(" forward %s", + ip6addr_string(fwdaddr6)); + tptr += sizeof(*fwdaddr6); + } + + if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) { + if (lsa_length < sizeof (u_int32_t)) + return (1); + lsa_length -= sizeof (u_int32_t); + TCHECK(*(u_int32_t *)tptr); + printf(" tag %s", + ipaddr_string((u_int32_t *)tptr)); + tptr += sizeof(u_int32_t); + } + + if (lsapp->lsa_p_metric) { + if (lsa_length < sizeof (u_int32_t)) + return (1); + lsa_length -= sizeof (u_int32_t); + TCHECK(*(u_int32_t *)tptr); + printf(" RefLSID: %s", + ipaddr_string((u_int32_t *)tptr)); + tptr += sizeof(u_int32_t); + } + break; + + case LS_TYPE_LINK: + /* Link LSA */ + llsap = &lsap->lsa_un.un_llsa; + if (lsa_length < sizeof (llsap->llsa_priandopt)) + return (1); + lsa_length -= sizeof (llsap->llsa_priandopt); + TCHECK(llsap->llsa_priandopt); + printf("\n\t Options [%s]", + bittok2str(ospf6_option_values, "none", + EXTRACT_32BITS(&llsap->llsa_options))); + + if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix)) + return (1); + lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix); + prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix); + printf("\n\t Priority %d, Link-local address %s, Prefixes %d:", + llsap->llsa_priority, + ip6addr_string(&llsap->llsa_lladdr), + prefixes); + + tptr = (u_int8_t *)llsap->llsa_prefix; + while (prefixes > 0) { + bytelen = ospf6_print_lsaprefix(tptr, lsa_length); + if (bytelen < 0) + goto trunc; + prefixes--; + lsa_length -= bytelen; + tptr += bytelen; + } + break; + + case LS_TYPE_INTRA_AP | LS_SCOPE_AREA: + /* Intra-Area-Prefix LSA */ + if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid); + TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid); + ospf6_print_ls_type( + EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype), + &lsap->lsa_un.un_intra_ap.intra_ap_lsid); + + if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix)) + return (1); + lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix); + TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); + prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix); + printf("\n\t Prefixes %d:", prefixes); + + tptr = (u_int8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; + while (prefixes > 0) { + bytelen = ospf6_print_lsaprefix(tptr, lsa_length); + if (bytelen < 0) + goto trunc; + prefixes--; + lsa_length -= bytelen; + tptr += bytelen; + } + break; + + case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL: + if (ospf_print_grace_lsa(tptr, lsa_length) == -1) { + return 1; + } + break; + + case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL: + if (ospf_print_te_lsa(tptr, lsa_length) == -1) { + return 1; + } + break; + + default: + if(!print_unknown_data(tptr, + "\n\t ", + lsa_length)) { + return (1); + } + break; + } + + return (0); +trunc: + return (1); +} + +static int +ospf6_decode_v3(register const struct ospf6hdr *op, + register const u_char *dataend) +{ + register const rtrid_t *ap; + register const struct lsr6 *lsrp; + register const struct lsa6_hdr *lshp; + register const struct lsa6 *lsap; + register int i; + + switch (op->ospf6_type) { + + case OSPF_TYPE_HELLO: + printf("\n\tOptions [%s]", + bittok2str(ospf6_option_values, "none", + EXTRACT_32BITS(&op->ospf6_hello.hello_options))); + + TCHECK(op->ospf6_hello.hello_deadint); + printf("\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u", + EXTRACT_16BITS(&op->ospf6_hello.hello_helloint), + EXTRACT_16BITS(&op->ospf6_hello.hello_deadint), + ipaddr_string(&op->ospf6_hello.hello_ifid), + op->ospf6_hello.hello_priority); + + TCHECK(op->ospf6_hello.hello_dr); + if (op->ospf6_hello.hello_dr != 0) + printf("\n\t Designated Router %s", + ipaddr_string(&op->ospf6_hello.hello_dr)); + TCHECK(op->ospf6_hello.hello_bdr); + if (op->ospf6_hello.hello_bdr != 0) + printf(", Backup Designated Router %s", + ipaddr_string(&op->ospf6_hello.hello_bdr)); + if (vflag) { + printf("\n\t Neighbor List:"); + ap = op->ospf6_hello.hello_neighbor; + while ((u_char *)ap < dataend) { + TCHECK(*ap); + printf("\n\t %s", ipaddr_string(ap)); + ++ap; + } + } + break; /* HELLO */ + + case OSPF_TYPE_DD: + TCHECK(op->ospf6_db.db_options); + printf("\n\tOptions [%s]", + bittok2str(ospf6_option_values, "none", + EXTRACT_32BITS(&op->ospf6_db.db_options))); + TCHECK(op->ospf6_db.db_flags); + printf(", DD Flags [%s]", + bittok2str(ospf6_dd_flag_values,"none",op->ospf6_db.db_flags)); + + TCHECK(op->ospf6_db.db_seq); + printf(", MTU %u, DD-Sequence 0x%08x", + EXTRACT_16BITS(&op->ospf6_db.db_mtu), + EXTRACT_32BITS(&op->ospf6_db.db_seq)); + + /* Print all the LS adv's */ + lshp = op->ospf6_db.db_lshdr; + while (!ospf6_print_lshdr(lshp)) { + ++lshp; + } + break; + + case OSPF_TYPE_LS_REQ: + if (vflag) { + lsrp = op->ospf6_lsr; + while ((u_char *)lsrp < dataend) { + TCHECK(*lsrp); + printf("\n\t Advertising Router %s", + ipaddr_string(&lsrp->ls_router)); + ospf6_print_ls_type(EXTRACT_16BITS(&lsrp->ls_type), + &lsrp->ls_stateid); + ++lsrp; + } + } + break; + + case OSPF_TYPE_LS_UPDATE: + if (vflag) { + lsap = op->ospf6_lsu.lsu_lsa; + TCHECK(op->ospf6_lsu.lsu_count); + i = EXTRACT_32BITS(&op->ospf6_lsu.lsu_count); + while (i--) { + if (ospf6_print_lsa(lsap)) + goto trunc; + lsap = (struct lsa6 *)((u_char *)lsap + + EXTRACT_16BITS(&lsap->ls_hdr.ls_length)); + } + } + break; + + + case OSPF_TYPE_LS_ACK: + if (vflag) { + lshp = op->ospf6_lsa.lsa_lshdr; + + while (!ospf6_print_lshdr(lshp)) { + ++lshp; + } + } + break; + + default: + break; + } + return (0); +trunc: + return (1); +} + +void +ospf6_print(register const u_char *bp, register u_int length) +{ + register const struct ospf6hdr *op; + register const u_char *dataend; + register const char *cp; + + op = (struct ospf6hdr *)bp; + + /* If the type is valid translate it, or just print the type */ + /* value. If it's not valid, say so and return */ + TCHECK(op->ospf6_type); + cp = tok2str(ospf6_type_values, "unknown LS-type", op->ospf6_type); + printf("OSPFv%u, %s, length %d", op->ospf6_version, cp, length); + if (*cp == 'u') { + return; + } + + if(!vflag) { /* non verbose - so lets bail out here */ + return; + } + + TCHECK(op->ospf6_len); + if (length != EXTRACT_16BITS(&op->ospf6_len)) { + printf(" [len %d]", EXTRACT_16BITS(&op->ospf6_len)); + return; + } + dataend = bp + length; + + /* Print the routerid if it is not the same as the source */ + TCHECK(op->ospf6_routerid); + printf("\n\tRouter-ID %s", ipaddr_string(&op->ospf6_routerid)); + + TCHECK(op->ospf6_areaid); + if (op->ospf6_areaid != 0) + printf(", Area %s", ipaddr_string(&op->ospf6_areaid)); + else + printf(", Backbone Area"); + TCHECK(op->ospf6_instanceid); + if (op->ospf6_instanceid) + printf(", Instance %u", op->ospf6_instanceid); + + /* Do rest according to version. */ + switch (op->ospf6_version) { + + case 3: + /* ospf version 3 */ + if (ospf6_decode_v3(op, dataend)) + goto trunc; + break; + + default: + printf(" ospf [version %d]", op->ospf6_version); + break; + } /* end switch on version */ + + return; +trunc: + fputs(tstr, stdout); +} diff --git a/freebsd/contrib/tcpdump/print-otv.c b/freebsd/contrib/tcpdump/print-otv.c new file mode 100644 index 00000000..12da24c8 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-otv.c @@ -0,0 +1,81 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> + +#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; +} diff --git a/freebsd/contrib/tcpdump/print-pflog.c b/freebsd/contrib/tcpdump/print-pflog.c new file mode 100644 index 00000000..5f67fb0e --- /dev/null +++ b/freebsd/contrib/tcpdump/print-pflog.c @@ -0,0 +1,190 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <rtems/bsd/sys/types.h> +#include <sys/socket.h> +#include <net/if.h> +#include <net/pfvar.h> +#include <net/if_pflog.h> + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> + +#include "extract.h" +#include "interface.h" +#include "addrtoname.h" + +static 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 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 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: + */ diff --git a/freebsd/contrib/tcpdump/print-pfsync.c b/freebsd/contrib/tcpdump/print-pfsync.c new file mode 100644 index 00000000..fc71f732 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-pfsync.c @@ -0,0 +1,453 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org> + * Copyright (c) 2002 Michael Shalayeff + * Copyright (c) 2001 Daniel Hartmeier + * 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 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 OR HIS RELATIVES 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 MIND, 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. + * + * $OpenBSD: print-pfsync.c,v 1.38 2012/09/19 13:50:36 mikeb Exp $ + * $OpenBSD: pf_print_state.c,v 1.11 2012/07/08 17:48:37 lteo Exp $ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <sys/endian.h> +#include <net/if.h> +#define TCPSTATES +#include <net/pfvar.h> /* XXX */ +#include <net/if_pfsync.h> +#include <netinet/ip.h> +#include <netinet/tcp_fsm.h> + +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" + +static void pfsync_print(struct pfsync_header *, const u_char *, u_int); +static void print_src_dst(const struct pfsync_state_peer *, + const struct pfsync_state_peer *, uint8_t); +static void print_state(struct pfsync_state *); + +#ifdef notyet +void +pfsync_if_print(u_char *user, const struct pcap_pkthdr *h, + register const u_char *p) +{ + u_int caplen = h->caplen; + + ts_print(&h->ts); + + if (caplen < PFSYNC_HDRLEN) { + printf("[|pfsync]"); + goto out; + } + + pfsync_print((struct pfsync_header *)p, + p + sizeof(struct pfsync_header), + caplen - sizeof(struct pfsync_header)); +out: + if (xflag) { + default_print((const u_char *)p, caplen); + } + putchar('\n'); +} +#endif /* notyet */ + +void +pfsync_ip_print(const u_char *bp, u_int len) +{ + struct pfsync_header *hdr = (struct pfsync_header *)bp; + + if (len < PFSYNC_HDRLEN) + printf("[|pfsync]"); + else + pfsync_print(hdr, bp + sizeof(struct pfsync_header), + len - sizeof(struct pfsync_header)); +} + +struct pfsync_actions { + const char *name; + size_t len; + void (*print)(const void *); +}; + +static void pfsync_print_clr(const void *); +static void pfsync_print_state(const void *); +static void pfsync_print_ins_ack(const void *); +static void pfsync_print_upd_c(const void *); +static void pfsync_print_upd_req(const void *); +static void pfsync_print_del_c(const void *); +static void pfsync_print_bus(const void *); +static void pfsync_print_tdb(const void *); + +struct pfsync_actions actions[] = { + { "clear all", sizeof(struct pfsync_clr), pfsync_print_clr }, + { "insert", sizeof(struct pfsync_state), pfsync_print_state }, + { "insert ack", sizeof(struct pfsync_ins_ack), pfsync_print_ins_ack }, + { "update", sizeof(struct pfsync_ins_ack), pfsync_print_state }, + { "update compressed", sizeof(struct pfsync_upd_c), + pfsync_print_upd_c }, + { "request uncompressed", sizeof(struct pfsync_upd_req), + pfsync_print_upd_req }, + { "delete", sizeof(struct pfsync_state), pfsync_print_state }, + { "delete compressed", sizeof(struct pfsync_del_c), + pfsync_print_del_c }, + { "frag insert", 0, NULL }, + { "frag delete", 0, NULL }, + { "bulk update status", sizeof(struct pfsync_bus), + pfsync_print_bus }, + { "tdb", 0, pfsync_print_tdb }, + { "eof", 0, NULL }, +}; + +static void +pfsync_print(struct pfsync_header *hdr, const u_char *bp, u_int len) +{ + struct pfsync_subheader *subh; + int count, plen, i; + u_int alen; + + plen = ntohs(hdr->len); + + printf("PFSYNCv%d len %d", hdr->version, plen); + + if (hdr->version != PFSYNC_VERSION) + return; + + plen -= sizeof(*hdr); + + while (plen > 0) { + if (len < sizeof(*subh)) + break; + + subh = (struct pfsync_subheader *)bp; + bp += sizeof(*subh); + len -= sizeof(*subh); + plen -= sizeof(*subh); + + if (subh->action >= PFSYNC_ACT_MAX) { + printf("\n act UNKNOWN id %d", subh->action); + return; + } + + count = ntohs(subh->count); + printf("\n %s count %d", actions[subh->action].name, count); + alen = actions[subh->action].len; + + if (subh->action == PFSYNC_ACT_EOF) + return; + + if (actions[subh->action].print == NULL) { + printf("\n unimplemented action %hhu", subh->action); + return; + } + + for (i = 0; i < count; i++) { + if (len < alen) { + len = 0; + break; + } + + if (vflag) + actions[subh->action].print(bp); + + bp += alen; + len -= alen; + plen -= alen; + } + } + + if (plen > 0) { + printf("\n ..."); + return; + } + if (plen < 0) { + printf("\n invalid header length"); + return; + } + if (len > 0) + printf("\n invalid packet length"); +} + +static void +pfsync_print_clr(const void *bp) +{ + const struct pfsync_clr *clr = bp; + + printf("\n\tcreatorid: %08x", htonl(clr->creatorid)); + if (clr->ifname[0] != '\0') + printf(" interface: %s", clr->ifname); +} + +static void +pfsync_print_state(const void *bp) +{ + struct pfsync_state *st = (struct pfsync_state *)bp; + + putchar('\n'); + print_state(st); +} + +static void +pfsync_print_ins_ack(const void *bp) +{ + const struct pfsync_ins_ack *iack = bp; + + printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(iack->id), + ntohl(iack->creatorid)); +} + +static void +pfsync_print_upd_c(const void *bp) +{ + const struct pfsync_upd_c *u = bp; + + printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(u->id), + ntohl(u->creatorid)); + if (vflag > 2) { + printf("\n\tTCP? :"); + print_src_dst(&u->src, &u->dst, IPPROTO_TCP); + } +} + +static void +pfsync_print_upd_req(const void *bp) +{ + const struct pfsync_upd_req *ur = bp; + + printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(ur->id), + ntohl(ur->creatorid)); +} + +static void +pfsync_print_del_c(const void *bp) +{ + const struct pfsync_del_c *d = bp; + + printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(d->id), + ntohl(d->creatorid)); +} + +static void +pfsync_print_bus(const void *bp) +{ + const struct pfsync_bus *b = bp; + uint32_t endtime; + int min, sec; + const char *status; + + endtime = ntohl(b->endtime); + sec = endtime % 60; + endtime /= 60; + min = endtime % 60; + endtime /= 60; + + switch (b->status) { + case PFSYNC_BUS_START: + status = "start"; + break; + case PFSYNC_BUS_END: + status = "end"; + break; + default: + status = "UNKNOWN"; + break; + } + + printf("\n\tcreatorid: %08x age: %.2u:%.2u:%.2u status: %s", + htonl(b->creatorid), endtime, min, sec, status); +} + +static void +pfsync_print_tdb(const void *bp) +{ + const struct pfsync_tdb *t = bp; + + printf("\n\tspi: 0x%08x rpl: %ju cur_bytes: %ju", + ntohl(t->spi), (uintmax_t )be64toh(t->rpl), + (uintmax_t )be64toh(t->cur_bytes)); +} + +static void +print_host(struct pf_addr *addr, uint16_t port, sa_family_t af, + const char *proto) +{ + char buf[48]; + + if (inet_ntop(af, addr, buf, sizeof(buf)) == NULL) + printf("?"); + else + printf("%s", buf); + + if (port) + printf(".%hu", ntohs(port)); +} + +static void +print_seq(const struct pfsync_state_peer *p) +{ + if (p->seqdiff) + printf("[%u + %u](+%u)", ntohl(p->seqlo), + ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff)); + else + printf("[%u + %u]", ntohl(p->seqlo), + ntohl(p->seqhi) - ntohl(p->seqlo)); +} + +static void +print_src_dst(const struct pfsync_state_peer *src, + const struct pfsync_state_peer *dst, uint8_t proto) +{ + + if (proto == IPPROTO_TCP) { + if (src->state <= TCPS_TIME_WAIT && + dst->state <= TCPS_TIME_WAIT) + printf(" %s:%s", tcpstates[src->state], + tcpstates[dst->state]); + else if (src->state == PF_TCPS_PROXY_SRC || + dst->state == PF_TCPS_PROXY_SRC) + printf(" PROXY:SRC"); + else if (src->state == PF_TCPS_PROXY_DST || + dst->state == PF_TCPS_PROXY_DST) + printf(" PROXY:DST"); + else + printf(" <BAD STATE LEVELS %u:%u>", + src->state, dst->state); + if (vflag > 1) { + printf("\n\t"); + print_seq(src); + if (src->wscale && dst->wscale) + printf(" wscale %u", + src->wscale & PF_WSCALE_MASK); + printf(" "); + print_seq(dst); + if (src->wscale && dst->wscale) + printf(" wscale %u", + dst->wscale & PF_WSCALE_MASK); + } + } else if (proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES && + dst->state < PFUDPS_NSTATES) { + const char *states[] = PFUDPS_NAMES; + + printf(" %s:%s", states[src->state], states[dst->state]); + } else if (proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES && + dst->state < PFOTHERS_NSTATES) { + /* XXX ICMP doesn't really have state levels */ + const char *states[] = PFOTHERS_NAMES; + + printf(" %s:%s", states[src->state], states[dst->state]); + } else { + printf(" %u:%u", src->state, dst->state); + } +} + +static void +print_state(struct pfsync_state *s) +{ + struct pfsync_state_peer *src, *dst; + struct pfsync_state_key *sk, *nk; + int min, sec; + + if (s->direction == PF_OUT) { + src = &s->src; + dst = &s->dst; + sk = &s->key[PF_SK_STACK]; + nk = &s->key[PF_SK_WIRE]; + if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6) + sk->port[0] = nk->port[0]; + } else { + src = &s->dst; + dst = &s->src; + sk = &s->key[PF_SK_WIRE]; + nk = &s->key[PF_SK_STACK]; + if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6) + sk->port[1] = nk->port[1]; + } + printf("\t%s ", s->ifname); + printf("proto %u ", s->proto); + + print_host(&nk->addr[1], nk->port[1], s->af, NULL); + if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) || + nk->port[1] != sk->port[1]) { + printf(" ("); + print_host(&sk->addr[1], sk->port[1], s->af, NULL); + printf(")"); + } + if (s->direction == PF_OUT) + printf(" -> "); + else + printf(" <- "); + print_host(&nk->addr[0], nk->port[0], s->af, NULL); + if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) || + nk->port[0] != sk->port[0]) { + printf(" ("); + print_host(&sk->addr[0], sk->port[0], s->af, NULL); + printf(")"); + } + + print_src_dst(src, dst, s->proto); + + if (vflag > 1) { + uint64_t packets[2]; + uint64_t bytes[2]; + uint32_t creation = ntohl(s->creation); + uint32_t expire = ntohl(s->expire); + + sec = creation % 60; + creation /= 60; + min = creation % 60; + creation /= 60; + printf("\n\tage %.2u:%.2u:%.2u", creation, min, sec); + sec = expire % 60; + expire /= 60; + min = expire % 60; + expire /= 60; + printf(", expires in %.2u:%.2u:%.2u", expire, min, sec); + + bcopy(s->packets[0], &packets[0], sizeof(uint64_t)); + bcopy(s->packets[1], &packets[1], sizeof(uint64_t)); + bcopy(s->bytes[0], &bytes[0], sizeof(uint64_t)); + bcopy(s->bytes[1], &bytes[1], sizeof(uint64_t)); + printf(", %ju:%ju pkts, %ju:%ju bytes", + be64toh(packets[0]), be64toh(packets[1]), + be64toh(bytes[0]), be64toh(bytes[1])); + if (s->anchor != ntohl(-1)) + printf(", anchor %u", ntohl(s->anchor)); + if (s->rule != ntohl(-1)) + printf(", rule %u", ntohl(s->rule)); + } + if (vflag > 1) { + uint64_t id; + + bcopy(&s->id, &id, sizeof(uint64_t)); + printf("\n\tid: %016jx creatorid: %08x", + (uintmax_t )be64toh(id), ntohl(s->creatorid)); + } +} diff --git a/freebsd/contrib/tcpdump/print-pgm.c b/freebsd/contrib/tcpdump/print-pgm.c new file mode 100644 index 00000000..065cffc8 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-pgm.c @@ -0,0 +1,849 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 Andy Heffernan (ahh@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-pgm.c,v 1.5 2005-06-07 22:05:58 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "ipproto.h" + +/* + * PGM header (RFC 3208) + */ +struct pgm_header { + u_int16_t pgm_sport; + u_int16_t pgm_dport; + u_int8_t pgm_type; + u_int8_t pgm_options; + u_int16_t pgm_sum; + u_int8_t pgm_gsid[6]; + u_int16_t pgm_length; +}; + +struct pgm_spm { + u_int32_t pgms_seq; + u_int32_t pgms_trailseq; + u_int32_t pgms_leadseq; + u_int16_t pgms_nla_afi; + u_int16_t pgms_reserved; + /* ... u_int8_t pgms_nla[0]; */ + /* ... options */ +}; + +struct pgm_nak { + u_int32_t pgmn_seq; + u_int16_t pgmn_source_afi; + u_int16_t pgmn_reserved; + /* ... u_int8_t pgmn_source[0]; */ + /* ... u_int16_t pgmn_group_afi */ + /* ... u_int16_t pgmn_reserved2; */ + /* ... u_int8_t pgmn_group[0]; */ + /* ... options */ +}; + +struct pgm_ack { + u_int32_t pgma_rx_max_seq; + u_int32_t pgma_bitmap; + /* ... options */ +}; + +struct pgm_poll { + u_int32_t pgmp_seq; + u_int16_t pgmp_round; + u_int16_t pgmp_reserved; + /* ... options */ +}; + +struct pgm_polr { + u_int32_t pgmp_seq; + u_int16_t pgmp_round; + u_int16_t pgmp_subtype; + u_int16_t pgmp_nla_afi; + u_int16_t pgmp_reserved; + /* ... u_int8_t pgmp_nla[0]; */ + /* ... options */ +}; + +struct pgm_data { + u_int32_t pgmd_seq; + u_int32_t pgmd_trailseq; + /* ... options */ +}; + +typedef enum _pgm_type { + PGM_SPM = 0, /* source path message */ + PGM_POLL = 1, /* POLL Request */ + PGM_POLR = 2, /* POLL Response */ + PGM_ODATA = 4, /* original data */ + PGM_RDATA = 5, /* repair data */ + PGM_NAK = 8, /* NAK */ + PGM_NULLNAK = 9, /* Null NAK */ + PGM_NCF = 10, /* NAK Confirmation */ + PGM_ACK = 11, /* ACK for congestion control */ + PGM_SPMR = 12, /* SPM request */ + PGM_MAX = 255 +} pgm_type; + +#define PGM_OPT_BIT_PRESENT 0x01 +#define PGM_OPT_BIT_NETWORK 0x02 +#define PGM_OPT_BIT_VAR_PKTLEN 0x40 +#define PGM_OPT_BIT_PARITY 0x80 + +#define PGM_OPT_LENGTH 0x00 +#define PGM_OPT_FRAGMENT 0x01 +#define PGM_OPT_NAK_LIST 0x02 +#define PGM_OPT_JOIN 0x03 +#define PGM_OPT_NAK_BO_IVL 0x04 +#define PGM_OPT_NAK_BO_RNG 0x05 + +#define PGM_OPT_REDIRECT 0x07 +#define PGM_OPT_PARITY_PRM 0x08 +#define PGM_OPT_PARITY_GRP 0x09 +#define PGM_OPT_CURR_TGSIZE 0x0A +#define PGM_OPT_NBR_UNREACH 0x0B +#define PGM_OPT_PATH_NLA 0x0C + +#define PGM_OPT_SYN 0x0D +#define PGM_OPT_FIN 0x0E +#define PGM_OPT_RST 0x0F +#define PGM_OPT_CR 0x10 +#define PGM_OPT_CRQST 0x11 + +#define PGM_OPT_PGMCC_DATA 0x12 +#define PGM_OPT_PGMCC_FEEDBACK 0x13 + +#define PGM_OPT_MASK 0x7f + +#define PGM_OPT_END 0x80 /* end of options marker */ + +#define PGM_MIN_OPT_LEN 4 + +#ifndef AFI_IP +#define AFI_IP 1 +#define AFI_IP6 2 +#endif + +void +pgm_print(register const u_char *bp, register u_int length, + register const u_char *bp2) +{ + register const struct pgm_header *pgm; + register const struct ip *ip; + register char ch; + u_int16_t sport, dport; + int addr_size; + const void *nla; + int nla_af; +#ifdef INET6 + char nla_buf[INET6_ADDRSTRLEN]; + register const struct ip6_hdr *ip6; +#else + char nla_buf[INET_ADDRSTRLEN]; +#endif + u_int8_t opt_type, opt_len, flags1, flags2; + u_int32_t seq, opts_len, len, offset; + + pgm = (struct pgm_header *)bp; + ip = (struct ip *)bp2; +#ifdef INET6 + if (IP_V(ip) == 6) + ip6 = (struct ip6_hdr *)bp2; + else + ip6 = NULL; +#else /* INET6 */ + if (IP_V(ip) == 6) { + (void)printf("Can't handle IPv6"); + return; + } +#endif /* INET6 */ + ch = '\0'; + if (!TTEST(pgm->pgm_dport)) { +#ifdef INET6 + if (ip6) { + (void)printf("%s > %s: [|pgm]", + ip6addr_string(&ip6->ip6_src), + ip6addr_string(&ip6->ip6_dst)); + return; + } else +#endif /* INET6 */ + { + (void)printf("%s > %s: [|pgm]", + ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst)); + return; + } + } + + sport = EXTRACT_16BITS(&pgm->pgm_sport); + dport = EXTRACT_16BITS(&pgm->pgm_dport); + +#ifdef INET6 + if (ip6) { + if (ip6->ip6_nxt == IPPROTO_PGM) { + (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_PGM) { + (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)); + } + } + + TCHECK(*pgm); + + (void)printf("PGM, length %u", pgm->pgm_length); + + if (!vflag) + return; + + if (length > pgm->pgm_length) + length = pgm->pgm_length; + + (void)printf(" 0x%02x%02x%02x%02x%02x%02x ", + pgm->pgm_gsid[0], + pgm->pgm_gsid[1], + pgm->pgm_gsid[2], + pgm->pgm_gsid[3], + pgm->pgm_gsid[4], + pgm->pgm_gsid[5]); + switch (pgm->pgm_type) { + case PGM_SPM: { + struct pgm_spm *spm; + + spm = (struct pgm_spm *)(pgm + 1); + TCHECK(*spm); + + switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + nla_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + nla_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp = (u_char *) (spm + 1); + TCHECK2(*bp, addr_size); + nla = bp; + bp += addr_size; + + inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); + (void)printf("SPM seq %u trail %u lead %u nla %s", + EXTRACT_32BITS(&spm->pgms_seq), + EXTRACT_32BITS(&spm->pgms_trailseq), + EXTRACT_32BITS(&spm->pgms_leadseq), + nla_buf); + break; + } + + case PGM_POLL: { + struct pgm_poll *poll; + + poll = (struct pgm_poll *)(pgm + 1); + TCHECK(*poll); + (void)printf("POLL seq %u round %u", + EXTRACT_32BITS(&poll->pgmp_seq), + EXTRACT_16BITS(&poll->pgmp_round)); + bp = (u_char *) (poll + 1); + break; + } + case PGM_POLR: { + struct pgm_polr *polr; + u_int32_t ivl, rnd, mask; + + polr = (struct pgm_polr *)(pgm + 1); + TCHECK(*polr); + + switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + nla_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + nla_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp = (u_char *) (polr + 1); + TCHECK2(*bp, addr_size); + nla = bp; + bp += addr_size; + + inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); + + TCHECK2(*bp, sizeof(u_int32_t)); + ivl = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + + TCHECK2(*bp, sizeof(u_int32_t)); + rnd = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + + TCHECK2(*bp, sizeof(u_int32_t)); + mask = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + + (void)printf("POLR seq %u round %u nla %s ivl %u rnd 0x%08x " + "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq), + EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask); + break; + } + case PGM_ODATA: { + struct pgm_data *odata; + + odata = (struct pgm_data *)(pgm + 1); + TCHECK(*odata); + (void)printf("ODATA trail %u seq %u", + EXTRACT_32BITS(&odata->pgmd_trailseq), + EXTRACT_32BITS(&odata->pgmd_seq)); + bp = (u_char *) (odata + 1); + break; + } + + case PGM_RDATA: { + struct pgm_data *rdata; + + rdata = (struct pgm_data *)(pgm + 1); + TCHECK(*rdata); + (void)printf("RDATA trail %u seq %u", + EXTRACT_32BITS(&rdata->pgmd_trailseq), + EXTRACT_32BITS(&rdata->pgmd_seq)); + bp = (u_char *) (rdata + 1); + break; + } + + case PGM_NAK: + case PGM_NULLNAK: + case PGM_NCF: { + struct pgm_nak *nak; + const void *source, *group; + int source_af, group_af; +#ifdef INET6 + char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN]; +#else + char source_buf[INET_ADDRSTRLEN], group_buf[INET_ADDRSTRLEN]; +#endif + + nak = (struct pgm_nak *)(pgm + 1); + TCHECK(*nak); + + /* + * Skip past the source, saving info along the way + * and stopping if we don't have enough. + */ + switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + source_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + source_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp = (u_char *) (nak + 1); + TCHECK2(*bp, addr_size); + source = bp; + bp += addr_size; + + /* + * Skip past the group, saving info along the way + * and stopping if we don't have enough. + */ + switch (EXTRACT_16BITS(bp)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + group_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + group_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp += (2 * sizeof(u_int16_t)); + TCHECK2(*bp, addr_size); + group = bp; + bp += addr_size; + + /* + * Options decoding can go here. + */ + inet_ntop(source_af, source, source_buf, sizeof(source_buf)); + inet_ntop(group_af, group, group_buf, sizeof(group_buf)); + switch (pgm->pgm_type) { + case PGM_NAK: + (void)printf("NAK "); + break; + case PGM_NULLNAK: + (void)printf("NNAK "); + break; + case PGM_NCF: + (void)printf("NCF "); + break; + default: + break; + } + (void)printf("(%s -> %s), seq %u", + source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq)); + break; + } + + case PGM_ACK: { + struct pgm_ack *ack; + + ack = (struct pgm_ack *)(pgm + 1); + TCHECK(*ack); + (void)printf("ACK seq %u", + EXTRACT_32BITS(&ack->pgma_rx_max_seq)); + bp = (u_char *) (ack + 1); + break; + } + + case PGM_SPMR: + (void)printf("SPMR"); + break; + + default: + (void)printf("UNKNOWN type %0x02x", pgm->pgm_type); + break; + + } + if (pgm->pgm_options & PGM_OPT_BIT_PRESENT) { + + /* + * make sure there's enough for the first option header + */ + if (!TTEST2(*bp, PGM_MIN_OPT_LEN)) { + (void)printf("[|OPT]"); + return; + } + + /* + * That option header MUST be an OPT_LENGTH option + * (see the first paragraph of section 9.1 in RFC 3208). + */ + opt_type = *bp++; + if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) { + (void)printf("[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK); + return; + } + opt_len = *bp++; + if (opt_len != 4) { + (void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len); + return; + } + opts_len = EXTRACT_16BITS(bp); + if (opts_len < 4) { + (void)printf("[Bad total option length %u < 4]", opts_len); + return; + } + bp += sizeof(u_int16_t); + (void)printf(" OPTS LEN %d", opts_len); + opts_len -= 4; + + while (opts_len) { + if (opts_len < PGM_MIN_OPT_LEN) { + (void)printf("[Total option length leaves no room for final option]"); + return; + } + opt_type = *bp++; + opt_len = *bp++; + if (opt_len < PGM_MIN_OPT_LEN) { + (void)printf("[Bad option, length %u < %u]", opt_len, + PGM_MIN_OPT_LEN); + break; + } + if (opts_len < opt_len) { + (void)printf("[Total option length leaves no room for final option]"); + return; + } + if (!TTEST2(*bp, opt_len - 2)) { + (void)printf(" [|OPT]"); + return; + } + + switch (opt_type & PGM_OPT_MASK) { + case PGM_OPT_LENGTH: + if (opt_len != 4) { + (void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len); + return; + } + (void)printf(" OPTS LEN (extra?) %d", EXTRACT_16BITS(bp)); + bp += sizeof(u_int16_t); + opts_len -= 4; + break; + + case PGM_OPT_FRAGMENT: + if (opt_len != 16) { + (void)printf("[Bad OPT_FRAGMENT option, length %u != 16]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + seq = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + offset = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + len = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" FRAG seq %u off %u len %u", seq, offset, len); + opts_len -= 16; + break; + + case PGM_OPT_NAK_LIST: + flags1 = *bp++; + flags2 = *bp++; + opt_len -= sizeof(u_int32_t); /* option header */ + (void)printf(" NAK LIST"); + while (opt_len) { + if (opt_len < sizeof(u_int32_t)) { + (void)printf("[Option length not a multiple of 4]"); + return; + } + TCHECK2(*bp, sizeof(u_int32_t)); + (void)printf(" %u", EXTRACT_32BITS(bp)); + bp += sizeof(u_int32_t); + opt_len -= sizeof(u_int32_t); + opts_len -= sizeof(u_int32_t); + } + break; + + case PGM_OPT_JOIN: + if (opt_len != 8) { + (void)printf("[Bad OPT_JOIN option, length %u != 8]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + seq = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" JOIN %u", seq); + opts_len -= 8; + break; + + case PGM_OPT_NAK_BO_IVL: + if (opt_len != 12) { + (void)printf("[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + offset = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + seq = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" BACKOFF ivl %u ivlseq %u", offset, seq); + opts_len -= 12; + break; + + case PGM_OPT_NAK_BO_RNG: + if (opt_len != 12) { + (void)printf("[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + offset = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + seq = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" BACKOFF max %u min %u", offset, seq); + opts_len -= 12; + break; + + case PGM_OPT_REDIRECT: + flags1 = *bp++; + flags2 = *bp++; + switch (EXTRACT_16BITS(bp)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + nla_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + nla_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp += (2 * sizeof(u_int16_t)); + if (opt_len != 4 + addr_size) { + (void)printf("[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len); + return; + } + TCHECK2(*bp, addr_size); + nla = bp; + bp += addr_size; + + inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); + (void)printf(" REDIRECT %s", (char *)nla); + opts_len -= 4 + addr_size; + break; + + case PGM_OPT_PARITY_PRM: + if (opt_len != 8) { + (void)printf("[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + len = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" PARITY MAXTGS %u", len); + opts_len -= 8; + break; + + case PGM_OPT_PARITY_GRP: + if (opt_len != 8) { + (void)printf("[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + seq = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" PARITY GROUP %u", seq); + opts_len -= 8; + break; + + case PGM_OPT_CURR_TGSIZE: + if (opt_len != 8) { + (void)printf("[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + len = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" PARITY ATGS %u", len); + opts_len -= 8; + break; + + case PGM_OPT_NBR_UNREACH: + if (opt_len != 4) { + (void)printf("[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + (void)printf(" NBR_UNREACH"); + opts_len -= 4; + break; + + case PGM_OPT_PATH_NLA: + (void)printf(" PATH_NLA [%d]", opt_len); + bp += opt_len; + opts_len -= opt_len; + break; + + case PGM_OPT_SYN: + if (opt_len != 4) { + (void)printf("[Bad OPT_SYN option, length %u != 4]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + (void)printf(" SYN"); + opts_len -= 4; + break; + + case PGM_OPT_FIN: + if (opt_len != 4) { + (void)printf("[Bad OPT_FIN option, length %u != 4]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + (void)printf(" FIN"); + opts_len -= 4; + break; + + case PGM_OPT_RST: + if (opt_len != 4) { + (void)printf("[Bad OPT_RST option, length %u != 4]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + (void)printf(" RST"); + opts_len -= 4; + break; + + case PGM_OPT_CR: + (void)printf(" CR"); + bp += opt_len; + opts_len -= opt_len; + break; + + case PGM_OPT_CRQST: + if (opt_len != 4) { + (void)printf("[Bad OPT_CRQST option, length %u != 4]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + (void)printf(" CRQST"); + opts_len -= 4; + break; + + case PGM_OPT_PGMCC_DATA: + flags1 = *bp++; + flags2 = *bp++; + offset = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + switch (EXTRACT_16BITS(bp)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + nla_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + nla_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp += (2 * sizeof(u_int16_t)); + if (opt_len != 12 + addr_size) { + (void)printf("[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len); + return; + } + TCHECK2(*bp, addr_size); + nla = bp; + bp += addr_size; + + inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); + (void)printf(" PGMCC DATA %u %s", offset, (char*)nla); + opts_len -= 16; + break; + + case PGM_OPT_PGMCC_FEEDBACK: + flags1 = *bp++; + flags2 = *bp++; + offset = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + switch (EXTRACT_16BITS(bp)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + nla_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + nla_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp += (2 * sizeof(u_int16_t)); + if (opt_len != 12 + addr_size) { + (void)printf("[Bad OPT_PGMCC_FEEDBACK option, length %u != 12 + address size]", opt_len); + return; + } + TCHECK2(*bp, addr_size); + nla = bp; + bp += addr_size; + + inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); + (void)printf(" PGMCC FEEDBACK %u %s", offset, (char*)nla); + opts_len -= 16; + break; + + default: + (void)printf(" OPT_%02X [%d] ", opt_type, opt_len); + bp += opt_len; + opts_len -= opt_len; + break; + } + + if (opt_type & PGM_OPT_END) + break; + } + } + + (void)printf(" [%u]", EXTRACT_16BITS(&pgm->pgm_length)); + + return; + +trunc: + fputs("[|pgm]", stdout); + if (ch != '\0') + putchar('>'); +} diff --git a/freebsd/contrib/tcpdump/print-pim.c b/freebsd/contrib/tcpdump/print-pim.c new file mode 100644 index 00000000..32a549c6 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-pim.c @@ -0,0 +1,1097 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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. + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.49 2006-02-13 01:31:35 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip.h" + +#define PIMV2_TYPE_HELLO 0 +#define PIMV2_TYPE_REGISTER 1 +#define PIMV2_TYPE_REGISTER_STOP 2 +#define PIMV2_TYPE_JOIN_PRUNE 3 +#define PIMV2_TYPE_BOOTSTRAP 4 +#define PIMV2_TYPE_ASSERT 5 +#define PIMV2_TYPE_GRAFT 6 +#define PIMV2_TYPE_GRAFT_ACK 7 +#define PIMV2_TYPE_CANDIDATE_RP 8 +#define PIMV2_TYPE_PRUNE_REFRESH 9 + +static struct tok pimv2_type_values[] = { + { PIMV2_TYPE_HELLO, "Hello" }, + { PIMV2_TYPE_REGISTER, "Register" }, + { PIMV2_TYPE_REGISTER_STOP, "Register Stop" }, + { PIMV2_TYPE_JOIN_PRUNE, "Join / Prune" }, + { PIMV2_TYPE_BOOTSTRAP, "Bootstrap" }, + { PIMV2_TYPE_ASSERT, "Assert" }, + { PIMV2_TYPE_GRAFT, "Graft" }, + { PIMV2_TYPE_GRAFT_ACK, "Graft Acknowledgement" }, + { PIMV2_TYPE_CANDIDATE_RP, "Candidate RP Advertisement" }, + { PIMV2_TYPE_PRUNE_REFRESH, "Prune Refresh" }, + { 0, NULL} +}; + +#define PIMV2_HELLO_OPTION_HOLDTIME 1 +#define PIMV2_HELLO_OPTION_LANPRUNEDELAY 2 +#define PIMV2_HELLO_OPTION_DR_PRIORITY_OLD 18 +#define PIMV2_HELLO_OPTION_DR_PRIORITY 19 +#define PIMV2_HELLO_OPTION_GENID 20 +#define PIMV2_HELLO_OPTION_REFRESH_CAP 21 +#define PIMV2_HELLO_OPTION_BIDIR_CAP 22 +#define PIMV2_HELLO_OPTION_ADDRESS_LIST 24 +#define PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD 65001 + +static struct tok pimv2_hello_option_values[] = { + { PIMV2_HELLO_OPTION_HOLDTIME, "Hold Time" }, + { PIMV2_HELLO_OPTION_LANPRUNEDELAY, "LAN Prune Delay" }, + { PIMV2_HELLO_OPTION_DR_PRIORITY_OLD, "DR Priority (Old)" }, + { PIMV2_HELLO_OPTION_DR_PRIORITY, "DR Priority" }, + { PIMV2_HELLO_OPTION_GENID, "Generation ID" }, + { PIMV2_HELLO_OPTION_REFRESH_CAP, "State Refresh Capability" }, + { PIMV2_HELLO_OPTION_BIDIR_CAP, "Bi-Directional Capability" }, + { PIMV2_HELLO_OPTION_ADDRESS_LIST, "Address List" }, + { PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD, "Address List (Old)" }, + { 0, NULL} +}; + +#define PIMV2_REGISTER_FLAG_LEN 4 +#define PIMV2_REGISTER_FLAG_BORDER 0x80000000 +#define PIMV2_REGISTER_FLAG_NULL 0x40000000 + +static struct tok pimv2_register_flag_values[] = { + { PIMV2_REGISTER_FLAG_BORDER, "Border" }, + { PIMV2_REGISTER_FLAG_NULL, "Null" }, + { 0, NULL} +}; + +/* + * XXX: We consider a case where IPv6 is not ready yet for portability, + * but PIM dependent defintions should be independent of IPv6... + */ + +struct pim { + u_int8_t pim_typever; + /* upper 4bit: PIM version number; 2 for PIMv2 */ + /* lower 4bit: the PIM message type, currently they are: + * Hello, Register, Register-Stop, Join/Prune, + * Bootstrap, Assert, Graft (PIM-DM only), + * Graft-Ack (PIM-DM only), C-RP-Adv + */ +#define PIM_VER(x) (((x) & 0xf0) >> 4) +#define PIM_TYPE(x) ((x) & 0x0f) + u_char pim_rsv; /* Reserved */ + u_short pim_cksum; /* IP style check sum */ +}; + +static void pimv2_print(register const u_char *bp, register u_int len, u_int cksum); + +static void +pimv1_join_prune_print(register const u_char *bp, register u_int len) +{ + int maddrlen, addrlen, ngroups, njoin, nprune; + int njp; + + /* If it's a single group and a single source, use 1-line output. */ + if (TTEST2(bp[0], 30) && bp[11] == 1 && + ((njoin = EXTRACT_16BITS(&bp[20])) + EXTRACT_16BITS(&bp[22])) == 1) { + int hold; + + (void)printf(" RPF %s ", ipaddr_string(bp)); + hold = EXTRACT_16BITS(&bp[6]); + if (hold != 180) { + (void)printf("Hold "); + relts_print(hold); + } + (void)printf("%s (%s/%d, %s", njoin ? "Join" : "Prune", + ipaddr_string(&bp[26]), bp[25] & 0x3f, + ipaddr_string(&bp[12])); + if (EXTRACT_32BITS(&bp[16]) != 0xffffffff) + (void)printf("/%s", ipaddr_string(&bp[16])); + (void)printf(") %s%s %s", + (bp[24] & 0x01) ? "Sparse" : "Dense", + (bp[25] & 0x80) ? " WC" : "", + (bp[25] & 0x40) ? "RP" : "SPT"); + return; + } + + TCHECK2(bp[0], sizeof(struct in_addr)); + if (vflag > 1) + (void)printf("\n"); + (void)printf(" Upstream Nbr: %s", ipaddr_string(bp)); + TCHECK2(bp[6], 2); + if (vflag > 1) + (void)printf("\n"); + (void)printf(" Hold time: "); + relts_print(EXTRACT_16BITS(&bp[6])); + if (vflag < 2) + return; + bp += 8; + len -= 8; + + TCHECK2(bp[0], 4); + maddrlen = bp[1]; + addrlen = bp[2]; + ngroups = bp[3]; + bp += 4; + len -= 4; + while (ngroups--) { + /* + * XXX - does the address have length "addrlen" and the + * mask length "maddrlen"? + */ + TCHECK2(bp[0], sizeof(struct in_addr)); + (void)printf("\n\tGroup: %s", ipaddr_string(bp)); + TCHECK2(bp[4], sizeof(struct in_addr)); + if (EXTRACT_32BITS(&bp[4]) != 0xffffffff) + (void)printf("/%s", ipaddr_string(&bp[4])); + TCHECK2(bp[8], 4); + njoin = EXTRACT_16BITS(&bp[8]); + nprune = EXTRACT_16BITS(&bp[10]); + (void)printf(" joined: %d pruned: %d", njoin, nprune); + bp += 12; + len -= 12; + for (njp = 0; njp < (njoin + nprune); njp++) { + const char *type; + + if (njp < njoin) + type = "Join "; + else + type = "Prune"; + TCHECK2(bp[0], 6); + (void)printf("\n\t%s %s%s%s%s/%d", type, + (bp[0] & 0x01) ? "Sparse " : "Dense ", + (bp[1] & 0x80) ? "WC " : "", + (bp[1] & 0x40) ? "RP " : "SPT ", + ipaddr_string(&bp[2]), bp[1] & 0x3f); + bp += 6; + len -= 6; + } + } + return; +trunc: + (void)printf("[|pim]"); + return; +} + +void +pimv1_print(register const u_char *bp, register u_int len) +{ + register const u_char *ep; + register u_char type; + + ep = (const u_char *)snapend; + if (bp >= ep) + return; + + TCHECK(bp[1]); + type = bp[1]; + + switch (type) { + case 0: + (void)printf(" Query"); + if (TTEST(bp[8])) { + switch (bp[8] >> 4) { + case 0: + (void)printf(" Dense-mode"); + break; + case 1: + (void)printf(" Sparse-mode"); + break; + case 2: + (void)printf(" Sparse-Dense-mode"); + break; + default: + (void)printf(" mode-%d", bp[8] >> 4); + break; + } + } + if (vflag) { + TCHECK2(bp[10],2); + (void)printf(" (Hold-time "); + relts_print(EXTRACT_16BITS(&bp[10])); + (void)printf(")"); + } + break; + + case 1: + (void)printf(" Register"); + TCHECK2(bp[8], 20); /* ip header */ + (void)printf(" for %s > %s", ipaddr_string(&bp[20]), + ipaddr_string(&bp[24])); + break; + case 2: + (void)printf(" Register-Stop"); + TCHECK2(bp[12], sizeof(struct in_addr)); + (void)printf(" for %s > %s", ipaddr_string(&bp[8]), + ipaddr_string(&bp[12])); + break; + case 3: + (void)printf(" Join/Prune"); + if (vflag) + pimv1_join_prune_print(&bp[8], len - 8); + break; + case 4: + (void)printf(" RP-reachable"); + if (vflag) { + TCHECK2(bp[22], 2); + (void)printf(" group %s", + ipaddr_string(&bp[8])); + if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) + (void)printf("/%s", ipaddr_string(&bp[12])); + (void)printf(" RP %s hold ", ipaddr_string(&bp[16])); + relts_print(EXTRACT_16BITS(&bp[22])); + } + break; + case 5: + (void)printf(" Assert"); + TCHECK2(bp[16], sizeof(struct in_addr)); + (void)printf(" for %s > %s", ipaddr_string(&bp[16]), + ipaddr_string(&bp[8])); + if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) + (void)printf("/%s", ipaddr_string(&bp[12])); + TCHECK2(bp[24], 4); + (void)printf(" %s pref %d metric %d", + (bp[20] & 0x80) ? "RP-tree" : "SPT", + EXTRACT_32BITS(&bp[20]) & 0x7fffffff, + EXTRACT_32BITS(&bp[24])); + break; + case 6: + (void)printf(" Graft"); + if (vflag) + pimv1_join_prune_print(&bp[8], len - 8); + break; + case 7: + (void)printf(" Graft-ACK"); + if (vflag) + pimv1_join_prune_print(&bp[8], len - 8); + break; + case 8: + (void)printf(" Mode"); + break; + default: + (void)printf(" [type %d]", type); + break; + } + if ((bp[4] >> 4) != 1) + (void)printf(" [v%d]", bp[4] >> 4); + return; + +trunc: + (void)printf("[|pim]"); + return; +} + +/* + * auto-RP is a cisco protocol, documented at + * ftp://ftpeng.cisco.com/ipmulticast/specs/pim-autorp-spec01.txt + * + * This implements version 1+, dated Sept 9, 1998. + */ +void +cisco_autorp_print(register const u_char *bp, register u_int len) +{ + int type; + int numrps; + int hold; + + TCHECK(bp[0]); + (void)printf(" auto-rp "); + type = bp[0]; + switch (type) { + case 0x11: + (void)printf("candidate-advert"); + break; + case 0x12: + (void)printf("mapping"); + break; + default: + (void)printf("type-0x%02x", type); + break; + } + + TCHECK(bp[1]); + numrps = bp[1]; + + TCHECK2(bp[2], 2); + (void)printf(" Hold "); + hold = EXTRACT_16BITS(&bp[2]); + if (hold) + relts_print(EXTRACT_16BITS(&bp[2])); + else + printf("FOREVER"); + + /* Next 4 bytes are reserved. */ + + bp += 8; len -= 8; + + /*XXX skip unless -v? */ + + /* + * Rest of packet: + * numrps entries of the form: + * 32 bits: RP + * 6 bits: reserved + * 2 bits: PIM version supported, bit 0 is "supports v1", 1 is "v2". + * 8 bits: # of entries for this RP + * each entry: 7 bits: reserved, 1 bit: negative, + * 8 bits: mask 32 bits: source + * lather, rinse, repeat. + */ + while (numrps--) { + int nentries; + char s; + + TCHECK2(bp[0], 4); + (void)printf(" RP %s", ipaddr_string(bp)); + TCHECK(bp[4]); + switch (bp[4] & 0x3) { + case 0: printf(" PIMv?"); + break; + case 1: printf(" PIMv1"); + break; + case 2: printf(" PIMv2"); + break; + case 3: printf(" PIMv1+2"); + break; + } + if (bp[4] & 0xfc) + (void)printf(" [rsvd=0x%02x]", bp[4] & 0xfc); + TCHECK(bp[5]); + nentries = bp[5]; + bp += 6; len -= 6; + s = ' '; + for (; nentries; nentries--) { + TCHECK2(bp[0], 6); + (void)printf("%c%s%s/%d", s, bp[0] & 1 ? "!" : "", + ipaddr_string(&bp[2]), bp[1]); + if (bp[0] & 0x02) { + (void)printf(" bidir"); + } + if (bp[0] & 0xfc) { + (void)printf("[rsvd=0x%02x]", bp[0] & 0xfc); + } + s = ','; + bp += 6; len -= 6; + } + } + return; + +trunc: + (void)printf("[|autorp]"); + return; +} + +void +pim_print(register const u_char *bp, register u_int len, u_int cksum) +{ + register const u_char *ep; + register struct pim *pim = (struct pim *)bp; + + ep = (const u_char *)snapend; + if (bp >= ep) + return; +#ifdef notyet /* currently we see only version and type */ + TCHECK(pim->pim_rsv); +#endif + + switch (PIM_VER(pim->pim_typever)) { + case 2: + if (!vflag) { + printf("PIMv%u, %s, length %u", + PIM_VER(pim->pim_typever), + tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)), + len); + return; + } else { + printf("PIMv%u, length %u\n\t%s", + PIM_VER(pim->pim_typever), + len, + tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever))); + pimv2_print(bp, len, cksum); + } + break; + default: + printf("PIMv%u, length %u", + PIM_VER(pim->pim_typever), + len); + break; + } + return; +} + +/* + * PIMv2 uses encoded address representations. + * + * The last PIM-SM I-D before RFC2117 was published specified the + * following representation for unicast addresses. However, RFC2117 + * specified no encoding for unicast addresses with the unicast + * address length specified in the header. Therefore, we have to + * guess which encoding is being used (Cisco's PIMv2 implementation + * uses the non-RFC encoding). RFC2117 turns a previously "Reserved" + * field into a 'unicast-address-length-in-bytes' field. We guess + * that it's the draft encoding if this reserved field is zero. + * + * RFC2362 goes back to the encoded format, and calls the addr length + * field "reserved" again. + * + * The first byte is the address family, from: + * + * 0 Reserved + * 1 IP (IP version 4) + * 2 IP6 (IP version 6) + * 3 NSAP + * 4 HDLC (8-bit multidrop) + * 5 BBN 1822 + * 6 802 (includes all 802 media plus Ethernet "canonical format") + * 7 E.163 + * 8 E.164 (SMDS, Frame Relay, ATM) + * 9 F.69 (Telex) + * 10 X.121 (X.25, Frame Relay) + * 11 IPX + * 12 Appletalk + * 13 Decnet IV + * 14 Banyan Vines + * 15 E.164 with NSAP format subaddress + * + * In addition, the second byte is an "Encoding". 0 is the default + * encoding for the address family, and no other encodings are currently + * specified. + * + */ + +static int pimv2_addr_len; + +enum pimv2_addrtype { + pimv2_unicast, pimv2_group, pimv2_source +}; + +/* 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Addr Family | Encoding Type | Unicast Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++++++ + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Addr Family | Encoding Type | Reserved | Mask Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Group multicast Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Source Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +static int +pimv2_addr_print(const u_char *bp, enum pimv2_addrtype at, int silent) +{ + int af; + int len, hdrlen; + + TCHECK(bp[0]); + + if (pimv2_addr_len == 0) { + TCHECK(bp[1]); + switch (bp[0]) { + case 1: + af = AF_INET; + len = sizeof(struct in_addr); + break; +#ifdef INET6 + case 2: + af = AF_INET6; + len = sizeof(struct in6_addr); + break; +#endif + default: + return -1; + } + if (bp[1] != 0) + return -1; + hdrlen = 2; + } else { + switch (pimv2_addr_len) { + case sizeof(struct in_addr): + af = AF_INET; + break; +#ifdef INET6 + case sizeof(struct in6_addr): + af = AF_INET6; + break; +#endif + default: + return -1; + break; + } + len = pimv2_addr_len; + hdrlen = 0; + } + + bp += hdrlen; + switch (at) { + case pimv2_unicast: + TCHECK2(bp[0], len); + if (af == AF_INET) { + if (!silent) + (void)printf("%s", ipaddr_string(bp)); + } +#ifdef INET6 + else if (af == AF_INET6) { + if (!silent) + (void)printf("%s", ip6addr_string(bp)); + } +#endif + return hdrlen + len; + case pimv2_group: + case pimv2_source: + TCHECK2(bp[0], len + 2); + if (af == AF_INET) { + if (!silent) { + (void)printf("%s", ipaddr_string(bp + 2)); + if (bp[1] != 32) + (void)printf("/%u", bp[1]); + } + } +#ifdef INET6 + else if (af == AF_INET6) { + if (!silent) { + (void)printf("%s", ip6addr_string(bp + 2)); + if (bp[1] != 128) + (void)printf("/%u", bp[1]); + } + } +#endif + if (bp[0] && !silent) { + if (at == pimv2_group) { + (void)printf("(0x%02x)", bp[0]); + } else { + (void)printf("(%s%s%s", + bp[0] & 0x04 ? "S" : "", + bp[0] & 0x02 ? "W" : "", + bp[0] & 0x01 ? "R" : ""); + if (bp[0] & 0xf8) { + (void) printf("+0x%02x", bp[0] & 0xf8); + } + (void)printf(")"); + } + } + return hdrlen + 2 + len; + default: + return -1; + } +trunc: + return -1; +} + +static void +pimv2_print(register const u_char *bp, register u_int len, u_int cksum) +{ + register const u_char *ep; + register struct pim *pim = (struct pim *)bp; + int advance; + + ep = (const u_char *)snapend; + if (bp >= ep) + return; + if (ep > bp + len) + ep = bp + len; + TCHECK(pim->pim_rsv); + pimv2_addr_len = pim->pim_rsv; + if (pimv2_addr_len != 0) + (void)printf(", RFC2117-encoding"); + + printf(", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum)); + if (EXTRACT_16BITS(&pim->pim_cksum) == 0) { + printf("(unverified)"); + } else { + printf("(%scorrect)", TTEST2(bp[0], len) && cksum ? "in" : "" ); + } + + switch (PIM_TYPE(pim->pim_typever)) { + case PIMV2_TYPE_HELLO: + { + u_int16_t otype, olen; + bp += 4; + while (bp < ep) { + TCHECK2(bp[0], 4); + otype = EXTRACT_16BITS(&bp[0]); + olen = EXTRACT_16BITS(&bp[2]); + TCHECK2(bp[0], 4 + olen); + + printf("\n\t %s Option (%u), length %u, Value: ", + tok2str( pimv2_hello_option_values,"Unknown",otype), + otype, + olen); + bp += 4; + + switch (otype) { + case PIMV2_HELLO_OPTION_HOLDTIME: + relts_print(EXTRACT_16BITS(bp)); + break; + + case PIMV2_HELLO_OPTION_LANPRUNEDELAY: + if (olen != 4) { + (void)printf("ERROR: Option Length != 4 Bytes (%u)", olen); + } else { + char t_bit; + u_int16_t lan_delay, override_interval; + lan_delay = EXTRACT_16BITS(bp); + override_interval = EXTRACT_16BITS(bp+2); + t_bit = (lan_delay & 0x8000)? 1 : 0; + lan_delay &= ~0x8000; + (void)printf("\n\t T-bit=%d, LAN delay %dms, Override interval %dms", + t_bit, lan_delay, override_interval); + } + break; + + case PIMV2_HELLO_OPTION_DR_PRIORITY_OLD: + case PIMV2_HELLO_OPTION_DR_PRIORITY: + switch (olen) { + case 0: + printf("Bi-Directional Capability (Old)"); + break; + case 4: + printf("%u", EXTRACT_32BITS(bp)); + break; + default: + printf("ERROR: Option Length != 4 Bytes (%u)", olen); + break; + } + break; + + case PIMV2_HELLO_OPTION_GENID: + (void)printf("0x%08x", EXTRACT_32BITS(bp)); + break; + + case PIMV2_HELLO_OPTION_REFRESH_CAP: + (void)printf("v%d", *bp); + if (*(bp+1) != 0) { + (void)printf(", interval "); + relts_print(*(bp+1)); + } + if (EXTRACT_16BITS(bp+2) != 0) { + (void)printf(" ?0x%04x?", EXTRACT_16BITS(bp+2)); + } + break; + + case PIMV2_HELLO_OPTION_BIDIR_CAP: + break; + + case PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD: + case PIMV2_HELLO_OPTION_ADDRESS_LIST: + if (vflag > 1) { + const u_char *ptr = bp; + while (ptr < (bp+olen)) { + int advance; + + printf("\n\t "); + advance = pimv2_addr_print(ptr, pimv2_unicast, 0); + if (advance < 0) { + printf("..."); + break; + } + ptr += advance; + } + } + break; + default: + if (vflag <= 1) + print_unknown_data(bp,"\n\t ",olen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag> 1) + print_unknown_data(bp,"\n\t ",olen); + bp += olen; + } + break; + } + + case PIMV2_TYPE_REGISTER: + { + struct ip *ip; + + if (!TTEST2(*(bp+4), PIMV2_REGISTER_FLAG_LEN)) + goto trunc; + + printf(", Flags [ %s ]\n\t", + tok2str(pimv2_register_flag_values, + "none", + EXTRACT_32BITS(bp+4))); + + bp += 8; len -= 8; + /* encapsulated multicast packet */ + ip = (struct ip *)bp; + switch (IP_V(ip)) { + case 0: /* Null header */ + (void)printf("IP-Null-header %s > %s", + ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst)); + break; + + case 4: /* IPv4 */ + ip_print(gndo, bp, len); + break; +#ifdef INET6 + case 6: /* IPv6 */ + ip6_print(gndo, bp, len); + break; +#endif + default: + (void)printf("IP ver %d", IP_V(ip)); + break; + } + break; + } + + case PIMV2_TYPE_REGISTER_STOP: + bp += 4; len -= 4; + if (bp >= ep) + break; + (void)printf(" group="); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; len -= advance; + if (bp >= ep) + break; + (void)printf(" source="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; len -= advance; + break; + + case PIMV2_TYPE_JOIN_PRUNE: + case PIMV2_TYPE_GRAFT: + case PIMV2_TYPE_GRAFT_ACK: + + + /* + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |PIM Ver| Type | Addr length | Checksum | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Unicast-Upstream Neighbor Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | Num groups | Holdtime | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Multicast Group Address-1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Number of Joined Sources | Number of Pruned Sources | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Joined Source Address-1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . | + * | . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Joined Source Address-n | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Pruned Source Address-1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . | + * | . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Pruned Source Address-n | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . | + * | . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Multicast Group Address-n | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + { + u_int8_t ngroup; + u_int16_t holdtime; + u_int16_t njoin; + u_int16_t nprune; + int i, j; + + bp += 4; len -= 4; + if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ + if (bp >= ep) + break; + (void)printf(", upstream-neighbor: "); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; len -= advance; + } + if (bp + 4 > ep) + break; + ngroup = bp[1]; + holdtime = EXTRACT_16BITS(&bp[2]); + (void)printf("\n\t %u group(s)", ngroup); + if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ + (void)printf(", holdtime: "); + if (holdtime == 0xffff) + (void)printf("infinite"); + else + relts_print(holdtime); + } + bp += 4; len -= 4; + for (i = 0; i < ngroup; i++) { + if (bp >= ep) + goto jp_done; + (void)printf("\n\t group #%u: ", i+1); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { + (void)printf("...)"); + goto jp_done; + } + bp += advance; len -= advance; + if (bp + 4 > ep) { + (void)printf("...)"); + goto jp_done; + } + njoin = EXTRACT_16BITS(&bp[0]); + nprune = EXTRACT_16BITS(&bp[2]); + (void)printf(", joined sources: %u, pruned sources: %u", njoin,nprune); + bp += 4; len -= 4; + for (j = 0; j < njoin; j++) { + (void)printf("\n\t joined source #%u: ",j+1); + if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) { + (void)printf("...)"); + goto jp_done; + } + bp += advance; len -= advance; + } + for (j = 0; j < nprune; j++) { + (void)printf("\n\t pruned source #%u: ",j+1); + if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) { + (void)printf("...)"); + goto jp_done; + } + bp += advance; len -= advance; + } + } + jp_done: + break; + } + + case PIMV2_TYPE_BOOTSTRAP: + { + int i, j, frpcnt; + bp += 4; + + /* Fragment Tag, Hash Mask len, and BSR-priority */ + if (bp + sizeof(u_int16_t) >= ep) break; + (void)printf(" tag=%x", EXTRACT_16BITS(bp)); + bp += sizeof(u_int16_t); + if (bp >= ep) break; + (void)printf(" hashmlen=%d", bp[0]); + if (bp + 1 >= ep) break; + (void)printf(" BSRprio=%d", bp[1]); + bp += 2; + + /* Encoded-Unicast-BSR-Address */ + if (bp >= ep) break; + (void)printf(" BSR="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; + + for (i = 0; bp < ep; i++) { + /* Encoded-Group Address */ + (void)printf(" (group%d: ", i); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) + < 0) { + (void)printf("...)"); + goto bs_done; + } + bp += advance; + + /* RP-Count, Frag RP-Cnt, and rsvd */ + if (bp >= ep) { + (void)printf("...)"); + goto bs_done; + } + (void)printf(" RPcnt=%d", bp[0]); + if (bp + 1 >= ep) { + (void)printf("...)"); + goto bs_done; + } + (void)printf(" FRPcnt=%d", frpcnt = bp[1]); + bp += 4; + + for (j = 0; j < frpcnt && bp < ep; j++) { + /* each RP info */ + (void)printf(" RP%d=", j); + if ((advance = pimv2_addr_print(bp, + pimv2_unicast, + 0)) < 0) { + (void)printf("...)"); + goto bs_done; + } + bp += advance; + + if (bp + 1 >= ep) { + (void)printf("...)"); + goto bs_done; + } + (void)printf(",holdtime="); + relts_print(EXTRACT_16BITS(bp)); + if (bp + 2 >= ep) { + (void)printf("...)"); + goto bs_done; + } + (void)printf(",prio=%d", bp[2]); + bp += 4; + } + (void)printf(")"); + } + bs_done: + break; + } + case PIMV2_TYPE_ASSERT: + bp += 4; len -= 4; + if (bp >= ep) + break; + (void)printf(" group="); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; len -= advance; + if (bp >= ep) + break; + (void)printf(" src="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; len -= advance; + if (bp + 8 > ep) + break; + if (bp[0] & 0x80) + (void)printf(" RPT"); + (void)printf(" pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff); + (void)printf(" metric=%u", EXTRACT_32BITS(&bp[4])); + break; + + case PIMV2_TYPE_CANDIDATE_RP: + { + int i, pfxcnt; + bp += 4; + + /* Prefix-Cnt, Priority, and Holdtime */ + if (bp >= ep) break; + (void)printf(" prefix-cnt=%d", bp[0]); + pfxcnt = bp[0]; + if (bp + 1 >= ep) break; + (void)printf(" prio=%d", bp[1]); + if (bp + 3 >= ep) break; + (void)printf(" holdtime="); + relts_print(EXTRACT_16BITS(&bp[2])); + bp += 4; + + /* Encoded-Unicast-RP-Address */ + if (bp >= ep) break; + (void)printf(" RP="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; + + /* Encoded-Group Addresses */ + for (i = 0; i < pfxcnt && bp < ep; i++) { + (void)printf(" Group%d=", i); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) + < 0) { + (void)printf("..."); + break; + } + bp += advance; + } + break; + } + + case PIMV2_TYPE_PRUNE_REFRESH: + (void)printf(" src="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; + (void)printf(" grp="); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; + (void)printf(" forwarder="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; + TCHECK2(bp[0], 2); + (void)printf(" TUNR "); + relts_print(EXTRACT_16BITS(bp)); + break; + + + default: + (void)printf(" [type %d]", PIM_TYPE(pim->pim_typever)); + break; + } + + return; + +trunc: + (void)printf("[|pim]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-ppi.c b/freebsd/contrib/tcpdump/print-ppi.c new file mode 100644 index 00000000..b78d8730 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ppi.c @@ -0,0 +1,106 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Oracle + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> + +#include "netdissect.h" +#include "interface.h" +#include "extract.h" +#include "ppi.h" + +#ifdef DLT_PPI + +static inline void +ppi_header_print(struct netdissect_options *ndo, const u_char *bp, u_int length) +{ + const ppi_header_t *hdr; + u_int32_t dlt; + u_int16_t len; + + hdr = (const ppi_header_t *)bp; + + len = EXTRACT_16BITS(&hdr->ppi_len); + dlt = EXTRACT_32BITS(&hdr->ppi_dlt); + + if (!ndo->ndo_qflag) { + ND_PRINT((ndo,", V.%d DLT %s (%d) len %d", hdr->ppi_ver, + pcap_datalink_val_to_name(dlt), dlt, + len)); + } else { + ND_PRINT((ndo,", %s", pcap_datalink_val_to_name(dlt))); + } + + ND_PRINT((ndo, ", length %u: ", length)); +} + +static void +ppi_print(struct netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + if_ndo_printer ndo_printer; + if_printer printer; + ppi_header_t *hdr; + u_int caplen = h->caplen; + u_int length = h->len; + u_int32_t dlt; + + if (caplen < sizeof(ppi_header_t)) { + ND_PRINT((ndo, "[|ppi]")); + return; + } + hdr = (ppi_header_t *)p; + dlt = EXTRACT_32BITS(&hdr->ppi_dlt); + + if (ndo->ndo_eflag) + ppi_header_print(ndo, p, length); + + length -= sizeof(ppi_header_t); + caplen -= sizeof(ppi_header_t); + p += sizeof(ppi_header_t); + + if ((printer = lookup_printer(dlt)) != NULL) { + printer(h, p); + } else if ((ndo_printer = lookup_ndo_printer(dlt)) != NULL) { + ndo_printer(ndo, h, p); + } else { + if (!ndo->ndo_eflag) + ppi_header_print(ndo, (u_char *)hdr, + length + sizeof(ppi_header_t)); + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether 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 +ppi_if_print(struct netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + ppi_print(ndo, h, p); + + return (sizeof(ppi_header_t)); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + +#endif /* DLT_PPI */ diff --git a/freebsd/contrib/tcpdump/print-ppp.c b/freebsd/contrib/tcpdump/print-ppp.c new file mode 100644 index 00000000..23eb21a2 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ppp.c @@ -0,0 +1,1761 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * Extensively modified by Motonori Shindo (mshindo@mshindo.net) for more + * complete PPP support. + * + * $FreeBSD$ + */ + +/* + * TODO: + * o resolve XXX as much as possible + * o MP support + * o BAP support + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.114 2005-12-05 11:35:58 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#ifdef __bsdi__ +#include <net/slcompress.h> +#include <net/if_ppp.h> +#endif + +#include <pcap.h> +#include <stdio.h> +#include <stdlib.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ppp.h" +#include "chdlc.h" +#include "ethertype.h" +#include "oui.h" + +/* + * The following constatns are defined by IANA. Please refer to + * http://www.isi.edu/in-notes/iana/assignments/ppp-numbers + * for the up-to-date information. + */ + +/* Protocol Codes defined in ppp.h */ + +struct tok ppptype2str[] = { + { PPP_IP, "IP" }, + { PPP_OSI, "OSI" }, + { PPP_NS, "NS" }, + { PPP_DECNET, "DECNET" }, + { PPP_APPLE, "APPLE" }, + { PPP_IPX, "IPX" }, + { PPP_VJC, "VJC IP" }, + { PPP_VJNC, "VJNC IP" }, + { PPP_BRPDU, "BRPDU" }, + { PPP_STII, "STII" }, + { PPP_VINES, "VINES" }, + { PPP_MPLS_UCAST, "MPLS" }, + { PPP_MPLS_MCAST, "MPLS" }, + { PPP_COMP, "Compressed"}, + { PPP_ML, "MLPPP"}, + { PPP_IPV6, "IP6"}, + + { PPP_HELLO, "HELLO" }, + { PPP_LUXCOM, "LUXCOM" }, + { PPP_SNS, "SNS" }, + { PPP_IPCP, "IPCP" }, + { PPP_OSICP, "OSICP" }, + { PPP_NSCP, "NSCP" }, + { PPP_DECNETCP, "DECNETCP" }, + { PPP_APPLECP, "APPLECP" }, + { PPP_IPXCP, "IPXCP" }, + { PPP_STIICP, "STIICP" }, + { PPP_VINESCP, "VINESCP" }, + { PPP_IPV6CP, "IP6CP" }, + { PPP_MPLSCP, "MPLSCP" }, + + { PPP_LCP, "LCP" }, + { PPP_PAP, "PAP" }, + { PPP_LQM, "LQM" }, + { PPP_CHAP, "CHAP" }, + { PPP_EAP, "EAP" }, + { PPP_SPAP, "SPAP" }, + { PPP_SPAP_OLD, "Old-SPAP" }, + { PPP_BACP, "BACP" }, + { PPP_BAP, "BAP" }, + { PPP_MPCP, "MLPPP-CP" }, + { 0, NULL } +}; + +/* Control Protocols (LCP/IPCP/CCP etc.) Codes defined in RFC 1661 */ + +#define CPCODES_VEXT 0 /* Vendor-Specific (RFC2153) */ +#define CPCODES_CONF_REQ 1 /* Configure-Request */ +#define CPCODES_CONF_ACK 2 /* Configure-Ack */ +#define CPCODES_CONF_NAK 3 /* Configure-Nak */ +#define CPCODES_CONF_REJ 4 /* Configure-Reject */ +#define CPCODES_TERM_REQ 5 /* Terminate-Request */ +#define CPCODES_TERM_ACK 6 /* Terminate-Ack */ +#define CPCODES_CODE_REJ 7 /* Code-Reject */ +#define CPCODES_PROT_REJ 8 /* Protocol-Reject (LCP only) */ +#define CPCODES_ECHO_REQ 9 /* Echo-Request (LCP only) */ +#define CPCODES_ECHO_RPL 10 /* Echo-Reply (LCP only) */ +#define CPCODES_DISC_REQ 11 /* Discard-Request (LCP only) */ +#define CPCODES_ID 12 /* Identification (LCP only) RFC1570 */ +#define CPCODES_TIME_REM 13 /* Time-Remaining (LCP only) RFC1570 */ +#define CPCODES_RESET_REQ 14 /* Reset-Request (CCP only) RFC1962 */ +#define CPCODES_RESET_REP 15 /* Reset-Reply (CCP only) */ + +struct tok cpcodes[] = { + {CPCODES_VEXT, "Vendor-Extension"}, /* RFC2153 */ + {CPCODES_CONF_REQ, "Conf-Request"}, + {CPCODES_CONF_ACK, "Conf-Ack"}, + {CPCODES_CONF_NAK, "Conf-Nack"}, + {CPCODES_CONF_REJ, "Conf-Reject"}, + {CPCODES_TERM_REQ, "Term-Request"}, + {CPCODES_TERM_ACK, "Term-Ack"}, + {CPCODES_CODE_REJ, "Code-Reject"}, + {CPCODES_PROT_REJ, "Prot-Reject"}, + {CPCODES_ECHO_REQ, "Echo-Request"}, + {CPCODES_ECHO_RPL, "Echo-Reply"}, + {CPCODES_DISC_REQ, "Disc-Req"}, + {CPCODES_ID, "Ident"}, /* RFC1570 */ + {CPCODES_TIME_REM, "Time-Rem"}, /* RFC1570 */ + {CPCODES_RESET_REQ, "Reset-Req"}, /* RFC1962 */ + {CPCODES_RESET_REP, "Reset-Ack"}, /* RFC1962 */ + {0, NULL} +}; + +/* LCP Config Options */ + +#define LCPOPT_VEXT 0 +#define LCPOPT_MRU 1 +#define LCPOPT_ACCM 2 +#define LCPOPT_AP 3 +#define LCPOPT_QP 4 +#define LCPOPT_MN 5 +#define LCPOPT_DEP6 6 +#define LCPOPT_PFC 7 +#define LCPOPT_ACFC 8 +#define LCPOPT_FCSALT 9 +#define LCPOPT_SDP 10 +#define LCPOPT_NUMMODE 11 +#define LCPOPT_DEP12 12 +#define LCPOPT_CBACK 13 +#define LCPOPT_DEP14 14 +#define LCPOPT_DEP15 15 +#define LCPOPT_DEP16 16 +#define LCPOPT_MLMRRU 17 +#define LCPOPT_MLSSNHF 18 +#define LCPOPT_MLED 19 +#define LCPOPT_PROP 20 +#define LCPOPT_DCEID 21 +#define LCPOPT_MPP 22 +#define LCPOPT_LD 23 +#define LCPOPT_LCPAOPT 24 +#define LCPOPT_COBS 25 +#define LCPOPT_PE 26 +#define LCPOPT_MLHF 27 +#define LCPOPT_I18N 28 +#define LCPOPT_SDLOS 29 +#define LCPOPT_PPPMUX 30 + +#define LCPOPT_MIN LCPOPT_VEXT +#define LCPOPT_MAX LCPOPT_PPPMUX + +static const char *lcpconfopts[] = { + "Vend-Ext", /* (0) */ + "MRU", /* (1) */ + "ACCM", /* (2) */ + "Auth-Prot", /* (3) */ + "Qual-Prot", /* (4) */ + "Magic-Num", /* (5) */ + "deprecated(6)", /* used to be a Quality Protocol */ + "PFC", /* (7) */ + "ACFC", /* (8) */ + "FCS-Alt", /* (9) */ + "SDP", /* (10) */ + "Num-Mode", /* (11) */ + "deprecated(12)", /* used to be a Multi-Link-Procedure*/ + "Call-Back", /* (13) */ + "deprecated(14)", /* used to be a Connect-Time */ + "deprecated(15)", /* used to be a Compund-Frames */ + "deprecated(16)", /* used to be a Nominal-Data-Encap */ + "MRRU", /* (17) */ + "12-Bit seq #", /* (18) */ + "End-Disc", /* (19) */ + "Proprietary", /* (20) */ + "DCE-Id", /* (21) */ + "MP+", /* (22) */ + "Link-Disc", /* (23) */ + "LCP-Auth-Opt", /* (24) */ + "COBS", /* (25) */ + "Prefix-elision", /* (26) */ + "Multilink-header-Form",/* (27) */ + "I18N", /* (28) */ + "SDL-over-SONET/SDH", /* (29) */ + "PPP-Muxing", /* (30) */ +}; + +/* ECP - to be supported */ + +/* CCP Config Options */ + +#define CCPOPT_OUI 0 /* RFC1962 */ +#define CCPOPT_PRED1 1 /* RFC1962 */ +#define CCPOPT_PRED2 2 /* RFC1962 */ +#define CCPOPT_PJUMP 3 /* RFC1962 */ +/* 4-15 unassigned */ +#define CCPOPT_HPPPC 16 /* RFC1962 */ +#define CCPOPT_STACLZS 17 /* RFC1974 */ +#define CCPOPT_MPPC 18 /* RFC2118 */ +#define CCPOPT_GFZA 19 /* RFC1962 */ +#define CCPOPT_V42BIS 20 /* RFC1962 */ +#define CCPOPT_BSDCOMP 21 /* RFC1977 */ +/* 22 unassigned */ +#define CCPOPT_LZSDCP 23 /* RFC1967 */ +#define CCPOPT_MVRCA 24 /* RFC1975 */ +#define CCPOPT_DEC 25 /* RFC1976 */ +#define CCPOPT_DEFLATE 26 /* RFC1979 */ +/* 27-254 unassigned */ +#define CCPOPT_RESV 255 /* RFC1962 */ + +const struct tok ccpconfopts_values[] = { + { CCPOPT_OUI, "OUI" }, + { CCPOPT_PRED1, "Pred-1" }, + { CCPOPT_PRED2, "Pred-2" }, + { CCPOPT_PJUMP, "Puddle" }, + { CCPOPT_HPPPC, "HP-PPC" }, + { CCPOPT_STACLZS, "Stac-LZS" }, + { CCPOPT_MPPC, "MPPC" }, + { CCPOPT_GFZA, "Gand-FZA" }, + { CCPOPT_V42BIS, "V.42bis" }, + { CCPOPT_BSDCOMP, "BSD-Comp" }, + { CCPOPT_LZSDCP, "LZS-DCP" }, + { CCPOPT_MVRCA, "MVRCA" }, + { CCPOPT_DEC, "DEC" }, + { CCPOPT_DEFLATE, "Deflate" }, + { CCPOPT_RESV, "Reserved"}, + {0, NULL} +}; + +/* BACP Config Options */ + +#define BACPOPT_FPEER 1 /* RFC2125 */ + +const struct tok bacconfopts_values[] = { + { BACPOPT_FPEER, "Favored-Peer" }, + {0, NULL} +}; + + +/* SDCP - to be supported */ + +/* IPCP Config Options */ +#define IPCPOPT_2ADDR 1 /* RFC1172, RFC1332 (deprecated) */ +#define IPCPOPT_IPCOMP 2 /* RFC1332 */ +#define IPCPOPT_ADDR 3 /* RFC1332 */ +#define IPCPOPT_MOBILE4 4 /* RFC2290 */ +#define IPCPOPT_PRIDNS 129 /* RFC1877 */ +#define IPCPOPT_PRINBNS 130 /* RFC1877 */ +#define IPCPOPT_SECDNS 131 /* RFC1877 */ +#define IPCPOPT_SECNBNS 132 /* RFC1877 */ + +struct tok ipcpopt_values[] = { + { IPCPOPT_2ADDR, "IP-Addrs" }, + { IPCPOPT_IPCOMP, "IP-Comp" }, + { IPCPOPT_ADDR, "IP-Addr" }, + { IPCPOPT_MOBILE4, "Home-Addr" }, + { IPCPOPT_PRIDNS, "Pri-DNS" }, + { IPCPOPT_PRINBNS, "Pri-NBNS" }, + { IPCPOPT_SECDNS, "Sec-DNS" }, + { IPCPOPT_SECNBNS, "Sec-NBNS" }, + { 0, NULL } +}; + +#define IPCPOPT_IPCOMP_HDRCOMP 0x61 /* rfc3544 */ +#define IPCPOPT_IPCOMP_MINLEN 14 + +struct tok ipcpopt_compproto_values[] = { + { PPP_VJC, "VJ-Comp" }, + { IPCPOPT_IPCOMP_HDRCOMP, "IP Header Compression" }, + { 0, NULL } +}; + +struct tok ipcpopt_compproto_subopt_values[] = { + { 1, "RTP-Compression" }, + { 2, "Enhanced RTP-Compression" }, + { 0, NULL } +}; + +/* IP6CP Config Options */ +#define IP6CP_IFID 1 + +struct tok ip6cpopt_values[] = { + { IP6CP_IFID, "Interface-ID" }, + { 0, NULL } +}; + +/* ATCP - to be supported */ +/* OSINLCP - to be supported */ +/* BVCP - to be supported */ +/* BCP - to be supported */ +/* IPXCP - to be supported */ +/* MPLSCP - to be supported */ + +/* Auth Algorithms */ + +/* 0-4 Reserved (RFC1994) */ +#define AUTHALG_CHAPMD5 5 /* RFC1994 */ +#define AUTHALG_MSCHAP1 128 /* RFC2433 */ +#define AUTHALG_MSCHAP2 129 /* RFC2795 */ + +struct tok authalg_values[] = { + { AUTHALG_CHAPMD5, "MD5" }, + { AUTHALG_MSCHAP1, "MS-CHAPv1" }, + { AUTHALG_MSCHAP2, "MS-CHAPv2" }, + { 0, NULL } +}; + +/* FCS Alternatives - to be supported */ + +/* Multilink Endpoint Discriminator (RFC1717) */ +#define MEDCLASS_NULL 0 /* Null Class */ +#define MEDCLASS_LOCAL 1 /* Locally Assigned */ +#define MEDCLASS_IPV4 2 /* Internet Protocol (IPv4) */ +#define MEDCLASS_MAC 3 /* IEEE 802.1 global MAC address */ +#define MEDCLASS_MNB 4 /* PPP Magic Number Block */ +#define MEDCLASS_PSNDN 5 /* Public Switched Network Director Number */ + +/* PPP LCP Callback */ +#define CALLBACK_AUTH 0 /* Location determined by user auth */ +#define CALLBACK_DSTR 1 /* Dialing string */ +#define CALLBACK_LID 2 /* Location identifier */ +#define CALLBACK_E164 3 /* E.164 number */ +#define CALLBACK_X500 4 /* X.500 distinguished name */ +#define CALLBACK_CBCP 6 /* Location is determined during CBCP nego */ + +struct tok ppp_callback_values[] = { + { CALLBACK_AUTH, "UserAuth" }, + { CALLBACK_DSTR, "DialString" }, + { CALLBACK_LID, "LocalID" }, + { CALLBACK_E164, "E.164" }, + { CALLBACK_X500, "X.500" }, + { CALLBACK_CBCP, "CBCP" }, + { 0, NULL } +}; + +/* CHAP */ + +#define CHAP_CHAL 1 +#define CHAP_RESP 2 +#define CHAP_SUCC 3 +#define CHAP_FAIL 4 + +struct tok chapcode_values[] = { + { CHAP_CHAL, "Challenge" }, + { CHAP_RESP, "Response" }, + { CHAP_SUCC, "Success" }, + { CHAP_FAIL, "Fail" }, + { 0, NULL} +}; + +/* PAP */ + +#define PAP_AREQ 1 +#define PAP_AACK 2 +#define PAP_ANAK 3 + +struct tok papcode_values[] = { + { PAP_AREQ, "Auth-Req" }, + { PAP_AACK, "Auth-ACK" }, + { PAP_ANAK, "Auth-NACK" }, + { 0, NULL } +}; + +/* BAP */ +#define BAP_CALLREQ 1 +#define BAP_CALLRES 2 +#define BAP_CBREQ 3 +#define BAP_CBRES 4 +#define BAP_LDQREQ 5 +#define BAP_LDQRES 6 +#define BAP_CSIND 7 +#define BAP_CSRES 8 + +static void handle_ctrl_proto (u_int proto,const u_char *p, int length); +static void handle_chap (const u_char *p, int length); +static void handle_pap (const u_char *p, int length); +static void handle_bap (const u_char *p, int length); +static void handle_mlppp(const u_char *p, int length); +static int print_lcp_config_options (const u_char *p, int); +static int print_ipcp_config_options (const u_char *p, int); +static int print_ip6cp_config_options (const u_char *p, int); +static int print_ccp_config_options (const u_char *p, int); +static int print_bacp_config_options (const u_char *p, int); +static void handle_ppp (u_int proto, const u_char *p, int length); +static void ppp_hdlc(const u_char *p, int length); + +/* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */ +static void +handle_ctrl_proto(u_int proto, const u_char *pptr, int length) +{ + const char *typestr; + u_int code, len; + int (*pfunc)(const u_char *, int); + int x, j; + const u_char *tptr; + + tptr=pptr; + + typestr = tok2str(ppptype2str, "unknown ctrl-proto (0x%04x)", proto); + printf("%s, ",typestr); + + if (length < 4) /* FIXME weak boundary checking */ + goto trunc; + TCHECK2(*tptr, 2); + + code = *tptr++; + + printf("%s (0x%02x), id %u, length %u", + tok2str(cpcodes, "Unknown Opcode",code), + code, + *tptr++, /* ID */ + length+2); + + if (!vflag) + return; + + if (length <= 4) + return; /* there may be a NULL confreq etc. */ + + TCHECK2(*tptr, 2); + len = EXTRACT_16BITS(tptr); + tptr += 2; + + printf("\n\tencoded length %u (=Option(s) length %u)",len,len-4); + + if (vflag>1) + print_unknown_data(pptr-2,"\n\t",6); + + + switch (code) { + case CPCODES_VEXT: + if (length < 11) + break; + TCHECK2(*tptr, 4); + printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); + tptr += 4; + TCHECK2(*tptr, 3); + printf(" Vendor: %s (%u)", + tok2str(oui_values,"Unknown",EXTRACT_24BITS(tptr)), + EXTRACT_24BITS(tptr)); + /* XXX: need to decode Kind and Value(s)? */ + break; + case CPCODES_CONF_REQ: + case CPCODES_CONF_ACK: + case CPCODES_CONF_NAK: + case CPCODES_CONF_REJ: + x = len - 4; /* Code(1), Identifier(1) and Length(2) */ + do { + switch (proto) { + case PPP_LCP: + pfunc = print_lcp_config_options; + break; + case PPP_IPCP: + pfunc = print_ipcp_config_options; + break; + case PPP_IPV6CP: + pfunc = print_ip6cp_config_options; + break; + case PPP_CCP: + pfunc = print_ccp_config_options; + break; + case PPP_BACP: + pfunc = print_bacp_config_options; + break; + default: + /* + * No print routine for the options for + * this protocol. + */ + pfunc = NULL; + break; + } + + if (pfunc == NULL) /* catch the above null pointer if unknown CP */ + break; + + if ((j = (*pfunc)(tptr, len)) == 0) + break; + x -= j; + tptr += j; + } while (x > 0); + break; + + case CPCODES_TERM_REQ: + case CPCODES_TERM_ACK: + /* XXX: need to decode Data? */ + break; + case CPCODES_CODE_REJ: + /* XXX: need to decode Rejected-Packet? */ + break; + case CPCODES_PROT_REJ: + if (length < 6) + break; + TCHECK2(*tptr, 2); + printf("\n\t Rejected %s Protocol (0x%04x)", + tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)), + EXTRACT_16BITS(tptr)); + /* XXX: need to decode Rejected-Information? - hexdump for now */ + if (len > 6) { + printf("\n\t Rejected Packet"); + print_unknown_data(tptr+2,"\n\t ",len-2); + } + break; + case CPCODES_ECHO_REQ: + case CPCODES_ECHO_RPL: + case CPCODES_DISC_REQ: + if (length < 8) + break; + TCHECK2(*tptr, 4); + printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); + /* XXX: need to decode Data? - hexdump for now */ + if (len > 8) { + printf("\n\t -----trailing data-----"); + TCHECK2(tptr[4], len-8); + print_unknown_data(tptr+4,"\n\t ",len-8); + } + break; + case CPCODES_ID: + if (length < 8) + break; + TCHECK2(*tptr, 4); + printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); + /* RFC 1661 says this is intended to be human readable */ + if (len > 8) { + printf("\n\t Message\n\t "); + fn_printn(tptr+4,len-4,snapend); + } + break; + case CPCODES_TIME_REM: + if (length < 12) + break; + TCHECK2(*tptr, 4); + printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); + TCHECK2(*(tptr + 4), 4); + printf(", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4)); + /* XXX: need to decode Message? */ + break; + default: + /* XXX this is dirty but we do not get the + * original pointer passed to the begin + * the PPP packet */ + if (vflag <= 1) + print_unknown_data(pptr-2,"\n\t ",length+2); + break; + } + return; + +trunc: + printf("[|%s]", typestr); +} + +/* LCP config options */ +static int +print_lcp_config_options(const u_char *p, int length) +{ + int len, opt; + + if (length < 2) + return 0; + TCHECK2(*p, 2); + len = p[1]; + opt = p[0]; + if (length < len) + return 0; + if (len < 2) { + if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) + printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", lcpconfopts[opt],opt,len); + else + printf("\n\tunknown LCP option 0x%02x", opt); + return 0; + } + if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) + printf("\n\t %s Option (0x%02x), length %u: ", lcpconfopts[opt],opt,len); + else { + printf("\n\tunknown LCP option 0x%02x", opt); + return len; + } + + switch (opt) { + case LCPOPT_VEXT: + if (len >= 6) { + TCHECK2(*(p + 2), 3); + printf("Vendor: %s (%u)", + tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)), + EXTRACT_24BITS(p+2)); +#if 0 + TCHECK(p[5]); + printf(", kind: 0x%02x", p[5]); + printf(", Value: 0x") + for (i = 0; i < len - 6; i++) { + TCHECK(p[6 + i]); + printf("%02x", p[6 + i]); + } +#endif + } + break; + case LCPOPT_MRU: + if (len == 4) { + TCHECK2(*(p + 2), 2); + printf("%u", EXTRACT_16BITS(p + 2)); + } + break; + case LCPOPT_ACCM: + if (len == 6) { + TCHECK2(*(p + 2), 4); + printf("0x%08x", EXTRACT_32BITS(p + 2)); + } + break; + case LCPOPT_AP: + if (len >= 4) { + TCHECK2(*(p + 2), 2); + printf("%s", tok2str(ppptype2str,"Unknown Auth Proto (0x04x)",EXTRACT_16BITS(p+2))); + + switch (EXTRACT_16BITS(p+2)) { + case PPP_CHAP: + TCHECK(p[4]); + printf(", %s",tok2str(authalg_values,"Unknown Auth Alg %u",p[4])); + break; + case PPP_PAP: /* fall through */ + case PPP_EAP: + case PPP_SPAP: + case PPP_SPAP_OLD: + break; + default: + print_unknown_data(p,"\n\t",len); + } + } + break; + case LCPOPT_QP: + if (len >= 4) { + TCHECK2(*(p + 2), 2); + if (EXTRACT_16BITS(p+2) == PPP_LQM) + printf(" LQR"); + else + printf(" unknown"); + } + break; + case LCPOPT_MN: + if (len == 6) { + TCHECK2(*(p + 2), 4); + printf("0x%08x", EXTRACT_32BITS(p + 2)); + } + break; + case LCPOPT_PFC: + break; + case LCPOPT_ACFC: + break; + case LCPOPT_LD: + if (len == 4) { + TCHECK2(*(p + 2), 2); + printf("0x%04x", EXTRACT_16BITS(p + 2)); + } + break; + case LCPOPT_CBACK: + if (len < 3) + break; + TCHECK(p[2]); + printf("Callback Operation %s (%u)", + tok2str(ppp_callback_values,"Unknown",p[2]), + p[2]); + break; + case LCPOPT_MLMRRU: + if (len == 4) { + TCHECK2(*(p + 2), 2); + printf("%u", EXTRACT_16BITS(p + 2)); + } + break; + case LCPOPT_MLED: + if (len < 3) + break; + TCHECK(p[2]); + switch (p[2]) { /* class */ + case MEDCLASS_NULL: + printf("Null"); + break; + case MEDCLASS_LOCAL: + printf("Local"); /* XXX */ + break; + case MEDCLASS_IPV4: + if (len != 7) + break; + TCHECK2(*(p + 3), 4); + printf("IPv4 %s", ipaddr_string(p + 3)); + break; + case MEDCLASS_MAC: + if (len != 9) + break; + TCHECK(p[8]); + printf("MAC %02x:%02x:%02x:%02x:%02x:%02x", + p[3], p[4], p[5], p[6], p[7], p[8]); + break; + case MEDCLASS_MNB: + printf("Magic-Num-Block"); /* XXX */ + break; + case MEDCLASS_PSNDN: + printf("PSNDN"); /* XXX */ + break; + } + break; + +/* XXX: to be supported */ +#if 0 + case LCPOPT_DEP6: + case LCPOPT_FCSALT: + case LCPOPT_SDP: + case LCPOPT_NUMMODE: + case LCPOPT_DEP12: + case LCPOPT_DEP14: + case LCPOPT_DEP15: + case LCPOPT_DEP16: + case LCPOPT_MLSSNHF: + case LCPOPT_PROP: + case LCPOPT_DCEID: + case LCPOPT_MPP: + case LCPOPT_LCPAOPT: + case LCPOPT_COBS: + case LCPOPT_PE: + case LCPOPT_MLHF: + case LCPOPT_I18N: + case LCPOPT_SDLOS: + case LCPOPT_PPPMUX: + break; +#endif + default: + if(vflag<2) + print_unknown_data(&p[2],"\n\t ",len-2); + break; + } + + if (vflag>1) + print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ + + return len; + +trunc: + printf("[|lcp]"); + return 0; +} + +/* ML-PPP*/ +struct tok ppp_ml_flag_values[] = { + { 0x80, "begin" }, + { 0x40, "end" }, + { 0, NULL } +}; + +static void +handle_mlppp(const u_char *p, int length) { + + if (!eflag) + printf("MLPPP, "); + + printf("seq 0x%03x, Flags [%s], length %u", + (EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */ + bittok2str(ppp_ml_flag_values, "none", *p & 0xc0), + length); + + return; +} + +/* CHAP */ +static void +handle_chap(const u_char *p, int length) +{ + u_int code, len; + int val_size, name_size, msg_size; + const u_char *p0; + int i; + + p0 = p; + if (length < 1) { + printf("[|chap]"); + return; + } else if (length < 4) { + TCHECK(*p); + printf("[|chap 0x%02x]", *p); + return; + } + + TCHECK(*p); + code = *p; + printf("CHAP, %s (0x%02x)", + tok2str(chapcode_values,"unknown",code), + code); + p++; + + TCHECK(*p); + printf(", id %u", *p); /* ID */ + p++; + + TCHECK2(*p, 2); + len = EXTRACT_16BITS(p); + p += 2; + + /* + * Note that this is a generic CHAP decoding routine. Since we + * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1, + * MS-CHAPv2) is used at this point, we can't decode packet + * specifically to each algorithms. Instead, we simply decode + * the GCD (Gratest Common Denominator) for all algorithms. + */ + switch (code) { + case CHAP_CHAL: + case CHAP_RESP: + if (length - (p - p0) < 1) + return; + TCHECK(*p); + val_size = *p; /* value size */ + p++; + if (length - (p - p0) < val_size) + return; + printf(", Value "); + for (i = 0; i < val_size; i++) { + TCHECK(*p); + printf("%02x", *p++); + } + name_size = len - (p - p0); + printf(", Name "); + for (i = 0; i < name_size; i++) { + TCHECK(*p); + safeputchar(*p++); + } + break; + case CHAP_SUCC: + case CHAP_FAIL: + msg_size = len - (p - p0); + printf(", Msg "); + for (i = 0; i< msg_size; i++) { + TCHECK(*p); + safeputchar(*p++); + } + break; + } + return; + +trunc: + printf("[|chap]"); +} + +/* PAP (see RFC 1334) */ +static void +handle_pap(const u_char *p, int length) +{ + u_int code, len; + int peerid_len, passwd_len, msg_len; + const u_char *p0; + int i; + + p0 = p; + if (length < 1) { + printf("[|pap]"); + return; + } else if (length < 4) { + TCHECK(*p); + printf("[|pap 0x%02x]", *p); + return; + } + + TCHECK(*p); + code = *p; + printf("PAP, %s (0x%02x)", + tok2str(papcode_values,"unknown",code), + code); + p++; + + TCHECK(*p); + printf(", id %u", *p); /* ID */ + p++; + + TCHECK2(*p, 2); + len = EXTRACT_16BITS(p); + p += 2; + + if ((int)len > length) { + printf(", length %u > packet size", len); + return; + } + length = len; + if (length < (p - p0)) { + printf(", length %u < PAP header length", length); + return; + } + + switch (code) { + case PAP_AREQ: + if (length - (p - p0) < 1) + return; + TCHECK(*p); + peerid_len = *p; /* Peer-ID Length */ + p++; + if (length - (p - p0) < peerid_len) + return; + printf(", Peer "); + for (i = 0; i < peerid_len; i++) { + TCHECK(*p); + safeputchar(*p++); + } + + if (length - (p - p0) < 1) + return; + TCHECK(*p); + passwd_len = *p; /* Password Length */ + p++; + if (length - (p - p0) < passwd_len) + return; + printf(", Name "); + for (i = 0; i < passwd_len; i++) { + TCHECK(*p); + safeputchar(*p++); + } + break; + case PAP_AACK: + case PAP_ANAK: + if (length - (p - p0) < 1) + return; + TCHECK(*p); + msg_len = *p; /* Msg-Length */ + p++; + if (length - (p - p0) < msg_len) + return; + printf(", Msg "); + for (i = 0; i< msg_len; i++) { + TCHECK(*p); + safeputchar(*p++); + } + break; + } + return; + +trunc: + printf("[|pap]"); +} + +/* BAP */ +static void +handle_bap(const u_char *p _U_, int length _U_) +{ + /* XXX: to be supported!! */ +} + + +/* IPCP config options */ +static int +print_ipcp_config_options(const u_char *p, int length) +{ + int len, opt; + u_int compproto, ipcomp_subopttotallen, ipcomp_subopt, ipcomp_suboptlen; + + if (length < 2) + return 0; + TCHECK2(*p, 2); + len = p[1]; + opt = p[0]; + if (length < len) + return 0; + if (len < 2) { + printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", + tok2str(ipcpopt_values,"unknown",opt), + opt, + len); + return 0; + } + + printf("\n\t %s Option (0x%02x), length %u: ", + tok2str(ipcpopt_values,"unknown",opt), + opt, + len); + + switch (opt) { + case IPCPOPT_2ADDR: /* deprecated */ + if (len != 10) + goto invlen; + TCHECK2(*(p + 6), 4); + printf("src %s, dst %s", + ipaddr_string(p + 2), + ipaddr_string(p + 6)); + break; + case IPCPOPT_IPCOMP: + if (len < 4) + goto invlen; + TCHECK2(*(p + 2), 2); + compproto = EXTRACT_16BITS(p+2); + + printf("%s (0x%02x):", + tok2str(ipcpopt_compproto_values,"Unknown",compproto), + compproto); + + switch (compproto) { + case PPP_VJC: + /* XXX: VJ-Comp parameters should be decoded */ + break; + case IPCPOPT_IPCOMP_HDRCOMP: + if (len < IPCPOPT_IPCOMP_MINLEN) + goto invlen; + + TCHECK2(*(p + 2), IPCPOPT_IPCOMP_MINLEN); + printf("\n\t TCP Space %u, non-TCP Space %u" \ + ", maxPeriod %u, maxTime %u, maxHdr %u", + EXTRACT_16BITS(p+4), + EXTRACT_16BITS(p+6), + EXTRACT_16BITS(p+8), + EXTRACT_16BITS(p+10), + EXTRACT_16BITS(p+12)); + + /* suboptions present ? */ + if (len > IPCPOPT_IPCOMP_MINLEN) { + ipcomp_subopttotallen = len - IPCPOPT_IPCOMP_MINLEN; + p += IPCPOPT_IPCOMP_MINLEN; + + printf("\n\t Suboptions, length %u", ipcomp_subopttotallen); + + while (ipcomp_subopttotallen >= 2) { + TCHECK2(*p, 2); + ipcomp_subopt = *p; + ipcomp_suboptlen = *(p+1); + + /* sanity check */ + if (ipcomp_subopt == 0 || + ipcomp_suboptlen == 0 ) + break; + + /* XXX: just display the suboptions for now */ + printf("\n\t\t%s Suboption #%u, length %u", + tok2str(ipcpopt_compproto_subopt_values, + "Unknown", + ipcomp_subopt), + ipcomp_subopt, + ipcomp_suboptlen); + + ipcomp_subopttotallen -= ipcomp_suboptlen; + p += ipcomp_suboptlen; + } + } + break; + default: + break; + } + break; + + case IPCPOPT_ADDR: /* those options share the same format - fall through */ + case IPCPOPT_MOBILE4: + case IPCPOPT_PRIDNS: + case IPCPOPT_PRINBNS: + case IPCPOPT_SECDNS: + case IPCPOPT_SECNBNS: + if (len != 6) + goto invlen; + TCHECK2(*(p + 2), 4); + printf("%s", ipaddr_string(p + 2)); + break; + default: + if(vflag<2) + print_unknown_data(&p[2],"\n\t ",len-2); + break; + } + if (vflag>1) + print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ + return len; + +invlen: + printf(", invalid-length-%d", opt); + return 0; + +trunc: + printf("[|ipcp]"); + return 0; +} + +/* IP6CP config options */ +static int +print_ip6cp_config_options(const u_char *p, int length) +{ + int len, opt; + + if (length < 2) + return 0; + TCHECK2(*p, 2); + len = p[1]; + opt = p[0]; + if (length < len) + return 0; + if (len < 2) { + printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", + tok2str(ip6cpopt_values,"unknown",opt), + opt, + len); + return 0; + } + + printf("\n\t %s Option (0x%02x), length %u: ", + tok2str(ip6cpopt_values,"unknown",opt), + opt, + len); + + switch (opt) { + case IP6CP_IFID: + if (len != 10) + goto invlen; + TCHECK2(*(p + 2), 8); + printf("%04x:%04x:%04x:%04x", + EXTRACT_16BITS(p + 2), + EXTRACT_16BITS(p + 4), + EXTRACT_16BITS(p + 6), + EXTRACT_16BITS(p + 8)); + break; + default: + if(vflag<2) + print_unknown_data(&p[2],"\n\t ",len-2); + break; + } + if (vflag>1) + print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ + + return len; + +invlen: + printf(", invalid-length-%d", opt); + return 0; + +trunc: + printf("[|ip6cp]"); + return 0; +} + + +/* CCP config options */ +static int +print_ccp_config_options(const u_char *p, int length) +{ + int len, opt; + + if (length < 2) + return 0; + TCHECK2(*p, 2); + len = p[1]; + opt = p[0]; + if (length < len) + return 0; + if (len < 2) { + printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", + tok2str(ccpconfopts_values, "Unknown", opt), + opt, + len); + return 0; + } + + printf("\n\t %s Option (0x%02x), length %u:", + tok2str(ccpconfopts_values, "Unknown", opt), + opt, + len); + + switch (opt) { + /* fall through --> default: nothing supported yet */ + case CCPOPT_OUI: + case CCPOPT_PRED1: + case CCPOPT_PRED2: + case CCPOPT_PJUMP: + case CCPOPT_HPPPC: + case CCPOPT_STACLZS: + case CCPOPT_MPPC: + case CCPOPT_GFZA: + case CCPOPT_V42BIS: + case CCPOPT_BSDCOMP: + case CCPOPT_LZSDCP: + case CCPOPT_MVRCA: + case CCPOPT_DEC: + case CCPOPT_DEFLATE: + case CCPOPT_RESV: + default: + if(vflag<2) + print_unknown_data(&p[2],"\n\t ",len-2); + break; + } + if (vflag>1) + print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ + + return len; + +trunc: + printf("[|ccp]"); + return 0; +} + +/* BACP config options */ +static int +print_bacp_config_options(const u_char *p, int length) +{ + int len, opt; + + if (length < 2) + return 0; + TCHECK2(*p, 2); + len = p[1]; + opt = p[0]; + if (length < len) + return 0; + if (len < 2) { + printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", + tok2str(bacconfopts_values, "Unknown", opt), + opt, + len); + return 0; + } + + printf("\n\t %s Option (0x%02x), length %u:", + tok2str(bacconfopts_values, "Unknown", opt), + opt, + len); + + switch (opt) { + case BACPOPT_FPEER: + TCHECK2(*(p + 2), 4); + printf(", Magic-Num 0x%08x", EXTRACT_32BITS(p + 2)); + break; + default: + if(vflag<2) + print_unknown_data(&p[2],"\n\t ",len-2); + break; + } + if (vflag>1) + print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ + + return len; + +trunc: + printf("[|bacp]"); + return 0; +} + + +static void +ppp_hdlc(const u_char *p, int length) +{ + u_char *b, *s, *t, c; + int i, proto; + const void *se; + + b = (u_int8_t *)malloc(length); + if (b == NULL) + return; + + /* + * Unescape all the data into a temporary, private, buffer. + * Do this so that we dont overwrite the original packet + * contents. + */ + for (s = (u_char *)p, t = b, i = length; i > 0; i--) { + c = *s++; + if (c == 0x7d) { + if (i > 1) { + i--; + c = *s++ ^ 0x20; + } else + continue; + } + *t++ = c; + } + + se = snapend; + snapend = t; + + /* now lets guess about the payload codepoint format */ + proto = *b; /* start with a one-octet codepoint guess */ + + switch (proto) { + case PPP_IP: + ip_print(gndo, b+1, t - b - 1); + goto cleanup; +#ifdef INET6 + case PPP_IPV6: + ip6_print(gndo, b+1, t - b - 1); + goto cleanup; +#endif + default: /* no luck - try next guess */ + break; + } + + proto = EXTRACT_16BITS(b); /* next guess - load two octets */ + + switch (proto) { + case (PPP_ADDRESS << 8 | PPP_CONTROL): /* looks like a PPP frame */ + proto = EXTRACT_16BITS(b+2); /* load the PPP proto-id */ + handle_ppp(proto, b+4, t - b - 4); + break; + default: /* last guess - proto must be a PPP proto-id */ + handle_ppp(proto, b+2, t - b - 2); + break; + } + +cleanup: + snapend = se; + free(b); + return; +} + + +/* PPP */ +static void +handle_ppp(u_int proto, const u_char *p, int length) +{ + if ((proto & 0xff00) == 0x7e00) {/* is this an escape code ? */ + ppp_hdlc(p-1, length); + return; + } + + switch (proto) { + case PPP_LCP: /* fall through */ + case PPP_IPCP: + case PPP_OSICP: + case PPP_MPLSCP: + case PPP_IPV6CP: + case PPP_CCP: + case PPP_BACP: + handle_ctrl_proto(proto, p, length); + break; + case PPP_ML: + handle_mlppp(p, length); + break; + case PPP_CHAP: + handle_chap(p, length); + break; + case PPP_PAP: + handle_pap(p, length); + break; + case PPP_BAP: /* XXX: not yet completed */ + handle_bap(p, length); + break; + case ETHERTYPE_IP: /*XXX*/ + case PPP_VJNC: + case PPP_IP: + ip_print(gndo, p, length); + break; +#ifdef INET6 + case ETHERTYPE_IPV6: /*XXX*/ + case PPP_IPV6: + ip6_print(gndo, p, length); + break; +#endif + case ETHERTYPE_IPX: /*XXX*/ + case PPP_IPX: + ipx_print(p, length); + break; + case PPP_OSI: + isoclns_print(p, length, length); + break; + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); + break; + case PPP_COMP: + printf("compressed PPP data"); + break; + default: + printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); + print_unknown_data(p,"\n\t",length); + break; + } +} + +/* Standard PPP printer */ +u_int +ppp_print(register const u_char *p, u_int length) +{ + u_int proto,ppp_header; + u_int olen = length; /* _o_riginal length */ + u_int hdr_len = 0; + + /* + * Here, we assume that p points to the Address and Control + * field (if they present). + */ + if (length < 2) + goto trunc; + TCHECK2(*p, 2); + ppp_header = EXTRACT_16BITS(p); + + switch(ppp_header) { + case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL): + if (eflag) printf("In "); + p += 2; + length -= 2; + hdr_len += 2; + break; + case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL): + if (eflag) printf("Out "); + p += 2; + length -= 2; + hdr_len += 2; + break; + case (PPP_ADDRESS << 8 | PPP_CONTROL): + p += 2; /* ACFC not used */ + length -= 2; + hdr_len += 2; + break; + + default: + break; + } + + if (length < 2) + goto trunc; + TCHECK(*p); + if (*p % 2) { + proto = *p; /* PFC is used */ + p++; + length--; + hdr_len++; + } else { + TCHECK2(*p, 2); + proto = EXTRACT_16BITS(p); + p += 2; + length -= 2; + hdr_len += 2; + } + + if (eflag) + printf("%s (0x%04x), length %u: ", + tok2str(ppptype2str, "unknown", proto), + proto, + olen); + + handle_ppp(proto, p, length); + return (hdr_len); +trunc: + printf("[|ppp]"); + return (0); +} + + +/* PPP I/F printer */ +u_int +ppp_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + + if (caplen < PPP_HDRLEN) { + printf("[|ppp]"); + return (caplen); + } + +#if 0 + /* + * XXX: seems to assume that there are 2 octets prepended to an + * actual PPP frame. The 1st octet looks like Input/Output flag + * while 2nd octet is unknown, at least to me + * (mshindo@mshindo.net). + * + * That was what the original tcpdump code did. + * + * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound + * packets and 0 for inbound packets - but only if the + * protocol field has the 0x8000 bit set (i.e., it's a network + * control protocol); it does so before running the packet through + * "bpf_filter" to see if it should be discarded, and to see + * if we should update the time we sent the most recent packet... + * + * ...but it puts the original address field back after doing + * so. + * + * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion. + * + * I don't know if any PPP implementation handed up to a BPF + * device packets with the first octet being 1 for outbound and + * 0 for inbound packets, so I (guy@alum.mit.edu) don't know + * whether that ever needs to be checked or not. + * + * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP, + * and its tcpdump appears to assume that the frame always + * begins with an address field and a control field, and that + * the address field might be 0x0f or 0x8f, for Cisco + * point-to-point with HDLC framing as per section 4.3.1 of RFC + * 1547, as well as 0xff, for PPP in HDLC-like framing as per + * RFC 1662. + * + * (Is the Cisco framing in question what DLT_C_HDLC, in + * BSD/OS, is?) + */ + if (eflag) + printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]); +#endif + + ppp_print(p, length); + + return (0); +} + +/* + * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like + * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547, + * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL, + * discard them *if* those are the first two octets, and parse the remaining + * packet as a PPP packet, as "ppp_print()" does). + * + * This handles, for example, DLT_PPP_SERIAL in NetBSD. + */ +u_int +ppp_hdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + u_int proto; + u_int hdrlen = 0; + + if (caplen < 2) { + printf("[|ppp]"); + return (caplen); + } + + switch (p[0]) { + + case PPP_ADDRESS: + if (caplen < 4) { + printf("[|ppp]"); + return (caplen); + } + + if (eflag) + printf("%02x %02x %d ", p[0], p[1], length); + p += 2; + length -= 2; + hdrlen += 2; + + proto = EXTRACT_16BITS(p); + p += 2; + length -= 2; + hdrlen += 2; + printf("%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); + + handle_ppp(proto, p, length); + break; + + case CHDLC_UNICAST: + case CHDLC_BCAST: + return (chdlc_if_print(h, p)); + + default: + if (eflag) + printf("%02x %02x %d ", p[0], p[1], length); + p += 2; + length -= 2; + hdrlen += 2; + + /* + * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats + * the next two octets as an Ethernet type; does that + * ever happen? + */ + printf("unknown addr %02x; ctrl %02x", p[0], p[1]); + break; + } + + return (hdrlen); +} + +#define PPP_BSDI_HDRLEN 24 + +/* BSD/OS specific PPP printer */ +u_int +ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_) +{ + register int hdrlength; +#ifdef __bsdi__ + register u_int length = h->len; + register u_int caplen = h->caplen; + u_int16_t ptype; + const u_char *q; + int i; + + if (caplen < PPP_BSDI_HDRLEN) { + printf("[|ppp]"); + return (caplen) + } + + hdrlength = 0; + +#if 0 + if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) { + if (eflag) + printf("%02x %02x ", p[0], p[1]); + p += 2; + hdrlength = 2; + } + + if (eflag) + printf("%d ", length); + /* Retrieve the protocol type */ + if (*p & 01) { + /* Compressed protocol field */ + ptype = *p; + if (eflag) + printf("%02x ", ptype); + p++; + hdrlength += 1; + } else { + /* Un-compressed protocol field */ + ptype = EXTRACT_16BITS(p); + if (eflag) + printf("%04x ", ptype); + p += 2; + hdrlength += 2; + } +#else + ptype = 0; /*XXX*/ + if (eflag) + printf("%c ", p[SLC_DIR] ? 'O' : 'I'); + if (p[SLC_LLHL]) { + /* link level header */ + struct ppp_header *ph; + + q = p + SLC_BPFHDRLEN; + ph = (struct ppp_header *)q; + if (ph->phdr_addr == PPP_ADDRESS + && ph->phdr_ctl == PPP_CONTROL) { + if (eflag) + printf("%02x %02x ", q[0], q[1]); + ptype = EXTRACT_16BITS(&ph->phdr_type); + if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) { + printf("%s ", tok2str(ppptype2str, + "proto-#%d", ptype)); + } + } else { + if (eflag) { + printf("LLH=["); + for (i = 0; i < p[SLC_LLHL]; i++) + printf("%02x", q[i]); + printf("] "); + } + } + } + if (eflag) + printf("%d ", length); + if (p[SLC_CHL]) { + q = p + SLC_BPFHDRLEN + p[SLC_LLHL]; + + switch (ptype) { + case PPP_VJC: + ptype = vjc_print(q, ptype); + hdrlength = PPP_BSDI_HDRLEN; + p += hdrlength; + switch (ptype) { + case PPP_IP: + ip_print(gndo, p, length); + break; +#ifdef INET6 + case PPP_IPV6: + ip6_print(gndo, p, length); + break; +#endif + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); + break; + } + goto printx; + case PPP_VJNC: + ptype = vjc_print(q, ptype); + hdrlength = PPP_BSDI_HDRLEN; + p += hdrlength; + switch (ptype) { + case PPP_IP: + ip_print(gndo, p, length); + break; +#ifdef INET6 + case PPP_IPV6: + ip6_print(gndo, p, length); + break; +#endif + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); + break; + } + goto printx; + default: + if (eflag) { + printf("CH=["); + for (i = 0; i < p[SLC_LLHL]; i++) + printf("%02x", q[i]); + printf("] "); + } + break; + } + } + + hdrlength = PPP_BSDI_HDRLEN; +#endif + + length -= hdrlength; + p += hdrlength; + + switch (ptype) { + case PPP_IP: + ip_print(p, length); + break; +#ifdef INET6 + case PPP_IPV6: + ip6_print(gndo, p, length); + break; +#endif + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(gndo, p, length); + break; + default: + printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype)); + } + +printx: +#else /* __bsdi */ + hdrlength = 0; +#endif /* __bsdi__ */ + return (hdrlength); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-pppoe.c b/freebsd/contrib/tcpdump/print-pppoe.c new file mode 100644 index 00000000..af12682f --- /dev/null +++ b/freebsd/contrib/tcpdump/print-pppoe.c @@ -0,0 +1,213 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <gsstark@mit.edu> + */ + +#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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#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 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 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<p+tag_len; v++) { + printf("%02X", *v); + } + printf("]"); + } + + + } else + printf(" [%s]", tok2str(pppoetag2str, + "TAG-0x%x", tag_type)); + + p += tag_len; + /* p points to next tag */ + } + return (0); + } else { + /* PPPoE data */ + printf(" "); + return (PPPOE_HDRLEN + ppp_print(pppoe_payload, pppoe_length)); + } + +trunc: + printf("[|pppoe]"); + return (PPPOE_HDRLEN); +} diff --git a/freebsd/contrib/tcpdump/print-pptp.c b/freebsd/contrib/tcpdump/print-pptp.c new file mode 100644 index 00000000..27eb7c72 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-pptp.c @@ -0,0 +1,1062 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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. + * + * PPTP support contributed by Motonori Shindo (mshindo@mshindo.net) + */ + + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-pptp.c,v 1.12 2006-06-23 02:03:09 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "interface.h" +#include "extract.h" + +static char tstr[] = " [|pptp]"; + +#define PPTP_MSG_TYPE_CTRL 1 /* Control Message */ +#define PPTP_MSG_TYPE_MGMT 2 /* Management Message (currently not used */ +#define PPTP_MAGIC_COOKIE 0x1a2b3c4d /* for sanity check */ + +#define PPTP_CTRL_MSG_TYPE_SCCRQ 1 +#define PPTP_CTRL_MSG_TYPE_SCCRP 2 +#define PPTP_CTRL_MSG_TYPE_StopCCRQ 3 +#define PPTP_CTRL_MSG_TYPE_StopCCRP 4 +#define PPTP_CTRL_MSG_TYPE_ECHORQ 5 +#define PPTP_CTRL_MSG_TYPE_ECHORP 6 +#define PPTP_CTRL_MSG_TYPE_OCRQ 7 +#define PPTP_CTRL_MSG_TYPE_OCRP 8 +#define PPTP_CTRL_MSG_TYPE_ICRQ 9 +#define PPTP_CTRL_MSG_TYPE_ICRP 10 +#define PPTP_CTRL_MSG_TYPE_ICCN 11 +#define PPTP_CTRL_MSG_TYPE_CCRQ 12 +#define PPTP_CTRL_MSG_TYPE_CDN 13 +#define PPTP_CTRL_MSG_TYPE_WEN 14 +#define PPTP_CTRL_MSG_TYPE_SLI 15 + +#define PPTP_FRAMING_CAP_ASYNC_MASK 0x00000001 /* Aynchronous */ +#define PPTP_FRAMING_CAP_SYNC_MASK 0x00000002 /* Synchronous */ + +#define PPTP_BEARER_CAP_ANALOG_MASK 0x00000001 /* Analog */ +#define PPTP_BEARER_CAP_DIGITAL_MASK 0x00000002 /* Digital */ + +static const char *pptp_message_type_string[] = { + "NOT_DEFINED", /* 0 Not defined in the RFC2637 */ + "SCCRQ", /* 1 Start-Control-Connection-Request */ + "SCCRP", /* 2 Start-Control-Connection-Reply */ + "StopCCRQ", /* 3 Stop-Control-Connection-Request */ + "StopCCRP", /* 4 Stop-Control-Connection-Reply */ + "ECHORQ", /* 5 Echo Request */ + "ECHORP", /* 6 Echo Reply */ + + "OCRQ", /* 7 Outgoing-Call-Request */ + "OCRP", /* 8 Outgoing-Call-Reply */ + "ICRQ", /* 9 Incoming-Call-Request */ + "ICRP", /* 10 Incoming-Call-Reply */ + "ICCN", /* 11 Incoming-Call-Connected */ + "CCRQ", /* 12 Call-Clear-Request */ + "CDN", /* 13 Call-Disconnect-Notify */ + + "WEN", /* 14 WAN-Error-Notify */ + + "SLI" /* 15 Set-Link-Info */ +#define PPTP_MAX_MSGTYPE_INDEX 16 +}; + +/* common for all PPTP control messages */ +struct pptp_hdr { + u_int16_t length; + u_int16_t msg_type; + u_int32_t magic_cookie; + u_int16_t ctrl_msg_type; + u_int16_t reserved0; +}; + +struct pptp_msg_sccrq { + u_int16_t proto_ver; + u_int16_t reserved1; + u_int32_t framing_cap; + u_int32_t bearer_cap; + u_int16_t max_channel; + u_int16_t firm_rev; + u_char hostname[64]; + u_char vendor[64]; +}; + +struct pptp_msg_sccrp { + u_int16_t proto_ver; + u_int8_t result_code; + u_int8_t err_code; + u_int32_t framing_cap; + u_int32_t bearer_cap; + u_int16_t max_channel; + u_int16_t firm_rev; + u_char hostname[64]; + u_char vendor[64]; +}; + +struct pptp_msg_stopccrq { + u_int8_t reason; + u_int8_t reserved1; + u_int16_t reserved2; +}; + +struct pptp_msg_stopccrp { + u_int8_t result_code; + u_int8_t err_code; + u_int16_t reserved1; +}; + +struct pptp_msg_echorq { + u_int32_t id; +}; + +struct pptp_msg_echorp { + u_int32_t id; + u_int8_t result_code; + u_int8_t err_code; + u_int16_t reserved1; +}; + +struct pptp_msg_ocrq { + u_int16_t call_id; + u_int16_t call_ser; + u_int32_t min_bps; + u_int32_t max_bps; + u_int32_t bearer_type; + u_int32_t framing_type; + u_int16_t recv_winsiz; + u_int16_t pkt_proc_delay; + u_int16_t phone_no_len; + u_int16_t reserved1; + u_char phone_no[64]; + u_char subaddr[64]; +}; + +struct pptp_msg_ocrp { + u_int16_t call_id; + u_int16_t peer_call_id; + u_int8_t result_code; + u_int8_t err_code; + u_int16_t cause_code; + u_int32_t conn_speed; + u_int16_t recv_winsiz; + u_int16_t pkt_proc_delay; + u_int32_t phy_chan_id; +}; + +struct pptp_msg_icrq { + u_int16_t call_id; + u_int16_t call_ser; + u_int32_t bearer_type; + u_int32_t phy_chan_id; + u_int16_t dialed_no_len; + u_int16_t dialing_no_len; + u_char dialed_no[64]; /* DNIS */ + u_char dialing_no[64]; /* CLID */ + u_char subaddr[64]; +}; + +struct pptp_msg_icrp { + u_int16_t call_id; + u_int16_t peer_call_id; + u_int8_t result_code; + u_int8_t err_code; + u_int16_t recv_winsiz; + u_int16_t pkt_proc_delay; + u_int16_t reserved1; +}; + +struct pptp_msg_iccn { + u_int16_t peer_call_id; + u_int16_t reserved1; + u_int32_t conn_speed; + u_int16_t recv_winsiz; + u_int16_t pkt_proc_delay; + u_int32_t framing_type; +}; + +struct pptp_msg_ccrq { + u_int16_t call_id; + u_int16_t reserved1; +}; + +struct pptp_msg_cdn { + u_int16_t call_id; + u_int8_t result_code; + u_int8_t err_code; + u_int16_t cause_code; + u_int16_t reserved1; + u_char call_stats[128]; +}; + +struct pptp_msg_wen { + u_int16_t peer_call_id; + u_int16_t reserved1; + u_int32_t crc_err; + u_int32_t framing_err; + u_int32_t hardware_overrun; + u_int32_t buffer_overrun; + u_int32_t timeout_err; + u_int32_t align_err; +}; + +struct pptp_msg_sli { + u_int16_t peer_call_id; + u_int16_t reserved1; + u_int32_t send_accm; + u_int32_t recv_accm; +}; + +/* attributes that appear more than once in above messages: + + Number of + occurence attributes + -------------------------------------- + 2 u_int32_t bearer_cap; + 2 u_int32_t bearer_type; + 6 u_int16_t call_id; + 2 u_int16_t call_ser; + 2 u_int16_t cause_code; + 2 u_int32_t conn_speed; + 6 u_int8_t err_code; + 2 u_int16_t firm_rev; + 2 u_int32_t framing_cap; + 2 u_int32_t framing_type; + 2 u_char hostname[64]; + 2 u_int32_t id; + 2 u_int16_t max_channel; + 5 u_int16_t peer_call_id; + 2 u_int32_t phy_chan_id; + 4 u_int16_t pkt_proc_delay; + 2 u_int16_t proto_ver; + 4 u_int16_t recv_winsiz; + 2 u_int8_t reserved1; + 9 u_int16_t reserved1; + 6 u_int8_t result_code; + 2 u_char subaddr[64]; + 2 u_char vendor[64]; + + so I will prepare print out functions for these attributes (except for + reserved*). +*/ + +/******************************************/ +/* Attribute-specific print out functions */ +/******************************************/ + +/* In these attribute-specific print-out functions, it't not necessary + to do TCHECK because they are already checked in the caller of + these functions. */ + +static void +pptp_bearer_cap_print(const u_int32_t *bearer_cap) +{ + printf(" BEARER_CAP("); + if (EXTRACT_32BITS(bearer_cap) & PPTP_BEARER_CAP_DIGITAL_MASK) { + printf("D"); + } + if (EXTRACT_32BITS(bearer_cap) & PPTP_BEARER_CAP_ANALOG_MASK) { + printf("A"); + } + printf(")"); +} + +static void +pptp_bearer_type_print(const u_int32_t *bearer_type) +{ + printf(" BEARER_TYPE("); + switch (EXTRACT_32BITS(bearer_type)) { + case 1: + printf("A"); /* Analog */ + break; + case 2: + printf("D"); /* Digital */ + break; + case 3: + printf("Any"); + break; + default: + printf("?"); + break; + } + printf(")"); +} + +static void +pptp_call_id_print(const u_int16_t *call_id) +{ + printf(" CALL_ID(%u)", EXTRACT_16BITS(call_id)); +} + +static void +pptp_call_ser_print(const u_int16_t *call_ser) +{ + printf(" CALL_SER_NUM(%u)", EXTRACT_16BITS(call_ser)); +} + +static void +pptp_cause_code_print(const u_int16_t *cause_code) +{ + printf(" CAUSE_CODE(%u)", EXTRACT_16BITS(cause_code)); +} + +static void +pptp_conn_speed_print(const u_int32_t *conn_speed) +{ + printf(" CONN_SPEED(%u)", EXTRACT_32BITS(conn_speed)); +} + +static void +pptp_err_code_print(const u_int8_t *err_code) +{ + printf(" ERR_CODE(%u", *err_code); + if (vflag) { + switch (*err_code) { + case 0: + printf(":None"); + break; + case 1: + printf(":Not-Connected"); + break; + case 2: + printf(":Bad-Format"); + break; + case 3: + printf(":Bad-Valude"); + break; + case 4: + printf(":No-Resource"); + break; + case 5: + printf(":Bad-Call-ID"); + break; + case 6: + printf(":PAC-Error"); + break; + default: + printf(":?"); + break; + } + } + printf(")"); +} + +static void +pptp_firm_rev_print(const u_int16_t *firm_rev) +{ + printf(" FIRM_REV(%u)", EXTRACT_16BITS(firm_rev)); +} + +static void +pptp_framing_cap_print(const u_int32_t *framing_cap) +{ + printf(" FRAME_CAP("); + if (EXTRACT_32BITS(framing_cap) & PPTP_FRAMING_CAP_ASYNC_MASK) { + printf("A"); /* Async */ + } + if (EXTRACT_32BITS(framing_cap) & PPTP_FRAMING_CAP_SYNC_MASK) { + printf("S"); /* Sync */ + } + printf(")"); +} + +static void +pptp_framing_type_print(const u_int32_t *framing_type) +{ + printf(" FRAME_TYPE("); + switch (EXTRACT_32BITS(framing_type)) { + case 1: + printf("A"); /* Async */ + break; + case 2: + printf("S"); /* Sync */ + break; + case 3: + printf("E"); /* Either */ + break; + default: + printf("?"); + break; + } + printf(")"); +} + +static void +pptp_hostname_print(const u_char *hostname) +{ + printf(" HOSTNAME(%.64s)", hostname); +} + +static void +pptp_id_print(const u_int32_t *id) +{ + printf(" ID(%u)", EXTRACT_32BITS(id)); +} + +static void +pptp_max_channel_print(const u_int16_t *max_channel) +{ + printf(" MAX_CHAN(%u)", EXTRACT_16BITS(max_channel)); +} + +static void +pptp_peer_call_id_print(const u_int16_t *peer_call_id) +{ + printf(" PEER_CALL_ID(%u)", EXTRACT_16BITS(peer_call_id)); +} + +static void +pptp_phy_chan_id_print(const u_int32_t *phy_chan_id) +{ + printf(" PHY_CHAN_ID(%u)", EXTRACT_32BITS(phy_chan_id)); +} + +static void +pptp_pkt_proc_delay_print(const u_int16_t *pkt_proc_delay) +{ + printf(" PROC_DELAY(%u)", EXTRACT_16BITS(pkt_proc_delay)); +} + +static void +pptp_proto_ver_print(const u_int16_t *proto_ver) +{ + printf(" PROTO_VER(%u.%u)", /* Version.Revision */ + EXTRACT_16BITS(proto_ver) >> 8, + EXTRACT_16BITS(proto_ver) & 0xff); +} + +static void +pptp_recv_winsiz_print(const u_int16_t *recv_winsiz) +{ + printf(" RECV_WIN(%u)", EXTRACT_16BITS(recv_winsiz)); +} + +static void +pptp_result_code_print(const u_int8_t *result_code, int ctrl_msg_type) +{ + printf(" RESULT_CODE(%u", *result_code); + if (vflag) { + switch (ctrl_msg_type) { + case PPTP_CTRL_MSG_TYPE_SCCRP: + switch (*result_code) { + case 1: + printf(":Successful channel establishment"); + break; + case 2: + printf(":General error"); + break; + case 3: + printf(":Command channel already exists"); + break; + case 4: + printf(":Requester is not authorized to establish a command channel"); + break; + case 5: + printf(":The protocol version of the requester is not supported"); + break; + default: + printf(":?"); + break; + } + break; + case PPTP_CTRL_MSG_TYPE_StopCCRP: + case PPTP_CTRL_MSG_TYPE_ECHORP: + switch (*result_code) { + case 1: + printf(":OK"); + break; + case 2: + printf(":General Error"); + break; + default: + printf(":?"); + break; + } + break; + case PPTP_CTRL_MSG_TYPE_OCRP: + switch (*result_code) { + case 1: + printf(":Connected"); + break; + case 2: + printf(":General Error"); + break; + case 3: + printf(":No Carrier"); + break; + case 4: + printf(":Busy"); + break; + case 5: + printf(":No Dial Tone"); + break; + case 6: + printf(":Time-out"); + break; + case 7: + printf(":Do Not Accept"); + break; + default: + printf(":?"); + break; + } + break; + case PPTP_CTRL_MSG_TYPE_ICRP: + switch (*result_code) { + case 1: + printf(":Connect"); + break; + case 2: + printf(":General Error"); + break; + case 3: + printf(":Do Not Accept"); + break; + default: + printf(":?"); + break; + } + break; + case PPTP_CTRL_MSG_TYPE_CDN: + switch (*result_code) { + case 1: + printf(":Lost Carrier"); + break; + case 2: + printf(":General Error"); + break; + case 3: + printf(":Admin Shutdown"); + break; + case 4: + printf(":Request"); + default: + printf(":?"); + break; + break; + } + default: + /* assertion error */ + break; + } + } + printf(")"); +} + +static void +pptp_subaddr_print(const u_char *subaddr) +{ + printf(" SUB_ADDR(%.64s)", subaddr); +} + +static void +pptp_vendor_print(const u_char *vendor) +{ + printf(" VENDOR(%.64s)", vendor); +} + +/************************************/ +/* PPTP message print out functions */ +/************************************/ +static void +pptp_sccrq_print(const u_char *dat) +{ + struct pptp_msg_sccrq *ptr = (struct pptp_msg_sccrq *)dat; + + TCHECK(ptr->proto_ver); + pptp_proto_ver_print(&ptr->proto_ver); + TCHECK(ptr->reserved1); + TCHECK(ptr->framing_cap); + pptp_framing_cap_print(&ptr->framing_cap); + TCHECK(ptr->bearer_cap); + pptp_bearer_cap_print(&ptr->bearer_cap); + TCHECK(ptr->max_channel); + pptp_max_channel_print(&ptr->max_channel); + TCHECK(ptr->firm_rev); + pptp_firm_rev_print(&ptr->firm_rev); + TCHECK(ptr->hostname); + pptp_hostname_print(&ptr->hostname[0]); + TCHECK(ptr->vendor); + pptp_vendor_print(&ptr->vendor[0]); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_sccrp_print(const u_char *dat) +{ + struct pptp_msg_sccrp *ptr = (struct pptp_msg_sccrp *)dat; + + TCHECK(ptr->proto_ver); + pptp_proto_ver_print(&ptr->proto_ver); + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_SCCRP); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->framing_cap); + pptp_framing_cap_print(&ptr->framing_cap); + TCHECK(ptr->bearer_cap); + pptp_bearer_cap_print(&ptr->bearer_cap); + TCHECK(ptr->max_channel); + pptp_max_channel_print(&ptr->max_channel); + TCHECK(ptr->firm_rev); + pptp_firm_rev_print(&ptr->firm_rev); + TCHECK(ptr->hostname); + pptp_hostname_print(&ptr->hostname[0]); + TCHECK(ptr->vendor); + pptp_vendor_print(&ptr->vendor[0]); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_stopccrq_print(const u_char *dat) +{ + struct pptp_msg_stopccrq *ptr = (struct pptp_msg_stopccrq *)dat; + + TCHECK(ptr->reason); + printf(" REASON(%u", ptr->reason); + if (vflag) { + switch (ptr->reason) { + case 1: + printf(":None"); + break; + case 2: + printf(":Stop-Protocol"); + break; + case 3: + printf(":Stop-Local-Shutdown"); + break; + default: + printf(":?"); + break; + } + } + printf(")"); + TCHECK(ptr->reserved1); + TCHECK(ptr->reserved2); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_stopccrp_print(const u_char *dat) +{ + struct pptp_msg_stopccrp *ptr = (struct pptp_msg_stopccrp *)dat; + + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_StopCCRP); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->reserved1); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_echorq_print(const u_char *dat) +{ + struct pptp_msg_echorq *ptr = (struct pptp_msg_echorq *)dat; + + TCHECK(ptr->id); + pptp_id_print(&ptr->id); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_echorp_print(const u_char *dat) +{ + struct pptp_msg_echorp *ptr = (struct pptp_msg_echorp *)dat; + + TCHECK(ptr->id); + pptp_id_print(&ptr->id); + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_ECHORP); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->reserved1); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_ocrq_print(const u_char *dat) +{ + struct pptp_msg_ocrq *ptr = (struct pptp_msg_ocrq *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->call_ser); + pptp_call_ser_print(&ptr->call_ser); + TCHECK(ptr->min_bps); + printf(" MIN_BPS(%u)", EXTRACT_32BITS(&ptr->min_bps)); + TCHECK(ptr->max_bps); + printf(" MAX_BPS(%u)", EXTRACT_32BITS(&ptr->max_bps)); + TCHECK(ptr->bearer_type); + pptp_bearer_type_print(&ptr->bearer_type); + TCHECK(ptr->framing_type); + pptp_framing_type_print(&ptr->framing_type); + TCHECK(ptr->recv_winsiz); + pptp_recv_winsiz_print(&ptr->recv_winsiz); + TCHECK(ptr->pkt_proc_delay); + pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay); + TCHECK(ptr->phone_no_len); + printf(" PHONE_NO_LEN(%u)", EXTRACT_16BITS(&ptr->phone_no_len)); + TCHECK(ptr->reserved1); + TCHECK(ptr->phone_no); + printf(" PHONE_NO(%.64s)", ptr->phone_no); + TCHECK(ptr->subaddr); + pptp_subaddr_print(&ptr->subaddr[0]); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_ocrp_print(const u_char *dat) +{ + struct pptp_msg_ocrp *ptr = (struct pptp_msg_ocrp *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->peer_call_id); + pptp_peer_call_id_print(&ptr->peer_call_id); + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_OCRP); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->cause_code); + pptp_cause_code_print(&ptr->cause_code); + TCHECK(ptr->conn_speed); + pptp_conn_speed_print(&ptr->conn_speed); + TCHECK(ptr->recv_winsiz); + pptp_recv_winsiz_print(&ptr->recv_winsiz); + TCHECK(ptr->pkt_proc_delay); + pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay); + TCHECK(ptr->phy_chan_id); + pptp_phy_chan_id_print(&ptr->phy_chan_id); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_icrq_print(const u_char *dat) +{ + struct pptp_msg_icrq *ptr = (struct pptp_msg_icrq *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->call_ser); + pptp_call_ser_print(&ptr->call_ser); + TCHECK(ptr->bearer_type); + pptp_bearer_type_print(&ptr->bearer_type); + TCHECK(ptr->phy_chan_id); + pptp_phy_chan_id_print(&ptr->phy_chan_id); + TCHECK(ptr->dialed_no_len); + printf(" DIALED_NO_LEN(%u)", EXTRACT_16BITS(&ptr->dialed_no_len)); + TCHECK(ptr->dialing_no_len); + printf(" DIALING_NO_LEN(%u)", EXTRACT_16BITS(&ptr->dialing_no_len)); + TCHECK(ptr->dialed_no); + printf(" DIALED_NO(%.64s)", ptr->dialed_no); + TCHECK(ptr->dialing_no); + printf(" DIALING_NO(%.64s)", ptr->dialing_no); + TCHECK(ptr->subaddr); + pptp_subaddr_print(&ptr->subaddr[0]); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_icrp_print(const u_char *dat) +{ + struct pptp_msg_icrp *ptr = (struct pptp_msg_icrp *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->peer_call_id); + pptp_peer_call_id_print(&ptr->peer_call_id); + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_ICRP); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->recv_winsiz); + pptp_recv_winsiz_print(&ptr->recv_winsiz); + TCHECK(ptr->pkt_proc_delay); + pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay); + TCHECK(ptr->reserved1); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_iccn_print(const u_char *dat) +{ + struct pptp_msg_iccn *ptr = (struct pptp_msg_iccn *)dat; + + TCHECK(ptr->peer_call_id); + pptp_peer_call_id_print(&ptr->peer_call_id); + TCHECK(ptr->reserved1); + TCHECK(ptr->conn_speed); + pptp_conn_speed_print(&ptr->conn_speed); + TCHECK(ptr->recv_winsiz); + pptp_recv_winsiz_print(&ptr->recv_winsiz); + TCHECK(ptr->pkt_proc_delay); + pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay); + TCHECK(ptr->framing_type); + pptp_framing_type_print(&ptr->framing_type); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_ccrq_print(const u_char *dat) +{ + struct pptp_msg_ccrq *ptr = (struct pptp_msg_ccrq *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->reserved1); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_cdn_print(const u_char *dat) +{ + struct pptp_msg_cdn *ptr = (struct pptp_msg_cdn *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_CDN); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->cause_code); + pptp_cause_code_print(&ptr->cause_code); + TCHECK(ptr->reserved1); + TCHECK(ptr->call_stats); + printf(" CALL_STATS(%.128s)", ptr->call_stats); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_wen_print(const u_char *dat) +{ + struct pptp_msg_wen *ptr = (struct pptp_msg_wen *)dat; + + TCHECK(ptr->peer_call_id); + pptp_peer_call_id_print(&ptr->peer_call_id); + TCHECK(ptr->reserved1); + TCHECK(ptr->crc_err); + printf(" CRC_ERR(%u)", EXTRACT_32BITS(&ptr->crc_err)); + TCHECK(ptr->framing_err); + printf(" FRAMING_ERR(%u)", EXTRACT_32BITS(&ptr->framing_err)); + TCHECK(ptr->hardware_overrun); + printf(" HARDWARE_OVERRUN(%u)", EXTRACT_32BITS(&ptr->hardware_overrun)); + TCHECK(ptr->buffer_overrun); + printf(" BUFFER_OVERRUN(%u)", EXTRACT_32BITS(&ptr->buffer_overrun)); + TCHECK(ptr->timeout_err); + printf(" TIMEOUT_ERR(%u)", EXTRACT_32BITS(&ptr->timeout_err)); + TCHECK(ptr->align_err); + printf(" ALIGN_ERR(%u)", EXTRACT_32BITS(&ptr->align_err)); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_sli_print(const u_char *dat) +{ + struct pptp_msg_sli *ptr = (struct pptp_msg_sli *)dat; + + TCHECK(ptr->peer_call_id); + pptp_peer_call_id_print(&ptr->peer_call_id); + TCHECK(ptr->reserved1); + TCHECK(ptr->send_accm); + printf(" SEND_ACCM(0x%08x)", EXTRACT_32BITS(&ptr->send_accm)); + TCHECK(ptr->recv_accm); + printf(" RECV_ACCM(0x%08x)", EXTRACT_32BITS(&ptr->recv_accm)); + + return; + +trunc: + printf("%s", tstr); +} + +void +pptp_print(const u_char *dat) +{ + const struct pptp_hdr *hdr; + u_int32_t mc; + u_int16_t ctrl_msg_type; + + printf(": pptp"); + + hdr = (struct pptp_hdr *)dat; + + TCHECK(hdr->length); + if (vflag) { + printf(" Length=%u", EXTRACT_16BITS(&hdr->length)); + } + TCHECK(hdr->msg_type); + if (vflag) { + switch(EXTRACT_16BITS(&hdr->msg_type)) { + case PPTP_MSG_TYPE_CTRL: + printf(" CTRL-MSG"); + break; + case PPTP_MSG_TYPE_MGMT: + printf(" MGMT-MSG"); + break; + default: + printf(" UNKNOWN-MSG-TYPE"); + break; + } + } + + TCHECK(hdr->magic_cookie); + mc = EXTRACT_32BITS(&hdr->magic_cookie); + if (mc != PPTP_MAGIC_COOKIE) { + printf(" UNEXPECTED Magic-Cookie!!(%08x)", mc); + } + if (vflag || mc != PPTP_MAGIC_COOKIE) { + printf(" Magic-Cookie=%08x", mc); + } + TCHECK(hdr->ctrl_msg_type); + ctrl_msg_type = EXTRACT_16BITS(&hdr->ctrl_msg_type); + if (ctrl_msg_type < PPTP_MAX_MSGTYPE_INDEX) { + printf(" CTRL_MSGTYPE=%s", + pptp_message_type_string[ctrl_msg_type]); + } else { + printf(" UNKNOWN_CTRL_MSGTYPE(%u)", ctrl_msg_type); + } + TCHECK(hdr->reserved0); + + dat += 12; + + switch(ctrl_msg_type) { + case PPTP_CTRL_MSG_TYPE_SCCRQ: + pptp_sccrq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_SCCRP: + pptp_sccrp_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_StopCCRQ: + pptp_stopccrq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_StopCCRP: + pptp_stopccrp_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_ECHORQ: + pptp_echorq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_ECHORP: + pptp_echorp_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_OCRQ: + pptp_ocrq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_OCRP: + pptp_ocrp_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_ICRQ: + pptp_icrq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_ICRP: + pptp_icrp_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_ICCN: + pptp_iccn_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_CCRQ: + pptp_ccrq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_CDN: + pptp_cdn_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_WEN: + pptp_wen_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_SLI: + pptp_sli_print(dat); + break; + default: + /* do nothing */ + break; + } + + return; + +trunc: + printf("%s", tstr); +} diff --git a/freebsd/contrib/tcpdump/print-radius.c b/freebsd/contrib/tcpdump/print-radius.c new file mode 100644 index 00000000..3ae0a4b1 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-radius.c @@ -0,0 +1,939 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <string.h> + +#include <stdio.h> + +#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 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]"); +} diff --git a/freebsd/contrib/tcpdump/print-raw.c b/freebsd/contrib/tcpdump/print-raw.c new file mode 100644 index 00000000..ec257de6 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-raw.c @@ -0,0 +1,55 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-raw.c,v 1.41 2003-11-16 09:36:34 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> +#include <string.h> + +#include "addrtoname.h" +#include "interface.h" + +/* + * The DLT_RAW packet has no header. It contains a raw IP packet. + */ + +u_int +raw_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + if (eflag) + printf("ip: "); + + ipN_print(p, h->len); + + return (0); +} diff --git a/freebsd/contrib/tcpdump/print-rip.c b/freebsd/contrib/tcpdump/print-rip.c new file mode 100644 index 00000000..8d6aced0 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-rip.c @@ -0,0 +1,274 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1989, 1990, 1991, 1993, 1994, 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-rip.c,v 1.59 2006-03-23 14:58:44 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#include "af.h" + +struct rip { + u_int8_t rip_cmd; /* request/response */ + u_int8_t rip_vers; /* protocol version # */ + u_int8_t unused[2]; /* unused */ +}; + +#define RIPCMD_REQUEST 1 /* want info */ +#define RIPCMD_RESPONSE 2 /* responding to request */ +#define RIPCMD_TRACEON 3 /* turn tracing on */ +#define RIPCMD_TRACEOFF 4 /* turn it off */ +#define RIPCMD_POLL 5 /* want info from everybody */ +#define RIPCMD_POLLENTRY 6 /* poll for entry */ + +static const struct tok rip_cmd_values[] = { + { RIPCMD_REQUEST, "Request" }, + { RIPCMD_RESPONSE, "Response" }, + { RIPCMD_TRACEON, "Trace on" }, + { RIPCMD_TRACEOFF, "Trace off" }, + { RIPCMD_POLL, "Poll" }, + { RIPCMD_POLLENTRY, "Poll Entry" }, + { 0, NULL} +}; + +#define RIP_AUTHLEN 16 +#define RIP_ROUTELEN 20 + +/* + * rfc 1723 + * + * 0 1 2 3 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Command (1) | Version (1) | unused | + * +---------------+---------------+-------------------------------+ + * | Address Family Identifier (2) | Route Tag (2) | + * +-------------------------------+-------------------------------+ + * | IP Address (4) | + * +---------------------------------------------------------------+ + * | Subnet Mask (4) | + * +---------------------------------------------------------------+ + * | Next Hop (4) | + * +---------------------------------------------------------------+ + * | Metric (4) | + * +---------------------------------------------------------------+ + * + */ + +struct rip_netinfo { + u_int16_t rip_family; + u_int16_t rip_tag; + u_int32_t rip_dest; + u_int32_t rip_dest_mask; + u_int32_t rip_router; + u_int32_t rip_metric; /* cost of route */ +}; + +static void +rip_entry_print_v1(register const struct rip_netinfo *ni) +{ + register u_short family; + + /* RFC 1058 */ + family = EXTRACT_16BITS(&ni->rip_family); + if (family != BSD_AFNUM_INET && family != 0) { + printf("\n\t AFI %s, ", tok2str(bsd_af_values, "Unknown (%u)", family)); + print_unknown_data((u_int8_t *)&ni->rip_family,"\n\t ",RIP_ROUTELEN); + return; + } + if (EXTRACT_16BITS(&ni->rip_tag) || + EXTRACT_32BITS(&ni->rip_dest_mask) || + EXTRACT_32BITS(&ni->rip_router)) { + /* MBZ fields not zero */ + print_unknown_data((u_int8_t *)&ni->rip_family,"\n\t ",RIP_ROUTELEN); + return; + } + if (family == 0) { + printf("\n\t AFI 0, %s, metric: %u", + ipaddr_string(&ni->rip_dest), + EXTRACT_32BITS(&ni->rip_metric)); + return; + } /* BSD_AFNUM_INET */ + printf("\n\t %s, metric: %u", + ipaddr_string(&ni->rip_dest), + EXTRACT_32BITS(&ni->rip_metric)); +} + +static unsigned +rip_entry_print_v2(register const struct rip_netinfo *ni, const unsigned remaining) +{ + register u_short family; + + family = EXTRACT_16BITS(&ni->rip_family); + if (family == 0xFFFF) { /* variable-sized authentication structures */ + u_int16_t auth_type = EXTRACT_16BITS(&ni->rip_tag); + if (auth_type == 2) { + register u_char *p = (u_char *)&ni->rip_dest; + u_int i = 0; + printf("\n\t Simple Text Authentication data: "); + for (; i < RIP_AUTHLEN; p++, i++) + putchar (isprint(*p) ? *p : '.'); + } else if (auth_type == 3) { + printf("\n\t Auth header:"); + printf(" Packet Len %u,", EXTRACT_16BITS((u_int8_t *)ni + 4)); + printf(" Key-ID %u,", *((u_int8_t *)ni + 6)); + printf(" Auth Data Len %u,", *((u_int8_t *)ni + 7)); + printf(" SeqNo %u,", EXTRACT_32BITS(&ni->rip_dest_mask)); + printf(" MBZ %u,", EXTRACT_32BITS(&ni->rip_router)); + printf(" MBZ %u", EXTRACT_32BITS(&ni->rip_metric)); + } else if (auth_type == 1) { + printf("\n\t Auth trailer:"); + print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t ",remaining); + return remaining; /* AT spans till the packet end */ + } else { + printf("\n\t Unknown (%u) Authentication data:", + EXTRACT_16BITS(&ni->rip_tag)); + print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t ",remaining); + } + } else if (family != BSD_AFNUM_INET && family != 0) { + printf("\n\t AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family)); + print_unknown_data((u_int8_t *)&ni->rip_tag,"\n\t ",RIP_ROUTELEN-2); + } else { /* BSD_AFNUM_INET or AFI 0 */ + printf("\n\t AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ", + tok2str(bsd_af_values, "%u", family), + ipaddr_string(&ni->rip_dest), + mask2plen(EXTRACT_32BITS(&ni->rip_dest_mask)), + EXTRACT_16BITS(&ni->rip_tag), + EXTRACT_32BITS(&ni->rip_metric)); + if (EXTRACT_32BITS(&ni->rip_router)) + printf("%s", ipaddr_string(&ni->rip_router)); + else + printf("self"); + } + return sizeof (*ni); +} + +void +rip_print(const u_char *dat, u_int length) +{ + register const struct rip *rp; + register const struct rip_netinfo *ni; + register u_int i, j; + + if (snapend < dat) { + printf(" [|rip]"); + return; + } + i = snapend - dat; + if (i > length) + i = length; + if (i < sizeof(*rp)) { + printf(" [|rip]"); + return; + } + i -= sizeof(*rp); + + rp = (struct rip *)dat; + + printf("%sRIPv%u", + (vflag >= 1) ? "\n\t" : "", + rp->rip_vers); + + switch (rp->rip_vers) { + case 0: + /* + * RFC 1058. + * + * XXX - RFC 1058 says + * + * 0 Datagrams whose version number is zero are to be ignored. + * These are from a previous version of the protocol, whose + * packet format was machine-specific. + * + * so perhaps we should just dump the packet, in hex. + */ + print_unknown_data((u_int8_t *)&rp->rip_cmd,"\n\t",length); + break; + default: + /* dump version and lets see if we know the commands name*/ + printf(", %s, length: %u", + tok2str(rip_cmd_values, + "unknown command (%u)", + rp->rip_cmd), + length); + + if (vflag < 1) + return; + + switch (rp->rip_cmd) { + case RIPCMD_REQUEST: + case RIPCMD_RESPONSE: + j = length / sizeof(*ni); + printf(", routes: %u%s", j, rp->rip_vers == 2 ? " or less" : ""); + ni = (struct rip_netinfo *)(rp + 1); + for (; i >= sizeof(*ni); ++ni) { + if (rp->rip_vers == 1) + { + rip_entry_print_v1(ni); + i -= sizeof(*ni); + } + else if (rp->rip_vers == 2) + i -= rip_entry_print_v2(ni, i); + else + break; + } + if (i) + printf("[|rip]"); + break; + + case RIPCMD_TRACEOFF: + case RIPCMD_POLL: + case RIPCMD_POLLENTRY: + break; + + case RIPCMD_TRACEON: + /* fall through */ + default: + if (vflag <= 1) { + if(!print_unknown_data((u_int8_t *)rp,"\n\t",length)) + return; + } + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag> 1) { + if(!print_unknown_data((u_int8_t *)rp,"\n\t",length)) + return; + } + } +} + + diff --git a/freebsd/contrib/tcpdump/print-ripng.c b/freebsd/contrib/tcpdump/print-ripng.c new file mode 100644 index 00000000..7ce8e977 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-ripng.c @@ -0,0 +1,130 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> +#include <stdio.h> + +#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 */ diff --git a/freebsd/contrib/tcpdump/print-rpki-rtr.c b/freebsd/contrib/tcpdump/print-rpki-rtr.c new file mode 100644 index 00000000..42c3ac1b --- /dev/null +++ b/freebsd/contrib/tcpdump/print-rpki-rtr.c @@ -0,0 +1,370 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1998-2011 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 The RPKI/Router Protocol as RFC6810 + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-rpki_rtr.c,v 1.10 2008-03-20 09:30:56 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * RPKI/Router PDU header + * + * Here's what the PDU header looks like. + * The length does include the version and length fields. + */ +typedef struct rpki_rtr_pdu_ { + u_char version; /* Version number */ + u_char pdu_type; /* PDU type */ + union { + u_char session_id[2]; /* Session id */ + u_char error_code[2]; /* Error code */ + } u; + u_char length[4]; +} rpki_rtr_pdu; +#define RPKI_RTR_PDU_OVERHEAD (offsetof(rpki_rtr_pdu, rpki_rtr_pdu_msg)) + +/* + * IPv4 Prefix PDU. + */ +typedef struct rpki_rtr_pdu_ipv4_prefix_ { + rpki_rtr_pdu pdu_header; + u_char flags; + u_char prefix_length; + u_char max_length; + u_char zero; + u_char prefix[4]; + u_char as[4]; +} rpki_rtr_pdu_ipv4_prefix; + +/* + * IPv6 Prefix PDU. + */ +typedef struct rpki_rtr_pdu_ipv6_prefix_ { + rpki_rtr_pdu pdu_header; + u_char flags; + u_char prefix_length; + u_char max_length; + u_char zero; + u_char prefix[16]; + u_char as[4]; +} rpki_rtr_pdu_ipv6_prefix; + +/* + * Error report PDU. + */ +typedef struct rpki_rtr_pdu_error_report_ { + rpki_rtr_pdu pdu_header; + u_char encapsulated_pdu_length[4]; /* Encapsulated PDU length */ +} rpki_rtr_pdu_error_report; + +/* + * PDU type codes + */ +#define RPKI_RTR_SERIAL_NOTIFY_PDU 0 +#define RPKI_RTR_SERIAL_QUERY_PDU 1 +#define RPKI_RTR_RESET_QUERY_PDU 2 +#define RPKI_RTR_CACHE_RESPONSE_PDU 3 +#define RPKI_RTR_IPV4_PREFIX_PDU 4 +#define RPKI_RTR_IPV6_PREFIX_PDU 6 +#define RPKI_RTR_END_OF_DATA_PDU 7 +#define RPKI_RTR_CACHE_RESET_PDU 8 +#define RPKI_RTR_ERROR_REPORT_PDU 10 + +static const struct tok rpki_rtr_pdu_values[] = { + { RPKI_RTR_SERIAL_NOTIFY_PDU, "Serial Notify" }, + { RPKI_RTR_SERIAL_QUERY_PDU, "Serial Query" }, + { RPKI_RTR_RESET_QUERY_PDU, "Reset Query" }, + { RPKI_RTR_CACHE_RESPONSE_PDU, "Cache Response" }, + { RPKI_RTR_IPV4_PREFIX_PDU, "IPV4 Prefix" }, + { RPKI_RTR_IPV6_PREFIX_PDU, "IPV6 Prefix" }, + { RPKI_RTR_END_OF_DATA_PDU, "End of Data" }, + { RPKI_RTR_CACHE_RESET_PDU, "Cache Reset" }, + { RPKI_RTR_ERROR_REPORT_PDU, "Error Report" }, + { 0, NULL} +}; + +static const struct tok rpki_rtr_error_codes[] = { + { 0, "Corrupt Data" }, + { 1, "Internal Error" }, + { 2, "No Data Available" }, + { 3, "Invalid Request" }, + { 4, "Unsupported Protocol Version" }, + { 5, "Unsupported PDU Type" }, + { 6, "Withdrawal of Unknown Record" }, + { 7, "Duplicate Announcement Received" }, + { 0, NULL} +}; + +/* + * Build a identation string for a given identation level. + * XXX this should be really in util.c + */ +static char * +indent_string (u_int indent) +{ + static char buf[20]; + u_int idx; + + idx = 0; + buf[idx] = '\0'; + + /* + * Does the static buffer fit ? + */ + if (sizeof(buf) < ((indent/8) + (indent %8) + 2)) { + return buf; + } + + /* + * Heading newline. + */ + buf[idx] = '\n'; + idx++; + + while (indent >= 8) { + buf[idx] = '\t'; + idx++; + indent -= 8; + } + + while (indent > 0) { + buf[idx] = ' '; + idx++; + indent--; + } + + /* + * Trailing zero. + */ + buf[idx] = '\0'; + + return buf; +} + +/* + * Print a single PDU. + */ +static void +rpki_rtr_pdu_print (const u_char *tptr, u_int indent) +{ + const rpki_rtr_pdu *pdu_header; + u_int pdu_type, pdu_len, hexdump; + const u_char *msg; + + pdu_header = (rpki_rtr_pdu *)tptr; + pdu_type = pdu_header->pdu_type; + pdu_len = EXTRACT_32BITS(pdu_header->length); + hexdump = FALSE; + + printf("%sRPKI-RTRv%u, %s PDU (%u), length: %u", + indent_string(8), + pdu_header->version, + tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type), + pdu_type, pdu_len); + + switch (pdu_type) { + + /* + * The following PDUs share the message format. + */ + case RPKI_RTR_SERIAL_NOTIFY_PDU: + case RPKI_RTR_SERIAL_QUERY_PDU: + case RPKI_RTR_END_OF_DATA_PDU: + msg = (const u_char *)(pdu_header + 1); + printf("%sSession ID: 0x%04x, Serial: %u", + indent_string(indent+2), + EXTRACT_16BITS(pdu_header->u.session_id), + EXTRACT_32BITS(msg)); + break; + + /* + * The following PDUs share the message format. + */ + case RPKI_RTR_RESET_QUERY_PDU: + case RPKI_RTR_CACHE_RESET_PDU: + + /* + * Zero payload PDUs. + */ + break; + + case RPKI_RTR_CACHE_RESPONSE_PDU: + printf("%sSession ID: 0x%04x", + indent_string(indent+2), + EXTRACT_16BITS(pdu_header->u.session_id)); + break; + + case RPKI_RTR_IPV4_PREFIX_PDU: + { + rpki_rtr_pdu_ipv4_prefix *pdu; + + pdu = (rpki_rtr_pdu_ipv4_prefix *)tptr; + printf("%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", + indent_string(indent+2), + ipaddr_string(pdu->prefix), + pdu->prefix_length, pdu->max_length, + EXTRACT_32BITS(pdu->as), pdu->flags); + } + break; + +#ifdef INET6 + case RPKI_RTR_IPV6_PREFIX_PDU: + { + rpki_rtr_pdu_ipv6_prefix *pdu; + + pdu = (rpki_rtr_pdu_ipv6_prefix *)tptr; + printf("%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x", + indent_string(indent+2), + ip6addr_string(pdu->prefix), + pdu->prefix_length, pdu->max_length, + EXTRACT_32BITS(pdu->as), pdu->flags); + } + break; +#endif + + case RPKI_RTR_ERROR_REPORT_PDU: + { + rpki_rtr_pdu_error_report *pdu; + u_int encapsulated_pdu_length, text_length, tlen, error_code; + u_char buf[80]; + + pdu = (rpki_rtr_pdu_error_report *)tptr; + encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length); + tlen = pdu_len; + + error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code); + printf("%sError code: %s (%u), Encapsulated PDU length: %u", + indent_string(indent+2), + tok2str(rpki_rtr_error_codes, "Unknown", error_code), + error_code, encapsulated_pdu_length); + + tptr += sizeof(*pdu); + tlen -= sizeof(*pdu); + + /* + * Recurse if there is an encapsulated PDU. + */ + if (encapsulated_pdu_length && + (encapsulated_pdu_length <= tlen)) { + printf("%s-----encapsulated PDU-----", indent_string(indent+4)); + rpki_rtr_pdu_print(tptr, indent+2); + } + + tptr += encapsulated_pdu_length; + tlen -= encapsulated_pdu_length; + + /* + * Extract, trail-zero and print the Error message. + */ + text_length = 0; + if (tlen > 4) { + text_length = EXTRACT_32BITS(tptr); + tptr += 4; + tlen -= 4; + } + if (text_length && (text_length <= tlen )) { + memcpy(buf, tptr, MIN(sizeof(buf)-1, text_length)); + buf[text_length] = '\0'; + printf("%sError text: %s", indent_string(indent+2), buf); + } + } + break; + + default: + + /* + * Unknown data, please hexdump. + */ + hexdump = TRUE; + } + + /* do we also want to see a hex dump ? */ + if (vflag > 1 || (vflag && hexdump)) { + print_unknown_data(tptr,"\n\t ", pdu_len); + } +} + +void +rpki_rtr_print(register const u_char *pptr, register u_int len) { + + u_int tlen, pdu_type, pdu_len; + const u_char *tptr; + const rpki_rtr_pdu *pdu_header; + + tptr = pptr; + tlen = len; + + if (!vflag) { + printf(", RPKI-RTR"); + return; + } + + while (tlen >= sizeof(rpki_rtr_pdu)) { + + TCHECK2(*tptr, sizeof(rpki_rtr_pdu)); + + pdu_header = (rpki_rtr_pdu *)tptr; + pdu_type = pdu_header->pdu_type; + pdu_len = EXTRACT_32BITS(pdu_header->length); + + /* infinite loop check */ + if (!pdu_type || !pdu_len) { + break; + } + + TCHECK2(*tptr, pdu_len); + if (tlen < pdu_len) { + goto trunc; + } + + /* + * Print the PDU. + */ + rpki_rtr_pdu_print(tptr, 8); + + tlen -= pdu_len; + tptr += pdu_len; + } + return; + trunc: + printf("\n\t[|RPKI-RTR]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-rrcp.c b/freebsd/contrib/tcpdump/print-rrcp.c new file mode 100644 index 00000000..57ed68ef --- /dev/null +++ b/freebsd/contrib/tcpdump/print-rrcp.c @@ -0,0 +1,145 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2007 - Andrey "nording" Chernyak <andrew@nording.ru> + * + * 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 Realtek Remote Control Protocol (RRCP) + * and Realtek Echo Protocol (RRCP-REP) packets. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-rrcp.c,v 1.2 2008-04-11 17:21:34 gianluca Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "netdissect.h" +#include "addrtoname.h" +#include "extract.h" +#include "ether.h" + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif + +#define RRCP_OPCODE_MASK 0x7F /* 0x00 = hello, 0x01 = get, 0x02 = set */ +#define RRCP_ISREPLY 0x80 /* 0 = request to switch, 0x80 = reply from switch */ + +#define RRCP_PROTO_OFFSET 0 /* proto - 1 byte, must be 1 */ +#define RRCP_OPCODE_ISREPLY_OFFSET 1 /* opcode and isreply flag - 1 byte */ +#define RRCP_AUTHKEY_OFFSET 2 /* authorization key - 2 bytes, 0x2379 by default */ + +/* most packets */ +#define RRCP_REG_ADDR_OFFSET 4 /* register address - 2 bytes */ +#define RRCP_REG_DATA_OFFSET 6 /* register data - 4 bytes */ +#define RRCP_COOKIE1_OFFSET 10 /* 4 bytes */ +#define RRCP_COOKIE2_OFFSET 14 /* 4 bytes */ + +/* hello reply packets */ +#define RRCP_DOWNLINK_PORT_OFFSET 4 /* 1 byte */ +#define RRCP_UPLINK_PORT_OFFSET 5 /* 1 byte */ +#define RRCP_UPLINK_MAC_OFFSET 6 /* 6 byte MAC address */ +#define RRCP_CHIP_ID_OFFSET 12 /* 2 bytes */ +#define RRCP_VENDOR_ID_OFFSET 14 /* 4 bytes */ + +static const struct tok proto_values[] = { + { 1, "RRCP" }, + { 2, "RRCP-REP" }, + { 0, NULL } +}; + +static const struct tok opcode_values[] = { + { 0, "hello" }, + { 1, "get" }, + { 2, "set" }, + { 0, NULL } +}; + +/* + * Print RRCP requests + */ +void +rrcp_print(netdissect_options *ndo, + register const u_char *cp, + u_int length _U_) +{ + const u_char *rrcp; + u_int8_t rrcp_proto; + u_int8_t rrcp_opcode; + register const struct ether_header *ep; + char proto_str[16]; + char opcode_str[32]; + + ep = (const struct ether_header *)cp; + rrcp = cp + ETHER_HDRLEN; + + ND_TCHECK(*(rrcp + RRCP_PROTO_OFFSET)); + rrcp_proto = *(rrcp + RRCP_PROTO_OFFSET); + ND_TCHECK(*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)); + rrcp_opcode = (*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; + ND_PRINT((ndo, "%s > %s, %s %s", + etheraddr_string(ESRC(ep)), + etheraddr_string(EDST(ep)), + tok2strbuf(proto_values,"RRCP-0x%02x",rrcp_proto,proto_str,sizeof(proto_str)), + ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query")); + if (rrcp_proto==1){ + ND_PRINT((ndo, ": %s", + tok2strbuf(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode,opcode_str,sizeof(opcode_str)))); + } + if (rrcp_opcode==1 || rrcp_opcode==2){ + ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6); + ND_PRINT((ndo, " addr=0x%04x, data=0x%08x", + EXTRACT_LE_16BITS(rrcp + RRCP_REG_ADDR_OFFSET), + EXTRACT_LE_32BITS(rrcp + RRCP_REG_DATA_OFFSET))); + } + if (rrcp_proto==1){ + ND_TCHECK2(*(rrcp + RRCP_AUTHKEY_OFFSET), 2); + ND_PRINT((ndo, ", auth=0x%04x", + EXTRACT_16BITS(rrcp + RRCP_AUTHKEY_OFFSET))); + } + if (rrcp_proto==1 && rrcp_opcode==0 && + ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ + ND_TCHECK2(*(rrcp + RRCP_VENDOR_ID_OFFSET), 4); + ND_PRINT((ndo, " downlink_port=%d, uplink_port=%d, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", + *(rrcp + RRCP_DOWNLINK_PORT_OFFSET), + *(rrcp + RRCP_UPLINK_PORT_OFFSET), + etheraddr_string(rrcp + RRCP_UPLINK_MAC_OFFSET), + EXTRACT_32BITS(rrcp + RRCP_VENDOR_ID_OFFSET), + EXTRACT_16BITS(rrcp + RRCP_CHIP_ID_OFFSET))); + }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){ + ND_TCHECK2(*(rrcp + RRCP_COOKIE2_OFFSET), 4); + ND_PRINT((ndo, ", cookie=0x%08x%08x ", + EXTRACT_32BITS(rrcp + RRCP_COOKIE2_OFFSET), + EXTRACT_32BITS(rrcp + RRCP_COOKIE1_OFFSET))); + } + if (!ndo->ndo_vflag) + return; + return; + +trunc: + ND_PRINT((ndo, "[|rrcp]")); +} diff --git a/freebsd/contrib/tcpdump/print-rsvp.c b/freebsd/contrib/tcpdump/print-rsvp.c new file mode 100644 index 00000000..009ef0c5 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-rsvp.c @@ -0,0 +1,1946 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-rsvp.c,v 1.50 2008-08-16 11:36:20 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "gmpls.h" +#include "af.h" +#include "signature.h" + +/* + * RFC 2205 common header + * + * 0 1 2 3 + * +-------------+-------------+-------------+-------------+ + * | Vers | Flags| Msg Type | RSVP Checksum | + * +-------------+-------------+-------------+-------------+ + * | Send_TTL | (Reserved) | RSVP Length | + * +-------------+-------------+-------------+-------------+ + * + */ + +struct rsvp_common_header { + u_int8_t version_flags; + u_int8_t msg_type; + u_int8_t checksum[2]; + u_int8_t ttl; + u_int8_t reserved; + u_int8_t length[2]; +}; + +/* + * RFC2205 object header + * + * + * 0 1 2 3 + * +-------------+-------------+-------------+-------------+ + * | Length (bytes) | Class-Num | C-Type | + * +-------------+-------------+-------------+-------------+ + * | | + * // (Object contents) // + * | | + * +-------------+-------------+-------------+-------------+ + */ + +struct rsvp_object_header { + u_int8_t length[2]; + u_int8_t class_num; + u_int8_t ctype; +}; + +#define RSVP_VERSION 1 +#define RSVP_EXTRACT_VERSION(x) (((x)&0xf0)>>4) +#define RSVP_EXTRACT_FLAGS(x) ((x)&0x0f) + +#define RSVP_MSGTYPE_PATH 1 +#define RSVP_MSGTYPE_RESV 2 +#define RSVP_MSGTYPE_PATHERR 3 +#define RSVP_MSGTYPE_RESVERR 4 +#define RSVP_MSGTYPE_PATHTEAR 5 +#define RSVP_MSGTYPE_RESVTEAR 6 +#define RSVP_MSGTYPE_RESVCONF 7 +#define RSVP_MSGTYPE_AGGREGATE 12 +#define RSVP_MSGTYPE_ACK 13 +#define RSVP_MSGTYPE_HELLO_OLD 14 /* ancient Hellos */ +#define RSVP_MSGTYPE_SREFRESH 15 +#define RSVP_MSGTYPE_HELLO 20 + +static const struct tok rsvp_msg_type_values[] = { + { RSVP_MSGTYPE_PATH, "Path" }, + { RSVP_MSGTYPE_RESV, "Resv" }, + { RSVP_MSGTYPE_PATHERR, "PathErr" }, + { RSVP_MSGTYPE_RESVERR, "ResvErr" }, + { RSVP_MSGTYPE_PATHTEAR, "PathTear" }, + { RSVP_MSGTYPE_RESVTEAR, "ResvTear" }, + { RSVP_MSGTYPE_RESVCONF, "ResvConf" }, + { RSVP_MSGTYPE_AGGREGATE, "Aggregate" }, + { RSVP_MSGTYPE_ACK, "Acknowledgement" }, + { RSVP_MSGTYPE_HELLO_OLD, "Hello (Old)" }, + { RSVP_MSGTYPE_SREFRESH, "Refresh" }, + { RSVP_MSGTYPE_HELLO, "Hello" }, + { 0, NULL} +}; + +static const struct tok rsvp_header_flag_values[] = { + { 0x01, "Refresh reduction capable" }, /* rfc2961 */ + { 0, NULL} +}; + +#define RSVP_OBJ_SESSION 1 /* rfc2205 */ +#define RSVP_OBJ_RSVP_HOP 3 /* rfc2205, rfc3473 */ +#define RSVP_OBJ_INTEGRITY 4 /* rfc2747 */ +#define RSVP_OBJ_TIME_VALUES 5 /* rfc2205 */ +#define RSVP_OBJ_ERROR_SPEC 6 +#define RSVP_OBJ_SCOPE 7 +#define RSVP_OBJ_STYLE 8 /* rfc2205 */ +#define RSVP_OBJ_FLOWSPEC 9 /* rfc2215 */ +#define RSVP_OBJ_FILTERSPEC 10 /* rfc2215 */ +#define RSVP_OBJ_SENDER_TEMPLATE 11 +#define RSVP_OBJ_SENDER_TSPEC 12 /* rfc2215 */ +#define RSVP_OBJ_ADSPEC 13 /* rfc2215 */ +#define RSVP_OBJ_POLICY_DATA 14 +#define RSVP_OBJ_CONFIRM 15 /* rfc2205 */ +#define RSVP_OBJ_LABEL 16 /* rfc3209 */ +#define RSVP_OBJ_LABEL_REQ 19 /* rfc3209 */ +#define RSVP_OBJ_ERO 20 /* rfc3209 */ +#define RSVP_OBJ_RRO 21 /* rfc3209 */ +#define RSVP_OBJ_HELLO 22 /* rfc3209 */ +#define RSVP_OBJ_MESSAGE_ID 23 /* rfc2961 */ +#define RSVP_OBJ_MESSAGE_ID_ACK 24 /* rfc2961 */ +#define RSVP_OBJ_MESSAGE_ID_LIST 25 /* rfc2961 */ +#define RSVP_OBJ_RECOVERY_LABEL 34 /* rfc3473 */ +#define RSVP_OBJ_UPSTREAM_LABEL 35 /* rfc3473 */ +#define RSVP_OBJ_LABEL_SET 36 /* rfc3473 */ +#define RSVP_OBJ_PROTECTION 37 /* rfc3473 */ +#define RSVP_OBJ_S2L 50 /* rfc4875 */ +#define RSVP_OBJ_DETOUR 63 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */ +#define RSVP_OBJ_CLASSTYPE 66 /* rfc4124 */ +#define RSVP_OBJ_CLASSTYPE_OLD 125 /* draft-ietf-tewg-diff-te-proto-07 */ +#define RSVP_OBJ_SUGGESTED_LABEL 129 /* rfc3473 */ +#define RSVP_OBJ_ACCEPT_LABEL_SET 130 /* rfc3473 */ +#define RSVP_OBJ_RESTART_CAPABILITY 131 /* rfc3473 */ +#define RSVP_OBJ_NOTIFY_REQ 195 /* rfc3473 */ +#define RSVP_OBJ_ADMIN_STATUS 196 /* rfc3473 */ +#define RSVP_OBJ_PROPERTIES 204 /* juniper proprietary */ +#define RSVP_OBJ_FASTREROUTE 205 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */ +#define RSVP_OBJ_SESSION_ATTRIBUTE 207 /* rfc3209 */ +#define RSVP_OBJ_GENERALIZED_UNI 229 /* OIF RSVP extensions UNI 1.0 Signaling, Rel. 2 */ +#define RSVP_OBJ_CALL_ID 230 /* rfc3474 */ +#define RSVP_OBJ_CALL_OPS 236 /* rfc3474 */ + +static const struct tok rsvp_obj_values[] = { + { RSVP_OBJ_SESSION, "Session" }, + { RSVP_OBJ_RSVP_HOP, "RSVP Hop" }, + { RSVP_OBJ_INTEGRITY, "Integrity" }, + { RSVP_OBJ_TIME_VALUES, "Time Values" }, + { RSVP_OBJ_ERROR_SPEC, "Error Spec" }, + { RSVP_OBJ_SCOPE, "Scope" }, + { RSVP_OBJ_STYLE, "Style" }, + { RSVP_OBJ_FLOWSPEC, "Flowspec" }, + { RSVP_OBJ_FILTERSPEC, "FilterSpec" }, + { RSVP_OBJ_SENDER_TEMPLATE, "Sender Template" }, + { RSVP_OBJ_SENDER_TSPEC, "Sender TSpec" }, + { RSVP_OBJ_ADSPEC, "Adspec" }, + { RSVP_OBJ_POLICY_DATA, "Policy Data" }, + { RSVP_OBJ_CONFIRM, "Confirm" }, + { RSVP_OBJ_LABEL, "Label" }, + { RSVP_OBJ_LABEL_REQ, "Label Request" }, + { RSVP_OBJ_ERO, "ERO" }, + { RSVP_OBJ_RRO, "RRO" }, + { RSVP_OBJ_HELLO, "Hello" }, + { RSVP_OBJ_MESSAGE_ID, "Message ID" }, + { RSVP_OBJ_MESSAGE_ID_ACK, "Message ID Ack" }, + { RSVP_OBJ_MESSAGE_ID_LIST, "Message ID List" }, + { RSVP_OBJ_RECOVERY_LABEL, "Recovery Label" }, + { RSVP_OBJ_UPSTREAM_LABEL, "Upstream Label" }, + { RSVP_OBJ_LABEL_SET, "Label Set" }, + { RSVP_OBJ_ACCEPT_LABEL_SET, "Acceptable Label Set" }, + { RSVP_OBJ_DETOUR, "Detour" }, + { RSVP_OBJ_CLASSTYPE, "Class Type" }, + { RSVP_OBJ_CLASSTYPE_OLD, "Class Type (old)" }, + { RSVP_OBJ_SUGGESTED_LABEL, "Suggested Label" }, + { RSVP_OBJ_PROPERTIES, "Properties" }, + { RSVP_OBJ_FASTREROUTE, "Fast Re-Route" }, + { RSVP_OBJ_SESSION_ATTRIBUTE, "Session Attribute" }, + { RSVP_OBJ_GENERALIZED_UNI, "Generalized UNI" }, + { RSVP_OBJ_CALL_ID, "Call-ID" }, + { RSVP_OBJ_CALL_OPS, "Call Capability" }, + { RSVP_OBJ_RESTART_CAPABILITY, "Restart Capability" }, + { RSVP_OBJ_NOTIFY_REQ, "Notify Request" }, + { RSVP_OBJ_PROTECTION, "Protection" }, + { RSVP_OBJ_ADMIN_STATUS, "Administrative Status" }, + { RSVP_OBJ_S2L, "Sub-LSP to LSP" }, + { 0, NULL} +}; + +#define RSVP_CTYPE_IPV4 1 +#define RSVP_CTYPE_IPV6 2 +#define RSVP_CTYPE_TUNNEL_IPV4 7 +#define RSVP_CTYPE_TUNNEL_IPV6 8 +#define RSVP_CTYPE_UNI_IPV4 11 /* OIF RSVP extensions UNI 1.0 Signaling Rel. 2 */ +#define RSVP_CTYPE_1 1 +#define RSVP_CTYPE_2 2 +#define RSVP_CTYPE_3 3 +#define RSVP_CTYPE_4 4 +#define RSVP_CTYPE_12 12 +#define RSVP_CTYPE_13 13 +#define RSVP_CTYPE_14 14 + +/* + * the ctypes are not globally unique so for + * translating it to strings we build a table based + * on objects offsetted by the ctype + */ + +static const struct tok rsvp_ctype_values[] = { + { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_3, "IPv4 plus opt. TLVs" }, + { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_4, "IPv6 plus opt. TLVs" }, + { 256*RSVP_OBJ_NOTIFY_REQ+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_NOTIFY_REQ+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_CONFIRM+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_CONFIRM+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_TIME_VALUES+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_FLOWSPEC+RSVP_CTYPE_1, "obsolete" }, + { 256*RSVP_OBJ_FLOWSPEC+RSVP_CTYPE_2, "IntServ" }, + { 256*RSVP_OBJ_SENDER_TSPEC+RSVP_CTYPE_2, "IntServ" }, + { 256*RSVP_OBJ_ADSPEC+RSVP_CTYPE_2, "IntServ" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_3, "IPv6 Flow-label" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_12, "IPv4 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_13, "IPv6 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_UNI_IPV4, "UNI IPv4" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_13, "IPv4 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_14, "IPv6 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_12, "IPv4 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_13, "IPv6 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_MESSAGE_ID+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_1, "Message id ack" }, + { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_2, "Message id nack" }, + { 256*RSVP_OBJ_MESSAGE_ID_LIST+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_STYLE+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_HELLO+RSVP_CTYPE_1, "Hello Request" }, + { 256*RSVP_OBJ_HELLO+RSVP_CTYPE_2, "Hello Ack" }, + { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_1, "without label range" }, + { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_2, "with ATM label range" }, + { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_3, "with FR label range" }, + { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_4, "Generalized Label" }, + { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_1, "Label" }, + { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_2, "Generalized Label" }, + { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, + { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_1, "Label" }, + { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_2, "Generalized Label" }, + { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, + { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_1, "Label" }, + { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_2, "Generalized Label" }, + { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, + { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_1, "Label" }, + { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_2, "Generalized Label" }, + { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, + { 256*RSVP_OBJ_ERO+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_RRO+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_3, "IPv4 plus opt. TLVs" }, + { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_4, "IPv6 plus opt. TLVs" }, + { 256*RSVP_OBJ_RESTART_CAPABILITY+RSVP_CTYPE_1, "IPv4" }, + { 256*RSVP_OBJ_SESSION_ATTRIBUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, /* old style*/ + { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_1, "1" }, /* new style */ + { 256*RSVP_OBJ_DETOUR+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_PROPERTIES+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_ADMIN_STATUS+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_CLASSTYPE+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_CLASSTYPE_OLD+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_LABEL_SET+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_GENERALIZED_UNI+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV4, "IPv4 sub-LSP" }, + { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV6, "IPv6 sub-LSP" }, + { 0, NULL} +}; + +struct rsvp_obj_integrity_t { + u_int8_t flags; + u_int8_t res; + u_int8_t key_id[6]; + u_int8_t sequence[8]; + u_int8_t digest[16]; +}; + +static const struct tok rsvp_obj_integrity_flag_values[] = { + { 0x80, "Handshake" }, + { 0, NULL} +}; + +struct rsvp_obj_frr_t { + u_int8_t setup_prio; + u_int8_t hold_prio; + u_int8_t hop_limit; + u_int8_t flags; + u_int8_t bandwidth[4]; + u_int8_t include_any[4]; + u_int8_t exclude_any[4]; + u_int8_t include_all[4]; +}; + + +#define RSVP_OBJ_XRO_MASK_SUBOBJ(x) ((x)&0x7f) +#define RSVP_OBJ_XRO_MASK_LOOSE(x) ((x)&0x80) + +#define RSVP_OBJ_XRO_RES 0 +#define RSVP_OBJ_XRO_IPV4 1 +#define RSVP_OBJ_XRO_IPV6 2 +#define RSVP_OBJ_XRO_LABEL 3 +#define RSVP_OBJ_XRO_ASN 32 +#define RSVP_OBJ_XRO_MPLS 64 + +static const struct tok rsvp_obj_xro_values[] = { + { RSVP_OBJ_XRO_RES, "Reserved" }, + { RSVP_OBJ_XRO_IPV4, "IPv4 prefix" }, + { RSVP_OBJ_XRO_IPV6, "IPv6 prefix" }, + { RSVP_OBJ_XRO_LABEL, "Label" }, + { RSVP_OBJ_XRO_ASN, "Autonomous system number" }, + { RSVP_OBJ_XRO_MPLS, "MPLS label switched path termination" }, + { 0, NULL} +}; + +/* draft-ietf-mpls-rsvp-lsp-fastreroute-07.txt */ +static const struct tok rsvp_obj_rro_flag_values[] = { + { 0x01, "Local protection available" }, + { 0x02, "Local protection in use" }, + { 0x04, "Bandwidth protection" }, + { 0x08, "Node protection" }, + { 0, NULL} +}; + +/* RFC3209 */ +static const struct tok rsvp_obj_rro_label_flag_values[] = { + { 0x01, "Global" }, + { 0, NULL} +}; + +static const struct tok rsvp_resstyle_values[] = { + { 17, "Wildcard Filter" }, + { 10, "Fixed Filter" }, + { 18, "Shared Explicit" }, + { 0, NULL} +}; + +#define RSVP_OBJ_INTSERV_GUARANTEED_SERV 2 +#define RSVP_OBJ_INTSERV_CONTROLLED_LOAD 5 + +static const struct tok rsvp_intserv_service_type_values[] = { + { 1, "Default/Global Information" }, + { RSVP_OBJ_INTSERV_GUARANTEED_SERV, "Guaranteed Service" }, + { RSVP_OBJ_INTSERV_CONTROLLED_LOAD, "Controlled Load" }, + { 0, NULL} +}; + +static const struct tok rsvp_intserv_parameter_id_values[] = { + { 4, "IS hop cnt" }, + { 6, "Path b/w estimate" }, + { 8, "Minimum path latency" }, + { 10, "Composed MTU" }, + { 127, "Token Bucket TSpec" }, + { 130, "Guaranteed Service RSpec" }, + { 133, "End-to-end composed value for C" }, + { 134, "End-to-end composed value for D" }, + { 135, "Since-last-reshaping point composed C" }, + { 136, "Since-last-reshaping point composed D" }, + { 0, NULL} +}; + +static struct tok rsvp_session_attribute_flag_values[] = { + { 0x01, "Local Protection" }, + { 0x02, "Label Recording" }, + { 0x04, "SE Style" }, + { 0x08, "Bandwidth protection" }, /* RFC4090 */ + { 0x10, "Node protection" }, /* RFC4090 */ + { 0, NULL} +}; + +static struct tok rsvp_obj_prop_tlv_values[] = { + { 0x01, "Cos" }, + { 0x02, "Metric 1" }, + { 0x04, "Metric 2" }, + { 0x08, "CCC Status" }, + { 0x10, "Path Type" }, + { 0, NULL} +}; + +#define RSVP_OBJ_ERROR_SPEC_CODE_ROUTING 24 +#define RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY 25 +#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE 28 +#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD 125 + +static struct tok rsvp_obj_error_code_values[] = { + { RSVP_OBJ_ERROR_SPEC_CODE_ROUTING, "Routing Problem" }, + { RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY, "Notify Error" }, + { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE, "Diffserv TE Error" }, + { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD, "Diffserv TE Error (Old)" }, + { 0, NULL} +}; + +static struct tok rsvp_obj_error_code_routing_values[] = { + { 1, "Bad EXPLICIT_ROUTE object" }, + { 2, "Bad strict node" }, + { 3, "Bad loose node" }, + { 4, "Bad initial subobject" }, + { 5, "No route available toward destination" }, + { 6, "Unacceptable label value" }, + { 7, "RRO indicated routing loops" }, + { 8, "non-RSVP-capable router in the path" }, + { 9, "MPLS label allocation failure" }, + { 10, "Unsupported L3PID" }, + { 0, NULL} +}; + +static struct tok rsvp_obj_error_code_diffserv_te_values[] = { + { 1, "Unexpected CT object" }, + { 2, "Unsupported CT" }, + { 3, "Invalid CT value" }, + { 4, "CT/setup priority do not form a configured TE-Class" }, + { 5, "CT/holding priority do not form a configured TE-Class" }, + { 6, "CT/setup priority and CT/holding priority do not form a configured TE-Class" }, + { 7, "Inconsistency between signaled PSC and signaled CT" }, + { 8, "Inconsistency between signaled PHBs and signaled CT" }, + { 0, NULL} +}; + +/* rfc3473 / rfc 3471 */ +static const struct tok rsvp_obj_admin_status_flag_values[] = { + { 0x80000000, "Reflect" }, + { 0x00000004, "Testing" }, + { 0x00000002, "Admin-down" }, + { 0x00000001, "Delete-in-progress" }, + { 0, NULL} +}; + +/* label set actions - rfc3471 */ +#define LABEL_SET_INCLUSIVE_LIST 0 +#define LABEL_SET_EXCLUSIVE_LIST 1 +#define LABEL_SET_INCLUSIVE_RANGE 2 +#define LABEL_SET_EXCLUSIVE_RANGE 3 + +static const struct tok rsvp_obj_label_set_action_values[] = { + { LABEL_SET_INCLUSIVE_LIST, "Inclusive list" }, + { LABEL_SET_EXCLUSIVE_LIST, "Exclusive list" }, + { LABEL_SET_INCLUSIVE_RANGE, "Inclusive range" }, + { LABEL_SET_EXCLUSIVE_RANGE, "Exclusive range" }, + { 0, NULL} +}; + +/* OIF RSVP extensions UNI 1.0 Signaling, release 2 */ +#define RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS 1 +#define RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS 2 +#define RSVP_GEN_UNI_SUBOBJ_DIVERSITY 3 +#define RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL 4 +#define RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL 5 + +static const struct tok rsvp_obj_generalized_uni_values[] = { + { RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS, "Source TNA address" }, + { RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS, "Destination TNA address" }, + { RSVP_GEN_UNI_SUBOBJ_DIVERSITY, "Diversity" }, + { RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL, "Egress label" }, + { RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL, "Service level" }, + { 0, NULL} +}; + +static int rsvp_intserv_print(const u_char *, u_short); + +/* + * this is a dissector for all the intserv defined + * specs as defined per rfc2215 + * it is called from various rsvp objects; + * returns the amount of bytes being processed + */ +static int +rsvp_intserv_print(const u_char *tptr, u_short obj_tlen) { + + int parameter_id,parameter_length; + union { + float f; + u_int32_t i; + } bw; + + if (obj_tlen < 4) + return 0; + parameter_id = *(tptr); + parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */ + + printf("\n\t Parameter ID: %s (%u), length: %u, Flags: [0x%02x]", + tok2str(rsvp_intserv_parameter_id_values,"unknown",parameter_id), + parameter_id, + parameter_length, + *(tptr+1)); + + if (obj_tlen < parameter_length+4) + return 0; + switch(parameter_id) { /* parameter_id */ + + case 4: + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 4 (e) | (f) | 1 (g) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IS hop cnt (32-bit unsigned integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (parameter_length == 4) + printf("\n\t\tIS hop count: %u", EXTRACT_32BITS(tptr+4)); + break; + + case 6: + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 6 (h) | (i) | 1 (j) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Path b/w estimate (32-bit IEEE floating point number) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (parameter_length == 4) { + bw.i = EXTRACT_32BITS(tptr+4); + printf("\n\t\tPath b/w estimate: %.10g Mbps", bw.f/125000); + } + break; + + case 8: + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 8 (k) | (l) | 1 (m) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Minimum path latency (32-bit integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (parameter_length == 4) { + printf("\n\t\tMinimum path latency: "); + if (EXTRACT_32BITS(tptr+4) == 0xffffffff) + printf("don't care"); + else + printf("%u", EXTRACT_32BITS(tptr+4)); + } + break; + + case 10: + + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 10 (n) | (o) | 1 (p) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Composed MTU (32-bit unsigned integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (parameter_length == 4) + printf("\n\t\tComposed MTU: %u bytes", EXTRACT_32BITS(tptr+4)); + break; + case 127: + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 127 (e) | 0 (f) | 5 (g) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Token Bucket Rate [r] (32-bit IEEE floating point number) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Token Bucket Size [b] (32-bit IEEE floating point number) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Peak Data Rate [p] (32-bit IEEE floating point number) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Minimum Policed Unit [m] (32-bit integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Maximum Packet Size [M] (32-bit integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + if (parameter_length == 20) { + bw.i = EXTRACT_32BITS(tptr+4); + printf("\n\t\tToken Bucket Rate: %.10g Mbps", bw.f/125000); + bw.i = EXTRACT_32BITS(tptr+8); + printf("\n\t\tToken Bucket Size: %.10g bytes", bw.f); + bw.i = EXTRACT_32BITS(tptr+12); + printf("\n\t\tPeak Data Rate: %.10g Mbps", bw.f/125000); + printf("\n\t\tMinimum Policed Unit: %u bytes", EXTRACT_32BITS(tptr+16)); + printf("\n\t\tMaximum Packet Size: %u bytes", EXTRACT_32BITS(tptr+20)); + } + break; + + case 130: + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 130 (h) | 0 (i) | 2 (j) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Rate [R] (32-bit IEEE floating point number) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Slack Term [S] (32-bit integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + if (parameter_length == 8) { + bw.i = EXTRACT_32BITS(tptr+4); + printf("\n\t\tRate: %.10g Mbps", bw.f/125000); + printf("\n\t\tSlack Term: %u", EXTRACT_32BITS(tptr+8)); + } + break; + + case 133: + case 134: + case 135: + case 136: + if (parameter_length == 4) + printf("\n\t\tValue: %u", EXTRACT_32BITS(tptr+4)); + break; + + default: + if (vflag <= 1) + print_unknown_data(tptr+4,"\n\t\t",parameter_length); + } + return (parameter_length+4); /* header length 4 bytes */ +} + +static int +rsvp_obj_print (const u_char *pptr +#ifndef HAVE_LIBCRYPTO +_U_ +#endif +, u_int plen +#ifndef HAVE_LIBCRYPTO +_U_ +#endif +, const u_char *tptr, + const char *ident, u_int tlen) { + + const struct rsvp_object_header *rsvp_obj_header; + const u_char *obj_tptr; + union { + const struct rsvp_obj_integrity_t *rsvp_obj_integrity; + const struct rsvp_obj_frr_t *rsvp_obj_frr; + } obj_ptr; + + u_short rsvp_obj_len,rsvp_obj_ctype,obj_tlen,intserv_serv_tlen; + int hexdump,processed,padbytes,error_code,error_value,i,sigcheck; + union { + float f; + u_int32_t i; + } bw; + u_int8_t namelen; + + u_int action, subchannel; + + while(tlen>=sizeof(struct rsvp_object_header)) { + /* did we capture enough for fully decoding the object header ? */ + if (!TTEST2(*tptr, sizeof(struct rsvp_object_header))) + goto trunc; + + rsvp_obj_header = (const struct rsvp_object_header *)tptr; + rsvp_obj_len=EXTRACT_16BITS(rsvp_obj_header->length); + rsvp_obj_ctype=rsvp_obj_header->ctype; + + if(rsvp_obj_len % 4) { + printf("%sERROR: object header size %u not a multiple of 4", ident, rsvp_obj_len); + return -1; + } + if(rsvp_obj_len < sizeof(struct rsvp_object_header)) { + printf("%sERROR: object header too short %u < %lu", ident, rsvp_obj_len, + (unsigned long)sizeof(const struct rsvp_object_header)); + return -1; + } + + printf("%s%s Object (%u) Flags: [%s", + ident, + tok2str(rsvp_obj_values, + "Unknown", + rsvp_obj_header->class_num), + rsvp_obj_header->class_num, + ((rsvp_obj_header->class_num)&0x80) ? "ignore" : "reject"); + + if (rsvp_obj_header->class_num > 128) + printf(" %s", + ((rsvp_obj_header->class_num)&0x40) ? "and forward" : "silently"); + + printf(" if unknown], Class-Type: %s (%u), length: %u", + tok2str(rsvp_ctype_values, + "Unknown", + ((rsvp_obj_header->class_num)<<8)+rsvp_obj_ctype), + rsvp_obj_ctype, + rsvp_obj_len); + + if(tlen < rsvp_obj_len) { + printf("%sERROR: object goes past end of objects TLV", ident); + return -1; + } + + obj_tptr=tptr+sizeof(struct rsvp_object_header); + obj_tlen=rsvp_obj_len-sizeof(struct rsvp_object_header); + + /* did we capture enough for fully decoding the object ? */ + if (!TTEST2(*tptr, rsvp_obj_len)) + return -1; + hexdump=FALSE; + + switch(rsvp_obj_header->class_num) { + case RSVP_OBJ_SESSION: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < 8) + return -1; + printf("%s IPv4 DestAddress: %s, Protocol ID: 0x%02x", + ident, + ipaddr_string(obj_tptr), + *(obj_tptr+sizeof(struct in_addr))); + printf("%s Flags: [0x%02x], DestPort %u", + ident, + *(obj_tptr+5), + EXTRACT_16BITS(obj_tptr+6)); + obj_tlen-=8; + obj_tptr+=8; + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < 20) + return -1; + printf("%s IPv6 DestAddress: %s, Protocol ID: 0x%02x", + ident, + ip6addr_string(obj_tptr), + *(obj_tptr+sizeof(struct in6_addr))); + printf("%s Flags: [0x%02x], DestPort %u", + ident, + *(obj_tptr+sizeof(struct in6_addr)+1), + EXTRACT_16BITS(obj_tptr+sizeof(struct in6_addr)+2)); + obj_tlen-=20; + obj_tptr+=20; + break; + + case RSVP_CTYPE_TUNNEL_IPV6: + if (obj_tlen < 36) + return -1; + printf("%s IPv6 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18), + ip6addr_string(obj_tptr+20)); + obj_tlen-=36; + obj_tptr+=36; + break; + + case RSVP_CTYPE_14: /* IPv6 p2mp LSP Tunnel */ + if (obj_tlen < 26) + return -1; + printf("%s IPv6 P2MP LSP ID: 0x%08x, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + ident, + EXTRACT_32BITS(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ip6addr_string(obj_tptr+8)); + obj_tlen-=26; + obj_tptr+=26; + break; +#endif + case RSVP_CTYPE_13: /* IPv4 p2mp LSP Tunnel */ + if (obj_tlen < 12) + return -1; + printf("%s IPv4 P2MP LSP ID: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ipaddr_string(obj_tptr+8)); + obj_tlen-=12; + obj_tptr+=12; + break; + case RSVP_CTYPE_TUNNEL_IPV4: + case RSVP_CTYPE_UNI_IPV4: + if (obj_tlen < 12) + return -1; + printf("%s IPv4 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ipaddr_string(obj_tptr+8)); + obj_tlen-=12; + obj_tptr+=12; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_CONFIRM: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < sizeof(struct in_addr)) + return -1; + printf("%s IPv4 Receiver Address: %s", + ident, + ipaddr_string(obj_tptr)); + obj_tlen-=sizeof(struct in_addr); + obj_tptr+=sizeof(struct in_addr); + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < sizeof(struct in6_addr)) + return -1; + printf("%s IPv6 Receiver Address: %s", + ident, + ip6addr_string(obj_tptr)); + obj_tlen-=sizeof(struct in6_addr); + obj_tptr+=sizeof(struct in6_addr); + break; +#endif + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_NOTIFY_REQ: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < sizeof(struct in_addr)) + return -1; + printf("%s IPv4 Notify Node Address: %s", + ident, + ipaddr_string(obj_tptr)); + obj_tlen-=sizeof(struct in_addr); + obj_tptr+=sizeof(struct in_addr); + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < sizeof(struct in6_addr)) + return-1; + printf("%s IPv6 Notify Node Address: %s", + ident, + ip6addr_string(obj_tptr)); + obj_tlen-=sizeof(struct in6_addr); + obj_tptr+=sizeof(struct in6_addr); + break; +#endif + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_SUGGESTED_LABEL: /* fall through */ + case RSVP_OBJ_UPSTREAM_LABEL: /* fall through */ + case RSVP_OBJ_RECOVERY_LABEL: /* fall through */ + case RSVP_OBJ_LABEL: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + while(obj_tlen >= 4 ) { + printf("%s Label: %u", ident, EXTRACT_32BITS(obj_tptr)); + obj_tlen-=4; + obj_tptr+=4; + } + break; + case RSVP_CTYPE_2: + if (obj_tlen < 4) + return-1; + printf("%s Generalized Label: %u", + ident, + EXTRACT_32BITS(obj_tptr)); + obj_tlen-=4; + obj_tptr+=4; + break; + case RSVP_CTYPE_3: + if (obj_tlen < 12) + return-1; + printf("%s Waveband ID: %u%s Start Label: %u, Stop Label: %u", + ident, + EXTRACT_32BITS(obj_tptr), + ident, + EXTRACT_32BITS(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+8)); + obj_tlen-=12; + obj_tptr+=12; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_STYLE: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + return-1; + printf("%s Reservation Style: %s, Flags: [0x%02x]", + ident, + tok2str(rsvp_resstyle_values, + "Unknown", + EXTRACT_24BITS(obj_tptr+1)), + *(obj_tptr)); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_SENDER_TEMPLATE: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < 8) + return-1; + printf("%s Source Address: %s, Source Port: %u", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6)); + obj_tlen-=8; + obj_tptr+=8; + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < 20) + return-1; + printf("%s Source Address: %s, Source Port: %u", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18)); + obj_tlen-=20; + obj_tptr+=20; + break; + case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ + if (obj_tlen < 40) + return-1; + printf("%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18), + ident, + ip6addr_string(obj_tptr+20), + EXTRACT_16BITS(obj_tptr+38)); + obj_tlen-=40; + obj_tptr+=40; + break; +#endif + case RSVP_CTYPE_TUNNEL_IPV4: + if (obj_tlen < 8) + return-1; + printf("%s IPv4 Tunnel Sender Address: %s, LSP-ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6)); + obj_tlen-=8; + obj_tptr+=8; + break; + case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ + if (obj_tlen < 16) + return-1; + printf("%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ident, + ipaddr_string(obj_tptr+8), + EXTRACT_16BITS(obj_tptr+12)); + obj_tlen-=16; + obj_tptr+=16; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_LABEL_REQ: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + while(obj_tlen >= 4 ) { + printf("%s L3 Protocol ID: %s", + ident, + tok2str(ethertype_values, + "Unknown Protocol (0x%04x)", + EXTRACT_16BITS(obj_tptr+2))); + obj_tlen-=4; + obj_tptr+=4; + } + break; + case RSVP_CTYPE_2: + if (obj_tlen < 12) + return-1; + printf("%s L3 Protocol ID: %s", + ident, + tok2str(ethertype_values, + "Unknown Protocol (0x%04x)", + EXTRACT_16BITS(obj_tptr+2))); + printf(",%s merge capability",((*(obj_tptr+4))&0x80) ? "no" : "" ); + printf("%s Minimum VPI/VCI: %u/%u", + ident, + (EXTRACT_16BITS(obj_tptr+4))&0xfff, + (EXTRACT_16BITS(obj_tptr+6))&0xfff); + printf("%s Maximum VPI/VCI: %u/%u", + ident, + (EXTRACT_16BITS(obj_tptr+8))&0xfff, + (EXTRACT_16BITS(obj_tptr+10))&0xfff); + obj_tlen-=12; + obj_tptr+=12; + break; + case RSVP_CTYPE_3: + if (obj_tlen < 12) + return-1; + printf("%s L3 Protocol ID: %s", + ident, + tok2str(ethertype_values, + "Unknown Protocol (0x%04x)", + EXTRACT_16BITS(obj_tptr+2))); + printf("%s Minimum/Maximum DLCI: %u/%u, %s%s bit DLCI", + ident, + (EXTRACT_32BITS(obj_tptr+4))&0x7fffff, + (EXTRACT_32BITS(obj_tptr+8))&0x7fffff, + (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 0 ) ? "10" : "", + (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 2 ) ? "23" : ""); + obj_tlen-=12; + obj_tptr+=12; + break; + case RSVP_CTYPE_4: + if (obj_tlen < 4) + return-1; + printf("%s LSP Encoding Type: %s (%u)", + ident, + tok2str(gmpls_encoding_values, + "Unknown", + *obj_tptr), + *obj_tptr); + printf("%s Switching Type: %s (%u), Payload ID: %s (0x%04x)", + ident, + tok2str(gmpls_switch_cap_values, + "Unknown", + *(obj_tptr+1)), + *(obj_tptr+1), + tok2str(gmpls_payload_values, + "Unknown", + EXTRACT_16BITS(obj_tptr+2)), + EXTRACT_16BITS(obj_tptr+2)); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_RRO: + case RSVP_OBJ_ERO: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + while(obj_tlen >= 4 ) { + printf("%s Subobject Type: %s, length %u", + ident, + tok2str(rsvp_obj_xro_values, + "Unknown %u", + RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)), + *(obj_tptr+1)); + + if (*(obj_tptr+1) == 0) { /* prevent infinite loops */ + printf("%s ERROR: zero length ERO subtype",ident); + break; + } + + switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) { + case RSVP_OBJ_XRO_IPV4: + printf(", %s, %s/%u, Flags: [%s]", + RSVP_OBJ_XRO_MASK_LOOSE(*obj_tptr) ? "Loose" : "Strict", + ipaddr_string(obj_tptr+2), + *(obj_tptr+6), + bittok2str(rsvp_obj_rro_flag_values, + "none", + *(obj_tptr+7))); /* rfc3209 says that this field is rsvd. */ + break; + case RSVP_OBJ_XRO_LABEL: + printf(", Flags: [%s] (%#x), Class-Type: %s (%u), %u", + bittok2str(rsvp_obj_rro_label_flag_values, + "none", + *(obj_tptr+2)), + *(obj_tptr+2), + tok2str(rsvp_ctype_values, + "Unknown", + *(obj_tptr+3) + 256*RSVP_OBJ_RRO), + *(obj_tptr+3), + EXTRACT_32BITS(obj_tptr+4)); + } + obj_tlen-=*(obj_tptr+1); + obj_tptr+=*(obj_tptr+1); + } + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_HELLO: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + case RSVP_CTYPE_2: + if (obj_tlen < 8) + return-1; + printf("%s Source Instance: 0x%08x, Destination Instance: 0x%08x", + ident, + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr+4)); + obj_tlen-=8; + obj_tptr+=8; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_RESTART_CAPABILITY: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 8) + return-1; + printf("%s Restart Time: %ums, Recovery Time: %ums", + ident, + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr+4)); + obj_tlen-=8; + obj_tptr+=8; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_SESSION_ATTRIBUTE: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_TUNNEL_IPV4: + if (obj_tlen < 4) + return-1; + namelen = *(obj_tptr+3); + if (obj_tlen < 4+namelen) + return-1; + printf("%s Session Name: ", ident); + for (i = 0; i < namelen; i++) + safeputchar(*(obj_tptr+4+i)); + printf("%s Setup Priority: %u, Holding Priority: %u, Flags: [%s] (%#x)", + ident, + (int)*obj_tptr, + (int)*(obj_tptr+1), + bittok2str(rsvp_session_attribute_flag_values, + "none", + *(obj_tptr+2)), + *(obj_tptr+2)); + obj_tlen-=4+*(obj_tptr+3); + obj_tptr+=4+*(obj_tptr+3); + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_GENERALIZED_UNI: + switch(rsvp_obj_ctype) { + int subobj_type,af,subobj_len,total_subobj_len; + + case RSVP_CTYPE_1: + + if (obj_tlen < 4) + return-1; + + /* read variable length subobjects */ + total_subobj_len = obj_tlen; + while(total_subobj_len > 0) { + subobj_len = EXTRACT_16BITS(obj_tptr); + subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8; + af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF; + + printf("%s Subobject Type: %s (%u), AF: %s (%u), length: %u", + ident, + tok2str(rsvp_obj_generalized_uni_values, "Unknown", subobj_type), + subobj_type, + tok2str(af_values, "Unknown", af), af, + subobj_len); + + switch(subobj_type) { + case RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS: + case RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS: + + switch(af) { + case AFNUM_INET: + if (subobj_len < 8) + return -1; + printf("%s UNI IPv4 TNA address: %s", + ident, ipaddr_string(obj_tptr+4)); + break; +#ifdef INET6 + case AFNUM_INET6: + if (subobj_len < 20) + return -1; + printf("%s UNI IPv6 TNA address: %s", + ident, ip6addr_string(obj_tptr+4)); + break; +#endif + case AFNUM_NSAP: + if (subobj_len) { + /* unless we have a TLV parser lets just hexdump */ + hexdump=TRUE; + } + break; + } + break; + + case RSVP_GEN_UNI_SUBOBJ_DIVERSITY: + if (subobj_len) { + /* unless we have a TLV parser lets just hexdump */ + hexdump=TRUE; + } + break; + + case RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL: + if (subobj_len < 16) { + return -1; + } + + printf("%s U-bit: %x, Label type: %u, Logical port id: %u, Label: %u", + ident, + ((EXTRACT_32BITS(obj_tptr+4))>>31), + ((EXTRACT_32BITS(obj_tptr+4))&0xFF), + EXTRACT_32BITS(obj_tptr+8), + EXTRACT_32BITS(obj_tptr+12)); + break; + + case RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL: + if (subobj_len < 8) { + return -1; + } + + printf("%s Service level: %u", + ident, (EXTRACT_32BITS(obj_tptr+4))>>24); + break; + + default: + hexdump=TRUE; + break; + } + total_subobj_len-=subobj_len; + obj_tptr+=subobj_len; + obj_tlen+=subobj_len; + } + + if (total_subobj_len) { + /* unless we have a TLV parser lets just hexdump */ + hexdump=TRUE; + } + break; + + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_RSVP_HOP: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */ + case RSVP_CTYPE_IPV4: + if (obj_tlen < 8) + return-1; + printf("%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_32BITS(obj_tptr+4)); + obj_tlen-=8; + obj_tptr+=8; + if (obj_tlen) + hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ + break; +#ifdef INET6 + case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ + case RSVP_CTYPE_IPV6: + if (obj_tlen < 20) + return-1; + printf("%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", + ident, + ip6addr_string(obj_tptr), + EXTRACT_32BITS(obj_tptr+16)); + obj_tlen-=20; + obj_tptr+=20; + hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ + break; +#endif + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_TIME_VALUES: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + return-1; + printf("%s Refresh Period: %ums", + ident, + EXTRACT_32BITS(obj_tptr)); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + + /* those three objects do share the same semantics */ + case RSVP_OBJ_SENDER_TSPEC: + case RSVP_OBJ_ADSPEC: + case RSVP_OBJ_FLOWSPEC: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_2: + if (obj_tlen < 4) + return-1; + printf("%s Msg-Version: %u, length: %u", + ident, + (*obj_tptr & 0xf0) >> 4, + EXTRACT_16BITS(obj_tptr+2)<<2); + obj_tptr+=4; /* get to the start of the service header */ + obj_tlen-=4; + + while (obj_tlen >= 4) { + intserv_serv_tlen=EXTRACT_16BITS(obj_tptr+2)<<2; + printf("%s Service Type: %s (%u), break bit %s set, Service length: %u", + ident, + tok2str(rsvp_intserv_service_type_values,"unknown",*(obj_tptr)), + *(obj_tptr), + (*(obj_tptr+1)&0x80) ? "" : "not", + intserv_serv_tlen); + + obj_tptr+=4; /* get to the start of the parameter list */ + obj_tlen-=4; + + while (intserv_serv_tlen>=4) { + processed = rsvp_intserv_print(obj_tptr, obj_tlen); + if (processed == 0) + break; + obj_tlen-=processed; + intserv_serv_tlen-=processed; + obj_tptr+=processed; + } + } + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_FILTERSPEC: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < 8) + return-1; + printf("%s Source Address: %s, Source Port: %u", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6)); + obj_tlen-=8; + obj_tptr+=8; + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < 20) + return-1; + printf("%s Source Address: %s, Source Port: %u", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18)); + obj_tlen-=20; + obj_tptr+=20; + break; + case RSVP_CTYPE_3: + if (obj_tlen < 20) + return-1; + printf("%s Source Address: %s, Flow Label: %u", + ident, + ip6addr_string(obj_tptr), + EXTRACT_24BITS(obj_tptr+17)); + obj_tlen-=20; + obj_tptr+=20; + break; + case RSVP_CTYPE_TUNNEL_IPV6: + if (obj_tlen < 20) + return-1; + printf("%s Source Address: %s, LSP-ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18)); + obj_tlen-=20; + obj_tptr+=20; + break; + case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ + if (obj_tlen < 40) + return-1; + printf("%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18), + ident, + ip6addr_string(obj_tptr+20), + EXTRACT_16BITS(obj_tptr+38)); + obj_tlen-=40; + obj_tptr+=40; + break; +#endif + case RSVP_CTYPE_TUNNEL_IPV4: + if (obj_tlen < 8) + return-1; + printf("%s Source Address: %s, LSP-ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6)); + obj_tlen-=8; + obj_tptr+=8; + break; + case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ + if (obj_tlen < 16) + return-1; + printf("%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ident, + ipaddr_string(obj_tptr+8), + EXTRACT_16BITS(obj_tptr+12)); + obj_tlen-=16; + obj_tptr+=16; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_FASTREROUTE: + /* the differences between c-type 1 and 7 are minor */ + obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr; + bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); + + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: /* new style */ + if (obj_tlen < sizeof(struct rsvp_obj_frr_t)) + return-1; + printf("%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", + ident, + (int)obj_ptr.rsvp_obj_frr->setup_prio, + (int)obj_ptr.rsvp_obj_frr->hold_prio, + (int)obj_ptr.rsvp_obj_frr->hop_limit, + bw.f*8/1000000); + printf("%s Include-any: 0x%08x, Exclude-any: 0x%08x, Include-all: 0x%08x", + ident, + EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any), + EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any), + EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_all)); + obj_tlen-=sizeof(struct rsvp_obj_frr_t); + obj_tptr+=sizeof(struct rsvp_obj_frr_t); + break; + + case RSVP_CTYPE_TUNNEL_IPV4: /* old style */ + if (obj_tlen < 16) + return-1; + printf("%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", + ident, + (int)obj_ptr.rsvp_obj_frr->setup_prio, + (int)obj_ptr.rsvp_obj_frr->hold_prio, + (int)obj_ptr.rsvp_obj_frr->hop_limit, + bw.f*8/1000000); + printf("%s Include Colors: 0x%08x, Exclude Colors: 0x%08x", + ident, + EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any), + EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any)); + obj_tlen-=16; + obj_tptr+=16; + break; + + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_DETOUR: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_TUNNEL_IPV4: + while(obj_tlen >= 8) { + printf("%s PLR-ID: %s, Avoid-Node-ID: %s", + ident, + ipaddr_string(obj_tptr), + ipaddr_string(obj_tptr+4)); + obj_tlen-=8; + obj_tptr+=8; + } + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_CLASSTYPE: + case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */ + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + printf("%s CT: %u", + ident, + EXTRACT_32BITS(obj_tptr)&0x7); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_ERROR_SPEC: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */ + case RSVP_CTYPE_IPV4: + if (obj_tlen < 8) + return-1; + error_code=*(obj_tptr+5); + error_value=EXTRACT_16BITS(obj_tptr+6); + printf("%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", + ident, + ipaddr_string(obj_tptr), + *(obj_tptr+4), + ident, + tok2str(rsvp_obj_error_code_values,"unknown",error_code), + error_code); + switch (error_code) { + case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING: + printf(", Error Value: %s (%u)", + tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value), + error_value); + break; + case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE: /* fall through */ + case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD: + printf(", Error Value: %s (%u)", + tok2str(rsvp_obj_error_code_diffserv_te_values,"unknown",error_value), + error_value); + break; + default: + printf(", Unknown Error Value (%u)", error_value); + break; + } + obj_tlen-=8; + obj_tptr+=8; + break; +#ifdef INET6 + case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ + case RSVP_CTYPE_IPV6: + if (obj_tlen < 20) + return-1; + error_code=*(obj_tptr+17); + error_value=EXTRACT_16BITS(obj_tptr+18); + printf("%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", + ident, + ip6addr_string(obj_tptr), + *(obj_tptr+16), + ident, + tok2str(rsvp_obj_error_code_values,"unknown",error_code), + error_code); + + switch (error_code) { + case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING: + printf(", Error Value: %s (%u)", + tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value), + error_value); + break; + default: + break; + } + obj_tlen-=20; + obj_tptr+=20; + break; +#endif + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_PROPERTIES: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + return-1; + padbytes = EXTRACT_16BITS(obj_tptr+2); + printf("%s TLV count: %u, padding bytes: %u", + ident, + EXTRACT_16BITS(obj_tptr), + padbytes); + obj_tlen-=4; + obj_tptr+=4; + /* loop through as long there is anything longer than the TLV header (2) */ + while(obj_tlen >= 2 + padbytes) { + printf("%s %s TLV (0x%02x), length: %u", /* length includes header */ + ident, + tok2str(rsvp_obj_prop_tlv_values,"unknown",*obj_tptr), + *obj_tptr, + *(obj_tptr+1)); + if (obj_tlen < *(obj_tptr+1)) + return-1; + if (*(obj_tptr+1) < 2) + return -1; + print_unknown_data(obj_tptr+2,"\n\t\t",*(obj_tptr+1)-2); + obj_tlen-=*(obj_tptr+1); + obj_tptr+=*(obj_tptr+1); + } + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_MESSAGE_ID: /* fall through */ + case RSVP_OBJ_MESSAGE_ID_ACK: /* fall through */ + case RSVP_OBJ_MESSAGE_ID_LIST: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + case RSVP_CTYPE_2: + if (obj_tlen < 8) + return-1; + printf("%s Flags [0x%02x], epoch: %u", + ident, + *obj_tptr, + EXTRACT_24BITS(obj_tptr+1)); + obj_tlen-=4; + obj_tptr+=4; + /* loop through as long there are no messages left */ + while(obj_tlen >= 4) { + printf("%s Message-ID 0x%08x (%u)", + ident, + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + obj_tlen-=4; + obj_tptr+=4; + } + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_INTEGRITY: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < sizeof(struct rsvp_obj_integrity_t)) + return-1; + obj_ptr.rsvp_obj_integrity = (const struct rsvp_obj_integrity_t *)obj_tptr; + printf("%s Key-ID 0x%04x%08x, Sequence 0x%08x%08x, Flags [%s]", + ident, + EXTRACT_16BITS(obj_ptr.rsvp_obj_integrity->key_id), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->key_id+2), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence+4), + bittok2str(rsvp_obj_integrity_flag_values, + "none", + obj_ptr.rsvp_obj_integrity->flags)); + printf("%s MD5-sum 0x%08x%08x%08x%08x ", + ident, + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+4), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+8), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+12)); + +#ifdef HAVE_LIBCRYPTO + sigcheck = signature_verify(pptr, plen, (unsigned char *)obj_ptr.\ + rsvp_obj_integrity->digest); +#else + sigcheck = CANT_CHECK_SIGNATURE; +#endif + printf(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck)); + + obj_tlen+=sizeof(struct rsvp_obj_integrity_t); + obj_tptr+=sizeof(struct rsvp_obj_integrity_t); + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_ADMIN_STATUS: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + return-1; + printf("%s Flags [%s]", ident, + bittok2str(rsvp_obj_admin_status_flag_values, "none", + EXTRACT_32BITS(obj_tptr))); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_LABEL_SET: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + return-1; + action = (EXTRACT_16BITS(obj_tptr)>>8); + + printf("%s Action: %s (%u), Label type: %u", ident, + tok2str(rsvp_obj_label_set_action_values, "Unknown", action), + action, ((EXTRACT_32BITS(obj_tptr) & 0x7F))); + + switch (action) { + case LABEL_SET_INCLUSIVE_RANGE: + case LABEL_SET_EXCLUSIVE_RANGE: /* fall through */ + + /* only a couple of subchannels are expected */ + if (obj_tlen < 12) + return -1; + printf("%s Start range: %u, End range: %u", ident, + EXTRACT_32BITS(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+8)); + obj_tlen-=12; + obj_tptr+=12; + break; + + default: + obj_tlen-=4; + obj_tptr+=4; + subchannel = 1; + while(obj_tlen >= 4 ) { + printf("%s Subchannel #%u: %u", ident, subchannel, + EXTRACT_32BITS(obj_tptr)); + obj_tptr+=4; + obj_tlen-=4; + subchannel++; + } + break; + } + break; + default: + hexdump=TRUE; + } + + case RSVP_OBJ_S2L: + switch (rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < 4) + return-1; + printf("%s Sub-LSP destination address: %s", + ident, ipaddr_string(obj_tptr)); + + obj_tlen-=4; + obj_tptr+=4; + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < 16) + return-1; + printf("%s Sub-LSP destination address: %s", + ident, ip6addr_string(obj_tptr)); + + obj_tlen-=16; + obj_tptr+=16; + break; +#endif + default: + hexdump=TRUE; + } + + /* + * FIXME those are the defined objects that lack a decoder + * you are welcome to contribute code ;-) + */ + + case RSVP_OBJ_SCOPE: + case RSVP_OBJ_POLICY_DATA: + case RSVP_OBJ_ACCEPT_LABEL_SET: + case RSVP_OBJ_PROTECTION: + default: + if (vflag <= 1) + print_unknown_data(obj_tptr,"\n\t ",obj_tlen); /* FIXME indentation */ + break; + } + /* do we also want to see a hex dump ? */ + if (vflag > 1 || hexdump==TRUE) + print_unknown_data(tptr+sizeof(struct rsvp_object_header),"\n\t ", /* FIXME indentation */ + rsvp_obj_len-sizeof(struct rsvp_object_header)); + + tptr+=rsvp_obj_len; + tlen-=rsvp_obj_len; + } + return 0; +trunc: + printf("\n\t\t packet exceeded snapshot"); + return -1; +} + + +void +rsvp_print(register const u_char *pptr, register u_int len) { + + struct rsvp_common_header *rsvp_com_header; + const u_char *tptr,*subtptr; + u_short plen, tlen, subtlen; + + tptr=pptr; + + rsvp_com_header = (struct rsvp_common_header *)pptr; + TCHECK(*rsvp_com_header); + + /* + * Sanity checking of the header. + */ + if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) { + printf("ERROR: RSVP version %u packet not supported", + RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags)); + return; + } + + /* in non-verbose mode just lets print the basic Message Type*/ + if (vflag < 1) { + printf("RSVPv%u %s Message, length: %u", + RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), + tok2str(rsvp_msg_type_values, "unknown (%u)",rsvp_com_header->msg_type), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + + plen = tlen = EXTRACT_16BITS(rsvp_com_header->length); + + printf("\n\tRSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", + RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), + tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type), + rsvp_com_header->msg_type, + bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)), + tlen, + rsvp_com_header->ttl, + EXTRACT_16BITS(rsvp_com_header->checksum)); + + /* + * Clear checksum prior to signature verification. + */ + rsvp_com_header->checksum[0] = 0; + rsvp_com_header->checksum[1] = 0; + + if (tlen < sizeof(const struct rsvp_common_header)) { + printf("ERROR: common header too short %u < %lu", tlen, + (unsigned long)sizeof(const struct rsvp_common_header)); + return; + } + + tptr+=sizeof(const struct rsvp_common_header); + tlen-=sizeof(const struct rsvp_common_header); + + switch(rsvp_com_header->msg_type) { + + case RSVP_MSGTYPE_AGGREGATE: + while(tlen > 0) { + subtptr=tptr; + rsvp_com_header = (struct rsvp_common_header *)subtptr; + TCHECK(*rsvp_com_header); + + /* + * Sanity checking of the header. + */ + if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) { + printf("ERROR: RSVP version %u packet not supported", + RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags)); + return; + } + subtlen=EXTRACT_16BITS(rsvp_com_header->length); + + printf("\n\t RSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", + RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), + tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type), + rsvp_com_header->msg_type, + bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)), + subtlen, + rsvp_com_header->ttl, + EXTRACT_16BITS(rsvp_com_header->checksum)); + + /* + * Clear checksum prior to signature verification. + */ + rsvp_com_header->checksum[0] = 0; + rsvp_com_header->checksum[1] = 0; + + if (subtlen < sizeof(const struct rsvp_common_header)) { + printf("ERROR: common header too short %u < %lu", subtlen, + (unsigned long)sizeof(const struct rsvp_common_header)); + return; + } + + if (tlen < subtlen) { + printf("ERROR: common header too large %u > %u", subtlen, + tlen); + return; + } + + subtptr+=sizeof(const struct rsvp_common_header); + subtlen-=sizeof(const struct rsvp_common_header); + + if (rsvp_obj_print(pptr, plen, subtptr,"\n\t ", subtlen) == -1) + return; + + tptr+=subtlen+sizeof(const struct rsvp_common_header); + tlen-=subtlen+sizeof(const struct rsvp_common_header); + } + + break; + + case RSVP_MSGTYPE_PATH: + case RSVP_MSGTYPE_RESV: + case RSVP_MSGTYPE_PATHERR: + case RSVP_MSGTYPE_RESVERR: + case RSVP_MSGTYPE_PATHTEAR: + case RSVP_MSGTYPE_RESVTEAR: + case RSVP_MSGTYPE_RESVCONF: + case RSVP_MSGTYPE_HELLO_OLD: + case RSVP_MSGTYPE_HELLO: + case RSVP_MSGTYPE_ACK: + case RSVP_MSGTYPE_SREFRESH: + if (rsvp_obj_print(pptr, plen, tptr,"\n\t ", tlen) == -1) + return; + break; + + default: + print_unknown_data(tptr,"\n\t ",tlen); + break; + } + + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} diff --git a/freebsd/contrib/tcpdump/print-rt6.c b/freebsd/contrib/tcpdump/print-rt6.c new file mode 100644 index 00000000..c9501c92 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-rt6.c @@ -0,0 +1,107 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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-rt6.c,v 1.27 2005-04-20 22:34:57 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef INET6 + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "ip6.h" + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +int +rt6_print(register const u_char *bp, const u_char *bp2 _U_) +{ + register const struct ip6_rthdr *dp; + register const struct ip6_rthdr0 *dp0; + register const u_char *ep; + int i, len; + register const struct in6_addr *addr; + + dp = (struct ip6_rthdr *)bp; + len = dp->ip6r_len; + + /* 'ep' points to the end of available data. */ + ep = snapend; + + TCHECK(dp->ip6r_segleft); + + printf("srcrt (len=%d", dp->ip6r_len); /*)*/ + printf(", type=%d", dp->ip6r_type); + printf(", segleft=%d", dp->ip6r_segleft); + + switch (dp->ip6r_type) { +#ifndef IPV6_RTHDR_TYPE_0 +#define IPV6_RTHDR_TYPE_0 0 +#endif +#ifndef IPV6_RTHDR_TYPE_2 +#define IPV6_RTHDR_TYPE_2 2 +#endif + case IPV6_RTHDR_TYPE_0: + case IPV6_RTHDR_TYPE_2: /* Mobile IPv6 ID-20 */ + dp0 = (struct ip6_rthdr0 *)dp; + + TCHECK(dp0->ip6r0_reserved); + if (dp0->ip6r0_reserved || vflag) { + printf(", rsv=0x%0x", + EXTRACT_32BITS(&dp0->ip6r0_reserved)); + } + + if (len % 2 == 1) + goto trunc; + len >>= 1; + addr = &dp0->ip6r0_addr[0]; + for (i = 0; i < len; i++) { + if ((u_char *)(addr + 1) > ep) + goto trunc; + + printf(", [%d]%s", i, ip6addr_string(addr)); + addr++; + } + /*(*/ + printf(") "); + return((dp0->ip6r0_len + 1) << 3); + break; + default: + goto trunc; + break; + } + + trunc: + fputs("[|srcrt]", stdout); + return -1; +} +#endif /* INET6 */ diff --git a/freebsd/contrib/tcpdump/print-rx.c b/freebsd/contrib/tcpdump/print-rx.c new file mode 100644 index 00000000..26ed1c63 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-rx.c @@ -0,0 +1,2800 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright: (c) 2000 United States Government as represented by the + * Secretary of the Navy. 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. + */ +/* + * This code unmangles RX packets. RX is the mutant form of RPC that AFS + * uses to communicate between clients and servers. + * + * In this code, I mainly concern myself with decoding the AFS calls, not + * with the guts of RX, per se. + * + * Bah. If I never look at rx_packet.h again, it will be too soon. + * + * Ken Hornstein <kenh@cmf.nrl.navy.mil> + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.42 2008-07-01 07:44:50 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <tcpdump-stdinc.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "rx.h" + +#include "ip.h" + +static struct tok rx_types[] = { + { RX_PACKET_TYPE_DATA, "data" }, + { RX_PACKET_TYPE_ACK, "ack" }, + { RX_PACKET_TYPE_BUSY, "busy" }, + { RX_PACKET_TYPE_ABORT, "abort" }, + { RX_PACKET_TYPE_ACKALL, "ackall" }, + { RX_PACKET_TYPE_CHALLENGE, "challenge" }, + { RX_PACKET_TYPE_RESPONSE, "response" }, + { RX_PACKET_TYPE_DEBUG, "debug" }, + { RX_PACKET_TYPE_PARAMS, "params" }, + { RX_PACKET_TYPE_VERSION, "version" }, + { 0, NULL }, +}; + +static struct double_tok { + int flag; /* Rx flag */ + int packetType; /* Packet type */ + const char *s; /* Flag string */ +} rx_flags[] = { + { RX_CLIENT_INITIATED, 0, "client-init" }, + { RX_REQUEST_ACK, 0, "req-ack" }, + { RX_LAST_PACKET, 0, "last-pckt" }, + { RX_MORE_PACKETS, 0, "more-pckts" }, + { RX_FREE_PACKET, 0, "free-pckt" }, + { RX_SLOW_START_OK, RX_PACKET_TYPE_ACK, "slow-start" }, + { RX_JUMBO_PACKET, RX_PACKET_TYPE_DATA, "jumbogram" } +}; + +static struct tok fs_req[] = { + { 130, "fetch-data" }, + { 131, "fetch-acl" }, + { 132, "fetch-status" }, + { 133, "store-data" }, + { 134, "store-acl" }, + { 135, "store-status" }, + { 136, "remove-file" }, + { 137, "create-file" }, + { 138, "rename" }, + { 139, "symlink" }, + { 140, "link" }, + { 141, "makedir" }, + { 142, "rmdir" }, + { 143, "oldsetlock" }, + { 144, "oldextlock" }, + { 145, "oldrellock" }, + { 146, "get-stats" }, + { 147, "give-cbs" }, + { 148, "get-vlinfo" }, + { 149, "get-vlstats" }, + { 150, "set-vlstats" }, + { 151, "get-rootvl" }, + { 152, "check-token" }, + { 153, "get-time" }, + { 154, "nget-vlinfo" }, + { 155, "bulk-stat" }, + { 156, "setlock" }, + { 157, "extlock" }, + { 158, "rellock" }, + { 159, "xstat-ver" }, + { 160, "get-xstat" }, + { 161, "dfs-lookup" }, + { 162, "dfs-flushcps" }, + { 163, "dfs-symlink" }, + { 220, "residency" }, + { 65536, "inline-bulk-status" }, + { 65537, "fetch-data-64" }, + { 65538, "store-data-64" }, + { 65539, "give-up-all-cbs" }, + { 65540, "get-caps" }, + { 65541, "cb-rx-conn-addr" }, + { 0, NULL }, +}; + +static struct tok cb_req[] = { + { 204, "callback" }, + { 205, "initcb" }, + { 206, "probe" }, + { 207, "getlock" }, + { 208, "getce" }, + { 209, "xstatver" }, + { 210, "getxstat" }, + { 211, "initcb2" }, + { 212, "whoareyou" }, + { 213, "initcb3" }, + { 214, "probeuuid" }, + { 215, "getsrvprefs" }, + { 216, "getcellservdb" }, + { 217, "getlocalcell" }, + { 218, "getcacheconf" }, + { 65536, "getce64" }, + { 65537, "getcellbynum" }, + { 65538, "tellmeaboutyourself" }, + { 0, NULL }, +}; + +static struct tok pt_req[] = { + { 500, "new-user" }, + { 501, "where-is-it" }, + { 502, "dump-entry" }, + { 503, "add-to-group" }, + { 504, "name-to-id" }, + { 505, "id-to-name" }, + { 506, "delete" }, + { 507, "remove-from-group" }, + { 508, "get-cps" }, + { 509, "new-entry" }, + { 510, "list-max" }, + { 511, "set-max" }, + { 512, "list-entry" }, + { 513, "change-entry" }, + { 514, "list-elements" }, + { 515, "same-mbr-of" }, + { 516, "set-fld-sentry" }, + { 517, "list-owned" }, + { 518, "get-cps2" }, + { 519, "get-host-cps" }, + { 520, "update-entry" }, + { 521, "list-entries" }, + { 530, "list-super-groups" }, + { 0, NULL }, +}; + +static struct tok vldb_req[] = { + { 501, "create-entry" }, + { 502, "delete-entry" }, + { 503, "get-entry-by-id" }, + { 504, "get-entry-by-name" }, + { 505, "get-new-volume-id" }, + { 506, "replace-entry" }, + { 507, "update-entry" }, + { 508, "setlock" }, + { 509, "releaselock" }, + { 510, "list-entry" }, + { 511, "list-attrib" }, + { 512, "linked-list" }, + { 513, "get-stats" }, + { 514, "probe" }, + { 515, "get-addrs" }, + { 516, "change-addr" }, + { 517, "create-entry-n" }, + { 518, "get-entry-by-id-n" }, + { 519, "get-entry-by-name-n" }, + { 520, "replace-entry-n" }, + { 521, "list-entry-n" }, + { 522, "list-attrib-n" }, + { 523, "linked-list-n" }, + { 524, "update-entry-by-name" }, + { 525, "create-entry-u" }, + { 526, "get-entry-by-id-u" }, + { 527, "get-entry-by-name-u" }, + { 528, "replace-entry-u" }, + { 529, "list-entry-u" }, + { 530, "list-attrib-u" }, + { 531, "linked-list-u" }, + { 532, "regaddr" }, + { 533, "get-addrs-u" }, + { 534, "list-attrib-n2" }, + { 0, NULL }, +}; + +static struct tok kauth_req[] = { + { 1, "auth-old" }, + { 21, "authenticate" }, + { 22, "authenticate-v2" }, + { 2, "change-pw" }, + { 3, "get-ticket-old" }, + { 23, "get-ticket" }, + { 4, "set-pw" }, + { 5, "set-fields" }, + { 6, "create-user" }, + { 7, "delete-user" }, + { 8, "get-entry" }, + { 9, "list-entry" }, + { 10, "get-stats" }, + { 11, "debug" }, + { 12, "get-pw" }, + { 13, "get-random-key" }, + { 14, "unlock" }, + { 15, "lock-status" }, + { 0, NULL }, +}; + +static struct tok vol_req[] = { + { 100, "create-volume" }, + { 101, "delete-volume" }, + { 102, "restore" }, + { 103, "forward" }, + { 104, "end-trans" }, + { 105, "clone" }, + { 106, "set-flags" }, + { 107, "get-flags" }, + { 108, "trans-create" }, + { 109, "dump" }, + { 110, "get-nth-volume" }, + { 111, "set-forwarding" }, + { 112, "get-name" }, + { 113, "get-status" }, + { 114, "sig-restore" }, + { 115, "list-partitions" }, + { 116, "list-volumes" }, + { 117, "set-id-types" }, + { 118, "monitor" }, + { 119, "partition-info" }, + { 120, "reclone" }, + { 121, "list-one-volume" }, + { 122, "nuke" }, + { 123, "set-date" }, + { 124, "x-list-volumes" }, + { 125, "x-list-one-volume" }, + { 126, "set-info" }, + { 127, "x-list-partitions" }, + { 128, "forward-multiple" }, + { 65536, "convert-ro" }, + { 65537, "get-size" }, + { 65538, "dump-v2" }, + { 0, NULL }, +}; + +static struct tok bos_req[] = { + { 80, "create-bnode" }, + { 81, "delete-bnode" }, + { 82, "set-status" }, + { 83, "get-status" }, + { 84, "enumerate-instance" }, + { 85, "get-instance-info" }, + { 86, "get-instance-parm" }, + { 87, "add-superuser" }, + { 88, "delete-superuser" }, + { 89, "list-superusers" }, + { 90, "list-keys" }, + { 91, "add-key" }, + { 92, "delete-key" }, + { 93, "set-cell-name" }, + { 94, "get-cell-name" }, + { 95, "get-cell-host" }, + { 96, "add-cell-host" }, + { 97, "delete-cell-host" }, + { 98, "set-t-status" }, + { 99, "shutdown-all" }, + { 100, "restart-all" }, + { 101, "startup-all" }, + { 102, "set-noauth-flag" }, + { 103, "re-bozo" }, + { 104, "restart" }, + { 105, "start-bozo-install" }, + { 106, "uninstall" }, + { 107, "get-dates" }, + { 108, "exec" }, + { 109, "prune" }, + { 110, "set-restart-time" }, + { 111, "get-restart-time" }, + { 112, "start-bozo-log" }, + { 113, "wait-all" }, + { 114, "get-instance-strings" }, + { 115, "get-restricted" }, + { 116, "set-restricted" }, + { 0, NULL }, +}; + +static struct tok ubik_req[] = { + { 10000, "vote-beacon" }, + { 10001, "vote-debug-old" }, + { 10002, "vote-sdebug-old" }, + { 10003, "vote-getsyncsite" }, + { 10004, "vote-debug" }, + { 10005, "vote-sdebug" }, + { 10006, "vote-xdebug" }, + { 10007, "vote-xsdebug" }, + { 20000, "disk-begin" }, + { 20001, "disk-commit" }, + { 20002, "disk-lock" }, + { 20003, "disk-write" }, + { 20004, "disk-getversion" }, + { 20005, "disk-getfile" }, + { 20006, "disk-sendfile" }, + { 20007, "disk-abort" }, + { 20008, "disk-releaselocks" }, + { 20009, "disk-truncate" }, + { 20010, "disk-probe" }, + { 20011, "disk-writev" }, + { 20012, "disk-interfaceaddr" }, + { 20013, "disk-setversion" }, + { 0, NULL }, +}; + +#define VOTE_LOW 10000 +#define VOTE_HIGH 10007 +#define DISK_LOW 20000 +#define DISK_HIGH 20013 + +static struct tok cb_types[] = { + { 1, "exclusive" }, + { 2, "shared" }, + { 3, "dropped" }, + { 0, NULL }, +}; + +static struct tok ubik_lock_types[] = { + { 1, "read" }, + { 2, "write" }, + { 3, "wait" }, + { 0, NULL }, +}; + +static const char *voltype[] = { "read-write", "read-only", "backup" }; + +static struct tok afs_fs_errors[] = { + { 101, "salvage volume" }, + { 102, "no such vnode" }, + { 103, "no such volume" }, + { 104, "volume exist" }, + { 105, "no service" }, + { 106, "volume offline" }, + { 107, "voline online" }, + { 108, "diskfull" }, + { 109, "diskquota exceeded" }, + { 110, "volume busy" }, + { 111, "volume moved" }, + { 112, "AFS IO error" }, + { -100, "restarting fileserver" }, + { 0, NULL } +}; + +/* + * Reasons for acknowledging a packet + */ + +static struct tok rx_ack_reasons[] = { + { 1, "ack requested" }, + { 2, "duplicate packet" }, + { 3, "out of sequence" }, + { 4, "exceeds window" }, + { 5, "no buffer space" }, + { 6, "ping" }, + { 7, "ping response" }, + { 8, "delay" }, + { 9, "idle" }, + { 0, NULL }, +}; + +/* + * Cache entries we keep around so we can figure out the RX opcode + * numbers for replies. This allows us to make sense of RX reply packets. + */ + +struct rx_cache_entry { + u_int32_t callnum; /* Call number (net order) */ + struct in_addr client; /* client IP address (net order) */ + struct in_addr server; /* server IP address (net order) */ + int dport; /* server port (host order) */ + u_short serviceId; /* Service identifier (net order) */ + u_int32_t opcode; /* RX opcode (host order) */ +}; + +#define RX_CACHE_SIZE 64 + +static struct rx_cache_entry rx_cache[RX_CACHE_SIZE]; + +static int rx_cache_next = 0; +static int rx_cache_hint = 0; +static void rx_cache_insert(const u_char *, const struct ip *, int); +static int rx_cache_find(const struct rx_header *, const struct ip *, + int, int32_t *); + +static void fs_print(const u_char *, int); +static void fs_reply_print(const u_char *, int, int32_t); +static void acl_print(u_char *, int, u_char *); +static void cb_print(const u_char *, int); +static void cb_reply_print(const u_char *, int, int32_t); +static void prot_print(const u_char *, int); +static void prot_reply_print(const u_char *, int, int32_t); +static void vldb_print(const u_char *, int); +static void vldb_reply_print(const u_char *, int, int32_t); +static void kauth_print(const u_char *, int); +static void kauth_reply_print(const u_char *, int, int32_t); +static void vol_print(const u_char *, int); +static void vol_reply_print(const u_char *, int, int32_t); +static void bos_print(const u_char *, int); +static void bos_reply_print(const u_char *, int, int32_t); +static void ubik_print(const u_char *); +static void ubik_reply_print(const u_char *, int, int32_t); + +static void rx_ack_print(const u_char *, int); + +static int is_ubik(u_int32_t); + +/* + * Handle the rx-level packet. See if we know what port it's going to so + * we can peek at the afs call inside + */ + +void +rx_print(register const u_char *bp, int length, int sport, int dport, + u_char *bp2) +{ + register struct rx_header *rxh; + int i; + int32_t opcode; + + if (snapend - bp < (int)sizeof (struct rx_header)) { + printf(" [|rx] (%d)", length); + return; + } + + rxh = (struct rx_header *) bp; + + printf(" rx %s", tok2str(rx_types, "type %d", rxh->type)); + + if (vflag) { + int firstflag = 0; + + if (vflag > 1) + printf(" cid %08x call# %d", + (int) EXTRACT_32BITS(&rxh->cid), + (int) EXTRACT_32BITS(&rxh->callNumber)); + + printf(" seq %d ser %d", + (int) EXTRACT_32BITS(&rxh->seq), + (int) EXTRACT_32BITS(&rxh->serial)); + + if (vflag > 2) + printf(" secindex %d serviceid %hu", + (int) rxh->securityIndex, + EXTRACT_16BITS(&rxh->serviceId)); + + if (vflag > 1) + for (i = 0; i < NUM_RX_FLAGS; i++) { + if (rxh->flags & rx_flags[i].flag && + (!rx_flags[i].packetType || + rxh->type == rx_flags[i].packetType)) { + if (!firstflag) { + firstflag = 1; + printf(" "); + } else { + printf(","); + } + printf("<%s>", rx_flags[i].s); + } + } + } + + /* + * Try to handle AFS calls that we know about. Check the destination + * port and make sure it's a data packet. Also, make sure the + * seq number is 1 (because otherwise it's a continuation packet, + * and we can't interpret that). Also, seems that reply packets + * do not have the client-init flag set, so we check for that + * as well. + */ + + if (rxh->type == RX_PACKET_TYPE_DATA && + EXTRACT_32BITS(&rxh->seq) == 1 && + rxh->flags & RX_CLIENT_INITIATED) { + + /* + * Insert this call into the call cache table, so we + * have a chance to print out replies + */ + + rx_cache_insert(bp, (const struct ip *) bp2, dport); + + switch (dport) { + case FS_RX_PORT: /* AFS file service */ + fs_print(bp, length); + break; + case CB_RX_PORT: /* AFS callback service */ + cb_print(bp, length); + break; + case PROT_RX_PORT: /* AFS protection service */ + prot_print(bp, length); + break; + case VLDB_RX_PORT: /* AFS VLDB service */ + vldb_print(bp, length); + break; + case KAUTH_RX_PORT: /* AFS Kerberos auth service */ + kauth_print(bp, length); + break; + case VOL_RX_PORT: /* AFS Volume service */ + vol_print(bp, length); + break; + case BOS_RX_PORT: /* AFS BOS service */ + bos_print(bp, length); + break; + default: + ; + } + + /* + * If it's a reply (client-init is _not_ set, but seq is one) + * then look it up in the cache. If we find it, call the reply + * printing functions Note that we handle abort packets here, + * because printing out the return code can be useful at times. + */ + + } else if (((rxh->type == RX_PACKET_TYPE_DATA && + EXTRACT_32BITS(&rxh->seq) == 1) || + rxh->type == RX_PACKET_TYPE_ABORT) && + (rxh->flags & RX_CLIENT_INITIATED) == 0 && + rx_cache_find(rxh, (const struct ip *) bp2, + sport, &opcode)) { + + switch (sport) { + case FS_RX_PORT: /* AFS file service */ + fs_reply_print(bp, length, opcode); + break; + case CB_RX_PORT: /* AFS callback service */ + cb_reply_print(bp, length, opcode); + break; + case PROT_RX_PORT: /* AFS PT service */ + prot_reply_print(bp, length, opcode); + break; + case VLDB_RX_PORT: /* AFS VLDB service */ + vldb_reply_print(bp, length, opcode); + break; + case KAUTH_RX_PORT: /* AFS Kerberos auth service */ + kauth_reply_print(bp, length, opcode); + break; + case VOL_RX_PORT: /* AFS Volume service */ + vol_reply_print(bp, length, opcode); + break; + case BOS_RX_PORT: /* AFS BOS service */ + bos_reply_print(bp, length, opcode); + break; + default: + ; + } + + /* + * If it's an RX ack packet, then use the appropriate ack decoding + * function (there isn't any service-specific information in the + * ack packet, so we can use one for all AFS services) + */ + + } else if (rxh->type == RX_PACKET_TYPE_ACK) + rx_ack_print(bp, length); + + + printf(" (%d)", length); +} + +/* + * Insert an entry into the cache. Taken from print-nfs.c + */ + +static void +rx_cache_insert(const u_char *bp, const struct ip *ip, int dport) +{ + struct rx_cache_entry *rxent; + const struct rx_header *rxh = (const struct rx_header *) bp; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) + return; + + rxent = &rx_cache[rx_cache_next]; + + if (++rx_cache_next >= RX_CACHE_SIZE) + rx_cache_next = 0; + + rxent->callnum = rxh->callNumber; + rxent->client = ip->ip_src; + rxent->server = ip->ip_dst; + rxent->dport = dport; + rxent->serviceId = rxh->serviceId; + rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header)); +} + +/* + * Lookup an entry in the cache. Also taken from print-nfs.c + * + * Note that because this is a reply, we're looking at the _source_ + * port. + */ + +static int +rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, + int32_t *opcode) +{ + int i; + struct rx_cache_entry *rxent; + u_int32_t clip = ip->ip_dst.s_addr; + u_int32_t sip = ip->ip_src.s_addr; + + /* Start the search where we last left off */ + + i = rx_cache_hint; + do { + rxent = &rx_cache[i]; + if (rxent->callnum == rxh->callNumber && + rxent->client.s_addr == clip && + rxent->server.s_addr == sip && + rxent->serviceId == rxh->serviceId && + rxent->dport == sport) { + + /* We got a match! */ + + rx_cache_hint = i; + *opcode = rxent->opcode; + return(1); + } + if (++i > RX_CACHE_SIZE) + i = 0; + } while (i != rx_cache_hint); + + /* Our search failed */ + return(0); +} + +/* + * These extrememly grody macros handle the printing of various AFS stuff. + */ + +#define FIDOUT() { unsigned long n1, n2, n3; \ + TCHECK2(bp[0], sizeof(int32_t) * 3); \ + n1 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + n2 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + n3 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + printf(" fid %d/%d/%d", (int) n1, (int) n2, (int) n3); \ + } + +#define STROUT(MAX) { unsigned int i; \ + TCHECK2(bp[0], sizeof(int32_t)); \ + i = EXTRACT_32BITS(bp); \ + if (i > (MAX)) \ + goto trunc; \ + bp += sizeof(int32_t); \ + printf(" \""); \ + if (fn_printn(bp, i, snapend)) \ + goto trunc; \ + printf("\""); \ + bp += ((i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \ + } + +#define INTOUT() { int i; \ + TCHECK2(bp[0], sizeof(int32_t)); \ + i = (int) EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + printf(" %d", i); \ + } + +#define UINTOUT() { unsigned long i; \ + TCHECK2(bp[0], sizeof(int32_t)); \ + i = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + printf(" %lu", i); \ + } + +#define UINT64OUT() { u_int64_t i; \ + TCHECK2(bp[0], sizeof(u_int64_t)); \ + i = EXTRACT_64BITS(bp); \ + bp += sizeof(u_int64_t); \ + printf(" %" PRIu64, i); \ + } + +#define DATEOUT() { time_t t; struct tm *tm; char str[256]; \ + TCHECK2(bp[0], sizeof(int32_t)); \ + t = (time_t) EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + tm = localtime(&t); \ + strftime(str, 256, "%Y/%m/%d %T", tm); \ + printf(" %s", str); \ + } + +#define STOREATTROUT() { unsigned long mask, i; \ + TCHECK2(bp[0], (sizeof(int32_t)*6)); \ + mask = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ + if (mask) printf (" StoreStatus"); \ + if (mask & 1) { printf(" date"); DATEOUT(); } \ + else bp += sizeof(int32_t); \ + i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ + if (mask & 2) printf(" owner %lu", i); \ + i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ + if (mask & 4) printf(" group %lu", i); \ + i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ + if (mask & 8) printf(" mode %lo", i & 07777); \ + i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ + if (mask & 16) printf(" segsize %lu", i); \ + /* undocumented in 3.3 docu */ \ + if (mask & 1024) printf(" fsync"); \ + } + +#define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \ + TCHECK2(bp[0], sizeof(int32_t) * 2); \ + epoch = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + counter = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + printf(" %d.%d", epoch, counter); \ + } + +#define AFSUUIDOUT() {u_int32_t temp; int i; \ + TCHECK2(bp[0], 11*sizeof(u_int32_t)); \ + temp = EXTRACT_32BITS(bp); \ + bp += sizeof(u_int32_t); \ + printf(" %08x", temp); \ + temp = EXTRACT_32BITS(bp); \ + bp += sizeof(u_int32_t); \ + printf("%04x", temp); \ + temp = EXTRACT_32BITS(bp); \ + bp += sizeof(u_int32_t); \ + printf("%04x", temp); \ + for (i = 0; i < 8; i++) { \ + temp = EXTRACT_32BITS(bp); \ + bp += sizeof(u_int32_t); \ + printf("%02x", (unsigned char) temp); \ + } \ + } + +/* + * This is the sickest one of all + */ + +#define VECOUT(MAX) { u_char *sp; \ + u_char s[AFSNAMEMAX]; \ + int k; \ + if ((MAX) + 1 > sizeof(s)) \ + goto trunc; \ + TCHECK2(bp[0], (MAX) * sizeof(int32_t)); \ + sp = s; \ + for (k = 0; k < (MAX); k++) { \ + *sp++ = (u_char) EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + } \ + s[(MAX)] = '\0'; \ + printf(" \""); \ + fn_print(s, NULL); \ + printf("\""); \ + } + +#define DESTSERVEROUT() { unsigned long n1, n2, n3; \ + TCHECK2(bp[0], sizeof(int32_t) * 3); \ + n1 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + n2 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + n3 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + printf(" server %d:%d:%d", (int) n1, (int) n2, (int) n3); \ + } + +/* + * Handle calls to the AFS file service (fs) + */ + +static void +fs_print(register const u_char *bp, int length) +{ + int fs_op; + unsigned long i; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from fsint/afsint.xg + */ + + fs_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" fs call %s", tok2str(fs_req, "op#%d", fs_op)); + + /* + * Print out arguments to some of the AFS calls. This stuff is + * all from afsint.xg + */ + + bp += sizeof(struct rx_header) + 4; + + /* + * Sigh. This is gross. Ritchie forgive me. + */ + + switch (fs_op) { + case 130: /* Fetch data */ + FIDOUT(); + printf(" offset"); + UINTOUT(); + printf(" length"); + UINTOUT(); + break; + case 131: /* Fetch ACL */ + case 132: /* Fetch Status */ + case 143: /* Old set lock */ + case 144: /* Old extend lock */ + case 145: /* Old release lock */ + case 156: /* Set lock */ + case 157: /* Extend lock */ + case 158: /* Release lock */ + FIDOUT(); + break; + case 135: /* Store status */ + FIDOUT(); + STOREATTROUT(); + break; + case 133: /* Store data */ + FIDOUT(); + STOREATTROUT(); + printf(" offset"); + UINTOUT(); + printf(" length"); + UINTOUT(); + printf(" flen"); + UINTOUT(); + break; + case 134: /* Store ACL */ + { + char a[AFSOPAQUEMAX+1]; + FIDOUT(); + TCHECK2(bp[0], 4); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + TCHECK2(bp[0], i); + i = min(AFSOPAQUEMAX, i); + strncpy(a, (char *) bp, i); + a[i] = '\0'; + acl_print((u_char *) a, sizeof(a), (u_char *) a + i); + break; + } + case 137: /* Create file */ + case 141: /* MakeDir */ + FIDOUT(); + STROUT(AFSNAMEMAX); + STOREATTROUT(); + break; + case 136: /* Remove file */ + case 142: /* Remove directory */ + FIDOUT(); + STROUT(AFSNAMEMAX); + break; + case 138: /* Rename file */ + printf(" old"); + FIDOUT(); + STROUT(AFSNAMEMAX); + printf(" new"); + FIDOUT(); + STROUT(AFSNAMEMAX); + break; + case 139: /* Symlink */ + FIDOUT(); + STROUT(AFSNAMEMAX); + printf(" link to"); + STROUT(AFSNAMEMAX); + break; + case 140: /* Link */ + FIDOUT(); + STROUT(AFSNAMEMAX); + printf(" link to"); + FIDOUT(); + break; + case 148: /* Get volume info */ + STROUT(AFSNAMEMAX); + break; + case 149: /* Get volume stats */ + case 150: /* Set volume stats */ + printf(" volid"); + UINTOUT(); + break; + case 154: /* New get volume info */ + printf(" volname"); + STROUT(AFSNAMEMAX); + break; + case 155: /* Bulk stat */ + case 65536: /* Inline bulk stat */ + { + unsigned long j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + for (i = 0; i < j; i++) { + FIDOUT(); + if (i != j - 1) + printf(","); + } + if (j == 0) + printf(" <none!>"); + } + case 65537: /* Fetch data 64 */ + FIDOUT(); + printf(" offset"); + UINT64OUT(); + printf(" length"); + UINT64OUT(); + break; + case 65538: /* Store data 64 */ + FIDOUT(); + STOREATTROUT(); + printf(" offset"); + UINT64OUT(); + printf(" length"); + UINT64OUT(); + printf(" flen"); + UINT64OUT(); + break; + case 65541: /* CallBack rx conn address */ + printf(" addr"); + UINTOUT(); + default: + ; + } + + return; + +trunc: + printf(" [|fs]"); +} + +/* + * Handle replies to the AFS file service + */ + +static void +fs_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + unsigned long i; + struct rx_header *rxh; + + if (length <= (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from fsint/afsint.xg + */ + + printf(" fs reply %s", tok2str(fs_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) { + switch (opcode) { + case 131: /* Fetch ACL */ + { + char a[AFSOPAQUEMAX+1]; + TCHECK2(bp[0], 4); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + TCHECK2(bp[0], i); + i = min(AFSOPAQUEMAX, i); + strncpy(a, (char *) bp, i); + a[i] = '\0'; + acl_print((u_char *) a, sizeof(a), (u_char *) a + i); + break; + } + case 137: /* Create file */ + case 141: /* MakeDir */ + printf(" new"); + FIDOUT(); + break; + case 151: /* Get root volume */ + printf(" root volume"); + STROUT(AFSNAMEMAX); + break; + case 153: /* Get time */ + DATEOUT(); + break; + default: + ; + } + } else if (rxh->type == RX_PACKET_TYPE_ABORT) { + int i; + + /* + * Otherwise, just print out the return code + */ + TCHECK2(bp[0], sizeof(int32_t)); + i = (int) EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + printf(" error %s", tok2str(afs_fs_errors, "#%d", i)); + } else { + printf(" strange fs reply of type %d", rxh->type); + } + + return; + +trunc: + printf(" [|fs]"); +} + +/* + * Print out an AFS ACL string. An AFS ACL is a string that has the + * following format: + * + * <positive> <negative> + * <uid1> <aclbits1> + * .... + * + * "positive" and "negative" are integers which contain the number of + * positive and negative ACL's in the string. The uid/aclbits pair are + * ASCII strings containing the UID/PTS record and and a ascii number + * representing a logical OR of all the ACL permission bits + */ + +static void +acl_print(u_char *s, int maxsize, u_char *end) +{ + int pos, neg, acl; + int n, i; + char *user; + char fmt[1024]; + + if ((user = (char *)malloc(maxsize)) == NULL) + return; + + if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2) + goto finish; + + s += n; + + if (s > end) + goto finish; + + /* + * This wacky order preserves the order used by the "fs" command + */ + +#define ACLOUT(acl) \ + if (acl & PRSFS_READ) \ + printf("r"); \ + if (acl & PRSFS_LOOKUP) \ + printf("l"); \ + if (acl & PRSFS_INSERT) \ + printf("i"); \ + if (acl & PRSFS_DELETE) \ + printf("d"); \ + if (acl & PRSFS_WRITE) \ + printf("w"); \ + if (acl & PRSFS_LOCK) \ + printf("k"); \ + if (acl & PRSFS_ADMINISTER) \ + printf("a"); + + for (i = 0; i < pos; i++) { + snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1); + if (sscanf((char *) s, fmt, user, &acl, &n) != 2) + goto finish; + s += n; + printf(" +{"); + fn_print((u_char *)user, NULL); + printf(" "); + ACLOUT(acl); + printf("}"); + if (s > end) + goto finish; + } + + for (i = 0; i < neg; i++) { + snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1); + if (sscanf((char *) s, fmt, user, &acl, &n) != 2) + goto finish; + s += n; + printf(" -{"); + fn_print((u_char *)user, NULL); + printf(" "); + ACLOUT(acl); + printf("}"); + if (s > end) + goto finish; + } + +finish: + free(user); + return; +} + +#undef ACLOUT + +/* + * Handle calls to the AFS callback service + */ + +static void +cb_print(register const u_char *bp, int length) +{ + int cb_op; + unsigned long i; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from fsint/afscbint.xg + */ + + cb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" cb call %s", tok2str(cb_req, "op#%d", cb_op)); + + bp += sizeof(struct rx_header) + 4; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from fsint/afscbint.xg + */ + + switch (cb_op) { + case 204: /* Callback */ + { + unsigned long j, t; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + for (i = 0; i < j; i++) { + FIDOUT(); + if (i != j - 1) + printf(","); + } + + if (j == 0) + printf(" <none!>"); + + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + if (j != 0) + printf(";"); + + for (i = 0; i < j; i++) { + printf(" ver"); + INTOUT(); + printf(" expires"); + DATEOUT(); + TCHECK2(bp[0], 4); + t = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + tok2str(cb_types, "type %d", t); + } + } + case 214: { + printf(" afsuuid"); + AFSUUIDOUT(); + break; + } + default: + ; + } + + return; + +trunc: + printf(" [|cb]"); +} + +/* + * Handle replies to the AFS Callback Service + */ + +static void +cb_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + + if (length <= (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from fsint/afscbint.xg + */ + + printf(" cb reply %s", tok2str(cb_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response. + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + switch (opcode) { + case 213: /* InitCallBackState3 */ + AFSUUIDOUT(); + break; + default: + ; + } + else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|cb]"); +} + +/* + * Handle calls to the AFS protection database server + */ + +static void +prot_print(register const u_char *bp, int length) +{ + unsigned long i; + int pt_op; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from ptserver/ptint.xg + */ + + pt_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" pt"); + + if (is_ubik(pt_op)) { + ubik_print(bp); + return; + } + + printf(" call %s", tok2str(pt_req, "op#%d", pt_op)); + + /* + * Decode some of the arguments to the PT calls + */ + + bp += sizeof(struct rx_header) + 4; + + switch (pt_op) { + case 500: /* I New User */ + STROUT(PRNAMEMAX); + printf(" id"); + INTOUT(); + printf(" oldid"); + INTOUT(); + break; + case 501: /* Where is it */ + case 506: /* Delete */ + case 508: /* Get CPS */ + case 512: /* List entry */ + case 514: /* List elements */ + case 517: /* List owned */ + case 518: /* Get CPS2 */ + case 519: /* Get host CPS */ + case 530: /* List super groups */ + printf(" id"); + INTOUT(); + break; + case 502: /* Dump entry */ + printf(" pos"); + INTOUT(); + break; + case 503: /* Add to group */ + case 507: /* Remove from group */ + case 515: /* Is a member of? */ + printf(" uid"); + INTOUT(); + printf(" gid"); + INTOUT(); + break; + case 504: /* Name to ID */ + { + unsigned long j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + /* + * Who designed this chicken-shit protocol? + * + * Each character is stored as a 32-bit + * integer! + */ + + for (i = 0; i < j; i++) { + VECOUT(PRNAMEMAX); + } + if (j == 0) + printf(" <none!>"); + } + break; + case 505: /* Id to name */ + { + unsigned long j; + printf(" ids:"); + TCHECK2(bp[0], 4); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + for (j = 0; j < i; j++) + INTOUT(); + if (j == 0) + printf(" <none!>"); + } + break; + case 509: /* New entry */ + STROUT(PRNAMEMAX); + printf(" flag"); + INTOUT(); + printf(" oid"); + INTOUT(); + break; + case 511: /* Set max */ + printf(" id"); + INTOUT(); + printf(" gflag"); + INTOUT(); + break; + case 513: /* Change entry */ + printf(" id"); + INTOUT(); + STROUT(PRNAMEMAX); + printf(" oldid"); + INTOUT(); + printf(" newid"); + INTOUT(); + break; + case 520: /* Update entry */ + printf(" id"); + INTOUT(); + STROUT(PRNAMEMAX); + break; + default: + ; + } + + + return; + +trunc: + printf(" [|pt]"); +} + +/* + * Handle replies to the AFS protection service + */ + +static void +prot_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + unsigned long i; + + if (length < (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from ptserver/ptint.xg. Check to see if it's a + * Ubik call, however. + */ + + printf(" pt"); + + if (is_ubik(opcode)) { + ubik_reply_print(bp, length, opcode); + return; + } + + printf(" reply %s", tok2str(pt_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + switch (opcode) { + case 504: /* Name to ID */ + { + unsigned long j; + printf(" ids:"); + TCHECK2(bp[0], 4); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + for (j = 0; j < i; j++) + INTOUT(); + if (j == 0) + printf(" <none!>"); + } + break; + case 505: /* ID to name */ + { + unsigned long j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + /* + * Who designed this chicken-shit protocol? + * + * Each character is stored as a 32-bit + * integer! + */ + + for (i = 0; i < j; i++) { + VECOUT(PRNAMEMAX); + } + if (j == 0) + printf(" <none!>"); + } + break; + case 508: /* Get CPS */ + case 514: /* List elements */ + case 517: /* List owned */ + case 518: /* Get CPS2 */ + case 519: /* Get host CPS */ + { + unsigned long j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + for (i = 0; i < j; i++) { + INTOUT(); + } + if (j == 0) + printf(" <none!>"); + } + break; + case 510: /* List max */ + printf(" maxuid"); + INTOUT(); + printf(" maxgid"); + INTOUT(); + break; + default: + ; + } + else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|pt]"); +} + +/* + * Handle calls to the AFS volume location database service + */ + +static void +vldb_print(register const u_char *bp, int length) +{ + int vldb_op; + unsigned long i; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from vlserver/vldbint.xg + */ + + vldb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" vldb"); + + if (is_ubik(vldb_op)) { + ubik_print(bp); + return; + } + printf(" call %s", tok2str(vldb_req, "op#%d", vldb_op)); + + /* + * Decode some of the arguments to the VLDB calls + */ + + bp += sizeof(struct rx_header) + 4; + + switch (vldb_op) { + case 501: /* Create new volume */ + case 517: /* Create entry N */ + VECOUT(VLNAMEMAX); + break; + case 502: /* Delete entry */ + case 503: /* Get entry by ID */ + case 507: /* Update entry */ + case 508: /* Set lock */ + case 509: /* Release lock */ + case 518: /* Get entry by ID N */ + printf(" volid"); + INTOUT(); + TCHECK2(bp[0], sizeof(int32_t)); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + if (i <= 2) + printf(" type %s", voltype[i]); + break; + case 504: /* Get entry by name */ + case 519: /* Get entry by name N */ + case 524: /* Update entry by name */ + case 527: /* Get entry by name U */ + STROUT(VLNAMEMAX); + break; + case 505: /* Get new vol id */ + printf(" bump"); + INTOUT(); + break; + case 506: /* Replace entry */ + case 520: /* Replace entry N */ + printf(" volid"); + INTOUT(); + TCHECK2(bp[0], sizeof(int32_t)); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + if (i <= 2) + printf(" type %s", voltype[i]); + VECOUT(VLNAMEMAX); + break; + case 510: /* List entry */ + case 521: /* List entry N */ + printf(" index"); + INTOUT(); + break; + default: + ; + } + + return; + +trunc: + printf(" [|vldb]"); +} + +/* + * Handle replies to the AFS volume location database service + */ + +static void +vldb_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + unsigned long i; + + if (length < (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from vlserver/vldbint.xg. Check to see if it's a + * Ubik call, however. + */ + + printf(" vldb"); + + if (is_ubik(opcode)) { + ubik_reply_print(bp, length, opcode); + return; + } + + printf(" reply %s", tok2str(vldb_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + switch (opcode) { + case 510: /* List entry */ + printf(" count"); + INTOUT(); + printf(" nextindex"); + INTOUT(); + case 503: /* Get entry by id */ + case 504: /* Get entry by name */ + { unsigned long nservers, j; + VECOUT(VLNAMEMAX); + TCHECK2(bp[0], sizeof(int32_t)); + bp += sizeof(int32_t); + printf(" numservers"); + TCHECK2(bp[0], sizeof(int32_t)); + nservers = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + printf(" %lu", nservers); + printf(" servers"); + for (i = 0; i < 8; i++) { + TCHECK2(bp[0], sizeof(int32_t)); + if (i < nservers) + printf(" %s", + intoa(((struct in_addr *) bp)->s_addr)); + bp += sizeof(int32_t); + } + printf(" partitions"); + for (i = 0; i < 8; i++) { + TCHECK2(bp[0], sizeof(int32_t)); + j = EXTRACT_32BITS(bp); + if (i < nservers && j <= 26) + printf(" %c", 'a' + (int)j); + else if (i < nservers) + printf(" %lu", j); + bp += sizeof(int32_t); + } + TCHECK2(bp[0], 8 * sizeof(int32_t)); + bp += 8 * sizeof(int32_t); + printf(" rwvol"); + UINTOUT(); + printf(" rovol"); + UINTOUT(); + printf(" backup"); + UINTOUT(); + } + break; + case 505: /* Get new volume ID */ + printf(" newvol"); + UINTOUT(); + break; + case 521: /* List entry */ + case 529: /* List entry U */ + printf(" count"); + INTOUT(); + printf(" nextindex"); + INTOUT(); + case 518: /* Get entry by ID N */ + case 519: /* Get entry by name N */ + { unsigned long nservers, j; + VECOUT(VLNAMEMAX); + printf(" numservers"); + TCHECK2(bp[0], sizeof(int32_t)); + nservers = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + printf(" %lu", nservers); + printf(" servers"); + for (i = 0; i < 13; i++) { + TCHECK2(bp[0], sizeof(int32_t)); + if (i < nservers) + printf(" %s", + intoa(((struct in_addr *) bp)->s_addr)); + bp += sizeof(int32_t); + } + printf(" partitions"); + for (i = 0; i < 13; i++) { + TCHECK2(bp[0], sizeof(int32_t)); + j = EXTRACT_32BITS(bp); + if (i < nservers && j <= 26) + printf(" %c", 'a' + (int)j); + else if (i < nservers) + printf(" %lu", j); + bp += sizeof(int32_t); + } + TCHECK2(bp[0], 13 * sizeof(int32_t)); + bp += 13 * sizeof(int32_t); + printf(" rwvol"); + UINTOUT(); + printf(" rovol"); + UINTOUT(); + printf(" backup"); + UINTOUT(); + } + break; + case 526: /* Get entry by ID U */ + case 527: /* Get entry by name U */ + { unsigned long nservers, j; + VECOUT(VLNAMEMAX); + printf(" numservers"); + TCHECK2(bp[0], sizeof(int32_t)); + nservers = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + printf(" %lu", nservers); + printf(" servers"); + for (i = 0; i < 13; i++) { + if (i < nservers) { + printf(" afsuuid"); + AFSUUIDOUT(); + } else { + TCHECK2(bp[0], 44); + bp += 44; + } + } + TCHECK2(bp[0], 4 * 13); + bp += 4 * 13; + printf(" partitions"); + for (i = 0; i < 13; i++) { + TCHECK2(bp[0], sizeof(int32_t)); + j = EXTRACT_32BITS(bp); + if (i < nservers && j <= 26) + printf(" %c", 'a' + (int)j); + else if (i < nservers) + printf(" %lu", j); + bp += sizeof(int32_t); + } + TCHECK2(bp[0], 13 * sizeof(int32_t)); + bp += 13 * sizeof(int32_t); + printf(" rwvol"); + UINTOUT(); + printf(" rovol"); + UINTOUT(); + printf(" backup"); + UINTOUT(); + } + default: + ; + } + + else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|vldb]"); +} + +/* + * Handle calls to the AFS Kerberos Authentication service + */ + +static void +kauth_print(register const u_char *bp, int length) +{ + int kauth_op; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from kauth/kauth.rg + */ + + kauth_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" kauth"); + + if (is_ubik(kauth_op)) { + ubik_print(bp); + return; + } + + + printf(" call %s", tok2str(kauth_req, "op#%d", kauth_op)); + + /* + * Decode some of the arguments to the KA calls + */ + + bp += sizeof(struct rx_header) + 4; + + switch (kauth_op) { + case 1: /* Authenticate old */; + case 21: /* Authenticate */ + case 22: /* Authenticate-V2 */ + case 2: /* Change PW */ + case 5: /* Set fields */ + case 6: /* Create user */ + case 7: /* Delete user */ + case 8: /* Get entry */ + case 14: /* Unlock */ + case 15: /* Lock status */ + printf(" principal"); + STROUT(KANAMEMAX); + STROUT(KANAMEMAX); + break; + case 3: /* GetTicket-old */ + case 23: /* GetTicket */ + { + int i; + printf(" kvno"); + INTOUT(); + printf(" domain"); + STROUT(KANAMEMAX); + TCHECK2(bp[0], sizeof(int32_t)); + i = (int) EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + TCHECK2(bp[0], i); + bp += i; + printf(" principal"); + STROUT(KANAMEMAX); + STROUT(KANAMEMAX); + break; + } + case 4: /* Set Password */ + printf(" principal"); + STROUT(KANAMEMAX); + STROUT(KANAMEMAX); + printf(" kvno"); + INTOUT(); + break; + case 12: /* Get password */ + printf(" name"); + STROUT(KANAMEMAX); + break; + default: + ; + } + + return; + +trunc: + printf(" [|kauth]"); +} + +/* + * Handle replies to the AFS Kerberos Authentication Service + */ + +static void +kauth_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + + if (length <= (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from kauth/kauth.rg + */ + + printf(" kauth"); + + if (is_ubik(opcode)) { + ubik_reply_print(bp, length, opcode); + return; + } + + printf(" reply %s", tok2str(kauth_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response. + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + /* Well, no, not really. Leave this for later */ + ; + else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|kauth]"); +} + +/* + * Handle calls to the AFS Volume location service + */ + +static void +vol_print(register const u_char *bp, int length) +{ + int vol_op; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from volser/volint.xg + */ + + vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" vol call %s", tok2str(vol_req, "op#%d", vol_op)); + + bp += sizeof(struct rx_header) + 4; + + switch (vol_op) { + case 100: /* Create volume */ + printf(" partition"); + UINTOUT(); + printf(" name"); + STROUT(AFSNAMEMAX); + printf(" type"); + UINTOUT(); + printf(" parent"); + UINTOUT(); + break; + case 101: /* Delete volume */ + case 107: /* Get flags */ + printf(" trans"); + UINTOUT(); + break; + case 102: /* Restore */ + printf(" totrans"); + UINTOUT(); + printf(" flags"); + UINTOUT(); + break; + case 103: /* Forward */ + printf(" fromtrans"); + UINTOUT(); + printf(" fromdate"); + DATEOUT(); + DESTSERVEROUT(); + printf(" desttrans"); + INTOUT(); + break; + case 104: /* End trans */ + printf(" trans"); + UINTOUT(); + break; + case 105: /* Clone */ + printf(" trans"); + UINTOUT(); + printf(" purgevol"); + UINTOUT(); + printf(" newtype"); + UINTOUT(); + printf(" newname"); + STROUT(AFSNAMEMAX); + break; + case 106: /* Set flags */ + printf(" trans"); + UINTOUT(); + printf(" flags"); + UINTOUT(); + break; + case 108: /* Trans create */ + printf(" vol"); + UINTOUT(); + printf(" partition"); + UINTOUT(); + printf(" flags"); + UINTOUT(); + break; + case 109: /* Dump */ + case 655537: /* Get size */ + printf(" fromtrans"); + UINTOUT(); + printf(" fromdate"); + DATEOUT(); + break; + case 110: /* Get n-th volume */ + printf(" index"); + UINTOUT(); + break; + case 111: /* Set forwarding */ + printf(" tid"); + UINTOUT(); + printf(" newsite"); + UINTOUT(); + break; + case 112: /* Get name */ + case 113: /* Get status */ + printf(" tid"); + break; + case 114: /* Signal restore */ + printf(" name"); + STROUT(AFSNAMEMAX); + printf(" type"); + UINTOUT(); + printf(" pid"); + UINTOUT(); + printf(" cloneid"); + UINTOUT(); + break; + case 116: /* List volumes */ + printf(" partition"); + UINTOUT(); + printf(" flags"); + UINTOUT(); + break; + case 117: /* Set id types */ + printf(" tid"); + UINTOUT(); + printf(" name"); + STROUT(AFSNAMEMAX); + printf(" type"); + UINTOUT(); + printf(" pid"); + UINTOUT(); + printf(" clone"); + UINTOUT(); + printf(" backup"); + UINTOUT(); + break; + case 119: /* Partition info */ + printf(" name"); + STROUT(AFSNAMEMAX); + break; + case 120: /* Reclone */ + printf(" tid"); + UINTOUT(); + break; + case 121: /* List one volume */ + case 122: /* Nuke volume */ + case 124: /* Extended List volumes */ + case 125: /* Extended List one volume */ + case 65536: /* Convert RO to RW volume */ + printf(" partid"); + UINTOUT(); + printf(" volid"); + UINTOUT(); + break; + case 123: /* Set date */ + printf(" tid"); + UINTOUT(); + printf(" date"); + DATEOUT(); + break; + case 126: /* Set info */ + printf(" tid"); + UINTOUT(); + break; + case 128: /* Forward multiple */ + printf(" fromtrans"); + UINTOUT(); + printf(" fromdate"); + DATEOUT(); + { + unsigned long i, j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + for (i = 0; i < j; i++) { + DESTSERVEROUT(); + if (i != j - 1) + printf(","); + } + if (j == 0) + printf(" <none!>"); + } + break; + case 65538: /* Dump version 2 */ + printf(" fromtrans"); + UINTOUT(); + printf(" fromdate"); + DATEOUT(); + printf(" flags"); + UINTOUT(); + break; + default: + ; + } + return; + +trunc: + printf(" [|vol]"); +} + +/* + * Handle replies to the AFS Volume Service + */ + +static void +vol_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + + if (length <= (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from volser/volint.xg + */ + + printf(" vol reply %s", tok2str(vol_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response. + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) { + switch (opcode) { + case 100: /* Create volume */ + printf(" volid"); + UINTOUT(); + printf(" trans"); + UINTOUT(); + break; + case 104: /* End transaction */ + UINTOUT(); + break; + case 105: /* Clone */ + printf(" newvol"); + UINTOUT(); + break; + case 107: /* Get flags */ + UINTOUT(); + break; + case 108: /* Transaction create */ + printf(" trans"); + UINTOUT(); + break; + case 110: /* Get n-th volume */ + printf(" volume"); + UINTOUT(); + printf(" partition"); + UINTOUT(); + break; + case 112: /* Get name */ + STROUT(AFSNAMEMAX); + break; + case 113: /* Get status */ + printf(" volid"); + UINTOUT(); + printf(" nextuniq"); + UINTOUT(); + printf(" type"); + UINTOUT(); + printf(" parentid"); + UINTOUT(); + printf(" clone"); + UINTOUT(); + printf(" backup"); + UINTOUT(); + printf(" restore"); + UINTOUT(); + printf(" maxquota"); + UINTOUT(); + printf(" minquota"); + UINTOUT(); + printf(" owner"); + UINTOUT(); + printf(" create"); + DATEOUT(); + printf(" access"); + DATEOUT(); + printf(" update"); + DATEOUT(); + printf(" expire"); + DATEOUT(); + printf(" backup"); + DATEOUT(); + printf(" copy"); + DATEOUT(); + break; + case 115: /* Old list partitions */ + break; + case 116: /* List volumes */ + case 121: /* List one volume */ + { + unsigned long i, j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + for (i = 0; i < j; i++) { + printf(" name"); + VECOUT(32); + printf(" volid"); + UINTOUT(); + printf(" type"); + bp += sizeof(int32_t) * 21; + if (i != j - 1) + printf(","); + } + if (j == 0) + printf(" <none!>"); + } + break; + + + default: + ; + } + } else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|vol]"); +} + +/* + * Handle calls to the AFS BOS service + */ + +static void +bos_print(register const u_char *bp, int length) +{ + int bos_op; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from bozo/bosint.xg + */ + + bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" bos call %s", tok2str(bos_req, "op#%d", bos_op)); + + /* + * Decode some of the arguments to the BOS calls + */ + + bp += sizeof(struct rx_header) + 4; + + switch (bos_op) { + case 80: /* Create B node */ + printf(" type"); + STROUT(BOSNAMEMAX); + printf(" instance"); + STROUT(BOSNAMEMAX); + break; + case 81: /* Delete B node */ + case 83: /* Get status */ + case 85: /* Get instance info */ + case 87: /* Add super user */ + case 88: /* Delete super user */ + case 93: /* Set cell name */ + case 96: /* Add cell host */ + case 97: /* Delete cell host */ + case 104: /* Restart */ + case 106: /* Uninstall */ + case 108: /* Exec */ + case 112: /* Getlog */ + case 114: /* Get instance strings */ + STROUT(BOSNAMEMAX); + break; + case 82: /* Set status */ + case 98: /* Set T status */ + STROUT(BOSNAMEMAX); + printf(" status"); + INTOUT(); + break; + case 86: /* Get instance parm */ + STROUT(BOSNAMEMAX); + printf(" num"); + INTOUT(); + break; + case 84: /* Enumerate instance */ + case 89: /* List super users */ + case 90: /* List keys */ + case 91: /* Add key */ + case 92: /* Delete key */ + case 95: /* Get cell host */ + INTOUT(); + break; + case 105: /* Install */ + STROUT(BOSNAMEMAX); + printf(" size"); + INTOUT(); + printf(" flags"); + INTOUT(); + printf(" date"); + INTOUT(); + break; + default: + ; + } + + return; + +trunc: + printf(" [|bos]"); +} + +/* + * Handle replies to the AFS BOS Service + */ + +static void +bos_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + + if (length <= (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from volser/volint.xg + */ + + printf(" bos reply %s", tok2str(bos_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response. + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + /* Well, no, not really. Leave this for later */ + ; + else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|bos]"); +} + +/* + * Check to see if this is a Ubik opcode. + */ + +static int +is_ubik(u_int32_t opcode) +{ + if ((opcode >= VOTE_LOW && opcode <= VOTE_HIGH) || + (opcode >= DISK_LOW && opcode <= DISK_HIGH)) + return(1); + else + return(0); +} + +/* + * Handle Ubik opcodes to any one of the replicated database services + */ + +static void +ubik_print(register const u_char *bp) +{ + int ubik_op; + int32_t temp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from ubik/ubik_int.xg + */ + + ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)); + + /* + * Decode some of the arguments to the Ubik calls + */ + + bp += sizeof(struct rx_header) + 4; + + switch (ubik_op) { + case 10000: /* Beacon */ + TCHECK2(bp[0], 4); + temp = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + printf(" syncsite %s", temp ? "yes" : "no"); + printf(" votestart"); + DATEOUT(); + printf(" dbversion"); + UBIK_VERSIONOUT(); + printf(" tid"); + UBIK_VERSIONOUT(); + break; + case 10003: /* Get sync site */ + printf(" site"); + UINTOUT(); + break; + case 20000: /* Begin */ + case 20001: /* Commit */ + case 20007: /* Abort */ + case 20008: /* Release locks */ + case 20010: /* Writev */ + printf(" tid"); + UBIK_VERSIONOUT(); + break; + case 20002: /* Lock */ + printf(" tid"); + UBIK_VERSIONOUT(); + printf(" file"); + INTOUT(); + printf(" pos"); + INTOUT(); + printf(" length"); + INTOUT(); + temp = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + tok2str(ubik_lock_types, "type %d", temp); + break; + case 20003: /* Write */ + printf(" tid"); + UBIK_VERSIONOUT(); + printf(" file"); + INTOUT(); + printf(" pos"); + INTOUT(); + break; + case 20005: /* Get file */ + printf(" file"); + INTOUT(); + break; + case 20006: /* Send file */ + printf(" file"); + INTOUT(); + printf(" length"); + INTOUT(); + printf(" dbversion"); + UBIK_VERSIONOUT(); + break; + case 20009: /* Truncate */ + printf(" tid"); + UBIK_VERSIONOUT(); + printf(" file"); + INTOUT(); + printf(" length"); + INTOUT(); + break; + case 20012: /* Set version */ + printf(" tid"); + UBIK_VERSIONOUT(); + printf(" oldversion"); + UBIK_VERSIONOUT(); + printf(" newversion"); + UBIK_VERSIONOUT(); + break; + default: + ; + } + + return; + +trunc: + printf(" [|ubik]"); +} + +/* + * Handle Ubik replies to any one of the replicated database services + */ + +static void +ubik_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + + if (length < (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the ubik call we're invoking. This table was gleaned + * from ubik/ubik_int.xg + */ + + printf(" ubik reply %s", tok2str(ubik_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, print out the arguments to the Ubik calls + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + switch (opcode) { + case 10000: /* Beacon */ + printf(" vote no"); + break; + case 20004: /* Get version */ + printf(" dbversion"); + UBIK_VERSIONOUT(); + break; + default: + ; + } + + /* + * Otherwise, print out "yes" it it was a beacon packet (because + * that's how yes votes are returned, go figure), otherwise + * just print out the error code. + */ + + else + switch (opcode) { + case 10000: /* Beacon */ + printf(" vote yes until"); + DATEOUT(); + break; + default: + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|ubik]"); +} + +/* + * Handle RX ACK packets. + */ + +static void +rx_ack_print(register const u_char *bp, int length) +{ + struct rx_ackPacket *rxa; + int i, start, last; + u_int32_t firstPacket; + + if (length < (int)sizeof(struct rx_header)) + return; + + bp += sizeof(struct rx_header); + + /* + * This may seem a little odd .... the rx_ackPacket structure + * contains an array of individual packet acknowledgements + * (used for selective ack/nack), but since it's variable in size, + * we don't want to truncate based on the size of the whole + * rx_ackPacket structure. + */ + + TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS); + + rxa = (struct rx_ackPacket *) bp; + bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS); + + /* + * Print out a few useful things from the ack packet structure + */ + + if (vflag > 2) + printf(" bufspace %d maxskew %d", + (int) EXTRACT_16BITS(&rxa->bufferSpace), + (int) EXTRACT_16BITS(&rxa->maxSkew)); + + firstPacket = EXTRACT_32BITS(&rxa->firstPacket); + printf(" first %d serial %d reason %s", + firstPacket, EXTRACT_32BITS(&rxa->serial), + tok2str(rx_ack_reasons, "#%d", (int) rxa->reason)); + + /* + * Okay, now we print out the ack array. The way _this_ works + * is that we start at "first", and step through the ack array. + * If we have a contiguous range of acks/nacks, try to + * collapse them into a range. + * + * If you're really clever, you might have noticed that this + * doesn't seem quite correct. Specifically, due to structure + * padding, sizeof(struct rx_ackPacket) - RX_MAXACKS won't actually + * yield the start of the ack array (because RX_MAXACKS is 255 + * and the structure will likely get padded to a 2 or 4 byte + * boundary). However, this is the way it's implemented inside + * of AFS - the start of the extra fields are at + * sizeof(struct rx_ackPacket) - RX_MAXACKS + nAcks, which _isn't_ + * the exact start of the ack array. Sigh. That's why we aren't + * using bp, but instead use rxa->acks[]. But nAcks gets added + * to bp after this, so bp ends up at the right spot. Go figure. + */ + + if (rxa->nAcks != 0) { + + TCHECK2(bp[0], rxa->nAcks); + + /* + * Sigh, this is gross, but it seems to work to collapse + * ranges correctly. + */ + + for (i = 0, start = last = -2; i < rxa->nAcks; i++) + if (rxa->acks[i] == RX_ACK_TYPE_ACK) { + + /* + * I figured this deserved _some_ explanation. + * First, print "acked" and the packet seq + * number if this is the first time we've + * seen an acked packet. + */ + + if (last == -2) { + printf(" acked %d", + firstPacket + i); + start = i; + } + + /* + * Otherwise, if the there is a skip in + * the range (such as an nacked packet in + * the middle of some acked packets), + * then print the current packet number + * seperated from the last number by + * a comma. + */ + + else if (last != i - 1) { + printf(",%d", firstPacket + i); + start = i; + } + + /* + * We always set last to the value of + * the last ack we saw. Conversely, start + * is set to the value of the first ack + * we saw in a range. + */ + + last = i; + + /* + * Okay, this bit a code gets executed when + * we hit a nack ... in _this_ case we + * want to print out the range of packets + * that were acked, so we need to print + * the _previous_ packet number seperated + * from the first by a dash (-). Since we + * already printed the first packet above, + * just print the final packet. Don't + * do this if there will be a single-length + * range. + */ + } else if (last == i - 1 && start != last) + printf("-%d", firstPacket + i - 1); + + /* + * So, what's going on here? We ran off the end of the + * ack list, and if we got a range we need to finish it up. + * So we need to determine if the last packet in the list + * was an ack (if so, then last will be set to it) and + * we need to see if the last range didn't start with the + * last packet (because if it _did_, then that would mean + * that the packet number has already been printed and + * we don't need to print it again). + */ + + if (last == i - 1 && start != last) + printf("-%d", firstPacket + i - 1); + + /* + * Same as above, just without comments + */ + + for (i = 0, start = last = -2; i < rxa->nAcks; i++) + if (rxa->acks[i] == RX_ACK_TYPE_NACK) { + if (last == -2) { + printf(" nacked %d", + firstPacket + i); + start = i; + } else if (last != i - 1) { + printf(",%d", firstPacket + i); + start = i; + } + last = i; + } else if (last == i - 1 && start != last) + printf("-%d", firstPacket + i - 1); + + if (last == i - 1 && start != last) + printf("-%d", firstPacket + i - 1); + + bp += rxa->nAcks; + } + + + /* + * These are optional fields; depending on your version of AFS, + * you may or may not see them + */ + +#define TRUNCRET(n) if (snapend - bp + 1 <= n) return; + + if (vflag > 1) { + TRUNCRET(4); + printf(" ifmtu"); + INTOUT(); + + TRUNCRET(4); + printf(" maxmtu"); + INTOUT(); + + TRUNCRET(4); + printf(" rwind"); + INTOUT(); + + TRUNCRET(4); + printf(" maxpackets"); + INTOUT(); + } + + return; + +trunc: + printf(" [|ack]"); +} +#undef TRUNCRET diff --git a/freebsd/contrib/tcpdump/print-sctp.c b/freebsd/contrib/tcpdump/print-sctp.c new file mode 100644 index 00000000..afd3f7d2 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-sctp.c @@ -0,0 +1,409 @@ +#include <machine/rtems-bsd-user-space.h> + +/* Copyright (c) 2001 NETLAB, Temple University + * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware + * + * Jerry Heinz <gheinz@astro.temple.edu> + * John Fiore <jfiore@joda.cis.temple.edu> + * Armando L. Caro Jr. <acaro@cis.udel.edu> + * + * 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. + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.21 2007-09-13 18:03:49 guy Exp $ (NETLAB/PEL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include "sctpHeader.h" +#include "sctpConstants.h" +#include <assert.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif + +#define CHAN_HP 6704 +#define CHAN_MP 6705 +#define CHAN_LP 6706 + +struct tok ForCES_channels[] = { + { CHAN_HP, "ForCES HP" }, + { CHAN_MP, "ForCES MP" }, + { CHAN_LP, "ForCES LP" }, + { 0, NULL } +}; + +static inline int isForCES_port(u_short Port) +{ + if (Port == CHAN_HP) + return 1; + if (Port == CHAN_MP) + return 1; + if (Port == CHAN_LP) + return 1; + + return 0; +} + +void sctp_print(const u_char *bp, /* beginning of sctp packet */ + const u_char *bp2, /* beginning of enclosing */ + u_int sctpPacketLength) /* ip packet */ +{ + const struct sctpHeader *sctpPktHdr; + const struct ip *ip; +#ifdef INET6 + const struct ip6_hdr *ip6; +#endif + const void *endPacketPtr; + u_short sourcePort, destPort; + int chunkCount; + const struct sctpChunkDesc *chunkDescPtr; + const void *nextChunk; + const char *sep; + int isforces = 0; + + + sctpPktHdr = (const struct sctpHeader*) bp; + endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength; + + if( (u_long) endPacketPtr > (u_long) snapend) + endPacketPtr = (const void *) snapend; + ip = (struct ip *)bp2; +#ifdef INET6 + if (IP_V(ip) == 6) + ip6 = (const struct ip6_hdr *)bp2; + else + ip6 = NULL; +#endif /*INET6*/ + TCHECK(*sctpPktHdr); + + if (sctpPacketLength < sizeof(struct sctpHeader)) + { + (void)printf("truncated-sctp - %ld bytes missing!", + (long)sctpPacketLength-sizeof(struct sctpHeader)); + return; + } + + /* sctpPacketLength -= sizeof(struct sctpHeader); packet length */ + /* is now only as long as the payload */ + + sourcePort = EXTRACT_16BITS(&sctpPktHdr->source); + destPort = EXTRACT_16BITS(&sctpPktHdr->destination); + +#ifdef INET6 + if (ip6) { + (void)printf("%s.%d > %s.%d: sctp", + ip6addr_string(&ip6->ip6_src), + sourcePort, + ip6addr_string(&ip6->ip6_dst), + destPort); + } else +#endif /*INET6*/ + { + (void)printf("%s.%d > %s.%d: sctp", + ipaddr_string(&ip->ip_src), + sourcePort, + ipaddr_string(&ip->ip_dst), + destPort); + } + fflush(stdout); + + if (isForCES_port(sourcePort)) { + printf("[%s]", tok2str(ForCES_channels, NULL, sourcePort)); + isforces = 1; + } + if (isForCES_port(destPort)) { + printf("[%s]", tok2str(ForCES_channels, NULL, destPort)); + isforces = 1; + } + + if (vflag >= 2) + sep = "\n\t"; + else + sep = " ("; + /* cycle through all chunks, printing information on each one */ + for (chunkCount = 0, + chunkDescPtr = (const struct sctpChunkDesc *) + ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader)); + chunkDescPtr != NULL && + ( (const void *) + ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc)) + <= endPacketPtr); + + chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++) + { + u_int16_t chunkLength; + const u_char *chunkEnd; + u_int16_t align; + + TCHECK(*chunkDescPtr); + chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength); + if (chunkLength < sizeof(*chunkDescPtr)) { + printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength); + break; + } + + TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength); + chunkEnd = ((const u_char*)chunkDescPtr + chunkLength); + + align=chunkLength % 4; + if (align != 0) + align = 4 - align; + + nextChunk = (const void *) (chunkEnd + align); + + printf("%s%d) ", sep, chunkCount+1); + switch (chunkDescPtr->chunkID) + { + case SCTP_DATA : + { + const struct sctpDataPart *dataHdrPtr; + + printf("[DATA] "); + + if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) + == SCTP_DATA_UNORDERED) + printf("(U)"); + + if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG) + == SCTP_DATA_FIRST_FRAG) + printf("(B)"); + + if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG) + == SCTP_DATA_LAST_FRAG) + printf("(E)"); + + if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) + == SCTP_DATA_UNORDERED) + || + ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG) + == SCTP_DATA_FIRST_FRAG) + || + ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG) + == SCTP_DATA_LAST_FRAG) ) + printf(" "); + + dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1); + + printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN)); + printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId)); + printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence)); + printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype)); + fflush(stdout); + if (isforces) { + const u_char *payloadPtr; + u_int chunksize = sizeof(struct sctpDataPart)+ + sizeof(struct sctpChunkDesc); + payloadPtr = (const u_char *) (dataHdrPtr + 1); + if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) < + sizeof(struct sctpDataPart)+ + sizeof(struct sctpChunkDesc)+1) { + /* Less than 1 byte of chunk payload */ + printf("bogus ForCES chunk length %u]", + EXTRACT_16BITS(&chunkDescPtr->chunkLength)); + return; + } + + forces_print(payloadPtr, EXTRACT_16BITS(&chunkDescPtr->chunkLength)- chunksize); + } else if (vflag >= 2) { /* if verbose output is specified */ + /* at the command line */ + const u_char *payloadPtr; + + printf("[Payload"); + + if (!suppress_default_print) { + payloadPtr = (const u_char *) (++dataHdrPtr); + printf(":"); + if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) < + sizeof(struct sctpDataPart)+ + sizeof(struct sctpChunkDesc)+1) { + /* Less than 1 byte of chunk payload */ + printf("bogus chunk length %u]", + EXTRACT_16BITS(&chunkDescPtr->chunkLength)); + return; + } + default_print(payloadPtr, + EXTRACT_16BITS(&chunkDescPtr->chunkLength) - + (sizeof(struct sctpDataPart)+ + sizeof(struct sctpChunkDesc))); + } else + printf("]"); + } + break; + } + case SCTP_INITIATION : + { + const struct sctpInitiation *init; + + printf("[INIT] "); + init=(const struct sctpInitiation*)(chunkDescPtr+1); + printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag)); + printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit)); + printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams)); + printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams)); + printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN)); + +#if(0) /* ALC you can add code for optional params here */ + if( (init+1) < chunkEnd ) + printf(" @@@@@ UNFINISHED @@@@@@%s\n", + "Optional params present, but not printed."); +#endif + break; + } + case SCTP_INITIATION_ACK : + { + const struct sctpInitiation *init; + + printf("[INIT ACK] "); + init=(const struct sctpInitiation*)(chunkDescPtr+1); + printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag)); + printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit)); + printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams)); + printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams)); + printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN)); + +#if(0) /* ALC you can add code for optional params here */ + if( (init+1) < chunkEnd ) + printf(" @@@@@ UNFINISHED @@@@@@%s\n", + "Optional params present, but not printed."); +#endif + break; + } + case SCTP_SELECTIVE_ACK: + { + const struct sctpSelectiveAck *sack; + const struct sctpSelectiveFrag *frag; + int fragNo, tsnNo; + const u_char *dupTSN; + + printf("[SACK] "); + sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1); + printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN)); + printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd)); + printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc)); + printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns)); + + + /* print gaps */ + for (frag = ( (const struct sctpSelectiveFrag *) + ((const struct sctpSelectiveAck *) sack+1)), + fragNo=0; + (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc); + frag++, fragNo++) + printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ", + fragNo+1, + EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart), + EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd)); + + + /* print duplicate TSNs */ + for (dupTSN = (const u_char *)frag, tsnNo=0; + (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns); + dupTSN += 4, tsnNo++) + printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1, + EXTRACT_32BITS(dupTSN)); + + break; + } + case SCTP_HEARTBEAT_REQUEST : + { + const struct sctpHBsender *hb; + + hb=(const struct sctpHBsender*)chunkDescPtr; + + printf("[HB REQ] "); + + break; + } + case SCTP_HEARTBEAT_ACK : + printf("[HB ACK] "); + break; + case SCTP_ABORT_ASSOCIATION : + printf("[ABORT] "); + break; + case SCTP_SHUTDOWN : + printf("[SHUTDOWN] "); + break; + case SCTP_SHUTDOWN_ACK : + printf("[SHUTDOWN ACK] "); + break; + case SCTP_OPERATION_ERR : + printf("[OP ERR] "); + break; + case SCTP_COOKIE_ECHO : + printf("[COOKIE ECHO] "); + break; + case SCTP_COOKIE_ACK : + printf("[COOKIE ACK] "); + break; + case SCTP_ECN_ECHO : + printf("[ECN ECHO] "); + break; + case SCTP_ECN_CWR : + printf("[ECN CWR] "); + break; + case SCTP_SHUTDOWN_COMPLETE : + printf("[SHUTDOWN COMPLETE] "); + break; + case SCTP_FORWARD_CUM_TSN : + printf("[FOR CUM TSN] "); + break; + case SCTP_RELIABLE_CNTL : + printf("[REL CTRL] "); + break; + case SCTP_RELIABLE_CNTL_ACK : + printf("[REL CTRL ACK] "); + break; + default : + printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID); + return; + } + + if (vflag < 2) + sep = ", ("; + } + return; + +trunc: + printf("[|sctp]"); + return; +} diff --git a/freebsd/contrib/tcpdump/print-sflow.c b/freebsd/contrib/tcpdump/print-sflow.c new file mode 100644 index 00000000..a82f7e81 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-sflow.c @@ -0,0 +1,936 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * The SFLOW protocol as per http://www.sflow.org/developers/specifications.php + * + * Original code by Carles Kishimoto <carles.kishimoto@gmail.com> + * + * Expansion and refactoring by Rick Jones <rick.jones2@hp.com> + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-sflow.c,v 1.1 2007-08-08 17:20:58 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * sFlow datagram + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sflow version (2,4,5) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IP version (1 for IPv4 | 2 for IPv6) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IP Address AGENT (4 or 16 bytes) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sub agent ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Datagram sequence number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Switch uptime in ms | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | num samples in datagram | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +struct sflow_datagram_t { + u_int8_t version[4]; + u_int8_t ip_version[4]; + u_int8_t agent[4]; + u_int8_t agent_id[4]; + u_int8_t seqnum[4]; + u_int8_t uptime[4]; + u_int8_t samples[4]; +}; + +struct sflow_sample_header { + u_int8_t format[4]; + u_int8_t len[4]; +}; + +#define SFLOW_FLOW_SAMPLE 1 +#define SFLOW_COUNTER_SAMPLE 2 +#define SFLOW_EXPANDED_FLOW_SAMPLE 3 +#define SFLOW_EXPANDED_COUNTER_SAMPLE 4 + +static const struct tok sflow_format_values[] = { + { SFLOW_FLOW_SAMPLE, "flow sample" }, + { SFLOW_COUNTER_SAMPLE, "counter sample" }, + { SFLOW_EXPANDED_FLOW_SAMPLE, "expanded flow sample" }, + { SFLOW_EXPANDED_COUNTER_SAMPLE, "expanded counter sample" }, + { 0, NULL} +}; + +struct sflow_flow_sample_t { + u_int8_t seqnum[4]; + u_int8_t typesource[4]; + u_int8_t rate[4]; + u_int8_t pool[4]; + u_int8_t drops[4]; + u_int8_t in_interface[4]; + u_int8_t out_interface[4]; + u_int8_t records[4]; + +}; + +struct sflow_expanded_flow_sample_t { + u_int8_t seqnum[4]; + u_int8_t type[4]; + u_int8_t index[4]; + u_int8_t rate[4]; + u_int8_t pool[4]; + u_int8_t drops[4]; + u_int8_t in_interface_format[4]; + u_int8_t in_interface_value[4]; + u_int8_t out_interface_format[4]; + u_int8_t out_interface_value[4]; + u_int8_t records[4]; +}; + +#define SFLOW_FLOW_RAW_PACKET 1 +#define SFLOW_FLOW_ETHERNET_FRAME 2 +#define SFLOW_FLOW_IPV4_DATA 3 +#define SFLOW_FLOW_IPV6_DATA 4 +#define SFLOW_FLOW_EXTENDED_SWITCH_DATA 1001 +#define SFLOW_FLOW_EXTENDED_ROUTER_DATA 1002 +#define SFLOW_FLOW_EXTENDED_GATEWAY_DATA 1003 +#define SFLOW_FLOW_EXTENDED_USER_DATA 1004 +#define SFLOW_FLOW_EXTENDED_URL_DATA 1005 +#define SFLOW_FLOW_EXTENDED_MPLS_DATA 1006 +#define SFLOW_FLOW_EXTENDED_NAT_DATA 1007 +#define SFLOW_FLOW_EXTENDED_MPLS_TUNNEL 1008 +#define SFLOW_FLOW_EXTENDED_MPLS_VC 1009 +#define SFLOW_FLOW_EXTENDED_MPLS_FEC 1010 +#define SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC 1011 +#define SFLOW_FLOW_EXTENDED_VLAN_TUNNEL 1012 + +static const struct tok sflow_flow_type_values[] = { + { SFLOW_FLOW_RAW_PACKET, "Raw packet"}, + { SFLOW_FLOW_ETHERNET_FRAME, "Ethernet frame"}, + { SFLOW_FLOW_IPV4_DATA, "IPv4 Data"}, + { SFLOW_FLOW_IPV6_DATA, "IPv6 Data"}, + { SFLOW_FLOW_EXTENDED_SWITCH_DATA, "Extended Switch data"}, + { SFLOW_FLOW_EXTENDED_ROUTER_DATA, "Extended Router data"}, + { SFLOW_FLOW_EXTENDED_GATEWAY_DATA, "Extended Gateway data"}, + { SFLOW_FLOW_EXTENDED_USER_DATA, "Extended User data"}, + { SFLOW_FLOW_EXTENDED_URL_DATA, "Extended URL data"}, + { SFLOW_FLOW_EXTENDED_MPLS_DATA, "Extended MPLS data"}, + { SFLOW_FLOW_EXTENDED_NAT_DATA, "Extended NAT data"}, + { SFLOW_FLOW_EXTENDED_MPLS_TUNNEL, "Extended MPLS tunnel"}, + { SFLOW_FLOW_EXTENDED_MPLS_VC, "Extended MPLS VC"}, + { SFLOW_FLOW_EXTENDED_MPLS_FEC, "Extended MPLS FEC"}, + { SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC, "Extended MPLS LVP FEC"}, + { SFLOW_FLOW_EXTENDED_VLAN_TUNNEL, "Extended VLAN Tunnel"}, + { 0, NULL} +}; + +#define SFLOW_HEADER_PROTOCOL_ETHERNET 1 +#define SFLOW_HEADER_PROTOCOL_IPV4 11 +#define SFLOW_HEADER_PROTOCOL_IPV6 12 + +static const struct tok sflow_flow_raw_protocol_values[] = { + { SFLOW_HEADER_PROTOCOL_ETHERNET, "Ethernet"}, + { SFLOW_HEADER_PROTOCOL_IPV4, "IPv4"}, + { SFLOW_HEADER_PROTOCOL_IPV6, "IPv6"}, + { 0, NULL} +}; + +struct sflow_expanded_flow_raw_t { + u_int8_t protocol[4]; + u_int8_t length[4]; + u_int8_t stripped_bytes[4]; + u_int8_t header_size[4]; +}; + +struct sflow_ethernet_frame_t { + u_int8_t length[4]; + u_int8_t src_mac[8]; + u_int8_t dst_mac[8]; + u_int8_t type[4]; +}; + +struct sflow_extended_switch_data_t { + u_int8_t src_vlan[4]; + u_int8_t src_pri[4]; + u_int8_t dst_vlan[4]; + u_int8_t dst_pri[4]; +}; + +struct sflow_counter_record_t { + u_int8_t format[4]; + u_int8_t length[4]; +}; + +struct sflow_flow_record_t { + u_int8_t format[4]; + u_int8_t length[4]; +}; + +struct sflow_counter_sample_t { + u_int8_t seqnum[4]; + u_int8_t typesource[4]; + u_int8_t records[4]; +}; + +struct sflow_expanded_counter_sample_t { + u_int8_t seqnum[4]; + u_int8_t type[4]; + u_int8_t index[4]; + u_int8_t records[4]; +}; + +#define SFLOW_COUNTER_GENERIC 1 +#define SFLOW_COUNTER_ETHERNET 2 +#define SFLOW_COUNTER_TOKEN_RING 3 +#define SFLOW_COUNTER_BASEVG 4 +#define SFLOW_COUNTER_VLAN 5 +#define SFLOW_COUNTER_PROCESSOR 1001 + +static const struct tok sflow_counter_type_values[] = { + { SFLOW_COUNTER_GENERIC, "Generic counter"}, + { SFLOW_COUNTER_ETHERNET, "Ethernet counter"}, + { SFLOW_COUNTER_TOKEN_RING, "Token ring counter"}, + { SFLOW_COUNTER_BASEVG, "100 BaseVG counter"}, + { SFLOW_COUNTER_VLAN, "Vlan counter"}, + { SFLOW_COUNTER_PROCESSOR, "Processor counter"}, + { 0, NULL} +}; + +#define SFLOW_IFACE_DIRECTION_UNKNOWN 0 +#define SFLOW_IFACE_DIRECTION_FULLDUPLEX 1 +#define SFLOW_IFACE_DIRECTION_HALFDUPLEX 2 +#define SFLOW_IFACE_DIRECTION_IN 3 +#define SFLOW_IFACE_DIRECTION_OUT 4 + +static const struct tok sflow_iface_direction_values[] = { + { SFLOW_IFACE_DIRECTION_UNKNOWN, "unknown"}, + { SFLOW_IFACE_DIRECTION_FULLDUPLEX, "full-duplex"}, + { SFLOW_IFACE_DIRECTION_HALFDUPLEX, "half-duplex"}, + { SFLOW_IFACE_DIRECTION_IN, "in"}, + { SFLOW_IFACE_DIRECTION_OUT, "out"}, + { 0, NULL} +}; + +struct sflow_generic_counter_t { + u_int8_t ifindex[4]; + u_int8_t iftype[4]; + u_int8_t ifspeed[8]; + u_int8_t ifdirection[4]; + u_int8_t ifstatus[4]; + u_int8_t ifinoctets[8]; + u_int8_t ifinunicastpkts[4]; + u_int8_t ifinmulticastpkts[4]; + u_int8_t ifinbroadcastpkts[4]; + u_int8_t ifindiscards[4]; + u_int8_t ifinerrors[4]; + u_int8_t ifinunkownprotos[4]; + u_int8_t ifoutoctets[8]; + u_int8_t ifoutunicastpkts[4]; + u_int8_t ifoutmulticastpkts[4]; + u_int8_t ifoutbroadcastpkts[4]; + u_int8_t ifoutdiscards[4]; + u_int8_t ifouterrors[4]; + u_int8_t ifpromiscmode[4]; +}; + +struct sflow_ethernet_counter_t { + u_int8_t alignerrors[4]; + u_int8_t fcserrors[4]; + u_int8_t single_collision_frames[4]; + u_int8_t multiple_collision_frames[4]; + u_int8_t test_errors[4]; + u_int8_t deferred_transmissions[4]; + u_int8_t late_collisions[4]; + u_int8_t excessive_collisions[4]; + u_int8_t mac_transmit_errors[4]; + u_int8_t carrier_sense_errors[4]; + u_int8_t frame_too_longs[4]; + u_int8_t mac_receive_errors[4]; + u_int8_t symbol_errors[4]; +}; + +struct sflow_100basevg_counter_t { + u_int8_t in_highpriority_frames[4]; + u_int8_t in_highpriority_octets[8]; + u_int8_t in_normpriority_frames[4]; + u_int8_t in_normpriority_octets[8]; + u_int8_t in_ipmerrors[4]; + u_int8_t in_oversized[4]; + u_int8_t in_data_errors[4]; + u_int8_t in_null_addressed_frames[4]; + u_int8_t out_highpriority_frames[4]; + u_int8_t out_highpriority_octets[8]; + u_int8_t transitioninto_frames[4]; + u_int8_t hc_in_highpriority_octets[8]; + u_int8_t hc_in_normpriority_octets[8]; + u_int8_t hc_out_highpriority_octets[8]; +}; + +struct sflow_vlan_counter_t { + u_int8_t vlan_id[4]; + u_int8_t octets[8]; + u_int8_t unicast_pkt[4]; + u_int8_t multicast_pkt[4]; + u_int8_t broadcast_pkt[4]; + u_int8_t discards[4]; +}; + +static int +print_sflow_counter_generic(const u_char *pointer, u_int len) { + + const struct sflow_generic_counter_t *sflow_gen_counter; + + if (len < sizeof(struct sflow_generic_counter_t)) + return 1; + + + sflow_gen_counter = (const struct sflow_generic_counter_t *)pointer; + printf("\n\t ifindex %u, iftype %u, ifspeed %" PRIu64 ", ifdirection %u (%s)", + EXTRACT_32BITS(sflow_gen_counter->ifindex), + EXTRACT_32BITS(sflow_gen_counter->iftype), + EXTRACT_64BITS(sflow_gen_counter->ifspeed), + EXTRACT_32BITS(sflow_gen_counter->ifdirection), + tok2str(sflow_iface_direction_values, "Unknown", + EXTRACT_32BITS(sflow_gen_counter->ifdirection))); + printf("\n\t ifstatus %u, adminstatus: %s, operstatus: %s", + EXTRACT_32BITS(sflow_gen_counter->ifstatus), + EXTRACT_32BITS(sflow_gen_counter->ifstatus)&1 ? "up" : "down", + (EXTRACT_32BITS(sflow_gen_counter->ifstatus)>>1)&1 ? "up" : "down"); + printf("\n\t In octets %" PRIu64 + ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u", + EXTRACT_64BITS(sflow_gen_counter->ifinoctets), + EXTRACT_32BITS(sflow_gen_counter->ifinunicastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifinmulticastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifinbroadcastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifindiscards)); + printf("\n\t In errors %u, unknown protos %u", + EXTRACT_32BITS(sflow_gen_counter->ifinerrors), + EXTRACT_32BITS(sflow_gen_counter->ifinunkownprotos)); + printf("\n\t Out octets %" PRIu64 + ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u", + EXTRACT_64BITS(sflow_gen_counter->ifoutoctets), + EXTRACT_32BITS(sflow_gen_counter->ifoutunicastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifoutmulticastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifoutbroadcastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifoutdiscards)); + printf("\n\t Out errors %u, promisc mode %u", + EXTRACT_32BITS(sflow_gen_counter->ifouterrors), + EXTRACT_32BITS(sflow_gen_counter->ifpromiscmode)); + + return 0; +} + +static int +print_sflow_counter_ethernet(const u_char *pointer, u_int len){ + + const struct sflow_ethernet_counter_t *sflow_eth_counter; + + if (len < sizeof(struct sflow_ethernet_counter_t)) + return 1; + + sflow_eth_counter = (const struct sflow_ethernet_counter_t *)pointer; + printf("\n\t align errors %u, fcs errors %u, single collision %u, multiple collision %u, test error %u", + EXTRACT_32BITS(sflow_eth_counter->alignerrors), + EXTRACT_32BITS(sflow_eth_counter->fcserrors), + EXTRACT_32BITS(sflow_eth_counter->single_collision_frames), + EXTRACT_32BITS(sflow_eth_counter->multiple_collision_frames), + EXTRACT_32BITS(sflow_eth_counter->test_errors)); + printf("\n\t deferred %u, late collision %u, excessive collision %u, mac trans error %u", + EXTRACT_32BITS(sflow_eth_counter->deferred_transmissions), + EXTRACT_32BITS(sflow_eth_counter->late_collisions), + EXTRACT_32BITS(sflow_eth_counter->excessive_collisions), + EXTRACT_32BITS(sflow_eth_counter->mac_transmit_errors)); + printf("\n\t carrier error %u, frames too long %u, mac receive errors %u, symbol errors %u", + EXTRACT_32BITS(sflow_eth_counter->carrier_sense_errors), + EXTRACT_32BITS(sflow_eth_counter->frame_too_longs), + EXTRACT_32BITS(sflow_eth_counter->mac_receive_errors), + EXTRACT_32BITS(sflow_eth_counter->symbol_errors)); + + return 0; +} + +static int +print_sflow_counter_token_ring(const u_char *pointer _U_, u_int len _U_) { + + return 0; +} + +static int +print_sflow_counter_basevg(const u_char *pointer, u_int len) { + + const struct sflow_100basevg_counter_t *sflow_100basevg_counter; + + if (len < sizeof(struct sflow_100basevg_counter_t)) + return 1; + + sflow_100basevg_counter = (const struct sflow_100basevg_counter_t *)pointer; + printf("\n\t in high prio frames %u, in high prio octets %" PRIu64, + EXTRACT_32BITS(sflow_100basevg_counter->in_highpriority_frames), + EXTRACT_64BITS(sflow_100basevg_counter->in_highpriority_octets)); + printf("\n\t in norm prio frames %u, in norm prio octets %" PRIu64, + EXTRACT_32BITS(sflow_100basevg_counter->in_normpriority_frames), + EXTRACT_64BITS(sflow_100basevg_counter->in_normpriority_octets)); + printf("\n\t in ipm errors %u, oversized %u, in data errors %u, null addressed frames %u", + EXTRACT_32BITS(sflow_100basevg_counter->in_ipmerrors), + EXTRACT_32BITS(sflow_100basevg_counter->in_oversized), + EXTRACT_32BITS(sflow_100basevg_counter->in_data_errors), + EXTRACT_32BITS(sflow_100basevg_counter->in_null_addressed_frames)); + printf("\n\t out high prio frames %u, out high prio octets %" PRIu64 + ", trans into frames %u", + EXTRACT_32BITS(sflow_100basevg_counter->out_highpriority_frames), + EXTRACT_64BITS(sflow_100basevg_counter->out_highpriority_octets), + EXTRACT_32BITS(sflow_100basevg_counter->transitioninto_frames)); + printf("\n\t in hc high prio octets %" PRIu64 + ", in hc norm prio octets %" PRIu64 + ", out hc high prio octets %" PRIu64, + EXTRACT_64BITS(sflow_100basevg_counter->hc_in_highpriority_octets), + EXTRACT_64BITS(sflow_100basevg_counter->hc_in_normpriority_octets), + EXTRACT_64BITS(sflow_100basevg_counter->hc_out_highpriority_octets)); + + return 0; +} + +static int +print_sflow_counter_vlan(const u_char *pointer, u_int len) { + + const struct sflow_vlan_counter_t *sflow_vlan_counter; + + if (len < sizeof(struct sflow_vlan_counter_t)) + return 1; + + sflow_vlan_counter = (const struct sflow_vlan_counter_t *)pointer; + printf("\n\t vlan_id %u, octets %" PRIu64 + ", unicast_pkt %u, multicast_pkt %u, broadcast_pkt %u, discards %u", + EXTRACT_32BITS(sflow_vlan_counter->vlan_id), + EXTRACT_64BITS(sflow_vlan_counter->octets), + EXTRACT_32BITS(sflow_vlan_counter->unicast_pkt), + EXTRACT_32BITS(sflow_vlan_counter->multicast_pkt), + EXTRACT_32BITS(sflow_vlan_counter->broadcast_pkt), + EXTRACT_32BITS(sflow_vlan_counter->discards)); + + return 0; +} + +struct sflow_processor_counter_t { + u_int8_t five_sec_util[4]; + u_int8_t one_min_util[4]; + u_int8_t five_min_util[4]; + u_int8_t total_memory[8]; + u_int8_t free_memory[8]; +}; + +static int +print_sflow_counter_processor(const u_char *pointer, u_int len) { + + const struct sflow_processor_counter_t *sflow_processor_counter; + + if (len < sizeof(struct sflow_processor_counter_t)) + return 1; + + sflow_processor_counter = (const struct sflow_processor_counter_t *)pointer; + printf("\n\t 5sec %u, 1min %u, 5min %u, total_mem %" PRIu64 + ", total_mem %" PRIu64, + EXTRACT_32BITS(sflow_processor_counter->five_sec_util), + EXTRACT_32BITS(sflow_processor_counter->one_min_util), + EXTRACT_32BITS(sflow_processor_counter->five_min_util), + EXTRACT_64BITS(sflow_processor_counter->total_memory), + EXTRACT_64BITS(sflow_processor_counter->free_memory)); + + return 0; +} + +static int +sflow_print_counter_records(const u_char *pointer, u_int len, u_int records) { + + u_int nrecords; + const u_char *tptr; + u_int tlen; + u_int counter_type; + u_int counter_len; + u_int enterprise; + const struct sflow_counter_record_t *sflow_counter_record; + + nrecords = records; + tptr = pointer; + tlen = len; + + while (nrecords > 0) { + /* do we have the "header?" */ + if (tlen < sizeof(struct sflow_counter_record_t)) + return 1; + sflow_counter_record = (const struct sflow_counter_record_t *)tptr; + + enterprise = EXTRACT_32BITS(sflow_counter_record->format); + counter_type = enterprise & 0x0FFF; + enterprise = enterprise >> 20; + counter_len = EXTRACT_32BITS(sflow_counter_record->length); + printf("\n\t enterprise %u, %s (%u) length %u", + enterprise, + (enterprise == 0) ? tok2str(sflow_counter_type_values,"Unknown",counter_type) : "Unknown", + counter_type, + counter_len); + + tptr += sizeof(struct sflow_counter_record_t); + tlen -= sizeof(struct sflow_counter_record_t); + + if (tlen < counter_len) + return 1; + if (enterprise == 0) { + switch (counter_type) { + case SFLOW_COUNTER_GENERIC: + if (print_sflow_counter_generic(tptr,tlen)) + return 1; + break; + case SFLOW_COUNTER_ETHERNET: + if (print_sflow_counter_ethernet(tptr,tlen)) + return 1; + break; + case SFLOW_COUNTER_TOKEN_RING: + if (print_sflow_counter_token_ring(tptr,tlen)) + return 1; + break; + case SFLOW_COUNTER_BASEVG: + if (print_sflow_counter_basevg(tptr,tlen)) + return 1; + break; + case SFLOW_COUNTER_VLAN: + if (print_sflow_counter_vlan(tptr,tlen)) + return 1; + break; + case SFLOW_COUNTER_PROCESSOR: + if (print_sflow_counter_processor(tptr,tlen)) + return 1; + break; + default: + if (vflag <= 1) + print_unknown_data(tptr, "\n\t\t", counter_len); + break; + } + } + tptr += counter_len; + tlen -= counter_len; + nrecords--; + + } + + return 0; +} + + +static int +sflow_print_counter_sample(const u_char *pointer, u_int len) { + + const struct sflow_counter_sample_t *sflow_counter_sample; + u_int nrecords; + u_int typesource; + u_int type; + u_int index; + + + if (len < sizeof(struct sflow_counter_sample_t)) + return 1; + + sflow_counter_sample = (const struct sflow_counter_sample_t *)pointer; + + typesource = EXTRACT_32BITS(sflow_counter_sample->typesource); + nrecords = EXTRACT_32BITS(sflow_counter_sample->records); + type = typesource >> 24; + index = typesource & 0x0FFF; + + printf(" seqnum %u, type %u, idx %u, records %u", + EXTRACT_32BITS(sflow_counter_sample->seqnum), + type, + index, + nrecords); + + return sflow_print_counter_records(pointer + sizeof(struct sflow_counter_sample_t), + len - sizeof(struct sflow_counter_sample_t), + nrecords); + +} + +static int +sflow_print_expanded_counter_sample(const u_char *pointer, u_int len) { + + const struct sflow_expanded_counter_sample_t *sflow_expanded_counter_sample; + u_int nrecords; + + + if (len < sizeof(struct sflow_expanded_counter_sample_t)) + return 1; + + sflow_expanded_counter_sample = (const struct sflow_expanded_counter_sample_t *)pointer; + + nrecords = EXTRACT_32BITS(sflow_expanded_counter_sample->records); + + printf(" seqnum %u, type %u, idx %u, records %u", + EXTRACT_32BITS(sflow_expanded_counter_sample->seqnum), + EXTRACT_32BITS(sflow_expanded_counter_sample->type), + EXTRACT_32BITS(sflow_expanded_counter_sample->index), + nrecords); + + return sflow_print_counter_records(pointer + sizeof(struct sflow_expanded_counter_sample_t), + len - sizeof(struct sflow_expanded_counter_sample_t), + nrecords); + +} + +static int +print_sflow_raw_packet(const u_char *pointer, u_int len) { + + const struct sflow_expanded_flow_raw_t *sflow_flow_raw; + + if (len < sizeof(struct sflow_expanded_flow_raw_t)) + return 1; + + sflow_flow_raw = (const struct sflow_expanded_flow_raw_t *)pointer; + printf("\n\t protocol %s (%u), length %u, stripped bytes %u, header_size %u", + tok2str(sflow_flow_raw_protocol_values,"Unknown",EXTRACT_32BITS(sflow_flow_raw->protocol)), + EXTRACT_32BITS(sflow_flow_raw->protocol), + EXTRACT_32BITS(sflow_flow_raw->length), + EXTRACT_32BITS(sflow_flow_raw->stripped_bytes), + EXTRACT_32BITS(sflow_flow_raw->header_size)); + + /* QUESTION - should we attempt to print the raw header itself? + assuming of course there is wnough data present to do so... */ + + return 0; +} + +static int +print_sflow_ethernet_frame(const u_char *pointer, u_int len) { + + const struct sflow_ethernet_frame_t *sflow_ethernet_frame; + + if (len < sizeof(struct sflow_ethernet_frame_t)) + return 1; + + sflow_ethernet_frame = (const struct sflow_ethernet_frame_t *)pointer; + + printf("\n\t frame len %u, type %u", + EXTRACT_32BITS(sflow_ethernet_frame->length), + EXTRACT_32BITS(sflow_ethernet_frame->type)); + + return 0; +} + +static int +print_sflow_extended_switch_data(const u_char *pointer, u_int len) { + + const struct sflow_extended_switch_data_t *sflow_extended_sw_data; + + if (len < sizeof(struct sflow_extended_switch_data_t)) + return 1; + + sflow_extended_sw_data = (const struct sflow_extended_switch_data_t *)pointer; + printf("\n\t src vlan %u, src pri %u, dst vlan %u, dst pri %u", + EXTRACT_32BITS(sflow_extended_sw_data->src_vlan), + EXTRACT_32BITS(sflow_extended_sw_data->src_pri), + EXTRACT_32BITS(sflow_extended_sw_data->dst_vlan), + EXTRACT_32BITS(sflow_extended_sw_data->dst_pri)); + + return 0; +} + +static int +sflow_print_flow_records(const u_char *pointer, u_int len, u_int records) { + + u_int nrecords; + const u_char *tptr; + u_int tlen; + u_int flow_type; + u_int enterprise; + u_int flow_len; + const struct sflow_flow_record_t *sflow_flow_record; + + nrecords = records; + tptr = pointer; + tlen = len; + + while (nrecords > 0) { + /* do we have the "header?" */ + if (tlen < sizeof(struct sflow_flow_record_t)) + return 1; + + sflow_flow_record = (const struct sflow_flow_record_t *)tptr; + + /* so, the funky encoding means we cannot blythly mask-off + bits, we must also check the enterprise. */ + + enterprise = EXTRACT_32BITS(sflow_flow_record->format); + flow_type = enterprise & 0x0FFF; + enterprise = enterprise >> 12; + flow_len = EXTRACT_32BITS(sflow_flow_record->length); + printf("\n\t enterprise %u %s (%u) length %u", + enterprise, + (enterprise == 0) ? tok2str(sflow_flow_type_values,"Unknown",flow_type) : "Unknown", + flow_type, + flow_len); + + tptr += sizeof(struct sflow_flow_record_t); + tlen -= sizeof(struct sflow_flow_record_t); + + if (tlen < flow_len) + return 1; + + if (enterprise == 0) { + switch (flow_type) { + case SFLOW_FLOW_RAW_PACKET: + if (print_sflow_raw_packet(tptr,tlen)) + return 1; + break; + case SFLOW_FLOW_EXTENDED_SWITCH_DATA: + if (print_sflow_extended_switch_data(tptr,tlen)) + return 1; + break; + case SFLOW_FLOW_ETHERNET_FRAME: + if (print_sflow_ethernet_frame(tptr,tlen)) + return 1; + break; + /* FIXME these need a decoder */ + case SFLOW_FLOW_IPV4_DATA: + case SFLOW_FLOW_IPV6_DATA: + case SFLOW_FLOW_EXTENDED_ROUTER_DATA: + case SFLOW_FLOW_EXTENDED_GATEWAY_DATA: + case SFLOW_FLOW_EXTENDED_USER_DATA: + case SFLOW_FLOW_EXTENDED_URL_DATA: + case SFLOW_FLOW_EXTENDED_MPLS_DATA: + case SFLOW_FLOW_EXTENDED_NAT_DATA: + case SFLOW_FLOW_EXTENDED_MPLS_TUNNEL: + case SFLOW_FLOW_EXTENDED_MPLS_VC: + case SFLOW_FLOW_EXTENDED_MPLS_FEC: + case SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC: + case SFLOW_FLOW_EXTENDED_VLAN_TUNNEL: + break; + default: + if (vflag <= 1) + print_unknown_data(tptr, "\n\t\t", flow_len); + break; + } + } + tptr += flow_len; + tlen -= flow_len; + nrecords--; + + } + + return 0; +} + +static int +sflow_print_flow_sample(const u_char *pointer, u_int len) { + + const struct sflow_flow_sample_t *sflow_flow_sample; + u_int nrecords; + u_int typesource; + u_int type; + u_int index; + + if (len < sizeof(struct sflow_flow_sample_t)) + return 1; + + sflow_flow_sample = (struct sflow_flow_sample_t *)pointer; + + typesource = EXTRACT_32BITS(sflow_flow_sample->typesource); + nrecords = EXTRACT_32BITS(sflow_flow_sample->records); + type = typesource >> 24; + index = typesource & 0x0FFF; + + printf(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, input %u output %u records %u", + EXTRACT_32BITS(sflow_flow_sample->seqnum), + type, + index, + EXTRACT_32BITS(sflow_flow_sample->rate), + EXTRACT_32BITS(sflow_flow_sample->pool), + EXTRACT_32BITS(sflow_flow_sample->drops), + EXTRACT_32BITS(sflow_flow_sample->in_interface), + EXTRACT_32BITS(sflow_flow_sample->out_interface), + nrecords); + + return sflow_print_flow_records(pointer + sizeof(struct sflow_flow_sample_t), + len - sizeof(struct sflow_flow_sample_t), + nrecords); + +} + +static int +sflow_print_expanded_flow_sample(const u_char *pointer, u_int len) { + + const struct sflow_expanded_flow_sample_t *sflow_expanded_flow_sample; + u_int nrecords; + + if (len < sizeof(struct sflow_expanded_flow_sample_t)) + return 1; + + sflow_expanded_flow_sample = (const struct sflow_expanded_flow_sample_t *)pointer; + + nrecords = EXTRACT_32BITS(sflow_expanded_flow_sample->records); + + printf(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, records %u", + EXTRACT_32BITS(sflow_expanded_flow_sample->seqnum), + EXTRACT_32BITS(sflow_expanded_flow_sample->type), + EXTRACT_32BITS(sflow_expanded_flow_sample->index), + EXTRACT_32BITS(sflow_expanded_flow_sample->rate), + EXTRACT_32BITS(sflow_expanded_flow_sample->pool), + EXTRACT_32BITS(sflow_expanded_flow_sample->drops), + EXTRACT_32BITS(sflow_expanded_flow_sample->records)); + + return sflow_print_flow_records(pointer + sizeof(struct sflow_expanded_flow_sample_t), + len - sizeof(struct sflow_expanded_flow_sample_t), + nrecords); + +} + +void +sflow_print(const u_char *pptr, u_int len) { + + const struct sflow_datagram_t *sflow_datagram; + const struct sflow_sample_header *sflow_sample; + + const u_char *tptr; + u_int tlen; + u_int32_t sflow_sample_type, sflow_sample_len; + u_int32_t nsamples; + + + tptr = pptr; + tlen = len; + sflow_datagram = (const struct sflow_datagram_t *)pptr; + TCHECK(*sflow_datagram); + + /* + * Sanity checking of the header. + */ + if (EXTRACT_32BITS(sflow_datagram->version) != 5) { + printf("sFlow version %u packet not supported", + EXTRACT_32BITS(sflow_datagram->version)); + return; + } + + if (vflag < 1) { + printf("sFlowv%u, %s agent %s, agent-id %u, length %u", + EXTRACT_32BITS(sflow_datagram->version), + EXTRACT_32BITS(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6", + ipaddr_string(sflow_datagram->agent), + EXTRACT_32BITS(sflow_datagram->samples), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + nsamples=EXTRACT_32BITS(sflow_datagram->samples); + printf("sFlowv%u, %s agent %s, agent-id %u, seqnum %u, uptime %u, samples %u, length %u", + EXTRACT_32BITS(sflow_datagram->version), + EXTRACT_32BITS(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6", + ipaddr_string(sflow_datagram->agent), + EXTRACT_32BITS(sflow_datagram->agent_id), + EXTRACT_32BITS(sflow_datagram->seqnum), + EXTRACT_32BITS(sflow_datagram->uptime), + nsamples, + len); + + /* skip Common header */ + tptr += sizeof(const struct sflow_datagram_t); + tlen -= sizeof(const struct sflow_datagram_t); + + while (nsamples > 0 && tlen > 0) { + sflow_sample = (const struct sflow_sample_header *)tptr; + TCHECK(*sflow_sample); + + sflow_sample_type = (EXTRACT_32BITS(sflow_sample->format)&0x0FFF); + sflow_sample_len = EXTRACT_32BITS(sflow_sample->len); + + if (tlen < sizeof(struct sflow_sample_header)) + goto trunc; + + tptr += sizeof(struct sflow_sample_header); + tlen -= sizeof(struct sflow_sample_header); + + printf("\n\t%s (%u), length %u,", + tok2str(sflow_format_values, "Unknown", sflow_sample_type), + sflow_sample_type, + sflow_sample_len); + + /* basic sanity check */ + if (sflow_sample_type == 0 || sflow_sample_len ==0) { + return; + } + + if (tlen < sflow_sample_len) + goto trunc; + + /* did we capture enough for fully decoding the sample ? */ + TCHECK2(*tptr, sflow_sample_len); + + switch(sflow_sample_type) { + case SFLOW_FLOW_SAMPLE: + if (sflow_print_flow_sample(tptr,tlen)) + goto trunc; + break; + + case SFLOW_COUNTER_SAMPLE: + if (sflow_print_counter_sample(tptr,tlen)) + goto trunc; + break; + + case SFLOW_EXPANDED_FLOW_SAMPLE: + if (sflow_print_expanded_flow_sample(tptr,tlen)) + goto trunc; + break; + + case SFLOW_EXPANDED_COUNTER_SAMPLE: + if (sflow_print_expanded_counter_sample(tptr,tlen)) + goto trunc; + break; + + default: + if (vflag <= 1) + print_unknown_data(tptr, "\n\t ", sflow_sample_len); + break; + } + tptr += sflow_sample_len; + tlen -= sflow_sample_len; + nsamples--; + } + return; + + trunc: + printf("[|SFLOW]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-sip.c b/freebsd/contrib/tcpdump/print-sip.c new file mode 100644 index 00000000..266fcbe7 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-sip.c @@ -0,0 +1,66 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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-sip.c,v 1.1 2004-07-27 17:04:20 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "interface.h" +#include "extract.h" + +#include "udp.h" + +void +sip_print(register const u_char *pptr, register u_int len) +{ + u_int idx; + + printf("SIP, length: %u%s", len, vflag ? "\n\t" : ""); + + /* in non-verbose mode just lets print the protocol and length */ + if (vflag < 1) + return; + + for (idx = 0; idx < len; idx++) { + TCHECK2(*(pptr+idx), 2); + if (EXTRACT_16BITS(pptr+idx) != 0x0d0a) { /* linefeed ? */ + safeputchar(*(pptr+idx)); + } else { + printf("\n\t"); + idx+=1; + } + } + + /* do we want to see an additionally hexdump ? */ + if (vflag> 1) + print_unknown_data(pptr,"\n\t",len); + + return; + +trunc: + printf("[|sip]"); +} diff --git a/freebsd/contrib/tcpdump/print-sl.c b/freebsd/contrib/tcpdump/print-sl.c new file mode 100644 index 00000000..9496a918 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-sl.c @@ -0,0 +1,243 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * $FreeBSD$ + */ + +#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 <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> + +#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)); +} diff --git a/freebsd/contrib/tcpdump/print-sll.c b/freebsd/contrib/tcpdump/print-sll.c new file mode 100644 index 00000000..264eeb30 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-sll.c @@ -0,0 +1,233 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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-sll.c,v 1.19 2005-11-13 12:12:43 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> +#include <pcap.h> + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "extract.h" + +#include "ether.h" +#include "sll.h" + +const struct tok sll_pkttype_values[] = { + { LINUX_SLL_HOST, "In" }, + { LINUX_SLL_BROADCAST, "B" }, + { LINUX_SLL_MULTICAST, "M" }, + { LINUX_SLL_OTHERHOST, "P" }, + { LINUX_SLL_OUTGOING, "Out" }, + { 0, NULL} +}; + +static inline void +sll_print(register const struct sll_header *sllp, u_int length) +{ + u_short ether_type; + + printf("%3s ",tok2str(sll_pkttype_values,"?",EXTRACT_16BITS(&sllp->sll_pkttype))); + + /* + * XXX - check the link-layer address type value? + * For now, we just assume 6 means Ethernet. + * XXX - print others as strings of hex? + */ + if (EXTRACT_16BITS(&sllp->sll_halen) == 6) + (void)printf("%s ", etheraddr_string(sllp->sll_addr)); + + if (!qflag) { + ether_type = EXTRACT_16BITS(&sllp->sll_protocol); + + if (ether_type <= ETHERMTU) { + /* + * Not an Ethernet type; what type is it? + */ + switch (ether_type) { + + case LINUX_SLL_P_802_3: + /* + * Ethernet_802.3 IPX frame. + */ + (void)printf("802.3"); + break; + + case LINUX_SLL_P_802_2: + /* + * 802.2. + */ + (void)printf("802.2"); + break; + + default: + /* + * What is it? + */ + (void)printf("ethertype Unknown (0x%04x)", + ether_type); + break; + } + } else { + (void)printf("ethertype %s (0x%04x)", + tok2str(ethertype_values, "Unknown", ether_type), + ether_type); + } + (void)printf(", length %u: ", length); + } +} + +/* + * This is the top level routine of the printer. 'p' points to the + * Linux "cooked capture" 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 +sll_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + register const struct sll_header *sllp; + u_short ether_type; + u_short extracted_ethertype; + + if (caplen < SLL_HDR_LEN) { + /* + * XXX - this "can't happen" because "pcap-linux.c" always + * adds this many bytes of header to every packet in a + * cooked socket capture. + */ + printf("[|sll]"); + return (caplen); + } + + sllp = (const struct sll_header *)p; + + if (eflag) + sll_print(sllp, length); + + /* + * Go past the cooked-mode header. + */ + length -= SLL_HDR_LEN; + caplen -= SLL_HDR_LEN; + p += SLL_HDR_LEN; + + ether_type = EXTRACT_16BITS(&sllp->sll_protocol); + +recurse: + /* + * Is it (gag) an 802.3 encapsulation, or some non-Ethernet + * packet type? + */ + if (ether_type <= ETHERMTU) { + /* + * Yes - what type is it? + */ + switch (ether_type) { + + case LINUX_SLL_P_802_3: + /* + * Ethernet_802.3 IPX frame. + */ + ipx_print(p, length); + break; + + case LINUX_SLL_P_802_2: + /* + * 802.2. + * Try to print the LLC-layer header & higher layers. + */ + if (llc_print(p, length, caplen, NULL, NULL, + &extracted_ethertype) == 0) + goto unknown; /* unknown LLC type */ + break; + + default: + extracted_ethertype = 0; + /*FALLTHROUGH*/ + + unknown: + /* ether_type not known, print raw packet */ + if (!eflag) + sll_print(sllp, length + SLL_HDR_LEN); + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + break; + } + } else if (ether_type == ETHERTYPE_8021Q) { + /* + * Print VLAN information, and then go back and process + * the enclosed type field. + */ + if (caplen < 4 || length < 4) { + printf("[|vlan]"); + return (SLL_HDR_LEN); + } + if (eflag) { + u_int16_t tag = EXTRACT_16BITS(p); + + printf("vlan %u, p %u%s, ", + tag & 0xfff, + tag >> 13, + (tag & 0x1000) ? ", CFI" : ""); + } + + ether_type = EXTRACT_16BITS(p + 2); + if (ether_type <= ETHERMTU) + ether_type = LINUX_SLL_P_802_2; + if (!qflag) { + (void)printf("ethertype %s, ", + tok2str(ethertype_values, "Unknown", ether_type)); + } + p += 4; + length -= 4; + caplen -= 4; + goto recurse; + } else { + if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + sll_print(sllp, length + SLL_HDR_LEN); + if (!suppress_default_print) + default_print(p, caplen); + } + } + + return (SLL_HDR_LEN); +} diff --git a/freebsd/contrib/tcpdump/print-slow.c b/freebsd/contrib/tcpdump/print-slow.c new file mode 100644 index 00000000..f4430887 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-slow.c @@ -0,0 +1,663 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#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; +} diff --git a/freebsd/contrib/tcpdump/print-smb.c b/freebsd/contrib/tcpdump/print-smb.c new file mode 100644 index 00000000..ba826762 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-smb.c @@ -0,0 +1,1512 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (C) Andrew Tridgell 1995-1999 + * + * This software may be distributed either under the terms of the + * BSD-style license that accompanies tcpdump or the GNU GPL version 2 + * or later + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-smb.c,v 1.47 2007-12-09 00:30:47 guy Exp $"; +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "smb.h" + +static int request = 0; +static int unicodestr = 0; + +const u_char *startbuf = NULL; + +struct smbdescript { + const char *req_f1; + const char *req_f2; + const char *rep_f1; + const char *rep_f2; + void (*fn)(const u_char *, const u_char *, const u_char *, const u_char *); +}; + +struct smbdescriptint { + const char *req_f1; + const char *req_f2; + const char *rep_f1; + const char *rep_f2; + void (*fn)(const u_char *, const u_char *, int, int); +}; + +struct smbfns +{ + int id; + const char *name; + int flags; + struct smbdescript descript; +}; + +struct smbfnsint +{ + int id; + const char *name; + int flags; + struct smbdescriptint descript; +}; + +#define DEFDESCRIPT { NULL, NULL, NULL, NULL, NULL } + +#define FLG_CHAIN (1 << 0) + +static struct smbfns * +smbfind(int id, struct smbfns *list) +{ + int sindex; + + for (sindex = 0; list[sindex].name; sindex++) + if (list[sindex].id == id) + return(&list[sindex]); + + return(&list[0]); +} + +static struct smbfnsint * +smbfindint(int id, struct smbfnsint *list) +{ + int sindex; + + for (sindex = 0; list[sindex].name; sindex++) + if (list[sindex].id == id) + return(&list[sindex]); + + return(&list[0]); +} + +static void +trans2_findfirst(const u_char *param, const u_char *data, int pcnt, int dcnt) +{ + const char *fmt; + + if (request) + fmt = "Attribute=[A]\nSearchCount=[d]\nFlags=[w]\nLevel=[dP4]\nFile=[S]\n"; + else + fmt = "Handle=[w]\nCount=[d]\nEOS=[w]\nEoffset=[d]\nLastNameOfs=[w]\n"; + + smb_fdata(param, fmt, param + pcnt, unicodestr); + if (dcnt) { + printf("data:\n"); + print_data(data, dcnt); + } +} + +static void +trans2_qfsinfo(const u_char *param, const u_char *data, int pcnt, int dcnt) +{ + static int level = 0; + const char *fmt=""; + + if (request) { + TCHECK2(*param, 2); + level = EXTRACT_LE_16BITS(param); + fmt = "InfoLevel=[d]\n"; + smb_fdata(param, fmt, param + pcnt, unicodestr); + } else { + switch (level) { + case 1: + fmt = "idFileSystem=[W]\nSectorUnit=[D]\nUnit=[D]\nAvail=[D]\nSectorSize=[d]\n"; + break; + case 2: + fmt = "CreationTime=[T2]VolNameLength=[lb]\nVolumeLabel=[c]\n"; + break; + case 0x105: + fmt = "Capabilities=[W]\nMaxFileLen=[D]\nVolNameLen=[lD]\nVolume=[C]\n"; + break; + default: + fmt = "UnknownLevel\n"; + break; + } + smb_fdata(data, fmt, data + dcnt, unicodestr); + } + if (dcnt) { + printf("data:\n"); + print_data(data, dcnt); + } + return; +trunc: + printf("[|SMB]"); + return; +} + +struct smbfnsint trans2_fns[] = { + { 0, "TRANSACT2_OPEN", 0, + { "Flags2=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]\nOFun=[w]\nSize=[D]\nRes=([w, w, w, w, w])\nPath=[S]", + NULL, + "Handle=[d]\nAttrib=[A]\nTime=[T2]\nSize=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nInode=[W]\nOffErr=[d]\n|EALength=[d]\n", + NULL, NULL }}, + { 1, "TRANSACT2_FINDFIRST", 0, + { NULL, NULL, NULL, NULL, trans2_findfirst }}, + { 2, "TRANSACT2_FINDNEXT", 0, DEFDESCRIPT }, + { 3, "TRANSACT2_QFSINFO", 0, + { NULL, NULL, NULL, NULL, trans2_qfsinfo }}, + { 4, "TRANSACT2_SETFSINFO", 0, DEFDESCRIPT }, + { 5, "TRANSACT2_QPATHINFO", 0, DEFDESCRIPT }, + { 6, "TRANSACT2_SETPATHINFO", 0, DEFDESCRIPT }, + { 7, "TRANSACT2_QFILEINFO", 0, DEFDESCRIPT }, + { 8, "TRANSACT2_SETFILEINFO", 0, DEFDESCRIPT }, + { 9, "TRANSACT2_FSCTL", 0, DEFDESCRIPT }, + { 10, "TRANSACT2_IOCTL", 0, DEFDESCRIPT }, + { 11, "TRANSACT2_FINDNOTIFYFIRST", 0, DEFDESCRIPT }, + { 12, "TRANSACT2_FINDNOTIFYNEXT", 0, DEFDESCRIPT }, + { 13, "TRANSACT2_MKDIR", 0, DEFDESCRIPT }, + { -1, NULL, 0, DEFDESCRIPT } +}; + + +static void +print_trans2(const u_char *words, const u_char *dat, const u_char *buf, const u_char *maxbuf) +{ + u_int bcc; + static struct smbfnsint *fn = &trans2_fns[0]; + const u_char *data, *param; + const u_char *w = words + 1; + const char *f1 = NULL, *f2 = NULL; + int pcnt, dcnt; + + TCHECK(words[0]); + if (request) { + TCHECK2(w[14 * 2], 2); + pcnt = EXTRACT_LE_16BITS(w + 9 * 2); + param = buf + EXTRACT_LE_16BITS(w + 10 * 2); + dcnt = EXTRACT_LE_16BITS(w + 11 * 2); + data = buf + EXTRACT_LE_16BITS(w + 12 * 2); + fn = smbfindint(EXTRACT_LE_16BITS(w + 14 * 2), trans2_fns); + } else { + if (words[0] == 0) { + printf("%s\n", fn->name); + printf("Trans2Interim\n"); + return; + } + TCHECK2(w[7 * 2], 2); + pcnt = EXTRACT_LE_16BITS(w + 3 * 2); + param = buf + EXTRACT_LE_16BITS(w + 4 * 2); + dcnt = EXTRACT_LE_16BITS(w + 6 * 2); + data = buf + EXTRACT_LE_16BITS(w + 7 * 2); + } + + printf("%s param_length=%d data_length=%d\n", fn->name, pcnt, dcnt); + + if (request) { + if (words[0] == 8) { + smb_fdata(words + 1, + "Trans2Secondary\nTotParam=[d]\nTotData=[d]\nParamCnt=[d]\nParamOff=[d]\nParamDisp=[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nHandle=[d]\n", + maxbuf, unicodestr); + return; + } else { + smb_fdata(words + 1, + "TotParam=[d]\nTotData=[d]\nMaxParam=[d]\nMaxData=[d]\nMaxSetup=[b][P1]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nDataCnt=[d]\nDataOff=[d]\nSetupCnt=[b][P1]\n", + words + 1 + 14 * 2, unicodestr); + } + f1 = fn->descript.req_f1; + f2 = fn->descript.req_f2; + } else { + smb_fdata(words + 1, + "TotParam=[d]\nTotData=[d]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nParamDisp[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nSetupCnt=[b][P1]\n", + words + 1 + 10 * 2, unicodestr); + f1 = fn->descript.rep_f1; + f2 = fn->descript.rep_f2; + } + + TCHECK2(*dat, 2); + bcc = EXTRACT_LE_16BITS(dat); + printf("smb_bcc=%u\n", bcc); + if (fn->descript.fn) + (*fn->descript.fn)(param, data, pcnt, dcnt); + else { + smb_fdata(param, f1 ? f1 : "Parameters=\n", param + pcnt, unicodestr); + smb_fdata(data, f2 ? f2 : "Data=\n", data + dcnt, unicodestr); + } + return; +trunc: + printf("[|SMB]"); + return; +} + + +static void +print_browse(const u_char *param, int paramlen, const u_char *data, int datalen) +{ + const u_char *maxbuf = data + datalen; + int command; + + TCHECK(data[0]); + command = data[0]; + + smb_fdata(param, "BROWSE PACKET\n|Param ", param+paramlen, unicodestr); + + switch (command) { + case 0xF: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (LocalMasterAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n", + maxbuf, unicodestr); + break; + + case 0x1: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (HostAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n", + maxbuf, unicodestr); + break; + + case 0x2: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (AnnouncementRequest)\nFlags=[B]\nReplySystemName=[S]\n", + maxbuf, unicodestr); + break; + + case 0xc: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (WorkgroupAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nCommentPointer=[W]\nServerName=[S]\n", + maxbuf, unicodestr); + break; + + case 0x8: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (ElectionFrame)\nElectionVersion=[B]\nOSSummary=[W]\nUptime=[(W, W)]\nServerName=[S]\n", + maxbuf, unicodestr); + break; + + case 0xb: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (BecomeBackupBrowser)\nName=[S]\n", + maxbuf, unicodestr); + break; + + case 0x9: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (GetBackupList)\nListCount?=[B]\nToken=[W]\n", + maxbuf, unicodestr); + break; + + case 0xa: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (BackupListResponse)\nServerCount?=[B]\nToken=[W]\n*Name=[S]\n", + maxbuf, unicodestr); + break; + + case 0xd: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (MasterAnnouncement)\nMasterName=[S]\n", + maxbuf, unicodestr); + break; + + case 0xe: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (ResetBrowser)\nOptions=[B]\n", maxbuf, unicodestr); + break; + + default: + data = smb_fdata(data, "Unknown Browser Frame ", maxbuf, unicodestr); + break; + } + return; +trunc: + printf("[|SMB]"); + return; +} + + +static void +print_ipc(const u_char *param, int paramlen, const u_char *data, int datalen) +{ + if (paramlen) + smb_fdata(param, "Command=[w]\nStr1=[S]\nStr2=[S]\n", param + paramlen, + unicodestr); + if (datalen) + smb_fdata(data, "IPC ", data + datalen, unicodestr); +} + + +static void +print_trans(const u_char *words, const u_char *data1, const u_char *buf, const u_char *maxbuf) +{ + u_int bcc; + const char *f1, *f2, *f3, *f4; + const u_char *data, *param; + const u_char *w = words + 1; + int datalen, paramlen; + + if (request) { + TCHECK2(w[12 * 2], 2); + paramlen = EXTRACT_LE_16BITS(w + 9 * 2); + param = buf + EXTRACT_LE_16BITS(w + 10 * 2); + datalen = EXTRACT_LE_16BITS(w + 11 * 2); + data = buf + EXTRACT_LE_16BITS(w + 12 * 2); + f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nMaxParmCnt=[d] \nMaxDataCnt=[d]\nMaxSCnt=[d] \nTransFlags=[w] \nRes1=[w] \nRes2=[w] \nRes3=[w]\nParamCnt=[d] \nParamOff=[d] \nDataCnt=[d] \nDataOff=[d] \nSUCnt=[d]\n"; + f2 = "|Name=[S]\n"; + f3 = "|Param "; + f4 = "|Data "; + } else { + TCHECK2(w[7 * 2], 2); + paramlen = EXTRACT_LE_16BITS(w + 3 * 2); + param = buf + EXTRACT_LE_16BITS(w + 4 * 2); + datalen = EXTRACT_LE_16BITS(w + 6 * 2); + data = buf + EXTRACT_LE_16BITS(w + 7 * 2); + f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nRes1=[d]\nParamCnt=[d] \nParamOff=[d] \nRes2=[d] \nDataCnt=[d] \nDataOff=[d] \nRes3=[d]\nLsetup=[d]\n"; + f2 = "|Unknown "; + f3 = "|Param "; + f4 = "|Data "; + } + + smb_fdata(words + 1, f1, SMBMIN(words + 1 + 2 * words[0], maxbuf), + unicodestr); + + TCHECK2(*data1, 2); + bcc = EXTRACT_LE_16BITS(data1); + printf("smb_bcc=%u\n", bcc); + if (bcc > 0) { + smb_fdata(data1 + 2, f2, maxbuf - (paramlen + datalen), unicodestr); + + if (strcmp((const char *)(data1 + 2), "\\MAILSLOT\\BROWSE") == 0) { + print_browse(param, paramlen, data, datalen); + return; + } + + if (strcmp((const char *)(data1 + 2), "\\PIPE\\LANMAN") == 0) { + print_ipc(param, paramlen, data, datalen); + return; + } + + if (paramlen) + smb_fdata(param, f3, SMBMIN(param + paramlen, maxbuf), unicodestr); + if (datalen) + smb_fdata(data, f4, SMBMIN(data + datalen, maxbuf), unicodestr); + } + return; +trunc: + printf("[|SMB]"); + return; +} + + +static void +print_negprot(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf) +{ + u_int wct, bcc; + const char *f1 = NULL, *f2 = NULL; + + TCHECK(words[0]); + wct = words[0]; + if (request) + f2 = "*|Dialect=[Y]\n"; + else { + if (wct == 1) + f1 = "Core Protocol\nDialectIndex=[d]"; + else if (wct == 17) + f1 = "NT1 Protocol\nDialectIndex=[d]\nSecMode=[B]\nMaxMux=[d]\nNumVcs=[d]\nMaxBuffer=[D]\nRawSize=[D]\nSessionKey=[W]\nCapabilities=[W]\nServerTime=[T3]TimeZone=[d]\nCryptKey="; + else if (wct == 13) + f1 = "Coreplus/Lanman1/Lanman2 Protocol\nDialectIndex=[d]\nSecMode=[w]\nMaxXMit=[d]\nMaxMux=[d]\nMaxVcs=[d]\nBlkMode=[w]\nSessionKey=[W]\nServerTime=[T1]TimeZone=[d]\nRes=[W]\nCryptKey="; + } + + if (f1) + smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf), + unicodestr); + else + print_data(words + 1, SMBMIN(wct * 2, PTR_DIFF(maxbuf, words + 1))); + + TCHECK2(*data, 2); + bcc = EXTRACT_LE_16BITS(data); + printf("smb_bcc=%u\n", bcc); + if (bcc > 0) { + if (f2) + smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), + maxbuf), unicodestr); + else + print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + } + return; +trunc: + printf("[|SMB]"); + return; +} + +static void +print_sesssetup(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf) +{ + u_int wct, bcc; + const char *f1 = NULL, *f2 = NULL; + + TCHECK(words[0]); + wct = words[0]; + if (request) { + if (wct == 10) + f1 = "Com2=[w]\nOff2=[d]\nBufSize=[d]\nMpxMax=[d]\nVcNum=[d]\nSessionKey=[W]\nPassLen=[d]\nCryptLen=[d]\nCryptOff=[d]\nPass&Name=\n"; + else + f1 = "Com2=[B]\nRes1=[B]\nOff2=[d]\nMaxBuffer=[d]\nMaxMpx=[d]\nVcNumber=[d]\nSessionKey=[W]\nCaseInsensitivePasswordLength=[d]\nCaseSensitivePasswordLength=[d]\nRes=[W]\nCapabilities=[W]\nPass1&Pass2&Account&Domain&OS&LanMan=\n"; + } else { + if (wct == 3) { + f1 = "Com2=[w]\nOff2=[d]\nAction=[w]\n"; + } else if (wct == 13) { + f1 = "Com2=[B]\nRes=[B]\nOff2=[d]\nAction=[w]\n"; + f2 = "NativeOS=[S]\nNativeLanMan=[S]\nPrimaryDomain=[S]\n"; + } + } + + if (f1) + smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf), + unicodestr); + else + print_data(words + 1, SMBMIN(wct * 2, PTR_DIFF(maxbuf, words + 1))); + + TCHECK2(*data, 2); + bcc = EXTRACT_LE_16BITS(data); + printf("smb_bcc=%u\n", bcc); + if (bcc > 0) { + if (f2) + smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), + maxbuf), unicodestr); + else + print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + } + return; +trunc: + printf("[|SMB]"); + return; +} + +static void +print_lockingandx(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf) +{ + u_int wct, bcc; + const u_char *maxwords; + const char *f1 = NULL, *f2 = NULL; + + TCHECK(words[0]); + wct = words[0]; + if (request) { + f1 = "Com2=[w]\nOff2=[d]\nHandle=[d]\nLockType=[w]\nTimeOut=[D]\nUnlockCount=[d]\nLockCount=[d]\n"; + TCHECK(words[7]); + if (words[7] & 0x10) + f2 = "*Process=[d]\n[P2]Offset=[M]\nLength=[M]\n"; + else + f2 = "*Process=[d]\nOffset=[D]\nLength=[D]\n"; + } else { + f1 = "Com2=[w]\nOff2=[d]\n"; + } + + maxwords = SMBMIN(words + 1 + wct * 2, maxbuf); + if (wct) + smb_fdata(words + 1, f1, maxwords, unicodestr); + + TCHECK2(*data, 2); + bcc = EXTRACT_LE_16BITS(data); + printf("smb_bcc=%u\n", bcc); + if (bcc > 0) { + if (f2) + smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), + maxbuf), unicodestr); + else + print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + } + return; +trunc: + printf("[|SMB]"); + return; +} + + +static struct smbfns smb_fns[] = { + { -1, "SMBunknown", 0, DEFDESCRIPT }, + + { SMBtcon, "SMBtcon", 0, + { NULL, "Path=[Z]\nPassword=[Z]\nDevice=[Z]\n", + "MaxXmit=[d]\nTreeId=[d]\n", NULL, + NULL } }, + + { SMBtdis, "SMBtdis", 0, DEFDESCRIPT }, + { SMBexit, "SMBexit", 0, DEFDESCRIPT }, + { SMBioctl, "SMBioctl", 0, DEFDESCRIPT }, + + { SMBecho, "SMBecho", 0, + { "ReverbCount=[d]\n", NULL, + "SequenceNum=[d]\n", NULL, + NULL } }, + + { SMBulogoffX, "SMBulogoffX", FLG_CHAIN, DEFDESCRIPT }, + + { SMBgetatr, "SMBgetatr", 0, + { NULL, "Path=[Z]\n", + "Attribute=[A]\nTime=[T2]Size=[D]\nRes=([w,w,w,w,w])\n", NULL, + NULL } }, + + { SMBsetatr, "SMBsetatr", 0, + { "Attribute=[A]\nTime=[T2]Res=([w,w,w,w,w])\n", "Path=[Z]\n", + NULL, NULL, NULL } }, + + { SMBchkpth, "SMBchkpth", 0, + { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, + + { SMBsearch, "SMBsearch", 0, + { "Count=[d]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\n", + "Count=[d]\n", + "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + NULL } }, + + { SMBopen, "SMBopen", 0, + { "Mode=[w]\nAttribute=[A]\n", "Path=[Z]\n", + "Handle=[d]\nOAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\n", + NULL, NULL } }, + + { SMBcreate, "SMBcreate", 0, + { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } }, + + { SMBmknew, "SMBmknew", 0, + { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } }, + + { SMBunlink, "SMBunlink", 0, + { "Attrib=[A]\n", "Path=[Z]\n", NULL, NULL, NULL } }, + + { SMBread, "SMBread", 0, + { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, + "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } }, + + { SMBwrite, "SMBwrite", 0, + { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, + "Count=[d]\n", NULL, NULL } }, + + { SMBclose, "SMBclose", 0, + { "Handle=[d]\nTime=[T2]", NULL, NULL, NULL, NULL } }, + + { SMBmkdir, "SMBmkdir", 0, + { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, + + { SMBrmdir, "SMBrmdir", 0, + { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, + + { SMBdskattr, "SMBdskattr", 0, + { NULL, NULL, + "TotalUnits=[d]\nBlocksPerUnit=[d]\nBlockSize=[d]\nFreeUnits=[d]\nMedia=[w]\n", + NULL, NULL } }, + + { SMBmv, "SMBmv", 0, + { "Attrib=[A]\n", "OldPath=[Z]\nNewPath=[Z]\n", NULL, NULL, NULL } }, + + /* + * this is a Pathworks specific call, allowing the + * changing of the root path + */ + { pSETDIR, "SMBsetdir", 0, { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, + + { SMBlseek, "SMBlseek", 0, + { "Handle=[d]\nMode=[w]\nOffset=[D]\n", "Offset=[D]\n", NULL, NULL, NULL } }, + + { SMBflush, "SMBflush", 0, { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBsplopen, "SMBsplopen", 0, + { "SetupLen=[d]\nMode=[w]\n", "Ident=[Z]\n", "Handle=[d]\n", + NULL, NULL } }, + + { SMBsplclose, "SMBsplclose", 0, + { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBsplretq, "SMBsplretq", 0, + { "MaxCount=[d]\nStartIndex=[d]\n", NULL, + "Count=[d]\nIndex=[d]\n", + "*Time=[T2]Status=[B]\nJobID=[d]\nSize=[D]\nRes=[B]Name=[s16]\n", + NULL } }, + + { SMBsplwr, "SMBsplwr", 0, + { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBlock, "SMBlock", 0, + { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } }, + + { SMBunlock, "SMBunlock", 0, + { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } }, + + /* CORE+ PROTOCOL FOLLOWS */ + + { SMBreadbraw, "SMBreadbraw", 0, + { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[d]\n", + NULL, NULL, NULL, NULL } }, + + { SMBwritebraw, "SMBwritebraw", 0, + { "Handle=[d]\nTotalCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\n|DataSize=[d]\nDataOff=[d]\n", + NULL, "WriteRawAck", NULL, NULL } }, + + { SMBwritec, "SMBwritec", 0, + { NULL, NULL, "Count=[d]\n", NULL, NULL } }, + + { SMBwriteclose, "SMBwriteclose", 0, + { "Handle=[d]\nCount=[d]\nOffset=[D]\nTime=[T2]Res=([w,w,w,w,w,w])", + NULL, "Count=[d]\n", NULL, NULL } }, + + { SMBlockread, "SMBlockread", 0, + { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, + "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } }, + + { SMBwriteunlock, "SMBwriteunlock", 0, + { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, + "Count=[d]\n", NULL, NULL } }, + + { SMBreadBmpx, "SMBreadBmpx", 0, + { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[w]\n", + NULL, + "Offset=[D]\nTotCount=[d]\nRemaining=[d]\nRes=([w,w])\nDataSize=[d]\nDataOff=[d]\n", + NULL, NULL } }, + + { SMBwriteBmpx, "SMBwriteBmpx", 0, + { "Handle=[d]\nTotCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\nDataSize=[d]\nDataOff=[d]\n", NULL, + "Remaining=[d]\n", NULL, NULL } }, + + { SMBwriteBs, "SMBwriteBs", 0, + { "Handle=[d]\nTotCount=[d]\nOffset=[D]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\n", + NULL, "Count=[d]\n", NULL, NULL } }, + + { SMBsetattrE, "SMBsetattrE", 0, + { "Handle=[d]\nCreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]", NULL, + NULL, NULL, NULL } }, + + { SMBgetattrE, "SMBgetattrE", 0, + { "Handle=[d]\n", NULL, + "CreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]Size=[D]\nAllocSize=[D]\nAttribute=[A]\n", + NULL, NULL } }, + + { SMBtranss, "SMBtranss", 0, DEFDESCRIPT }, + { SMBioctls, "SMBioctls", 0, DEFDESCRIPT }, + + { SMBcopy, "SMBcopy", 0, + { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n", + "CopyCount=[d]\n", "|ErrStr=[S]\n", NULL } }, + + { SMBmove, "SMBmove", 0, + { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n", + "MoveCount=[d]\n", "|ErrStr=[S]\n", NULL } }, + + { SMBopenX, "SMBopenX", FLG_CHAIN, + { "Com2=[w]\nOff2=[d]\nFlags=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]OFun=[w]\nSize=[D]\nTimeOut=[D]\nRes=[W]\n", + "Path=[S]\n", + "Com2=[w]\nOff2=[d]\nHandle=[d]\nAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nFileID=[W]\nRes=[w]\n", + NULL, NULL } }, + + { SMBreadX, "SMBreadX", FLG_CHAIN, + { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nCountLeft=[d]\n", + NULL, + "Com2=[w]\nOff2=[d]\nRemaining=[d]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\nRes=([w,w,w,w])\n", + NULL, NULL } }, + + { SMBwriteX, "SMBwriteX", FLG_CHAIN, + { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nCountLeft=[d]\nRes=[w]\nDataSize=[d]\nDataOff=[d]\n", + NULL, + "Com2=[w]\nOff2=[d]\nCount=[d]\nRemaining=[d]\nRes=[W]\n", + NULL, NULL } }, + + { SMBffirst, "SMBffirst", 0, + { "Count=[d]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n", + "Count=[d]\n", + "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + NULL } }, + + { SMBfunique, "SMBfunique", 0, + { "Count=[d]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n", + "Count=[d]\n", + "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + NULL } }, + + { SMBfclose, "SMBfclose", 0, + { "Count=[d]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n", + "Count=[d]\n", + "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + NULL } }, + + { SMBfindnclose, "SMBfindnclose", 0, + { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBfindclose, "SMBfindclose", 0, + { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBsends, "SMBsends", 0, + { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } }, + + { SMBsendstrt, "SMBsendstrt", 0, + { NULL, "Source=[Z]\nDest=[Z]\n", "GroupID=[d]\n", NULL, NULL } }, + + { SMBsendend, "SMBsendend", 0, + { "GroupID=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBsendtxt, "SMBsendtxt", 0, + { "GroupID=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBsendb, "SMBsendb", 0, + { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } }, + + { SMBfwdname, "SMBfwdname", 0, DEFDESCRIPT }, + { SMBcancelf, "SMBcancelf", 0, DEFDESCRIPT }, + { SMBgetmac, "SMBgetmac", 0, DEFDESCRIPT }, + + { SMBnegprot, "SMBnegprot", 0, + { NULL, NULL, NULL, NULL, print_negprot } }, + + { SMBsesssetupX, "SMBsesssetupX", FLG_CHAIN, + { NULL, NULL, NULL, NULL, print_sesssetup } }, + + { SMBtconX, "SMBtconX", FLG_CHAIN, + { "Com2=[w]\nOff2=[d]\nFlags=[w]\nPassLen=[d]\nPasswd&Path&Device=\n", + NULL, "Com2=[w]\nOff2=[d]\n", "ServiceType=[R]\n", NULL } }, + + { SMBlockingX, "SMBlockingX", FLG_CHAIN, + { NULL, NULL, NULL, NULL, print_lockingandx } }, + + { SMBtrans2, "SMBtrans2", 0, { NULL, NULL, NULL, NULL, print_trans2 } }, + + { SMBtranss2, "SMBtranss2", 0, DEFDESCRIPT }, + { SMBctemp, "SMBctemp", 0, DEFDESCRIPT }, + { SMBreadBs, "SMBreadBs", 0, DEFDESCRIPT }, + { SMBtrans, "SMBtrans", 0, { NULL, NULL, NULL, NULL, print_trans } }, + + { SMBnttrans, "SMBnttrans", 0, DEFDESCRIPT }, + { SMBnttranss, "SMBnttranss", 0, DEFDESCRIPT }, + + { SMBntcreateX, "SMBntcreateX", FLG_CHAIN, + { "Com2=[w]\nOff2=[d]\nRes=[b]\nNameLen=[ld]\nFlags=[W]\nRootDirectoryFid=[D]\nAccessMask=[W]\nAllocationSize=[L]\nExtFileAttributes=[W]\nShareAccess=[W]\nCreateDisposition=[W]\nCreateOptions=[W]\nImpersonationLevel=[W]\nSecurityFlags=[b]\n", + "Path=[C]\n", + "Com2=[w]\nOff2=[d]\nOplockLevel=[b]\nFid=[d]\nCreateAction=[W]\nCreateTime=[T3]LastAccessTime=[T3]LastWriteTime=[T3]ChangeTime=[T3]ExtFileAttributes=[W]\nAllocationSize=[L]\nEndOfFile=[L]\nFileType=[w]\nDeviceState=[w]\nDirectory=[b]\n", + NULL, NULL } }, + + { SMBntcancel, "SMBntcancel", 0, DEFDESCRIPT }, + + { -1, NULL, 0, DEFDESCRIPT } +}; + + +/* + * print a SMB message + */ +static void +print_smb(const u_char *buf, const u_char *maxbuf) +{ + u_int16_t flags2; + int nterrcodes; + int command; + u_int32_t nterror; + const u_char *words, *maxwords, *data; + struct smbfns *fn; + const char *fmt_smbheader = + "[P4]SMB Command = [B]\nError class = [BP1]\nError code = [d]\nFlags1 = [B]\nFlags2 = [B][P13]\nTree ID = [d]\nProc ID = [d]\nUID = [d]\nMID = [d]\nWord Count = [b]\n"; + int smboffset; + + TCHECK(buf[9]); + request = (buf[9] & 0x80) ? 0 : 1; + flags2 = EXTRACT_LE_16BITS(&buf[10]); + unicodestr = flags2 & 0x8000; + nterrcodes = flags2 & 0x4000; + startbuf = buf; + + command = buf[4]; + + fn = smbfind(command, smb_fns); + + if (vflag > 1) + printf("\n"); + + printf("SMB PACKET: %s (%s)\n", fn->name, request ? "REQUEST" : "REPLY"); + + if (vflag < 2) + return; + + /* print out the header */ + smb_fdata(buf, fmt_smbheader, buf + 33, unicodestr); + + if (nterrcodes) { + nterror = EXTRACT_LE_32BITS(&buf[5]); + if (nterror) + printf("NTError = %s\n", nt_errstr(nterror)); + } else { + if (buf[5]) + printf("SMBError = %s\n", smb_errstr(buf[5], EXTRACT_LE_16BITS(&buf[7]))); + } + + smboffset = 32; + + for (;;) { + const char *f1, *f2; + int wct; + u_int bcc; + int newsmboffset; + + words = buf + smboffset; + TCHECK(words[0]); + wct = words[0]; + data = words + 1 + wct * 2; + maxwords = SMBMIN(data, maxbuf); + + if (request) { + f1 = fn->descript.req_f1; + f2 = fn->descript.req_f2; + } else { + f1 = fn->descript.rep_f1; + f2 = fn->descript.rep_f2; + } + + if (fn->descript.fn) + (*fn->descript.fn)(words, data, buf, maxbuf); + else { + if (wct) { + if (f1) + smb_fdata(words + 1, f1, words + 1 + wct * 2, unicodestr); + else { + int i; + int v; + + for (i = 0; &words[1 + 2 * i] < maxwords; i++) { + TCHECK2(words[1 + 2 * i], 2); + v = EXTRACT_LE_16BITS(words + 1 + 2 * i); + printf("smb_vwv[%d]=%d (0x%X)\n", i, v, v); + } + } + } + + TCHECK2(*data, 2); + bcc = EXTRACT_LE_16BITS(data); + printf("smb_bcc=%u\n", bcc); + if (f2) { + if (bcc > 0) + smb_fdata(data + 2, f2, data + 2 + bcc, unicodestr); + } else { + if (bcc > 0) { + printf("smb_buf[]=\n"); + print_data(data + 2, SMBMIN(bcc, PTR_DIFF(maxbuf, data + 2))); + } + } + } + + if ((fn->flags & FLG_CHAIN) == 0) + break; + if (wct == 0) + break; + TCHECK(words[1]); + command = words[1]; + if (command == 0xFF) + break; + TCHECK2(words[3], 2); + newsmboffset = EXTRACT_LE_16BITS(words + 3); + + fn = smbfind(command, smb_fns); + + printf("\nSMB PACKET: %s (%s) (CHAINED)\n", + fn->name, request ? "REQUEST" : "REPLY"); + if (newsmboffset <= smboffset) { + printf("Bad andX offset: %u <= %u\n", newsmboffset, smboffset); + break; + } + smboffset = newsmboffset; + } + + printf("\n"); + return; +trunc: + printf("[|SMB]"); + return; +} + + +/* + * print a NBT packet received across tcp on port 139 + */ +void +nbt_tcp_print(const u_char *data, int length) +{ + int caplen; + int type; + u_int nbt_len; + const u_char *maxbuf; + + if (length < 4) + goto trunc; + if (snapend < data) + goto trunc; + caplen = snapend - data; + if (caplen < 4) + goto trunc; + maxbuf = data + caplen; + type = data[0]; + nbt_len = EXTRACT_16BITS(data + 2); + length -= 4; + caplen -= 4; + + startbuf = data; + + if (vflag < 2) { + printf(" NBT Session Packet: "); + switch (type) { + case 0x00: + printf("Session Message"); + break; + + case 0x81: + printf("Session Request"); + break; + + case 0x82: + printf("Session Granted"); + break; + + case 0x83: + { + int ecode; + + if (nbt_len < 4) + goto trunc; + if (length < 4) + goto trunc; + if (caplen < 4) + goto trunc; + ecode = data[4]; + + printf("Session Reject, "); + switch (ecode) { + case 0x80: + printf("Not listening on called name"); + break; + case 0x81: + printf("Not listening for calling name"); + break; + case 0x82: + printf("Called name not present"); + break; + case 0x83: + printf("Called name present, but insufficient resources"); + break; + default: + printf("Unspecified error 0x%X", ecode); + break; + } + } + break; + + case 0x85: + printf("Session Keepalive"); + break; + + default: + data = smb_fdata(data, "Unknown packet type [rB]", maxbuf, 0); + break; + } + } else { + printf ("\n>>> NBT Session Packet\n"); + switch (type) { + case 0x00: + data = smb_fdata(data, "[P1]NBT Session Message\nFlags=[B]\nLength=[rd]\n", + data + 4, 0); + if (data == NULL) + break; + if (nbt_len >= 4 && caplen >= 4 && memcmp(data,"\377SMB",4) == 0) { + if ((int)nbt_len > caplen) { + if ((int)nbt_len > length) + printf("WARNING: Packet is continued in later TCP segments\n"); + else + printf("WARNING: Short packet. Try increasing the snap length by %d\n", + nbt_len - caplen); + } + print_smb(data, maxbuf > data + nbt_len ? data + nbt_len : maxbuf); + } else + printf("Session packet:(raw data or continuation?)\n"); + break; + + case 0x81: + data = smb_fdata(data, + "[P1]NBT Session Request\nFlags=[B]\nLength=[rd]\nDestination=[n1]\nSource=[n1]\n", + maxbuf, 0); + break; + + case 0x82: + data = smb_fdata(data, "[P1]NBT Session Granted\nFlags=[B]\nLength=[rd]\n", maxbuf, 0); + break; + + case 0x83: + { + const u_char *origdata; + int ecode; + + origdata = data; + data = smb_fdata(data, "[P1]NBT SessionReject\nFlags=[B]\nLength=[rd]\nReason=[B]\n", + maxbuf, 0); + if (data == NULL) + break; + if (nbt_len >= 1 && caplen >= 1) { + ecode = origdata[4]; + switch (ecode) { + case 0x80: + printf("Not listening on called name\n"); + break; + case 0x81: + printf("Not listening for calling name\n"); + break; + case 0x82: + printf("Called name not present\n"); + break; + case 0x83: + printf("Called name present, but insufficient resources\n"); + break; + default: + printf("Unspecified error 0x%X\n", ecode); + break; + } + } + } + break; + + case 0x85: + data = smb_fdata(data, "[P1]NBT Session Keepalive\nFlags=[B]\nLength=[rd]\n", maxbuf, 0); + break; + + default: + data = smb_fdata(data, "NBT - Unknown packet type\nType=[B]\n", maxbuf, 0); + break; + } + printf("\n"); + fflush(stdout); + } + return; +trunc: + printf("[|SMB]"); + return; +} + + +/* + * print a NBT packet received across udp on port 137 + */ +void +nbt_udp137_print(const u_char *data, int length) +{ + const u_char *maxbuf = data + length; + int name_trn_id, response, opcode, nm_flags, rcode; + int qdcount, ancount, nscount, arcount; + const char *opcodestr; + const u_char *p; + int total, i; + + TCHECK2(data[10], 2); + name_trn_id = EXTRACT_16BITS(data); + response = (data[2] >> 7); + opcode = (data[2] >> 3) & 0xF; + nm_flags = ((data[2] & 0x7) << 4) + (data[3] >> 4); + rcode = data[3] & 0xF; + qdcount = EXTRACT_16BITS(data + 4); + ancount = EXTRACT_16BITS(data + 6); + nscount = EXTRACT_16BITS(data + 8); + arcount = EXTRACT_16BITS(data + 10); + startbuf = data; + + if (maxbuf <= data) + return; + + if (vflag > 1) + printf("\n>>> "); + + printf("NBT UDP PACKET(137): "); + + switch (opcode) { + case 0: opcodestr = "QUERY"; break; + case 5: opcodestr = "REGISTRATION"; break; + case 6: opcodestr = "RELEASE"; break; + case 7: opcodestr = "WACK"; break; + case 8: opcodestr = "REFRESH(8)"; break; + case 9: opcodestr = "REFRESH"; break; + case 15: opcodestr = "MULTIHOMED REGISTRATION"; break; + default: opcodestr = "OPUNKNOWN"; break; + } + printf("%s", opcodestr); + if (response) { + if (rcode) + printf("; NEGATIVE"); + else + printf("; POSITIVE"); + } + + if (response) + printf("; RESPONSE"); + else + printf("; REQUEST"); + + if (nm_flags & 1) + printf("; BROADCAST"); + else + printf("; UNICAST"); + + if (vflag < 2) + return; + + printf("\nTrnID=0x%X\nOpCode=%d\nNmFlags=0x%X\nRcode=%d\nQueryCount=%d\nAnswerCount=%d\nAuthorityCount=%d\nAddressRecCount=%d\n", + name_trn_id, opcode, nm_flags, rcode, qdcount, ancount, nscount, + arcount); + + p = data + 12; + + total = ancount + nscount + arcount; + + if (qdcount > 100 || total > 100) { + printf("Corrupt packet??\n"); + return; + } + + if (qdcount) { + printf("QuestionRecords:\n"); + for (i = 0; i < qdcount; i++) { + p = smb_fdata(p, + "|Name=[n1]\nQuestionType=[rw]\nQuestionClass=[rw]\n#", + maxbuf, 0); + if (p == NULL) + goto out; + } + } + + if (total) { + printf("\nResourceRecords:\n"); + for (i = 0; i < total; i++) { + int rdlen; + int restype; + + p = smb_fdata(p, "Name=[n1]\n#", maxbuf, 0); + if (p == NULL) + goto out; + restype = EXTRACT_16BITS(p); + p = smb_fdata(p, "ResType=[rw]\nResClass=[rw]\nTTL=[rD]\n", p + 8, 0); + if (p == NULL) + goto out; + rdlen = EXTRACT_16BITS(p); + printf("ResourceLength=%d\nResourceData=\n", rdlen); + p += 2; + if (rdlen == 6) { + p = smb_fdata(p, "AddrType=[rw]\nAddress=[b.b.b.b]\n", p + rdlen, 0); + if (p == NULL) + goto out; + } else { + if (restype == 0x21) { + int numnames; + + TCHECK(*p); + numnames = p[0]; + p = smb_fdata(p, "NumNames=[B]\n", p + 1, 0); + if (p == NULL) + goto out; + while (numnames--) { + p = smb_fdata(p, "Name=[n2]\t#", maxbuf, 0); + if (p == NULL) + goto out; + TCHECK(*p); + if (p[0] & 0x80) + printf("<GROUP> "); + switch (p[0] & 0x60) { + case 0x00: printf("B "); break; + case 0x20: printf("P "); break; + case 0x40: printf("M "); break; + case 0x60: printf("_ "); break; + } + if (p[0] & 0x10) + printf("<DEREGISTERING> "); + if (p[0] & 0x08) + printf("<CONFLICT> "); + if (p[0] & 0x04) + printf("<ACTIVE> "); + if (p[0] & 0x02) + printf("<PERMANENT> "); + printf("\n"); + p += 2; + } + } else { + print_data(p, min(rdlen, length - (p - data))); + p += rdlen; + } + } + } + } + + if (p < maxbuf) + smb_fdata(p, "AdditionalData:\n", maxbuf, 0); + +out: + printf("\n"); + fflush(stdout); + return; +trunc: + printf("[|SMB]"); + return; +} + +/* + * Print an SMB-over-TCP packet received across tcp on port 445 + */ +void +smb_tcp_print (const u_char * data, int length) +{ + int caplen; + u_int smb_len; + const u_char *maxbuf; + + if (length < 4) + goto trunc; + if (snapend < data) + goto trunc; + caplen = snapend - data; + if (caplen < 4) + goto trunc; + maxbuf = data + caplen; + smb_len = EXTRACT_24BITS(data + 1); + length -= 4; + caplen -= 4; + + startbuf = data; + data += 4; + + if (smb_len >= 4 && caplen >= 4 && memcmp(data,"\377SMB",4) == 0) { + if ((int)smb_len > caplen) { + if ((int)smb_len > length) + printf("WARNING: Packet is continued in later TCP segments\n"); + else + printf("WARNING: Short packet. Try increasing the snap length by %d\n", + smb_len - caplen); + } + print_smb(data, maxbuf > data + smb_len ? data + smb_len : maxbuf); + } else + printf("SMB-over-TCP packet:(raw data or continuation?)\n"); + return; +trunc: + printf("[|SMB]"); + return; +} + +/* + * print a NBT packet received across udp on port 138 + */ +void +nbt_udp138_print(const u_char *data, int length) +{ + const u_char *maxbuf = data + length; + + if (maxbuf > snapend) + maxbuf = snapend; + if (maxbuf <= data) + return; + startbuf = data; + + if (vflag < 2) { + printf("NBT UDP PACKET(138)"); + return; + } + + data = smb_fdata(data, + "\n>>> NBT UDP PACKET(138) Res=[rw] ID=[rw] IP=[b.b.b.b] Port=[rd] Length=[rd] Res2=[rw]\nSourceName=[n1]\nDestName=[n1]\n#", + maxbuf, 0); + + if (data != NULL) { + /* If there isn't enough data for "\377SMB", don't check for it. */ + if (&data[3] >= maxbuf) + goto out; + + if (memcmp(data, "\377SMB",4) == 0) + print_smb(data, maxbuf); + } +out: + printf("\n"); + fflush(stdout); +} + + +/* + print netbeui frames +*/ +struct nbf_strings { + const char *name; + const char *nonverbose; + const char *verbose; +} nbf_strings[0x20] = { + { "Add Group Name Query", ", [P23]Name to add=[n2]#", + "[P5]ResponseCorrelator=[w]\n[P16]Name to add=[n2]\n" }, + { "Add Name Query", ", [P23]Name to add=[n2]#", + "[P5]ResponseCorrelator=[w]\n[P16]Name to add=[n2]\n" }, + { "Name In Conflict", NULL, NULL }, + { "Status Query", NULL, NULL }, + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { "Terminate Trace", NULL, NULL }, + { "Datagram", NULL, + "[P7]Destination=[n2]\nSource=[n2]\n" }, + { "Broadcast Datagram", NULL, + "[P7]Destination=[n2]\nSource=[n2]\n" }, + { "Name Query", ", [P7]Name=[n2]#", + "[P1]SessionNumber=[B]\nNameType=[B][P2]\nResponseCorrelator=[w]\nName=[n2]\nName of sender=[n2]\n" }, + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { "Add Name Response", ", [P1]GroupName=[w] [P4]Destination=[n2] Source=[n2]#", + "AddNameInProcess=[B]\nGroupName=[w]\nTransmitCorrelator=[w][P2]\nDestination=[n2]\nSource=[n2]\n" }, + { "Name Recognized", NULL, + "[P1]Data2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nDestination=[n2]\nSource=[n2]\n" }, + { "Status Response", NULL, NULL }, + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { "Terminate Trace", NULL, NULL }, + { "Data Ack", NULL, + "[P3]TransmitCorrelator=[w][P2]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Data First/Middle", NULL, + "Flags=[{RECEIVE_CONTINUE|NO_ACK||PIGGYBACK_ACK_INCLUDED|}]\nResyncIndicator=[w][P2]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Data Only/Last", NULL, + "Flags=[{|NO_ACK|PIGGYBACK_ACK_ALLOWED|PIGGYBACK_ACK_INCLUDED|}]\nResyncIndicator=[w][P2]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Session Confirm", NULL, + "Data1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Session End", NULL, + "[P1]Data2=[w][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Session Initialize", NULL, + "Data1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "No Receive", NULL, + "Flags=[{|SEND_NO_ACK}]\nDataBytesAccepted=[b][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Receive Outstanding", NULL, + "[P1]DataBytesAccepted=[b][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Receive Continue", NULL, + "[P2]TransmitCorrelator=[w]\n[P2]RemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { "Session Alive", NULL, NULL } +}; + +void +netbeui_print(u_short control, const u_char *data, int length) +{ + const u_char *maxbuf = data + length; + int len; + int command; + const u_char *data2; + int is_truncated = 0; + + if (maxbuf > snapend) + maxbuf = snapend; + TCHECK(data[4]); + len = EXTRACT_LE_16BITS(data); + command = data[4]; + data2 = data + len; + if (data2 >= maxbuf) { + data2 = maxbuf; + is_truncated = 1; + } + + startbuf = data; + + if (vflag < 2) { + printf("NBF Packet: "); + data = smb_fdata(data, "[P5]#", maxbuf, 0); + } else { + printf("\n>>> NBF Packet\nType=0x%X ", control); + data = smb_fdata(data, "Length=[d] Signature=[w] Command=[B]\n#", maxbuf, 0); + } + if (data == NULL) + goto out; + + if (command > 0x1f || nbf_strings[command].name == NULL) { + if (vflag < 2) + data = smb_fdata(data, "Unknown NBF Command#", data2, 0); + else + data = smb_fdata(data, "Unknown NBF Command\n", data2, 0); + } else { + if (vflag < 2) { + printf("%s", nbf_strings[command].name); + if (nbf_strings[command].nonverbose != NULL) + data = smb_fdata(data, nbf_strings[command].nonverbose, data2, 0); + } else { + printf("%s:\n", nbf_strings[command].name); + if (nbf_strings[command].verbose != NULL) + data = smb_fdata(data, nbf_strings[command].verbose, data2, 0); + else + printf("\n"); + } + } + + if (vflag < 2) + return; + + if (data == NULL) + goto out; + + if (is_truncated) { + /* data2 was past the end of the buffer */ + goto out; + } + + /* If this isn't a command that would contain an SMB message, quit. */ + if (command != 0x08 && command != 0x09 && command != 0x15 && + command != 0x16) + goto out; + + /* If there isn't enough data for "\377SMB", don't look for it. */ + if (&data2[3] >= maxbuf) + goto out; + + if (memcmp(data2, "\377SMB",4) == 0) + print_smb(data2, maxbuf); + else { + int i; + for (i = 0; i < 128; i++) { + if (&data2[i + 3] >= maxbuf) + break; + if (memcmp(&data2[i], "\377SMB", 4) == 0) { + printf("found SMB packet at %d\n", i); + print_smb(&data2[i], maxbuf); + break; + } + } + } + +out: + printf("\n"); + return; +trunc: + printf("[|SMB]"); + return; +} + + +/* + * print IPX-Netbios frames + */ +void +ipx_netbios_print(const u_char *data, u_int length) +{ + /* + * this is a hack till I work out how to parse the rest of the + * NetBIOS-over-IPX stuff + */ + int i; + const u_char *maxbuf; + + maxbuf = data + length; + /* Don't go past the end of the captured data in the packet. */ + if (maxbuf > snapend) + maxbuf = snapend; + startbuf = data; + for (i = 0; i < 128; i++) { + if (&data[i + 4] > maxbuf) + break; + if (memcmp(&data[i], "\377SMB", 4) == 0) { + smb_fdata(data, "\n>>> IPX transport ", &data[i], 0); + print_smb(&data[i], maxbuf); + printf("\n"); + fflush(stdout); + break; + } + } + if (i == 128) + smb_fdata(data, "\n>>> Unknown IPX ", maxbuf, 0); +} diff --git a/freebsd/contrib/tcpdump/print-snmp.c b/freebsd/contrib/tcpdump/print-snmp.c new file mode 100644 index 00000000..e585a4b5 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-snmp.c @@ -0,0 +1,1906 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 + * John Robert LoVerso. 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 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. + * + * + * This implementation has been influenced by the CMU SNMP release, + * by Steve Waldbusser. However, this shares no code with that system. + * Additional ASN.1 insight gained from Marshall T. Rose's _The_Open_Book_. + * Earlier forms of this implementation were derived and/or inspired by an + * awk script originally written by C. Philip Wood of LANL (but later + * heavily modified by John Robert LoVerso). The copyright notice for + * that work is preserved below, even though it may not rightly apply + * to this file. + * + * Support for SNMPv2c/SNMPv3 and the ability to link the module against + * the libsmi was added by J. Schoenwaelder, Copyright (c) 1999. + * + * This started out as a very simple program, but the incremental decoding + * (into the BE structure) complicated things. + * + # Los Alamos National Laboratory + # + # Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 + # This software was produced under a U.S. Government contract + # (W-7405-ENG-36) by Los Alamos National Laboratory, which is + # operated by the University of California for the U.S. Department + # of Energy. The U.S. Government is licensed to use, reproduce, + # and distribute this software. Permission is granted to the + # public to copy and use this software without charge, provided + # that this Notice and any statement of authorship are reproduced + # on all copies. Neither the Government nor the University makes + # any warranty, express or implied, or assumes any liability or + # responsibility for the use of this software. + # @(#)snmp.awk.x 1.1 (LANL) 1/15/90 + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-snmp.c,v 1.64 2005-05-06 07:56:53 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#ifdef HAVE_SMI_H +#include <smi.h> +#endif + +#include "interface.h" +#include "addrtoname.h" + +#undef OPAQUE /* defined in <wingdi.h> */ + +/* + * Universal ASN.1 types + * (we only care about the tag values for those allowed in the Internet SMI) + */ +const char *Universal[] = { + "U-0", + "Boolean", + "Integer", +#define INTEGER 2 + "Bitstring", + "String", +#define STRING 4 + "Null", +#define ASN_NULL 5 + "ObjID", +#define OBJECTID 6 + "ObjectDes", + "U-8","U-9","U-10","U-11", /* 8-11 */ + "U-12","U-13","U-14","U-15", /* 12-15 */ + "Sequence", +#define SEQUENCE 16 + "Set" +}; + +/* + * Application-wide ASN.1 types from the Internet SMI and their tags + */ +const char *Application[] = { + "IpAddress", +#define IPADDR 0 + "Counter", +#define COUNTER 1 + "Gauge", +#define GAUGE 2 + "TimeTicks", +#define TIMETICKS 3 + "Opaque", +#define OPAQUE 4 + "C-5", + "Counter64" +#define COUNTER64 6 +}; + +/* + * Context-specific ASN.1 types for the SNMP PDUs and their tags + */ +const char *Context[] = { + "GetRequest", +#define GETREQ 0 + "GetNextRequest", +#define GETNEXTREQ 1 + "GetResponse", +#define GETRESP 2 + "SetRequest", +#define SETREQ 3 + "Trap", +#define TRAP 4 + "GetBulk", +#define GETBULKREQ 5 + "Inform", +#define INFORMREQ 6 + "V2Trap", +#define V2TRAP 7 + "Report" +#define REPORT 8 +}; + +#define NOTIFY_CLASS(x) (x == TRAP || x == V2TRAP || x == INFORMREQ) +#define READ_CLASS(x) (x == GETREQ || x == GETNEXTREQ || x == GETBULKREQ) +#define WRITE_CLASS(x) (x == SETREQ) +#define RESPONSE_CLASS(x) (x == GETRESP) +#define INTERNAL_CLASS(x) (x == REPORT) + +/* + * Context-specific ASN.1 types for the SNMP Exceptions and their tags + */ +const char *Exceptions[] = { + "noSuchObject", +#define NOSUCHOBJECT 0 + "noSuchInstance", +#define NOSUCHINSTANCE 1 + "endOfMibView", +#define ENDOFMIBVIEW 2 +}; + +/* + * Private ASN.1 types + * The Internet SMI does not specify any + */ +const char *Private[] = { + "P-0" +}; + +/* + * error-status values for any SNMP PDU + */ +const char *ErrorStatus[] = { + "noError", + "tooBig", + "noSuchName", + "badValue", + "readOnly", + "genErr", + "noAccess", + "wrongType", + "wrongLength", + "wrongEncoding", + "wrongValue", + "noCreation", + "inconsistentValue", + "resourceUnavailable", + "commitFailed", + "undoFailed", + "authorizationError", + "notWritable", + "inconsistentName" +}; +#define DECODE_ErrorStatus(e) \ + ( e >= 0 && (size_t)e < sizeof(ErrorStatus)/sizeof(ErrorStatus[0]) \ + ? ErrorStatus[e] \ + : (snprintf(errbuf, sizeof(errbuf), "err=%u", e), errbuf)) + +/* + * generic-trap values in the SNMP Trap-PDU + */ +const char *GenericTrap[] = { + "coldStart", + "warmStart", + "linkDown", + "linkUp", + "authenticationFailure", + "egpNeighborLoss", + "enterpriseSpecific" +#define GT_ENTERPRISE 6 +}; +#define DECODE_GenericTrap(t) \ + ( t >= 0 && (size_t)t < sizeof(GenericTrap)/sizeof(GenericTrap[0]) \ + ? GenericTrap[t] \ + : (snprintf(buf, sizeof(buf), "gt=%d", t), buf)) + +/* + * ASN.1 type class table + * Ties together the preceding Universal, Application, Context, and Private + * type definitions. + */ +#define defineCLASS(x) { "x", x, sizeof(x)/sizeof(x[0]) } /* not ANSI-C */ +struct { + const char *name; + const char **Id; + int numIDs; + } Class[] = { + defineCLASS(Universal), +#define UNIVERSAL 0 + defineCLASS(Application), +#define APPLICATION 1 + defineCLASS(Context), +#define CONTEXT 2 + defineCLASS(Private), +#define PRIVATE 3 + defineCLASS(Exceptions), +#define EXCEPTIONS 4 +}; + +/* + * defined forms for ASN.1 types + */ +const char *Form[] = { + "Primitive", +#define PRIMITIVE 0 + "Constructed", +#define CONSTRUCTED 1 +}; + +/* + * A structure for the OID tree for the compiled-in MIB. + * This is stored as a general-order tree. + */ +struct obj { + const char *desc; /* name of object */ + u_char oid; /* sub-id following parent */ + u_char type; /* object type (unused) */ + struct obj *child, *next; /* child and next sibling pointers */ +} *objp = NULL; + +/* + * Include the compiled in SNMP MIB. "mib.h" is produced by feeding + * RFC-1156 format files into "makemib". "mib.h" MUST define at least + * a value for `mibroot'. + * + * In particular, this is gross, as this is including initialized structures, + * and by right shouldn't be an "include" file. + */ +#include "mib.h" + +/* + * This defines a list of OIDs which will be abbreviated on output. + * Currently, this includes the prefixes for the Internet MIB, the + * private enterprises tree, and the experimental tree. + */ +struct obj_abrev { + const char *prefix; /* prefix for this abrev */ + struct obj *node; /* pointer into object table */ + const char *oid; /* ASN.1 encoded OID */ +} obj_abrev_list[] = { +#ifndef NO_ABREV_MIB + /* .iso.org.dod.internet.mgmt.mib */ + { "", &_mib_obj, "\53\6\1\2\1" }, +#endif +#ifndef NO_ABREV_ENTER + /* .iso.org.dod.internet.private.enterprises */ + { "E:", &_enterprises_obj, "\53\6\1\4\1" }, +#endif +#ifndef NO_ABREV_EXPERI + /* .iso.org.dod.internet.experimental */ + { "X:", &_experimental_obj, "\53\6\1\3" }, +#endif +#ifndef NO_ABBREV_SNMPMODS + /* .iso.org.dod.internet.snmpV2.snmpModules */ + { "S:", &_snmpModules_obj, "\53\6\1\6\3" }, +#endif + { 0,0,0 } +}; + +/* + * This is used in the OID print routine to walk down the object tree + * rooted at `mibroot'. + */ +#define OBJ_PRINT(o, suppressdot) \ +{ \ + if (objp) { \ + do { \ + if ((o) == objp->oid) \ + break; \ + } while ((objp = objp->next) != NULL); \ + } \ + if (objp) { \ + printf(suppressdot?"%s":".%s", objp->desc); \ + objp = objp->child; \ + } else \ + printf(suppressdot?"%u":".%u", (o)); \ +} + +/* + * This is the definition for the Any-Data-Type storage used purely for + * temporary internal representation while decoding an ASN.1 data stream. + */ +struct be { + u_int32_t asnlen; + union { + caddr_t raw; + int32_t integer; + u_int32_t uns; + const u_char *str; + struct { + u_int32_t high; + u_int32_t low; + } uns64; + } data; + u_short id; + u_char form, class; /* tag info */ + u_char type; +#define BE_ANY 255 +#define BE_NONE 0 +#define BE_NULL 1 +#define BE_OCTET 2 +#define BE_OID 3 +#define BE_INT 4 +#define BE_UNS 5 +#define BE_STR 6 +#define BE_SEQ 7 +#define BE_INETADDR 8 +#define BE_PDU 9 +#define BE_UNS64 10 +#define BE_NOSUCHOBJECT 128 +#define BE_NOSUCHINST 129 +#define BE_ENDOFMIBVIEW 130 +}; + +/* + * SNMP versions recognized by this module + */ +const char *SnmpVersion[] = { + "SNMPv1", +#define SNMP_VERSION_1 0 + "SNMPv2c", +#define SNMP_VERSION_2 1 + "SNMPv2u", +#define SNMP_VERSION_2U 2 + "SNMPv3" +#define SNMP_VERSION_3 3 +}; + +/* + * Defaults for SNMP PDU components + */ +#define DEF_COMMUNITY "public" + +/* + * constants for ASN.1 decoding + */ +#define OIDMUX 40 +#define ASNLEN_INETADDR 4 +#define ASN_SHIFT7 7 +#define ASN_SHIFT8 8 +#define ASN_BIT8 0x80 +#define ASN_LONGLEN 0x80 + +#define ASN_ID_BITS 0x1f +#define ASN_FORM_BITS 0x20 +#define ASN_FORM_SHIFT 5 +#define ASN_CLASS_BITS 0xc0 +#define ASN_CLASS_SHIFT 6 + +#define ASN_ID_EXT 0x1f /* extension ID in tag field */ + +/* + * This decodes the next ASN.1 object in the stream pointed to by "p" + * (and of real-length "len") and stores the intermediate data in the + * provided BE object. + * + * This returns -l if it fails (i.e., the ASN.1 stream is not valid). + * O/w, this returns the number of bytes parsed from "p". + */ +static int +asn1_parse(register const u_char *p, u_int len, struct be *elem) +{ + u_char form, class, id; + int i, hdr; + + elem->asnlen = 0; + elem->type = BE_ANY; + if (len < 1) { + fputs("[nothing to parse]", stdout); + return -1; + } + TCHECK(*p); + + /* + * it would be nice to use a bit field, but you can't depend on them. + * +---+---+---+---+---+---+---+---+ + * + class |frm| id | + * +---+---+---+---+---+---+---+---+ + * 7 6 5 4 3 2 1 0 + */ + id = *p & ASN_ID_BITS; /* lower 5 bits, range 00-1f */ +#ifdef notdef + form = (*p & 0xe0) >> 5; /* move upper 3 bits to lower 3 */ + class = form >> 1; /* bits 7&6 -> bits 1&0, range 0-3 */ + form &= 0x1; /* bit 5 -> bit 0, range 0-1 */ +#else + form = (u_char)(*p & ASN_FORM_BITS) >> ASN_FORM_SHIFT; + class = (u_char)(*p & ASN_CLASS_BITS) >> ASN_CLASS_SHIFT; +#endif + elem->form = form; + elem->class = class; + elem->id = id; + p++; len--; hdr = 1; + /* extended tag field */ + if (id == ASN_ID_EXT) { + /* + * The ID follows, as a sequence of octets with the + * 8th bit set and the remaining 7 bits being + * the next 7 bits of the value, terminated with + * an octet with the 8th bit not set. + * + * First, assemble all the octets with the 8th + * bit set. XXX - this doesn't handle a value + * that won't fit in 32 bits. + */ + for (id = 0; *p & ASN_BIT8; len--, hdr++, p++) { + if (len < 1) { + fputs("[Xtagfield?]", stdout); + return -1; + } + TCHECK(*p); + id = (id << 7) | (*p & ~ASN_BIT8); + } + if (len < 1) { + fputs("[Xtagfield?]", stdout); + return -1; + } + TCHECK(*p); + elem->id = id = (id << 7) | *p; + --len; + ++hdr; + ++p; + } + if (len < 1) { + fputs("[no asnlen]", stdout); + return -1; + } + TCHECK(*p); + elem->asnlen = *p; + p++; len--; hdr++; + if (elem->asnlen & ASN_BIT8) { + u_int32_t noct = elem->asnlen % ASN_BIT8; + elem->asnlen = 0; + if (len < noct) { + printf("[asnlen? %d<%d]", len, noct); + return -1; + } + TCHECK2(*p, noct); + for (; noct-- > 0; len--, hdr++) + elem->asnlen = (elem->asnlen << ASN_SHIFT8) | *p++; + } + if (len < elem->asnlen) { + printf("[len%d<asnlen%u]", len, elem->asnlen); + return -1; + } + if (form >= sizeof(Form)/sizeof(Form[0])) { + printf("[form?%d]", form); + return -1; + } + if (class >= sizeof(Class)/sizeof(Class[0])) { + printf("[class?%c/%d]", *Form[form], class); + return -1; + } + if ((int)id >= Class[class].numIDs) { + printf("[id?%c/%s/%d]", *Form[form], Class[class].name, id); + return -1; + } + + switch (form) { + case PRIMITIVE: + switch (class) { + case UNIVERSAL: + switch (id) { + case STRING: + elem->type = BE_STR; + elem->data.str = p; + break; + + case INTEGER: { + register int32_t data; + elem->type = BE_INT; + data = 0; + + TCHECK2(*p, elem->asnlen); + if (*p & ASN_BIT8) /* negative */ + data = -1; + for (i = elem->asnlen; i-- > 0; p++) + data = (data << ASN_SHIFT8) | *p; + elem->data.integer = data; + break; + } + + case OBJECTID: + elem->type = BE_OID; + elem->data.raw = (caddr_t)p; + break; + + case ASN_NULL: + elem->type = BE_NULL; + elem->data.raw = NULL; + break; + + default: + elem->type = BE_OCTET; + elem->data.raw = (caddr_t)p; + printf("[P/U/%s]", + Class[class].Id[id]); + break; + } + break; + + case APPLICATION: + switch (id) { + case IPADDR: + elem->type = BE_INETADDR; + elem->data.raw = (caddr_t)p; + break; + + case COUNTER: + case GAUGE: + case TIMETICKS: { + register u_int32_t data; + TCHECK2(*p, elem->asnlen); + elem->type = BE_UNS; + data = 0; + for (i = elem->asnlen; i-- > 0; p++) + data = (data << 8) + *p; + elem->data.uns = data; + break; + } + + case COUNTER64: { + register u_int32_t high, low; + TCHECK2(*p, elem->asnlen); + elem->type = BE_UNS64; + high = 0, low = 0; + for (i = elem->asnlen; i-- > 0; p++) { + high = (high << 8) | + ((low & 0xFF000000) >> 24); + low = (low << 8) | *p; + } + elem->data.uns64.high = high; + elem->data.uns64.low = low; + break; + } + + default: + elem->type = BE_OCTET; + elem->data.raw = (caddr_t)p; + printf("[P/A/%s]", + Class[class].Id[id]); + break; + } + break; + + case CONTEXT: + switch (id) { + case NOSUCHOBJECT: + elem->type = BE_NOSUCHOBJECT; + elem->data.raw = NULL; + break; + + case NOSUCHINSTANCE: + elem->type = BE_NOSUCHINST; + elem->data.raw = NULL; + break; + + case ENDOFMIBVIEW: + elem->type = BE_ENDOFMIBVIEW; + elem->data.raw = NULL; + break; + } + break; + + default: + printf("[P/%s/%s]", + Class[class].name, Class[class].Id[id]); + TCHECK2(*p, elem->asnlen); + elem->type = BE_OCTET; + elem->data.raw = (caddr_t)p; + break; + } + break; + + case CONSTRUCTED: + switch (class) { + case UNIVERSAL: + switch (id) { + case SEQUENCE: + elem->type = BE_SEQ; + elem->data.raw = (caddr_t)p; + break; + + default: + elem->type = BE_OCTET; + elem->data.raw = (caddr_t)p; + printf("C/U/%s", Class[class].Id[id]); + break; + } + break; + + case CONTEXT: + elem->type = BE_PDU; + elem->data.raw = (caddr_t)p; + break; + + default: + elem->type = BE_OCTET; + elem->data.raw = (caddr_t)p; + printf("C/%s/%s", + Class[class].name, Class[class].Id[id]); + break; + } + break; + } + p += elem->asnlen; + len -= elem->asnlen; + return elem->asnlen + hdr; + +trunc: + fputs("[|snmp]", stdout); + return -1; +} + +/* + * Display the ASN.1 object represented by the BE object. + * This used to be an integral part of asn1_parse() before the intermediate + * BE form was added. + */ +static int +asn1_print(struct be *elem) +{ + u_char *p = (u_char *)elem->data.raw; + u_int32_t asnlen = elem->asnlen; + u_int32_t i; + + switch (elem->type) { + + case BE_OCTET: + TCHECK2(*p, asnlen); + for (i = asnlen; i-- > 0; p++) + printf("_%.2x", *p); + break; + + case BE_NULL: + break; + + case BE_OID: { + int o = 0, first = -1, i = asnlen; + + if (!sflag && !nflag && asnlen > 2) { + struct obj_abrev *a = &obj_abrev_list[0]; + size_t a_len = strlen(a->oid); + for (; a->node; a++) { + TCHECK2(*p, a_len); + if (memcmp(a->oid, (char *)p, a_len) == 0) { + objp = a->node->child; + i -= strlen(a->oid); + p += strlen(a->oid); + fputs(a->prefix, stdout); + first = 1; + break; + } + } + } + + for (; !sflag && i-- > 0; p++) { + TCHECK(*p); + o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8); + if (*p & ASN_LONGLEN) + continue; + + /* + * first subitem encodes two items with 1st*OIDMUX+2nd + * (see X.690:1997 clause 8.19 for the details) + */ + if (first < 0) { + int s; + if (!nflag) + objp = mibroot; + first = 0; + s = o / OIDMUX; + if (s > 2) s = 2; + OBJ_PRINT(s, first); + o -= s * OIDMUX; + } + OBJ_PRINT(o, first); + if (--first < 0) + first = 0; + o = 0; + } + break; + } + + case BE_INT: + printf("%d", elem->data.integer); + break; + + case BE_UNS: + printf("%u", elem->data.uns); + break; + + case BE_UNS64: { /* idea borrowed from by Marshall Rose */ + double d; + int j, carry; + char *cpf, *cpl, last[6], first[30]; + if (elem->data.uns64.high == 0) { + printf("%u", elem->data.uns64.low); + break; + } + d = elem->data.uns64.high * 4294967296.0; /* 2^32 */ + if (elem->data.uns64.high <= 0x1fffff) { + d += elem->data.uns64.low; +#if 0 /*is looks illegal, but what is the intention?*/ + printf("%.f", d); +#else + printf("%f", d); +#endif + break; + } + d += (elem->data.uns64.low & 0xfffff000); +#if 0 /*is looks illegal, but what is the intention?*/ + snprintf(first, sizeof(first), "%.f", d); +#else + snprintf(first, sizeof(first), "%f", d); +#endif + snprintf(last, sizeof(last), "%5.5d", + elem->data.uns64.low & 0xfff); + for (carry = 0, cpf = first+strlen(first)-1, cpl = last+4; + cpl >= last; + cpf--, cpl--) { + j = carry + (*cpf - '0') + (*cpl - '0'); + if (j > 9) { + j -= 10; + carry = 1; + } else { + carry = 0; + } + *cpf = j + '0'; + } + fputs(first, stdout); + break; + } + + case BE_STR: { + register int printable = 1, first = 1; + const u_char *p = elem->data.str; + TCHECK2(*p, asnlen); + for (i = asnlen; printable && i-- > 0; p++) + printable = isprint(*p) || isspace(*p); + p = elem->data.str; + if (printable) { + putchar('"'); + if (fn_printn(p, asnlen, snapend)) { + putchar('"'); + goto trunc; + } + putchar('"'); + } else + for (i = asnlen; i-- > 0; p++) { + printf(first ? "%.2x" : "_%.2x", *p); + first = 0; + } + break; + } + + case BE_SEQ: + printf("Seq(%u)", elem->asnlen); + break; + + case BE_INETADDR: + if (asnlen != ASNLEN_INETADDR) + printf("[inetaddr len!=%d]", ASNLEN_INETADDR); + TCHECK2(*p, asnlen); + for (i = asnlen; i-- != 0; p++) { + printf((i == asnlen-1) ? "%u" : ".%u", *p); + } + break; + + case BE_NOSUCHOBJECT: + case BE_NOSUCHINST: + case BE_ENDOFMIBVIEW: + printf("[%s]", Class[EXCEPTIONS].Id[elem->id]); + break; + + case BE_PDU: + printf("%s(%u)", + Class[CONTEXT].Id[elem->id], elem->asnlen); + break; + + case BE_ANY: + fputs("[BE_ANY!?]", stdout); + break; + + default: + fputs("[be!?]", stdout); + break; + } + return 0; + +trunc: + fputs("[|snmp]", stdout); + return -1; +} + +#ifdef notdef +/* + * This is a brute force ASN.1 printer: recurses to dump an entire structure. + * This will work for any ASN.1 stream, not just an SNMP PDU. + * + * By adding newlines and spaces at the correct places, this would print in + * Rose-Normal-Form. + * + * This is not currently used. + */ +static void +asn1_decode(u_char *p, u_int length) +{ + struct be elem; + int i = 0; + + while (i >= 0 && length > 0) { + i = asn1_parse(p, length, &elem); + if (i >= 0) { + fputs(" ", stdout); + if (asn1_print(&elem) < 0) + return; + if (elem.type == BE_SEQ || elem.type == BE_PDU) { + fputs(" {", stdout); + asn1_decode(elem.data.raw, elem.asnlen); + fputs(" }", stdout); + } + length -= i; + p += i; + } + } +} +#endif + +#ifdef LIBSMI + +struct smi2be { + SmiBasetype basetype; + int be; +}; + +static struct smi2be smi2betab[] = { + { SMI_BASETYPE_INTEGER32, BE_INT }, + { SMI_BASETYPE_OCTETSTRING, BE_STR }, + { SMI_BASETYPE_OCTETSTRING, BE_INETADDR }, + { SMI_BASETYPE_OBJECTIDENTIFIER, BE_OID }, + { SMI_BASETYPE_UNSIGNED32, BE_UNS }, + { SMI_BASETYPE_INTEGER64, BE_NONE }, + { SMI_BASETYPE_UNSIGNED64, BE_UNS64 }, + { SMI_BASETYPE_FLOAT32, BE_NONE }, + { SMI_BASETYPE_FLOAT64, BE_NONE }, + { SMI_BASETYPE_FLOAT128, BE_NONE }, + { SMI_BASETYPE_ENUM, BE_INT }, + { SMI_BASETYPE_BITS, BE_STR }, + { SMI_BASETYPE_UNKNOWN, BE_NONE } +}; + +static int +smi_decode_oid(struct be *elem, unsigned int *oid, + unsigned int oidsize, unsigned int *oidlen) +{ + u_char *p = (u_char *)elem->data.raw; + u_int32_t asnlen = elem->asnlen; + int o = 0, first = -1, i = asnlen; + + for (*oidlen = 0; sflag && i-- > 0; p++) { + TCHECK(*p); + o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8); + if (*p & ASN_LONGLEN) + continue; + + /* + * first subitem encodes two items with 1st*OIDMUX+2nd + * (see X.690:1997 clause 8.19 for the details) + */ + if (first < 0) { + first = 0; + if (*oidlen < oidsize) { + oid[*oidlen] = o / OIDMUX; + if (oid[*oidlen] > 2) oid[*oidlen] = 2; + } + o -= oid[*oidlen] * OIDMUX; + if (*oidlen < oidsize) (*oidlen)++; + } + if (*oidlen < oidsize) { + oid[(*oidlen)++] = o; + } + o = 0; + } + return 0; + +trunc: + fputs("[|snmp]", stdout); + return -1; +} + +static int smi_check_type(SmiBasetype basetype, int be) +{ + int i; + + for (i = 0; smi2betab[i].basetype != SMI_BASETYPE_UNKNOWN; i++) { + if (smi2betab[i].basetype == basetype && smi2betab[i].be == be) { + return 1; + } + } + + return 0; +} + +static int smi_check_a_range(SmiType *smiType, SmiRange *smiRange, + struct be *elem) +{ + int ok = 1; + + switch (smiType->basetype) { + case SMI_BASETYPE_OBJECTIDENTIFIER: + case SMI_BASETYPE_OCTETSTRING: + if (smiRange->minValue.value.unsigned32 + == smiRange->maxValue.value.unsigned32) { + ok = (elem->asnlen == smiRange->minValue.value.unsigned32); + } else { + ok = (elem->asnlen >= smiRange->minValue.value.unsigned32 + && elem->asnlen <= smiRange->maxValue.value.unsigned32); + } + break; + + case SMI_BASETYPE_INTEGER32: + ok = (elem->data.integer >= smiRange->minValue.value.integer32 + && elem->data.integer <= smiRange->maxValue.value.integer32); + break; + + case SMI_BASETYPE_UNSIGNED32: + ok = (elem->data.uns >= smiRange->minValue.value.unsigned32 + && elem->data.uns <= smiRange->maxValue.value.unsigned32); + break; + + case SMI_BASETYPE_UNSIGNED64: + /* XXX */ + break; + + /* case SMI_BASETYPE_INTEGER64: SMIng */ + /* case SMI_BASETYPE_FLOAT32: SMIng */ + /* case SMI_BASETYPE_FLOAT64: SMIng */ + /* case SMI_BASETYPE_FLOAT128: SMIng */ + + case SMI_BASETYPE_ENUM: + case SMI_BASETYPE_BITS: + case SMI_BASETYPE_UNKNOWN: + ok = 1; + break; + + default: + ok = 0; + break; + } + + return ok; +} + +static int smi_check_range(SmiType *smiType, struct be *elem) +{ + SmiRange *smiRange; + int ok = 1; + + for (smiRange = smiGetFirstRange(smiType); + smiRange; + smiRange = smiGetNextRange(smiRange)) { + + ok = smi_check_a_range(smiType, smiRange, elem); + + if (ok) { + break; + } + } + + if (ok) { + SmiType *parentType; + parentType = smiGetParentType(smiType); + if (parentType) { + ok = smi_check_range(parentType, elem); + } + } + + return ok; +} + +static SmiNode *smi_print_variable(struct be *elem, int *status) +{ + unsigned int oid[128], oidlen; + SmiNode *smiNode = NULL; + unsigned int i; + + *status = smi_decode_oid(elem, oid, sizeof(oid)/sizeof(unsigned int), + &oidlen); + if (*status < 0) + return NULL; + smiNode = smiGetNodeByOID(oidlen, oid); + if (! smiNode) { + *status = asn1_print(elem); + return NULL; + } + if (vflag) { + fputs(smiGetNodeModule(smiNode)->name, stdout); + fputs("::", stdout); + } + fputs(smiNode->name, stdout); + if (smiNode->oidlen < oidlen) { + for (i = smiNode->oidlen; i < oidlen; i++) { + printf(".%u", oid[i]); + } + } + *status = 0; + return smiNode; +} + +static int +smi_print_value(SmiNode *smiNode, u_char pduid, struct be *elem) +{ + unsigned int i, oid[128], oidlen; + SmiType *smiType; + SmiNamedNumber *nn; + int done = 0; + + if (! smiNode || ! (smiNode->nodekind + & (SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN))) { + return asn1_print(elem); + } + + if (elem->type == BE_NOSUCHOBJECT + || elem->type == BE_NOSUCHINST + || elem->type == BE_ENDOFMIBVIEW) { + return asn1_print(elem); + } + + if (NOTIFY_CLASS(pduid) && smiNode->access < SMI_ACCESS_NOTIFY) { + fputs("[notNotifyable]", stdout); + } + + if (READ_CLASS(pduid) && smiNode->access < SMI_ACCESS_READ_ONLY) { + fputs("[notReadable]", stdout); + } + + if (WRITE_CLASS(pduid) && smiNode->access < SMI_ACCESS_READ_WRITE) { + fputs("[notWritable]", stdout); + } + + if (RESPONSE_CLASS(pduid) + && smiNode->access == SMI_ACCESS_NOT_ACCESSIBLE) { + fputs("[noAccess]", stdout); + } + + smiType = smiGetNodeType(smiNode); + if (! smiType) { + return asn1_print(elem); + } + + if (! smi_check_type(smiType->basetype, elem->type)) { + fputs("[wrongType]", stdout); + } + + if (! smi_check_range(smiType, elem)) { + fputs("[outOfRange]", stdout); + } + + /* resolve bits to named bits */ + + /* check whether instance identifier is valid */ + + /* apply display hints (integer, octetstring) */ + + /* convert instance identifier to index type values */ + + switch (elem->type) { + case BE_OID: + if (smiType->basetype == SMI_BASETYPE_BITS) { + /* print bit labels */ + } else { + smi_decode_oid(elem, oid, + sizeof(oid)/sizeof(unsigned int), + &oidlen); + smiNode = smiGetNodeByOID(oidlen, oid); + if (smiNode) { + if (vflag) { + fputs(smiGetNodeModule(smiNode)->name, stdout); + fputs("::", stdout); + } + fputs(smiNode->name, stdout); + if (smiNode->oidlen < oidlen) { + for (i = smiNode->oidlen; + i < oidlen; i++) { + printf(".%u", oid[i]); + } + } + done++; + } + } + break; + + case BE_INT: + if (smiType->basetype == SMI_BASETYPE_ENUM) { + for (nn = smiGetFirstNamedNumber(smiType); + nn; + nn = smiGetNextNamedNumber(nn)) { + if (nn->value.value.integer32 + == elem->data.integer) { + fputs(nn->name, stdout); + printf("(%d)", elem->data.integer); + done++; + break; + } + } + } + break; + } + + if (! done) { + return asn1_print(elem); + } + return 0; +} +#endif + +/* + * General SNMP header + * SEQUENCE { + * version INTEGER {version-1(0)}, + * community OCTET STRING, + * data ANY -- PDUs + * } + * PDUs for all but Trap: (see rfc1157 from page 15 on) + * SEQUENCE { + * request-id INTEGER, + * error-status INTEGER, + * error-index INTEGER, + * varbindlist SEQUENCE OF + * SEQUENCE { + * name ObjectName, + * value ObjectValue + * } + * } + * PDU for Trap: + * SEQUENCE { + * enterprise OBJECT IDENTIFIER, + * agent-addr NetworkAddress, + * generic-trap INTEGER, + * specific-trap INTEGER, + * time-stamp TimeTicks, + * varbindlist SEQUENCE OF + * SEQUENCE { + * name ObjectName, + * value ObjectValue + * } + * } + */ + +/* + * Decode SNMP varBind + */ +static void +varbind_print(u_char pduid, const u_char *np, u_int length) +{ + struct be elem; + int count = 0, ind; +#ifdef LIBSMI + SmiNode *smiNode = NULL; +#endif + int status; + + /* Sequence of varBind */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!SEQ of varbind]", stdout); + asn1_print(&elem); + return; + } + if ((u_int)count < length) + printf("[%d extra after SEQ of varbind]", length - count); + /* descend */ + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + for (ind = 1; length > 0; ind++) { + const u_char *vbend; + u_int vblength; + + fputs(" ", stdout); + + /* Sequence */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!varbind]", stdout); + asn1_print(&elem); + return; + } + vbend = np + count; + vblength = length - count; + /* descend */ + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + /* objName (OID) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_OID) { + fputs("[objName!=OID]", stdout); + asn1_print(&elem); + return; + } +#ifdef LIBSMI + smiNode = smi_print_variable(&elem, &status); +#else + status = asn1_print(&elem); +#endif + if (status < 0) + return; + length -= count; + np += count; + + if (pduid != GETREQ && pduid != GETNEXTREQ + && pduid != GETBULKREQ) + fputs("=", stdout); + + /* objVal (ANY) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (pduid == GETREQ || pduid == GETNEXTREQ + || pduid == GETBULKREQ) { + if (elem.type != BE_NULL) { + fputs("[objVal!=NULL]", stdout); + if (asn1_print(&elem) < 0) + return; + } + } else { + if (elem.type != BE_NULL) { +#ifdef LIBSMI + status = smi_print_value(smiNode, pduid, &elem); +#else + status = asn1_print(&elem); +#endif + } + if (status < 0) + return; + } + length = vblength; + np = vbend; + } +} + +/* + * Decode SNMP PDUs: GetRequest, GetNextRequest, GetResponse, SetRequest, + * GetBulk, Inform, V2Trap, and Report + */ +static void +snmppdu_print(u_short pduid, const u_char *np, u_int length) +{ + struct be elem; + int count = 0, error; + + /* reqId (Integer) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[reqId!=INT]", stdout); + asn1_print(&elem); + return; + } + if (vflag) + printf("R=%d ", elem.data.integer); + length -= count; + np += count; + + /* errorStatus (Integer) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[errorStatus!=INT]", stdout); + asn1_print(&elem); + return; + } + error = 0; + if ((pduid == GETREQ || pduid == GETNEXTREQ || pduid == SETREQ + || pduid == INFORMREQ || pduid == V2TRAP || pduid == REPORT) + && elem.data.integer != 0) { + char errbuf[20]; + printf("[errorStatus(%s)!=0]", + DECODE_ErrorStatus(elem.data.integer)); + } else if (pduid == GETBULKREQ) { + printf(" N=%d", elem.data.integer); + } else if (elem.data.integer != 0) { + char errbuf[20]; + printf(" %s", DECODE_ErrorStatus(elem.data.integer)); + error = elem.data.integer; + } + length -= count; + np += count; + + /* errorIndex (Integer) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[errorIndex!=INT]", stdout); + asn1_print(&elem); + return; + } + if ((pduid == GETREQ || pduid == GETNEXTREQ || pduid == SETREQ + || pduid == INFORMREQ || pduid == V2TRAP || pduid == REPORT) + && elem.data.integer != 0) + printf("[errorIndex(%d)!=0]", elem.data.integer); + else if (pduid == GETBULKREQ) + printf(" M=%d", elem.data.integer); + else if (elem.data.integer != 0) { + if (!error) + printf("[errorIndex(%d) w/o errorStatus]", + elem.data.integer); + else { + printf("@%d", elem.data.integer); + error = elem.data.integer; + } + } else if (error) { + fputs("[errorIndex==0]", stdout); + error = 0; + } + length -= count; + np += count; + + varbind_print(pduid, np, length); + return; +} + +/* + * Decode SNMP Trap PDU + */ +static void +trappdu_print(const u_char *np, u_int length) +{ + struct be elem; + int count = 0, generic; + + putchar(' '); + + /* enterprise (oid) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_OID) { + fputs("[enterprise!=OID]", stdout); + asn1_print(&elem); + return; + } + if (asn1_print(&elem) < 0) + return; + length -= count; + np += count; + + putchar(' '); + + /* agent-addr (inetaddr) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INETADDR) { + fputs("[agent-addr!=INETADDR]", stdout); + asn1_print(&elem); + return; + } + if (asn1_print(&elem) < 0) + return; + length -= count; + np += count; + + /* generic-trap (Integer) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[generic-trap!=INT]", stdout); + asn1_print(&elem); + return; + } + generic = elem.data.integer; + { + char buf[20]; + printf(" %s", DECODE_GenericTrap(generic)); + } + length -= count; + np += count; + + /* specific-trap (Integer) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[specific-trap!=INT]", stdout); + asn1_print(&elem); + return; + } + if (generic != GT_ENTERPRISE) { + if (elem.data.integer != 0) + printf("[specific-trap(%d)!=0]", elem.data.integer); + } else + printf(" s=%d", elem.data.integer); + length -= count; + np += count; + + putchar(' '); + + /* time-stamp (TimeTicks) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_UNS) { /* XXX */ + fputs("[time-stamp!=TIMETICKS]", stdout); + asn1_print(&elem); + return; + } + if (asn1_print(&elem) < 0) + return; + length -= count; + np += count; + + varbind_print (TRAP, np, length); + return; +} + +/* + * Decode arbitrary SNMP PDUs. + */ +static void +pdu_print(const u_char *np, u_int length, int version) +{ + struct be pdu; + int count = 0; + + /* PDU (Context) */ + if ((count = asn1_parse(np, length, &pdu)) < 0) + return; + if (pdu.type != BE_PDU) { + fputs("[no PDU]", stdout); + return; + } + if ((u_int)count < length) + printf("[%d extra after PDU]", length - count); + if (vflag) { + fputs("{ ", stdout); + } + if (asn1_print(&pdu) < 0) + return; + fputs(" ", stdout); + /* descend into PDU */ + length = pdu.asnlen; + np = (u_char *)pdu.data.raw; + + if (version == SNMP_VERSION_1 && + (pdu.id == GETBULKREQ || pdu.id == INFORMREQ || + pdu.id == V2TRAP || pdu.id == REPORT)) { + printf("[v2 PDU in v1 message]"); + return; + } + + if (version == SNMP_VERSION_2 && pdu.id == TRAP) { + printf("[v1 PDU in v2 message]"); + return; + } + + switch (pdu.id) { + case TRAP: + trappdu_print(np, length); + break; + case GETREQ: + case GETNEXTREQ: + case GETRESP: + case SETREQ: + case GETBULKREQ: + case INFORMREQ: + case V2TRAP: + case REPORT: + snmppdu_print(pdu.id, np, length); + break; + } + + if (vflag) { + fputs(" } ", stdout); + } +} + +/* + * Decode a scoped SNMP PDU. + */ +static void +scopedpdu_print(const u_char *np, u_int length, int version) +{ + struct be elem; + int i, count = 0; + + /* Sequence */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!scoped PDU]", stdout); + asn1_print(&elem); + return; + } + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + /* contextEngineID (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[contextEngineID!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + fputs("E= ", stdout); + for (i = 0; i < (int)elem.asnlen; i++) { + printf("0x%02X", elem.data.str[i]); + } + fputs(" ", stdout); + + /* contextName (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[contextName!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + printf("C=%.*s ", (int)elem.asnlen, elem.data.str); + + pdu_print(np, length, version); +} + +/* + * Decode SNMP Community Header (SNMPv1 and SNMPv2c) + */ +static void +community_print(const u_char *np, u_int length, int version) +{ + struct be elem; + int count = 0; + + /* Community (String) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[comm!=STR]", stdout); + asn1_print(&elem); + return; + } + /* default community */ + if (!(elem.asnlen == sizeof(DEF_COMMUNITY) - 1 && + strncmp((char *)elem.data.str, DEF_COMMUNITY, + sizeof(DEF_COMMUNITY) - 1) == 0)) + /* ! "public" */ + printf("C=%.*s ", (int)elem.asnlen, elem.data.str); + length -= count; + np += count; + + pdu_print(np, length, version); +} + +/* + * Decode SNMPv3 User-based Security Message Header (SNMPv3) + */ +static void +usm_print(const u_char *np, u_int length) +{ + struct be elem; + int count = 0; + + /* Sequence */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!usm]", stdout); + asn1_print(&elem); + return; + } + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + /* msgAuthoritativeEngineID (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgAuthoritativeEngineID!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + /* msgAuthoritativeEngineBoots (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[msgAuthoritativeEngineBoots!=INT]", stdout); + asn1_print(&elem); + return; + } + if (vflag) + printf("B=%d ", elem.data.integer); + length -= count; + np += count; + + /* msgAuthoritativeEngineTime (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[msgAuthoritativeEngineTime!=INT]", stdout); + asn1_print(&elem); + return; + } + if (vflag) + printf("T=%d ", elem.data.integer); + length -= count; + np += count; + + /* msgUserName (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgUserName!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + printf("U=%.*s ", (int)elem.asnlen, elem.data.str); + + /* msgAuthenticationParameters (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgAuthenticationParameters!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + /* msgPrivacyParameters (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgPrivacyParameters!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + if ((u_int)count < length) + printf("[%d extra after usm SEQ]", length - count); +} + +/* + * Decode SNMPv3 Message Header (SNMPv3) + */ +static void +v3msg_print(const u_char *np, u_int length) +{ + struct be elem; + int count = 0; + u_char flags; + int model; + const u_char *xnp = np; + int xlength = length; + + /* Sequence */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!message]", stdout); + asn1_print(&elem); + return; + } + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + if (vflag) { + fputs("{ ", stdout); + } + + /* msgID (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[msgID!=INT]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + /* msgMaxSize (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[msgMaxSize!=INT]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + /* msgFlags (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgFlags!=STR]", stdout); + asn1_print(&elem); + return; + } + if (elem.asnlen != 1) { + printf("[msgFlags size %d]", elem.asnlen); + return; + } + flags = elem.data.str[0]; + if (flags != 0x00 && flags != 0x01 && flags != 0x03 + && flags != 0x04 && flags != 0x05 && flags != 0x07) { + printf("[msgFlags=0x%02X]", flags); + return; + } + length -= count; + np += count; + + fputs("F=", stdout); + if (flags & 0x01) fputs("a", stdout); + if (flags & 0x02) fputs("p", stdout); + if (flags & 0x04) fputs("r", stdout); + fputs(" ", stdout); + + /* msgSecurityModel (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[msgSecurityModel!=INT]", stdout); + asn1_print(&elem); + return; + } + model = elem.data.integer; + length -= count; + np += count; + + if ((u_int)count < length) + printf("[%d extra after message SEQ]", length - count); + + if (vflag) { + fputs("} ", stdout); + } + + if (model == 3) { + if (vflag) { + fputs("{ USM ", stdout); + } + } else { + printf("[security model %d]", model); + return; + } + + np = xnp + (np - xnp); + length = xlength - (np - xnp); + + /* msgSecurityParameters (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgSecurityParameters!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + if (model == 3) { + usm_print(elem.data.str, elem.asnlen); + if (vflag) { + fputs("} ", stdout); + } + } + + if (vflag) { + fputs("{ ScopedPDU ", stdout); + } + + scopedpdu_print(np, length, 3); + + if (vflag) { + fputs("} ", stdout); + } +} + +/* + * Decode SNMP header and pass on to PDU printing routines + */ +void +snmp_print(const u_char *np, u_int length) +{ + struct be elem; + int count = 0; + int version = 0; + + putchar(' '); + + /* initial Sequence */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!init SEQ]", stdout); + asn1_print(&elem); + return; + } + if ((u_int)count < length) + printf("[%d extra after iSEQ]", length - count); + /* descend */ + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + /* Version (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[version!=INT]", stdout); + asn1_print(&elem); + return; + } + + switch (elem.data.integer) { + case SNMP_VERSION_1: + case SNMP_VERSION_2: + case SNMP_VERSION_3: + if (vflag) + printf("{ %s ", SnmpVersion[elem.data.integer]); + break; + default: + printf("[version = %d]", elem.data.integer); + return; + } + version = elem.data.integer; + length -= count; + np += count; + + switch (version) { + case SNMP_VERSION_1: + case SNMP_VERSION_2: + community_print(np, length, version); + break; + case SNMP_VERSION_3: + v3msg_print(np, length); + break; + default: + printf("[version = %d]", elem.data.integer); + break; + } + + if (vflag) { + fputs("} ", stdout); + } +} diff --git a/freebsd/contrib/tcpdump/print-stp.c b/freebsd/contrib/tcpdump/print-stp.c new file mode 100644 index 00000000..6cd9432e --- /dev/null +++ b/freebsd/contrib/tcpdump/print-stp.c @@ -0,0 +1,460 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2000 Lennert Buytenhek + * + * This software may be distributed either under the terms of the + * BSD-style license that accompanies tcpdump or the GNU General + * Public License + * + * Format and print IEEE 802.1d spanning tree protocol packets. + * Contributed by Lennert Buytenhek <buytenh@gnu.org> + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-stp.c,v 1.20 2007-03-18 17:11:46 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#define RSTP_EXTRACT_PORT_ROLE(x) (((x)&0x0C)>>2) +/* STP timers are expressed in multiples of 1/256th second */ +#define STP_TIME_BASE 256 +#define STP_BPDU_MSTP_MIN_LEN 102 + +struct stp_bpdu_ { + u_int8_t protocol_id[2]; + u_int8_t protocol_version; + u_int8_t bpdu_type; + u_int8_t flags; + u_int8_t root_id[8]; + u_int8_t root_path_cost[4]; + u_int8_t bridge_id[8]; + u_int8_t port_id[2]; + u_int8_t message_age[2]; + u_int8_t max_age[2]; + u_int8_t hello_time[2]; + u_int8_t forward_delay[2]; + u_int8_t v1_length; +}; + +#define STP_PROTO_REGULAR 0x00 +#define STP_PROTO_RAPID 0x02 +#define STP_PROTO_MSTP 0x03 +#define STP_PROTO_SPB 0x04 + +struct tok stp_proto_values[] = { + { STP_PROTO_REGULAR, "802.1d" }, + { STP_PROTO_RAPID, "802.1w" }, + { STP_PROTO_MSTP, "802.1s" }, + { STP_PROTO_SPB, "802.1aq" }, + { 0, NULL} +}; + +#define STP_BPDU_TYPE_CONFIG 0x00 +#define STP_BPDU_TYPE_RSTP 0x02 +#define STP_BPDU_TYPE_TOPO_CHANGE 0x80 + +struct tok stp_bpdu_flag_values[] = { + { 0x01, "Topology change" }, + { 0x02, "Proposal" }, + { 0x10, "Learn" }, + { 0x20, "Forward" }, + { 0x40, "Agreement" }, + { 0x80, "Topology change ACK" }, + { 0, NULL} +}; + +struct tok stp_bpdu_type_values[] = { + { STP_BPDU_TYPE_CONFIG, "Config" }, + { STP_BPDU_TYPE_RSTP, "Rapid STP" }, + { STP_BPDU_TYPE_TOPO_CHANGE, "Topology Change" }, + { 0, NULL} +}; + +struct tok rstp_obj_port_role_values[] = { + { 0x00, "Unknown" }, + { 0x01, "Alternate" }, + { 0x02, "Root" }, + { 0x03, "Designated" }, + { 0, NULL} +}; + +static char * +stp_print_bridge_id(const u_char *p) +{ + static char bridge_id_str[sizeof("pppp.aa:bb:cc:dd:ee:ff")]; + + snprintf(bridge_id_str, sizeof(bridge_id_str), + "%.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + + return bridge_id_str; +} + +static void +stp_print_config_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length) +{ + printf(", Flags [%s]", + bittok2str(stp_bpdu_flag_values, "none", stp_bpdu->flags)); + + printf(", bridge-id %s.%04x, length %u", + stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id), + EXTRACT_16BITS(&stp_bpdu->port_id), length); + + /* in non-verbose mode just print the bridge-id */ + if (!vflag) { + return; + } + + printf("\n\tmessage-age %.2fs, max-age %.2fs" + ", hello-time %.2fs, forwarding-delay %.2fs", + (float)EXTRACT_16BITS(&stp_bpdu->message_age) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->max_age) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->hello_time) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->forward_delay) / STP_TIME_BASE); + + printf("\n\troot-id %s, root-pathcost %u", + stp_print_bridge_id((const u_char *)&stp_bpdu->root_id), + EXTRACT_32BITS(&stp_bpdu->root_path_cost)); + + /* Port role is only valid for 802.1w */ + if (stp_bpdu->protocol_version == STP_PROTO_RAPID) { + printf(", port-role %s", + tok2str(rstp_obj_port_role_values, "Unknown", + RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags))); + } +} + +/* + * MSTP packet format + * Ref. IEEE 802.1Q 2003 Ed. Section 14 + * + * MSTP BPDU + * + * 2 - bytes Protocol Id + * 1 - byte Protocol Ver. + * 1 - byte BPDU tye + * 1 - byte Flags + * 8 - bytes CIST Root Identifier + * 4 - bytes CIST External Path Cost + * 8 - bytes CIST Regional Root Identifier + * 2 - bytes CIST Port Identifier + * 2 - bytes Message Age + * 2 - bytes Max age + * 2 - bytes Hello Time + * 2 - bytes Forward delay + * 1 - byte Version 1 length. Must be 0 + * 2 - bytes Version 3 length + * 1 - byte Config Identifier + * 32 - bytes Config Name + * 2 - bytes Revision level + * 16 - bytes Config Digest [MD5] + * 4 - bytes CIST Internal Root Path Cost + * 8 - bytes CIST Bridge Identifier + * 1 - byte CIST Remaining Hops + * 16 - bytes MSTI information [Max 64 MSTI, each 16 bytes] + * + * + * SPB BPDU + * Ref. IEEE 802.1aq. Section 14 + * + * 2 - bytes Version 4 length + * 1 - byte Aux Config Identifier + * 32 - bytes Aux Config Name + * 2 - bytes Aux Revision level + * 16 - bytes Aux Config Digest [MD5] + * 1 - byte (1 - 2) Agreement Number + * (3 - 4) Discarded Agreement Number + * (5) Agreement Valid Flag + * (6) Restricted Role Flag + * (7 - 8) Unused sent zero + * 1 - byte Unused + * 1 - byte (1 - 4) Agreement Digest Format Identifier + * (5 - 8) Agreement Digest Format Capabilities + * 1 - byte (1 - 4) Agreement Digest Convention Identifier + * (5 - 8) Agreement Digest Convention Capabilities + * 2 - bytes Agreement Digest Edge Count + * 8 - byte Reserved Set + * 20 - bytes Computed Topology Digest + * + * + * MSTI Payload + * + * 1 - byte MSTI flag + * 8 - bytes MSTI Regional Root Identifier + * 4 - bytes MSTI Regional Path Cost + * 1 - byte MSTI Bridge Priority + * 1 - byte MSTI Port Priority + * 1 - byte MSTI Remaining Hops + * + */ + +#define MST_BPDU_MSTI_LENGTH 16 +#define MST_BPDU_CONFIG_INFO_LENGTH 64 + +/* Offsets of fields from the begginning for the packet */ +#define MST_BPDU_VER3_LEN_OFFSET 36 +#define MST_BPDU_CONFIG_NAME_OFFSET 39 +#define MST_BPDU_CONFIG_DIGEST_OFFSET 73 +#define MST_BPDU_CIST_INT_PATH_COST_OFFSET 89 +#define MST_BPDU_CIST_BRIDGE_ID_OFFSET 93 +#define MST_BPDU_CIST_REMAIN_HOPS_OFFSET 101 +#define MST_BPDU_MSTI_OFFSET 102 +/* Offsets within an MSTI */ +#define MST_BPDU_MSTI_ROOT_PRIO_OFFSET 1 +#define MST_BPDU_MSTI_ROOT_PATH_COST_OFFSET 9 +#define MST_BPDU_MSTI_BRIDGE_PRIO_OFFSET 13 +#define MST_BPDU_MSTI_PORT_PRIO_OFFSET 14 +#define MST_BPDU_MSTI_REMAIN_HOPS_OFFSET 15 + +#define SPB_BPDU_MIN_LEN 87 +#define SPB_BPDU_CONFIG_NAME_OFFSET 3 +#define SPB_BPDU_CONFIG_REV_OFFSET SPB_BPDU_CONFIG_NAME_OFFSET + 32 +#define SPB_BPDU_CONFIG_DIGEST_OFFSET SPB_BPDU_CONFIG_REV_OFFSET + 2 +#define SPB_BPDU_AGREEMENT_OFFSET SPB_BPDU_CONFIG_DIGEST_OFFSET + 16 +#define SPB_BPDU_AGREEMENT_UNUSED_OFFSET SPB_BPDU_AGREEMENT_OFFSET + 1 +#define SPB_BPDU_AGREEMENT_FORMAT_OFFSET SPB_BPDU_AGREEMENT_UNUSED_OFFSET + 1 +#define SPB_BPDU_AGREEMENT_CON_OFFSET SPB_BPDU_AGREEMENT_FORMAT_OFFSET + 1 +#define SPB_BPDU_AGREEMENT_EDGE_OFFSET SPB_BPDU_AGREEMENT_CON_OFFSET + 1 +#define SPB_BPDU_AGREEMENT_RES1_OFFSET SPB_BPDU_AGREEMENT_EDGE_OFFSET + 2 +#define SPB_BPDU_AGREEMENT_RES2_OFFSET SPB_BPDU_AGREEMENT_RES1_OFFSET + 4 +#define SPB_BPDU_AGREEMENT_DIGEST_OFFSET SPB_BPDU_AGREEMENT_RES2_OFFSET + 4 + + +static void +stp_print_mstp_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length) +{ + const u_char *ptr; + u_int16_t v3len; + u_int16_t len; + u_int16_t msti; + u_int16_t offset; + + ptr = (const u_char *)stp_bpdu; + printf(", CIST Flags [%s], length %u", + bittok2str(stp_bpdu_flag_values, "none", stp_bpdu->flags), length); + + /* + * in non-verbose mode just print the flags. We dont read that much + * of the packet (DEFAULT_SNAPLEN) to print out cist bridge-id + */ + if (!vflag) { + return; + } + + printf("\n\tport-role %s, ", + tok2str(rstp_obj_port_role_values, "Unknown", + RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags))); + + printf("CIST root-id %s, CIST ext-pathcost %u ", + stp_print_bridge_id((const u_char *)&stp_bpdu->root_id), + EXTRACT_32BITS(&stp_bpdu->root_path_cost)); + + printf("\n\tCIST regional-root-id %s, ", + stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id)); + + printf("CIST port-id %04x, ", EXTRACT_16BITS(&stp_bpdu->port_id)); + + printf("\n\tmessage-age %.2fs, max-age %.2fs" + ", hello-time %.2fs, forwarding-delay %.2fs", + (float)EXTRACT_16BITS(&stp_bpdu->message_age) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->max_age) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->hello_time) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->forward_delay) / STP_TIME_BASE); + + printf ("\n\tv3len %d, ", EXTRACT_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET)); + printf("MCID Name %s, rev %u, " + "\n\t\tdigest %08x%08x%08x%08x, ", + ptr + MST_BPDU_CONFIG_NAME_OFFSET, + EXTRACT_16BITS(ptr + MST_BPDU_CONFIG_NAME_OFFSET + 32), + EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET), + EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 4), + EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 8), + EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12)); + + printf ("CIST int-root-pathcost %u, ", + EXTRACT_32BITS(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET)); + + printf("\n\tCIST bridge-id %s, ", + stp_print_bridge_id(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET)); + + printf("CIST remaining-hops %d", ptr[MST_BPDU_CIST_REMAIN_HOPS_OFFSET]); + + /* Dump all MSTI's */ + v3len = EXTRACT_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET); + if (v3len > MST_BPDU_CONFIG_INFO_LENGTH) { + len = v3len - MST_BPDU_CONFIG_INFO_LENGTH; + offset = MST_BPDU_MSTI_OFFSET; + while (len >= MST_BPDU_MSTI_LENGTH) { + msti = EXTRACT_16BITS(ptr + offset + + MST_BPDU_MSTI_ROOT_PRIO_OFFSET); + msti = msti & 0x0FFF; + + printf("\n\tMSTI %d, Flags [%s], port-role %s", + msti, bittok2str(stp_bpdu_flag_values, "none", ptr[offset]), + tok2str(rstp_obj_port_role_values, "Unknown", + RSTP_EXTRACT_PORT_ROLE(ptr[offset]))); + printf("\n\t\tMSTI regional-root-id %s, pathcost %u", + stp_print_bridge_id(ptr + offset + + MST_BPDU_MSTI_ROOT_PRIO_OFFSET), + EXTRACT_32BITS(ptr + offset + + MST_BPDU_MSTI_ROOT_PATH_COST_OFFSET)); + printf("\n\t\tMSTI bridge-prio %d, port-prio %d, hops %d", + ptr[offset + MST_BPDU_MSTI_BRIDGE_PRIO_OFFSET] >> 4, + ptr[offset + MST_BPDU_MSTI_PORT_PRIO_OFFSET] >> 4, + ptr[offset + MST_BPDU_MSTI_REMAIN_HOPS_OFFSET]); + + len -= MST_BPDU_MSTI_LENGTH; + offset += MST_BPDU_MSTI_LENGTH; + } + } + + if ((length-offset) >= SPB_BPDU_MIN_LEN) + { + printf("\n\tv4len %d AUXMCID Name %s, Rev %u, \n\t\tdigest %08x%08x%08x%08x", + EXTRACT_16BITS (ptr + offset), + ptr + offset + SPB_BPDU_CONFIG_NAME_OFFSET, + EXTRACT_16BITS(ptr + offset + SPB_BPDU_CONFIG_REV_OFFSET), + EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET), + EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 4), + EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 8), + EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 12)); + + printf("\n\tAgreement num %d, Discarded Agreement num %d, Agreement valid-" + "flag %d, \n\tRestricted role-flag: %d, Format id %d cap %d, " + "Convention id %d cap %d, \n\tEdge count %d, " + "Agreement digest %08x%08x%08x%08x%08x\n", + ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>6, + ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>4 & 0x3, + ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>3 & 0x1, + ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>2 & 0x1, + ptr[offset + SPB_BPDU_AGREEMENT_FORMAT_OFFSET]>>4, + ptr[offset + SPB_BPDU_AGREEMENT_FORMAT_OFFSET]&0x00ff, + ptr[offset + SPB_BPDU_AGREEMENT_CON_OFFSET]>>4, + ptr[offset + SPB_BPDU_AGREEMENT_CON_OFFSET]&0x00ff, + EXTRACT_16BITS(ptr + offset + SPB_BPDU_AGREEMENT_EDGE_OFFSET), + EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET), + EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+4, + EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+8, + EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+12, + EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+16); + } +} + +/* + * Print 802.1d / 802.1w / 802.1q (mstp) / 802.1aq (spb) packets. + */ +void +stp_print(const u_char *p, u_int length) +{ + const struct stp_bpdu_ *stp_bpdu; + u_int16_t mstp_len; + u_int16_t spb_len; + + stp_bpdu = (struct stp_bpdu_*)p; + + /* Minimum STP Frame size. */ + if (length < 4) + goto trunc; + + if (EXTRACT_16BITS(&stp_bpdu->protocol_id)) { + printf("unknown STP version, length %u", length); + return; + } + + printf("STP %s", tok2str(stp_proto_values, "Unknown STP protocol (0x%02x)", + stp_bpdu->protocol_version)); + + switch (stp_bpdu->protocol_version) { + case STP_PROTO_REGULAR: + case STP_PROTO_RAPID: + case STP_PROTO_MSTP: + case STP_PROTO_SPB: + break; + default: + return; + } + + printf(", %s", tok2str(stp_bpdu_type_values, "Unknown BPDU Type (0x%02x)", + stp_bpdu->bpdu_type)); + + switch (stp_bpdu->bpdu_type) { + case STP_BPDU_TYPE_CONFIG: + if (length < sizeof(struct stp_bpdu_) - 1) { + goto trunc; + } + stp_print_config_bpdu(stp_bpdu, length); + break; + + case STP_BPDU_TYPE_RSTP: + if (stp_bpdu->protocol_version == STP_PROTO_RAPID) { + if (length < sizeof(struct stp_bpdu_)) { + goto trunc; + } + stp_print_config_bpdu(stp_bpdu, length); + } else if (stp_bpdu->protocol_version == STP_PROTO_MSTP || + stp_bpdu->protocol_version == STP_PROTO_SPB) { + if (length < STP_BPDU_MSTP_MIN_LEN) { + goto trunc; + } + + if (stp_bpdu->v1_length != 0) { + /* FIX ME: Emit a message here ? */ + goto trunc; + } + + /* Validate v3 length */ + mstp_len = EXTRACT_16BITS(p + MST_BPDU_VER3_LEN_OFFSET); + mstp_len += 2; /* length encoding itself is 2 bytes */ + if (length < (sizeof(struct stp_bpdu_) + mstp_len)) { + goto trunc; + } + + if (stp_bpdu->protocol_version == STP_PROTO_SPB) + { + /* Validate v4 length */ + spb_len = EXTRACT_16BITS (p + MST_BPDU_VER3_LEN_OFFSET + mstp_len); + spb_len += 2; + if (length < (sizeof(struct stp_bpdu_) + mstp_len + spb_len) || + spb_len < SPB_BPDU_MIN_LEN) { + goto trunc; + } + } + + stp_print_mstp_bpdu(stp_bpdu, length); + } + break; + + case STP_BPDU_TYPE_TOPO_CHANGE: + /* always empty message - just break out */ + break; + + default: + break; + } + + return; + trunc: + printf("[|stp %d]", length); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-sunatm.c b/freebsd/contrib/tcpdump/print-sunatm.c new file mode 100644 index 00000000..2cd223da --- /dev/null +++ b/freebsd/contrib/tcpdump/print-sunatm.c @@ -0,0 +1,119 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +struct mbuf; +struct rtentry; + +#include <stdio.h> +#include <pcap.h> + +#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); +} diff --git a/freebsd/contrib/tcpdump/print-sunrpc.c b/freebsd/contrib/tcpdump/print-sunrpc.c new file mode 100644 index 00000000..07eddff2 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-sunrpc.c @@ -0,0 +1,176 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1992, 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. + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-sunrpc.c,v 1.47 2005-04-27 21:43:48 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * At least on HP-UX: + * + * 1) getrpcbynumber() is declared in <netdb.h>, not any of the RPC + * header files + * + * and + * + * 2) if _XOPEN_SOURCE_EXTENDED is defined, <netdb.h> doesn't declare + * it + * + * so we undefine it. + */ +#undef _XOPEN_SOURCE_EXTENDED + +#include <tcpdump-stdinc.h> + +#if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) +#include <rpc/rpc.h> +#ifdef HAVE_RPC_RPCENT_H +#include <rpc/rpcent.h> +#endif /* HAVE_RPC_RPCENT_H */ +#endif /* defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) */ + +#include <stdio.h> +#include <string.h> + +#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 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); +} diff --git a/freebsd/contrib/tcpdump/print-symantec.c b/freebsd/contrib/tcpdump/print-symantec.c new file mode 100644 index 00000000..d42e6faa --- /dev/null +++ b/freebsd/contrib/tcpdump/print-symantec.c @@ -0,0 +1,122 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * 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-symantec.c,v 1.5 2005-07-07 01:22:21 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <pcap.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" + +#include "ether.h" + +struct symantec_header { + u_int8_t stuff1[6]; + u_int16_t ether_type; + u_int8_t stuff2[36]; +}; + +static inline void +symantec_hdr_print(register const u_char *bp, u_int length) +{ + register const struct symantec_header *sp; + u_int16_t etype; + + sp = (const struct symantec_header *)bp; + + etype = EXTRACT_16BITS(&sp->ether_type); + if (!qflag) { + if (etype <= ETHERMTU) + (void)printf("invalid ethertype %u", etype); + else + (void)printf("ethertype %s (0x%04x)", + tok2str(ethertype_values,"Unknown", etype), + etype); + } else { + if (etype <= ETHERMTU) + (void)printf("invalid ethertype %u", etype); + else + (void)printf("%s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", etype)); + } + + (void)printf(", length %u: ", length); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether 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 +symantec_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int length = h->len; + u_int caplen = h->caplen; + struct symantec_header *sp; + u_short ether_type; + + if (caplen < sizeof (struct symantec_header)) { + printf("[|symantec]"); + return caplen; + } + + if (eflag) + symantec_hdr_print(p, length); + + length -= sizeof (struct symantec_header); + caplen -= sizeof (struct symantec_header); + sp = (struct symantec_header *)p; + p += sizeof (struct symantec_header); + + ether_type = EXTRACT_16BITS(&sp->ether_type); + + if (ether_type <= ETHERMTU) { + /* ether_type not known, print raw packet */ + if (!eflag) + symantec_hdr_print((u_char *)sp, length + sizeof (struct symantec_header)); + + if (!suppress_default_print) + default_print(p, caplen); + } else if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + symantec_hdr_print((u_char *)sp, length + sizeof (struct symantec_header)); + + if (!suppress_default_print) + default_print(p, caplen); + } + + return (sizeof (struct symantec_header)); +} diff --git a/freebsd/contrib/tcpdump/print-syslog.c b/freebsd/contrib/tcpdump/print-syslog.c new file mode 100644 index 00000000..8585ee00 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-syslog.c @@ -0,0 +1,165 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org> + * 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. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-syslog.c,v 1.1 2004-10-29 11:42:53 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * tokenlists and #defines taken from Ethereal - Network traffic analyzer + * by Gerald Combs <gerald@ethereal.com> + */ + +#define SYSLOG_SEVERITY_MASK 0x0007 /* 0000 0000 0000 0111 */ +#define SYSLOG_FACILITY_MASK 0x03f8 /* 0000 0011 1111 1000 */ +#define SYSLOG_MAX_DIGITS 3 /* The maximum number if priority digits to read in. */ + +static const struct tok syslog_severity_values[] = { + { 0, "emergency" }, + { 1, "alert" }, + { 2, "critical" }, + { 3, "error" }, + { 4, "warning" }, + { 5, "notice" }, + { 6, "info" }, + { 7, "debug" }, + { 0, NULL }, +}; + +static const struct tok syslog_facility_values[] = { + { 0, "kernel" }, + { 1, "user" }, + { 2, "mail" }, + { 3, "daemon" }, + { 4, "auth" }, + { 5, "syslog" }, + { 6, "lpr" }, + { 7, "news" }, + { 8, "uucp" }, + { 9, "cron" }, + { 10, "authpriv" }, + { 11, "ftp" }, + { 12, "ntp" }, + { 13, "security" }, + { 14, "console" }, + { 15, "cron" }, + { 16, "local0" }, + { 17, "local1" }, + { 18, "local2" }, + { 19, "local3" }, + { 20, "local4" }, + { 21, "local5" }, + { 22, "local6" }, + { 23, "local7" }, + { 0, NULL }, +}; + +void +syslog_print(register const u_char *pptr, register u_int len) +{ + u_int16_t msg_off = 0; + u_int16_t pri = 0; + u_int16_t facility,severity; + + /* extract decimal figures that are + * encapsulated within < > tags + * based on this decimal figure extract the + * severity and facility values + */ + + if (!TTEST2(*pptr, 1)) + goto trunc; + + if (*(pptr+msg_off) == '<') { + msg_off++; + + if (!TTEST2(*(pptr+msg_off), 1)) + goto trunc; + + while ( *(pptr+msg_off) >= '0' && + *(pptr+msg_off) <= '9' && + msg_off <= SYSLOG_MAX_DIGITS) { + + if (!TTEST2(*(pptr+msg_off), 1)) + goto trunc; + + pri = pri * 10 + (*(pptr+msg_off) - '0'); + msg_off++; + + if (!TTEST2(*(pptr+msg_off), 1)) + goto trunc; + + if (*(pptr+msg_off) == '>') + msg_off++; + } + } else { + printf("[|syslog]"); + return; + } + + facility = (pri & SYSLOG_FACILITY_MASK) >> 3; + severity = pri & SYSLOG_SEVERITY_MASK; + + + if (vflag < 1 ) + { + printf("SYSLOG %s.%s, length: %u", + tok2str(syslog_facility_values, "unknown (%u)", facility), + tok2str(syslog_severity_values, "unknown (%u)", severity), + len); + return; + } + + printf("SYSLOG, length: %u\n\tFacility %s (%u), Severity %s (%u)\n\tMsg: ", + len, + tok2str(syslog_facility_values, "unknown (%u)", facility), + facility, + tok2str(syslog_severity_values, "unknown (%u)", severity), + severity); + + /* print the syslog text in verbose mode */ + for (; msg_off < len; msg_off++) { + if (!TTEST2(*(pptr+msg_off), 1)) + goto trunc; + safeputchar(*(pptr+msg_off)); + } + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t",len)) + return; + } + + return; + +trunc: + printf("[|syslog]"); +} diff --git a/freebsd/contrib/tcpdump/print-tcp.c b/freebsd/contrib/tcpdump/print-tcp.c new file mode 100644 index 00000000..c377bac9 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-tcp.c @@ -0,0 +1,827 @@ +#include <machine/rtems-bsd-user-space.h> + +/* $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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#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 <openssl/md5.h> +#include <signature.h> + +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 { +#ifndef INET6 + struct in_addr src; + struct in_addr dst; +#else + struct in6_addr src; + struct in6_addr dst; +#endif /*INET6*/ + u_int port; +}; + +struct tcp_seq_hash { + struct tcp_seq_hash *nxt; + struct tha addr; + tcp_seq seq; + tcp_seq ack; +}; + +#define TSEQ_HASHSIZE 919 + +/* 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_hash[TSEQ_HASHSIZE]; + +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 } +}; + +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" }, + { 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; + int threv; +#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; + + /* + * 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. + */ + if (!qflag && hlen >= sizeof(*tp) && hlen <= length && + (length - hlen) >= 4) { + u_char *fraglenp; + u_int32_t fraglen; + register struct sunrpc_msg *rp; + enum sunrpc_msg_type direction; + + fraglenp = (u_char *)tp + hlen; + if (TTEST2(*fraglenp, 4)) { + fraglen = EXTRACT_32BITS(fraglenp) & 0x7FFFFFFF; + if (fraglen > (length - hlen) - 4) + fraglen = (length - hlen) - 4; + rp = (struct sunrpc_msg *)(fraglenp + 4); + if (TTEST(rp->rm_direction)) { + direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); + if (dport == NFS_PORT && + direction == SUNRPC_CALL) { + nfsreq_print((u_char *)rp, fraglen, + (u_char *)ip); + return; + } + if (sport == NFS_PORT && + direction == SUNRPC_REPLY) { + nfsreply_print((u_char *)rp, fraglen, + (u_char *)ip); + return; + } + } + } + } +#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)) { + register struct tcp_seq_hash *th; + const void *src, *dst; + register int rev; + struct tha tha; + /* + * Find (or record) the initial sequence numbers for + * this conversation. (we pick an arbitrary + * collating order so there's only one entry for + * both directions). + */ +#ifdef INET6 + rev = 0; + if (ip6) { + 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; + } + } else { + /* + * Zero out the tha structure; the src and dst + * fields are big enough to hold an IPv6 + * address, but we only have IPv4 addresses + * and thus must clear out the remaining 124 + * bits. + * + * XXX - should we just clear those bytes after + * copying the IPv4 addresses, rather than + * zeroing out the entire structure and then + * overwriting some of the zeroes? + * + * XXX - this could fail if we see TCP packets + * with an IPv6 address with the lower 124 bits + * all zero and also see TCP packes with an + * IPv4 address with the same 32 bits as the + * upper 32 bits of the IPv6 address in question. + * Can that happen? Is it likely enough to be + * an issue? + */ + memset(&tha, 0, sizeof(tha)); + 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; + } + } +#else + rev = 0; + 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; + } +#endif + + threv = rev; + 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 = threv = 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 Option %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 (threv) { + 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; + + default: + datalen = len - 2; + 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 (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); + } + + 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 +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); +} +#endif /* HAVE_LIBCRYPTO */ + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-telnet.c b/freebsd/contrib/tcpdump/print-telnet.c new file mode 100644 index 00000000..a2091789 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-telnet.c @@ -0,0 +1,269 @@ +#include <machine/rtems-bsd-user-space.h> + +/* $NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40: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 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. + */ +/* + * @(#)Copyright (c) 1994, Simon J. Gerraty. + * + * This is free software. It comes with NO WARRANTY. + * Permission to use, modify and distribute this source code + * is granted subject to the following conditions. + * 1/ that the above copyright notice and this notice + * are preserved in all copies. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-telnet.c,v 1.24 2003-12-29 11:05:10 hannes Exp $"; +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" + +#define TELCMDS +#define TELOPTS +#include "telnet.h" + +/* normal */ +static const char *cmds[] = { + "IS", "SEND", "INFO", +}; + +/* 37: Authentication */ +static const char *authcmd[] = { + "IS", "SEND", "REPLY", "NAME", +}; +static const char *authtype[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", + "SRP", "RSA", "SSL", NULL, NULL, + "LOKI", "SSA", "KEA_SJ", "KEA_SJ_INTEG", "DSS", + "NTLM", +}; + +/* 38: Encryption */ +static const char *enccmd[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "END_KEYID", "DEC_KEYID", +}; +static const char *enctype[] = { + "NULL", "DES_CFB64", "DES_OFB64", "DES3_CFB64", "DES3_OFB64", + NULL, "CAST5_40_CFB64", "CAST5_40_OFB64", "CAST128_CFB64", "CAST128_OFB64", +}; + +#define STR_OR_ID(x, tab) \ + (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) + +static char * +numstr(int x) +{ + static char buf[20]; + + snprintf(buf, sizeof(buf), "%#x", x); + return buf; +} + +/* sp points to IAC byte */ +static int +telnet_parse(const u_char *sp, u_int length, int print) +{ + int i, x; + u_int c; + const u_char *osp, *p; +#define FETCH(c, sp, length) \ + do { \ + if (length < 1) \ + goto pktend; \ + TCHECK(*sp); \ + c = *sp++; \ + length--; \ + } while (0) + + osp = sp; + + FETCH(c, sp, length); + if (c != IAC) + goto pktend; + FETCH(c, sp, length); + if (c == IAC) { /* <IAC><IAC>! */ + if (print) + printf("IAC IAC"); + goto done; + } + + i = c - TELCMD_FIRST; + if (i < 0 || i > IAC - TELCMD_FIRST) + goto pktend; + + switch (c) { + case DONT: + case DO: + case WONT: + case WILL: + case SB: + /* DONT/DO/WONT/WILL x */ + FETCH(x, sp, length); + if (x >= 0 && x < NTELOPTS) { + if (print) + (void)printf("%s %s", telcmds[i], telopts[x]); + } else { + if (print) + (void)printf("%s %#x", telcmds[i], x); + } + if (c != SB) + break; + /* IAC SB .... IAC SE */ + p = sp; + while (length > (u_int)(p + 1 - sp)) { + if (p[0] == IAC && p[1] == SE) + break; + p++; + } + if (*p != IAC) + goto pktend; + + switch (x) { + case TELOPT_AUTHENTICATION: + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, authcmd)); + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, authtype)); + break; + case TELOPT_ENCRYPT: + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, enccmd)); + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, enctype)); + break; + default: + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, cmds)); + break; + } + while (p > sp) { + FETCH(x, sp, length); + if (print) + (void)printf(" %#x", x); + } + /* terminating IAC SE */ + if (print) + (void)printf(" SE"); + sp += 2; + length -= 2; + break; + default: + if (print) + (void)printf("%s", telcmds[i]); + goto done; + } + +done: + return sp - osp; + +trunc: + (void)printf("[|telnet]"); +pktend: + return -1; +#undef FETCH +} + +void +telnet_print(const u_char *sp, u_int length) +{ + int first = 1; + const u_char *osp; + int l; + + osp = sp; + + while (length > 0 && *sp == IAC) { + l = telnet_parse(sp, length, 0); + if (l < 0) + break; + + /* + * now print it + */ + if (Xflag && 2 < vflag) { + if (first) + printf("\nTelnet:"); + hex_print_with_offset("\n", sp, l, sp - osp); + if (l > 8) + printf("\n\t\t\t\t"); + else + printf("%*s\t", (8 - l) * 3, ""); + } else + printf("%s", (first) ? " [telnet " : ", "); + + (void)telnet_parse(sp, length, 1); + first = 0; + + sp += l; + length -= l; + } + if (!first) { + if (Xflag && 2 < vflag) + printf("\n"); + else + printf("]"); + } +} diff --git a/freebsd/contrib/tcpdump/print-tftp.c b/freebsd/contrib/tcpdump/print-tftp.c new file mode 100644 index 00000000..2a2f70b4 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-tftp.c @@ -0,0 +1,155 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * Format and print trivial file transfer protocol packets. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.39 2008-04-11 16:47:38 gianluca Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#ifdef SEGSIZE +#undef SEGSIZE /* SINIX sucks */ +#endif + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "tftp.h" + +/* op code to string mapping */ +static struct tok op2str[] = { + { RRQ, "RRQ" }, /* read request */ + { WRQ, "WRQ" }, /* write request */ + { DATA, "DATA" }, /* data packet */ + { ACK, "ACK" }, /* acknowledgement */ + { TFTP_ERROR, "ERROR" }, /* error code */ + { OACK, "OACK" }, /* option acknowledgement */ + { 0, NULL } +}; + +/* error code to string mapping */ +static struct tok err2str[] = { + { EUNDEF, "EUNDEF" }, /* not defined */ + { ENOTFOUND, "ENOTFOUND" }, /* file not found */ + { EACCESS, "EACCESS" }, /* access violation */ + { ENOSPACE, "ENOSPACE" }, /* disk full or allocation exceeded */ + { EBADOP, "EBADOP" }, /* illegal TFTP operation */ + { EBADID, "EBADID" }, /* unknown transfer ID */ + { EEXISTS, "EEXISTS" }, /* file already exists */ + { ENOUSER, "ENOUSER" }, /* no such user */ + { 0, NULL } +}; + +/* + * Print trivial file transfer program requests + */ +void +tftp_print(register const u_char *bp, u_int length) +{ + register const struct tftphdr *tp; + register const char *cp; + register const u_char *p; + register int opcode, i; + static char tstr[] = " [|tftp]"; + + tp = (const struct tftphdr *)bp; + + /* Print length */ + printf(" %d", length); + + /* Print tftp request type */ + TCHECK(tp->th_opcode); + opcode = EXTRACT_16BITS(&tp->th_opcode); + cp = tok2str(op2str, "tftp-#%d", opcode); + printf(" %s", cp); + /* Bail if bogus opcode */ + if (*cp == 't') + return; + + switch (opcode) { + + case RRQ: + case WRQ: + case OACK: + p = (u_char *)tp->th_stuff; + putchar(' '); + /* Print filename or first option */ + if (opcode != OACK) + putchar('"'); + i = fn_print(p, snapend); + if (opcode != OACK) + putchar('"'); + + /* Print the mode (RRQ and WRQ only) and any options */ + while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) { + if (length <= (u_int)(p - (const u_char *)&tp->th_block)) + break; + p++; + if (*p != '\0') { + putchar(' '); + fn_print(p, snapend); + } + } + + if (i) + goto trunc; + break; + + case ACK: + case DATA: + TCHECK(tp->th_block); + printf(" block %d", EXTRACT_16BITS(&tp->th_block)); + break; + + case TFTP_ERROR: + /* Print error code string */ + TCHECK(tp->th_code); + printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"", + EXTRACT_16BITS(&tp->th_code))); + /* Print error message string */ + i = fn_print((const u_char *)tp->th_data, snapend); + putchar('"'); + if (i) + goto trunc; + break; + + default: + /* We shouldn't get here */ + printf("(unknown #%d)", opcode); + break; + } + return; +trunc: + fputs(tstr, stdout); + return; +} diff --git a/freebsd/contrib/tcpdump/print-timed.c b/freebsd/contrib/tcpdump/print-timed.c new file mode 100644 index 00000000..b9fabef7 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-timed.c @@ -0,0 +1,113 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2000 Ben Smithurst <ben@scientia.demon.co.uk> + * 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-timed.c,v 1.9 2003-11-16 09:36:40 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "timed.h" +#include "interface.h" +#include "extract.h" + +static const char *tsptype[TSPTYPENUMBER] = + { "ANY", "ADJTIME", "ACK", "MASTERREQ", "MASTERACK", "SETTIME", "MASTERUP", + "SLAVEUP", "ELECTION", "ACCEPT", "REFUSE", "CONFLICT", "RESOLVE", "QUIT", + "DATE", "DATEREQ", "DATEACK", "TRACEON", "TRACEOFF", "MSITE", "MSITEREQ", + "TEST", "SETDATE", "SETDATEREQ", "LOOP" }; + +void +timed_print(register const u_char *bp) +{ +#define endof(x) ((u_char *)&(x) + sizeof (x)) + struct tsp *tsp = (struct tsp *)bp; + long sec, usec; + const u_char *end; + + if (endof(tsp->tsp_type) > snapend) { + fputs("[|timed]", stdout); + return; + } + if (tsp->tsp_type < TSPTYPENUMBER) + printf("TSP_%s", tsptype[tsp->tsp_type]); + else + printf("(tsp_type %#x)", tsp->tsp_type); + + if (endof(tsp->tsp_vers) > snapend) { + fputs(" [|timed]", stdout); + return; + } + printf(" vers %d", tsp->tsp_vers); + + if (endof(tsp->tsp_seq) > snapend) { + fputs(" [|timed]", stdout); + return; + } + printf(" seq %d", tsp->tsp_seq); + + if (tsp->tsp_type == TSP_LOOP) { + if (endof(tsp->tsp_hopcnt) > snapend) { + fputs(" [|timed]", stdout); + return; + } + printf(" hopcnt %d", tsp->tsp_hopcnt); + } else if (tsp->tsp_type == TSP_SETTIME || + tsp->tsp_type == TSP_ADJTIME || + tsp->tsp_type == TSP_SETDATE || + tsp->tsp_type == TSP_SETDATEREQ) { + if (endof(tsp->tsp_time) > snapend) { + fputs(" [|timed]", stdout); + return; + } + sec = EXTRACT_32BITS(&tsp->tsp_time.tv_sec); + usec = EXTRACT_32BITS(&tsp->tsp_time.tv_usec); + if (usec < 0) + /* corrupt, skip the rest of the packet */ + return; + fputs(" time ", stdout); + if (sec < 0 && usec != 0) { + sec++; + if (sec == 0) + fputc('-', stdout); + usec = 1000000 - usec; + } + printf("%ld.%06ld", sec, usec); + } + + end = memchr(tsp->tsp_name, '\0', snapend - (u_char *)tsp->tsp_name); + if (end == NULL) + fputs(" [|timed]", stdout); + else { + fputs(" name ", stdout); + fwrite(tsp->tsp_name, end - (u_char *)tsp->tsp_name, 1, stdout); + } +} diff --git a/freebsd/contrib/tcpdump/print-tipc.c b/freebsd/contrib/tcpdump/print-tipc.c new file mode 100644 index 00000000..d0a20b58 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-tipc.c @@ -0,0 +1,394 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#include "netdissect.h" +#include "addrtoname.h" +#include "ether.h" +#include "ethertype.h" +#include "extract.h" /* must come after interface.h */ + +/* + * Transparent Inter-Process Communication (TIPC) protocol. + * + * http://tipc.sourceforge.net/doc/draft-spec-tipc-07.html + * http://tipc.sourceforge.net/doc/tipc_message_formats.html + */ + +#define TIPC_USER_LOW_IMPORTANCE 0 +#define TIPC_USER_MEDIUM_IMPORTANCE 1 +#define TIPC_USER_HIGH_IMPORTANCE 2 +#define TIPC_USER_CRITICAL_IMPORTANCE 3 +#define TIPC_USER_BCAST_PROTOCOL 5 +#define TIPC_USER_MSG_BUNDLER 6 +#define TIPC_USER_LINK_PROTOCOL 7 +#define TIPC_USER_CONN_MANAGER 8 +#define TIPC_USER_CHANGEOVER_PROTOCOL 10 +#define TIPC_USER_NAME_DISTRIBUTOR 11 +#define TIPC_USER_MSG_FRAGMENTER 12 +#define TIPC_USER_LINK_CONFIG 13 + +#define TIPC_CONN_MSG 0 +#define TIPC_DIRECT_MSG 1 +#define TIPC_NAMED_MSG 2 +#define TIPC_MCAST_MSG 3 + +#define TIPC_ZONE(addr) (((addr) >> 24) & 0xFF) +#define TIPC_CLUSTER(addr) (((addr) >> 12) & 0xFFF) +#define TIPC_NODE(addr) (((addr) >> 0) & 0xFFF) + +struct tipc_pkthdr { + u_int32_t w0; + u_int32_t w1; +}; + +#define TIPC_VER(w0) (((w0) >> 29) & 0x07) +#define TIPC_USER(w0) (((w0) >> 25) & 0x0F) +#define TIPC_HSIZE(w0) (((w0) >> 21) & 0x0F) +#define TIPC_MSIZE(w0) (((w0) >> 0) & 0xFFFF) +#define TIPC_MTYPE(w1) (((w1) >> 29) & 0x07) +#define TIPC_BROADCAST_ACK(w1) (((w1) >> 0) & 0xFFFF) +#define TIPC_LINK_ACK(w2) (((w2) >> 16) & 0xFFFF) +#define TIPC_LINK_SEQ(w2) (((w2) >> 0) & 0xFFFF) + +static const struct tok tipcuser_values[] = { + { TIPC_USER_LOW_IMPORTANCE, "Low Importance Data payload" }, + { TIPC_USER_MEDIUM_IMPORTANCE, "Medium Importance Data payload" }, + { TIPC_USER_HIGH_IMPORTANCE, "High Importance Data payload" }, + { TIPC_USER_CRITICAL_IMPORTANCE, "Critical Importance Data payload" }, + { TIPC_USER_BCAST_PROTOCOL, "Broadcast Link Protocol internal" }, + { TIPC_USER_MSG_BUNDLER, "Message Bundler Protocol internal" }, + { TIPC_USER_LINK_PROTOCOL, "Link State Protocol internal" }, + { TIPC_USER_CONN_MANAGER, "Connection Manager internal" }, + { TIPC_USER_CHANGEOVER_PROTOCOL, "Link Changeover Protocol internal" }, + { TIPC_USER_NAME_DISTRIBUTOR, "Name Table Update Protocol internal" }, + { TIPC_USER_MSG_FRAGMENTER, "Message Fragmentation Protocol internal" }, + { TIPC_USER_LINK_CONFIG, "Neighbor Detection Protocol internal" }, + { 0, NULL } +}; + +static const struct tok tipcmtype_values[] = { + { TIPC_CONN_MSG, "CONN_MSG" }, + { TIPC_DIRECT_MSG, "MCAST_MSG" }, + { TIPC_NAMED_MSG, "NAMED_MSG" }, + { TIPC_MCAST_MSG, "DIRECT_MSG" }, + { 0, NULL } +}; + +static const struct tok tipc_linkconf_mtype_values[] = { + { 0, "Link request" }, + { 1, "Link response" }, + { 0, NULL } +}; + +struct payload_tipc_pkthdr { + u_int32_t w0; + u_int32_t w1; + u_int32_t w2; + u_int32_t prev_node; + u_int32_t orig_port; + u_int32_t dest_port; + u_int32_t orig_node; + u_int32_t dest_node; + u_int32_t name_type; + u_int32_t w9; + u_int32_t wA; +}; + +struct internal_tipc_pkthdr { + u_int32_t w0; + u_int32_t w1; + u_int32_t w2; + u_int32_t prev_node; + u_int32_t w4; + u_int32_t w5; + u_int32_t orig_node; + u_int32_t dest_node; + u_int32_t trans_seq; + u_int32_t w9; +}; + +#define TIPC_SEQ_GAP(w1) (((w1) >> 16) & 0x1FFF) +#define TIPC_BC_GAP_AFTER(w2) (((w2) >> 16) & 0xFFFF) +#define TIPC_BC_GAP_TO(w2) (((w2) >> 0) & 0xFFFF) +#define TIPC_LAST_SENT_FRAG(w4) (((w4) >> 16) & 0xFFFF) +#define TIPC_NEXT_SENT_FRAG(w4) (((w4) >> 0) & 0xFFFF) +#define TIPC_SESS_NO(w5) (((w5) >> 16) & 0xFFFF) +#define TIPC_MSG_CNT(w9) (((w9) >> 16) & 0xFFFF) +#define TIPC_LINK_TOL(w9) (((w9) >> 0) & 0xFFFF) + +struct link_conf_tipc_pkthdr { + u_int32_t w0; + u_int32_t w1; + u_int32_t dest_domain; + u_int32_t prev_node; + u_int32_t ntwrk_id; + u_int32_t w5; + u_int8_t media_address[16]; +}; + +#define TIPC_NODE_SIG(w1) (((w1) >> 0) & 0xFFFF) +#define TIPC_MEDIA_ID(w5) (((w5) >> 0) & 0xFF) + +static void +print_payload(netdissect_options *ndo, const struct payload_tipc_pkthdr *ap) +{ + u_int32_t w0, w1, w2; + u_int user; + u_int hsize; + u_int msize; + u_int mtype; + u_int broadcast_ack; + u_int link_ack; + u_int link_seq; + u_int prev_node; + u_int orig_port; + u_int dest_port; + u_int orig_node; + u_int dest_node; + + ND_TCHECK(ap->dest_port); + w0 = EXTRACT_32BITS(&ap->w0); + user = TIPC_USER(w0); + hsize = TIPC_HSIZE(w0); + msize = TIPC_MSIZE(w0); + w1 = EXTRACT_32BITS(&ap->w1); + mtype = TIPC_MTYPE(w1); + prev_node = EXTRACT_32BITS(&ap->prev_node); + orig_port = EXTRACT_32BITS(&ap->orig_port); + dest_port = EXTRACT_32BITS(&ap->dest_port); + if (hsize <= 6) { + ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", + TIPC_VER(w0), + TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), + orig_port, dest_port, + hsize*4, msize, + tok2str(tipcuser_values, "unknown", user), + tok2str(tipcmtype_values, "Unknown", mtype))); + } else { + ND_TCHECK(ap->dest_node); + orig_node = EXTRACT_32BITS(&ap->orig_node); + dest_node = EXTRACT_32BITS(&ap->dest_node); + ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u.%u.%u:%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", + TIPC_VER(w0), + TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node), + orig_port, + TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node), + dest_port, + hsize*4, msize, + tok2str(tipcuser_values, "unknown", user), + tok2str(tipcmtype_values, "Unknown", mtype))); + + if (ndo->ndo_vflag) { + broadcast_ack = TIPC_BROADCAST_ACK(w1); + w2 = EXTRACT_32BITS(&ap->w2); + link_ack = TIPC_LINK_ACK(w2); + link_seq = TIPC_LINK_SEQ(w2); + ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Broadcast Ack %u, Link Ack %u, Link Sequence %u", + TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), + broadcast_ack, link_ack, link_seq)); + } + } + return; + +trunc: + ND_PRINT((ndo, "[|TIPC]")); +} + +static void +print_internal(netdissect_options *ndo, const struct internal_tipc_pkthdr *ap) +{ + u_int32_t w0, w1, w2, w4, w5, w9; + u_int user; + u_int hsize; + u_int msize; + u_int mtype; + u_int seq_gap; + u_int broadcast_ack; + u_int bc_gap_after; + u_int bc_gap_to; + u_int prev_node; + u_int last_sent_frag; + u_int next_sent_frag; + u_int sess_no; + u_int orig_node; + u_int dest_node; + u_int trans_seq; + u_int msg_cnt; + u_int link_tol; + + ND_TCHECK(ap->dest_node); + w0 = EXTRACT_32BITS(&ap->w0); + user = TIPC_USER(w0); + hsize = TIPC_HSIZE(w0); + msize = TIPC_MSIZE(w0); + w1 = EXTRACT_32BITS(&ap->w1); + mtype = TIPC_MTYPE(w1); + orig_node = EXTRACT_32BITS(&ap->orig_node); + dest_node = EXTRACT_32BITS(&ap->dest_node); + ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s (0x%08x)", + TIPC_VER(w0), + TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node), + TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node), + hsize*4, msize, + tok2str(tipcuser_values, "unknown", user), + tok2str(tipcmtype_values, "Unknown", mtype), w1)); + + if (ndo->ndo_vflag) { + ND_TCHECK(*ap); + seq_gap = TIPC_SEQ_GAP(w1); + broadcast_ack = TIPC_BROADCAST_ACK(w1); + w2 = EXTRACT_32BITS(&ap->w2); + bc_gap_after = TIPC_BC_GAP_AFTER(w2); + bc_gap_to = TIPC_BC_GAP_TO(w2); + prev_node = EXTRACT_32BITS(&ap->prev_node); + w4 = EXTRACT_32BITS(&ap->w4); + last_sent_frag = TIPC_LAST_SENT_FRAG(w4); + next_sent_frag = TIPC_NEXT_SENT_FRAG(w4); + w5 = EXTRACT_32BITS(&ap->w5); + sess_no = TIPC_SESS_NO(w5); + trans_seq = EXTRACT_32BITS(&ap->trans_seq); + w9 = EXTRACT_32BITS(&ap->w9); + msg_cnt = TIPC_MSG_CNT(w9); + link_tol = TIPC_LINK_TOL(w9); + ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Session No. %u, Broadcast Ack %u, Sequence Gap %u, Broadcast Gap After %u, Broadcast Gap To %u, Last Sent Packet No. %u, Next sent Packet No. %u, Transport Sequence %u, msg_count %u, Link Tolerance %u", + TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), + sess_no, broadcast_ack, seq_gap, bc_gap_after, bc_gap_to, + last_sent_frag, next_sent_frag, trans_seq, msg_cnt, + link_tol)); + } + return; + +trunc: + ND_PRINT((ndo, "[|TIPC]")); +} + +static void +print_link_conf(netdissect_options *ndo, const struct link_conf_tipc_pkthdr *ap) +{ + u_int32_t w0, w1, w5; + u_int user; + u_int hsize; + u_int msize; + u_int mtype; + u_int node_sig; + u_int prev_node; + u_int dest_domain; + u_int ntwrk_id; + u_int media_id; + + ND_TCHECK(ap->prev_node); + w0 = EXTRACT_32BITS(&ap->w0); + user = TIPC_USER(w0); + hsize = TIPC_HSIZE(w0); + msize = TIPC_MSIZE(w0); + w1 = EXTRACT_32BITS(&ap->w1); + mtype = TIPC_MTYPE(w1); + prev_node = EXTRACT_32BITS(&ap->prev_node); + dest_domain = EXTRACT_32BITS(&ap->dest_domain); + prev_node = EXTRACT_32BITS(&ap->prev_node); + + ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s", + TIPC_VER(w0), + TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node), + TIPC_ZONE(dest_domain), TIPC_CLUSTER(dest_domain), TIPC_NODE(dest_domain), + hsize*4, msize, + tok2str(tipcuser_values, "unknown", user), + tok2str(tipc_linkconf_mtype_values, "Unknown", mtype))); + if (ndo->ndo_vflag) { + ND_TCHECK(ap->w5); + node_sig = TIPC_NODE_SIG(w1); + ntwrk_id = EXTRACT_32BITS(&ap->ntwrk_id); + w5 = EXTRACT_32BITS(&ap->w5); + media_id = TIPC_MEDIA_ID(w5); + ND_PRINT((ndo, "\n\tNodeSignature %u, network_id %u, media_id %u", + node_sig, ntwrk_id, media_id)); + } + return; + +trunc: + ND_PRINT((ndo, "[|TIPC]")); +} + +void +tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_, + u_int caplen _U_) +{ + const struct tipc_pkthdr *ap; + u_int32_t w0; + u_int user; + + ap = (struct tipc_pkthdr *)bp; + ND_TCHECK(ap->w0); + w0 = EXTRACT_32BITS(&ap->w0); + user = TIPC_USER(w0); + + switch (user) + { + case TIPC_USER_LOW_IMPORTANCE: + case TIPC_USER_MEDIUM_IMPORTANCE: + case TIPC_USER_HIGH_IMPORTANCE: + case TIPC_USER_CRITICAL_IMPORTANCE: + case TIPC_USER_NAME_DISTRIBUTOR: + case TIPC_USER_CONN_MANAGER: + print_payload(ndo, (struct payload_tipc_pkthdr *)bp); + break; + + case TIPC_USER_LINK_CONFIG: + print_link_conf(ndo, (struct link_conf_tipc_pkthdr *)bp); + break; + + case TIPC_USER_BCAST_PROTOCOL: + case TIPC_USER_MSG_BUNDLER: + case TIPC_USER_LINK_PROTOCOL: + case TIPC_USER_CHANGEOVER_PROTOCOL: + case TIPC_USER_MSG_FRAGMENTER: + print_internal(ndo, (struct internal_tipc_pkthdr *)bp); + break; + + } + return; + +trunc: + ND_PRINT((ndo, "[|TIPC]")); +} + +/* + * Local Variables: + * c-style: bsd + * End: + */ + diff --git a/freebsd/contrib/tcpdump/print-token.c b/freebsd/contrib/tcpdump/print-token.c new file mode 100644 index 00000000..5d1a44c3 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-token.c @@ -0,0 +1,207 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 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. + * + * Hacked version of print-ether.c Larry Lile <lile@stdio.com> + * + * Further tweaked to more closely resemble print-fddi.c + * Guy Harris <guy@alum.mit.edu> + * + * $FreeBSD$ + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.27 2005-11-13 12:12:43 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" + +#include "ether.h" +#include "token.h" + +/* Extract src, dst addresses */ +static inline void +extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst) +{ + memcpy(fdst, (const char *)trp->token_dhost, 6); + memcpy(fsrc, (const char *)trp->token_shost, 6); +} + +/* + * Print the TR MAC header + */ +static inline void +token_hdr_print(register const struct token_header *trp, register u_int length, + register const u_char *fsrc, register const u_char *fdst) +{ + const char *srcname, *dstname; + + srcname = etheraddr_string(fsrc); + dstname = etheraddr_string(fdst); + + if (vflag) + (void) printf("%02x %02x %s %s %d: ", + trp->token_ac, + trp->token_fc, + srcname, dstname, + length); + else + printf("%s %s %d: ", srcname, dstname, length); +} + +static const char *broadcast_indicator[] = { + "Non-Broadcast", "Non-Broadcast", + "Non-Broadcast", "Non-Broadcast", + "All-routes", "All-routes", + "Single-route", "Single-route" +}; + +static const char *direction[] = { + "Forward", "Backward" +}; + +static const char *largest_frame[] = { + "516", + "1500", + "2052", + "4472", + "8144", + "11407", + "17800", + "??" +}; + +u_int +token_print(const u_char *p, u_int length, u_int caplen) +{ + const struct token_header *trp; + u_short extracted_ethertype; + struct ether_header ehdr; + u_int route_len = 0, hdr_len = TOKEN_HDRLEN; + int seg; + + trp = (const struct token_header *)p; + + if (caplen < TOKEN_HDRLEN) { + printf("[|token-ring]"); + return hdr_len; + } + + /* + * Get the TR addresses into a canonical form + */ + extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr)); + + /* Adjust for source routing information in the MAC header */ + if (IS_SOURCE_ROUTED(trp)) { + /* Clear source-routed bit */ + *ESRC(&ehdr) &= 0x7f; + + if (eflag) + token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); + + if (caplen < TOKEN_HDRLEN + 2) { + printf("[|token-ring]"); + return hdr_len; + } + route_len = RIF_LENGTH(trp); + hdr_len += route_len; + if (caplen < hdr_len) { + printf("[|token-ring]"); + return hdr_len; + } + if (vflag) { + printf("%s ", broadcast_indicator[BROADCAST(trp)]); + printf("%s", direction[DIRECTION(trp)]); + + for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) + printf(" [%d:%d]", RING_NUMBER(trp, seg), + BRIDGE_NUMBER(trp, seg)); + } else { + printf("rt = %x", EXTRACT_16BITS(&trp->token_rcf)); + + for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) + printf(":%x", EXTRACT_16BITS(&trp->token_rseg[seg])); + } + printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); + } else { + if (eflag) + token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); + } + + /* Skip over token ring MAC header and routing information */ + length -= hdr_len; + p += hdr_len; + caplen -= hdr_len; + + /* Frame Control field determines interpretation of packet */ + if (FRAME_TYPE(trp) == TOKEN_FC_LLC) { + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr), + &extracted_ethertype) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + token_hdr_print(trp, + length + TOKEN_HDRLEN + route_len, + ESRC(&ehdr), EDST(&ehdr)); + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + } + } else { + /* Some kinds of TR packet we cannot handle intelligently */ + /* XXX - dissect MAC packets if frame type is 0 */ + if (!eflag) + token_hdr_print(trp, length + TOKEN_HDRLEN + route_len, + ESRC(&ehdr), EDST(&ehdr)); + if (!suppress_default_print) + default_print(p, caplen); + } + return (hdr_len); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the TR 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 +token_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + return (token_print(p, h->len, h->caplen)); +} diff --git a/freebsd/contrib/tcpdump/print-udld.c b/freebsd/contrib/tcpdump/print-udld.c new file mode 100644 index 00000000..82135c9d --- /dev/null +++ b/freebsd/contrib/tcpdump/print-udld.c @@ -0,0 +1,175 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <carles.kishimoto@gmail.com> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#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 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 struct tok udld_code_values[] = { + { 0x00, "Reserved"}, + { 0x01, "Probe message"}, + { 0x02, "Echo message"}, + { 0x03, "Flush message"}, + { 0, NULL} +}; + +static 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: + */ diff --git a/freebsd/contrib/tcpdump/print-udp.c b/freebsd/contrib/tcpdump/print-udp.c new file mode 100644 index 00000000..fa419fb8 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-udp.c @@ -0,0 +1,693 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * $FreeBSD$ + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.142 2007-08-08 17:20:58 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#ifdef SEGSIZE +#undef SEGSIZE +#endif + +#include <stdio.h> +#include <string.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "appletalk.h" + +#include "udp.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "ipproto.h" +#include "rpc_auth.h" +#include "rpc_msg.h" + +#include "nameser.h" +#include "nfs.h" +#include "bootp.h" + +struct rtcphdr { + u_int16_t rh_flags; /* T:2 P:1 CNT:5 PT:8 */ + u_int16_t rh_len; /* length of message (in words) */ + u_int32_t rh_ssrc; /* synchronization src id */ +}; + +typedef struct { + u_int32_t upper; /* more significant 32 bits */ + u_int32_t lower; /* less significant 32 bits */ +} ntp64; + +/* + * Sender report. + */ +struct rtcp_sr { + ntp64 sr_ntp; /* 64-bit ntp timestamp */ + u_int32_t sr_ts; /* reference media timestamp */ + u_int32_t sr_np; /* no. packets sent */ + u_int32_t sr_nb; /* no. bytes sent */ +}; + +/* + * Receiver report. + * Time stamps are middle 32-bits of ntp timestamp. + */ +struct rtcp_rr { + u_int32_t rr_srcid; /* sender being reported */ + u_int32_t rr_nl; /* no. packets lost */ + u_int32_t rr_ls; /* extended last seq number received */ + u_int32_t rr_dv; /* jitter (delay variance) */ + u_int32_t rr_lsr; /* orig. ts from last rr from this src */ + u_int32_t rr_dlsr; /* time from recpt of last rr to xmit time */ +}; + +/*XXX*/ +#define RTCP_PT_SR 200 +#define RTCP_PT_RR 201 +#define RTCP_PT_SDES 202 +#define RTCP_SDES_CNAME 1 +#define RTCP_SDES_NAME 2 +#define RTCP_SDES_EMAIL 3 +#define RTCP_SDES_PHONE 4 +#define RTCP_SDES_LOC 5 +#define RTCP_SDES_TOOL 6 +#define RTCP_SDES_NOTE 7 +#define RTCP_SDES_PRIV 8 +#define RTCP_PT_BYE 203 +#define RTCP_PT_APP 204 + +static void +vat_print(const void *hdr, register const struct udphdr *up) +{ + /* vat/vt audio */ + u_int ts = *(u_int16_t *)hdr; + if ((ts & 0xf060) != 0) { + /* probably vt */ + (void)printf("udp/vt %u %d / %d", + (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up)), + ts & 0x3ff, ts >> 10); + } else { + /* probably vat */ + u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]); + u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]); + printf("udp/vat %u c%d %u%s", + (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8), + i0 & 0xffff, + i1, i0 & 0x800000? "*" : ""); + /* audio format */ + if (i0 & 0x1f0000) + printf(" f%d", (i0 >> 16) & 0x1f); + if (i0 & 0x3f000000) + printf(" s%d", (i0 >> 24) & 0x3f); + } +} + +static void +rtp_print(const void *hdr, u_int len, register const struct udphdr *up) +{ + /* rtp v1 or v2 */ + u_int *ip = (u_int *)hdr; + u_int hasopt, hasext, contype, hasmarker; + u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]); + u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]); + u_int dlen = EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8; + const char * ptype; + + ip += 2; + len >>= 2; + len -= 2; + hasopt = 0; + hasext = 0; + if ((i0 >> 30) == 1) { + /* rtp v1 */ + hasopt = i0 & 0x800000; + contype = (i0 >> 16) & 0x3f; + hasmarker = i0 & 0x400000; + ptype = "rtpv1"; + } else { + /* rtp v2 */ + hasext = i0 & 0x10000000; + contype = (i0 >> 16) & 0x7f; + hasmarker = i0 & 0x800000; + dlen -= 4; + ptype = "rtp"; + ip += 1; + len -= 1; + } + printf("udp/%s %d c%d %s%s %d %u", + ptype, + dlen, + contype, + (hasopt || hasext)? "+" : "", + hasmarker? "*" : "", + i0 & 0xffff, + i1); + if (vflag) { + printf(" %u", EXTRACT_32BITS(&((u_int *)hdr)[2])); + if (hasopt) { + u_int i2, optlen; + do { + i2 = ip[0]; + optlen = (i2 >> 16) & 0xff; + if (optlen == 0 || optlen > len) { + printf(" !opt"); + return; + } + ip += optlen; + len -= optlen; + } while ((int)i2 >= 0); + } + if (hasext) { + u_int i2, extlen; + i2 = ip[0]; + extlen = (i2 & 0xffff) + 1; + if (extlen > len) { + printf(" !ext"); + return; + } + ip += extlen; + } + if (contype == 0x1f) /*XXX H.261 */ + printf(" 0x%04x", ip[0] >> 16); + } +} + +static const u_char * +rtcp_print(const u_char *hdr, const u_char *ep) +{ + /* rtp v2 control (rtcp) */ + struct rtcp_rr *rr = 0; + struct rtcp_sr *sr; + struct rtcphdr *rh = (struct rtcphdr *)hdr; + u_int len; + u_int16_t flags; + int cnt; + double ts, dts; + if ((u_char *)(rh + 1) > ep) { + printf(" [|rtcp]"); + return (ep); + } + len = (EXTRACT_16BITS(&rh->rh_len) + 1) * 4; + flags = EXTRACT_16BITS(&rh->rh_flags); + cnt = (flags >> 8) & 0x1f; + switch (flags & 0xff) { + case RTCP_PT_SR: + sr = (struct rtcp_sr *)(rh + 1); + printf(" sr"); + if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh)) + printf(" [%d]", len); + if (vflag) + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); + if ((u_char *)(sr + 1) > ep) { + printf(" [|rtcp]"); + return (ep); + } + ts = (double)(EXTRACT_32BITS(&sr->sr_ntp.upper)) + + ((double)(EXTRACT_32BITS(&sr->sr_ntp.lower)) / + 4294967296.0); + printf(" @%.2f %u %up %ub", ts, EXTRACT_32BITS(&sr->sr_ts), + EXTRACT_32BITS(&sr->sr_np), EXTRACT_32BITS(&sr->sr_nb)); + rr = (struct rtcp_rr *)(sr + 1); + break; + case RTCP_PT_RR: + printf(" rr"); + if (len != cnt * sizeof(*rr) + sizeof(*rh)) + printf(" [%d]", len); + rr = (struct rtcp_rr *)(rh + 1); + if (vflag) + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); + break; + case RTCP_PT_SDES: + printf(" sdes %d", len); + if (vflag) + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); + cnt = 0; + break; + case RTCP_PT_BYE: + printf(" bye %d", len); + if (vflag) + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); + cnt = 0; + break; + default: + printf(" type-0x%x %d", flags & 0xff, len); + cnt = 0; + break; + } + if (cnt > 1) + printf(" c%d", cnt); + while (--cnt >= 0) { + if ((u_char *)(rr + 1) > ep) { + printf(" [|rtcp]"); + return (ep); + } + if (vflag) + printf(" %u", EXTRACT_32BITS(&rr->rr_srcid)); + ts = (double)(EXTRACT_32BITS(&rr->rr_lsr)) / 65536.; + dts = (double)(EXTRACT_32BITS(&rr->rr_dlsr)) / 65536.; + printf(" %ul %us %uj @%.2f+%.2f", + EXTRACT_32BITS(&rr->rr_nl) & 0x00ffffff, + EXTRACT_32BITS(&rr->rr_ls), + EXTRACT_32BITS(&rr->rr_dv), ts, dts); + } + return (hdr + len); +} + +static int udp_cksum(register const struct ip *ip, + register const struct udphdr *up, + register u_int len) +{ + return (nextproto4_cksum(ip, (const u_int8_t *)(void *)up, len, + IPPROTO_UDP)); +} + +#ifdef INET6 +static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, + u_int len) +{ + return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)up, len, + IPPROTO_UDP)); +} +#endif + +static void +udpipaddr_print(const struct ip *ip, int sport, int dport) +{ +#ifdef INET6 + const struct ip6_hdr *ip6; + + if (IP_V(ip) == 6) + ip6 = (const struct ip6_hdr *)ip; + else + ip6 = NULL; + + if (ip6) { + if (ip6->ip6_nxt == IPPROTO_UDP) { + if (sport == -1) { + (void)printf("%s > %s: ", + ip6addr_string(&ip6->ip6_src), + ip6addr_string(&ip6->ip6_dst)); + } else { + (void)printf("%s.%s > %s.%s: ", + ip6addr_string(&ip6->ip6_src), + udpport_string(sport), + ip6addr_string(&ip6->ip6_dst), + udpport_string(dport)); + } + } else { + if (sport != -1) { + (void)printf("%s > %s: ", + udpport_string(sport), + udpport_string(dport)); + } + } + } else +#endif /*INET6*/ + { + if (ip->ip_p == IPPROTO_UDP) { + if (sport == -1) { + (void)printf("%s > %s: ", + ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst)); + } else { + (void)printf("%s.%s > %s.%s: ", + ipaddr_string(&ip->ip_src), + udpport_string(sport), + ipaddr_string(&ip->ip_dst), + udpport_string(dport)); + } + } else { + if (sport != -1) { + (void)printf("%s > %s: ", + udpport_string(sport), + udpport_string(dport)); + } + } + } +} + +void +udp_print(register const u_char *bp, u_int length, + register const u_char *bp2, int fragmented) +{ + register const struct udphdr *up; + register const struct ip *ip; + register const u_char *cp; + register const u_char *ep = bp + length; + u_int16_t sport, dport, ulen; +#ifdef INET6 + register const struct ip6_hdr *ip6; +#endif + + if (ep > snapend) + ep = snapend; + up = (struct udphdr *)bp; + ip = (struct ip *)bp2; +#ifdef INET6 + if (IP_V(ip) == 6) + ip6 = (struct ip6_hdr *)bp2; + else + ip6 = NULL; +#endif /*INET6*/ + cp = (u_char *)(up + 1); + if (!TTEST(up->uh_dport)) { + udpipaddr_print(ip, -1, -1); + (void)printf("[|udp]"); + return; + } + + sport = EXTRACT_16BITS(&up->uh_sport); + dport = EXTRACT_16BITS(&up->uh_dport); + + if (length < sizeof(struct udphdr)) { + udpipaddr_print(ip, sport, dport); + (void)printf("truncated-udp %d", length); + return; + } + length -= sizeof(struct udphdr); + + if (cp > snapend) { + udpipaddr_print(ip, sport, dport); + (void)printf("[|udp]"); + return; + } + + ulen = EXTRACT_16BITS(&up->uh_ulen); + if (ulen < 8) { + udpipaddr_print(ip, sport, dport); + (void)printf("truncated-udplength %d", ulen); + return; + } + if (packettype) { + register struct sunrpc_msg *rp; + enum sunrpc_msg_type direction; + + switch (packettype) { + + case PT_VAT: + udpipaddr_print(ip, sport, dport); + vat_print((void *)(up + 1), up); + break; + + case PT_WB: + udpipaddr_print(ip, sport, dport); + wb_print((void *)(up + 1), length); + break; + + case PT_RPC: + rp = (struct sunrpc_msg *)(up + 1); + direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); +#ifndef __rtems__ + if (direction == SUNRPC_CALL) + sunrpcrequest_print((u_char *)rp, length, + (u_char *)ip); + else +#endif + nfsreply_print((u_char *)rp, length, + (u_char *)ip); /*XXX*/ + break; + + case PT_RTP: + udpipaddr_print(ip, sport, dport); + rtp_print((void *)(up + 1), length, up); + break; + + case PT_RTCP: + udpipaddr_print(ip, sport, dport); + while (cp < ep) + cp = rtcp_print(cp, ep); + break; + + case PT_SNMP: + udpipaddr_print(ip, sport, dport); + snmp_print((const u_char *)(up + 1), length); + break; + + case PT_CNFP: + udpipaddr_print(ip, sport, dport); + cnfp_print(cp, (const u_char *)ip); + break; + + case PT_TFTP: + udpipaddr_print(ip, sport, dport); + tftp_print(cp, length); + break; + + case PT_AODV: + udpipaddr_print(ip, sport, dport); + aodv_print((const u_char *)(up + 1), length, +#ifdef INET6 + ip6 != NULL); +#else + 0); +#endif + break; + + case PT_RADIUS: + udpipaddr_print(ip, sport, dport); + radius_print(cp, length); + break; + + case PT_VXLAN: + udpipaddr_print(ip, sport, dport); + vxlan_print((const u_char *)(up + 1), length); + break; + } + return; + } + + if (!qflag) { + register struct sunrpc_msg *rp; + enum sunrpc_msg_type direction; + + rp = (struct sunrpc_msg *)(up + 1); + if (TTEST(rp->rm_direction)) { + direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); + if (dport == NFS_PORT && direction == SUNRPC_CALL) { + nfsreq_print((u_char *)rp, length, + (u_char *)ip); + return; + } + if (sport == NFS_PORT && direction == SUNRPC_REPLY) { + nfsreply_print((u_char *)rp, length, + (u_char *)ip); + return; + } +#ifdef notdef + if (dport == SUNRPC_PORT && direction == SUNRPC_CALL) { + sunrpcrequest_print((u_char *)rp, length, (u_char *)ip); + return; + } +#endif + } + if (TTEST(((struct LAP *)cp)->type) && + ((struct LAP *)cp)->type == lapDDP && + (atalk_port(sport) || atalk_port(dport))) { + if (vflag) + fputs("kip ", stdout); + llap_print(cp, length); + return; + } + } + udpipaddr_print(ip, sport, dport); + + if (vflag && !Kflag && !fragmented) { + /* Check the checksum, if possible. */ + u_int16_t sum, udp_sum; + + /* + * XXX - do this even if vflag == 1? + * TCP does, and we do so for UDP-over-IPv6. + */ + if (IP_V(ip) == 4 && (vflag > 1)) { + udp_sum = EXTRACT_16BITS(&up->uh_sum); + if (udp_sum == 0) { + (void)printf("[no cksum] "); + } else if (TTEST2(cp[0], length)) { + sum = udp_cksum(ip, up, length + sizeof(struct udphdr)); + + if (sum != 0) { + (void)printf("[bad udp cksum 0x%04x -> 0x%04x!] ", + udp_sum, + in_cksum_shouldbe(udp_sum, sum)); + } else + (void)printf("[udp sum ok] "); + } + } +#ifdef INET6 + else if (IP_V(ip) == 6 && ip6->ip6_plen) { + /* for IPv6, UDP checksum is mandatory */ + if (TTEST2(cp[0], length)) { + sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr)); + udp_sum = EXTRACT_16BITS(&up->uh_sum); + + if (sum != 0) { + (void)printf("[bad udp cksum 0x%04x -> 0x%04x!] ", + udp_sum, + in_cksum_shouldbe(udp_sum, sum)); + } else + (void)printf("[udp sum ok] "); + } + } +#endif + } + + if (!qflag) { +#define ISPORT(p) (dport == (p) || sport == (p)) + if (ISPORT(NAMESERVER_PORT)) + ns_print((const u_char *)(up + 1), length, 0); + else if (ISPORT(MULTICASTDNS_PORT)) + ns_print((const u_char *)(up + 1), length, 1); + else if (ISPORT(TIMED_PORT)) + timed_print((const u_char *)(up + 1)); + else if (ISPORT(TFTP_PORT)) + tftp_print((const u_char *)(up + 1), length); + else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS)) + bootp_print((const u_char *)(up + 1), length); + else if (ISPORT(RIP_PORT)) + rip_print((const u_char *)(up + 1), length); + else if (ISPORT(AODV_PORT)) + aodv_print((const u_char *)(up + 1), length, +#ifdef INET6 + ip6 != NULL); +#else + 0); +#endif + else if (ISPORT(ISAKMP_PORT)) + isakmp_print(gndo, (const u_char *)(up + 1), length, bp2); + else if (ISPORT(ISAKMP_PORT_NATT)) + isakmp_rfc3948_print(gndo, (const u_char *)(up + 1), length, bp2); +#if 1 /*???*/ + else if (ISPORT(ISAKMP_PORT_USER1) || ISPORT(ISAKMP_PORT_USER2)) + isakmp_print(gndo, (const u_char *)(up + 1), length, bp2); +#endif + else if (ISPORT(SNMP_PORT) || ISPORT(SNMPTRAP_PORT)) + snmp_print((const u_char *)(up + 1), length); + else if (ISPORT(NTP_PORT)) + ntp_print((const u_char *)(up + 1), length); + else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT)) + krb_print((const void *)(up + 1)); + else if (ISPORT(L2TP_PORT)) + l2tp_print((const u_char *)(up + 1), length); +#ifdef TCPDUMP_DO_SMB + else if (ISPORT(NETBIOS_NS_PORT)) + nbt_udp137_print((const u_char *)(up + 1), length); + else if (ISPORT(NETBIOS_DGRAM_PORT)) + nbt_udp138_print((const u_char *)(up + 1), length); +#endif + else if (dport == 3456) + vat_print((const void *)(up + 1), up); + else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT)) + zephyr_print((const void *)(up + 1), length); + /* + * Since there are 10 possible ports to check, I think + * a <> test would be more efficient + */ + else if ((sport >= RX_PORT_LOW && sport <= RX_PORT_HIGH) || + (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH)) + rx_print((const void *)(up + 1), length, sport, dport, + (u_char *) ip); +#ifdef INET6 + else if (ISPORT(RIPNG_PORT)) + ripng_print((const u_char *)(up + 1), length); + else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT)) + dhcp6_print((const u_char *)(up + 1), length); + else if (ISPORT(BABEL_PORT) || ISPORT(BABEL_PORT_OLD)) + babel_print((const u_char *)(up + 1), length); +#endif /*INET6*/ + /* + * Kludge in test for whiteboard packets. + */ + else if (dport == 4567) + wb_print((const void *)(up + 1), length); + else if (ISPORT(CISCO_AUTORP_PORT)) + cisco_autorp_print((const void *)(up + 1), length); + else if (ISPORT(RADIUS_PORT) || + ISPORT(RADIUS_NEW_PORT) || + ISPORT(RADIUS_ACCOUNTING_PORT) || + ISPORT(RADIUS_NEW_ACCOUNTING_PORT) ) + radius_print((const u_char *)(up+1), length); + else if (dport == HSRP_PORT) + hsrp_print((const u_char *)(up + 1), length); + else if (ISPORT(LWRES_PORT)) + lwres_print((const u_char *)(up + 1), length); + else if (ISPORT(LDP_PORT)) + ldp_print((const u_char *)(up + 1), length); + else if (ISPORT(OLSR_PORT)) + olsr_print((const u_char *)(up + 1), length, +#if INET6 + (IP_V(ip) == 6) ? 1 : 0); +#else + 0); +#endif + else if (ISPORT(MPLS_LSP_PING_PORT)) + lspping_print((const u_char *)(up + 1), length); + else if (dport == BFD_CONTROL_PORT || + dport == BFD_ECHO_PORT ) + bfd_print((const u_char *)(up+1), length, dport); + else if (ISPORT(LMP_PORT)) + lmp_print((const u_char *)(up + 1), length); + else if (ISPORT(VQP_PORT)) + vqp_print((const u_char *)(up + 1), length); + else if (ISPORT(SFLOW_PORT)) + sflow_print((const u_char *)(up + 1), length); + else if (dport == LWAPP_CONTROL_PORT) + lwapp_control_print((const u_char *)(up + 1), length, 1); + else if (sport == LWAPP_CONTROL_PORT) + lwapp_control_print((const u_char *)(up + 1), length, 0); + else if (ISPORT(LWAPP_DATA_PORT)) + lwapp_data_print((const u_char *)(up + 1), length); + else if (ISPORT(SIP_PORT)) + sip_print((const u_char *)(up + 1), length); + else if (ISPORT(SYSLOG_PORT)) + syslog_print((const u_char *)(up + 1), length); + else if (ISPORT(OTV_PORT)) + otv_print((const u_char *)(up + 1), length); + else + (void)printf("UDP, length %u", + (u_int32_t)(ulen - sizeof(*up))); +#undef ISPORT + } else + (void)printf("UDP, length %u", (u_int32_t)(ulen - sizeof(*up))); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/freebsd/contrib/tcpdump/print-usb.c b/freebsd/contrib/tcpdump/print-usb.c new file mode 100644 index 00000000..393b66b5 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-usb.c @@ -0,0 +1,176 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright 2009 Bert Vermeulen <bert@biot.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 Paolo Abeni.'' + * The name of author 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. + * + * Support for USB packets + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> +#include <string.h> + +#include "interface.h" + + +#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) +#include <pcap/usb.h> + +/* returns direction: 1=inbound 2=outbound -1=invalid */ +static int +get_direction(int transfer_type, int event_type) +{ + int direction; + + direction = -1; + switch(transfer_type){ + case URB_BULK: + case URB_CONTROL: + case URB_ISOCHRONOUS: + switch(event_type) + { + case URB_SUBMIT: + direction = 2; + break; + case URB_COMPLETE: + case URB_ERROR: + direction = 1; + break; + default: + direction = -1; + } + break; + case URB_INTERRUPT: + switch(event_type) + { + case URB_SUBMIT: + direction = 1; + break; + case URB_COMPLETE: + case URB_ERROR: + direction = 2; + break; + default: + direction = -1; + } + break; + default: + direction = -1; + } + + return direction; +} + +static void +usb_header_print(const pcap_usb_header *uh) +{ + int direction; + + switch(uh->transfer_type) + { + case URB_ISOCHRONOUS: + printf("ISOCHRONOUS"); + break; + case URB_INTERRUPT: + printf("INTERRUPT"); + break; + case URB_CONTROL: + printf("CONTROL"); + break; + case URB_BULK: + printf("BULK"); + break; + default: + printf(" ?"); + } + + switch(uh->event_type) + { + case URB_SUBMIT: + printf(" SUBMIT"); + break; + case URB_COMPLETE: + printf(" COMPLETE"); + break; + case URB_ERROR: + printf(" ERROR"); + break; + default: + printf(" ?"); + } + + direction = get_direction(uh->transfer_type, uh->event_type); + if(direction == 1) + printf(" from"); + else if(direction == 2) + printf(" to"); + printf(" %d:%d:%d", uh->bus_id, uh->device_address, uh->endpoint_number & 0x7f); +} + +/* + * This is the top level routine of the printer for captures with a + * 48-byte header. + * + * 'p' points to the 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 +usb_linux_48_byte_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + if (h->caplen < sizeof(pcap_usb_header)) { + printf("[|usb]"); + return(sizeof(pcap_usb_header)); + } + + usb_header_print((const pcap_usb_header *) p); + + return(sizeof(pcap_usb_header)); +} + +#ifdef DLT_USB_LINUX_MMAPPED +/* + * This is the top level routine of the printer for captures with a + * 64-byte header. + * + * 'p' points to the 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 +usb_linux_64_byte_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + if (h->caplen < sizeof(pcap_usb_header_mmapped)) { + printf("[|usb]"); + return(sizeof(pcap_usb_header_mmapped)); + } + + usb_header_print((const pcap_usb_header *) p); + + return(sizeof(pcap_usb_header_mmapped)); +} +#endif /* DLT_USB_LINUX_MMAPPED */ + +#endif /* defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) */ + diff --git a/freebsd/contrib/tcpdump/print-vjc.c b/freebsd/contrib/tcpdump/print-vjc.c new file mode 100644 index 00000000..05f3d3ea --- /dev/null +++ b/freebsd/contrib/tcpdump/print-vjc.c @@ -0,0 +1,121 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-vjc.c,v 1.15 2004-03-25 03:31:17 mcr Exp $ (LBL)"; +#endif + +#include <tcpdump-stdinc.h> + +#include <pcap.h> +#include <stdio.h> + +#include "interface.h" +#include "addrtoname.h" + +#include "slcompress.h" +#include "ppp.h" + +/* + * XXX - for BSD/OS PPP, what packets get supplied with a PPP header type + * of PPP_VJC and what packets get supplied with a PPP header type of + * PPP_VJNC? PPP_VJNC is for "UNCOMPRESSED_TCP" packets, and PPP_VJC + * is for COMPRESSED_TCP packets (PPP_IP is used for TYPE_IP packets). + * + * RFC 1144 implies that, on the wire, the packet type is *not* needed + * for PPP, as different PPP protocol types can be used; it only needs + * to be put on the wire for SLIP. + * + * It also indicates that, for compressed SLIP: + * + * If the COMPRESSED_TCP bit is set in the first byte, it's + * a COMPRESSED_TCP packet; that byte is the change byte, and + * the COMPRESSED_TCP bit, 0x80, isn't used in the change byte. + * + * If the upper 4 bits of the first byte are 7, it's an + * UNCOMPRESSED_TCP packet; that byte is the first byte of + * the UNCOMPRESSED_TCP modified IP header, with a connection + * number in the protocol field, and with the version field + * being 7, not 4. + * + * Otherwise, the packet is an IPv4 packet (where the upper 4 bits + * of the packet are 4). + * + * So this routine looks as if it's sort-of intended to handle + * compressed SLIP, although it doesn't handle UNCOMPRESSED_TCP + * correctly for that (it doesn't fix the version number and doesn't + * do anything to the protocol field), and doesn't check for COMPRESSED_TCP + * packets correctly for that (you only check the first bit - see + * B.1 in RFC 1144). + * + * But it's called for BSD/OS PPP, not SLIP - perhaps BSD/OS does weird + * things with the headers? + * + * Without a BSD/OS VJC-compressed PPP trace, or knowledge of what the + * BSD/OS VJC code does, we can't say what's the case. + * + * We therefore leave "proto" - which is the PPP protocol type - in place, + * *not* marked as unused, for now, so that GCC warnings about the + * unused argument remind us that we should fix this some day. + */ +int +vjc_print(register const char *bp, u_short proto _U_) +{ + int i; + + switch (bp[0] & 0xf0) { + case TYPE_IP: + if (eflag) + printf("(vjc type=IP) "); + return PPP_IP; + case TYPE_UNCOMPRESSED_TCP: + if (eflag) + printf("(vjc type=raw TCP) "); + return PPP_IP; + case TYPE_COMPRESSED_TCP: + if (eflag) + printf("(vjc type=compressed TCP) "); + for (i = 0; i < 8; i++) { + if (bp[1] & (0x80 >> i)) + printf("%c", "?CI?SAWU"[i]); + } + if (bp[1]) + printf(" "); + printf("C=0x%02x ", bp[2]); + printf("sum=0x%04x ", *(u_short *)&bp[3]); + return -1; + case TYPE_ERROR: + if (eflag) + printf("(vjc type=error) "); + return -1; + default: + if (eflag) + printf("(vjc type=0x%02x) ", bp[0] & 0xf0); + return -1; + } +} diff --git a/freebsd/contrib/tcpdump/print-vqp.c b/freebsd/contrib/tcpdump/print-vqp.c new file mode 100644 index 00000000..4dcc385c --- /dev/null +++ b/freebsd/contrib/tcpdump/print-vqp.c @@ -0,0 +1,211 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 Cisco prop. VQP Protocol + * + * Original code by Carles Kishimoto <Carles.Kishimoto@bsc.es> + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-vqp.c,v 1.3 2006-08-19 06:51:13 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#define VQP_VERSION 1 +#define VQP_EXTRACT_VERSION(x) ((x)&0xFF) + +/* + * VQP 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Constant | Packet type | Error Code | nitems | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Packet Sequence Number (4 bytes) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct vqp_common_header_t { + u_int8_t version; + u_int8_t msg_type; + u_int8_t error_code; + u_int8_t nitems; + u_int8_t sequence[4]; +}; + +struct vqp_obj_tlv_t { + u_int8_t obj_type[4]; + u_int8_t obj_length[2]; +}; + +#define VQP_OBJ_REQ_JOIN_PORT 0x01 +#define VQP_OBJ_RESP_VLAN 0x02 +#define VQP_OBJ_REQ_RECONFIRM 0x03 +#define VQP_OBJ_RESP_RECONFIRM 0x04 + +static const struct tok vqp_msg_type_values[] = { + { VQP_OBJ_REQ_JOIN_PORT, "Request, Join Port"}, + { VQP_OBJ_RESP_VLAN, "Response, VLAN"}, + { VQP_OBJ_REQ_RECONFIRM, "Request, Reconfirm"}, + { VQP_OBJ_RESP_RECONFIRM, "Response, Reconfirm"}, + { 0, NULL} +}; + +static const struct tok vqp_error_code_values[] = { + { 0x00, "No error"}, + { 0x03, "Access denied"}, + { 0x04, "Shutdown port"}, + { 0x05, "Wrong VTP domain"}, + { 0, NULL} +}; + +/* FIXME the heading 0x0c looks ugly - those must be flags etc. */ +#define VQP_OBJ_IP_ADDRESS 0x0c01 +#define VQP_OBJ_PORT_NAME 0x0c02 +#define VQP_OBJ_VLAN_NAME 0x0c03 +#define VQP_OBJ_VTP_DOMAIN 0x0c04 +#define VQP_OBJ_ETHERNET_PKT 0x0c05 +#define VQP_OBJ_MAC_NULL 0x0c06 +#define VQP_OBJ_MAC_ADDRESS 0x0c08 + +static const struct tok vqp_obj_values[] = { + { VQP_OBJ_IP_ADDRESS, "Client IP Address" }, + { VQP_OBJ_PORT_NAME, "Port Name" }, + { VQP_OBJ_VLAN_NAME, "VLAN Name" }, + { VQP_OBJ_VTP_DOMAIN, "VTP Domain" }, + { VQP_OBJ_ETHERNET_PKT, "Ethernet Packet" }, + { VQP_OBJ_MAC_NULL, "MAC Null" }, + { VQP_OBJ_MAC_ADDRESS, "MAC Address" }, + { 0, NULL} +}; + +void +vqp_print(register const u_char *pptr, register u_int len) +{ + const struct vqp_common_header_t *vqp_common_header; + const struct vqp_obj_tlv_t *vqp_obj_tlv; + + const u_char *tptr; + u_int16_t vqp_obj_len; + u_int32_t vqp_obj_type; + int tlen; + u_int8_t nitems; + + tptr=pptr; + tlen = len; + vqp_common_header = (const struct vqp_common_header_t *)pptr; + TCHECK(*vqp_common_header); + + /* + * Sanity checking of the header. + */ + if (VQP_EXTRACT_VERSION(vqp_common_header->version) != VQP_VERSION) { + printf("VQP version %u packet not supported", + VQP_EXTRACT_VERSION(vqp_common_header->version)); + return; + } + + /* in non-verbose mode just lets print the basic Message Type */ + if (vflag < 1) { + printf("VQPv%u %s Message, error-code %s (%u), length %u", + VQP_EXTRACT_VERSION(vqp_common_header->version), + tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type), + tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code), + vqp_common_header->error_code, + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + nitems = vqp_common_header->nitems; + printf("\n\tVQPv%u, %s Message, error-code %s (%u), seq 0x%08x, items %u, length %u", + VQP_EXTRACT_VERSION(vqp_common_header->version), + tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type), + tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code), + vqp_common_header->error_code, + EXTRACT_32BITS(&vqp_common_header->sequence), + nitems, + len); + + /* skip VQP Common header */ + tptr+=sizeof(const struct vqp_common_header_t); + tlen-=sizeof(const struct vqp_common_header_t); + + while (nitems > 0 && tlen > 0) { + + vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr; + vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type); + vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length); + tptr+=sizeof(struct vqp_obj_tlv_t); + tlen-=sizeof(struct vqp_obj_tlv_t); + + printf("\n\t %s Object (0x%08x), length %u, value: ", + tok2str(vqp_obj_values, "Unknown", vqp_obj_type), + vqp_obj_type, vqp_obj_len); + + /* basic sanity check */ + if (vqp_obj_type == 0 || vqp_obj_len ==0) { + return; + } + + /* did we capture enough for fully decoding the object ? */ + if (!TTEST2(*tptr, vqp_obj_len)) + goto trunc; + + switch(vqp_obj_type) { + case VQP_OBJ_IP_ADDRESS: + printf("%s (0x%08x)", ipaddr_string(tptr), EXTRACT_32BITS(tptr)); + break; + /* those objects have similar semantics - fall through */ + case VQP_OBJ_PORT_NAME: + case VQP_OBJ_VLAN_NAME: + case VQP_OBJ_VTP_DOMAIN: + case VQP_OBJ_ETHERNET_PKT: + safeputs((const char *)tptr, vqp_obj_len); + break; + /* those objects have similar semantics - fall through */ + case VQP_OBJ_MAC_ADDRESS: + case VQP_OBJ_MAC_NULL: + printf("%s", etheraddr_string(tptr)); + break; + default: + if (vflag <= 1) + print_unknown_data(tptr, "\n\t ", vqp_obj_len); + break; + } + tptr += vqp_obj_len; + tlen -= vqp_obj_len; + nitems--; + } + return; +trunc: + printf("\n\t[|VQP]"); +} diff --git a/freebsd/contrib/tcpdump/print-vrrp.c b/freebsd/contrib/tcpdump/print-vrrp.c new file mode 100644 index 00000000..dcc7dfaa --- /dev/null +++ b/freebsd/contrib/tcpdump/print-vrrp.c @@ -0,0 +1,149 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 2000 William C. Fenner. + * All rights reserved. + * + * Kevin Steves <ks@hp.se> July 2000 + * Modified to: + * - print version, type string and packet length + * - print IP address count if > 1 (-v) + * - verify checksum (-v) + * - print authentication string (-v) + * + * 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. + * The name of William C. Fenner 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. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-vrrp.c,v 1.10 2005-05-06 07:56:54 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * RFC 2338: + * 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| Type | Virtual Rtr ID| Priority | Count IP Addrs| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Auth Type | Adver Int | Checksum | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IP Address (1) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . | + * | . | + * | . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IP Address (n) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Authentication Data (1) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Authentication Data (2) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/* Type */ +#define VRRP_TYPE_ADVERTISEMENT 1 + +static const struct tok type2str[] = { + { VRRP_TYPE_ADVERTISEMENT, "Advertisement" }, + { 0, NULL } +}; + +/* Auth Type */ +#define VRRP_AUTH_NONE 0 +#define VRRP_AUTH_SIMPLE 1 +#define VRRP_AUTH_AH 2 + +static const struct tok auth2str[] = { + { VRRP_AUTH_NONE, "none" }, + { VRRP_AUTH_SIMPLE, "simple" }, + { VRRP_AUTH_AH, "ah" }, + { 0, NULL } +}; + +void +vrrp_print(register const u_char *bp, register u_int len, int ttl) +{ + int version, type, auth_type; + const char *type_s; + + TCHECK(bp[0]); + version = (bp[0] & 0xf0) >> 4; + type = bp[0] & 0x0f; + type_s = tok2str(type2str, "unknown type (%u)", type); + printf("VRRPv%u, %s", version, type_s); + if (ttl != 255) + printf(", (ttl %u)", ttl); + if (version != 2 || type != VRRP_TYPE_ADVERTISEMENT) + return; + TCHECK(bp[2]); + printf(", vrid %u, prio %u", bp[1], bp[2]); + TCHECK(bp[5]); + auth_type = bp[4]; + printf(", authtype %s", tok2str(auth2str, NULL, auth_type)); + printf(", intvl %us, length %u", bp[5],len); + if (vflag) { + int naddrs = bp[3]; + int i; + char c; + + if (TTEST2(bp[0], len)) { + struct cksum_vec vec[1]; + + vec[0].ptr = bp; + vec[0].len = len; + if (in_cksum(vec, 1)) + printf(", (bad vrrp cksum %x)", + EXTRACT_16BITS(&bp[6])); + } + printf(", addrs"); + if (naddrs > 1) + printf("(%d)", naddrs); + printf(":"); + c = ' '; + bp += 8; + for (i = 0; i < naddrs; i++) { + TCHECK(bp[3]); + printf("%c%s", c, ipaddr_string(bp)); + c = ','; + bp += 4; + } + if (auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */ + TCHECK(bp[7]); + printf(" auth \""); + if (fn_printn(bp, 8, snapend)) { + printf("\""); + goto trunc; + } + printf("\""); + } + } + return; +trunc: + printf("[|vrrp]"); +} diff --git a/freebsd/contrib/tcpdump/print-vtp.c b/freebsd/contrib/tcpdump/print-vtp.c new file mode 100644 index 00000000..47afa101 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-vtp.c @@ -0,0 +1,380 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <carles.kishimoto@gmail.com> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> + +#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 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 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 struct tok vtp_vlan_type_values[] = { + { 0x01, "Ethernet"}, + { 0x02, "FDDI"}, + { 0x03, "TrCRF"}, + { 0x04, "FDDI-net"}, + { 0x05, "TrBRF"}, + { 0, NULL } +}; + +static 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 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 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: + */ diff --git a/freebsd/contrib/tcpdump/print-vxlan.c b/freebsd/contrib/tcpdump/print-vxlan.c new file mode 100644 index 00000000..41ad613c --- /dev/null +++ b/freebsd/contrib/tcpdump/print-vxlan.c @@ -0,0 +1,76 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#include "udp.h" + +/* + * VXLAN header, draft-mahalingam-dutt-dcops-vxlan-03 + * + * 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| Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VXLAN Network Identifier (VNI) | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +void +vxlan_print(const u_char *bp, u_int len) +{ + u_int8_t flags; + u_int32_t vni; + + if (len < 8) { + printf("[|VXLAN]"); + return; + } + + flags = *bp; + bp += 4; + + vni = EXTRACT_24BITS(bp); + bp += 4; + + printf("VXLAN, "); + + fputs("flags [", stdout); + if (flags & 0x08) + fputs("I", stdout); + else + fputs(".", stdout); + fputs("] ", stdout); + + printf("(0x%02x), ", flags); + printf("vni %u\n", vni); + + ether_print(gndo, bp, len - 8, len - 8, NULL, NULL); + return; +} diff --git a/freebsd/contrib/tcpdump/print-wb.c b/freebsd/contrib/tcpdump/print-wb.c new file mode 100644 index 00000000..1bcf4b65 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-wb.c @@ -0,0 +1,446 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 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-wb.c,v 1.33 2004-03-24 04:06:28 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +/* XXX need to add byte-swapping macros! */ +/* XXX - you mean like the ones in "extract.h"? */ + +/* + * Largest packet size. Everything should fit within this space. + * For instance, multiline objects are sent piecewise. + */ +#define MAXFRAMESIZE 1024 + +/* + * Multiple drawing ops can be sent in one packet. Each one starts on a + * an even multiple of DOP_ALIGN bytes, which must be a power of two. + */ +#define DOP_ALIGN 4 +#define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1)) +#define DOP_NEXT(d)\ + ((struct dophdr *)((u_char *)(d) + \ + DOP_ROUNDUP(EXTRACT_16BITS(&(d)->dh_len) + sizeof(*(d))))) + +/* + * Format of the whiteboard packet header. + * The transport level header. + */ +struct pkt_hdr { + u_int32_t ph_src; /* site id of source */ + u_int32_t ph_ts; /* time stamp (for skew computation) */ + u_int16_t ph_version; /* version number */ + u_char ph_type; /* message type */ + u_char ph_flags; /* message flags */ +}; + +/* Packet types */ +#define PT_DRAWOP 0 /* drawing operation */ +#define PT_ID 1 /* announcement packet */ +#define PT_RREQ 2 /* repair request */ +#define PT_RREP 3 /* repair reply */ +#define PT_KILL 4 /* terminate participation */ +#define PT_PREQ 5 /* page vector request */ +#define PT_PREP 7 /* page vector reply */ + +#ifdef PF_USER +#undef PF_USER /* {Digital,Tru64} UNIX define this, alas */ +#endif + +/* flags */ +#define PF_USER 0x01 /* hint that packet has interactive data */ +#define PF_VIS 0x02 /* only visible ops wanted */ + +struct PageID { + u_int32_t p_sid; /* session id of initiator */ + u_int32_t p_uid; /* page number */ +}; + +struct dophdr { + u_int32_t dh_ts; /* sender's timestamp */ + u_int16_t dh_len; /* body length */ + u_char dh_flags; + u_char dh_type; /* body type */ + /* body follows */ +}; +/* + * Drawing op sub-types. + */ +#define DT_RECT 2 +#define DT_LINE 3 +#define DT_ML 4 +#define DT_DEL 5 +#define DT_XFORM 6 +#define DT_ELL 7 +#define DT_CHAR 8 +#define DT_STR 9 +#define DT_NOP 10 +#define DT_PSCODE 11 +#define DT_PSCOMP 12 +#define DT_REF 13 +#define DT_SKIP 14 +#define DT_HOLE 15 +#define DT_MAXTYPE 15 + +/* + * A drawing operation. + */ +struct pkt_dop { + struct PageID pd_page; /* page that operations apply to */ + u_int32_t pd_sseq; /* start sequence number */ + u_int32_t pd_eseq; /* end sequence number */ + /* drawing ops follow */ +}; + +/* + * A repair request. + */ +struct pkt_rreq { + u_int32_t pr_id; /* source id of drawops to be repaired */ + struct PageID pr_page; /* page of drawops */ + u_int32_t pr_sseq; /* start seqno */ + u_int32_t pr_eseq; /* end seqno */ +}; + +/* + * A repair reply. + */ +struct pkt_rrep { + u_int32_t pr_id; /* original site id of ops */ + struct pkt_dop pr_dop; + /* drawing ops follow */ +}; + +struct id_off { + u_int32_t id; + u_int32_t off; +}; + +struct pgstate { + u_int32_t slot; + struct PageID page; + u_int16_t nid; + u_int16_t rsvd; + /* seqptr's */ +}; + +/* + * An announcement packet. + */ +struct pkt_id { + u_int32_t pi_mslot; + struct PageID pi_mpage; /* current page */ + struct pgstate pi_ps; + /* seqptr's */ + /* null-terminated site name */ +}; + +struct pkt_preq { + struct PageID pp_page; + u_int32_t pp_low; + u_int32_t pp_high; +}; + +struct pkt_prep { + u_int32_t pp_n; /* size of pageid array */ + /* pgstate's follow */ +}; + +static int +wb_id(const struct pkt_id *id, u_int len) +{ + int i; + const char *cp; + const struct id_off *io; + char c; + int nid; + + printf(" wb-id:"); + if (len < sizeof(*id) || (u_char *)(id + 1) > snapend) + return (-1); + len -= sizeof(*id); + + printf(" %u/%s:%u (max %u/%s:%u) ", + EXTRACT_32BITS(&id->pi_ps.slot), + ipaddr_string(&id->pi_ps.page.p_sid), + EXTRACT_32BITS(&id->pi_ps.page.p_uid), + EXTRACT_32BITS(&id->pi_mslot), + ipaddr_string(&id->pi_mpage.p_sid), + EXTRACT_32BITS(&id->pi_mpage.p_uid)); + + nid = EXTRACT_16BITS(&id->pi_ps.nid); + len -= sizeof(*io) * nid; + io = (struct id_off *)(id + 1); + cp = (char *)(io + nid); + if ((u_char *)cp + len <= snapend) { + putchar('"'); + (void)fn_print((u_char *)cp, (u_char *)cp + len); + putchar('"'); + } + + c = '<'; + for (i = 0; i < nid && (u_char *)(io + 1) <= snapend; ++io, ++i) { + printf("%c%s:%u", + c, ipaddr_string(&io->id), EXTRACT_32BITS(&io->off)); + c = ','; + } + if (i >= nid) { + printf(">"); + return (0); + } + return (-1); +} + +static int +wb_rreq(const struct pkt_rreq *rreq, u_int len) +{ + printf(" wb-rreq:"); + if (len < sizeof(*rreq) || (u_char *)(rreq + 1) > snapend) + return (-1); + + printf(" please repair %s %s:%u<%u:%u>", + ipaddr_string(&rreq->pr_id), + ipaddr_string(&rreq->pr_page.p_sid), + EXTRACT_32BITS(&rreq->pr_page.p_uid), + EXTRACT_32BITS(&rreq->pr_sseq), + EXTRACT_32BITS(&rreq->pr_eseq)); + return (0); +} + +static int +wb_preq(const struct pkt_preq *preq, u_int len) +{ + printf(" wb-preq:"); + if (len < sizeof(*preq) || (u_char *)(preq + 1) > snapend) + return (-1); + + printf(" need %u/%s:%u", + EXTRACT_32BITS(&preq->pp_low), + ipaddr_string(&preq->pp_page.p_sid), + EXTRACT_32BITS(&preq->pp_page.p_uid)); + return (0); +} + +static int +wb_prep(const struct pkt_prep *prep, u_int len) +{ + int n; + const struct pgstate *ps; + const u_char *ep = snapend; + + printf(" wb-prep:"); + if (len < sizeof(*prep)) { + return (-1); + } + n = EXTRACT_32BITS(&prep->pp_n); + ps = (const struct pgstate *)(prep + 1); + while (--n >= 0 && (u_char *)(ps + 1) <= ep) { + const struct id_off *io, *ie; + char c = '<'; + + printf(" %u/%s:%u", + EXTRACT_32BITS(&ps->slot), + ipaddr_string(&ps->page.p_sid), + EXTRACT_32BITS(&ps->page.p_uid)); + io = (struct id_off *)(ps + 1); + for (ie = io + ps->nid; io < ie && (u_char *)(io + 1) <= ep; ++io) { + printf("%c%s:%u", c, ipaddr_string(&io->id), + EXTRACT_32BITS(&io->off)); + c = ','; + } + printf(">"); + ps = (struct pgstate *)io; + } + return ((u_char *)ps <= ep? 0 : -1); +} + + +const char *dopstr[] = { + "dop-0!", + "dop-1!", + "RECT", + "LINE", + "ML", + "DEL", + "XFORM", + "ELL", + "CHAR", + "STR", + "NOP", + "PSCODE", + "PSCOMP", + "REF", + "SKIP", + "HOLE", +}; + +static int +wb_dops(const struct dophdr *dh, u_int32_t ss, u_int32_t es) +{ + printf(" <"); + for ( ; ss <= es; ++ss) { + register int t = dh->dh_type; + + if (t > DT_MAXTYPE) + printf(" dop-%d!", t); + else { + printf(" %s", dopstr[t]); + if (t == DT_SKIP || t == DT_HOLE) { + u_int32_t ts = EXTRACT_32BITS(&dh->dh_ts); + printf("%d", ts - ss + 1); + if (ss > ts || ts > es) { + printf("[|]"); + if (ts < ss) + return (0); + } + ss = ts; + } + } + dh = DOP_NEXT(dh); + if ((u_char *)dh > snapend) { + printf("[|wb]"); + break; + } + } + printf(" >"); + return (0); +} + +static int +wb_rrep(const struct pkt_rrep *rrep, u_int len) +{ + const struct pkt_dop *dop = &rrep->pr_dop; + + printf(" wb-rrep:"); + if (len < sizeof(*rrep) || (u_char *)(rrep + 1) > snapend) + return (-1); + len -= sizeof(*rrep); + + printf(" for %s %s:%u<%u:%u>", + ipaddr_string(&rrep->pr_id), + ipaddr_string(&dop->pd_page.p_sid), + EXTRACT_32BITS(&dop->pd_page.p_uid), + EXTRACT_32BITS(&dop->pd_sseq), + EXTRACT_32BITS(&dop->pd_eseq)); + + if (vflag) + return (wb_dops((const struct dophdr *)(dop + 1), + EXTRACT_32BITS(&dop->pd_sseq), + EXTRACT_32BITS(&dop->pd_eseq))); + return (0); +} + +static int +wb_drawop(const struct pkt_dop *dop, u_int len) +{ + printf(" wb-dop:"); + if (len < sizeof(*dop) || (u_char *)(dop + 1) > snapend) + return (-1); + len -= sizeof(*dop); + + printf(" %s:%u<%u:%u>", + ipaddr_string(&dop->pd_page.p_sid), + EXTRACT_32BITS(&dop->pd_page.p_uid), + EXTRACT_32BITS(&dop->pd_sseq), + EXTRACT_32BITS(&dop->pd_eseq)); + + if (vflag) + return (wb_dops((const struct dophdr *)(dop + 1), + EXTRACT_32BITS(&dop->pd_sseq), + EXTRACT_32BITS(&dop->pd_eseq))); + return (0); +} + +/* + * Print whiteboard multicast packets. + */ +void +wb_print(register const void *hdr, register u_int len) +{ + register const struct pkt_hdr *ph; + + ph = (const struct pkt_hdr *)hdr; + if (len < sizeof(*ph) || (u_char *)(ph + 1) > snapend) { + printf("[|wb]"); + return; + } + len -= sizeof(*ph); + + if (ph->ph_flags) + printf("*"); + switch (ph->ph_type) { + + case PT_KILL: + printf(" wb-kill"); + return; + + case PT_ID: + if (wb_id((struct pkt_id *)(ph + 1), len) >= 0) + return; + break; + + case PT_RREQ: + if (wb_rreq((struct pkt_rreq *)(ph + 1), len) >= 0) + return; + break; + + case PT_RREP: + if (wb_rrep((struct pkt_rrep *)(ph + 1), len) >= 0) + return; + break; + + case PT_DRAWOP: + if (wb_drawop((struct pkt_dop *)(ph + 1), len) >= 0) + return; + break; + + case PT_PREQ: + if (wb_preq((struct pkt_preq *)(ph + 1), len) >= 0) + return; + break; + + case PT_PREP: + if (wb_prep((struct pkt_prep *)(ph + 1), len) >= 0) + return; + break; + + default: + printf(" wb-%d!", ph->ph_type); + return; + } +} diff --git a/freebsd/contrib/tcpdump/print-zephyr.c b/freebsd/contrib/tcpdump/print-zephyr.c new file mode 100644 index 00000000..7ed72118 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-zephyr.c @@ -0,0 +1,324 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Decode and print Zephyr packets. + * + * http://web.mit.edu/zephyr/doc/protocol + * + * Copyright (c) 2001 Nickolai Zeldovich <kolya@MIT.EDU> + * 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, 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. + * The name of the author(s) 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. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-zephyr.c,v 1.10 2007-08-09 18:47:27 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "interface.h" + +struct z_packet { + char *version; + int numfields; + int kind; + char *uid; + int port; + int auth; + int authlen; + char *authdata; + char *class; + char *inst; + char *opcode; + char *sender; + const char *recipient; + char *format; + int cksum; + int multi; + char *multi_uid; + /* Other fields follow here.. */ +}; + +enum z_packet_type { + Z_PACKET_UNSAFE = 0, + Z_PACKET_UNACKED, + Z_PACKET_ACKED, + Z_PACKET_HMACK, + Z_PACKET_HMCTL, + Z_PACKET_SERVACK, + Z_PACKET_SERVNAK, + Z_PACKET_CLIENTACK, + Z_PACKET_STAT +}; + +static struct tok z_types[] = { + { Z_PACKET_UNSAFE, "unsafe" }, + { Z_PACKET_UNACKED, "unacked" }, + { Z_PACKET_ACKED, "acked" }, + { Z_PACKET_HMACK, "hm-ack" }, + { Z_PACKET_HMCTL, "hm-ctl" }, + { Z_PACKET_SERVACK, "serv-ack" }, + { Z_PACKET_SERVNAK, "serv-nak" }, + { Z_PACKET_CLIENTACK, "client-ack" }, + { Z_PACKET_STAT, "stat" } +}; + +char z_buf[256]; + +static char * +parse_field(char **pptr, int *len) +{ + char *s; + + if (*len <= 0 || !pptr || !*pptr) + return NULL; + if (*pptr > (char *) snapend) + return NULL; + + s = *pptr; + while (*pptr <= (char *) snapend && *len >= 0 && **pptr) { + (*pptr)++; + (*len)--; + } + (*pptr)++; + (*len)--; + if (*len < 0 || *pptr > (char *) snapend) + return NULL; + return s; +} + +static const char * +z_triple(char *class, char *inst, const char *recipient) +{ + if (!*recipient) + recipient = "*"; + snprintf(z_buf, sizeof(z_buf), "<%s,%s,%s>", class, inst, recipient); + z_buf[sizeof(z_buf)-1] = '\0'; + return z_buf; +} + +static const char * +str_to_lower(char *string) +{ + strncpy(z_buf, string, sizeof(z_buf)); + z_buf[sizeof(z_buf)-1] = '\0'; + + string = z_buf; + while (*string) { + *string = tolower((unsigned char)(*string)); + string++; + } + + return z_buf; +} + +void +zephyr_print(const u_char *cp, int length) +{ + struct z_packet z; + char *parse = (char *) cp; + int parselen = length; + char *s; + int lose = 0; + + /* squelch compiler warnings */ + + z.kind = 0; + z.class = 0; + z.inst = 0; + z.opcode = 0; + z.sender = 0; + z.recipient = 0; + +#define PARSE_STRING \ + s = parse_field(&parse, &parselen); \ + if (!s) lose = 1; + +#define PARSE_FIELD_INT(field) \ + PARSE_STRING \ + if (!lose) field = strtol(s, 0, 16); + +#define PARSE_FIELD_STR(field) \ + PARSE_STRING \ + if (!lose) field = s; + + PARSE_FIELD_STR(z.version); + if (lose) return; + if (strncmp(z.version, "ZEPH", 4)) + return; + + PARSE_FIELD_INT(z.numfields); + PARSE_FIELD_INT(z.kind); + PARSE_FIELD_STR(z.uid); + PARSE_FIELD_INT(z.port); + PARSE_FIELD_INT(z.auth); + PARSE_FIELD_INT(z.authlen); + PARSE_FIELD_STR(z.authdata); + PARSE_FIELD_STR(z.class); + PARSE_FIELD_STR(z.inst); + PARSE_FIELD_STR(z.opcode); + PARSE_FIELD_STR(z.sender); + PARSE_FIELD_STR(z.recipient); + PARSE_FIELD_STR(z.format); + PARSE_FIELD_INT(z.cksum); + PARSE_FIELD_INT(z.multi); + PARSE_FIELD_STR(z.multi_uid); + + if (lose) { + printf(" [|zephyr] (%d)", length); + return; + } + + printf(" zephyr"); + if (strncmp(z.version+4, "0.2", 3)) { + printf(" v%s", z.version+4); + return; + } + + printf(" %s", tok2str(z_types, "type %d", z.kind)); + if (z.kind == Z_PACKET_SERVACK) { + /* Initialization to silence warnings */ + char *ackdata = NULL; + PARSE_FIELD_STR(ackdata); + if (!lose && strcmp(ackdata, "SENT")) + printf("/%s", str_to_lower(ackdata)); + } + if (*z.sender) printf(" %s", z.sender); + + if (!strcmp(z.class, "USER_LOCATE")) { + if (!strcmp(z.opcode, "USER_HIDE")) + printf(" hide"); + else if (!strcmp(z.opcode, "USER_UNHIDE")) + printf(" unhide"); + else + printf(" locate %s", z.inst); + return; + } + + if (!strcmp(z.class, "ZEPHYR_ADMIN")) { + printf(" zephyr-admin %s", str_to_lower(z.opcode)); + return; + } + + if (!strcmp(z.class, "ZEPHYR_CTL")) { + if (!strcmp(z.inst, "CLIENT")) { + if (!strcmp(z.opcode, "SUBSCRIBE") || + !strcmp(z.opcode, "SUBSCRIBE_NODEFS") || + !strcmp(z.opcode, "UNSUBSCRIBE")) { + + printf(" %ssub%s", strcmp(z.opcode, "SUBSCRIBE") ? "un" : "", + strcmp(z.opcode, "SUBSCRIBE_NODEFS") ? "" : + "-nodefs"); + if (z.kind != Z_PACKET_SERVACK) { + /* Initialization to silence warnings */ + char *c = NULL, *i = NULL, *r = NULL; + PARSE_FIELD_STR(c); + PARSE_FIELD_STR(i); + PARSE_FIELD_STR(r); + if (!lose) printf(" %s", z_triple(c, i, r)); + } + return; + } + + if (!strcmp(z.opcode, "GIMME")) { + printf(" ret"); + return; + } + + if (!strcmp(z.opcode, "GIMMEDEFS")) { + printf(" gimme-defs"); + return; + } + + if (!strcmp(z.opcode, "CLEARSUB")) { + printf(" clear-subs"); + return; + } + + printf(" %s", str_to_lower(z.opcode)); + return; + } + + if (!strcmp(z.inst, "HM")) { + printf(" %s", str_to_lower(z.opcode)); + return; + } + + if (!strcmp(z.inst, "REALM")) { + if (!strcmp(z.opcode, "ADD_SUBSCRIBE")) + printf(" realm add-subs"); + if (!strcmp(z.opcode, "REQ_SUBSCRIBE")) + printf(" realm req-subs"); + if (!strcmp(z.opcode, "RLM_SUBSCRIBE")) + printf(" realm rlm-sub"); + if (!strcmp(z.opcode, "RLM_UNSUBSCRIBE")) + printf(" realm rlm-unsub"); + return; + } + } + + if (!strcmp(z.class, "HM_CTL")) { + printf(" hm_ctl %s", str_to_lower(z.inst)); + printf(" %s", str_to_lower(z.opcode)); + return; + } + + if (!strcmp(z.class, "HM_STAT")) { + if (!strcmp(z.inst, "HMST_CLIENT") && !strcmp(z.opcode, "GIMMESTATS")) { + printf(" get-client-stats"); + return; + } + } + + if (!strcmp(z.class, "WG_CTL")) { + printf(" wg_ctl %s", str_to_lower(z.inst)); + printf(" %s", str_to_lower(z.opcode)); + return; + } + + if (!strcmp(z.class, "LOGIN")) { + if (!strcmp(z.opcode, "USER_FLUSH")) { + printf(" flush_locs"); + return; + } + + if (!strcmp(z.opcode, "NONE") || + !strcmp(z.opcode, "OPSTAFF") || + !strcmp(z.opcode, "REALM-VISIBLE") || + !strcmp(z.opcode, "REALM-ANNOUNCED") || + !strcmp(z.opcode, "NET-VISIBLE") || + !strcmp(z.opcode, "NET-ANNOUNCED")) { + printf(" set-exposure %s", str_to_lower(z.opcode)); + return; + } + } + + if (!*z.recipient) + z.recipient = "*"; + + printf(" to %s", z_triple(z.class, z.inst, z.recipient)); + if (*z.opcode) + printf(" op %s", z.opcode); + return; +} diff --git a/freebsd/contrib/tcpdump/print-zeromq.c b/freebsd/contrib/tcpdump/print-zeromq.c new file mode 100644 index 00000000..ffd90bc1 --- /dev/null +++ b/freebsd/contrib/tcpdump/print-zeromq.c @@ -0,0 +1,150 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * This file implements decoding of ZeroMQ network protocol(s). + * + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> + +#include "interface.h" +#include "extract.h" + +/* Maximum number of ZMTP/1.0 frame body bytes (without the flags) to dump in + * hex and ASCII under a single "-v" flag. + */ +#define VBYTES 128 + +/* + * Below is an excerpt from the "13/ZMTP" specification: + * + * A ZMTP message consists of 1 or more frames. + * + * A ZMTP frame consists of a length, followed by a flags field and a frame + * body of (length - 1) octets. Note: the length includes the flags field, so + * an empty frame has a length of 1. + * + * For frames with a length of 1 to 254 octets, the length SHOULD BE encoded + * as a single octet. The minimum valid length of a frame is 1 octet, thus a + * length of 0 is invalid and such frames SHOULD be discarded silently. + * + * For frames with lengths of 255 and greater, the length SHALL BE encoded as + * a single octet with the value 255, followed by the length encoded as a + * 64-bit unsigned integer in network byte order. For frames with lengths of + * 1 to 254 octets this encoding MAY be also used. + * + * The flags field consists of a single octet containing various control + * flags. Bit 0 is the least significant bit. + * + * - Bit 0 (MORE): More frames to follow. A value of 0 indicates that there + * are no more frames to follow. A value of 1 indicates that more frames + * will follow. On messages consisting of a single frame the MORE flag MUST + * be 0. + * + * - Bits 1-7: Reserved. Bits 1-7 are reserved for future use and SHOULD be + * zero. + */ + +static const u_char * +zmtp1_print_frame(const u_char *cp, const u_char *ep) { + u_int64_t body_len_declared, body_len_captured, header_len; + u_int8_t flags; + + printf("\n\t"); + TCHECK2(*cp, 1); /* length/0xFF */ + + if (cp[0] != 0xFF) { + header_len = 1; /* length */ + body_len_declared = cp[0]; + if (body_len_declared == 0) + return cp + header_len; /* skip to next frame */ + printf(" frame flags+body (8-bit) length %"PRIu8"", cp[0]); + TCHECK2(*cp, header_len + 1); /* length, flags */ + flags = cp[1]; + } else { + header_len = 1 + 8; /* 0xFF, length */ + printf(" frame flags+body (64-bit) length"); + TCHECK2(*cp, header_len); /* 0xFF, length */ + body_len_declared = EXTRACT_64BITS(cp + 1); + if (body_len_declared == 0) + return cp + header_len; /* skip to next frame */ + printf(" %"PRIu64"", body_len_declared); + TCHECK2(*cp, header_len + 1); /* 0xFF, length, flags */ + flags = cp[9]; + } + + body_len_captured = ep - cp - header_len; + if (body_len_declared > body_len_captured) + printf(" (%"PRIu64" captured)", body_len_captured); + printf(", flags 0x%02"PRIx8"", flags); + + if (vflag) { + u_int64_t body_len_printed = MIN(body_len_captured, body_len_declared); + + printf(" (%s|%s|%s|%s|%s|%s|%s|%s)", + flags & 0x80 ? "MBZ" : "-", + flags & 0x40 ? "MBZ" : "-", + flags & 0x20 ? "MBZ" : "-", + flags & 0x10 ? "MBZ" : "-", + flags & 0x08 ? "MBZ" : "-", + flags & 0x04 ? "MBZ" : "-", + flags & 0x02 ? "MBZ" : "-", + flags & 0x01 ? "MORE" : "-"); + + if (vflag == 1) + body_len_printed = MIN(VBYTES + 1, body_len_printed); + if (body_len_printed > 1) { + printf(", first %"PRIu64" byte(s) of body:", body_len_printed - 1); + hex_and_ascii_print("\n\t ", cp + header_len + 1, body_len_printed - 1); + printf("\n"); + } + } + + TCHECK2(*cp, header_len + body_len_declared); /* Next frame within the buffer ? */ + return cp + header_len + body_len_declared; + +trunc: + printf(" [|zmtp1]"); + return ep; +} + +void +zmtp1_print(const u_char *cp, u_int len) { + const u_char *ep = MIN(snapend, cp + len); + + printf(": ZMTP/1.0"); + while (cp < ep) + cp = zmtp1_print_frame(cp, ep); +} + diff --git a/freebsd/contrib/tcpdump/route6d.h b/freebsd/contrib/tcpdump/route6d.h new file mode 100644 index 00000000..53953fdb --- /dev/null +++ b/freebsd/contrib/tcpdump/route6d.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 1995, 1996, 1997 and 1998 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. + */ +/* + * $Header: /tcpdump/master/tcpdump/route6d.h,v 1.5 2002-12-11 07:14:10 guy Exp $ + */ + +#define RIP6_VERSION 1 + +#define RIP6_REQUEST 1 +#define RIP6_RESPONSE 2 + +struct netinfo6 { + struct in6_addr rip6_dest; + u_int16_t rip6_tag; + u_int8_t rip6_plen; + u_int8_t rip6_metric; +}; + +struct rip6 { + u_int8_t rip6_cmd; + u_int8_t rip6_vers; + u_int8_t rip6_res1[2]; + union { + struct netinfo6 ru6_nets[1]; + char ru6_tracefile[1]; + } rip6un; +#define rip6_nets rip6un.ru6_nets +#define rip6_tracefile rip6un.ru6_tracefile +}; + +#define HOPCNT_INFINITY6 16 +#define MAXRTE 24 +#define NEXTHOP_METRIC 0xff + +#ifndef DEBUG +#define SUPPLY_INTERVAL6 30 +#define RIP_LIFETIME 180 +#define RIP_HOLDDOWN 120 +#define RIP_TRIG_INTERVAL6 5 +#define RIP_TRIG_INTERVAL6_MIN 1 +#else +/* only for debugging; can not wait for 30sec to appear a bug */ +#define SUPPLY_INTERVAL6 10 +#define RIP_LIFETIME 60 +#define RIP_HOLDDOWN 40 +#define RIP_TRIG_INTERVAL6 5 +#define RIP_TRIG_INTERVAL6_MIN 1 +#endif + +#define RIP6_PORT 521 +#define RIP6_DEST "ff02::9" diff --git a/freebsd/contrib/tcpdump/rpc_auth.h b/freebsd/contrib/tcpdump/rpc_auth.h new file mode 100644 index 00000000..0e5a1c12 --- /dev/null +++ b/freebsd/contrib/tcpdump/rpc_auth.h @@ -0,0 +1,80 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/rpc_auth.h,v 1.2 2005-04-27 21:43:48 guy Exp $ (LBL) */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)auth.h 1.17 88/02/08 SMI + * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC + * $FreeBSD$ + * FreeBSD: src/include/rpc/auth.h,v 1.14.2.1 1999/08/29 14:39:02 peter Exp + */ + +/* + * auth.h, Authentication interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The data structures are completely opaque to the client. The client + * is required to pass a AUTH * to routines that create rpc + * "sessions". + */ + +/* + * Status returned from authentication check + */ +enum sunrpc_auth_stat { + SUNRPC_AUTH_OK=0, + /* + * failed at remote end + */ + SUNRPC_AUTH_BADCRED=1, /* bogus credentials (seal broken) */ + SUNRPC_AUTH_REJECTEDCRED=2, /* client should begin new session */ + SUNRPC_AUTH_BADVERF=3, /* bogus verifier (seal broken) */ + SUNRPC_AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ + SUNRPC_AUTH_TOOWEAK=5, /* rejected due to security reasons */ + /* + * failed locally + */ + SUNRPC_AUTH_INVALIDRESP=6, /* bogus response verifier */ + SUNRPC_AUTH_FAILED=7 /* some unknown reason */ +}; + +/* + * Authentication info. Opaque to client. + */ +struct sunrpc_opaque_auth { + u_int32_t oa_flavor; /* flavor of auth */ + u_int32_t oa_len; /* length of opaque body */ + /* zero or more bytes of body */ +}; + +#define SUNRPC_AUTH_NONE 0 /* no authentication */ +#define SUNRPC_AUTH_NULL 0 /* backward compatibility */ +#define SUNRPC_AUTH_UNIX 1 /* unix style (uid, gids) */ +#define SUNRPC_AUTH_SYS 1 /* forward compatibility */ +#define SUNRPC_AUTH_SHORT 2 /* short hand unix style */ +#define SUNRPC_AUTH_DES 3 /* des style (encrypted timestamps) */ diff --git a/freebsd/contrib/tcpdump/rpc_msg.h b/freebsd/contrib/tcpdump/rpc_msg.h new file mode 100644 index 00000000..9c2770c2 --- /dev/null +++ b/freebsd/contrib/tcpdump/rpc_msg.h @@ -0,0 +1,129 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/rpc_msg.h,v 1.2 2005-04-27 21:43:48 guy Exp $ (LBL) */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)rpc_msg.h 1.7 86/07/16 SMI + * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD$ + * FreeBSD: src/include/rpc/rpc_msg.h,v 1.11.2.1 1999/08/29 14:39:07 peter Exp + */ + +/* + * rpc_msg.h + * rpc message definition + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#define SUNRPC_MSG_VERSION ((u_int32_t) 2) + +/* + * Bottom up definition of an rpc message. + * NOTE: call and reply use the same overall stuct but + * different parts of unions within it. + */ + +enum sunrpc_msg_type { + SUNRPC_CALL=0, + SUNRPC_REPLY=1 +}; + +enum sunrpc_reply_stat { + SUNRPC_MSG_ACCEPTED=0, + SUNRPC_MSG_DENIED=1 +}; + +enum sunrpc_accept_stat { + SUNRPC_SUCCESS=0, + SUNRPC_PROG_UNAVAIL=1, + SUNRPC_PROG_MISMATCH=2, + SUNRPC_PROC_UNAVAIL=3, + SUNRPC_GARBAGE_ARGS=4, + SUNRPC_SYSTEM_ERR=5 +}; + +enum sunrpc_reject_stat { + SUNRPC_RPC_MISMATCH=0, + SUNRPC_AUTH_ERROR=1 +}; + +/* + * Reply part of an rpc exchange + */ + +/* + * Reply to an rpc request that was rejected by the server. + */ +struct sunrpc_rejected_reply { + u_int32_t rj_stat; /* enum reject_stat */ + union { + struct { + u_int32_t low; + u_int32_t high; + } RJ_versions; + u_int32_t RJ_why; /* enum auth_stat - why authentication did not work */ + } ru; +#define rj_vers ru.RJ_versions +#define rj_why ru.RJ_why +}; + +/* + * Body of a reply to an rpc request. + */ +struct sunrpc_reply_body { + u_int32_t rp_stat; /* enum reply_stat */ + struct sunrpc_rejected_reply rp_reject; /* if rejected */ +}; + +/* + * Body of an rpc request call. + */ +struct sunrpc_call_body { + u_int32_t cb_rpcvers; /* must be equal to two */ + u_int32_t cb_prog; + u_int32_t cb_vers; + u_int32_t cb_proc; + struct sunrpc_opaque_auth cb_cred; + /* followed by opaque verifier */ +}; + +/* + * The rpc message + */ +struct sunrpc_msg { + u_int32_t rm_xid; + u_int32_t rm_direction; /* enum msg_type */ + union { + struct sunrpc_call_body RM_cmb; + struct sunrpc_reply_body RM_rmb; + } ru; +#define rm_call ru.RM_cmb +#define rm_reply ru.RM_rmb +}; +#define acpted_rply ru.RM_rmb.ru.RP_ar +#define rjcted_rply ru.RM_rmb.ru.RP_dr diff --git a/freebsd/contrib/tcpdump/rx.h b/freebsd/contrib/tcpdump/rx.h new file mode 100644 index 00000000..b79dd30c --- /dev/null +++ b/freebsd/contrib/tcpdump/rx.h @@ -0,0 +1,113 @@ +/* + * Copyright: (c) 2000 United States Government as represented by the + * Secretary of the Navy. 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. + */ +/* + * Rx protocol format + * + * $Id: rx.h,v 1.8 2002-12-11 07:14:11 guy Exp $ + */ + +#define FS_RX_PORT 7000 +#define CB_RX_PORT 7001 +#define PROT_RX_PORT 7002 +#define VLDB_RX_PORT 7003 +#define KAUTH_RX_PORT 7004 +#define VOL_RX_PORT 7005 +#define ERROR_RX_PORT 7006 /* Doesn't seem to be used */ +#define BOS_RX_PORT 7007 + +#ifndef AFSNAMEMAX +#define AFSNAMEMAX 256 +#endif + +#ifndef AFSOPAQUEMAX +#define AFSOPAQUEMAX 1024 +#endif + +#define PRNAMEMAX 64 +#define VLNAMEMAX 65 +#define KANAMEMAX 64 +#define BOSNAMEMAX 256 + +#define PRSFS_READ 1 /* Read files */ +#define PRSFS_WRITE 2 /* Write files */ +#define PRSFS_INSERT 4 /* Insert files into a directory */ +#define PRSFS_LOOKUP 8 /* Lookup files into a directory */ +#define PRSFS_DELETE 16 /* Delete files */ +#define PRSFS_LOCK 32 /* Lock files */ +#define PRSFS_ADMINISTER 64 /* Change ACL's */ + +struct rx_header { + u_int32_t epoch; + u_int32_t cid; + u_int32_t callNumber; + u_int32_t seq; + u_int32_t serial; + u_int8_t type; +#define RX_PACKET_TYPE_DATA 1 +#define RX_PACKET_TYPE_ACK 2 +#define RX_PACKET_TYPE_BUSY 3 +#define RX_PACKET_TYPE_ABORT 4 +#define RX_PACKET_TYPE_ACKALL 5 +#define RX_PACKET_TYPE_CHALLENGE 6 +#define RX_PACKET_TYPE_RESPONSE 7 +#define RX_PACKET_TYPE_DEBUG 8 +#define RX_PACKET_TYPE_PARAMS 9 +#define RX_PACKET_TYPE_VERSION 13 + u_int8_t flags; +#define RX_CLIENT_INITIATED 1 +#define RX_REQUEST_ACK 2 +#define RX_LAST_PACKET 4 +#define RX_MORE_PACKETS 8 +#define RX_FREE_PACKET 16 +#define RX_SLOW_START_OK 32 +#define RX_JUMBO_PACKET 32 + u_int8_t userStatus; + u_int8_t securityIndex; + u_int16_t spare; /* How clever: even though the AFS */ + u_int16_t serviceId; /* header files indicate that the */ +}; /* serviceId is first, it's really */ + /* encoded _after_ the spare field */ + /* I wasted a day figuring that out! */ + +#define NUM_RX_FLAGS 7 + +#define RX_MAXACKS 255 + +struct rx_ackPacket { + u_int16_t bufferSpace; /* Number of packet buffers available */ + u_int16_t maxSkew; /* Max diff between ack'd packet and */ + /* highest packet received */ + u_int32_t firstPacket; /* The first packet in ack list */ + u_int32_t previousPacket; /* Previous packet recv'd (obsolete) */ + u_int32_t serial; /* # of packet that prompted the ack */ + u_int8_t reason; /* Reason for acknowledgement */ + u_int8_t nAcks; /* Number of acknowledgements */ + u_int8_t acks[RX_MAXACKS]; /* Up to RX_MAXACKS acknowledgements */ +}; + +/* + * Values for the acks array + */ + +#define RX_ACK_TYPE_NACK 0 /* Don't have this packet */ +#define RX_ACK_TYPE_ACK 1 /* I have this packet */ diff --git a/freebsd/contrib/tcpdump/sctpConstants.h b/freebsd/contrib/tcpdump/sctpConstants.h new file mode 100644 index 00000000..ac28a151 --- /dev/null +++ b/freebsd/contrib/tcpdump/sctpConstants.h @@ -0,0 +1,571 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/sctpConstants.h,v 1.4 2003-06-03 23:49:23 guy Exp $ (LBL) */ + +/* SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola + * + * 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 Cisco nor of Motorola 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. + * + * This file is part of the SCTP reference Implementation + * + * + * Please send any bug reports or fixes you make to one of the following email + * addresses: + * + * rstewar1@email.mot.com + * kmorneau@cisco.com + * qxie1@email.mot.com + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorperated into the next SCTP release. + */ + + +#ifndef __sctpConstants_h__ +#define __sctpConstants_h__ + + + /* If you wish to use MD5 instead of SLA uncomment the line + * below. Why you would like to do this: + * a) There may be IPR on SHA-1, or so the FIP-180-1 page says, + * b) MD5 is 3 times faster (has coded here). + * + * The disadvantage is, it is thought that MD5 has been + * cracked... see RFC2104. + */ +/*#define USE_MD5 1*/ + +/* the SCTP protocol signature + * this includes the version number + * encoded in the last 4 bits of the + * signature. + */ +#define PROTO_SIGNATURE_A 0x30000000 + +#define SCTP_VERSION_NUMBER 0x3 + +#define MAX_TSN 0xffffffff +#define MAX_SEQ 0xffff + +/* option: + * If you comment out the following you will + * receive the old behavior of obeying cwnd for + * the fast retransmit algorithm. With this defined + * a FR happens right away with-out waiting for the + * flightsize to drop below the cwnd value (which + * is reduced by the FR to 1/2 the inflight packets). + */ +#define SCTP_IGNORE_CWND_ON_FR 1 +/* default max I can burst out after a fast retransmit */ +#define SCTP_DEF_MAX_BURST 4 + +/* Packet transmit states in the sent + * field in the SCTP_transmitOnQueue struct + */ +#define SCTP_DATAGRAM_UNSENT 0 +#define SCTP_DATAGRAM_SENT 1 +#define SCTP_DATAGRAM_RESEND1 2 /* not used */ +#define SCTP_DATAGRAM_RESEND2 3 /* not used */ +#define SCTP_DATAGRAM_RESEND3 4 /* not used */ +#define SCTP_DATAGRAM_RESEND 5 +#define SCTP_DATAGRAM_ACKED 10010 +#define SCTP_DATAGRAM_INBOUND 10011 +#define SCTP_READY_TO_TRANSMIT 10012 +#define SCTP_DATAGRAM_MARKED 20010 + +#define MAX_FSID 64 /* debug 5 ints used for cc dynamic tracking */ + +/* The valid defines for all message + * types know to SCTP. 0 is reserved + */ +#define SCTP_MSGTYPE_MASK 0xff + +#define SCTP_DATA 0x00 +#define SCTP_INITIATION 0x01 +#define SCTP_INITIATION_ACK 0x02 +#define SCTP_SELECTIVE_ACK 0x03 +#define SCTP_HEARTBEAT_REQUEST 0x04 +#define SCTP_HEARTBEAT_ACK 0x05 +#define SCTP_ABORT_ASSOCIATION 0x06 +#define SCTP_SHUTDOWN 0x07 +#define SCTP_SHUTDOWN_ACK 0x08 +#define SCTP_OPERATION_ERR 0x09 +#define SCTP_COOKIE_ECHO 0x0a +#define SCTP_COOKIE_ACK 0x0b +#define SCTP_ECN_ECHO 0x0c +#define SCTP_ECN_CWR 0x0d +#define SCTP_SHUTDOWN_COMPLETE 0x0e +#define SCTP_FORWARD_CUM_TSN 0xc0 +#define SCTP_RELIABLE_CNTL 0xc1 +#define SCTP_RELIABLE_CNTL_ACK 0xc2 + +/* ABORT and SHUTDOWN COMPLETE FLAG */ +#define SCTP_HAD_NO_TCB 0x01 + +/* Data Chuck Specific Flags */ +#define SCTP_DATA_FRAG_MASK 0x03 +#define SCTP_DATA_MIDDLE_FRAG 0x00 +#define SCTP_DATA_LAST_FRAG 0x01 +#define SCTP_DATA_FIRST_FRAG 0x02 +#define SCTP_DATA_NOT_FRAG 0x03 +#define SCTP_DATA_UNORDERED 0x04 + +#define SCTP_CRC_ENABLE_BIT 0x01 /* lower bit of reserved */ + +#define isSCTPControl(a) (a->chunkID != SCTP_DATA) +#define isSCTPData(a) (a->chunkID == SCTP_DATA) + +/* sctp parameter types for init/init-ack */ + +#define SCTP_IPV4_PARAM_TYPE 0x0005 +#define SCTP_IPV6_PARAM_TYPE 0x0006 +#define SCTP_RESPONDER_COOKIE 0x0007 +#define SCTP_UNRECOG_PARAM 0x0008 +#define SCTP_COOKIE_PRESERVE 0x0009 +#define SCTP_HOSTNAME_VIA_DNS 0x000b +#define SCTP_RESTRICT_ADDR_TO 0x000c + +#define SCTP_ECN_I_CAN_DO_ECN 0x8000 +#define SCTP_OPERATION_SUCCEED 0x4001 +#define SCTP_ERROR_NOT_EXECUTED 0x4002 + +#define SCTP_UNRELIABLE_STRM 0xc000 +#define SCTP_ADD_IP_ADDRESS 0xc001 +#define SCTP_DEL_IP_ADDRESS 0xc002 +#define SCTP_STRM_FLOW_LIMIT 0xc003 +#define SCTP_PARTIAL_CSUM 0xc004 +#define SCTP_ERROR_CAUSE_TLV 0xc005 +#define SCTP_MIT_STACK_NAME 0xc006 +#define SCTP_SETADDRESS_PRIMARY 0xc007 + +/* bits for TOS field */ +#define SCTP_ECT_BIT 0x02 +#define SCTP_CE_BIT 0x01 + +/* error codes */ +#define SCTP_OP_ERROR_NO_ERROR 0x0000 +#define SCTP_OP_ERROR_INV_STRM 0x0001 +#define SCTP_OP_ERROR_MISS_PARAM 0x0002 +#define SCTP_OP_ERROR_STALE_COOKIE 0x0003 +#define SCTP_OP_ERROR_NO_RESOURCE 0x0004 +#define SCTP_OP_ERROR_DNS_FAILED 0x0005 +#define SCTP_OP_ERROR_UNK_CHUNK 0x0006 +#define SCTP_OP_ERROR_INV_PARAM 0x0007 +#define SCTP_OP_ERROR_UNK_PARAM 0x0008 +#define SCTP_OP_ERROR_NO_USERD 0x0009 +#define SCTP_OP_ERROR_COOKIE_SHUT 0x000a +#define SCTP_OP_ERROR_DELETE_LAST 0x000b +#define SCTP_OP_ERROR_RESOURCE_SHORT 0x000c + +#define SCTP_MAX_ERROR_CAUSE 12 + +/* empty error causes i.e. nothing but the cause + * are SCTP_OP_ERROR_NO_RESOURCE, SCTP_OP_ERROR_INV_PARAM, + * SCTP_OP_ERROR_COOKIE_SHUT. + */ + +/* parameter for Heart Beat */ +#define HEART_BEAT_PARAM 0x0001 + + + +/* send options for SCTP + */ +#define SCTP_ORDERED_DELIVERY 0x01 +#define SCTP_NON_ORDERED_DELIVERY 0x02 +#define SCTP_DO_CRC16 0x08 +#define SCTP_MY_ADDRESS_ONLY 0x10 + +/* below turns off above */ +#define SCTP_FLEXIBLE_ADDRESS 0x20 +#define SCTP_NO_HEARTBEAT 0x40 + +/* mask to get sticky */ +#define SCTP_STICKY_OPTIONS_MASK 0x0c + +/* MTU discovery flags */ +#define SCTP_DONT_FRAGMENT 0x0100 +#define SCTP_FRAGMENT_OK 0x0200 + + +/* SCTP state defines for internal state machine */ +#define SCTP_STATE_EMPTY 0x0000 +#define SCTP_STATE_INUSE 0x0001 +#define SCTP_STATE_COOKIE_WAIT 0x0002 +#define SCTP_STATE_COOKIE_SENT 0x0004 +#define SCTP_STATE_OPEN 0x0008 +#define SCTP_STATE_SHUTDOWN 0x0010 +#define SCTP_STATE_SHUTDOWN_RECV 0x0020 +#define SCTP_STATE_SHUTDOWN_ACK_SENT 0x0040 +#define SCTP_STATE_SHUTDOWN_PEND 0x0080 +#define SCTP_STATE_MASK 0x007f +/* SCTP reachability state for each address */ +#define SCTP_ADDR_NOT_REACHABLE 1 +#define SCTP_ADDR_REACHABLE 2 +#define SCTP_ADDR_NOHB 4 +#define SCTP_ADDR_BEING_DELETED 8 + +/* How long a cookie lives */ +#define SCTP_DEFAULT_COOKIE_LIFE 60 /* seconds */ + +/* resource limit of streams */ +#define MAX_SCTP_STREAMS 2048 + + +/* guess at how big to make the TSN mapping array */ +#define SCTP_STARTING_MAPARRAY 10000 + +/* Here we define the timer types used + * by the implementation has + * arguments in the set/get timer type calls. + */ +#define SCTP_TIMER_INIT 0 +#define SCTP_TIMER_RECV 1 +#define SCTP_TIMER_SEND 2 +#define SCTP_TIMER_SHUTDOWN 3 +#define SCTP_TIMER_HEARTBEAT 4 +#define SCTP_TIMER_PMTU 5 +/* number of timer types in the base SCTP + * structure used in the set/get and has + * the base default. + */ +#define SCTP_NUM_TMRS 6 + + + +#define SCTP_IPV4_ADDRESS 2 +#define SCTP_IPV6_ADDRESS 4 + +/* timer types */ +#define SctpTimerTypeNone 0 +#define SctpTimerTypeSend 1 +#define SctpTimerTypeInit 2 +#define SctpTimerTypeRecv 3 +#define SctpTimerTypeShutdown 4 +#define SctpTimerTypeHeartbeat 5 +#define SctpTimerTypeCookie 6 +#define SctpTimerTypeNewCookie 7 +#define SctpTimerTypePathMtuRaise 8 +#define SctpTimerTypeShutdownAck 9 +#define SctpTimerTypeRelReq 10 + +/* Here are the timer directives given to the + * user provided function + */ +#define SCTP_TIMER_START 1 +#define SCTP_TIMER_STOP 2 + +/* running flag states in timer structure */ +#define SCTP_TIMER_IDLE 0x0 +#define SCTP_TIMER_EXPIRED 0x1 +#define SCTP_TIMER_RUNNING 0x2 + + +/* number of simultaneous timers running */ +#define SCTP_MAX_NET_TIMERS 6 /* base of where net timers start */ +#define SCTP_NUMBER_TIMERS 12 /* allows up to 6 destinations */ + + +/* Of course we really don't collect stale cookies, being + * folks of decerning taste. However we do count them, if + * we get to many before the association comes up.. we + * give up. Below is the constant that dictates when + * we give it up...this is a implemenation dependant + * treatment. In ours we do not ask for a extension of + * time, but just retry this many times... + */ +#define SCTP_MAX_STALE_COOKIES_I_COLLECT 10 + +/* max number of TSN's dup'd that I will hold */ +#define SCTP_MAX_DUP_TSNS 20 + +/* Here we define the types used when + * setting the retry ammounts. + */ +/* constants for type of set */ +#define SCTP_MAXATTEMPT_INIT 2 +#define SCTP_MAXATTEMPT_SEND 3 + +/* Here we define the default timers and the + * default number of attemts we make for + * each respective side (send/init). + */ + +/* init timer def = 3sec */ +#define SCTP_INIT_SEC 3 +#define SCTP_INIT_NSEC 0 + +/* send timer def = 3 seconds */ +#define SCTP_SEND_SEC 1 +#define SCTP_SEND_NSEC 0 + +/* recv timer def = 200ms (in nsec) */ +#define SCTP_RECV_SEC 0 +#define SCTP_RECV_NSEC 200000000 + +/* 30 seconds + RTO */ +#define SCTP_HB_SEC 30 +#define SCTP_HB_NSEC 0 + + +/* 300 ms */ +#define SCTP_SHUTDOWN_SEC 0 +#define SCTP_SHUTDOWN_NSEC 300000000 + +#define SCTP_RTO_UPPER_BOUND 60000000 /* 60 sec in micro-second's */ +#define SCTP_RTO_UPPER_BOUND_SEC 60 /* for the init timer */ +#define SCTP_RTO_LOWER_BOUND 1000000 /* 1 sec in micro-sec's */ + +#define SCTP_DEF_MAX_INIT 8 +#define SCTP_DEF_MAX_SEND 10 + +#define SCTP_DEF_PMTU_RAISE 600 /* 10 Minutes between raise attempts */ +#define SCTP_DEF_PMTU_MIN 600 + +#define SCTP_MSEC_IN_A_SEC 1000 +#define SCTP_USEC_IN_A_SEC 1000000 +#define SCTP_NSEC_IN_A_SEC 1000000000 + + +/* Events that SCTP will look for, these + * are or'd together to declare what SCTP + * wants. Each select mask/poll list should be + * set for the fd, if the bit is on. + */ +#define SCTP_EVENT_READ 0x000001 +#define SCTP_EVENT_WRITE 0x000002 +#define SCTP_EVENT_EXCEPT 0x000004 + +/* The following constant is a value for this + * particular implemenation. It is quite arbitrary and + * is used to limit how much data will be queued up to + * a sender, waiting for cwnd to be larger than flightSize. + * All implementations will need this protection is some + * way due to buffer size constraints. + */ + +#define SCTP_MAX_OUTSTANDING_DG 10000 + + + +/* This constant (SCTP_MAX_READBUFFER) define + * how big the read/write buffer is + * when we enter the fd event notification + * the buffer is put on the stack, so the bigger + * it is the more stack you chew up, however it + * has got to be big enough to handle the bigest + * message this O/S will send you. In solaris + * with sockets (not TLI) we end up at a value + * of 64k. In TLI we could do partial reads to + * get it all in with less hassel.. but we + * write to sockets for generality. + */ +#define SCTP_MAX_READBUFFER 65536 +#define SCTP_ADDRMAX 60 + +/* amount peer is obligated to have in rwnd or + * I will abort + */ +#define SCTP_MIN_RWND 1500 + +#define SCTP_WINDOW_MIN 1500 /* smallest rwnd can be */ +#define SCTP_WINDOW_MAX 1048576 /* biggest I can grow rwnd to + * My playing around suggests a + * value greater than 64k does not + * do much, I guess via the kernel + * limitations on the stream/socket. + */ + +#define SCTP_MAX_BUNDLE_UP 256 /* max number of chunks I can bundle */ + +/* I can handle a 1meg re-assembly */ +#define SCTP_DEFAULT_MAXMSGREASM 1048576 + + +#define SCTP_DEFAULT_MAXWINDOW 32768 /* default rwnd size */ +#define SCTP_DEFAULT_MAXSEGMENT 1500 /* MTU size, this is the default + * to which we set the smallestMTU + * size to. This governs what is the + * largest size we will use, of course + * PMTU will raise this up to + * the largest interface MTU or the + * ceiling below if there is no + * SIOCGIFMTU. + */ +#ifdef LYNX +#define DEFAULT_MTU_CEILING 1500 /* Since Lynx O/S is brain dead + * in the way it handles the + * raw IP socket, insisting + * on makeing its own IP + * header, we limit the growth + * to that of the e-net size + */ +#else +#define DEFAULT_MTU_CEILING 2048 /* If no SIOCGIFMTU, highest value + * to raise the PMTU to, i.e. + * don't try to raise above this + * value. Tune this per your + * largest MTU interface if your + * system does not support the + * SIOCGIFMTU ioctl. + */ +#endif +#define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */ +#define SCTP_HOW_MANY_SECRETS 2 /* how many secrets I keep */ +/* This is how long a secret lives, NOT how long a cookie lives */ +#define SCTP_HOW_LONG_COOKIE_LIVE 3600 /* how many seconds the current secret will live */ + +#define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */ +#define SCTP_SECRET_SIZE 32 /* number of octets in a 256 bits */ + +#ifdef USE_MD5 +#define SCTP_SIGNATURE_SIZE 16 /* size of a MD5 signature */ +#else +#define SCTP_SIGNATURE_SIZE 20 /* size of a SLA-1 signature */ +#endif +/* Here are the notification constants + * that the code and upper layer will get + */ + +/* association is up */ +#define SCTP_NOTIFY_ASSOC_UP 1 + +/* association is down */ +#define SCTP_NOTIFY_ASSOC_DOWN 2 + +/* interface on a association is down + * and out of consideration for selection. + */ +#define SCTP_NOTIFY_INTF_DOWN 3 + +/* interface on a association is up + * and now back in consideration for selection. + */ +#define SCTP_NOTIFY_INTF_UP 4 + +/* The given datagram cannot be delivered + * to the peer, this will probably be followed + * by a SCTP_NOTFIY_ASSOC_DOWN. + */ +#define SCTP_NOTIFY_DG_FAIL 5 + +/* Sent dg on non-open stream extreme code error! + */ +#define SCTP_NOTIFY_STRDATA_ERR 6 + +#define SCTP_NOTIFY_ASSOC_ABORTED 7 + +/* The stream ones are not used yet, but could + * be when a association opens. + */ +#define SCTP_NOTIFY_PEER_OPENED_STR 8 +#define SCTP_NOTIFY_STREAM_OPENED_OK 9 + +/* association sees a restart event */ +#define SCTP_NOTIFY_ASSOC_RESTART 10 + +/* a user requested HB returned */ +#define SCTP_NOTIFY_HB_RESP 11 + +/* a result from a REL-REQ */ +#define SCTP_NOTIFY_RELREQ_RESULT_OK 12 +#define SCTP_NOTIFY_RELREQ_RESULT_FAILED 13 + +/* clock variance is 10ms or 10,000 us's */ +#define SCTP_CLOCK_GRAINULARITY 10000 + +#define IP_HDR_SIZE 40 /* we use the size of a IP6 header here + * this detracts a small amount for ipv4 + * but it simplifies the ipv6 addition + */ + +#define SCTP_NUM_FDS 3 + +/* raw IP filedescriptor */ +#define SCTP_FD_IP 0 +/* raw ICMP filedescriptor */ +#define SCTP_FD_ICMP 1 +/* processes contact me for requests here */ +#define SCTP_REQUEST 2 + + +#define SCTP_DEAMON_PORT 9899 + +/* Deamon registration message types/responses */ +#define DEAMON_REGISTER 0x01 +#define DEAMON_REGISTER_ACK 0x02 +#define DEAMON_DEREGISTER 0x03 +#define DEAMON_DEREGISTER_ACK 0x04 +#define DEAMON_CHECKADDR_LIST 0x05 + +#define DEAMON_MAGIC_VER_LEN 0xff + +/* max times I will attempt to send a message to deamon */ +#define SCTP_MAX_ATTEMPTS_AT_DEAMON 5 +#define SCTP_TIMEOUT_IN_POLL_FOR_DEAMON 1500 /* 1.5 seconds */ + +/* modular comparison */ +/* True if a > b (mod = M) */ +#define compare_with_wrap(a, b, M) ((a > b) && ((a - b) < (M >> 1))) || \ + ((b > a) && ((b - a) > (M >> 1))) + +#ifndef TIMEVAL_TO_TIMESPEC +#define TIMEVAL_TO_TIMESPEC(tv, ts) \ +{ \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ +} +#endif + +/* pegs */ +#define SCTP_NUMBER_OF_PEGS 21 +/* peg index's */ +#define SCTP_PEG_SACKS_SEEN 0 +#define SCTP_PEG_SACKS_SENT 1 +#define SCTP_PEG_TSNS_SENT 2 +#define SCTP_PEG_TSNS_RCVD 3 +#define SCTP_DATAGRAMS_SENT 4 +#define SCTP_DATAGRAMS_RCVD 5 +#define SCTP_RETRANTSN_SENT 6 +#define SCTP_DUPTSN_RECVD 7 +#define SCTP_HBR_RECV 8 +#define SCTP_HBA_RECV 9 +#define SCTP_HB_SENT 10 +#define SCTP_DATA_DG_SENT 11 +#define SCTP_DATA_DG_RECV 12 +#define SCTP_TMIT_TIMER 13 +#define SCTP_RECV_TIMER 14 +#define SCTP_HB_TIMER 15 +#define SCTP_FAST_RETRAN 16 +#define SCTP_PEG_TSNS_READ 17 +#define SCTP_NONE_LFT_TO 18 +#define SCTP_NONE_LFT_RWND 19 +#define SCTP_NONE_LFT_CWND 20 + + + +#endif + diff --git a/freebsd/contrib/tcpdump/sctpHeader.h b/freebsd/contrib/tcpdump/sctpHeader.h new file mode 100644 index 00000000..63f30b5d --- /dev/null +++ b/freebsd/contrib/tcpdump/sctpHeader.h @@ -0,0 +1,323 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/sctpHeader.h,v 1.6 2002-12-11 07:14:11 guy Exp $ (LBL) */ + +/* SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola + * + * 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. + * + * 4. Neither the name of Cisco nor of Motorola 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. + * + * This file is part of the SCTP reference Implementation + * + * + * Please send any bug reports or fixes you make to one of the following email + * addresses: + * + * rstewar1@email.mot.com + * kmorneau@cisco.com + * qxie1@email.mot.com + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorperated into the next SCTP release. + */ + + +#ifndef __sctpHeader_h__ +#define __sctpHeader_h__ + +#include <sctpConstants.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* the sctp common header */ + +#ifdef TRU64 + #define _64BITS 1 +#endif + +struct sctpHeader{ + u_int16_t source; + u_int16_t destination; + u_int32_t verificationTag; + u_int32_t adler32; +}; + +/* various descriptor parsers */ + +struct sctpChunkDesc{ + u_int8_t chunkID; + u_int8_t chunkFlg; + u_int16_t chunkLength; +}; + +struct sctpParamDesc{ + u_int16_t paramType; + u_int16_t paramLength; +}; + + +struct sctpRelChunkDesc{ + struct sctpChunkDesc chk; + u_int32_t serialNumber; +}; + +struct sctpVendorSpecificParam { + struct sctpParamDesc p; /* type must be 0xfffe */ + u_int32_t vendorId; /* vendor ID from RFC 1700 */ + u_int16_t vendorSpecificType; + u_int16_t vendorSpecificLen; +}; + + +/* Structures for the control parts */ + + + +/* Sctp association init request/ack */ + +/* this is used for init ack, too */ +struct sctpInitiation{ + u_int32_t initTag; /* tag of mine */ + u_int32_t rcvWindowCredit; /* rwnd */ + u_int16_t NumPreopenStreams; /* OS */ + u_int16_t MaxInboundStreams; /* MIS */ + u_int32_t initialTSN; + /* optional param's follow in sctpParamDesc form */ +}; + +struct sctpV4IpAddress{ + struct sctpParamDesc p; /* type is set to SCTP_IPV4_PARAM_TYPE, len=10 */ + u_int32_t ipAddress; +}; + + +struct sctpV6IpAddress{ + struct sctpParamDesc p; /* type is set to SCTP_IPV6_PARAM_TYPE, len=22 */ + u_int8_t ipAddress[16]; +}; + +struct sctpDNSName{ + struct sctpParamDesc param; + u_int8_t name[1]; +}; + + +struct sctpCookiePreserve{ + struct sctpParamDesc p; /* type is set to SCTP_COOKIE_PRESERVE, len=8 */ + u_int32_t extraTime; +}; + + +struct sctpTimeStamp{ + u_int32_t ts_sec; + u_int32_t ts_usec; +}; + +/* wire structure of my cookie */ +struct cookieMessage{ + u_int32_t TieTag_curTag; /* copied from assoc if present */ + u_int32_t TieTag_hisTag; /* copied from assoc if present */ + int32_t cookieLife; /* life I will award this cookie */ + struct sctpTimeStamp timeEnteringState; /* the time I built cookie */ + struct sctpInitiation initAckISent; /* the INIT-ACK that I sent to my peer */ + u_int32_t addressWhereISent[4]; /* I make this 4 ints so I get 128bits for future */ + int32_t addrtype; /* address type */ + u_int16_t locScope; /* V6 local scope flag */ + u_int16_t siteScope; /* V6 site scope flag */ + /* at the end is tacked on the INIT chunk sent in + * its entirety and of course our + * signature. + */ +}; + + +/* this guy is for use when + * I have a initiate message gloming the + * things together. + + */ +struct sctpUnifiedInit{ + struct sctpChunkDesc uh; + struct sctpInitiation initm; +}; + +struct sctpSendableInit{ + struct sctpHeader mh; + struct sctpUnifiedInit msg; +}; + + +/* Selective Acknowledgement + * has the following structure with + * a optional ammount of trailing int's + * on the last part (based on the numberOfDesc + * field). + */ + +struct sctpSelectiveAck{ + u_int32_t highestConseqTSN; + u_int32_t updatedRwnd; + u_int16_t numberOfdesc; + u_int16_t numDupTsns; +}; + +struct sctpSelectiveFrag{ + u_int16_t fragmentStart; + u_int16_t fragmentEnd; +}; + + +struct sctpUnifiedSack{ + struct sctpChunkDesc uh; + struct sctpSelectiveAck sack; +}; + +/* for both RTT request/response the + * following is sent + */ + +struct sctpHBrequest { + u_int32_t time_value_1; + u_int32_t time_value_2; +}; + +/* here is what I read and respond with to. */ +struct sctpHBunified{ + struct sctpChunkDesc hdr; + struct sctpParamDesc hb; +}; + + +/* here is what I send */ +struct sctpHBsender{ + struct sctpChunkDesc hdr; + struct sctpParamDesc hb; + struct sctpHBrequest rtt; + int8_t addrFmt[SCTP_ADDRMAX]; + u_int16_t userreq; +}; + + + +/* for the abort and shutdown ACK + * we must carry the init tag in the common header. Just the + * common header is all that is needed with a chunk descriptor. + */ +struct sctpUnifiedAbort{ + struct sctpChunkDesc uh; +}; + +struct sctpUnifiedAbortLight{ + struct sctpHeader mh; + struct sctpChunkDesc uh; +}; + +struct sctpUnifiedAbortHeavy{ + struct sctpHeader mh; + struct sctpChunkDesc uh; + u_int16_t causeCode; + u_int16_t causeLen; +}; + +/* For the graceful shutdown we must carry + * the tag (in common header) and the highest consequitive acking value + */ +struct sctpShutdown { + u_int32_t TSN_Seen; +}; + +struct sctpUnifiedShutdown{ + struct sctpChunkDesc uh; + struct sctpShutdown shut; +}; + +/* in the unified message we add the trailing + * stream id since it is the only message + * that is defined as a operation error. + */ +struct sctpOpErrorCause{ + u_int16_t cause; + u_int16_t causeLen; +}; + +struct sctpUnifiedOpError{ + struct sctpChunkDesc uh; + struct sctpOpErrorCause c; +}; + +struct sctpUnifiedStreamError{ + struct sctpHeader mh; + struct sctpChunkDesc uh; + struct sctpOpErrorCause c; + u_int16_t strmNum; + u_int16_t reserved; +}; + +struct staleCookieMsg{ + struct sctpHeader mh; + struct sctpChunkDesc uh; + struct sctpOpErrorCause c; + u_int32_t moretime; +}; + +/* the following is used in all sends + * where nothing is needed except the + * chunk/type i.e. shutdownAck Abort */ + +struct sctpUnifiedSingleMsg{ + struct sctpHeader mh; + struct sctpChunkDesc uh; +}; + +struct sctpDataPart{ + u_int32_t TSN; + u_int16_t streamId; + u_int16_t sequence; + u_int32_t payloadtype; +}; + +struct sctpUnifiedDatagram{ + struct sctpChunkDesc uh; + struct sctpDataPart dp; +}; + +struct sctpECN_echo{ + struct sctpChunkDesc uh; + u_int32_t Lowest_TSN; +}; + + +struct sctpCWR{ + struct sctpChunkDesc uh; + u_int32_t TSN_reduced_at; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/freebsd/contrib/tcpdump/setsignal.c b/freebsd/contrib/tcpdump/setsignal.c new file mode 100644 index 00000000..7a9d08e0 --- /dev/null +++ b/freebsd/contrib/tcpdump/setsignal.c @@ -0,0 +1,95 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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/setsignal.c,v 1.11 2003-11-16 09:36:42 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <signal.h> +#ifdef HAVE_SIGACTION +#include <string.h> +#endif + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#include "setsignal.h" + +/* + * An OS-independent signal() with, whenever possible, partial BSD + * semantics, i.e. the signal handler is restored following service + * of the signal, but system calls are *not* restarted, so that if + * "pcap_breakloop()" is called in a signal handler in a live capture, + * the read/recvfrom/whatever in the live capture doesn't get restarted, + * it returns -1 and sets "errno" to EINTR, so we can break out of the + * live capture loop. + * + * We use "sigaction()" if available. We don't specify that the signal + * should restart system calls, so that should always do what we want. + * + * Otherwise, if "sigset()" is available, it probably has BSD semantics + * while "signal()" has traditional semantics, so we use "sigset()"; it + * might cause system calls to be restarted for the signal, however. + * I don't know whether, in any systems where it did cause system calls to + * be restarted, there was a way to ask it not to do so; there may no + * longer be any interesting systems without "sigaction()", however, + * and, if there are, they might have "sigvec()" with SV_INTERRUPT + * (which I think first appeared in 4.3BSD). + * + * Otherwise, we use "signal()" - which means we might get traditional + * semantics, wherein system calls don't get restarted *but* the + * signal handler is reset to SIG_DFL and the signal is not blocked, + * so that a subsequent signal would kill the process immediately. + * + * Did I mention that signals suck? At least in POSIX-compliant systems + * they suck far less, as those systems have "sigaction()". + */ +RETSIGTYPE +(*setsignal (int sig, RETSIGTYPE (*func)(int)))(int) +{ +#ifdef HAVE_SIGACTION + struct sigaction old, new; + + memset(&new, 0, sizeof(new)); + new.sa_handler = func; + if (sigaction(sig, &new, &old) < 0) + return (SIG_ERR); + return (old.sa_handler); + +#else +#ifdef HAVE_SIGSET + return (sigset(sig, func)); +#else + return (signal(sig, func)); +#endif +#endif +} + diff --git a/freebsd/contrib/tcpdump/setsignal.h b/freebsd/contrib/tcpdump/setsignal.h new file mode 100644 index 00000000..984c3407 --- /dev/null +++ b/freebsd/contrib/tcpdump/setsignal.h @@ -0,0 +1,27 @@ +/* + * 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. + * + * @(#) $Header: /tcpdump/master/tcpdump/setsignal.h,v 1.2 1999-10-07 23:47:13 mcr Exp $ (LBL) + */ +#ifndef setsignal_h +#define setsignal_h + +RETSIGTYPE (*setsignal(int, RETSIGTYPE (*)(int)))(int); +#endif diff --git a/freebsd/contrib/tcpdump/signature.c b/freebsd/contrib/tcpdump/signature.c new file mode 100644 index 00000000..373b33a0 --- /dev/null +++ b/freebsd/contrib/tcpdump/signature.c @@ -0,0 +1,161 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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. + * + * Functions for signature and digest verification. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/signature.c,v 1.2 2008-09-22 20:22:10 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tcpdump-stdinc.h> + +#include <string.h> + +#include "interface.h" +#include "signature.h" + +#ifdef HAVE_LIBCRYPTO +#include <openssl/md5.h> +#endif + +const struct tok signature_check_values[] = { + { SIGNATURE_VALID, "valid"}, + { SIGNATURE_INVALID, "invalid"}, + { CANT_CHECK_SIGNATURE, "unchecked"}, + { 0, NULL } +}; + + +#ifdef HAVE_LIBCRYPTO +/* + * Compute a HMAC MD5 sum. + * Taken from rfc2104, Appendix. + */ +static void +signature_compute_hmac_md5(const u_int8_t *text, int text_len, unsigned char *key, + unsigned int key_len, u_int8_t *digest) +{ + MD5_CTX context; + unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ + unsigned char k_opad[65]; /* outer padding - key XORd with opad */ + unsigned char tk[16]; + int i; + + /* if key is longer than 64 bytes reset it to key=MD5(key) */ + if (key_len > 64) { + + MD5_CTX tctx; + + MD5_Init(&tctx); + MD5_Update(&tctx, key, key_len); + MD5_Final(tk, &tctx); + + key = tk; + key_len = 16; + } + + /* + * the HMAC_MD5 transform looks like: + * + * MD5(K XOR opad, MD5(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected + */ + + /* start out by storing key in pads */ + memset(k_ipad, 0, sizeof k_ipad); + memset(k_opad, 0, sizeof k_opad); + memcpy(k_ipad, key, key_len); + memcpy(k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i<64; i++) { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + + /* + * perform inner MD5 + */ + MD5_Init(&context); /* init context for 1st pass */ + MD5_Update(&context, k_ipad, 64); /* start with inner pad */ + MD5_Update(&context, text, text_len); /* then text of datagram */ + MD5_Final(digest, &context); /* finish up 1st pass */ + + /* + * perform outer MD5 + */ + MD5_Init(&context); /* init context for 2nd pass */ + MD5_Update(&context, k_opad, 64); /* start with outer pad */ + MD5_Update(&context, digest, 16); /* then results of 1st hash */ + MD5_Final(digest, &context); /* finish up 2nd pass */ +} +#endif + +#ifdef HAVE_LIBCRYPTO +/* + * Verify a cryptographic signature of the packet. + * Currently only MD5 is supported. + */ +int +signature_verify (const u_char *pptr, u_int plen, u_char *sig_ptr) +{ + u_int8_t rcvsig[16]; + u_int8_t sig[16]; + unsigned int i; + + /* + * Save the signature before clearing it. + */ + memcpy(rcvsig, sig_ptr, sizeof(rcvsig)); + memset(sig_ptr, 0, sizeof(rcvsig)); + + if (!sigsecret) { + return (CANT_CHECK_SIGNATURE); + } + + signature_compute_hmac_md5(pptr, plen, (unsigned char *)sigsecret, + strlen(sigsecret), sig); + + if (memcmp(rcvsig, sig, sizeof(sig)) == 0) { + return (SIGNATURE_VALID); + + } else { + + for (i = 0; i < sizeof(sig); ++i) { + (void)printf("%02x", sig[i]); + } + + return (SIGNATURE_INVALID); + } +} +#endif + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/freebsd/contrib/tcpdump/signature.h b/freebsd/contrib/tcpdump/signature.h new file mode 100644 index 00000000..e48b7229 --- /dev/null +++ b/freebsd/contrib/tcpdump/signature.h @@ -0,0 +1,26 @@ +/* + * 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. + * + * Functions for signature and digest verification. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +/* @(#) $Header: /tcpdump/master/tcpdump/signature.h,v 1.1 2008-08-16 11:36:20 hannes Exp $ (LBL) */ + +/* signature checking result codes */ +#define SIGNATURE_VALID 0 +#define SIGNATURE_INVALID 1 +#define CANT_CHECK_SIGNATURE 2 + +extern const struct tok signature_check_values[]; +extern int signature_verify (const u_char *, u_int, u_char *); diff --git a/freebsd/contrib/tcpdump/slcompress.h b/freebsd/contrib/tcpdump/slcompress.h new file mode 100644 index 00000000..d10243a9 --- /dev/null +++ b/freebsd/contrib/tcpdump/slcompress.h @@ -0,0 +1,87 @@ +/* + * Definitions for tcp compression routines. + * + * @(#) $Header: /tcpdump/master/tcpdump/slcompress.h,v 1.2 2000-10-09 02:03:44 guy Exp $ (LBL) + * + * Copyright (c) 1989, 1990, 1992, 1993 Regents of the University of + * California. All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + */ + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowlegement, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + +/* packet types */ +#define TYPE_IP 0x40 +#define TYPE_UNCOMPRESSED_TCP 0x70 +#define TYPE_COMPRESSED_TCP 0x80 +#define TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 diff --git a/freebsd/contrib/tcpdump/slip.h b/freebsd/contrib/tcpdump/slip.h new file mode 100644 index 00000000..aa6402c3 --- /dev/null +++ b/freebsd/contrib/tcpdump/slip.h @@ -0,0 +1,34 @@ +/* + * Definitions that user level programs might need to know to interact + * with serial line IP (slip) lines. + * + * @(#) $Header: /tcpdump/master/tcpdump/slip.h,v 1.1 2000-10-09 01:53:21 guy Exp $ + * + * Copyright (c) 1990 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * definitions of the pseudo- link-level header attached to slip + * packets grabbed by the packet filter (bpf) traffic monitor. + */ +#define SLIP_HDRLEN 16 + +#define SLX_DIR 0 +#define SLX_CHDR 1 +#define CHDR_LEN 15 + +#define SLIPDIR_IN 0 +#define SLIPDIR_OUT 1 diff --git a/freebsd/contrib/tcpdump/sll.h b/freebsd/contrib/tcpdump/sll.h new file mode 100644 index 00000000..0a34963a --- /dev/null +++ b/freebsd/contrib/tcpdump/sll.h @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * 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. + * + * @(#) $Header: /tcpdump/master/tcpdump/sll.h,v 1.8 2008-05-30 01:37:41 guy Exp $ (LBL) + */ + +/* + * For captures on Linux cooked sockets, we construct a fake header + * that includes: + * + * a 2-byte "packet type" which is one of: + * + * LINUX_SLL_HOST packet was sent to us + * LINUX_SLL_BROADCAST packet was broadcast + * LINUX_SLL_MULTICAST packet was multicast + * LINUX_SLL_OTHERHOST packet was sent to somebody else + * LINUX_SLL_OUTGOING packet was sent *by* us; + * + * a 2-byte Ethernet protocol field; + * + * a 2-byte link-layer type; + * + * a 2-byte link-layer address length; + * + * an 8-byte source link-layer address, whose actual length is + * specified by the previous value. + * + * All fields except for the link-layer address are in network byte order. + * + * DO NOT change the layout of this structure, or change any of the + * LINUX_SLL_ values below. If you must change the link-layer header + * for a "cooked" Linux capture, introduce a new DLT_ type (ask + * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it + * a value that collides with a value already being used), and use the + * new header in captures of that type, so that programs that can + * handle DLT_LINUX_SLL captures will continue to handle them correctly + * without any change, and so that capture files with different headers + * can be told apart and programs that read them can dissect the + * packets in them. + * + * This structure, and the #defines below, must be the same in the + * libpcap and tcpdump versions of "sll.h". + */ + +/* + * A DLT_LINUX_SLL fake link-layer header. + */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ + +struct sll_header { + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ +}; + +/* + * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the + * PACKET_ values on Linux, but are defined here so that they're + * available even on systems other than Linux, and so that they + * don't change even if the PACKET_ values change. + */ +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 + +/* + * The LINUX_SLL_ values for "sll_protocol"; these correspond to the + * ETH_P_ values on Linux, but are defined here so that they're + * available even on systems other than Linux. We assume, for now, + * that the ETH_P_ values won't change in Linux; if they do, then: + * + * if we don't translate them in "pcap-linux.c", capture files + * won't necessarily be readable if captured on a system that + * defines ETH_P_ values that don't match these values; + * + * if we do translate them in "pcap-linux.c", that makes life + * unpleasant for the BPF code generator, as the values you test + * for in the kernel aren't the values that you test for when + * reading a capture file, so the fixup code run on BPF programs + * handed to the kernel ends up having to do more work. + * + * Add other values here as necessary, for handling packet types that + * might show up on non-Ethernet, non-802.x networks. (Not all the ones + * in the Linux "if_ether.h" will, I suspect, actually show up in + * captures.) + */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ diff --git a/freebsd/contrib/tcpdump/smb.h b/freebsd/contrib/tcpdump/smb.h new file mode 100644 index 00000000..8eeb303f --- /dev/null +++ b/freebsd/contrib/tcpdump/smb.h @@ -0,0 +1,122 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/smb.h,v 1.9 2004-12-28 22:29:44 guy Exp $ (LBL) */ +/* + * Copyright (C) Andrew Tridgell 1995-1999 + * + * This software may be distributed either under the terms of the + * BSD-style license that accompanies tcpdump or the GNU GPL version 2 + * or later + */ + +#define SMBMIN(a,b) ((a)<(b)?(a):(b)) + +/* the complete */ +#define SMBmkdir 0x00 /* create directory */ +#define SMBrmdir 0x01 /* delete directory */ +#define SMBopen 0x02 /* open file */ +#define SMBcreate 0x03 /* create file */ +#define SMBclose 0x04 /* close file */ +#define SMBflush 0x05 /* flush file */ +#define SMBunlink 0x06 /* delete file */ +#define SMBmv 0x07 /* rename file */ +#define SMBgetatr 0x08 /* get file attributes */ +#define SMBsetatr 0x09 /* set file attributes */ +#define SMBread 0x0A /* read from file */ +#define SMBwrite 0x0B /* write to file */ +#define SMBlock 0x0C /* lock byte range */ +#define SMBunlock 0x0D /* unlock byte range */ +#define SMBctemp 0x0E /* create temporary file */ +#define SMBmknew 0x0F /* make new file */ +#define SMBchkpth 0x10 /* check directory path */ +#define SMBexit 0x11 /* process exit */ +#define SMBlseek 0x12 /* seek */ +#define SMBtcon 0x70 /* tree connect */ +#define SMBtconX 0x75 /* tree connect and X*/ +#define SMBtdis 0x71 /* tree disconnect */ +#define SMBnegprot 0x72 /* negotiate protocol */ +#define SMBdskattr 0x80 /* get disk attributes */ +#define SMBsearch 0x81 /* search directory */ +#define SMBsplopen 0xC0 /* open print spool file */ +#define SMBsplwr 0xC1 /* write to print spool file */ +#define SMBsplclose 0xC2 /* close print spool file */ +#define SMBsplretq 0xC3 /* return print queue */ +#define SMBsends 0xD0 /* send single block message */ +#define SMBsendb 0xD1 /* send broadcast message */ +#define SMBfwdname 0xD2 /* forward user name */ +#define SMBcancelf 0xD3 /* cancel forward */ +#define SMBgetmac 0xD4 /* get machine name */ +#define SMBsendstrt 0xD5 /* send start of multi-block message */ +#define SMBsendend 0xD6 /* send end of multi-block message */ +#define SMBsendtxt 0xD7 /* send text of multi-block message */ + +/* Core+ protocol */ +#define SMBlockread 0x13 /* Lock a range and read */ +#define SMBwriteunlock 0x14 /* Unlock a range then write */ +#define SMBreadbraw 0x1a /* read a block of data with no smb header */ +#define SMBwritebraw 0x1d /* write a block of data with no smb header */ +#define SMBwritec 0x20 /* secondary write request */ +#define SMBwriteclose 0x2c /* write a file then close it */ + +/* dos extended protocol */ +#define SMBreadBraw 0x1A /* read block raw */ +#define SMBreadBmpx 0x1B /* read block multiplexed */ +#define SMBreadBs 0x1C /* read block (secondary response) */ +#define SMBwriteBraw 0x1D /* write block raw */ +#define SMBwriteBmpx 0x1E /* write block multiplexed */ +#define SMBwriteBs 0x1F /* write block (secondary request) */ +#define SMBwriteC 0x20 /* write complete response */ +#define SMBsetattrE 0x22 /* set file attributes expanded */ +#define SMBgetattrE 0x23 /* get file attributes expanded */ +#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */ +#define SMBtrans 0x25 /* transaction - name, bytes in/out */ +#define SMBtranss 0x26 /* transaction (secondary request/response) */ +#define SMBioctl 0x27 /* IOCTL */ +#define SMBioctls 0x28 /* IOCTL (secondary request/response) */ +#define SMBcopy 0x29 /* copy */ +#define SMBmove 0x2A /* move */ +#define SMBecho 0x2B /* echo */ +#define SMBopenX 0x2D /* open and X */ +#define SMBreadX 0x2E /* read and X */ +#define SMBwriteX 0x2F /* write and X */ +#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */ +#define SMBffirst 0x82 /* find first */ +#define SMBfunique 0x83 /* find unique */ +#define SMBfclose 0x84 /* find close */ +#define SMBinvalid 0xFE /* invalid command */ + +/* Extended 2.0 protocol */ +#define SMBtrans2 0x32 /* TRANS2 protocol set */ +#define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */ +#define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */ +#define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */ +#define SMBulogoffX 0x74 /* user logoff */ + +/* NT SMB extensions. */ +#define SMBnttrans 0xA0 /* NT transact */ +#define SMBnttranss 0xA1 /* NT transact secondary */ +#define SMBntcreateX 0xA2 /* NT create and X */ +#define SMBntcancel 0xA4 /* NT cancel */ + +/* pathworks special */ +#define pSETDIR '\377' + + +/* these are the TRANS2 sub commands */ +#define TRANSACT2_OPEN 0 +#define TRANSACT2_FINDFIRST 1 +#define TRANSACT2_FINDNEXT 2 +#define TRANSACT2_QFSINFO 3 +#define TRANSACT2_SETFSINFO 4 +#define TRANSACT2_QPATHINFO 5 +#define TRANSACT2_SETPATHINFO 6 +#define TRANSACT2_QFILEINFO 7 +#define TRANSACT2_SETFILEINFO 8 +#define TRANSACT2_FSCTL 9 +#define TRANSACT2_IOCTL 10 +#define TRANSACT2_FINDNOTIFYFIRST 11 +#define TRANSACT2_FINDNOTIFYNEXT 12 +#define TRANSACT2_MKDIR 13 + +#define PTR_DIFF(p1, p2) ((size_t)(((char *)(p1)) - (char *)(p2))) + +/* some protos */ +const u_char *smb_fdata(const u_char *, const char *, const u_char *, int); diff --git a/freebsd/contrib/tcpdump/smbutil.c b/freebsd/contrib/tcpdump/smbutil.c new file mode 100644 index 00000000..e27f280b --- /dev/null +++ b/freebsd/contrib/tcpdump/smbutil.c @@ -0,0 +1,1891 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (C) Andrew Tridgell 1995-1999 + * + * This software may be distributed either under the terms of the + * BSD-style license that accompanies tcpdump or the GNU GPL version 2 + * or later + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.39 2007-07-15 19:07:39 guy Exp $"; +#endif + +#include <tcpdump-stdinc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "interface.h" +#include "extract.h" +#include "smb.h" + +static u_int32_t stringlen; +extern const u_char *startbuf; + +/* + * interpret a 32 bit dos packed date/time to some parameters + */ +static void +interpret_dos_date(u_int32_t date, struct tm *tp) +{ + u_int32_t p0, p1, p2, p3; + + p0 = date & 0xFF; + p1 = ((date & 0xFF00) >> 8) & 0xFF; + p2 = ((date & 0xFF0000) >> 16) & 0xFF; + p3 = ((date & 0xFF000000) >> 24) & 0xFF; + + tp->tm_sec = 2 * (p0 & 0x1F); + tp->tm_min = ((p0 >> 5) & 0xFF) + ((p1 & 0x7) << 3); + tp->tm_hour = (p1 >> 3) & 0xFF; + tp->tm_mday = (p2 & 0x1F); + tp->tm_mon = ((p2 >> 5) & 0xFF) + ((p3 & 0x1) << 3) - 1; + tp->tm_year = ((p3 >> 1) & 0xFF) + 80; +} + +/* + * common portion: + * create a unix date from a dos date + */ +static time_t +int_unix_date(u_int32_t dos_date) +{ + struct tm t; + + if (dos_date == 0) + return(0); + + interpret_dos_date(dos_date, &t); + t.tm_wday = 1; + t.tm_yday = 1; + t.tm_isdst = 0; + + return (mktime(&t)); +} + +/* + * create a unix date from a dos date + * in network byte order + */ +static time_t +make_unix_date(const u_char *date_ptr) +{ + u_int32_t dos_date = 0; + + dos_date = EXTRACT_LE_32BITS(date_ptr); + + return int_unix_date(dos_date); +} + +/* + * create a unix date from a dos date + * in halfword-swapped network byte order! + */ +static time_t +make_unix_date2(const u_char *date_ptr) +{ + u_int32_t x, x2; + + x = EXTRACT_LE_32BITS(date_ptr); + x2 = ((x & 0xFFFF) << 16) | ((x & 0xFFFF0000) >> 16); + return int_unix_date(x2); +} + +/* + * interpret an 8 byte "filetime" structure to a time_t + * It's originally in "100ns units since jan 1st 1601" + */ +static time_t +interpret_long_date(const u_char *p) +{ + double d; + time_t ret; + + /* this gives us seconds since jan 1st 1601 (approx) */ + d = (EXTRACT_LE_32BITS(p + 4) * 256.0 + p[3]) * (1.0e-7 * (1 << 24)); + + /* now adjust by 369 years to make the secs since 1970 */ + d -= 369.0 * 365.25 * 24 * 60 * 60; + + /* and a fudge factor as we got it wrong by a few days */ + d += (3 * 24 * 60 * 60 + 6 * 60 * 60 + 2); + + if (d < 0) + return(0); + + ret = (time_t)d; + + return(ret); +} + +/* + * interpret the weird netbios "name". Return the name type, or -1 if + * we run past the end of the buffer + */ +static int +name_interpret(const u_char *in, const u_char *maxbuf, char *out) +{ + int ret; + int len; + + if (in >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + TCHECK2(*in, 1); + len = (*in++) / 2; + + *out=0; + + if (len > 30 || len < 1) + return(0); + + while (len--) { + TCHECK2(*in, 2); + if (in + 1 >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { + *out = 0; + return(0); + } + *out = ((in[0] - 'A') << 4) + (in[1] - 'A'); + in += 2; + out++; + } + *out = 0; + ret = out[-1]; + + return(ret); + +trunc: + return(-1); +} + +/* + * find a pointer to a netbios name + */ +static const u_char * +name_ptr(const u_char *buf, int ofs, const u_char *maxbuf) +{ + const u_char *p; + u_char c; + + p = buf + ofs; + if (p >= maxbuf) + return(NULL); /* name goes past the end of the buffer */ + TCHECK2(*p, 1); + + c = *p; + + /* XXX - this should use the same code that the DNS dissector does */ + if ((c & 0xC0) == 0xC0) { + u_int16_t l; + + TCHECK2(*p, 2); + if ((p + 1) >= maxbuf) + return(NULL); /* name goes past the end of the buffer */ + l = EXTRACT_16BITS(p) & 0x3FFF; + if (l == 0) { + /* We have a pointer that points to itself. */ + return(NULL); + } + p = buf + l; + if (p >= maxbuf) + return(NULL); /* name goes past the end of the buffer */ + TCHECK2(*p, 1); + } + return(p); + +trunc: + return(NULL); /* name goes past the end of the buffer */ +} + +/* + * extract a netbios name from a buf + */ +static int +name_extract(const u_char *buf, int ofs, const u_char *maxbuf, char *name) +{ + const u_char *p = name_ptr(buf, ofs, maxbuf); + if (p == NULL) + return(-1); /* error (probably name going past end of buffer) */ + name[0] = '\0'; + return(name_interpret(p, maxbuf, name)); +} + + +/* + * return the total storage length of a mangled name + */ +static int +name_len(const unsigned char *s, const unsigned char *maxbuf) +{ + const unsigned char *s0 = s; + unsigned char c; + + if (s >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + TCHECK2(*s, 1); + c = *s; + if ((c & 0xC0) == 0xC0) + return(2); + while (*s) { + if (s >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + TCHECK2(*s, 1); + s += (*s) + 1; + } + return(PTR_DIFF(s, s0) + 1); + +trunc: + return(-1); /* name goes past the end of the buffer */ +} + +static void +print_asc(const unsigned char *buf, int len) +{ + int i; + for (i = 0; i < len; i++) + safeputchar(buf[i]); +} + +static const char * +name_type_str(int name_type) +{ + const char *f = NULL; + + switch (name_type) { + case 0: f = "Workstation"; break; + case 0x03: f = "Client?"; break; + case 0x20: f = "Server"; break; + case 0x1d: f = "Master Browser"; break; + case 0x1b: f = "Domain Controller"; break; + case 0x1e: f = "Browser Server"; break; + default: f = "Unknown"; break; + } + return(f); +} + +void +print_data(const unsigned char *buf, int len) +{ + int i = 0; + + if (len <= 0) + return; + printf("[%03X] ", i); + for (i = 0; i < len; /*nothing*/) { + TCHECK(buf[i]); + printf("%02X ", buf[i] & 0xff); + i++; + if (i%8 == 0) + printf(" "); + if (i % 16 == 0) { + print_asc(&buf[i - 16], 8); + printf(" "); + print_asc(&buf[i - 8], 8); + printf("\n"); + if (i < len) + printf("[%03X] ", i); + } + } + if (i % 16) { + int n; + + n = 16 - (i % 16); + printf(" "); + if (n>8) + printf(" "); + while (n--) + printf(" "); + + n = SMBMIN(8, i % 16); + print_asc(&buf[i - (i % 16)], n); + printf(" "); + n = (i % 16) - n; + if (n > 0) + print_asc(&buf[i - n], n); + printf("\n"); + } + return; + +trunc: + printf("\n"); + printf("WARNING: Short packet. Try increasing the snap length\n"); +} + + +static void +write_bits(unsigned int val, const char *fmt) +{ + const char *p = fmt; + int i = 0; + + while ((p = strchr(fmt, '|'))) { + size_t l = PTR_DIFF(p, fmt); + if (l && (val & (1 << i))) + printf("%.*s ", (int)l, fmt); + fmt = p + 1; + i++; + } +} + +/* convert a UCS2 string into iso-8859-1 string */ +#define MAX_UNISTR_SIZE 1000 +static const char * +unistr(const u_char *s, u_int32_t *len, int use_unicode) +{ + static char buf[MAX_UNISTR_SIZE+1]; + size_t l = 0; + u_int32_t strsize; + const u_char *sp; + + if (use_unicode) { + /* + * Skip padding that puts the string on an even boundary. + */ + if (((s - startbuf) % 2) != 0) { + TCHECK(s[0]); + s++; + } + } + if (*len == 0) { + /* + * Null-terminated string. + */ + strsize = 0; + sp = s; + if (!use_unicode) { + for (;;) { + TCHECK(sp[0]); + *len += 1; + if (sp[0] == 0) + break; + sp++; + } + strsize = *len - 1; + } else { + for (;;) { + TCHECK2(sp[0], 2); + *len += 2; + if (sp[0] == 0 && sp[1] == 0) + break; + sp += 2; + } + strsize = *len - 2; + } + } else { + /* + * Counted string. + */ + strsize = *len; + } + if (!use_unicode) { + while (strsize != 0) { + TCHECK(s[0]); + if (l >= MAX_UNISTR_SIZE) + break; + if (isprint(s[0])) + buf[l] = s[0]; + else { + if (s[0] == 0) + break; + buf[l] = '.'; + } + l++; + s++; + strsize--; + } + } else { + while (strsize != 0) { + TCHECK2(s[0], 2); + if (l >= MAX_UNISTR_SIZE) + break; + if (s[1] == 0 && isprint(s[0])) { + /* It's a printable ASCII character */ + buf[l] = s[0]; + } else { + /* It's a non-ASCII character or a non-printable ASCII character */ + if (s[0] == 0 && s[1] == 0) + break; + buf[l] = '.'; + } + l++; + s += 2; + if (strsize == 1) + break; + strsize -= 2; + } + } + buf[l] = 0; + return buf; + +trunc: + return NULL; +} + +static const u_char * +smb_fdata1(const u_char *buf, const char *fmt, const u_char *maxbuf, + int unicodestr) +{ + int reverse = 0; + const char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|"; + + while (*fmt && buf<maxbuf) { + switch (*fmt) { + case 'a': + TCHECK(buf[0]); + write_bits(buf[0], attrib_fmt); + buf++; + fmt++; + break; + + case 'A': + TCHECK2(buf[0], 2); + write_bits(EXTRACT_LE_16BITS(buf), attrib_fmt); + buf += 2; + fmt++; + break; + + case '{': + { + char bitfmt[128]; + char *p; + int l; + + p = strchr(++fmt, '}'); + l = PTR_DIFF(p, fmt); + + if ((unsigned int)l > sizeof(bitfmt) - 1) + l = sizeof(bitfmt)-1; + + strncpy(bitfmt, fmt, l); + bitfmt[l] = '\0'; + fmt = p + 1; + TCHECK(buf[0]); + write_bits(buf[0], bitfmt); + buf++; + break; + } + + case 'P': + { + int l = atoi(fmt + 1); + TCHECK2(buf[0], l); + buf += l; + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + case 'r': + reverse = !reverse; + fmt++; + break; + case 'b': + { + unsigned int x; + TCHECK(buf[0]); + x = buf[0]; + printf("%u (0x%x)", x, x); + buf += 1; + fmt++; + break; + } + case 'd': + { + unsigned int x; + TCHECK2(buf[0], 2); + x = reverse ? EXTRACT_16BITS(buf) : + EXTRACT_LE_16BITS(buf); + printf("%d (0x%x)", x, x); + buf += 2; + fmt++; + break; + } + case 'D': + { + unsigned int x; + TCHECK2(buf[0], 4); + x = reverse ? EXTRACT_32BITS(buf) : + EXTRACT_LE_32BITS(buf); + printf("%d (0x%x)", x, x); + buf += 4; + fmt++; + break; + } + case 'L': + { + u_int64_t x; + TCHECK2(buf[0], 8); + x = reverse ? EXTRACT_64BITS(buf) : + EXTRACT_LE_64BITS(buf); + printf("%" PRIu64 " (0x%" PRIx64 ")", x, x); + buf += 8; + fmt++; + break; + } + case 'M': + { + /* Weird mixed-endian length values in 64-bit locks */ + u_int32_t x1, x2; + u_int64_t x; + TCHECK2(buf[0], 8); + x1 = reverse ? EXTRACT_32BITS(buf) : + EXTRACT_LE_32BITS(buf); + x2 = reverse ? EXTRACT_32BITS(buf + 4) : + EXTRACT_LE_32BITS(buf + 4); + x = (((u_int64_t)x1) << 32) | x2; + printf("%" PRIu64 " (0x%" PRIx64 ")", x, x); + buf += 8; + fmt++; + break; + } + case 'B': + { + unsigned int x; + TCHECK(buf[0]); + x = buf[0]; + printf("0x%X", x); + buf += 1; + fmt++; + break; + } + case 'w': + { + unsigned int x; + TCHECK2(buf[0], 2); + x = reverse ? EXTRACT_16BITS(buf) : + EXTRACT_LE_16BITS(buf); + printf("0x%X", x); + buf += 2; + fmt++; + break; + } + case 'W': + { + unsigned int x; + TCHECK2(buf[0], 4); + x = reverse ? EXTRACT_32BITS(buf) : + EXTRACT_LE_32BITS(buf); + printf("0x%X", x); + buf += 4; + fmt++; + break; + } + case 'l': + { + fmt++; + switch (*fmt) { + + case 'b': + TCHECK(buf[0]); + stringlen = buf[0]; + printf("%u", stringlen); + buf += 1; + break; + + case 'd': + TCHECK2(buf[0], 2); + stringlen = reverse ? EXTRACT_16BITS(buf) : + EXTRACT_LE_16BITS(buf); + printf("%u", stringlen); + buf += 2; + break; + + case 'D': + TCHECK2(buf[0], 4); + stringlen = reverse ? EXTRACT_32BITS(buf) : + EXTRACT_LE_32BITS(buf); + printf("%u", stringlen); + buf += 4; + break; + } + fmt++; + break; + } + case 'S': + case 'R': /* like 'S', but always ASCII */ + { + /*XXX unistr() */ + const char *s; + u_int32_t len; + + len = 0; + s = unistr(buf, &len, (*fmt == 'R') ? 0 : unicodestr); + if (s == NULL) + goto trunc; + printf("%s", s); + buf += len; + fmt++; + break; + } + case 'Z': + case 'Y': /* like 'Z', but always ASCII */ + { + const char *s; + u_int32_t len; + + TCHECK(*buf); + if (*buf != 4 && *buf != 2) { + printf("Error! ASCIIZ buffer of type %u", *buf); + return maxbuf; /* give up */ + } + len = 0; + s = unistr(buf + 1, &len, (*fmt == 'Y') ? 0 : unicodestr); + if (s == NULL) + goto trunc; + printf("%s", s); + buf += len + 1; + fmt++; + break; + } + case 's': + { + int l = atoi(fmt + 1); + TCHECK2(*buf, l); + printf("%-*.*s", l, l, buf); + buf += l; + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + case 'c': + { + TCHECK2(*buf, stringlen); + printf("%-*.*s", (int)stringlen, (int)stringlen, buf); + buf += stringlen; + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + case 'C': + { + const char *s; + s = unistr(buf, &stringlen, unicodestr); + if (s == NULL) + goto trunc; + printf("%s", s); + buf += stringlen; + fmt++; + break; + } + case 'h': + { + int l = atoi(fmt + 1); + TCHECK2(*buf, l); + while (l--) + printf("%02x", *buf++); + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + case 'n': + { + int t = atoi(fmt+1); + char nbuf[255]; + int name_type; + int len; + + switch (t) { + case 1: + name_type = name_extract(startbuf, PTR_DIFF(buf, startbuf), + maxbuf, nbuf); + if (name_type < 0) + goto trunc; + len = name_len(buf, maxbuf); + if (len < 0) + goto trunc; + buf += len; + printf("%-15.15s NameType=0x%02X (%s)", nbuf, name_type, + name_type_str(name_type)); + break; + case 2: + TCHECK(buf[15]); + name_type = buf[15]; + printf("%-15.15s NameType=0x%02X (%s)", buf, name_type, + name_type_str(name_type)); + buf += 16; + break; + } + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + case 'T': + { + time_t t; + struct tm *lt; + const char *tstring; + u_int32_t x; + + switch (atoi(fmt + 1)) { + case 1: + TCHECK2(buf[0], 4); + x = EXTRACT_LE_32BITS(buf); + if (x == 0 || x == 0xFFFFFFFF) + t = 0; + else + t = make_unix_date(buf); + buf += 4; + break; + case 2: + TCHECK2(buf[0], 4); + x = EXTRACT_LE_32BITS(buf); + if (x == 0 || x == 0xFFFFFFFF) + t = 0; + else + t = make_unix_date2(buf); + buf += 4; + break; + case 3: + TCHECK2(buf[0], 8); + t = interpret_long_date(buf); + buf += 8; + break; + default: + t = 0; + break; + } + if (t != 0) { + lt = localtime(&t); + if (lt != NULL) + tstring = asctime(lt); + else + tstring = "(Can't convert time)\n"; + } else + tstring = "NULL\n"; + printf("%s", tstring); + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + default: + putchar(*fmt); + fmt++; + break; + } + } + + if (buf >= maxbuf && *fmt) + printf("END OF BUFFER\n"); + + return(buf); + +trunc: + printf("\n"); + printf("WARNING: Short packet. Try increasing the snap length\n"); + return(NULL); +} + +const u_char * +smb_fdata(const u_char *buf, const char *fmt, const u_char *maxbuf, + int unicodestr) +{ + static int depth = 0; + char s[128]; + char *p; + + while (*fmt) { + switch (*fmt) { + case '*': + fmt++; + while (buf < maxbuf) { + const u_char *buf2; + depth++; + buf2 = smb_fdata(buf, fmt, maxbuf, unicodestr); + depth--; + if (buf2 == NULL) + return(NULL); + if (buf2 == buf) + return(buf); + buf = buf2; + } + return(buf); + + case '|': + fmt++; + if (buf >= maxbuf) + return(buf); + break; + + case '%': + fmt++; + buf = maxbuf; + break; + + case '#': + fmt++; + return(buf); + break; + + case '[': + fmt++; + if (buf >= maxbuf) + return(buf); + memset(s, 0, sizeof(s)); + p = strchr(fmt, ']'); + if ((size_t)(p - fmt + 1) > sizeof(s)) { + /* overrun */ + return(buf); + } + strncpy(s, fmt, p - fmt); + s[p - fmt] = '\0'; + fmt = p + 1; + buf = smb_fdata1(buf, s, maxbuf, unicodestr); + if (buf == NULL) + return(NULL); + break; + + default: + putchar(*fmt); + fmt++; + fflush(stdout); + break; + } + } + if (!depth && buf < maxbuf) { + size_t len = PTR_DIFF(maxbuf, buf); + printf("Data: (%lu bytes)\n", (unsigned long)len); + print_data(buf, len); + return(buf + len); + } + return(buf); +} + +typedef struct { + const char *name; + int code; + const char *message; +} err_code_struct; + +/* DOS Error Messages */ +static const err_code_struct dos_msgs[] = { + { "ERRbadfunc", 1, "Invalid function." }, + { "ERRbadfile", 2, "File not found." }, + { "ERRbadpath", 3, "Directory invalid." }, + { "ERRnofids", 4, "No file descriptors available" }, + { "ERRnoaccess", 5, "Access denied." }, + { "ERRbadfid", 6, "Invalid file handle." }, + { "ERRbadmcb", 7, "Memory control blocks destroyed." }, + { "ERRnomem", 8, "Insufficient server memory to perform the requested function." }, + { "ERRbadmem", 9, "Invalid memory block address." }, + { "ERRbadenv", 10, "Invalid environment." }, + { "ERRbadformat", 11, "Invalid format." }, + { "ERRbadaccess", 12, "Invalid open mode." }, + { "ERRbaddata", 13, "Invalid data." }, + { "ERR", 14, "reserved." }, + { "ERRbaddrive", 15, "Invalid drive specified." }, + { "ERRremcd", 16, "A Delete Directory request attempted to remove the server's current directory." }, + { "ERRdiffdevice", 17, "Not same device." }, + { "ERRnofiles", 18, "A File Search command can find no more files matching the specified criteria." }, + { "ERRbadshare", 32, "The sharing mode specified for an Open conflicts with existing FIDs on the file." }, + { "ERRlock", 33, "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process." }, + { "ERRfilexists", 80, "The file named in a Create Directory, Make New File or Link request already exists." }, + { "ERRbadpipe", 230, "Pipe invalid." }, + { "ERRpipebusy", 231, "All instances of the requested pipe are busy." }, + { "ERRpipeclosing", 232, "Pipe close in progress." }, + { "ERRnotconnected", 233, "No process on other end of pipe." }, + { "ERRmoredata", 234, "There is more data to be returned." }, + { NULL, -1, NULL } + }; + +/* Server Error Messages */ +static const err_code_struct server_msgs[] = { + { "ERRerror", 1, "Non-specific error code." }, + { "ERRbadpw", 2, "Bad password - name/password pair in a Tree Connect or Session Setup are invalid." }, + { "ERRbadtype", 3, "reserved." }, + { "ERRaccess", 4, "The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID." }, + { "ERRinvnid", 5, "The tree ID (TID) specified in a command was invalid." }, + { "ERRinvnetname", 6, "Invalid network name in tree connect." }, + { "ERRinvdevice", 7, "Invalid device - printer request made to non-printer connection or non-printer request made to printer connection." }, + { "ERRqfull", 49, "Print queue full (files) -- returned by open print file." }, + { "ERRqtoobig", 50, "Print queue full -- no space." }, + { "ERRqeof", 51, "EOF on print queue dump." }, + { "ERRinvpfid", 52, "Invalid print file FID." }, + { "ERRsmbcmd", 64, "The server did not recognize the command received." }, + { "ERRsrverror", 65, "The server encountered an internal error, e.g., system file unavailable." }, + { "ERRfilespecs", 67, "The file handle (FID) and pathname parameters contained an invalid combination of values." }, + { "ERRreserved", 68, "reserved." }, + { "ERRbadpermits", 69, "The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute." }, + { "ERRreserved", 70, "reserved." }, + { "ERRsetattrmode", 71, "The attribute mode in the Set File Attribute request is invalid." }, + { "ERRpaused", 81, "Server is paused." }, + { "ERRmsgoff", 82, "Not receiving messages." }, + { "ERRnoroom", 83, "No room to buffer message." }, + { "ERRrmuns", 87, "Too many remote user names." }, + { "ERRtimeout", 88, "Operation timed out." }, + { "ERRnoresource", 89, "No resources currently available for request." }, + { "ERRtoomanyuids", 90, "Too many UIDs active on this session." }, + { "ERRbaduid", 91, "The UID is not known as a valid ID on this session." }, + { "ERRusempx", 250, "Temp unable to support Raw, use MPX mode." }, + { "ERRusestd", 251, "Temp unable to support Raw, use standard read/write." }, + { "ERRcontmpx", 252, "Continue in MPX mode." }, + { "ERRreserved", 253, "reserved." }, + { "ERRreserved", 254, "reserved." }, + { "ERRnosupport", 0xFFFF, "Function not supported." }, + { NULL, -1, NULL } +}; + +/* Hard Error Messages */ +static const err_code_struct hard_msgs[] = { + { "ERRnowrite", 19, "Attempt to write on write-protected diskette." }, + { "ERRbadunit", 20, "Unknown unit." }, + { "ERRnotready", 21, "Drive not ready." }, + { "ERRbadcmd", 22, "Unknown command." }, + { "ERRdata", 23, "Data error (CRC)." }, + { "ERRbadreq", 24, "Bad request structure length." }, + { "ERRseek", 25 , "Seek error." }, + { "ERRbadmedia", 26, "Unknown media type." }, + { "ERRbadsector", 27, "Sector not found." }, + { "ERRnopaper", 28, "Printer out of paper." }, + { "ERRwrite", 29, "Write fault." }, + { "ERRread", 30, "Read fault." }, + { "ERRgeneral", 31, "General failure." }, + { "ERRbadshare", 32, "A open conflicts with an existing open." }, + { "ERRlock", 33, "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process." }, + { "ERRwrongdisk", 34, "The wrong disk was found in a drive." }, + { "ERRFCBUnavail", 35, "No FCBs are available to process request." }, + { "ERRsharebufexc", 36, "A sharing buffer has been exceeded." }, + { NULL, -1, NULL } +}; + +static const struct { + int code; + const char *class; + const err_code_struct *err_msgs; +} err_classes[] = { + { 0, "SUCCESS", NULL }, + { 0x01, "ERRDOS", dos_msgs }, + { 0x02, "ERRSRV", server_msgs }, + { 0x03, "ERRHRD", hard_msgs }, + { 0x04, "ERRXOS", NULL }, + { 0xE1, "ERRRMX1", NULL }, + { 0xE2, "ERRRMX2", NULL }, + { 0xE3, "ERRRMX3", NULL }, + { 0xFF, "ERRCMD", NULL }, + { -1, NULL, NULL } +}; + +/* + * return a SMB error string from a SMB buffer + */ +char * +smb_errstr(int class, int num) +{ + static char ret[128]; + int i, j; + + ret[0] = 0; + + for (i = 0; err_classes[i].class; i++) + if (err_classes[i].code == class) { + if (err_classes[i].err_msgs) { + const err_code_struct *err = err_classes[i].err_msgs; + for (j = 0; err[j].name; j++) + if (num == err[j].code) { + snprintf(ret, sizeof(ret), "%s - %s (%s)", + err_classes[i].class, err[j].name, err[j].message); + return ret; + } + } + + snprintf(ret, sizeof(ret), "%s - %d", err_classes[i].class, num); + return ret; + } + + snprintf(ret, sizeof(ret), "ERROR: Unknown error (%d,%d)", class, num); + return(ret); +} + +typedef struct { + u_int32_t code; + const char *name; +} nt_err_code_struct; + +/* + * NT Error codes + */ +static const nt_err_code_struct nt_errors[] = { + { 0x00000000, "STATUS_SUCCESS" }, + { 0x00000000, "STATUS_WAIT_0" }, + { 0x00000001, "STATUS_WAIT_1" }, + { 0x00000002, "STATUS_WAIT_2" }, + { 0x00000003, "STATUS_WAIT_3" }, + { 0x0000003F, "STATUS_WAIT_63" }, + { 0x00000080, "STATUS_ABANDONED" }, + { 0x00000080, "STATUS_ABANDONED_WAIT_0" }, + { 0x000000BF, "STATUS_ABANDONED_WAIT_63" }, + { 0x000000C0, "STATUS_USER_APC" }, + { 0x00000100, "STATUS_KERNEL_APC" }, + { 0x00000101, "STATUS_ALERTED" }, + { 0x00000102, "STATUS_TIMEOUT" }, + { 0x00000103, "STATUS_PENDING" }, + { 0x00000104, "STATUS_REPARSE" }, + { 0x00000105, "STATUS_MORE_ENTRIES" }, + { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" }, + { 0x00000107, "STATUS_SOME_NOT_MAPPED" }, + { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" }, + { 0x00000109, "STATUS_VOLUME_MOUNTED" }, + { 0x0000010A, "STATUS_RXACT_COMMITTED" }, + { 0x0000010B, "STATUS_NOTIFY_CLEANUP" }, + { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" }, + { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" }, + { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" }, + { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" }, + { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" }, + { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" }, + { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" }, + { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" }, + { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" }, + { 0x00000116, "STATUS_CRASH_DUMP" }, + { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" }, + { 0x00000118, "STATUS_REPARSE_OBJECT" }, + { 0x0000045C, "STATUS_NO_SHUTDOWN_IN_PROGRESS" }, + { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" }, + { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" }, + { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" }, + { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" }, + { 0x40000004, "STATUS_RXACT_STATE_CREATED" }, + { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" }, + { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" }, + { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" }, + { 0x40000008, "STATUS_SERIAL_MORE_WRITES" }, + { 0x40000009, "STATUS_REGISTRY_RECOVERED" }, + { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" }, + { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" }, + { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" }, + { 0x4000000D, "STATUS_NULL_LM_PASSWORD" }, + { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" }, + { 0x4000000F, "STATUS_RECEIVE_PARTIAL" }, + { 0x40000010, "STATUS_RECEIVE_EXPEDITED" }, + { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" }, + { 0x40000012, "STATUS_EVENT_DONE" }, + { 0x40000013, "STATUS_EVENT_PENDING" }, + { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" }, + { 0x40000015, "STATUS_FATAL_APP_EXIT" }, + { 0x40000016, "STATUS_PREDEFINED_HANDLE" }, + { 0x40000017, "STATUS_WAS_UNLOCKED" }, + { 0x40000018, "STATUS_SERVICE_NOTIFICATION" }, + { 0x40000019, "STATUS_WAS_LOCKED" }, + { 0x4000001A, "STATUS_LOG_HARD_ERROR" }, + { 0x4000001B, "STATUS_ALREADY_WIN32" }, + { 0x4000001C, "STATUS_WX86_UNSIMULATE" }, + { 0x4000001D, "STATUS_WX86_CONTINUE" }, + { 0x4000001E, "STATUS_WX86_SINGLE_STEP" }, + { 0x4000001F, "STATUS_WX86_BREAKPOINT" }, + { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" }, + { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" }, + { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" }, + { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" }, + { 0x40000024, "STATUS_NO_YIELD_PERFORMED" }, + { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" }, + { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" }, + { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" }, + { 0x80000003, "STATUS_BREAKPOINT" }, + { 0x80000004, "STATUS_SINGLE_STEP" }, + { 0x80000005, "STATUS_BUFFER_OVERFLOW" }, + { 0x80000006, "STATUS_NO_MORE_FILES" }, + { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" }, + { 0x8000000A, "STATUS_HANDLES_CLOSED" }, + { 0x8000000B, "STATUS_NO_INHERITANCE" }, + { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" }, + { 0x8000000D, "STATUS_PARTIAL_COPY" }, + { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" }, + { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" }, + { 0x80000010, "STATUS_DEVICE_OFF_LINE" }, + { 0x80000011, "STATUS_DEVICE_BUSY" }, + { 0x80000012, "STATUS_NO_MORE_EAS" }, + { 0x80000013, "STATUS_INVALID_EA_NAME" }, + { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" }, + { 0x80000015, "STATUS_INVALID_EA_FLAG" }, + { 0x80000016, "STATUS_VERIFY_REQUIRED" }, + { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" }, + { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" }, + { 0x8000001A, "STATUS_NO_MORE_ENTRIES" }, + { 0x8000001B, "STATUS_FILEMARK_DETECTED" }, + { 0x8000001C, "STATUS_MEDIA_CHANGED" }, + { 0x8000001D, "STATUS_BUS_RESET" }, + { 0x8000001E, "STATUS_END_OF_MEDIA" }, + { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" }, + { 0x80000020, "STATUS_MEDIA_CHECK" }, + { 0x80000021, "STATUS_SETMARK_DETECTED" }, + { 0x80000022, "STATUS_NO_DATA_DETECTED" }, + { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" }, + { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" }, + { 0x80000025, "STATUS_ALREADY_DISCONNECTED" }, + { 0x80000026, "STATUS_LONGJUMP" }, + { 0x80040111, "MAPI_E_LOGON_FAILED" }, + { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" }, + { 0x80090301, "SEC_E_INVALID_HANDLE" }, + { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" }, + { 0x8009030B, "SEC_E_NO_IMPERSONATION" }, + { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" }, + { 0x8009030E, "SEC_E_NO_CREDENTIALS" }, + { 0x8009030F, "SEC_E_MESSAGE_ALTERED" }, + { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" }, + { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" }, + { 0xC0000001, "STATUS_UNSUCCESSFUL" }, + { 0xC0000002, "STATUS_NOT_IMPLEMENTED" }, + { 0xC0000003, "STATUS_INVALID_INFO_CLASS" }, + { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" }, + { 0xC0000005, "STATUS_ACCESS_VIOLATION" }, + { 0xC0000006, "STATUS_IN_PAGE_ERROR" }, + { 0xC0000007, "STATUS_PAGEFILE_QUOTA" }, + { 0xC0000008, "STATUS_INVALID_HANDLE" }, + { 0xC0000009, "STATUS_BAD_INITIAL_STACK" }, + { 0xC000000A, "STATUS_BAD_INITIAL_PC" }, + { 0xC000000B, "STATUS_INVALID_CID" }, + { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" }, + { 0xC000000D, "STATUS_INVALID_PARAMETER" }, + { 0xC000000E, "STATUS_NO_SUCH_DEVICE" }, + { 0xC000000F, "STATUS_NO_SUCH_FILE" }, + { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" }, + { 0xC0000011, "STATUS_END_OF_FILE" }, + { 0xC0000012, "STATUS_WRONG_VOLUME" }, + { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" }, + { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" }, + { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" }, + { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" }, + { 0xC0000017, "STATUS_NO_MEMORY" }, + { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" }, + { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" }, + { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" }, + { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" }, + { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" }, + { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" }, + { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" }, + { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" }, + { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" }, + { 0xC0000021, "STATUS_ALREADY_COMMITTED" }, + { 0xC0000022, "STATUS_ACCESS_DENIED" }, + { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" }, + { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" }, + { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" }, + { 0xC0000026, "STATUS_INVALID_DISPOSITION" }, + { 0xC0000027, "STATUS_UNWIND" }, + { 0xC0000028, "STATUS_BAD_STACK" }, + { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" }, + { 0xC000002A, "STATUS_NOT_LOCKED" }, + { 0xC000002B, "STATUS_PARITY_ERROR" }, + { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" }, + { 0xC000002D, "STATUS_NOT_COMMITTED" }, + { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" }, + { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" }, + { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" }, + { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" }, + { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" }, + { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" }, + { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" }, + { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" }, + { 0xC0000037, "STATUS_PORT_DISCONNECTED" }, + { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" }, + { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" }, + { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" }, + { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" }, + { 0xC000003C, "STATUS_DATA_OVERRUN" }, + { 0xC000003D, "STATUS_DATA_LATE_ERROR" }, + { 0xC000003E, "STATUS_DATA_ERROR" }, + { 0xC000003F, "STATUS_CRC_ERROR" }, + { 0xC0000040, "STATUS_SECTION_TOO_BIG" }, + { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" }, + { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" }, + { 0xC0000043, "STATUS_SHARING_VIOLATION" }, + { 0xC0000044, "STATUS_QUOTA_EXCEEDED" }, + { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" }, + { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" }, + { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" }, + { 0xC0000048, "STATUS_PORT_ALREADY_SET" }, + { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" }, + { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" }, + { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" }, + { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" }, + { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" }, + { 0xC000004E, "STATUS_SECTION_PROTECTION" }, + { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" }, + { 0xC0000050, "STATUS_EA_TOO_LARGE" }, + { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" }, + { 0xC0000052, "STATUS_NO_EAS_ON_FILE" }, + { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" }, + { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" }, + { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" }, + { 0xC0000056, "STATUS_DELETE_PENDING" }, + { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" }, + { 0xC0000058, "STATUS_UNKNOWN_REVISION" }, + { 0xC0000059, "STATUS_REVISION_MISMATCH" }, + { 0xC000005A, "STATUS_INVALID_OWNER" }, + { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" }, + { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" }, + { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" }, + { 0xC000005E, "STATUS_NO_LOGON_SERVERS" }, + { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" }, + { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" }, + { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" }, + { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" }, + { 0xC0000063, "STATUS_USER_EXISTS" }, + { 0xC0000064, "STATUS_NO_SUCH_USER" }, + { 0xC0000065, "STATUS_GROUP_EXISTS" }, + { 0xC0000066, "STATUS_NO_SUCH_GROUP" }, + { 0xC0000067, "STATUS_MEMBER_IN_GROUP" }, + { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" }, + { 0xC0000069, "STATUS_LAST_ADMIN" }, + { 0xC000006A, "STATUS_WRONG_PASSWORD" }, + { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" }, + { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" }, + { 0xC000006D, "STATUS_LOGON_FAILURE" }, + { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" }, + { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" }, + { 0xC0000070, "STATUS_INVALID_WORKSTATION" }, + { 0xC0000071, "STATUS_PASSWORD_EXPIRED" }, + { 0xC0000072, "STATUS_ACCOUNT_DISABLED" }, + { 0xC0000073, "STATUS_NONE_MAPPED" }, + { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" }, + { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" }, + { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" }, + { 0xC0000077, "STATUS_INVALID_ACL" }, + { 0xC0000078, "STATUS_INVALID_SID" }, + { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" }, + { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" }, + { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" }, + { 0xC000007C, "STATUS_NO_TOKEN" }, + { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" }, + { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" }, + { 0xC000007F, "STATUS_DISK_FULL" }, + { 0xC0000080, "STATUS_SERVER_DISABLED" }, + { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" }, + { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" }, + { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" }, + { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" }, + { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" }, + { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" }, + { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" }, + { 0xC0000088, "STATUS_NOT_MAPPED_DATA" }, + { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" }, + { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" }, + { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" }, + { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" }, + { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" }, + { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" }, + { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" }, + { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" }, + { 0xC0000091, "STATUS_FLOAT_OVERFLOW" }, + { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" }, + { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" }, + { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" }, + { 0xC0000095, "STATUS_INTEGER_OVERFLOW" }, + { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" }, + { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" }, + { 0xC0000098, "STATUS_FILE_INVALID" }, + { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" }, + { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" }, + { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" }, + { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" }, + { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" }, + { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" }, + { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" }, + { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" }, + { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" }, + { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" }, + { 0xC00000A3, "STATUS_DEVICE_NOT_READY" }, + { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" }, + { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" }, + { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" }, + { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" }, + { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" }, + { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" }, + { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" }, + { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" }, + { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" }, + { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" }, + { 0xC00000AE, "STATUS_PIPE_BUSY" }, + { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" }, + { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" }, + { 0xC00000B1, "STATUS_PIPE_CLOSING" }, + { 0xC00000B2, "STATUS_PIPE_CONNECTED" }, + { 0xC00000B3, "STATUS_PIPE_LISTENING" }, + { 0xC00000B4, "STATUS_INVALID_READ_MODE" }, + { 0xC00000B5, "STATUS_IO_TIMEOUT" }, + { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" }, + { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" }, + { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" }, + { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" }, + { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" }, + { 0xC00000BB, "STATUS_NOT_SUPPORTED" }, + { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" }, + { 0xC00000BD, "STATUS_DUPLICATE_NAME" }, + { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" }, + { 0xC00000BF, "STATUS_NETWORK_BUSY" }, + { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" }, + { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" }, + { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" }, + { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" }, + { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" }, + { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" }, + { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" }, + { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" }, + { 0xC00000C8, "STATUS_PRINT_CANCELLED" }, + { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" }, + { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" }, + { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" }, + { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" }, + { 0xC00000CD, "STATUS_TOO_MANY_NAMES" }, + { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" }, + { 0xC00000CF, "STATUS_SHARING_PAUSED" }, + { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" }, + { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" }, + { 0xC00000D2, "STATUS_NET_WRITE_FAULT" }, + { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" }, + { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" }, + { 0xC00000D5, "STATUS_FILE_RENAMED" }, + { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" }, + { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" }, + { 0xC00000D8, "STATUS_CANT_WAIT" }, + { 0xC00000D9, "STATUS_PIPE_EMPTY" }, + { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" }, + { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" }, + { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" }, + { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" }, + { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" }, + { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" }, + { 0xC00000E0, "STATUS_DOMAIN_EXISTS" }, + { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" }, + { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" }, + { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" }, + { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" }, + { 0xC00000E5, "STATUS_INTERNAL_ERROR" }, + { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" }, + { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" }, + { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" }, + { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" }, + { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" }, + { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" }, + { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" }, + { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" }, + { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" }, + { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" }, + { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" }, + { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" }, + { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" }, + { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" }, + { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" }, + { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" }, + { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" }, + { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" }, + { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" }, + { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" }, + { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" }, + { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" }, + { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" }, + { 0xC00000FD, "STATUS_STACK_OVERFLOW" }, + { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" }, + { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" }, + { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" }, + { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" }, + { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" }, + { 0xC0000103, "STATUS_NOT_A_DIRECTORY" }, + { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" }, + { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" }, + { 0xC0000106, "STATUS_NAME_TOO_LONG" }, + { 0xC0000107, "STATUS_FILES_OPEN" }, + { 0xC0000108, "STATUS_CONNECTION_IN_USE" }, + { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" }, + { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" }, + { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" }, + { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" }, + { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" }, + { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" }, + { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" }, + { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" }, + { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" }, + { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" }, + { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" }, + { 0xC0000114, "STATUS_ABIOS_INVALID_LID" }, + { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" }, + { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" }, + { 0xC0000117, "STATUS_NO_LDT" }, + { 0xC0000118, "STATUS_INVALID_LDT_SIZE" }, + { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" }, + { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" }, + { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" }, + { 0xC000011C, "STATUS_RXACT_INVALID_STATE" }, + { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" }, + { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" }, + { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" }, + { 0xC0000120, "STATUS_CANCELLED" }, + { 0xC0000121, "STATUS_CANNOT_DELETE" }, + { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" }, + { 0xC0000123, "STATUS_FILE_DELETED" }, + { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" }, + { 0xC0000125, "STATUS_SPECIAL_GROUP" }, + { 0xC0000126, "STATUS_SPECIAL_USER" }, + { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" }, + { 0xC0000128, "STATUS_FILE_CLOSED" }, + { 0xC0000129, "STATUS_TOO_MANY_THREADS" }, + { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" }, + { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" }, + { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" }, + { 0xC000012D, "STATUS_COMMITMENT_LIMIT" }, + { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" }, + { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" }, + { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" }, + { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" }, + { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" }, + { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" }, + { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" }, + { 0xC0000135, "STATUS_DLL_NOT_FOUND" }, + { 0xC0000136, "STATUS_OPEN_FAILED" }, + { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" }, + { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" }, + { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" }, + { 0xC000013A, "STATUS_CONTROL_C_EXIT" }, + { 0xC000013B, "STATUS_LOCAL_DISCONNECT" }, + { 0xC000013C, "STATUS_REMOTE_DISCONNECT" }, + { 0xC000013D, "STATUS_REMOTE_RESOURCES" }, + { 0xC000013E, "STATUS_LINK_FAILED" }, + { 0xC000013F, "STATUS_LINK_TIMEOUT" }, + { 0xC0000140, "STATUS_INVALID_CONNECTION" }, + { 0xC0000141, "STATUS_INVALID_ADDRESS" }, + { 0xC0000142, "STATUS_DLL_INIT_FAILED" }, + { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" }, + { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" }, + { 0xC0000145, "STATUS_APP_INIT_FAILURE" }, + { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" }, + { 0xC0000147, "STATUS_NO_PAGEFILE" }, + { 0xC0000148, "STATUS_INVALID_LEVEL" }, + { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" }, + { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" }, + { 0xC000014B, "STATUS_PIPE_BROKEN" }, + { 0xC000014C, "STATUS_REGISTRY_CORRUPT" }, + { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" }, + { 0xC000014E, "STATUS_NO_EVENT_PAIR" }, + { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" }, + { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" }, + { 0xC0000151, "STATUS_NO_SUCH_ALIAS" }, + { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" }, + { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" }, + { 0xC0000154, "STATUS_ALIAS_EXISTS" }, + { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" }, + { 0xC0000156, "STATUS_TOO_MANY_SECRETS" }, + { 0xC0000157, "STATUS_SECRET_TOO_LONG" }, + { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" }, + { 0xC0000159, "STATUS_FULLSCREEN_MODE" }, + { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" }, + { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" }, + { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" }, + { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" }, + { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" }, + { 0xC000015F, "STATUS_FT_MISSING_MEMBER" }, + { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" }, + { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" }, + { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" }, + { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" }, + { 0xC0000164, "STATUS_FLOPPY_VOLUME" }, + { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" }, + { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" }, + { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" }, + { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" }, + { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" }, + { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" }, + { 0xC000016B, "STATUS_DISK_RESET_FAILED" }, + { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" }, + { 0xC000016D, "STATUS_FT_ORPHANING" }, + { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" }, + { 0xC0000172, "STATUS_PARTITION_FAILURE" }, + { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" }, + { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" }, + { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" }, + { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" }, + { 0xC0000177, "STATUS_EOM_OVERFLOW" }, + { 0xC0000178, "STATUS_NO_MEDIA" }, + { 0xC000017A, "STATUS_NO_SUCH_MEMBER" }, + { 0xC000017B, "STATUS_INVALID_MEMBER" }, + { 0xC000017C, "STATUS_KEY_DELETED" }, + { 0xC000017D, "STATUS_NO_LOG_SPACE" }, + { 0xC000017E, "STATUS_TOO_MANY_SIDS" }, + { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" }, + { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" }, + { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" }, + { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" }, + { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" }, + { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" }, + { 0xC0000185, "STATUS_IO_DEVICE_ERROR" }, + { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" }, + { 0xC0000187, "STATUS_BACKUP_CONTROLLER" }, + { 0xC0000188, "STATUS_LOG_FILE_FULL" }, + { 0xC0000189, "STATUS_TOO_LATE" }, + { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" }, + { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" }, + { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" }, + { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" }, + { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" }, + { 0xC000018F, "STATUS_EVENTLOG_CANT_START" }, + { 0xC0000190, "STATUS_TRUST_FAILURE" }, + { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" }, + { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" }, + { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" }, + { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" }, + { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" }, + { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" }, + { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" }, + { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" }, + { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" }, + { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" }, + { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" }, + { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" }, + { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" }, + { 0xC0000203, "STATUS_USER_SESSION_DELETED" }, + { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" }, + { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" }, + { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" }, + { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" }, + { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" }, + { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" }, + { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" }, + { 0xC000020B, "STATUS_ADDRESS_CLOSED" }, + { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" }, + { 0xC000020D, "STATUS_CONNECTION_RESET" }, + { 0xC000020E, "STATUS_TOO_MANY_NODES" }, + { 0xC000020F, "STATUS_TRANSACTION_ABORTED" }, + { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" }, + { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" }, + { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" }, + { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" }, + { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" }, + { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" }, + { 0xC0000216, "STATUS_NOT_SERVER_SESSION" }, + { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" }, + { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" }, + { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" }, + { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" }, + { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" }, + { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" }, + { 0xC000021D, "STATUS_VDM_HARD_ERROR" }, + { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" }, + { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" }, + { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" }, + { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" }, + { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" }, + { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" }, + { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" }, + { 0xC0000225, "STATUS_NOT_FOUND" }, + { 0xC0000226, "STATUS_NOT_TINY_STREAM" }, + { 0xC0000227, "STATUS_RECOVERY_FAILURE" }, + { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" }, + { 0xC0000229, "STATUS_FAIL_CHECK" }, + { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" }, + { 0xC000022B, "STATUS_OBJECTID_EXISTS" }, + { 0xC000022C, "STATUS_CONVERT_TO_LARGE" }, + { 0xC000022D, "STATUS_RETRY" }, + { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" }, + { 0xC000022F, "STATUS_ALLOCATE_BUCKET" }, + { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" }, + { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" }, + { 0xC0000232, "STATUS_INVALID_VARIANT" }, + { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" }, + { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" }, + { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" }, + { 0xC0000236, "STATUS_CONNECTION_REFUSED" }, + { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" }, + { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" }, + { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" }, + { 0xC000023A, "STATUS_CONNECTION_INVALID" }, + { 0xC000023B, "STATUS_CONNECTION_ACTIVE" }, + { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" }, + { 0xC000023D, "STATUS_HOST_UNREACHABLE" }, + { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" }, + { 0xC000023F, "STATUS_PORT_UNREACHABLE" }, + { 0xC0000240, "STATUS_REQUEST_ABORTED" }, + { 0xC0000241, "STATUS_CONNECTION_ABORTED" }, + { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" }, + { 0xC0000243, "STATUS_USER_MAPPED_FILE" }, + { 0xC0000244, "STATUS_AUDIT_FAILED" }, + { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" }, + { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" }, + { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" }, + { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" }, + { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" }, + { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" }, + { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" }, + { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" }, + { 0xC0000253, "STATUS_LPC_REPLY_LOST" }, + { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" }, + { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" }, + { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" }, + { 0xC0000257, "STATUS_PATH_NOT_COVERED" }, + { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" }, + { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" }, + { 0xC000025A, "STATUS_PWD_TOO_SHORT" }, + { 0xC000025B, "STATUS_PWD_TOO_RECENT" }, + { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" }, + { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" }, + { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" }, + { 0xC0000260, "STATUS_INVALID_HW_PROFILE" }, + { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" }, + { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" }, + { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" }, + { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" }, + { 0xC0000265, "STATUS_TOO_MANY_LINKS" }, + { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" }, + { 0xC0000267, "STATUS_FILE_IS_OFFLINE" }, + { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" }, + { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" }, + { 0xC000026A, "STATUS_LICENSE_VIOLATION" }, + { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" }, + { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" }, + { 0xC000026D, "STATUS_DFS_UNAVAILABLE" }, + { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" }, + { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" }, + { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" }, + { 0xC0000271, "STATUS_VALIDATE_CONTINUE" }, + { 0xC0000272, "STATUS_NO_MATCH" }, + { 0xC0000273, "STATUS_NO_MORE_MATCHES" }, + { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" }, + { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" }, + { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" }, + { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" }, + { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" }, + { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" }, + { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" }, + { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" }, + { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" }, + { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" }, + { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" }, + { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" }, + { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" }, + { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" }, + { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" }, + { 0xC000028A, "STATUS_ENCRYPTION_FAILED" }, + { 0xC000028B, "STATUS_DECRYPTION_FAILED" }, + { 0xC000028C, "STATUS_RANGE_NOT_FOUND" }, + { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" }, + { 0xC000028E, "STATUS_NO_EFS" }, + { 0xC000028F, "STATUS_WRONG_EFS" }, + { 0xC0000290, "STATUS_NO_USER_KEYS" }, + { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" }, + { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" }, + { 0xC0000293, "STATUS_FILE_ENCRYPTED" }, + { 0x40000294, "STATUS_WAKE_SYSTEM" }, + { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" }, + { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" }, + { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" }, + { 0xC0000298, "STATUS_WMI_TRY_AGAIN" }, + { 0xC0000299, "STATUS_SHARED_POLICY" }, + { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" }, + { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" }, + { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" }, + { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" }, + { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" }, + { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" }, + { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" }, + { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" }, + { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" }, + { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" }, + { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" }, + { 0xC00002A5, "STATUS_DS_BUSY" }, + { 0xC00002A6, "STATUS_DS_UNAVAILABLE" }, + { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" }, + { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" }, + { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" }, + { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" }, + { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" }, + { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" }, + { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" }, + { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" }, + { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" }, + { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" }, + { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" }, + { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" }, + { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" }, + { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" }, + { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" }, + { 0xC00002B6, "STATUS_DEVICE_REMOVED" }, + { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" }, + { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" }, + { 0xC00002B9, "STATUS_NOINTERFACE" }, + { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" }, + { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" }, + { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" }, + { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" }, + { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" }, + { 0xC00002C6, "STATUS_WMI_READ_ONLY" }, + { 0xC00002C7, "STATUS_WMI_SET_FAILURE" }, + { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" }, + { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" }, + { 0xC00002CA, "STATUS_TRANSPORT_FULL" }, + { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" }, + { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" }, + { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" }, + { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" }, + { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" }, + { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" }, + { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" }, + { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" }, + { 0xC00002D3, "STATUS_POWER_STATE_INVALID" }, + { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" }, + { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" }, + { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" }, + { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" }, + { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" }, + { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" }, + { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" }, + { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" }, + { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" }, + { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" }, + { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" }, + { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" }, + { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" }, + { 0xC00002E1, "STATUS_DS_CANT_START" }, + { 0xC00002E2, "STATUS_DS_INIT_FAILURE" }, + { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" }, + { 0xC00002E4, "STATUS_DS_GC_REQUIRED" }, + { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" }, + { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" }, + { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" }, + { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" }, + { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" }, + { 0xC0009898, "STATUS_WOW_ASSERTION" }, + { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" }, + { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" }, + { 0xC0020003, "RPC_NT_INVALID_BINDING" }, + { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" }, + { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" }, + { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" }, + { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" }, + { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" }, + { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" }, + { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" }, + { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" }, + { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" }, + { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" }, + { 0xC002000E, "RPC_NT_ALREADY_LISTENING" }, + { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" }, + { 0xC0020010, "RPC_NT_NOT_LISTENING" }, + { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" }, + { 0xC0020012, "RPC_NT_UNKNOWN_IF" }, + { 0xC0020013, "RPC_NT_NO_BINDINGS" }, + { 0xC0020014, "RPC_NT_NO_PROTSEQS" }, + { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" }, + { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" }, + { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" }, + { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" }, + { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" }, + { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" }, + { 0xC002001B, "RPC_NT_CALL_FAILED" }, + { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" }, + { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" }, + { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" }, + { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" }, + { 0xC0020022, "RPC_NT_INVALID_TAG" }, + { 0xC0020023, "RPC_NT_INVALID_BOUND" }, + { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" }, + { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" }, + { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" }, + { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" }, + { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" }, + { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" }, + { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" }, + { 0xC002002C, "RPC_NT_STRING_TOO_LONG" }, + { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" }, + { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" }, + { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" }, + { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" }, + { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" }, + { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" }, + { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" }, + { 0xC0020034, "EPT_NT_INVALID_ENTRY" }, + { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" }, + { 0xC0020036, "EPT_NT_NOT_REGISTERED" }, + { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" }, + { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" }, + { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" }, + { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" }, + { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" }, + { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" }, + { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" }, + { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" }, + { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" }, + { 0xC0020040, "RPC_NT_INVALID_NAF_ID" }, + { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" }, + { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" }, + { 0xC0020043, "RPC_NT_INTERNAL_ERROR" }, + { 0xC0020044, "RPC_NT_ZERO_DIVIDE" }, + { 0xC0020045, "RPC_NT_ADDRESS_ERROR" }, + { 0xC0020046, "RPC_NT_FP_DIV_ZERO" }, + { 0xC0020047, "RPC_NT_FP_UNDERFLOW" }, + { 0xC0020048, "RPC_NT_FP_OVERFLOW" }, + { 0xC0021007, "RPC_P_RECEIVE_ALERTED" }, + { 0xC0021008, "RPC_P_CONNECTION_CLOSED" }, + { 0xC0021009, "RPC_P_RECEIVE_FAILED" }, + { 0xC002100A, "RPC_P_SEND_FAILED" }, + { 0xC002100B, "RPC_P_TIMEOUT" }, + { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" }, + { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" }, + { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" }, + { 0xC0021015, "RPC_P_THREAD_LISTENING" }, + { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" }, + { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" }, + { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" }, + { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" }, + { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" }, + { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" }, + { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" }, + { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" }, + { 0xC0030009, "RPC_NT_NULL_REF_POINTER" }, + { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" }, + { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" }, + { 0xC003000C, "RPC_NT_BAD_STUB_DATA" }, + { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" }, + { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" }, + { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" }, + { 0xC002004C, "EPT_NT_CANT_CREATE" }, + { 0xC002004D, "RPC_NT_INVALID_OBJECT" }, + { 0xC002004F, "RPC_NT_NO_INTERFACES" }, + { 0xC0020050, "RPC_NT_CALL_CANCELLED" }, + { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" }, + { 0xC0020052, "RPC_NT_COMM_FAILURE" }, + { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" }, + { 0xC0020054, "RPC_NT_NO_PRINC_NAME" }, + { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" }, + { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" }, + { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" }, + { 0xC0020058, "RPC_NT_NOT_CANCELLED" }, + { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" }, + { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" }, + { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" }, + { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" }, + { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" }, + { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" }, + { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" }, + { 0, NULL } +}; + +/* + * return an NT error string from a SMB buffer + */ +const char * +nt_errstr(u_int32_t err) +{ + static char ret[128]; + int i; + + ret[0] = 0; + + for (i = 0; nt_errors[i].name; i++) { + if (err == nt_errors[i].code) + return nt_errors[i].name; + } + + snprintf(ret, sizeof(ret), "0x%08x", err); + return ret; +} diff --git a/freebsd/contrib/tcpdump/tcp.h b/freebsd/contrib/tcpdump/tcp.h new file mode 100644 index 00000000..92d505ae --- /dev/null +++ b/freebsd/contrib/tcpdump/tcp.h @@ -0,0 +1,112 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/tcp.h,v 1.14 2007-12-09 00:30:47 guy 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. + * + * @(#)tcp.h 8.1 (Berkeley) 6/10/93 + */ + +typedef u_int32_t tcp_seq; +/* + * TCP header. + * Per RFC 793, September, 1981. + */ +struct tcphdr { + u_int16_t th_sport; /* source port */ + u_int16_t th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ + u_int8_t th_offx2; /* data offset, rsvd */ + u_int8_t th_flags; + u_int16_t th_win; /* window */ + u_int16_t th_sum; /* checksum */ + u_int16_t th_urp; /* urgent pointer */ +}; + +#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) + +/* TCP flags */ +#define TH_FIN 0x01 +#define TH_SYN 0x02 +#define TH_RST 0x04 +#define TH_PUSH 0x08 +#define TH_ACK 0x10 +#define TH_URG 0x20 +#define TH_ECNECHO 0x40 /* ECN Echo */ +#define TH_CWR 0x80 /* ECN Cwnd Reduced */ + + +#define TCPOPT_EOL 0 +#define TCPOPT_NOP 1 +#define TCPOPT_MAXSEG 2 +#define TCPOLEN_MAXSEG 4 +#define TCPOPT_WSCALE 3 /* window scale factor (rfc1323) */ +#define TCPOPT_SACKOK 4 /* selective ack ok (rfc2018) */ +#define TCPOPT_SACK 5 /* selective ack (rfc2018) */ +#define TCPOPT_ECHO 6 /* echo (rfc1072) */ +#define TCPOPT_ECHOREPLY 7 /* echo (rfc1072) */ +#define TCPOPT_TIMESTAMP 8 /* timestamp (rfc1323) */ +#define TCPOLEN_TIMESTAMP 10 +#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ +#define TCPOPT_CC 11 /* T/TCP CC options (rfc1644) */ +#define TCPOPT_CCNEW 12 /* T/TCP CC options (rfc1644) */ +#define TCPOPT_CCECHO 13 /* T/TCP CC options (rfc1644) */ +#define TCPOPT_SIGNATURE 19 /* Keyed MD5 (rfc2385) */ +#define TCPOLEN_SIGNATURE 18 +#define TCP_SIGLEN 16 /* length of an option 19 digest */ +#define TCPOPT_AUTH 20 /* Enhanced AUTH option */ +#define TCPOPT_UTO 28 /* tcp user timeout (rfc5482) */ +#define TCPOLEN_UTO 4 + + +#define TCPOPT_TSTAMP_HDR \ + (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) + +#ifndef TELNET_PORT +#define TELNET_PORT 23 +#endif +#ifndef BGP_PORT +#define BGP_PORT 179 +#endif +#define NETBIOS_SSN_PORT 139 +#ifndef PPTP_PORT +#define PPTP_PORT 1723 +#endif +#define BEEP_PORT 10288 +#ifndef NFS_PORT +#define NFS_PORT 2049 +#endif +#define MSDP_PORT 639 +#define RPKI_RTR_PORT 323 +#define LDP_PORT 646 +#ifndef SMB_PORT +#define SMB_PORT 445 +#endif diff --git a/freebsd/contrib/tcpdump/tcpdump-stdinc.h b/freebsd/contrib/tcpdump/tcpdump-stdinc.h new file mode 100644 index 00000000..411326a4 --- /dev/null +++ b/freebsd/contrib/tcpdump/tcpdump-stdinc.h @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * 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 Politecnico di Torino 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 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 + * OWNER 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. + * + * + * @(#) $Header: /tcpdump/master/tcpdump/tcpdump-stdinc.h,v 1.18 2007-11-24 18:13:33 mcr Exp $ (LBL) + */ + +/* + * Include the appropriate OS header files on Windows and various flavors + * of UNIX, and also define some additional items and include various + * non-OS header files on Windows, and; this isolates most of the platform + * differences to this one file. + */ + +#ifndef tcpdump_stdinc_h +#define tcpdump_stdinc_h + +#ifdef WIN32 + +#include <stdio.h> +#include <winsock2.h> +#include <Ws2tcpip.h> +#include "bittypes.h" +#include <ctype.h> +#include <time.h> +#include <io.h> +#include <fcntl.h> +#include <rtems/bsd/sys/types.h> +#include <net/netdb.h> /* in wpcap's Win32/include */ + +#ifndef NBBY +#define NBBY 8 +#endif + +#if !defined(__MINGW32__) && !defined(__WATCOMC__) +#undef toascii +#define isascii __isascii +#define toascii __toascii +#define stat _stat +#define open _open +#define fstat _fstat +#define read _read +#define close _close +#define O_RDONLY _O_RDONLY + +typedef short ino_t; +#endif /* __MINGW32__ */ + +#ifdef __MINGW32__ +#include <stdint.h> +#endif + +/* Protos for missing/x.c functions (ideally <missing/addrinfo.h> + * should be used, but it clashes with <ws2tcpip.h>). + */ +extern const char *inet_ntop (int, const void *, char *, size_t); +extern int inet_pton (int, const char *, void *); +extern int inet_aton (const char *cp, struct in_addr *addr); + +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif + +#ifndef toascii +#define toascii(c) ((c) & 0x7f) +#endif + +#ifndef caddr_t +typedef char* caddr_t; +#endif /* caddr_t */ + +#define MAXHOSTNAMELEN 64 +#define NI_MAXHOST 1025 +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#define RETSIGTYPE void + +#else /* WIN32 */ + +#include <ctype.h> +#include <unistd.h> +#include <netdb.h> +#if HAVE_INTTYPES_H +#include <inttypes.h> +#else +#if HAVE_STDINT_H +#include <stdint.h> +#endif +#endif +#ifdef HAVE_SYS_BITYPES_H +#include <sys/bitypes.h> +#endif +#include <rtems/bsd/sys/param.h> +#include <rtems/bsd/sys/types.h> /* concession to AIX */ +#include <rtems/bsd/sys/time.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#ifdef TIME_WITH_SYS_TIME +#include <time.h> +#endif + +#include <arpa/inet.h> + +#endif /* WIN32 */ + +#ifndef HAVE___ATTRIBUTE__ +#define __attribute__(x) +#endif + +/* + * Used to declare a structure unaligned, so that the C compiler, + * if necessary, generates code that doesn't assume alignment. + * This is required because there is no guarantee that the packet + * data we get from libpcap/WinPcap is properly aligned. + * + * This assumes that, for all compilers that support __attribute__: + * + * 1) they support __attribute__((packed)); + * + * 2) for all instruction set architectures requiring strict + * alignment, declaring a structure with that attribute + * causes the compiler to generate code that handles + * misaligned 2-byte, 4-byte, and 8-byte integral + * quantities. + * + * It does not (yet) handle compilers where you can get the compiler + * to generate code of that sort by some other means. + * + * This is required in order to, for example, keep the compiler from + * generating, for + * + * if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { + * + * in print-bootp.c, code that loads the first 4-byte word of a + * "struct bootp", masking out the bp_hops field, and comparing the result + * against 0x01010600. + * + * Note: this also requires that padding be put into the structure, + * at least for compilers where it's implemented as __attribute__((packed)). + */ +#define UNALIGNED __attribute__((packed)) + +#if defined(WIN32) || defined(MSDOS) + #define FOPEN_READ_TXT "rt" + #define FOPEN_READ_BIN "rb" + #define FOPEN_WRITE_TXT "wt" + #define FOPEN_WRITE_BIN "wb" +#else + #define FOPEN_READ_TXT "r" + #define FOPEN_READ_BIN FOPEN_READ_TXT + #define FOPEN_WRITE_TXT "w" + #define FOPEN_WRITE_BIN FOPEN_WRITE_TXT +#endif + +#if defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) && !defined(__ntohl) + #undef ntohl + #undef ntohs + #undef htonl + #undef htons + + static __inline__ unsigned long __ntohl (unsigned long x); + static __inline__ unsigned short __ntohs (unsigned short x); + + #define ntohl(x) __ntohl(x) + #define ntohs(x) __ntohs(x) + #define htonl(x) __ntohl(x) + #define htons(x) __ntohs(x) + + static __inline__ unsigned long __ntohl (unsigned long x) + { + __asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */ + "rorl $16, %0\n\t" /* swap words */ + "xchgb %b0, %h0" /* swap higher bytes */ + : "=q" (x) : "0" (x)); + return (x); + } + + static __inline__ unsigned short __ntohs (unsigned short x) + { + __asm__ ("xchgb %b0, %h0" /* swap bytes */ + : "=q" (x) : "0" (x)); + return (x); + } +#endif + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#endif /* tcpdump_stdinc_h */ diff --git a/freebsd/contrib/tcpdump/tcpdump.c b/freebsd/contrib/tcpdump/tcpdump.c new file mode 100644 index 00000000..32ffb456 --- /dev/null +++ b/freebsd/contrib/tcpdump/tcpdump.c @@ -0,0 +1,2201 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * 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. + * + * Support for splitting captures into multiple files with a maximum + * file size: + * + * Copyright (c) 2001 + * Seth Webster <swebster@sst.ll.mit.edu> + */ + +#if 0 +#ifndef lint +static const char copyright[] _U_ = + "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ +The Regents of the University of California. All rights reserved.\n"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.283 2008-09-25 21:45:50 guy Exp $ (LBL)"; +#endif +#endif + +/* $FreeBSD$ */ + +/* + * tcpdump - monitor tcp/ip traffic on an ethernet. + * + * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory. + * Mercilessly hacked and occasionally improved since then via the + * combined efforts of Van, Steve McCanne and Craig Leres of LBL. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if __rtems__ +#define __need_getopt_newlib +#include <getopt.h> +#define setpriority(a, b, c) +#endif + +#include <tcpdump-stdinc.h> + +#ifdef WIN32 +#include "getopt.h" +#include "w32_fzs.h" +extern int strcasecmp (const char *__s1, const char *__s2); +extern int SIZE_BUF; +#define off_t long +#define uint UINT +#endif /* WIN32 */ + +#ifdef HAVE_SMI_H +#include <smi.h> +#endif + +#include <pcap.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#ifndef WIN32 +#include <sys/wait.h> +#include <rtems/bsd/sys/resource.h> +#include <pwd.h> +#include <grp.h> +#include <errno.h> +#endif /* WIN32 */ + +/* capabilities convinience library */ +#ifdef HAVE_CAP_NG_H +#include <cap-ng.h> +#endif /* HAVE_CAP_NG_H */ + +#include "netdissect.h" +#include "interface.h" +#include "addrtoname.h" +#include "machdep.h" +#include "setsignal.h" +#include "gmt2local.h" +#include "pcap-missing.h" + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#ifdef SIGINFO +#define SIGNAL_REQ_INFO SIGINFO +#elif SIGUSR1 +#define SIGNAL_REQ_INFO SIGUSR1 +#endif + +netdissect_options Gndo; +netdissect_options *gndo = &Gndo; + +static int dflag; /* print filter code */ +static int Lflag; /* list available data link types and exit */ +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE +static int Jflag; /* list available time stamp types */ +#endif +static char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */ + +static int infodelay; +static int infoprint; + +char *program_name; + +int32_t thiszone; /* seconds offset from gmt to local time */ + +/* Forwards */ +static RETSIGTYPE cleanup(int); +static RETSIGTYPE child_cleanup(int); +static void usage(void) __attribute__((noreturn)); +static void show_dlts_and_exit(const char *device, pcap_t *pd) __attribute__((noreturn)); + +static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); +static void ndo_default_print(netdissect_options *, const u_char *, u_int); +static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); +static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *); +static void droproot(const char *, const char *); +static void ndo_error(netdissect_options *ndo, const char *fmt, ...) + __attribute__ ((noreturn, format (printf, 2, 3))); +static void ndo_warning(netdissect_options *ndo, const char *fmt, ...); + +#ifdef SIGNAL_REQ_INFO +RETSIGTYPE requestinfo(int); +#endif + +#if defined(USE_WIN32_MM_TIMER) + #include <MMsystem.h> + static UINT timer_id; + static void CALLBACK verbose_stats_dump(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR); +#elif defined(HAVE_ALARM) + static void verbose_stats_dump(int sig); +#endif + +static void info(int); +static u_int packets_captured; + +struct printer { + if_printer f; + int type; +}; + + +struct ndo_printer { + if_ndo_printer f; + int type; +}; + + +static const struct printer printers[] = { +#if !__rtems__ + { arcnet_if_print, DLT_ARCNET }, +#endif +#ifdef DLT_ARCNET_LINUX + { arcnet_linux_if_print, DLT_ARCNET_LINUX }, +#endif +#if !__rtems__ + { token_if_print, DLT_IEEE802 }, +#endif +#ifdef DLT_LANE8023 + { lane_if_print, DLT_LANE8023 }, +#endif +#ifdef DLT_CIP + { cip_if_print, DLT_CIP }, +#endif +#ifdef DLT_ATM_CLIP + { cip_if_print, DLT_ATM_CLIP }, +#endif + { sl_if_print, DLT_SLIP }, +#ifdef DLT_SLIP_BSDOS + { sl_bsdos_if_print, DLT_SLIP_BSDOS }, +#endif + { ppp_if_print, DLT_PPP }, +#ifdef DLT_PPP_WITHDIRECTION + { ppp_if_print, DLT_PPP_WITHDIRECTION }, +#endif +#ifdef DLT_PPP_BSDOS + { ppp_bsdos_if_print, DLT_PPP_BSDOS }, +#endif +#if !__rtems__ + { fddi_if_print, DLT_FDDI }, +#endif + { null_if_print, DLT_NULL }, +#ifdef DLT_LOOP + { null_if_print, DLT_LOOP }, +#endif + { raw_if_print, DLT_RAW }, +#if !__rtems__ + { atm_if_print, DLT_ATM_RFC1483 }, +#endif +#ifdef DLT_C_HDLC + { chdlc_if_print, DLT_C_HDLC }, +#endif +#ifdef DLT_HDLC + { chdlc_if_print, DLT_HDLC }, +#endif +#ifdef DLT_PPP_SERIAL + { ppp_hdlc_if_print, DLT_PPP_SERIAL }, +#endif +#ifdef DLT_PPP_ETHER + { pppoe_if_print, DLT_PPP_ETHER }, +#endif +#ifdef DLT_LINUX_SLL + { sll_if_print, DLT_LINUX_SLL }, +#endif +#ifdef DLT_IEEE802_11 + { ieee802_11_if_print, DLT_IEEE802_11}, +#endif +#ifdef DLT_LTALK + { ltalk_if_print, DLT_LTALK }, +#endif +#if defined(DLT_PFLOG) && defined(HAVE_NET_PFVAR_H) + { pflog_if_print, DLT_PFLOG }, +#endif +#ifdef DLT_FR + { fr_if_print, DLT_FR }, +#endif +#ifdef DLT_FRELAY + { fr_if_print, DLT_FRELAY }, +#endif +#ifdef DLT_SUNATM + { sunatm_if_print, DLT_SUNATM }, +#endif +#ifdef DLT_IP_OVER_FC + { ipfc_if_print, DLT_IP_OVER_FC }, +#endif +#ifdef DLT_PRISM_HEADER + { prism_if_print, DLT_PRISM_HEADER }, +#endif +#ifdef DLT_IEEE802_11_RADIO + { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, +#endif +#ifdef DLT_ENC + { enc_if_print, DLT_ENC }, +#endif +#ifdef DLT_SYMANTEC_FIREWALL + { symantec_if_print, DLT_SYMANTEC_FIREWALL }, +#endif +#ifdef DLT_APPLE_IP_OVER_IEEE1394 + { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, +#endif +#ifdef DLT_IEEE802_11_RADIO_AVS + { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, +#endif +#ifdef DLT_JUNIPER_ATM1 + { juniper_atm1_print, DLT_JUNIPER_ATM1 }, +#endif +#ifdef DLT_JUNIPER_ATM2 + { juniper_atm2_print, DLT_JUNIPER_ATM2 }, +#endif +#ifdef DLT_JUNIPER_MFR + { juniper_mfr_print, DLT_JUNIPER_MFR }, +#endif +#ifdef DLT_JUNIPER_MLFR + { juniper_mlfr_print, DLT_JUNIPER_MLFR }, +#endif +#ifdef DLT_JUNIPER_MLPPP + { juniper_mlppp_print, DLT_JUNIPER_MLPPP }, +#endif +#ifdef DLT_JUNIPER_PPPOE + { juniper_pppoe_print, DLT_JUNIPER_PPPOE }, +#endif +#ifdef DLT_JUNIPER_PPPOE_ATM + { juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM }, +#endif +#ifdef DLT_JUNIPER_GGSN + { juniper_ggsn_print, DLT_JUNIPER_GGSN }, +#endif +#ifdef DLT_JUNIPER_ES + { juniper_es_print, DLT_JUNIPER_ES }, +#endif +#ifdef DLT_JUNIPER_MONITOR + { juniper_monitor_print, DLT_JUNIPER_MONITOR }, +#endif +#ifdef DLT_JUNIPER_SERVICES + { juniper_services_print, DLT_JUNIPER_SERVICES }, +#endif +#ifdef DLT_JUNIPER_ETHER + { juniper_ether_print, DLT_JUNIPER_ETHER }, +#endif +#ifdef DLT_JUNIPER_PPP + { juniper_ppp_print, DLT_JUNIPER_PPP }, +#endif +#ifdef DLT_JUNIPER_FRELAY + { juniper_frelay_print, DLT_JUNIPER_FRELAY }, +#endif +#ifdef DLT_JUNIPER_CHDLC + { juniper_chdlc_print, DLT_JUNIPER_CHDLC }, +#endif +#ifdef DLT_MFR + { mfr_if_print, DLT_MFR }, +#endif +#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) + { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, +#endif +#ifdef HAVE_PCAP_USB_H +#ifdef DLT_USB_LINUX + { usb_linux_48_byte_print, DLT_USB_LINUX}, +#endif /* DLT_USB_LINUX */ +#ifdef DLT_USB_LINUX_MMAPPED + { usb_linux_64_byte_print, DLT_USB_LINUX_MMAPPED}, +#endif /* DLT_USB_LINUX_MMAPPED */ +#endif /* HAVE_PCAP_USB_H */ +#ifdef DLT_IPV4 + { raw_if_print, DLT_IPV4 }, +#endif +#ifdef DLT_IPV6 + { raw_if_print, DLT_IPV6 }, +#endif + { NULL, 0 }, +}; + +static const struct ndo_printer ndo_printers[] = { + { ether_if_print, DLT_EN10MB }, +#ifdef DLT_IPNET + { ipnet_if_print, DLT_IPNET }, +#endif +#ifdef DLT_IEEE802_15_4 + { ieee802_15_4_if_print, DLT_IEEE802_15_4 }, +#endif +#ifdef DLT_IEEE802_15_4_NOFCS + { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS }, +#endif +#ifdef DLT_PPI + { ppi_if_print, DLT_PPI }, +#endif +#ifdef DLT_NETANALYZER + { netanalyzer_if_print, DLT_NETANALYZER }, +#endif +#ifdef DLT_NETANALYZER_TRANSPARENT + { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT }, +#endif + { NULL, 0 }, +}; + +if_printer +lookup_printer(int type) +{ + struct printer *p; + + for (p = printers; p->f; ++p) + if (type == p->type) + return p->f; + + return NULL; + /* NOTREACHED */ +} + +if_ndo_printer +lookup_ndo_printer(int type) +{ + struct ndo_printer *p; + + for (p = ndo_printers; p->f; ++p) + if (type == p->type) + return p->f; + + return NULL; + /* NOTREACHED */ +} + +static pcap_t *pd; + +static int supports_monitor_mode; + +#ifdef __rtems__ +#define optind getopt_data.optind +#define optarg getopt_data.optarg +#define opterr getopt_data.opterr +#define optopt getopt_data.optopt +#define getopt(argc, argv, opt) getopt_r(argc, argv, "+" opt, &getopt_data) +#else +extern int optind; +extern int opterr; +extern char *optarg; +#endif + +struct print_info { + netdissect_options *ndo; + union { + if_printer printer; + if_ndo_printer ndo_printer; + } p; + int ndo_type; +}; + +struct dump_info { + char *WFileName; + char *CurrentFileName; + pcap_t *pd; + pcap_dumper_t *p; +}; + +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE +static void +show_tstamp_types_and_exit(const char *device, pcap_t *pd) +{ + int n_tstamp_types; + int *tstamp_types = 0; + const char *tstamp_type_name; + int i; + + n_tstamp_types = pcap_list_tstamp_types(pd, &tstamp_types); + if (n_tstamp_types < 0) + error("%s", pcap_geterr(pd)); + + if (n_tstamp_types == 0) { + fprintf(stderr, "Time stamp type cannot be set for %s\n", + device); + exit(0); + } + fprintf(stderr, "Time stamp types for %s (use option -j to set):\n", + device); + for (i = 0; i < n_tstamp_types; i++) { + tstamp_type_name = pcap_tstamp_type_val_to_name(tstamp_types[i]); + if (tstamp_type_name != NULL) { + (void) fprintf(stderr, " %s (%s)\n", tstamp_type_name, + pcap_tstamp_type_val_to_description(tstamp_types[i])); + } else { + (void) fprintf(stderr, " %d\n", tstamp_types[i]); + } + } + pcap_free_tstamp_types(tstamp_types); + exit(0); +} +#endif + +static void +show_dlts_and_exit(const char *device, pcap_t *pd) +{ + int n_dlts; + int *dlts = 0; + const char *dlt_name; + + n_dlts = pcap_list_datalinks(pd, &dlts); + if (n_dlts < 0) + error("%s", pcap_geterr(pd)); + else if (n_dlts == 0 || !dlts) + error("No data link types."); + + /* + * If the interface is known to support monitor mode, indicate + * whether these are the data link types available when not in + * monitor mode, if -I wasn't specified, or when in monitor mode, + * when -I was specified (the link-layer types available in + * monitor mode might be different from the ones available when + * not in monitor mode). + */ + if (supports_monitor_mode) + (void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n", + device, + Iflag ? "when in monitor mode" : "when not in monitor mode"); + else + (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n", + device); + + while (--n_dlts >= 0) { + dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); + if (dlt_name != NULL) { + (void) fprintf(stderr, " %s (%s)", dlt_name, + pcap_datalink_val_to_description(dlts[n_dlts])); + + /* + * OK, does tcpdump handle that type? + */ + if (lookup_printer(dlts[n_dlts]) == NULL + && lookup_ndo_printer(dlts[n_dlts]) == NULL) + (void) fprintf(stderr, " (printing not supported)"); + fprintf(stderr, "\n"); + } else { + (void) fprintf(stderr, " DLT %d (printing not supported)\n", + dlts[n_dlts]); + } + } +#ifdef HAVE_PCAP_FREE_DATALINKS + pcap_free_datalinks(dlts); +#endif + exit(0); +} + +/* + * Set up flags that might or might not be supported depending on the + * version of libpcap we're using. + */ +#if defined(HAVE_PCAP_CREATE) || defined(WIN32) +#define B_FLAG "B:" +#define B_FLAG_USAGE " [ -B size ]" +#else /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ +#define B_FLAG +#define B_FLAG_USAGE +#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ + +#ifdef HAVE_PCAP_CREATE +#define I_FLAG "I" +#else /* HAVE_PCAP_CREATE */ +#define I_FLAG +#endif /* HAVE_PCAP_CREATE */ + +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE +#define j_FLAG "j:" +#define j_FLAG_USAGE " [ -j tstamptype ]" +#define J_FLAG "J" +#else /* PCAP_ERROR_TSTAMP_TYPE_NOTSUP */ +#define j_FLAG +#define j_FLAG_USAGE +#define J_FLAG +#endif /* PCAP_ERROR_TSTAMP_TYPE_NOTSUP */ + +#ifdef HAVE_PCAP_FINDALLDEVS +#ifndef HAVE_PCAP_IF_T +#undef HAVE_PCAP_FINDALLDEVS +#endif +#endif + +#ifdef HAVE_PCAP_FINDALLDEVS +#define D_FLAG "D" +#else +#define D_FLAG +#endif + +#ifdef HAVE_PCAP_DUMP_FLUSH +#define U_FLAG "U" +#else +#define U_FLAG +#endif + +#ifndef WIN32 +/* Drop root privileges and chroot if necessary */ +static void +droproot(const char *username, const char *chroot_dir) +{ + struct passwd *pw = NULL; + + if (chroot_dir && !username) { + fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n"); + exit(1); + } + + pw = getpwnam(username); + if (pw) { + if (chroot_dir) { + if (chroot(chroot_dir) != 0 || chdir ("/") != 0) { + fprintf(stderr, "tcpdump: Couldn't chroot/chdir to '%.64s': %s\n", + chroot_dir, pcap_strerror(errno)); + exit(1); + } + } +#ifdef HAVE_CAP_NG_H + int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG); + if (ret < 0) { + printf("error : ret %d\n", ret); + } + /* We don't need CAP_SETUID and CAP_SETGID */ + capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID); + capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID); + capng_update(CAPNG_DROP, CAPNG_PERMITTED, CAP_SETUID); + capng_update(CAPNG_DROP, CAPNG_PERMITTED, CAP_SETUID); + capng_apply(CAPNG_SELECT_BOTH); + +#else +#ifndef __rtems__ + if (initgroups(pw->pw_name, pw->pw_gid) != 0 || + setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { + fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n", + username, + (unsigned long)pw->pw_uid, + (unsigned long)pw->pw_gid, + pcap_strerror(errno)); + exit(1); + } +#endif +#endif /* HAVE_CAP_NG_H */ + } + else { + fprintf(stderr, "tcpdump: Couldn't find user '%.32s'\n", + username); + exit(1); + } +} +#endif /* WIN32 */ + +static int +getWflagChars(int x) +{ + int c = 0; + + x -= 1; + while (x > 0) { + c += 1; + x /= 10; + } + + return c; +} + + +static void +MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) +{ + char *filename = malloc(PATH_MAX + 1); + if (filename == NULL) + error("Makefilename: malloc"); + + /* Process with strftime if Gflag is set. */ + if (Gflag != 0) { + struct tm *local_tm; + + /* Convert Gflag_time to a usable format */ + if ((local_tm = localtime(&Gflag_time)) == NULL) { + error("MakeTimedFilename: localtime"); + } + + /* There's no good way to detect an error in strftime since a return + * value of 0 isn't necessarily failure. + */ + strftime(filename, PATH_MAX, orig_name, local_tm); + } else { + strncpy(filename, orig_name, PATH_MAX); + } + + if (cnt == 0 && max_chars == 0) + strncpy(buffer, filename, PATH_MAX + 1); + else + if (snprintf(buffer, PATH_MAX + 1, "%s%0*d", filename, max_chars, cnt) > PATH_MAX) + /* Report an error if the filename is too large */ + error("too many output files or filename is too long (> %d)", PATH_MAX); + free(filename); +} + +static int tcpdump_printf(netdissect_options *ndo _U_, + const char *fmt, ...) +{ + + va_list args; + int ret; + + va_start(args, fmt); + ret=vfprintf(stdout, fmt, args); + va_end(args); + + return ret; +} + +static struct print_info +get_print_info(int type) +{ + struct print_info printinfo; + + printinfo.ndo_type = 1; + printinfo.ndo = gndo; + printinfo.p.ndo_printer = lookup_ndo_printer(type); + if (printinfo.p.ndo_printer == NULL) { + printinfo.p.printer = lookup_printer(type); + printinfo.ndo_type = 0; + if (printinfo.p.printer == NULL) { + gndo->ndo_dltname = pcap_datalink_val_to_name(type); + if (gndo->ndo_dltname != NULL) + error("packet printing is not supported for link type %s: use -w", + gndo->ndo_dltname); + else + error("packet printing is not supported for link type %d: use -w", type); + } + } + return (printinfo); +} + +static char * +get_next_file(FILE *VFile, char *ptr) +{ + char *ret; + + ret = fgets(ptr, PATH_MAX, VFile); + if (!ret) + return NULL; + + if (ptr[strlen(ptr) - 1] == '\n') + ptr[strlen(ptr) - 1] = '\0'; + + return ret; +} + +#ifdef __rtems__ +static int main(int argc, char **argv); + +int rtems_bsd_command_tcpdump(int argc, char *argv[]) +{ + int exit_code; + + rtems_bsd_program_lock(); + + dflag = 0; + Lflag = 0; +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + Jflag = 0; +#endif + zflag = NULL; + infodelay = 0; + infoprint = 0; + program_name = NULL; + thiszone = 0; + packets_captured = 0; + pd = 0; + supports_monitor_mode = 0; + + exit_code = rtems_bsd_program_call_main("tcpdump", main, argc, argv); + + rtems_bsd_program_unlock(); + + return exit_code; +} +#endif /* __rtems__ */ +int +#ifndef __rtems__ +main(int argc, char *const *argv) +#else /* __rtems__ */ +main(int argc, char **argv) +#endif /* __rtems__ */ +{ + register int cnt, op, i; + bpf_u_int32 localnet, netmask; + register char *cp, *infile, *cmdbuf, *device, *RFileName, *VFileName, *WFileName; + pcap_handler callback; + int type; + int dlt; + int new_dlt; + const char *dlt_name; + struct bpf_program fcode; +#ifndef WIN32 + RETSIGTYPE (*oldhandler)(int); +#endif + struct print_info printinfo; + struct dump_info dumpinfo; + u_char *pcap_userdata; + char ebuf[PCAP_ERRBUF_SIZE]; + char VFileLine[PATH_MAX + 1]; + char *username = NULL; + char *chroot_dir = NULL; + char *ret = NULL; + char *end; +#ifdef HAVE_PCAP_FINDALLDEVS + pcap_if_t *devpointer; + int devnum; +#endif + int status; + FILE *VFile; +#ifdef __rtems__ + struct getopt_data getopt_data; + memset(&getopt_data, 0, sizeof(getopt_data)); +#endif +#ifdef WIN32 + if(wsockinit() != 0) return 1; +#endif /* WIN32 */ + + jflag=-1; /* not set */ + gndo->ndo_Oflag=1; + gndo->ndo_Rflag=1; + gndo->ndo_dlt=-1; + gndo->ndo_default_print=ndo_default_print; + gndo->ndo_printf=tcpdump_printf; + gndo->ndo_error=ndo_error; + gndo->ndo_warning=ndo_warning; + gndo->ndo_snaplen = DEFAULT_SNAPLEN; + + cnt = -1; + device = NULL; + infile = NULL; + RFileName = NULL; + VFileName = NULL; + VFile = NULL; + WFileName = NULL; + dlt = -1; + if ((cp = strrchr(argv[0], '/')) != NULL) + program_name = cp + 1; + else + program_name = argv[0]; + + if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0) + error("%s", ebuf); + +#ifdef LIBSMI + smiInit("tcpdump"); +#endif + + while ( + (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "V:vw:W:xXy:Yz:Z:")) != -1) + switch (op) { + + case 'a': + /* compatibility for old -a */ + break; + + case 'A': + ++Aflag; + break; + + case 'b': + ++bflag; + break; + +#if defined(HAVE_PCAP_CREATE) || defined(WIN32) + case 'B': + Bflag = atoi(optarg)*1024; + if (Bflag <= 0) + error("invalid packet buffer size %s", optarg); + break; +#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ + + case 'c': + cnt = atoi(optarg); + if (cnt <= 0) + error("invalid packet count %s", optarg); + break; + + case 'C': + Cflag = atoi(optarg) * 1000000; + if (Cflag < 0) + error("invalid file size %s", optarg); + break; + + case 'd': + ++dflag; + break; + +#ifdef HAVE_PCAP_FINDALLDEVS + case 'D': + if (pcap_findalldevs(&devpointer, ebuf) < 0) + error("%s", ebuf); + else { + for (i = 0; devpointer != 0; i++) { + printf("%d.%s", i+1, devpointer->name); + if (devpointer->description != NULL) + printf(" (%s)", devpointer->description); + printf("\n"); + devpointer = devpointer->next; + } + } + return 0; +#endif /* HAVE_PCAP_FINDALLDEVS */ + + case 'L': + Lflag++; + break; + + case 'e': + ++eflag; + break; + + case 'E': +#ifndef HAVE_LIBCRYPTO + warning("crypto code not compiled in"); +#endif + gndo->ndo_espsecret = optarg; + break; + + case 'f': + ++fflag; + break; + + case 'F': + infile = optarg; + break; + + case 'G': + Gflag = atoi(optarg); + if (Gflag < 0) + error("invalid number of seconds %s", optarg); + + /* We will create one file initially. */ + Gflag_count = 0; + + /* Grab the current time for rotation use. */ + if ((Gflag_time = time(NULL)) == (time_t)-1) { + error("main: can't get current time: %s", + pcap_strerror(errno)); + } + break; + + case 'h': + usage(); + break; + + case 'H': + ++Hflag; + break; + + case 'i': + if (optarg[0] == '0' && optarg[1] == 0) + error("Invalid adapter index"); + +#ifdef HAVE_PCAP_FINDALLDEVS + /* + * If the argument is a number, treat it as + * an index into the list of adapters, as + * printed by "tcpdump -D". + * + * This should be OK on UNIX systems, as interfaces + * shouldn't have names that begin with digits. + * It can be useful on Windows, where more than + * one interface can have the same name. + */ + devnum = strtol(optarg, &end, 10); + if (optarg != end && *end == '\0') { + if (devnum < 0) + error("Invalid adapter index"); + + if (pcap_findalldevs(&devpointer, ebuf) < 0) + error("%s", ebuf); + else { + /* + * Look for the devnum-th entry + * in the list of devices + * (1-based). + */ + for (i = 0; + i < devnum-1 && devpointer != NULL; + i++, devpointer = devpointer->next) + ; + if (devpointer == NULL) + error("Invalid adapter index"); + } + device = devpointer->name; + break; + } +#endif /* HAVE_PCAP_FINDALLDEVS */ + device = optarg; + break; + +#ifdef HAVE_PCAP_CREATE + case 'I': + ++Iflag; + break; +#endif /* HAVE_PCAP_CREATE */ + +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + case 'j': + jflag = pcap_tstamp_type_name_to_val(optarg); + if (jflag < 0) + error("invalid time stamp type %s", optarg); + break; + + case 'J': + Jflag++; + break; +#endif + + case 'l': +#ifdef WIN32 + /* + * _IOLBF is the same as _IOFBF in Microsoft's C + * libraries; the only alternative they offer + * is _IONBF. + * + * XXX - this should really be checking for MSVC++, + * not WIN32, if, for example, MinGW has its own + * C library that is more UNIX-compatible. + */ + setvbuf(stdout, NULL, _IONBF, 0); +#else /* WIN32 */ +#ifdef HAVE_SETLINEBUF + setlinebuf(stdout); +#else + setvbuf(stdout, NULL, _IOLBF, 0); +#endif +#endif /* WIN32 */ + break; + + case 'K': + ++Kflag; + break; + + case 'm': +#ifdef LIBSMI + if (smiLoadModule(optarg) == 0) { + error("could not load MIB module %s", optarg); + } + sflag = 1; +#else + (void)fprintf(stderr, "%s: ignoring option `-m %s' ", + program_name, optarg); + (void)fprintf(stderr, "(no libsmi support)\n"); +#endif + break; + + case 'M': + /* TCP-MD5 shared secret */ +#ifndef HAVE_LIBCRYPTO + warning("crypto code not compiled in"); +#endif + sigsecret = optarg; + break; + + case 'n': + ++nflag; + break; + + case 'N': + ++Nflag; + break; + + case 'O': + Oflag = 0; + break; + + case 'p': + ++pflag; + break; + + case 'q': + ++qflag; + ++suppress_default_print; + break; + + case 'r': + RFileName = optarg; + break; + + case 'R': + Rflag = 0; + break; + + case 's': + snaplen = strtol(optarg, &end, 0); + if (optarg == end || *end != '\0' + || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN) + error("invalid snaplen %s", optarg); + else if (snaplen == 0) + snaplen = MAXIMUM_SNAPLEN; + break; + + case 'S': + ++Sflag; + break; + + case 't': + ++tflag; + break; + + case 'T': + if (strcasecmp(optarg, "vat") == 0) + packettype = PT_VAT; + else if (strcasecmp(optarg, "wb") == 0) + packettype = PT_WB; + else if (strcasecmp(optarg, "rpc") == 0) + packettype = PT_RPC; + else if (strcasecmp(optarg, "rtp") == 0) + packettype = PT_RTP; + else if (strcasecmp(optarg, "rtcp") == 0) + packettype = PT_RTCP; + else if (strcasecmp(optarg, "snmp") == 0) + packettype = PT_SNMP; + else if (strcasecmp(optarg, "cnfp") == 0) + packettype = PT_CNFP; + else if (strcasecmp(optarg, "tftp") == 0) + packettype = PT_TFTP; + else if (strcasecmp(optarg, "aodv") == 0) + packettype = PT_AODV; + else if (strcasecmp(optarg, "carp") == 0) + packettype = PT_CARP; + else if (strcasecmp(optarg, "radius") == 0) + packettype = PT_RADIUS; + else if (strcasecmp(optarg, "zmtp1") == 0) + packettype = PT_ZMTP1; + else if (strcasecmp(optarg, "vxlan") == 0) + packettype = PT_VXLAN; + else + error("unknown packet type `%s'", optarg); + break; + + case 'u': + ++uflag; + break; + +#ifdef HAVE_PCAP_DUMP_FLUSH + case 'U': + ++Uflag; + break; +#endif + + case 'v': + ++vflag; + break; + + case 'V': + VFileName = optarg; + break; + + case 'w': + WFileName = optarg; + break; + + case 'W': + Wflag = atoi(optarg); + if (Wflag < 0) + error("invalid number of output files %s", optarg); + WflagChars = getWflagChars(Wflag); + break; + + case 'x': + ++xflag; + ++suppress_default_print; + break; + + case 'X': + ++Xflag; + ++suppress_default_print; + break; + + case 'y': + gndo->ndo_dltname = optarg; + gndo->ndo_dlt = + pcap_datalink_name_to_val(gndo->ndo_dltname); + if (gndo->ndo_dlt < 0) + error("invalid data link type %s", gndo->ndo_dltname); + break; + +#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) + case 'Y': + { + /* Undocumented flag */ +#ifdef HAVE_PCAP_DEBUG + extern int pcap_debug; + pcap_debug = 1; +#else + extern int yydebug; + yydebug = 1; +#endif + } + break; +#endif + case 'z': + if (optarg) { + zflag = strdup(optarg); + } else { + usage(); + /* NOTREACHED */ + } + break; + + case 'Z': + if (optarg) { + username = strdup(optarg); + } + else { + usage(); + /* NOTREACHED */ + } + break; + + default: + usage(); + /* NOTREACHED */ + } + + switch (tflag) { + + case 0: /* Default */ + case 4: /* Default + Date*/ + thiszone = gmt2local(0); + break; + + case 1: /* No time stamp */ + case 2: /* Unix timeval style */ + case 3: /* Microseconds since previous packet */ + case 5: /* Microseconds since first packet */ + break; + + default: /* Not supported */ + error("only -t, -tt, -ttt, -tttt and -ttttt are supported"); + break; + } + + if (fflag != 0 && (VFileName != NULL || RFileName != NULL)) + error("-f can not be used with -V or -r"); + + if (VFileName != NULL && RFileName != NULL) + error("-V and -r are mutually exclusive."); + +#ifdef WITH_CHROOT + /* if run as root, prepare for chrooting */ + if (getuid() == 0 || geteuid() == 0) { + /* future extensibility for cmd-line arguments */ + if (!chroot_dir) + chroot_dir = WITH_CHROOT; + } +#endif + +#ifdef WITH_USER + /* if run as root, prepare for dropping root privileges */ + if (getuid() == 0 || geteuid() == 0) { + /* Run with '-Z root' to restore old behaviour */ + if (!username) + username = WITH_USER; + } +#endif + + if (RFileName != NULL || VFileName != NULL) { + /* + * If RFileName is non-null, it's the pathname of a + * savefile to read. If VFileName is non-null, it's + * the pathname of a file containing a list of pathnames + * (one per line) of savefiles to read. + * + * In either case, we're reading a savefile, not doing + * a live capture. + */ +#ifndef WIN32 + /* + * We don't need network access, so relinquish any set-UID + * or set-GID privileges we have (if any). + * + * We do *not* want set-UID privileges when opening a + * trace file, as that might let the user read other + * people's trace files (especially if we're set-UID + * root). + */ + if (setgid(getgid()) != 0 || setuid(getuid()) != 0 ) + fprintf(stderr, "Warning: setgid/setuid failed !\n"); +#endif /* WIN32 */ + if (VFileName != NULL) { + if (VFileName[0] == '-' && VFileName[1] == '\0') + VFile = stdin; + else + VFile = fopen(VFileName, "r"); + + if (VFile == NULL) + error("Unable to open file: %s\n", strerror(errno)); + + ret = get_next_file(VFile, VFileLine); + if (!ret) + error("Nothing in %s\n", VFileName); + RFileName = VFileLine; + } + + pd = pcap_open_offline(RFileName, ebuf); + if (pd == NULL) + error("%s", ebuf); + dlt = pcap_datalink(pd); + dlt_name = pcap_datalink_val_to_name(dlt); + if (dlt_name == NULL) { + fprintf(stderr, "reading from file %s, link-type %u\n", + RFileName, dlt); + } else { + fprintf(stderr, + "reading from file %s, link-type %s (%s)\n", + RFileName, dlt_name, + pcap_datalink_val_to_description(dlt)); + } + localnet = 0; + netmask = 0; + } else { + /* + * We're doing a live capture. + */ + if (device == NULL) { + device = pcap_lookupdev(ebuf); + if (device == NULL) + error("%s", ebuf); + } +#ifdef WIN32 + /* + * Print a message to the standard error on Windows. + * XXX - why do it here, with a different message? + */ + if(strlen(device) == 1) //we assume that an ASCII string is always longer than 1 char + { //a Unicode string has a \0 as second byte (so strlen() is 1) + fprintf(stderr, "%s: listening on %ws\n", program_name, device); + } + else + { + fprintf(stderr, "%s: listening on %s\n", program_name, device); + } + + fflush(stderr); +#endif /* WIN32 */ +#ifdef HAVE_PCAP_CREATE + pd = pcap_create(device, ebuf); + if (pd == NULL) + error("%s", ebuf); +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + if (Jflag) + show_tstamp_types_and_exit(device, pd); +#endif + /* + * Is this an interface that supports monitor mode? + */ + if (pcap_can_set_rfmon(pd) == 1) + supports_monitor_mode = 1; + else + supports_monitor_mode = 0; + status = pcap_set_snaplen(pd, snaplen); + if (status != 0) + error("%s: Can't set snapshot length: %s", + device, pcap_statustostr(status)); + status = pcap_set_promisc(pd, !pflag); + if (status != 0) + error("%s: Can't set promiscuous mode: %s", + device, pcap_statustostr(status)); + if (Iflag) { + status = pcap_set_rfmon(pd, 1); + if (status != 0) + error("%s: Can't set monitor mode: %s", + device, pcap_statustostr(status)); + } + status = pcap_set_timeout(pd, 1000); + if (status != 0) + error("%s: pcap_set_timeout failed: %s", + device, pcap_statustostr(status)); + if (Bflag != 0) { + status = pcap_set_buffer_size(pd, Bflag); + if (status != 0) + error("%s: Can't set buffer size: %s", + device, pcap_statustostr(status)); + } +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + if (jflag != -1) { + status = pcap_set_tstamp_type(pd, jflag); + if (status < 0) + error("%s: Can't set time stamp type: %s", + device, pcap_statustostr(status)); + } +#endif + status = pcap_activate(pd); + if (status < 0) { + /* + * pcap_activate() failed. + */ + cp = pcap_geterr(pd); + if (status == PCAP_ERROR) + error("%s", cp); + else if ((status == PCAP_ERROR_NO_SUCH_DEVICE || + status == PCAP_ERROR_PERM_DENIED) && + *cp != '\0') + error("%s: %s\n(%s)", device, + pcap_statustostr(status), cp); + else + error("%s: %s", device, + pcap_statustostr(status)); + } else if (status > 0) { + /* + * pcap_activate() succeeded, but it's warning us + * of a problem it had. + */ + cp = pcap_geterr(pd); + if (status == PCAP_WARNING) + warning("%s", cp); + else if (status == PCAP_WARNING_PROMISC_NOTSUP && + *cp != '\0') + warning("%s: %s\n(%s)", device, + pcap_statustostr(status), cp); + else + warning("%s: %s", device, + pcap_statustostr(status)); + } +#else + *ebuf = '\0'; + pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); + if (pd == NULL) + error("%s", ebuf); + else if (*ebuf) + warning("%s", ebuf); +#endif /* HAVE_PCAP_CREATE */ + /* + * Let user own process after socket has been opened. + */ +#ifndef WIN32 + if (setgid(getgid()) != 0 || setuid(getuid()) != 0) + fprintf(stderr, "Warning: setgid/setuid failed !\n"); +#endif /* WIN32 */ +#if !defined(HAVE_PCAP_CREATE) && defined(WIN32) + if(Bflag != 0) + if(pcap_setbuff(pd, Bflag)==-1){ + error("%s", pcap_geterr(pd)); + } +#endif /* !defined(HAVE_PCAP_CREATE) && defined(WIN32) */ + if (Lflag) + show_dlts_and_exit(device, pd); + if (gndo->ndo_dlt >= 0) { +#ifdef HAVE_PCAP_SET_DATALINK + if (pcap_set_datalink(pd, gndo->ndo_dlt) < 0) + error("%s", pcap_geterr(pd)); +#else + /* + * We don't actually support changing the + * data link type, so we only let them + * set it to what it already is. + */ + if (gndo->ndo_dlt != pcap_datalink(pd)) { + error("%s is not one of the DLTs supported by this device\n", + gndo->ndo_dltname); + } +#endif + (void)fprintf(stderr, "%s: data link type %s\n", + program_name, gndo->ndo_dltname); + (void)fflush(stderr); + } + i = pcap_snapshot(pd); + if (snaplen < i) { + warning("snaplen raised from %d to %d", snaplen, i); + snaplen = i; + } + if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { + localnet = 0; + netmask = 0; + warning("%s", ebuf); + } + } + if (infile) + cmdbuf = read_infile(infile); + else + cmdbuf = copy_argv(&argv[optind]); + + if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) + error("%s", pcap_geterr(pd)); + if (dflag) { + bpf_dump(&fcode, dflag); + pcap_close(pd); + free(cmdbuf); + exit(0); + } + init_addrtoname(localnet, netmask); + init_checksum(); + +#ifndef WIN32 + (void)setsignal(SIGPIPE, cleanup); + (void)setsignal(SIGTERM, cleanup); + (void)setsignal(SIGINT, cleanup); +#endif /* WIN32 */ +#if defined(HAVE_FORK) || defined(HAVE_VFORK) + (void)setsignal(SIGCHLD, child_cleanup); +#endif + /* Cooperate with nohup(1) */ +#ifndef WIN32 + if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) + (void)setsignal(SIGHUP, oldhandler); +#endif /* WIN32 */ + +#ifndef WIN32 + /* + * If a user name was specified with "-Z", attempt to switch to + * that user's UID. This would probably be used with sudo, + * to allow tcpdump to be run in a special restricted + * account (if you just want to allow users to open capture + * devices, and can't just give users that permission, + * you'd make tcpdump set-UID or set-GID). + * + * Tcpdump doesn't necessarily write only to one savefile; + * the general only way to allow a -Z instance to write to + * savefiles as the user under whose UID it's run, rather + * than as the user specified with -Z, would thus be to switch + * to the original user ID before opening a capture file and + * then switch back to the -Z user ID after opening the savefile. + * Switching to the -Z user ID only after opening the first + * savefile doesn't handle the general case. + */ + +#ifdef HAVE_CAP_NG_H + /* We are running as root and we will be writing to savefile */ + if ((getuid() == 0 || geteuid() == 0) && WFileName) { + if (username) { + /* Drop all capabilities from effective set */ + capng_clear(CAPNG_EFFECTIVE); + /* Add capabilities we will need*/ + capng_update(CAPNG_ADD, CAPNG_PERMITTED, CAP_SETUID); + capng_update(CAPNG_ADD, CAPNG_PERMITTED, CAP_SETGID); + capng_update(CAPNG_ADD, CAPNG_PERMITTED, CAP_DAC_OVERRIDE); + + capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_SETUID); + capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_SETGID); + capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); + + capng_apply(CAPNG_SELECT_BOTH); + } + } +#endif /* HAVE_CAP_NG_H */ + + if (getuid() == 0 || geteuid() == 0) { + if (username || chroot_dir) + droproot(username, chroot_dir); + + } +#endif /* WIN32 */ + + if (pcap_setfilter(pd, &fcode) < 0) + error("%s", pcap_geterr(pd)); + if (WFileName) { + pcap_dumper_t *p; + /* Do not exceed the default PATH_MAX for files. */ + dumpinfo.CurrentFileName = (char *)malloc(PATH_MAX + 1); + + if (dumpinfo.CurrentFileName == NULL) + error("malloc of dumpinfo.CurrentFileName"); + + /* We do not need numbering for dumpfiles if Cflag isn't set. */ + if (Cflag != 0) + MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, WflagChars); + else + MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0); + + p = pcap_dump_open(pd, dumpinfo.CurrentFileName); +#ifdef HAVE_CAP_NG_H + /* Give up capabilities, clear Effective set */ + capng_clear(CAPNG_EFFECTIVE); +#endif + if (p == NULL) + error("%s", pcap_geterr(pd)); + if (Cflag != 0 || Gflag != 0) { + callback = dump_packet_and_trunc; + dumpinfo.WFileName = WFileName; + dumpinfo.pd = pd; + dumpinfo.p = p; + pcap_userdata = (u_char *)&dumpinfo; + } else { + callback = dump_packet; + pcap_userdata = (u_char *)p; + } +#ifdef HAVE_PCAP_DUMP_FLUSH + if (Uflag) + pcap_dump_flush(p); +#endif + } else { + type = pcap_datalink(pd); + printinfo = get_print_info(type); + callback = print_packet; + pcap_userdata = (u_char *)&printinfo; + } + +#ifdef SIGNAL_REQ_INFO + /* + * We can't get statistics when reading from a file rather + * than capturing from a device. + */ + if (RFileName == NULL) + (void)setsignal(SIGNAL_REQ_INFO, requestinfo); +#endif + + if (vflag > 0 && WFileName) { + /* + * When capturing to a file, "-v" means tcpdump should, + * every 10 secodns, "v"erbosely report the number of + * packets captured. + */ +#ifdef USE_WIN32_MM_TIMER + /* call verbose_stats_dump() each 1000 +/-100msec */ + timer_id = timeSetEvent(1000, 100, verbose_stats_dump, 0, TIME_PERIODIC); + setvbuf(stderr, NULL, _IONBF, 0); +#elif defined(HAVE_ALARM) + (void)setsignal(SIGALRM, verbose_stats_dump); + alarm(1); +#endif + } + +#ifndef WIN32 + if (RFileName == NULL) { + /* + * Live capture (if -V was specified, we set RFileName + * to a file from the -V file). Print a message to + * the standard error on UN*X. + */ + if (!vflag && !WFileName) { + (void)fprintf(stderr, + "%s: verbose output suppressed, use -v or -vv for full protocol decode\n", + program_name); + } else + (void)fprintf(stderr, "%s: ", program_name); + dlt = pcap_datalink(pd); + dlt_name = pcap_datalink_val_to_name(dlt); + if (dlt_name == NULL) { + (void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n", + device, dlt, snaplen); + } else { + (void)fprintf(stderr, "listening on %s, link-type %s (%s), capture size %u bytes\n", + device, dlt_name, + pcap_datalink_val_to_description(dlt), snaplen); + } + (void)fflush(stderr); + } +#endif /* WIN32 */ + do { + status = pcap_loop(pd, cnt, callback, pcap_userdata); + if (WFileName == NULL) { + /* + * We're printing packets. Flush the printed output, + * so it doesn't get intermingled with error output. + */ + if (status == -2) { + /* + * We got interrupted, so perhaps we didn't + * manage to finish a line we were printing. + * Print an extra newline, just in case. + */ + putchar('\n'); + } + (void)fflush(stdout); + } + if (status == -1) { + /* + * Error. Report it. + */ + (void)fprintf(stderr, "%s: pcap_loop: %s\n", + program_name, pcap_geterr(pd)); + } + if (RFileName == NULL) { + /* + * We're doing a live capture. Report the capture + * statistics. + */ + info(1); + } + pcap_close(pd); + if (VFileName != NULL) { + ret = get_next_file(VFile, VFileLine); + if (ret) { + RFileName = VFileLine; + pd = pcap_open_offline(RFileName, ebuf); + if (pd == NULL) + error("%s", ebuf); + new_dlt = pcap_datalink(pd); + if (WFileName && new_dlt != dlt) + error("%s: new dlt does not match original", RFileName); + printinfo = get_print_info(new_dlt); + dlt_name = pcap_datalink_val_to_name(new_dlt); + if (dlt_name == NULL) { + fprintf(stderr, "reading from file %s, link-type %u\n", + RFileName, new_dlt); + } else { + fprintf(stderr, + "reading from file %s, link-type %s (%s)\n", + RFileName, dlt_name, + pcap_datalink_val_to_description(new_dlt)); + } + if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) + error("%s", pcap_geterr(pd)); + if (pcap_setfilter(pd, &fcode) < 0) + error("%s", pcap_geterr(pd)); + } + } + } + while (ret != NULL); + + free(cmdbuf); + exit(status == -1 ? 1 : 0); +} + +/* make a clean exit on interrupts */ +static RETSIGTYPE +cleanup(int signo _U_) +{ +#ifdef USE_WIN32_MM_TIMER + if (timer_id) + timeKillEvent(timer_id); + timer_id = 0; +#elif defined(HAVE_ALARM) + alarm(0); +#endif + +#ifdef HAVE_PCAP_BREAKLOOP + /* + * We have "pcap_breakloop()"; use it, so that we do as little + * as possible in the signal handler (it's probably not safe + * to do anything with standard I/O streams in a signal handler - + * the ANSI C standard doesn't say it is). + */ + pcap_breakloop(pd); +#else + /* + * We don't have "pcap_breakloop()"; this isn't safe, but + * it's the best we can do. Print the summary if we're + * not reading from a savefile - i.e., if we're doing a + * live capture - and exit. + */ + if (pd != NULL && pcap_file(pd) == NULL) { + /* + * We got interrupted, so perhaps we didn't + * manage to finish a line we were printing. + * Print an extra newline, just in case. + */ + putchar('\n'); + (void)fflush(stdout); + info(1); + } + exit(0); +#endif +} + +/* + On windows, we do not use a fork, so we do not care less about + waiting a child processes to die + */ +#if defined(HAVE_FORK) || defined(HAVE_VFORK) +static RETSIGTYPE +child_cleanup(int signo _U_) +{ + wait(NULL); +} +#endif /* HAVE_FORK && HAVE_VFORK */ + +static void +info(register int verbose) +{ + struct pcap_stat stat; + + /* + * Older versions of libpcap didn't set ps_ifdrop on some + * platforms; initialize it to 0 to handle that. + */ + stat.ps_ifdrop = 0; + if (pcap_stats(pd, &stat) < 0) { + (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd)); + infoprint = 0; + return; + } + + if (!verbose) + fprintf(stderr, "%s: ", program_name); + + (void)fprintf(stderr, "%u packet%s captured", packets_captured, + PLURAL_SUFFIX(packets_captured)); + if (!verbose) + fputs(", ", stderr); + else + putc('\n', stderr); + (void)fprintf(stderr, "%u packet%s received by filter", stat.ps_recv, + PLURAL_SUFFIX(stat.ps_recv)); + if (!verbose) + fputs(", ", stderr); + else + putc('\n', stderr); + (void)fprintf(stderr, "%u packet%s dropped by kernel", stat.ps_drop, + PLURAL_SUFFIX(stat.ps_drop)); + if (stat.ps_ifdrop != 0) { + if (!verbose) + fputs(", ", stderr); + else + putc('\n', stderr); + (void)fprintf(stderr, "%u packet%s dropped by interface\n", + stat.ps_ifdrop, PLURAL_SUFFIX(stat.ps_ifdrop)); + } else + putc('\n', stderr); + infoprint = 0; +} + +#if defined(HAVE_FORK) || defined(HAVE_VFORK) +static void +compress_savefile(const char *filename) +{ +# ifdef HAVE_FORK + if (fork()) +# else + if (vfork()) +# endif + return; + /* + * Set to lowest priority so that this doesn't disturb the capture + */ +#ifdef NZERO + setpriority(PRIO_PROCESS, 0, NZERO - 1); +#else + setpriority(PRIO_PROCESS, 0, 19); +#endif + if (execlp(zflag, zflag, filename, (char *)NULL) == -1) + fprintf(stderr, + "compress_savefile:execlp(%s, %s): %s\n", + zflag, + filename, + strerror(errno)); +# ifdef HAVE_FORK + exit(1); +# else + _exit(1); +# endif +} +#else /* HAVE_FORK && HAVE_VFORK */ +static void +compress_savefile(const char *filename) +{ + fprintf(stderr, + "compress_savefile failed. Functionality not implemented under your system\n"); +} +#endif /* HAVE_FORK && HAVE_VFORK */ + +static void +dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) +{ + struct dump_info *dump_info; + + ++packets_captured; + + ++infodelay; + + dump_info = (struct dump_info *)user; + + /* + * XXX - this won't force the file to rotate on the specified time + * boundary, but it will rotate on the first packet received after the + * specified Gflag number of seconds. Note: if a Gflag time boundary + * and a Cflag size boundary coincide, the time rotation will occur + * first thereby cancelling the Cflag boundary (since the file should + * be 0). + */ + if (Gflag != 0) { + /* Check if it is time to rotate */ + time_t t; + + /* Get the current time */ + if ((t = time(NULL)) == (time_t)-1) { + error("dump_and_trunc_packet: can't get current_time: %s", + pcap_strerror(errno)); + } + + + /* If the time is greater than the specified window, rotate */ + if (t - Gflag_time >= Gflag) { + /* Update the Gflag_time */ + Gflag_time = t; + /* Update Gflag_count */ + Gflag_count++; + /* + * Close the current file and open a new one. + */ + pcap_dump_close(dump_info->p); + + /* + * Compress the file we just closed, if the user asked for it + */ + if (zflag != NULL) + compress_savefile(dump_info->CurrentFileName); + + /* + * Check to see if we've exceeded the Wflag (when + * not using Cflag). + */ + if (Cflag == 0 && Wflag > 0 && Gflag_count >= Wflag) { + (void)fprintf(stderr, "Maximum file limit reached: %d\n", + Wflag); + exit(0); + /* NOTREACHED */ + } + if (dump_info->CurrentFileName != NULL) + free(dump_info->CurrentFileName); + /* Allocate space for max filename + \0. */ + dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1); + if (dump_info->CurrentFileName == NULL) + error("dump_packet_and_trunc: malloc"); + /* + * This is always the first file in the Cflag + * rotation: e.g. 0 + * We also don't need numbering if Cflag is not set. + */ + if (Cflag != 0) + MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0, + WflagChars); + else + MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0, 0); + +#ifdef HAVE_CAP_NG_H + capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); + capng_apply(CAPNG_EFFECTIVE); +#endif /* HAVE_CAP_NG_H */ + dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); +#ifdef HAVE_CAP_NG_H + capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); + capng_apply(CAPNG_EFFECTIVE); +#endif /* HAVE_CAP_NG_H */ + if (dump_info->p == NULL) + error("%s", pcap_geterr(pd)); + } + } + + /* + * XXX - this won't prevent capture files from getting + * larger than Cflag - the last packet written to the + * file could put it over Cflag. + */ + if (Cflag != 0 && pcap_dump_ftell(dump_info->p) > Cflag) { + /* + * Close the current file and open a new one. + */ + pcap_dump_close(dump_info->p); + + /* + * Compress the file we just closed, if the user asked for it + */ + if (zflag != NULL) + compress_savefile(dump_info->CurrentFileName); + + Cflag_count++; + if (Wflag > 0) { + if (Cflag_count >= Wflag) + Cflag_count = 0; + } + if (dump_info->CurrentFileName != NULL) + free(dump_info->CurrentFileName); + dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1); + if (dump_info->CurrentFileName == NULL) + error("dump_packet_and_trunc: malloc"); + MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, Cflag_count, WflagChars); + dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); + if (dump_info->p == NULL) + error("%s", pcap_geterr(pd)); + } + + pcap_dump((u_char *)dump_info->p, h, sp); +#ifdef HAVE_PCAP_DUMP_FLUSH + if (Uflag) + pcap_dump_flush(dump_info->p); +#endif + + --infodelay; + if (infoprint) + info(0); +} + +static void +dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) +{ + ++packets_captured; + + ++infodelay; + + pcap_dump(user, h, sp); +#ifdef HAVE_PCAP_DUMP_FLUSH + if (Uflag) + pcap_dump_flush((pcap_dumper_t *)user); +#endif + + --infodelay; + if (infoprint) + info(0); +} + +static void +print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) +{ + struct print_info *print_info; + u_int hdrlen; + + ++packets_captured; + + ++infodelay; + ts_print(&h->ts); + + print_info = (struct print_info *)user; + + /* + * Some printers want to check that they're not walking off the + * end of the packet. + * Rather than pass it all the way down, we set this global. + */ + snapend = sp + h->caplen; + + if(print_info->ndo_type) { + hdrlen = (*print_info->p.ndo_printer)(print_info->ndo, h, sp); + } else { + hdrlen = (*print_info->p.printer)(h, sp); + } + + if (Xflag) { + /* + * Print the raw packet data in hex and ASCII. + */ + if (Xflag > 1) { + /* + * Include the link-layer header. + */ + hex_and_ascii_print("\n\t", sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + hex_and_ascii_print("\n\t", sp + hdrlen, + h->caplen - hdrlen); + } + } else if (xflag) { + /* + * Print the raw packet data in hex. + */ + if (xflag > 1) { + /* + * Include the link-layer header. + */ + hex_print("\n\t", sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + hex_print("\n\t", sp + hdrlen, + h->caplen - hdrlen); + } + } else if (Aflag) { + /* + * Print the raw packet data in ASCII. + */ + if (Aflag > 1) { + /* + * Include the link-layer header. + */ + ascii_print(sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + ascii_print(sp + hdrlen, h->caplen - hdrlen); + } + } + + putchar('\n'); + + --infodelay; + if (infoprint) + info(0); +} + +#ifdef WIN32 + /* + * XXX - there should really be libpcap calls to get the version + * number as a string (the string would be generated from #defines + * at run time, so that it's not generated from string constants + * in the library, as, on many UNIX systems, those constants would + * be statically linked into the application executable image, and + * would thus reflect the version of libpcap on the system on + * which the application was *linked*, not the system on which it's + * *running*. + * + * That routine should be documented, unlike the "version[]" + * string, so that UNIX vendors providing their own libpcaps + * don't omit it (as a couple of vendors have...). + * + * Packet.dll should perhaps also export a routine to return the + * version number of the Packet.dll code, to supply the + * "Wpcap_version" information on Windows. + */ + char WDversion[]="current-cvs.tcpdump.org"; +#if !defined(HAVE_GENERATED_VERSION) + char version[]="current-cvs.tcpdump.org"; +#endif + char pcap_version[]="current-cvs.tcpdump.org"; + char Wpcap_version[]="3.1"; +#endif + +/* + * By default, print the specified data out in hex and ASCII. + */ +static void +ndo_default_print(netdissect_options *ndo _U_, const u_char *bp, u_int length) +{ + hex_and_ascii_print("\n\t", bp, length); /* pass on lf and identation string */ +} + +void +default_print(const u_char *bp, u_int length) +{ + ndo_default_print(gndo, bp, length); +} + +#ifdef SIGNAL_REQ_INFO +RETSIGTYPE requestinfo(int signo _U_) +{ + if (infodelay) + ++infoprint; + else + info(0); +} +#endif + +/* + * Called once each second in verbose mode while dumping to file + */ +#ifdef USE_WIN32_MM_TIMER +void CALLBACK verbose_stats_dump (UINT timer_id _U_, UINT msg _U_, DWORD_PTR arg _U_, + DWORD_PTR dw1 _U_, DWORD_PTR dw2 _U_) +{ + struct pcap_stat stat; + + if (infodelay == 0 && pcap_stats(pd, &stat) >= 0) + fprintf(stderr, "Got %u\r", packets_captured); +} +#elif defined(HAVE_ALARM) +static void verbose_stats_dump(int sig _U_) +{ + struct pcap_stat stat; + + if (infodelay == 0 && pcap_stats(pd, &stat) >= 0) + fprintf(stderr, "Got %u\r", packets_captured); + alarm(1); +} +#endif + +static void +usage(void) +{ +#if __rtems__ + #define version "RTEMS Version" +#else + extern char version[]; +#endif +#ifndef HAVE_PCAP_LIB_VERSION +#if defined(WIN32) || defined(HAVE_PCAP_VERSION) + extern char pcap_version[]; +#else /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */ + static char pcap_version[] = "unknown"; +#endif /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */ +#endif /* HAVE_PCAP_LIB_VERSION */ + +#ifdef HAVE_PCAP_LIB_VERSION +#ifdef WIN32 + (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); +#else /* WIN32 */ + (void)fprintf(stderr, "%s version %s\n", program_name, version); +#endif /* WIN32 */ + (void)fprintf(stderr, "%s\n",pcap_lib_version()); +#else /* HAVE_PCAP_LIB_VERSION */ +#ifdef WIN32 + (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); + (void)fprintf(stderr, "WinPcap version %s, based on libpcap version %s\n",Wpcap_version, pcap_version); +#else /* WIN32 */ + (void)fprintf(stderr, "%s version %s\n", program_name, version); + (void)fprintf(stderr, "libpcap version %s\n", pcap_version); +#endif /* WIN32 */ +#endif /* HAVE_PCAP_LIB_VERSION */ + (void)fprintf(stderr, +"Usage: %s [-aAbd" D_FLAG "efhH" I_FLAG J_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name); + (void)fprintf(stderr, +"\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n"); + (void)fprintf(stderr, +"\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ]\n"); + (void)fprintf(stderr, +"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -V file ] [ -w file ]\n"); + (void)fprintf(stderr, +"\t\t[ -W filecount ] [ -y datalinktype ] [ -z command ]\n"); + (void)fprintf(stderr, +"\t\t[ -Z user ] [ expression ]\n"); + exit(1); +} + + + +/* VARARGS */ +static void +ndo_error(netdissect_options *ndo _U_, 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 */ +static void +ndo_warning(netdissect_options *ndo _U_, 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); + } +} diff --git a/freebsd/contrib/tcpdump/telnet.h b/freebsd/contrib/tcpdump/telnet.h new file mode 100644 index 00000000..33a07be9 --- /dev/null +++ b/freebsd/contrib/tcpdump/telnet.h @@ -0,0 +1,348 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/telnet.h,v 1.5 2007-08-29 02:31:44 mcr Exp $ (LBL) */ + +/* NetBSD: telnet.h,v 1.9 2001/06/11 01:50:50 wiz Exp */ + +/* + * Copyright (c) 1983, 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. + * + * @(#)telnet.h 8.2 (Berkeley) 12/15/93 + */ + +#ifndef _ARPA_TELNET_H_ +#define _ARPA_TELNET_H_ + +/* + * Definitions for the TELNET protocol. + */ +#define IAC 255 /* interpret as command: */ +#define DONT 254 /* you are not to use option */ +#define DO 253 /* please, you use option */ +#define WONT 252 /* I won't use option */ +#define WILL 251 /* I will use option */ +#define SB 250 /* interpret as subnegotiation */ +#define GA 249 /* you may reverse the line */ +#define EL 248 /* erase the current line */ +#define EC 247 /* erase the current character */ +#define AYT 246 /* are you there */ +#define AO 245 /* abort output--but let prog finish */ +#define IP 244 /* interrupt process--permanently */ +#define BREAK 243 /* break */ +#define DM 242 /* data mark--for connect. cleaning */ +#define NOP 241 /* nop */ +#define SE 240 /* end sub negotiation */ +#define EOR 239 /* end of record (transparent mode) */ +#define ABORT 238 /* Abort process */ +#define SUSP 237 /* Suspend process */ +#define xEOF 236 /* End of file: EOF is already used... */ + +#define SYNCH 242 /* for telfunc calls */ + +#ifdef TELCMDS +const char *telcmds[] = { + "EOF", "SUSP", "ABORT", "EOR", + "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", + "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0, +}; +#else +extern char *telcmds[]; +#endif + +#define TELCMD_FIRST xEOF +#define TELCMD_LAST IAC +#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \ + (unsigned int)(x) >= TELCMD_FIRST) +#define TELCMD(x) telcmds[(x)-TELCMD_FIRST] + +/* telnet options */ +#define TELOPT_BINARY 0 /* 8-bit data path */ +#define TELOPT_ECHO 1 /* echo */ +#define TELOPT_RCP 2 /* prepare to reconnect */ +#define TELOPT_SGA 3 /* suppress go ahead */ +#define TELOPT_NAMS 4 /* approximate message size */ +#define TELOPT_STATUS 5 /* give status */ +#define TELOPT_TM 6 /* timing mark */ +#define TELOPT_RCTE 7 /* remote controlled transmission and echo */ +#define TELOPT_NAOL 8 /* negotiate about output line width */ +#define TELOPT_NAOP 9 /* negotiate about output page size */ +#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */ +#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */ +#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */ +#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */ +#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */ +#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */ +#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */ +#define TELOPT_XASCII 17 /* extended ascic character set */ +#define TELOPT_LOGOUT 18 /* force logout */ +#define TELOPT_BM 19 /* byte macro */ +#define TELOPT_DET 20 /* data entry terminal */ +#define TELOPT_SUPDUP 21 /* supdup protocol */ +#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */ +#define TELOPT_SNDLOC 23 /* send location */ +#define TELOPT_TTYPE 24 /* terminal type */ +#define TELOPT_EOR 25 /* end or record */ +#define TELOPT_TUID 26 /* TACACS user identification */ +#define TELOPT_OUTMRK 27 /* output marking */ +#define TELOPT_TTYLOC 28 /* terminal location number */ +#define TELOPT_3270REGIME 29 /* 3270 regime */ +#define TELOPT_X3PAD 30 /* X.3 PAD */ +#define TELOPT_NAWS 31 /* window size */ +#define TELOPT_TSPEED 32 /* terminal speed */ +#define TELOPT_LFLOW 33 /* remote flow control */ +#define TELOPT_LINEMODE 34 /* Linemode option */ +#define TELOPT_XDISPLOC 35 /* X Display Location */ +#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */ +#define TELOPT_AUTHENTICATION 37/* Authenticate */ +#define TELOPT_ENCRYPT 38 /* Encryption option */ +#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */ +#define TELOPT_EXOPL 255 /* extended-options-list */ + + +#define NTELOPTS (1+TELOPT_NEW_ENVIRON) +#ifdef TELOPTS +const char *telopts[NTELOPTS+1] = { + "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", + "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", + "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", + "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", + "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", + "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", + "TACACS UID", "OUTPUT MARKING", "TTYLOC", + "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW", + "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", + "ENCRYPT", "NEW-ENVIRON", + 0, +}; +#define TELOPT_FIRST TELOPT_BINARY +#define TELOPT_LAST TELOPT_NEW_ENVIRON +#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) +#define TELOPT(x) telopts[(x)-TELOPT_FIRST] +#endif + +/* sub-option qualifiers */ +#define TELQUAL_IS 0 /* option is... */ +#define TELQUAL_SEND 1 /* send option */ +#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */ +#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */ +#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */ + +#define LFLOW_OFF 0 /* Disable remote flow control */ +#define LFLOW_ON 1 /* Enable remote flow control */ +#define LFLOW_RESTART_ANY 2 /* Restart output on any char */ +#define LFLOW_RESTART_XON 3 /* Restart output only on XON */ + +/* + * LINEMODE suboptions + */ + +#define LM_MODE 1 +#define LM_FORWARDMASK 2 +#define LM_SLC 3 + +#define MODE_EDIT 0x01 +#define MODE_TRAPSIG 0x02 +#define MODE_ACK 0x04 +#define MODE_SOFT_TAB 0x08 +#define MODE_LIT_ECHO 0x10 + +#define MODE_MASK 0x1f + +/* Not part of protocol, but needed to simplify things... */ +#define MODE_FLOW 0x0100 +#define MODE_ECHO 0x0200 +#define MODE_INBIN 0x0400 +#define MODE_OUTBIN 0x0800 +#define MODE_FORCE 0x1000 + +#define SLC_SYNCH 1 +#define SLC_BRK 2 +#define SLC_IP 3 +#define SLC_AO 4 +#define SLC_AYT 5 +#define SLC_EOR 6 +#define SLC_ABORT 7 +#define SLC_EOF 8 +#define SLC_SUSP 9 +#define SLC_EC 10 +#define SLC_EL 11 +#define SLC_EW 12 +#define SLC_RP 13 +#define SLC_LNEXT 14 +#define SLC_XON 15 +#define SLC_XOFF 16 +#define SLC_FORW1 17 +#define SLC_FORW2 18 +#define SLC_MCL 19 +#define SLC_MCR 20 +#define SLC_MCWL 21 +#define SLC_MCWR 22 +#define SLC_MCBOL 23 +#define SLC_MCEOL 24 +#define SLC_INSRT 25 +#define SLC_OVER 26 +#define SLC_ECR 27 +#define SLC_EWR 28 +#define SLC_EBOL 29 +#define SLC_EEOL 30 + +#define NSLC 30 + +/* + * For backwards compatibility, we define SLC_NAMES to be the + * list of names if SLC_NAMES is not defined. + */ +#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \ + "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \ + "LNEXT", "XON", "XOFF", "FORW1", "FORW2", \ + "MCL", "MCR", "MCWL", "MCWR", "MCBOL", \ + "MCEOL", "INSRT", "OVER", "ECR", "EWR", \ + "EBOL", "EEOL", \ + 0, + +#ifdef SLC_NAMES +const char *slc_names[] = { + SLC_NAMELIST +}; +#else +extern char *slc_names[]; +#define SLC_NAMES SLC_NAMELIST +#endif + +#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC) +#define SLC_NAME(x) slc_names[x] + +#define SLC_NOSUPPORT 0 +#define SLC_CANTCHANGE 1 +#define SLC_VARIABLE 2 +#define SLC_DEFAULT 3 +#define SLC_LEVELBITS 0x03 + +#define SLC_FUNC 0 +#define SLC_FLAGS 1 +#define SLC_VALUE 2 + +#define SLC_ACK 0x80 +#define SLC_FLUSHIN 0x40 +#define SLC_FLUSHOUT 0x20 + +#define OLD_ENV_VAR 1 +#define OLD_ENV_VALUE 0 +#define NEW_ENV_VAR 0 +#define NEW_ENV_VALUE 1 +#define ENV_ESC 2 +#define ENV_USERVAR 3 + +/* + * AUTHENTICATION suboptions + */ + +/* + * Who is authenticating who ... + */ +#define AUTH_WHO_CLIENT 0 /* Client authenticating server */ +#define AUTH_WHO_SERVER 1 /* Server authenticating client */ +#define AUTH_WHO_MASK 1 + +/* + * amount of authentication done + */ +#define AUTH_HOW_ONE_WAY 0 +#define AUTH_HOW_MUTUAL 2 +#define AUTH_HOW_MASK 2 + +/* + * should we be encrypting? (not yet formally standardized) + */ +#define AUTH_ENCRYPT_OFF 0 +#define AUTH_ENCRYPT_ON 4 +#define AUTH_ENCRYPT_MASK 4 + +#define AUTHTYPE_NULL 0 +#define AUTHTYPE_KERBEROS_V4 1 +#define AUTHTYPE_KERBEROS_V5 2 +#define AUTHTYPE_SPX 3 +#define AUTHTYPE_MINK 4 +#define AUTHTYPE_CNT 5 + +#define AUTHTYPE_TEST 99 + +#ifdef AUTH_NAMES +const char *authtype_names[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0, +}; +#else +extern char *authtype_names[]; +#endif + +#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT) +#define AUTHTYPE_NAME(x) authtype_names[x] + +/* + * ENCRYPTion suboptions + */ +#define ENCRYPT_IS 0 /* I pick encryption type ... */ +#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ +#define ENCRYPT_REPLY 2 /* Initial setup response */ +#define ENCRYPT_START 3 /* Am starting to send encrypted */ +#define ENCRYPT_END 4 /* Am ending encrypted */ +#define ENCRYPT_REQSTART 5 /* Request you start encrypting */ +#define ENCRYPT_REQEND 6 /* Request you send encrypting */ +#define ENCRYPT_ENC_KEYID 7 +#define ENCRYPT_DEC_KEYID 8 +#define ENCRYPT_CNT 9 + +#define ENCTYPE_ANY 0 +#define ENCTYPE_DES_CFB64 1 +#define ENCTYPE_DES_OFB64 2 +#define ENCTYPE_CNT 3 + +#ifdef ENCRYPT_NAMES +const char *encrypt_names[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID", + 0, +}; +const char *enctype_names[] = { + "ANY", "DES_CFB64", "DES_OFB64", 0, +}; +#else +extern char *encrypt_names[]; +extern char *enctype_names[]; +#endif + + +#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT) +#define ENCRYPT_NAME(x) encrypt_names[x] + +#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT) +#define ENCTYPE_NAME(x) enctype_names[x] + +#endif /* _ARPA_TELNET_H_ */ diff --git a/freebsd/contrib/tcpdump/tftp.h b/freebsd/contrib/tcpdump/tftp.h new file mode 100644 index 00000000..6a092e0a --- /dev/null +++ b/freebsd/contrib/tcpdump/tftp.h @@ -0,0 +1,82 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/tftp.h,v 1.2 2008-04-11 16:47:38 gianluca Exp $ (LBL) */ +/* + * Copyright (c) 1983, 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. + * + * @(#)tftp.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _TFTP_H_ +#define _TFTP_H_ + +/* + * Trivial File Transfer Protocol (IEN-133) + */ +#define SEGSIZE 512 /* data segment size */ + +/* + * Packet types. + */ +#define RRQ 01 /* read request */ +#define WRQ 02 /* write request */ +#define DATA 03 /* data packet */ +#define ACK 04 /* acknowledgement */ +#define TFTP_ERROR 05 /* error code */ +#define OACK 06 /* option acknowledgement */ + +struct tftphdr { + unsigned short th_opcode; /* packet type */ + union { + unsigned short tu_block; /* block # */ + unsigned short tu_code; /* error code */ + char tu_stuff[1]; /* request packet stuff */ + } th_u; + char th_data[1]; /* data or error string */ +}; + +#define th_block th_u.tu_block +#define th_code th_u.tu_code +#define th_stuff th_u.tu_stuff +#define th_msg th_data + +/* + * Error codes. + */ +#define EUNDEF 0 /* not defined */ +#define ENOTFOUND 1 /* file not found */ +#define EACCESS 2 /* access violation */ +#define ENOSPACE 3 /* disk full or allocation exceeded */ +#define EBADOP 4 /* illegal TFTP operation */ +#define EBADID 5 /* unknown transfer ID */ +#define EEXISTS 6 /* file already exists */ +#define ENOUSER 7 /* no such user */ + +#endif /* !_TFTP_H_ */ diff --git a/freebsd/contrib/tcpdump/timed.h b/freebsd/contrib/tcpdump/timed.h new file mode 100644 index 00000000..f8d5a113 --- /dev/null +++ b/freebsd/contrib/tcpdump/timed.h @@ -0,0 +1,97 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/timed.h,v 1.6 2008-02-05 19:46:19 guy Exp $ (LBL) */ +/* + * Copyright (c) 1983, 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. + * + * @(#)timed.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _PROTOCOLS_TIMED_H_ +#define _PROTOCOLS_TIMED_H_ + +/* + * Time Synchronization Protocol + */ + +#define TSPVERSION 1 +#define ANYADDR NULL + +struct tsp_timeval { + u_int32_t tv_sec; + u_int32_t tv_usec; +}; + +struct tsp { + u_int8_t tsp_type; + u_int8_t tsp_vers; + u_int16_t tsp_seq; + union { + struct tsp_timeval tspu_time; + int8_t tspu_hopcnt; + } tsp_u; + int8_t tsp_name[256]; +}; + +#define tsp_time tsp_u.tspu_time +#define tsp_hopcnt tsp_u.tspu_hopcnt + +/* + * Command types. + */ +#define TSP_ANY 0 /* match any types */ +#define TSP_ADJTIME 1 /* send adjtime */ +#define TSP_ACK 2 /* generic acknowledgement */ +#define TSP_MASTERREQ 3 /* ask for master's name */ +#define TSP_MASTERACK 4 /* acknowledge master request */ +#define TSP_SETTIME 5 /* send network time */ +#define TSP_MASTERUP 6 /* inform slaves that master is up */ +#define TSP_SLAVEUP 7 /* slave is up but not polled */ +#define TSP_ELECTION 8 /* advance candidature for master */ +#define TSP_ACCEPT 9 /* support candidature of master */ +#define TSP_REFUSE 10 /* reject candidature of master */ +#define TSP_CONFLICT 11 /* two or more masters present */ +#define TSP_RESOLVE 12 /* masters' conflict resolution */ +#define TSP_QUIT 13 /* reject candidature if master is up */ +#define TSP_DATE 14 /* reset the time (date command) */ +#define TSP_DATEREQ 15 /* remote request to reset the time */ +#define TSP_DATEACK 16 /* acknowledge time setting */ +#define TSP_TRACEON 17 /* turn tracing on */ +#define TSP_TRACEOFF 18 /* turn tracing off */ +#define TSP_MSITE 19 /* find out master's site */ +#define TSP_MSITEREQ 20 /* remote master's site request */ +#define TSP_TEST 21 /* for testing election algo */ +#define TSP_SETDATE 22 /* New from date command */ +#define TSP_SETDATEREQ 23 /* New remote for above */ +#define TSP_LOOP 24 /* loop detection packet */ + +#define TSPTYPENUMBER 25 + +#endif /* !_TIMED_H_ */ diff --git a/freebsd/contrib/tcpdump/token.h b/freebsd/contrib/tcpdump/token.h new file mode 100644 index 00000000..19524c6c --- /dev/null +++ b/freebsd/contrib/tcpdump/token.h @@ -0,0 +1,53 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/token.h,v 1.6 2002-12-11 07:14:12 guy Exp $ (LBL) */ +/* + * Copyright (c) 1998, Larry Lile + * 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 unmodified, 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#define TOKEN_HDRLEN 14 +#define TOKEN_RING_MAC_LEN 6 +#define ROUTING_SEGMENT_MAX 16 +#define IS_SOURCE_ROUTED(trp) ((trp)->token_shost[0] & 0x80) +#define FRAME_TYPE(trp) (((trp)->token_fc & 0xC0) >> 6) +#define TOKEN_FC_LLC 1 + +#define BROADCAST(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0xE000) >> 13) +#define RIF_LENGTH(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x1f00) >> 8) +#define DIRECTION(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x0080) >> 7) +#define LARGEST_FRAME(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x0070) >> 4) +#define RING_NUMBER(trp, x) ((EXTRACT_16BITS(&(trp)->token_rseg[x]) & 0xfff0) >> 4) +#define BRIDGE_NUMBER(trp, x) ((EXTRACT_16BITS(&(trp)->token_rseg[x]) & 0x000f)) +#define SEGMENT_COUNT(trp) ((int)((RIF_LENGTH(trp) - 2) / 2)) + +struct token_header { + u_int8_t token_ac; + u_int8_t token_fc; + u_int8_t token_dhost[TOKEN_RING_MAC_LEN]; + u_int8_t token_shost[TOKEN_RING_MAC_LEN]; + u_int16_t token_rcf; + u_int16_t token_rseg[ROUTING_SEGMENT_MAX]; +}; diff --git a/freebsd/contrib/tcpdump/udp.h b/freebsd/contrib/tcpdump/udp.h new file mode 100644 index 00000000..b07cdd43 --- /dev/null +++ b/freebsd/contrib/tcpdump/udp.h @@ -0,0 +1,96 @@ +/* @(#) $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 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 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 */ + +#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 diff --git a/freebsd/contrib/tcpdump/util.c b/freebsd/contrib/tcpdump/util.c new file mode 100644 index 00000000..d50e1254 --- /dev/null +++ b/freebsd/contrib/tcpdump/util.c @@ -0,0 +1,610 @@ +#include <machine/rtems-bsd-user-space.h> + +/* + * 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 <tcpdump-stdinc.h> + +#include <sys/stat.h> + +#include <errno.h> +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#include <pcap.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#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 <interface.h> 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); +} |