diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2002-09-18 19:39:36 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2002-09-18 19:39:36 +0000 |
commit | 47b2d466e73fcffa1e6299829ace5f46080fbc6c (patch) | |
tree | 4318d141aff762b6bd11ce3d6982f95385b0869d /usr.sbin | |
parent | 1c85df66fa6305a9baec8fac6e980fa1b7c4431d (diff) |
Fully decode source routing elements defined in rfc1702
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/tcpdump/print-gre.c | 103 |
1 files changed, 102 insertions, 1 deletions
diff --git a/usr.sbin/tcpdump/print-gre.c b/usr.sbin/tcpdump/print-gre.c index f010de904a2..6028a4fcbad 100644 --- a/usr.sbin/tcpdump/print-gre.c +++ b/usr.sbin/tcpdump/print-gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print-gre.c,v 1.3 2002/09/18 18:49:03 jason Exp $ */ +/* $OpenBSD: print-gre.c,v 1.4 2002/09/18 19:39:35 jason Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -31,6 +31,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ +/* + * tcpdump filter for GRE - Generic Routing Encapsulation (RFC1701 and RFC1702) + */ + #include <sys/param.h> #include <sys/time.h> #include <sys/uio.h> @@ -39,8 +43,10 @@ #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> +#include <arpa/inet.h> #include <stdio.h> +#include <string.h> #include "interface.h" #include "addrtoname.h" @@ -56,6 +62,14 @@ #define GREPROTO_IP 0x0800 /* IP */ +/* source route entry types */ +#define GRESRE_IP 0x0800 /* IP */ +#define GRESRE_ASN 0xfffe /* ASN */ + +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) { @@ -135,6 +149,8 @@ gre_print(const u_char *bp, u_int length) if (af == 0 && srelen == 0) break; + gre_sre_print(af, sreoff, srelen, bp, len); + if (len < srelen) goto trunc; bp += srelen; @@ -154,3 +170,88 @@ gre_print(const u_char *bp, u_int length) 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; + } +} |