diff options
Diffstat (limited to 'contrib/tcpdump/print-isoclns.c')
-rw-r--r-- | contrib/tcpdump/print-isoclns.c | 319 |
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]); +} |