diff options
author | fenner <fenner@FreeBSD.org> | 2002-06-21 00:43:23 +0000 |
---|---|---|
committer | fenner <fenner@FreeBSD.org> | 2002-06-21 00:43:23 +0000 |
commit | 91fc581e384bca8ae8831d23b70ab73ab0dc1a21 (patch) | |
tree | 89431945035dbd4a9ce74e63c4a1f65ed4166a1a /contrib/tcpdump/print-cdp.c | |
parent | f815ae37f4671c581fdc1c6f99a8490a6dfbb4f6 (diff) | |
download | FreeBSD-src-91fc581e384bca8ae8831d23b70ab73ab0dc1a21.zip FreeBSD-src-91fc581e384bca8ae8831d23b70ab73ab0dc1a21.tar.gz |
Import tcpdump 3.7.1, from
http://www.tcpdump.org/release/tcpdump-3.7.1.tar.gz
Diffstat (limited to 'contrib/tcpdump/print-cdp.c')
-rw-r--r-- | contrib/tcpdump/print-cdp.c | 293 |
1 files changed, 184 insertions, 109 deletions
diff --git a/contrib/tcpdump/print-cdp.c b/contrib/tcpdump/print-cdp.c index 53eff98..a73fc3f 100644 --- a/contrib/tcpdump/print-cdp.c +++ b/contrib/tcpdump/print-cdp.c @@ -26,7 +26,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-cdp.c,v 1.4 2000/07/29 07:27:54 assar Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-cdp.c,v 1.11 2001/09/17 21:57:56 fenner Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -47,141 +47,216 @@ static const char rcsid[] = #include "addrtoname.h" #include "extract.h" /* must come after interface.h */ -static void cdp_print_addr( const u_char * p, int l ); -static void cdp_print_prefixes( const u_char * p, int l ); +static int cdp_print_addr(const u_char *, int); +static int cdp_print_prefixes(const u_char *, int); -/* - * Returns non-zero IFF it succeeds in printing the header - */ void cdp_print(const u_char *p, u_int length, u_int caplen, const u_char *esrc, const u_char *edst) { - int i; + u_int i; int type, len; /* Cisco Discovery Protocol */ - - if ( caplen < 12 ) { + if (caplen < 4) { (void)printf("[|cdp]"); return; } - i=8; /* CDP data starts at offset 8 */ - printf ("CDP v%d, ttl=%ds", p[i], p[i+1] ); - i+=4; /* skip version, TTL and chksum */ + i = 0; /* CDP data starts at offset 0 */ + printf("CDP v%u, ttl=%us", p[i], p[i + 1]); + i += 4; /* skip version, TTL and chksum */ while (i < length) { - if ( i+4 > caplen ) { - printf("[!cdp]"); - return; - } - type = (p[i]<<8) + p[i+1]; - len = (p[i+2]<<8) + p[i+3]; + if (i + 4 > caplen) + goto trunc; + type = (p[i] << 8) + p[i + 1]; + len = (p[i + 2] << 8) + p[i + 3]; - if ( vflag ) - printf( "\n\t%02x/%02x", type, len ); - else - printf( "\n\t" ); + if (vflag > 1) + printf("\n\t"); - if ( i+len > caplen ) { - printf("[!cdp]"); - return; - } - - switch( type ) - { - case 0x01: - printf( " DevID '%.*s'", len-4, p+i+4 ); - break; - case 0x02: - printf( " Addr" ); - cdp_print_addr( p+i+4, len-4 ); - break; - case 0x03: - printf( " PortID '%.*s'", len-4, p+i+4 ); - break; - case 0x04: - printf( " CAP 0x%02x", (unsigned) p[i+7] ); - break; - case 0x05: - if ( vflag ) - printf( " Version:\n%.*s", len-4, p+i+4 ); - else - printf( " Version: (suppressed)" ); - break; - case 0x06: - printf( " Platform: '%.*s'", len-4, p+i+4 ); - break; - case 0x07: - cdp_print_prefixes( p+i+4, len-4 ); - break; - case 0x09: /* guess - not documented */ - printf( " VTP Management Domain: '%.*s'", len-4, p+i+4 ); - break; - case 0x0a: /* guess - not documented */ - printf( " Native VLAN ID: %d", (p[i+4]<<8) + p[i+4+1] - 1 ); - break; - case 0x0b: /* guess - not documented */ - printf( " Duplex: %s", p[i+4] ? "full": "half" ); - break; - default: - printf( " unknown field type %02x, len %d", type, len ); - } - - /* avoid infinite loop */ - if (len == 0) - break; - i+=len; + if (vflag) + printf(" %02x/%02x", type, len); + + if (i + len > caplen) + goto trunc; + + switch (type) { + case 0x00: + printf(" Goodbye"); + break; + case 0x01: + printf(" DevID '%.*s'", len - 4, p + i + 4); + break; + case 0x02: + printf(" Addr"); + if (cdp_print_addr(p + i + 4, len - 4) < 0) + goto trunc; + break; + case 0x03: + printf(" PortID '%.*s'", len - 4, p + i + 4); + break; + case 0x04: + printf(" CAP 0x%02x", (unsigned) p[i + 7]); + break; + case 0x05: + if (vflag > 1) + printf(" Version:\n%.*s", len - 4, p + i + 4); + else + printf(" Version: (suppressed)"); + break; + case 0x06: + printf(" Platform: '%.*s'", len - 4, p + i + 4); + break; + case 0x07: + if (cdp_print_prefixes(p + i + 4, len - 4) < 0) + goto trunc; + break; + case 0x09: /* guess - not documented */ + printf(" VTP Management Domain: '%.*s'", len - 4, + p + i + 4); + break; + case 0x0a: /* guess - not documented */ + printf(" Native VLAN ID: %d", + (p[i + 4] << 8) + p[i + 4 + 1] - 1); + break; + case 0x0b: /* guess - not documented */ + printf(" Duplex: %s", p[i + 4] ? "full": "half"); + break; + default: + printf(" unknown field type %02x, len %d", type, len); + break; + } + + /* avoid infinite loop */ + if (len == 0) + break; + i += len; } + + return; + +trunc: + printf("[|cdp]"); } -static void -cdp_print_addr( const u_char * p, int l ) +/* + * 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 pl, al, num; - const u_char * endp = p+l; - - num = (p[0] << 24) + (p[1]<<16) + (p[2]<<8)+ p[3]; - p+=4; - - printf(" (%d): ", num ); - - while( p < endp && num >= 0) { - pl=*(p+1); - p+=2; - - /* special case: IPv4, protocol type=0xcc, addr. length=4 */ - if ( pl == 1 && *p == 0xcc && - p[1] == 0 && p[2] == 4 ) { - p+=3; - - printf( "IPv4 %d.%d.%d.%d ", p[0], p[1], p[2], p[3] ); - p+=4; - } else { /* generic case: just print raw data */ - printf("pt=0x%02x, pl=%d, pb=", *(p-2), pl); - while( pl-- > 0 ) - printf( " %02x", *p++); - al=(*p << 8) + *(p+1); - printf( ", al=%d, a=", al ); - p+=2; - while( al-- > 0 ) - printf( " %02x", *p++); + 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 + + num = EXTRACT_32BITS(p); + p += 4; + + printf(" (%d): ", num); + + while (p < endp && num >= 0) { + if (p + 2 > endp) + goto trunc; + pt = p[0]; /* type of "protocol" field */ + pl = p[1]; /* length of "protocol" field */ + p += 2; + + if (p + pl + 2 > endp) + goto trunc; + al = EXTRACT_16BITS(&p[pl]); /* address length */ + + if (pt == PT_NLPID && pl == 1 && *p == 0xcc && al == 4) { + /* + * IPv4: protocol type = NLPID, protocol length = 1 + * (1-byte NLPID), protocol = 0xcc (NLPID for IPv4), + * address length = 4 + */ + p += 3; + + if (p + 4 > endp) + goto trunc; + printf("IPv4 %u.%u.%u.%u", p[0], p[1], p[2], p[3]); + 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; + if (p + al > endp) + goto trunc; + + printf("IPv6 %s", ip6addr_string(p)); + p += al; + } +#endif + else { + /* + * Generic case: just print raw data + */ + if (p + pl > endp) + goto trunc; + printf("pt=0x%02x, pl=%d, pb=", *(p - 2), pl); + while (pl-- > 0) + printf(" %02x", *p++); + if (p + 2 > endp) + goto trunc; + al = (*p << 8) + *(p + 1); + printf(", al=%d, a=", al); + p += 2; + if (p + al > endp) + goto trunc; + while (al-- > 0) + printf(" %02x", *p++); } - printf(" "); num--; + if (num) + printf(" "); } + + return 0; + +trunc: + return -1; } -static void -cdp_print_prefixes( const u_char * p, int l ) +static int +cdp_print_prefixes(const u_char * p, int l) { - printf( " IPv4 Prefixes (%d):", l/5 ); + 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; - while(l > 0) { - printf( " %d.%d.%d.%d/%d", p[0], p[1], p[2], p[3], p[4] ); - l-=5; p+=5; - } +trunc: + return -1; } |