summaryrefslogtreecommitdiff
path: root/print-ip6opts.c
diff options
context:
space:
mode:
authoritojun <itojun>1999-10-30 05:11:06 +0000
committeritojun <itojun>1999-10-30 05:11:06 +0000
commitc9d84d15c5c4dc8eca7594101fe5026080ed641e (patch)
tree79e5976a7e801dfa189fd653936ab06481654f91 /print-ip6opts.c
parentce751501abbddbe91d683d13b5cd845a5d551d8f (diff)
downloadtcpdump-c9d84d15c5c4dc8eca7594101fe5026080ed641e.tar.gz
Bring in KAME IPv6 tcpdump. replaces esp/ah/isakmp decoder.
Hope I did not break anything. Portability on IPv4-only node needs checking, I'll do this very soon. (sorry for rather jumbo commit) XXx what is _FAVOR_BSD?
Diffstat (limited to 'print-ip6opts.c')
-rw-r--r--print-ip6opts.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/print-ip6opts.c b/print-ip6opts.c
new file mode 100644
index 00000000..fe715b79
--- /dev/null
+++ b/print-ip6opts.c
@@ -0,0 +1,153 @@
+/*
+ * 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 INET6
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+void
+ip6_opt_print(const u_char *bp, int len)
+{
+ int i;
+ int optlen;
+
+ for (i = 0; i < len; i += optlen) {
+ switch (bp[i]) {
+ case IP6OPT_PAD1:
+ optlen = 1;
+ break;
+ case IP6OPT_PADN:
+ if (len - i < IP6OPT_MINLEN) {
+ printf("(padn: trunc)");
+ goto trunc;
+ }
+ optlen = bp[i + 1] + 2;
+ break;
+ case IP6OPT_RTALERT:
+ 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) ", ntohs(*(u_short *)&bp[i + 2]));
+ optlen = IP6OPT_RTALERT_LEN;
+ 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) ", (u_int32_t)ntohl(*(u_int *)&bp[i + 2]));
+ optlen = IP6OPT_JUMBO_LEN;
+ 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]);
+ optlen = bp[i + 1] + 2;
+ break;
+ }
+ }
+
+#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;
+ register const u_char *ep;
+ int hbhlen = 0;
+
+ /* 'ep' points to the end of avaible data. */
+ ep = snapend;
+ 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(hbhlen);
+}
+
+int
+dstopt_print(register const u_char *bp)
+{
+ const struct ip6_dest *dp = (struct ip6_dest *)bp;
+ register const u_char *ep;
+ int dstoptlen = 0;
+
+ /* 'ep' points to the end of avaible data. */
+ ep = snapend;
+ 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(dstoptlen);
+}
+#endif /* INET6 */