summaryrefslogtreecommitdiffstats
path: root/contrib/tcpdump/print-isoclns.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tcpdump/print-isoclns.c')
-rw-r--r--contrib/tcpdump/print-isoclns.c319
1 files changed, 319 insertions, 0 deletions
diff --git a/contrib/tcpdump/print-isoclns.c b/contrib/tcpdump/print-isoclns.c
new file mode 100644
index 0000000..c7db005
--- /dev/null
+++ b/contrib/tcpdump/print-isoclns.c
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * Original code by Matt Thomas, Digital Equipment Corporation
+ */
+
+#ifndef lint
+static char rcsid[] =
+ "@(#) $Header: print-isoclns.c,v 1.12 96/07/14 19:39:00 leres Exp $ (LBL)";
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#define CLNS 129
+#define ESIS 130
+#define ISIS 131
+#define NULLNS 0
+
+static int osi_cksum(const u_char *, u_int, const u_char *, u_char *, u_char *);
+static void esis_print(const u_char *, u_int);
+
+void
+isoclns_print(const u_char *p, u_int length, u_int caplen,
+ const u_char *esrc, const u_char *edst)
+{
+ if (caplen < 1) {
+ printf("[|iso-clns] ");
+ if (!eflag)
+ printf("%s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ return;
+ }
+
+ switch (*p) {
+
+ case CLNS:
+ /* esis_print(&p, &length); */
+ printf("iso-clns");
+ if (!eflag)
+ (void)printf(" %s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ break;
+
+ case ESIS:
+ printf("iso-esis");
+ if (!eflag)
+ (void)printf(" %s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ esis_print(p, length);
+ return;
+
+ case ISIS:
+ printf("iso-isis");
+ if (!eflag)
+ (void)printf(" %s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ /* isis_print(&p, &length); */
+ (void)printf(" len=%d ", length);
+ if (caplen > 1)
+ default_print_unaligned(p, caplen);
+ break;
+
+ case NULLNS:
+ printf("iso-nullns");
+ if (!eflag)
+ (void)printf(" %s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ break;
+
+ default:
+ printf("iso-clns %02x", p[0]);
+ if (!eflag)
+ (void)printf(" %s > %s",
+ etheraddr_string(esrc),
+ etheraddr_string(edst));
+ (void)printf(" len=%d ", length);
+ if (caplen > 1)
+ default_print_unaligned(p, caplen);
+ break;
+ }
+}
+
+#define ESIS_REDIRECT 6
+#define ESIS_ESH 2
+#define ESIS_ISH 4
+
+struct esis_hdr {
+ u_char version;
+ u_char reserved;
+ u_char type;
+ u_char tmo[2];
+ u_char cksum[2];
+};
+
+static void
+esis_print(const u_char *p, u_int length)
+{
+ const u_char *ep;
+ int li = p[1];
+ const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
+ u_char cksum[2];
+ u_char off[2];
+
+ if (length == 2) {
+ if (qflag)
+ printf(" bad pkt!");
+ else
+ printf(" no header at all!");
+ return;
+ }
+ ep = p + li;
+ if (li > length) {
+ if (qflag)
+ printf(" bad pkt!");
+ else
+ printf(" LI(%d) > PDU size (%d)!", li, length);
+ return;
+ }
+ if (li < sizeof(struct esis_hdr) + 2) {
+ if (qflag)
+ printf(" bad pkt!");
+ else {
+ printf(" too short for esis header %d:", li);
+ while (--length >= 0)
+ printf("%02X", *p++);
+ }
+ return;
+ }
+ switch (eh->type & 0x1f) {
+
+ case ESIS_REDIRECT:
+ printf(" redirect");
+ break;
+
+ case ESIS_ESH:
+ printf(" esh");
+ break;
+
+ case ESIS_ISH:
+ printf(" ish");
+ break;
+
+ default:
+ printf(" type %d", eh->type & 0x1f);
+ break;
+ }
+ off[0] = eh->cksum[0];
+ off[1] = eh->cksum[1];
+ if (vflag && osi_cksum(p, li, eh->cksum, cksum, off)) {
+ printf(" bad cksum (got %02x%02x want %02x%02x)",
+ eh->cksum[1], eh->cksum[0], cksum[1], cksum[0]);
+ return;
+ }
+ if (eh->version != 1) {
+ printf(" unsupported version %d", eh->version);
+ return;
+ }
+ p += sizeof(*eh) + 2;
+ li -= sizeof(*eh) + 2; /* protoid * li */
+
+ switch (eh->type & 0x1f) {
+ case ESIS_REDIRECT: {
+ const u_char *dst, *snpa, *is;
+
+ dst = p; p += *p + 1;
+ if (p > snapend)
+ return;
+ printf(" %s", isonsap_string(dst));
+ snpa = p; p += *p + 1;
+ is = p; p += *p + 1;
+ if (p > snapend)
+ return;
+ if (p > ep) {
+ printf(" [bad li]");
+ return;
+ }
+ if (is[0] == 0)
+ printf(" > %s", etheraddr_string(&snpa[1]));
+ else
+ printf(" > %s", isonsap_string(is));
+ li = ep - p;
+ break;
+ }
+#if 0
+ case ESIS_ESH:
+ printf(" esh");
+ break;
+#endif
+ case ESIS_ISH: {
+ const u_char *is;
+
+ is = p; p += *p + 1;
+ if (p > ep) {
+ printf(" [bad li]");
+ return;
+ }
+ if (p > snapend)
+ return;
+ printf(" %s", isonsap_string(is));
+ li = ep - p;
+ break;
+ }
+
+ default:
+ (void)printf(" len=%d", length);
+ if (length && p < snapend) {
+ length = snapend - p;
+ default_print(p, length);
+ }
+ return;
+ }
+ if (vflag)
+ while (p < ep && li) {
+ int op, opli;
+ const u_char *q;
+
+ if (snapend - p < 2)
+ return;
+ if (li < 2) {
+ printf(" bad opts/li");
+ return;
+ }
+ op = *p++;
+ opli = *p++;
+ li -= 2;
+ if (opli > li) {
+ printf(" opt (%d) too long", op);
+ return;
+ }
+ li -= opli;
+ q = p;
+ p += opli;
+ if (snapend < p)
+ return;
+ if (op == 198 && opli == 2) {
+ printf(" tmo=%d", q[0] * 256 + q[1]);
+ continue;
+ }
+ printf (" %d:<", op);
+ while (--opli >= 0)
+ printf("%02x", *q++);
+ printf (">");
+ }
+}
+
+static int
+osi_cksum(register const u_char *p, register u_int len,
+ const u_char *toff, u_char *cksum, u_char *off)
+{
+ int x, y, f = (len - ((toff - p) + 1));
+ int32_t c0 = 0, c1 = 0;
+
+ if ((cksum[0] = off[0]) == 0 && (cksum[1] = off[1]) == 0)
+ return 0;
+
+ off[0] = off[1] = 0;
+ while (--len >= 0) {
+ c0 += *p++;
+ c1 += c0;
+ c0 %= 255;
+ c1 %= 255;
+ }
+ x = (c0 * f - c1);
+ if (x < 0)
+ x = 255 - (-x % 255);
+ else
+ x %= 255;
+ y = -1 * (x + c0);
+ if (y < 0)
+ y = 255 - (-y % 255);
+ else
+ y %= 255;
+
+ off[0] = x;
+ off[1] = y;
+
+ return (off[0] != cksum[0] || off[1] != cksum[1]);
+}
OpenPOWER on IntegriCloud