aboutsummaryrefslogtreecommitdiff
path: root/contrib/tcpdump/print-ip6opts.c
diff options
context:
space:
mode:
authorBill Fenner <fenner@FreeBSD.org>2001-04-03 07:45:48 +0000
committerBill Fenner <fenner@FreeBSD.org>2001-04-03 07:45:48 +0000
commit685295f4d740a26b206b4cae691262196b887f34 (patch)
tree6aab3a02ca4ebbeac636a060855172c8ebe77d46 /contrib/tcpdump/print-ip6opts.c
parentb0453382235492c8e30b09659b52d784128ca7d0 (diff)
downloadsrc-685295f4d740a26b206b4cae691262196b887f34.tar.gz
src-685295f4d740a26b206b4cae691262196b887f34.zip
Notes
Diffstat (limited to 'contrib/tcpdump/print-ip6opts.c')
-rw-r--r--contrib/tcpdump/print-ip6opts.c185
1 files changed, 174 insertions, 11 deletions
diff --git a/contrib/tcpdump/print-ip6opts.c b/contrib/tcpdump/print-ip6opts.c
index 756f098a3876..22d017e9d105 100644
--- a/contrib/tcpdump/print-ip6opts.c
+++ b/contrib/tcpdump/print-ip6opts.c
@@ -33,7 +33,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ip6opts.c,v 1.2.2.1 2000/01/11 06:58:25 fenner Exp $";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ip6opts.c,v 1.8 2000/12/13 07:57:05 itojun Exp $";
#endif
#ifdef INET6
@@ -43,13 +43,86 @@ static const char rcsid[] =
#include <sys/socket.h>
#include <netinet/in.h>
-#include <netinet/ip6.h>
-
#include <stdio.h>
+#include "ip6.h"
+
#include "interface.h"
#include "addrtoname.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_ALTCOA 0x4
+#define IP6SOPT_ALTCOA_MINLEN 18
+#define IP6SOPT_UI 0x2
+#define IP6SOPT_UI_MINLEN 4
+
+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) {
+ switch (bp[i]) {
+ case IP6OPT_PAD1:
+ printf(", pad1");
+ optlen = 1;
+ break;
+ case IP6OPT_PADN:
+ if (len - i < IP6OPT_MINLEN) {
+ printf(", padn: trunc");
+ goto trunc;
+ }
+ printf(", padn");
+ optlen = bp[i + 1] + 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]));
+ optlen = bp[i + 1] + 2;
+ break;
+ case IP6SOPT_UI:
+ if (len - i < IP6SOPT_UI_MINLEN) {
+ printf(", ui: trunc");
+ goto trunc;
+ }
+ printf("(ui: 0x%04x) ", ntohs(*(u_int16_t *)&bp[i + 2]));
+ optlen = bp[i + 1] + 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]);
+ optlen = bp[i + 1] + 2;
+ break;
+ }
+ }
+ return;
+
+trunc:
+ printf("[trunc] ");
+}
+
void
ip6_opt_print(const u_char *bp, int len)
{
@@ -59,6 +132,7 @@ ip6_opt_print(const u_char *bp, int len)
for (i = 0; i < len; i += optlen) {
switch (bp[i]) {
case IP6OPT_PAD1:
+ printf("(pad1)");
optlen = 1;
break;
case IP6OPT_PADN:
@@ -66,9 +140,10 @@ ip6_opt_print(const u_char *bp, int len)
printf("(padn: trunc)");
goto trunc;
}
+ printf("(padn)");
optlen = bp[i + 1] + 2;
break;
- case IP6OPT_RTALERT:
+ case IP6OPT_ROUTER_ALERT:
if (len - i < IP6OPT_RTALERT_LEN) {
printf("(rtalert: trunc)");
goto trunc;
@@ -77,7 +152,7 @@ ip6_opt_print(const u_char *bp, int len)
printf("(rtalert: invalid len %d)", bp[i + 1]);
goto trunc;
}
- printf("(rtalert: 0x%04x) ", ntohs(*(u_short *)&bp[i + 2]));
+ printf("(rtalert: 0x%04x) ", ntohs(*(u_int16_t *)&bp[i + 2]));
optlen = IP6OPT_RTALERT_LEN;
break;
case IP6OPT_JUMBO:
@@ -89,15 +164,103 @@ ip6_opt_print(const u_char *bp, int len)
printf("(jumbo: invalid len %d)", bp[i + 1]);
goto trunc;
}
- printf("(jumbo: %u) ", (u_int32_t)ntohl(*(u_int *)&bp[i + 2]));
+ printf("(jumbo: %u) ", (u_int32_t)ntohl(*(u_int32_t *)&bp[i + 2]));
optlen = IP6OPT_JUMBO_LEN;
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(")");
+ optlen = bp[i + 1] + 2;
+ 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("R");
+ if (bp[i + 2] & 0x10)
+ printf("D");
+ if (bp[i + 2] & 0x0f)
+ printf("res");
+ printf(", prefixlen: %u", bp[i + 3]);
+ printf(", sequence: %u",
+ (u_int16_t)ntohs(*(u_int16_t *)&bp[i + 4]));
+ printf(", lifetime: %u",
+ (u_int32_t)ntohs(*(u_int32_t *)&bp[i + 8]));
+
+ optlen = bp[i + 1] + 2;
+ 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]);
+ printf(", sequence: %u",
+ (u_int16_t)ntohs(*(u_int16_t *)&bp[i + 3]));
+ printf(", lifetime: %u",
+ (u_int32_t)ntohs(*(u_int32_t *)&bp[i + 7]));
+ printf(", refresh: %u",
+ (u_int32_t)ntohs(*(u_int32_t *)&bp[i + 11]));
+
+ if (bp[i + 1] > IP6OPT_BA_MINLEN - 2) {
+ ip6_sopt_print(&bp[i + IP6OPT_BA_MINLEN],
+ (optlen-IP6OPT_BA_MINLEN));
+ }
+ printf(")");
+ optlen = bp[i + 1] + 2;
+ 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(")");
+ optlen = bp[i + 1] + 2;
+ break;
default:
if (len - i < IP6OPT_MINLEN) {
printf("(type %d: trunc)", bp[i]);
goto trunc;
}
- printf("(type 0x%02x: len=%d) ", bp[i], bp[i + 1]);
+ printf("(opt_type 0x%02x: len=%d) ", bp[i], bp[i + 1]);
optlen = bp[i + 1] + 2;
break;
}
@@ -119,11 +282,11 @@ hbhopt_print(register const u_char *bp)
register const u_char *ep;
int hbhlen = 0;
- /* 'ep' points to the end of avaible data. */
+ /* 'ep' points to the end of available data. */
ep = snapend;
TCHECK(dp->ip6h_len);
hbhlen = (int)((dp->ip6h_len + 1) << 3);
- TCHECK2(dp, hbhlen);
+ TCHECK2(*dp, hbhlen);
printf("HBH ");
if (vflag)
ip6_opt_print((const u_char *)dp + sizeof(*dp), hbhlen - sizeof(*dp));
@@ -142,11 +305,11 @@ dstopt_print(register const u_char *bp)
register const u_char *ep;
int dstoptlen = 0;
- /* 'ep' points to the end of avaible data. */
+ /* 'ep' points to the end of available data. */
ep = snapend;
TCHECK(dp->ip6d_len);
dstoptlen = (int)((dp->ip6d_len + 1) << 3);
- TCHECK2(dp, dstoptlen);
+ TCHECK2(*dp, dstoptlen);
printf("DSTOPT ");
if (vflag) {
ip6_opt_print((const u_char *)dp + sizeof(*dp),