diff options
author | Hakan Olsson <ho@cvs.openbsd.org> | 2002-09-03 12:21:13 +0000 |
---|---|---|
committer | Hakan Olsson <ho@cvs.openbsd.org> | 2002-09-03 12:21:13 +0000 |
commit | 8ea4c6553bbe6504e4677016c61cde0506658266 (patch) | |
tree | 3923674cb3d792806fc662adbb23c123ef00c6fe /usr.sbin/tcpdump | |
parent | 543630bca29764688093df1356a74b6e285912ab (diff) |
Sync with tcpdump.org
Diffstat (limited to 'usr.sbin/tcpdump')
-rw-r--r-- | usr.sbin/tcpdump/extract.h | 38 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-bgp.c | 211 |
2 files changed, 151 insertions, 98 deletions
diff --git a/usr.sbin/tcpdump/extract.h b/usr.sbin/tcpdump/extract.h index 22207110965..cecfb342759 100644 --- a/usr.sbin/tcpdump/extract.h +++ b/usr.sbin/tcpdump/extract.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extract.h,v 1.6 2000/10/03 14:31:54 ho Exp $ */ +/* $OpenBSD: extract.h,v 1.7 2002/09/03 12:21:12 ho Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995, 1996 @@ -20,40 +20,40 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/extract.h,v 1.6 2000/10/03 14:31:54 ho Exp $ (LBL) + * @(#) $TCPDUMP: /tcpdump/master/tcpdump/extract.h,v 1.17 2001/09/17 21:57:52 fenner Exp $ (LBL) */ /* Network to host order macros */ #ifdef LBL_ALIGN #define EXTRACT_16BITS(p) \ - ((u_short)*((u_char *)(p) + 0) << 8 | \ - (u_short)*((u_char *)(p) + 1)) + ((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_char *)(p) + 0) << 24 | \ - (u_int32_t)*((u_char *)(p) + 1) << 16 | \ - (u_int32_t)*((u_char *)(p) + 2) << 8 | \ - (u_int32_t)*((u_char *)(p) + 3)) + ((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)) #else #define EXTRACT_16BITS(p) \ - ((u_short)ntohs(*(u_short *)(p))) + ((u_int16_t)ntohs(*(const u_int16_t *)(p))) #define EXTRACT_32BITS(p) \ - ((u_int32_t)ntohl(*(u_int32_t *)(p))) + ((u_int32_t)ntohl(*(const u_int32_t *)(p))) #endif #define EXTRACT_24BITS(p) \ - ((u_int32_t)*((u_char *)(p) + 0) << 16 | \ - (u_int32_t)*((u_char *)(p) + 1) << 8 | \ - (u_int32_t)*((u_char *)(p) + 2)) + ((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)) /* Little endian protocol host order macros */ #define EXTRACT_LE_8BITS(p) (*(p)) #define EXTRACT_LE_16BITS(p) \ - ((u_short)*((u_char *)(p) + 1) << 8 | \ - (u_short)*((u_char *)(p) + 0)) + ((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_char *)(p) + 3) << 24 | \ - (u_int32_t)*((u_char *)(p) + 2) << 16 | \ - (u_int32_t)*((u_char *)(p) + 1) << 8 | \ - (u_int32_t)*((u_char *)(p) + 0)) + ((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)) diff --git a/usr.sbin/tcpdump/print-bgp.c b/usr.sbin/tcpdump/print-bgp.c index 631ae1bf2f1..adbe25262bd 100644 --- a/usr.sbin/tcpdump/print-bgp.c +++ b/usr.sbin/tcpdump/print-bgp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print-bgp.c,v 1.3 2000/10/03 14:15:55 ho Exp $ */ +/* $OpenBSD: print-bgp.c,v 1.4 2002/09/03 12:21:12 ho Exp $ */ /* * Copyright (C) 1999 WIDE Project. @@ -29,25 +29,26 @@ * SUCH DAMAGE. */ +#ifndef lint +static const char rcsid[] = + "@(#) $TCPDUMP: /tcpdump/master/tcpdump/print-bgp.c,v 1.27 2001/10/18 09:52:17 itojun Exp $"; +#endif + #include <sys/param.h> #include <sys/time.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/ip_var.h> -#include <netinet/udp.h> -#include <netinet/udp_var.h> -#include <arpa/inet.h> #include <errno.h> #include <stdio.h> #include <string.h> +#include <netdb.h> #include "interface.h" #include "addrtoname.h" +#include "extract.h" struct bgp { u_int8_t bgp_marker[16]; @@ -72,12 +73,14 @@ struct bgp_open { 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 */ struct bgp_notification { u_int8_t bgpn_marker[16]; @@ -87,6 +90,7 @@ struct bgp_notification { u_int8_t bgpn_minor; /* data should follow */ }; +#define BGP_NOTIFICATION_SIZE 21 /* unaligned */ struct bgp_attr { u_int8_t bgpa_flags; @@ -125,7 +129,7 @@ static const char *bgptype[] = { #define bgp_type(x) num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (x)) static const char *bgpopt_type[] = { - NULL, "Authentication Information", + NULL, "Authentication Information", "Capabilities Advertisement", }; #define bgp_opttype(x) \ num_or_str(bgpopt_type, sizeof(bgpopt_type)/sizeof(bgpopt_type[0]), (x)) @@ -189,7 +193,7 @@ static const char *bgpattr_type[] = { /* Subsequent address family identifier, RFC2283 section 7 */ static const char *bgpattr_nlri_safi[] = { - "Reserved", "Unicast", "Multicast", "Unicast+Multicast", + "Reserved", "Unicast", "Multicast", "Unicast+Multicast", }; #define bgp_attr_nlri_safi(x) \ num_or_str(bgpattr_nlri_safi, \ @@ -267,10 +271,10 @@ bgp_notify_minor(int major, int minor) } static int -decode_prefix4(const u_char *pd, char *buf, int buflen) +decode_prefix4(const u_char *pd, char *buf, u_int buflen) { struct in_addr addr; - int plen; + u_int plen; plen = pd[0]; if (plen < 0 || 32 < plen) @@ -282,16 +286,16 @@ decode_prefix4(const u_char *pd, char *buf, int buflen) ((u_char *)&addr)[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } - snprintf(buf, buflen, "%s/%d", inet_ntoa(addr), plen); + snprintf(buf, buflen, "%s/%d", getname((u_char *)&addr), plen); return 1 + (plen + 7) / 8; } #ifdef INET6 static int -decode_prefix6(const u_char *pd, char *buf, int buflen) +decode_prefix6(const u_char *pd, char *buf, u_int buflen) { struct in6_addr addr; - int plen; + u_int plen; plen = pd[0]; if (plen < 0 || 128 < plen) @@ -303,7 +307,7 @@ decode_prefix6(const u_char *pd, char *buf, int buflen) addr.s6_addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff); } - snprintf(buf, buflen, "%s/%d", getname6((char *)&addr), plen); + snprintf(buf, buflen, "%s/%d", getname6((u_char *)&addr), plen); return 1 + (plen + 7) / 8; } #endif @@ -317,10 +321,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) int advance; int tlen; const u_char *p; - char buf[256]; - u_int16_t ss; - u_int32_t ll; - struct in_addr aa; + char buf[MAXHOSTNAMELEN + 100]; p = dat; @@ -346,10 +347,9 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) if (p[0] == 3 || p[0] == 4) printf("confed"); printf("%s", (p[0] & 1) ? "{" : ""); - for (i = 0; i < p[1]; i += 2) { - memcpy((void *)&ss, (void *)&p[2+i], sizeof(ss)); + for (i = 0; i < p[1] * 2; i += 2) { printf("%s%u", i == 0 ? "" : " ", - ntohs(ss)); + EXTRACT_16BITS(&p[2 + i])); } printf("%s", (p[0] & 1) ? "}" : ""); p += 2 + p[1] * 2; @@ -358,19 +358,15 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) case BGPTYPE_NEXT_HOP: if (len != 4) printf(" invalid len"); - else { - memcpy((void *)&aa.s_addr, (void *)&p[0], sizeof(aa.s_addr)); - printf(" %s", inet_ntoa(aa)); - } + else + printf(" %s", getname(p)); break; case BGPTYPE_MULTI_EXIT_DISC: case BGPTYPE_LOCAL_PREF: if (len != 4) printf(" invalid len"); - else { - memcpy((void *)&ll, (void *)&p[0], sizeof(ll)); - printf(" %u", (u_int32_t)ntohl(ll)); - } + else + printf(" %u", EXTRACT_32BITS(p)); break; case BGPTYPE_ATOMIC_AGGREGATE: if (len != 0) @@ -381,9 +377,8 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) printf(" invalid len"); break; } - memcpy((void *)&ss, (void *)&p[0], sizeof(ss)); - memcpy((void *)&aa.s_addr, (void *)&p[2], sizeof(aa.s_addr)); - printf(" AS #%u, origin %s", ntohs(ss), inet_ntoa(aa)); + printf(" AS #%u, origin %s", EXTRACT_16BITS(p), + getname(p + 2)); break; case BGPTYPE_COMMUNITIES: if (len % 4) { @@ -392,8 +387,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) } for (i = 0; i < len; i += 4) { u_int32_t comm; - memcpy((void *)&ll,(void *)&p[0+i],sizeof(ll)); - comm = (u_int32_t)ntohl(ll); + comm = EXTRACT_32BITS(&p[i]); switch (comm) { case BGP_COMMUNITY_NO_EXPORT: printf(" NO_EXPORT"); @@ -412,8 +406,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) } break; case BGPTYPE_MP_REACH_NLRI: - memcpy((void *)&ss, (void *)&p[0], sizeof(ss)); - af = ntohs(ss); + af = EXTRACT_16BITS(p); safi = p[2]; if (safi >= 128) printf(" %s vendor specific,", af_name(af)); @@ -435,22 +428,24 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) tlen = p[0]; if (tlen) { printf(" nexthop"); + i = 0; + while (i < tlen) { + switch (af) { + case AFNUM_INET: + printf(" %s", getname(p + 1 + i)); + i += sizeof(struct in_addr); + break; #ifdef INET6 - if (af == AFNUM_INET6) - advance = 16; - else -#endif - advance = 4; /* AFNUM_INET */ - - for (i = 0; i < tlen; i += advance) { - if (af == AFNUM_INET) { - memcpy((void *)&aa.s_addr, (void *)&p[1+i], sizeof(aa.s_addr)); - printf(" %s", inet_ntoa(aa)); - } -#ifdef INET6 - else if (af == AFNUM_INET6) + case AFNUM_INET6: printf(" %s", getname6(p + 1 + i)); + i += sizeof(struct in6_addr); + break; #endif + default: + printf(" (unknown af)"); + i = tlen; /*exit loop*/ + break; + } } printf(","); } @@ -469,13 +464,23 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) printf(" NLRI"); while (len - (p - dat) > 0) { + switch (af) { + case AFNUM_INET: + advance = decode_prefix4(p, buf, sizeof(buf)); + printf(" %s", buf); + break; #ifdef INET6 - if (af == AFNUM_INET6) + case AFNUM_INET6: advance = decode_prefix6(p, buf, sizeof(buf)); - else + printf(" %s", buf); + break; #endif - advance = decode_prefix4(p, buf, sizeof(buf)); - printf(" %s", buf); + default: + printf(" (unknown af)"); + advance = 0; + p = dat + len; + break; + } p += advance; } @@ -483,8 +488,7 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) break; case BGPTYPE_MP_UNREACH_NLRI: - memcpy((void *)&ss, (void *)&p[0], sizeof(ss)); - af = ntohs(ss); + af = EXTRACT_16BITS(p); safi = p[2]; if (safi >= 128) printf(" %s vendor specific,", af_name(af)); @@ -496,14 +500,23 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) printf(" Withdraw"); while (len - (p - dat) > 0) { + switch (af) { + case AFNUM_INET: + advance = decode_prefix4(p, buf, sizeof(buf)); + printf(" %s", buf); + break; #ifdef INET6 - if (af == AFNUM_INET6) + case AFNUM_INET6: advance = decode_prefix6(p, buf, sizeof(buf)); - else + printf(" %s", buf); + break; #endif - advance = decode_prefix4(p, buf, sizeof(buf)); - - printf(" %s", buf); + default: + printf(" (unknown af)"); + advance = 0; + p = dat + len; + break; + } p += advance; } @@ -522,21 +535,24 @@ bgp_open_print(const u_char *dat, int length) const u_char *opt; int i; - memcpy(&bgpo, dat, sizeof(bgpo)); + TCHECK2(dat[0], BGP_OPEN_SIZE); + memcpy(&bgpo, dat, BGP_OPEN_SIZE); hlen = ntohs(bgpo.bgpo_len); printf(": Version %d,", bgpo.bgpo_version); printf(" AS #%u,", ntohs(bgpo.bgpo_myas)); printf(" Holdtime %u,", ntohs(bgpo.bgpo_holdtime)); - printf(" ID %s,", getname((const u_char *)&bgpo.bgpo_id)); + printf(" ID %s,", getname((u_char *)&bgpo.bgpo_id)); printf(" Option length %u", bgpo.bgpo_optlen); /* ugly! */ - opt = &((struct bgp_open *)dat)->bgpo_optlen; + opt = &((const struct bgp_open *)dat)->bgpo_optlen; opt++; - for (i = 0; i < bgpo.bgpo_optlen; i++) { - memcpy(&bgpopt, &opt[i], sizeof(bgpopt)); + 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(" [|opt %d %d]", bgpopt.bgpopt_len, bgpopt.bgpopt_type); break; @@ -544,8 +560,11 @@ bgp_open_print(const u_char *dat, int length) printf(" (option %s, len=%d)", bgp_opttype(bgpopt.bgpopt_type), bgpopt.bgpopt_len); - i += sizeof(bgpopt) + bgpopt.bgpopt_len; + i += BGP_OPT_SIZE + bgpopt.bgpopt_len; } + return; +trunc: + printf("[|BGP]"); } static void @@ -558,23 +577,42 @@ bgp_update_print(const u_char *dat, int length) int len; int i; int newline; - u_int16_t ss; - memcpy(&bgp, dat, sizeof(bgp)); + TCHECK2(dat[0], BGP_SIZE); + memcpy(&bgp, dat, BGP_SIZE); hlen = ntohs(bgp.bgp_len); p = dat + BGP_SIZE; /*XXX*/ printf(":"); /* Unfeasible routes */ - memcpy((void *)&ss, (void *)&p[0], sizeof(ss)); - len = ntohs(ss); + len = EXTRACT_16BITS(p); if (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. + */ +#ifdef INET6 printf(" (Withdrawn routes: %d bytes)", len); +#else + char buf[MAXHOSTNAMELEN + 100]; + + TCHECK2(p[2], len); + i = 2; + + printf(" (Withdrawn routes:"); + + while(i < 2 + len) { + i += decode_prefix4(&p[i], buf, sizeof(buf)); + printf(" %s", buf); + } + printf(")\n"); +#endif } p += 2 + len; - memcpy((void *)&ss, (void *)&p[0], sizeof(ss)); - len = ntohs(ss); + TCHECK2(p[0], 2); + len = EXTRACT_16BITS(p); if (len) { /* do something more useful!*/ i = 2; @@ -583,6 +621,7 @@ bgp_update_print(const u_char *dat, int length) while (i < 2 + len) { int alen, aoff; + TCHECK2(p[i], sizeof(bgpa)); memcpy(&bgpa, &p[i], sizeof(bgpa)); alen = bgp_attr_len(&bgpa); aoff = bgp_attr_off(&bgpa); @@ -594,11 +633,14 @@ bgp_update_print(const u_char *dat, int length) printf("("); /* ) */ printf("%s", bgp_attr_type(bgpa.bgpa_type)); if (bgpa.bgpa_flags) { - printf("[%s%s%s%s]", + printf("[%s%s%s%s", bgpa.bgpa_flags & 0x80 ? "O" : "", bgpa.bgpa_flags & 0x40 ? "T" : "", bgpa.bgpa_flags & 0x20 ? "P" : "", - bgpa.bgpa_flags & 0x00 ? "E" : ""); + bgpa.bgpa_flags & 0x10 ? "E" : ""); + if (bgpa.bgpa_flags & 0xf) + printf("+%x", bgpa.bgpa_flags & 0xf); + printf("]"); } bgp_attr_print(&bgpa, &p[i + aoff], alen); @@ -620,7 +662,7 @@ bgp_update_print(const u_char *dat, int length) if (dat + length > p) { printf("(NLRI:"); /* ) */ while (dat + length > p) { - char buf[256]; + char buf[MAXHOSTNAMELEN + 100]; i = decode_prefix4(p, buf, sizeof(buf)); printf(" %s", buf); if (i < 0) @@ -631,6 +673,9 @@ bgp_update_print(const u_char *dat, int length) /* ( */ printf(")"); } + return; +trunc: + printf("[|BGP]"); } static void @@ -639,12 +684,16 @@ bgp_notification_print(const u_char *dat, int length) struct bgp_notification bgpn; int hlen; - memcpy(&bgpn, dat, sizeof(bgpn)); + TCHECK2(dat[0], BGP_NOTIFICATION_SIZE); + memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE); hlen = ntohs(bgpn.bgpn_len); printf(": error %s,", bgp_notify_major(bgpn.bgpn_major)); printf(" subcode %s", bgp_notify_minor(bgpn.bgpn_major, bgpn.bgpn_minor)); + return; +trunc: + printf("[|BGP]"); } static void @@ -652,7 +701,8 @@ bgp_header_print(const u_char *dat, int length) { struct bgp bgp; - memcpy(&bgp, dat, sizeof(bgp)); + TCHECK2(dat[0], BGP_SIZE); + memcpy(&bgp, dat, BGP_SIZE); printf("(%s", bgp_type(bgp.bgp_type)); /* ) */ switch (bgp.bgp_type) { @@ -669,6 +719,9 @@ bgp_header_print(const u_char *dat, int length) /* ( */ printf(")"); + return; +trunc: + printf("[|BGP]"); } void @@ -711,7 +764,7 @@ bgp_print(const u_char *dat, int length) /* found BGP header */ TCHECK2(p[0], BGP_SIZE); /*XXX*/ - memcpy(&bgp, p, sizeof(bgp)); + memcpy(&bgp, p, BGP_SIZE); if (start != p) printf(" [|BGP]"); |