home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / tcpdumpb.zip / print-isoclns.c < prev    next >
C/C++ Source or Header  |  1996-07-15  |  7KB  |  320 lines

  1. /*
  2.  * Copyright (c) 1992, 1993, 1994, 1995, 1996
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. /*
  23.  * Original code by Matt Thomas, Digital Equipment Corporation
  24.  */
  25.  
  26. #ifndef lint
  27. static char rcsid[] =
  28.     "@(#) $Header: print-isoclns.c,v 1.12 96/07/14 19:39:00 leres Exp $ (LBL)";
  29. #endif
  30.  
  31. #include <sys/types.h>
  32. #include <sys/time.h>
  33. #include <sys/socket.h>
  34.  
  35. #if __STDC__
  36. struct mbuf;
  37. struct rtentry;
  38. #endif
  39. #include <net/if.h>
  40.  
  41. #include <netinet/in.h>
  42. #include <netinet/if_ether.h>
  43.  
  44. #include <stdio.h>
  45.  
  46. #include "interface.h"
  47. #include "addrtoname.h"
  48. #include "ethertype.h"
  49.  
  50. #define    CLNS    129
  51. #define    ESIS    130
  52. #define    ISIS    131
  53. #define    NULLNS    0
  54.  
  55. static int osi_cksum(const u_char *, u_int, const u_char *, u_char *, u_char *);
  56. static void esis_print(const u_char *, u_int);
  57.  
  58. void
  59. isoclns_print(const u_char *p, u_int length, u_int caplen,
  60.           const u_char *esrc, const u_char *edst)
  61. {
  62.     if (caplen < 1) {
  63.         printf("[|iso-clns] ");
  64.         if (!eflag)
  65.             printf("%s > %s",
  66.                    etheraddr_string(esrc),
  67.                    etheraddr_string(edst));
  68.         return;
  69.     }
  70.  
  71.     switch (*p) {
  72.  
  73.     case CLNS:
  74.         /* esis_print(&p, &length); */
  75.         printf("iso-clns");
  76.         if (!eflag)
  77.             (void)printf(" %s > %s",
  78.                      etheraddr_string(esrc),
  79.                      etheraddr_string(edst));
  80.         break;
  81.  
  82.     case ESIS:
  83.         printf("iso-esis");
  84.         if (!eflag)
  85.             (void)printf(" %s > %s",
  86.                      etheraddr_string(esrc),
  87.                      etheraddr_string(edst));
  88.         esis_print(p, length);
  89.         return;
  90.  
  91.     case ISIS:
  92.         printf("iso-isis");
  93.         if (!eflag)
  94.             (void)printf(" %s > %s",
  95.                      etheraddr_string(esrc),
  96.                      etheraddr_string(edst));
  97.         /* isis_print(&p, &length); */
  98.         (void)printf(" len=%d ", length);
  99.         if (caplen > 1)
  100.             default_print_unaligned(p, caplen);
  101.         break;
  102.  
  103.     case NULLNS:
  104.         printf("iso-nullns");
  105.         if (!eflag)
  106.             (void)printf(" %s > %s",
  107.                      etheraddr_string(esrc),
  108.                      etheraddr_string(edst));
  109.         break;
  110.  
  111.     default:
  112.         printf("iso-clns %02x", p[0]);
  113.         if (!eflag)
  114.             (void)printf(" %s > %s",
  115.                      etheraddr_string(esrc),
  116.                      etheraddr_string(edst));
  117.         (void)printf(" len=%d ", length);
  118.         if (caplen > 1)
  119.             default_print_unaligned(p, caplen);
  120.         break;
  121.     }
  122. }
  123.  
  124. #define    ESIS_REDIRECT    6
  125. #define    ESIS_ESH    2
  126. #define    ESIS_ISH    4
  127.  
  128. struct esis_hdr {
  129.     u_char version;
  130.     u_char reserved;
  131.     u_char type;
  132.     u_char tmo[2];
  133.     u_char cksum[2];
  134. };
  135.  
  136. static void
  137. esis_print(const u_char *p, u_int length)
  138. {
  139.     const u_char *ep;
  140.     int li = p[1];
  141.     const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
  142.     u_char cksum[2];
  143.     u_char off[2];
  144.  
  145.     if (length == 2) {
  146.         if (qflag)
  147.             printf(" bad pkt!");
  148.         else
  149.             printf(" no header at all!");
  150.         return;
  151.     }
  152.     ep = p + li;
  153.     if (li > length) {
  154.         if (qflag)
  155.             printf(" bad pkt!");
  156.         else
  157.             printf(" LI(%d) > PDU size (%d)!", li, length);
  158.         return;
  159.     }
  160.     if (li < sizeof(struct esis_hdr) + 2) {
  161.         if (qflag)
  162.             printf(" bad pkt!");
  163.         else {
  164.             printf(" too short for esis header %d:", li);
  165.             while (--length >= 0)
  166.                 printf("%02X", *p++);
  167.         }
  168.         return;
  169.     }
  170.     switch (eh->type & 0x1f) {
  171.  
  172.     case ESIS_REDIRECT:
  173.         printf(" redirect");
  174.         break;
  175.  
  176.     case ESIS_ESH:
  177.         printf(" esh");
  178.         break;
  179.  
  180.     case ESIS_ISH:
  181.         printf(" ish");
  182.         break;
  183.  
  184.     default:
  185.         printf(" type %d", eh->type & 0x1f);
  186.         break;
  187.     }
  188.     off[0] = eh->cksum[0];
  189.     off[1] = eh->cksum[1];
  190.     if (vflag && osi_cksum(p, li, eh->cksum, cksum, off)) {
  191.         printf(" bad cksum (got %02x%02x want %02x%02x)",
  192.                eh->cksum[1], eh->cksum[0], cksum[1], cksum[0]);
  193.         return;
  194.     }
  195.     if (eh->version != 1) {
  196.         printf(" unsupported version %d", eh->version);
  197.         return;
  198.     }
  199.     p += sizeof(*eh) + 2;
  200.     li -= sizeof(*eh) + 2;    /* protoid * li */
  201.  
  202.     switch (eh->type & 0x1f) {
  203.     case ESIS_REDIRECT: {
  204.         const u_char *dst, *snpa, *is;
  205.  
  206.         dst = p; p += *p + 1;
  207.         if (p > snapend)
  208.             return;
  209.         printf(" %s", isonsap_string(dst));
  210.         snpa = p; p += *p + 1;
  211.         is = p;   p += *p + 1;
  212.         if (p > snapend)
  213.             return;
  214.         if (p > ep) {
  215.             printf(" [bad li]");
  216.             return;
  217.         }
  218.         if (is[0] == 0)
  219.             printf(" > %s", etheraddr_string(&snpa[1]));
  220.         else
  221.             printf(" > %s", isonsap_string(is));
  222.         li = ep - p;
  223.         break;
  224.     }
  225. #if 0
  226.     case ESIS_ESH:
  227.         printf(" esh");
  228.         break;
  229. #endif
  230.     case ESIS_ISH: {
  231.         const u_char *is;
  232.  
  233.         is = p; p += *p + 1;
  234.         if (p > ep) {
  235.             printf(" [bad li]");
  236.             return;
  237.         }
  238.         if (p > snapend)
  239.             return;
  240.         printf(" %s", isonsap_string(is));
  241.         li = ep - p;
  242.         break;
  243.     }
  244.  
  245.     default:
  246.         (void)printf(" len=%d", length);
  247.         if (length && p < snapend) {
  248.             length = snapend - p;
  249.             default_print(p, length);
  250.         }
  251.         return;
  252.     }
  253.     if (vflag)
  254.         while (p < ep && li) {
  255.             int op, opli;
  256.             const u_char *q;
  257.  
  258.             if (snapend - p < 2)
  259.                 return;
  260.             if (li < 2) {
  261.                 printf(" bad opts/li");
  262.                 return;
  263.             }
  264.             op = *p++;
  265.             opli = *p++;
  266.             li -= 2;
  267.             if (opli > li) {
  268.                 printf(" opt (%d) too long", op);
  269.                 return;
  270.             }
  271.             li -= opli;
  272.             q = p;
  273.             p += opli;
  274.             if (snapend < p)
  275.                 return;
  276.             if (op == 198 && opli == 2) {
  277.                 printf(" tmo=%d", q[0] * 256 + q[1]);
  278.                 continue;
  279.             }
  280.             printf (" %d:<", op);
  281.             while (--opli >= 0)
  282.                 printf("%02x", *q++);
  283.             printf (">");
  284.         }
  285. }
  286.  
  287. static int
  288. osi_cksum(register const u_char *p, register u_int len,
  289.       const u_char *toff, u_char *cksum, u_char *off)
  290. {
  291.     int x, y, f = (len - ((toff - p) + 1));
  292.     int32_t c0 = 0, c1 = 0;
  293.  
  294.     if ((cksum[0] = off[0]) == 0 && (cksum[1] = off[1]) == 0)
  295.         return 0;
  296.  
  297.     off[0] = off[1] = 0;
  298.     while (--len >= 0) {
  299.         c0 += *p++;
  300.         c1 += c0;
  301.         c0 %= 255;
  302.         c1 %= 255;
  303.     }
  304.     x = (c0 * f - c1);
  305.     if (x < 0)
  306.         x = 255 - (-x % 255);
  307.     else
  308.         x %= 255;
  309.     y = -1 * (x + c0);
  310.     if (y < 0)
  311.         y = 255 - (-y % 255);
  312.     else
  313.         y %= 255;
  314.  
  315.     off[0] = x;
  316.     off[1] = y;
  317.  
  318.     return (off[0] != cksum[0] || off[1] != cksum[1]);
  319. }
  320.