home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / tcpdumpb.zip / print-dvmrp.c < prev    next >
C/C++ Source or Header  |  1997-02-14  |  11KB  |  346 lines

  1. /*
  2.  * Copyright (c) 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. #ifndef lint
  23. static char rcsid[] =
  24. "@(#) $Header: print-dvmrp.c,v 1.9 96/07/23 14:17:23 leres Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/param.h>
  28. #include <sys/time.h>
  29. #include <sys/socket.h>
  30.  
  31. #include <netinet/in.h>
  32. #include <netinet/in_systm.h>
  33. #include <netinet/ip.h>
  34. #ifndef __EMX__
  35. #include <netinet/ip_var.h>
  36. #endif
  37. #include <netinet/udp.h>
  38. #include <netinet/udp_var.h>
  39. #include <netinet/tcp.h>
  40. #ifndef __EMX__
  41. #include <netinet/tcpip.h>
  42. #endif
  43.  
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <stdlib.h>
  47. #include <unistd.h>
  48.  
  49. #include "interface.h"
  50. #include "addrtoname.h"
  51.  
  52. /*
  53.  * DVMRP message types and flag values shamelessly stolen from
  54.  * mrouted/dvmrp.h.
  55.  */
  56. #define DVMRP_PROBE             1       /* for finding neighbors */
  57. #define DVMRP_REPORT            2       /* for reporting some or all routes */
  58. #define DVMRP_ASK_NEIGHBORS     3       /* sent by mapper, asking for a list */
  59.                                         /*
  60.                                          * of this router's neighbors
  61.                                          */
  62. #define DVMRP_NEIGHBORS         4       /* response to such a request */
  63. #define DVMRP_ASK_NEIGHBORS2    5       /* as above, want new format reply */
  64. #define DVMRP_NEIGHBORS2        6
  65. #define DVMRP_PRUNE             7       /* prune message */
  66. #define DVMRP_GRAFT             8       /* graft message */
  67. #define DVMRP_GRAFT_ACK         9       /* graft acknowledgement */
  68.  
  69. /*
  70.  * 'flags' byte values in DVMRP_NEIGHBORS2 reply.
  71.  */
  72. #define DVMRP_NF_TUNNEL         0x01    /* neighbors reached via tunnel */
  73. #define DVMRP_NF_SRCRT          0x02    /* tunnel uses IP source routing */
  74. #define DVMRP_NF_DOWN           0x10    /* kernel state of interface */
  75. #define DVMRP_NF_DISABLED       0x20    /* administratively disabled */
  76. #define DVMRP_NF_QUERIER        0x40    /* I am the subnet's querier */
  77.  
  78. static void print_report(const u_char *, const u_char *, u_int);
  79. static void print_neighbors(const u_char *, const u_char *, u_int);
  80. static void print_neighbors2(const u_char *, const u_char *, u_int);
  81. static void print_prune(const u_char *, const u_char *, u_int);
  82. static void print_graft(const u_char *, const u_char *, u_int);
  83. static void print_graft_ack(const u_char *, const u_char *, u_int);
  84.  
  85. static u_int32_t target_level;
  86.  
  87. void
  88. dvmrp_print(register const u_char *bp, register u_int len)
  89. {
  90.         register const u_char *ep;
  91.         register u_char type;
  92.  
  93.         ep = (const u_char *)snapend;
  94.         if (bp >= ep)
  95.                 return;
  96.  
  97.         type = bp[1];
  98.         bp += 8;
  99.         /*
  100.          * Skip IGMP header
  101.          */
  102.  
  103.         len -= 8;
  104.  
  105.         switch (type) {
  106.         case DVMRP_PROBE:
  107.                 printf(" Probe");
  108.                 break;
  109.  
  110.         case DVMRP_REPORT:
  111.                 printf(" Report");
  112.                 if (vflag)
  113.                         print_report(bp, ep, len);
  114.                 break;
  115.  
  116.         case DVMRP_ASK_NEIGHBORS:
  117.                 printf(" Ask-neighbors(old)");
  118.                 break;
  119.  
  120.         case DVMRP_NEIGHBORS:
  121.                 printf(" Neighbors(old)");
  122.                 print_neighbors(bp, ep, len);
  123.                 break;
  124.  
  125.         case DVMRP_ASK_NEIGHBORS2:
  126.                 printf(" Ask-neighbors");
  127.                 break;
  128.  
  129.         case DVMRP_NEIGHBORS2:
  130.                 printf(" Neighbors");
  131.                 bp -= 4;
  132.                 target_level = ((u_int32_t) * bp++ << 24);
  133.                 /*
  134.                  * Group address in IGMP
  135.                  */
  136.  
  137.                 target_level += ((u_int32_t) * bp++ << 16);
  138.                 /*
  139.                  * header is version number
  140.                  */
  141.  
  142.                 target_level += ((u_int32_t) * bp++ << 8);
  143.                 target_level += ((u_int32_t) * bp++);
  144.                 target_level = htonl(target_level);
  145.                 print_neighbors2(bp, ep, len);
  146.                 break;
  147.  
  148.         case DVMRP_PRUNE:
  149.                 printf(" Prune");
  150.                 print_prune(bp, ep, len);
  151.                 break;
  152.  
  153.         case DVMRP_GRAFT:
  154.                 printf(" Graft");
  155.                 print_graft(bp, ep, len);
  156.                 break;
  157.  
  158.         case DVMRP_GRAFT_ACK:
  159.                 printf(" Graft-ACK");
  160.                 print_graft_ack(bp, ep, len);
  161.                 break;
  162.  
  163.         default:
  164.                 printf(" [type %d]", type);
  165.                 break;
  166.         }
  167. }
  168.  
  169. static void
  170. print_report(const u_char *bp, const u_char *ep, u_int len)
  171. {
  172.         u_int32_t mask, origin;
  173.         int metric;
  174.         int i;
  175.         int width;
  176.         int done;
  177.  
  178.         while (len > 0) {
  179.                 if (len < 3) {
  180.                         printf(" [|]");
  181.                         return;
  182.                 }
  183.                 mask = 0xff << 24 | bp[0] << 16 | bp[1] << 8 | bp[2];
  184.                 width = 1;
  185.                 if (bp[0])
  186.                         width = 2;
  187.                 if (bp[1])
  188.                         width = 3;
  189.                 if (bp[2])
  190.                         width = 4;
  191.  
  192.                 printf("\n\tMask %s", intoa(htonl(mask)));
  193.                 bp += 3;
  194.                 len -= 3;
  195.                 do {
  196.                         if (bp + width + 1 > ep) {
  197.                                 printf(" [|]");
  198.                                 return;
  199.                         }
  200.                         if (len < width + 1) {
  201.                                 printf("\n\t  [Truncated Report]");
  202.                                 return;
  203.                         }
  204.                         origin = 0;
  205.                         for (i = 0; i < width; ++i)
  206.                                 origin = origin << 8 | *bp++;
  207.                         for ( ; i < 4; ++i)
  208.                                 origin <<= 8;
  209.  
  210.                         metric = *bp++;
  211.                         done = metric & 0x80;
  212.                         metric &= 0x7f;
  213.                         printf("\n\t  %s metric %d", intoa(htonl(origin)),
  214.                                 metric);
  215.                         len -= width + 1;
  216.                 } while (!done);
  217.         }
  218. }
  219.  
  220. #define GET_ADDR(to) (memcpy((char*)to, (char*)bp, 4), bp += 4)
  221.  
  222. static void
  223. print_neighbors(const u_char *bp, const u_char *ep, u_int len)
  224. {
  225.         u_char laddr[4], neighbor[4];
  226.         u_char metric;
  227.         u_char thresh;
  228.         u_char save_nflag;
  229.         int ncount;
  230.  
  231.         save_nflag = nflag;
  232.         while (len > 0 && bp < ep) {
  233.                 if (len < 7 || (bp + 7) >= ep) {
  234.                         printf(" [|]");
  235.                         return;
  236.                 }
  237.                 GET_ADDR(laddr);
  238.                 metric = *bp++;
  239.                 thresh = *bp++;
  240.                 ncount = *bp++;
  241.                 len -= 7;
  242.                 while (--ncount >= 0 && (len >= 4) && (bp + 4) < ep) {
  243.                         GET_ADDR(neighbor);
  244.                         nflag = 0;
  245.                         printf(" [%s ->", ipaddr_string(laddr));
  246.                         nflag = save_nflag;
  247.                         printf(" %s, (%d/%d)]",
  248.                                    ipaddr_string(neighbor), metric, thresh);
  249.                         len -= 4;
  250.                 }
  251.         }
  252. }
  253.  
  254. static void
  255. print_neighbors2(const u_char *bp, const u_char *ep, u_int len)
  256. {
  257.         u_char laddr[4], neighbor[4];
  258.         u_char metric;
  259.         u_char thresh;
  260.         u_char flags;
  261.         u_char save_nflag;
  262.         int ncount;
  263.  
  264.         printf(" (v %d.%d):",
  265.                (int)target_level & 0xff,
  266.                (int)(target_level >> 8) & 0xff);
  267.  
  268.         save_nflag = nflag;
  269.         while (len > 0 && bp < ep) {
  270.                 if (len < 8 || (bp + 8) >= ep) {
  271.                         printf(" [|]");
  272.                         return;
  273.                 }
  274.                 GET_ADDR(laddr);
  275.                 metric = *bp++;
  276.                 thresh = *bp++;
  277.                 flags = *bp++;
  278.                 ncount = *bp++;
  279.                 len -= 8;
  280.                 while (--ncount >= 0 && (len >= 4) && (bp + 4) < ep) {
  281.                         GET_ADDR(neighbor);
  282.                         nflag = 0;
  283.                         printf(" [%s -> ", ipaddr_string(laddr));
  284.                         nflag = save_nflag;
  285.                         printf("%s (%d/%d", ipaddr_string(neighbor),
  286.                                      metric, thresh);
  287.                         if (flags & DVMRP_NF_TUNNEL)
  288.                                 printf("/tunnel");
  289.                         if (flags & DVMRP_NF_SRCRT)
  290.                                 printf("/srcrt");
  291.                         if (flags & DVMRP_NF_QUERIER)
  292.                                 printf("/querier");
  293.                         if (flags & DVMRP_NF_DISABLED)
  294.                                 printf("/disabled");
  295.                         if (flags & DVMRP_NF_DOWN)
  296.                                 printf("/down");
  297.                         printf(")]");
  298.                         len -= 4;
  299.                 }
  300.                 if (ncount != -1) {
  301.                         printf(" [|]");
  302.                         return;
  303.                 }
  304.         }
  305. }
  306.  
  307. static void
  308. print_prune(const u_char *bp, const u_char *ep, u_int len)
  309. {
  310.         union a {
  311.                 u_char b[4];
  312.                 u_int32_t i;
  313.         } prune_timer;
  314.  
  315.         if (len < 12 || (bp + 12) >= ep) {
  316.                 printf(" [|]");
  317.                 return;
  318.         }
  319.         printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
  320.         bp += 8;
  321.         GET_ADDR(prune_timer.b);
  322.         printf(" timer %d", (int)ntohl(prune_timer.i));
  323. }
  324.  
  325. static void
  326. print_graft(const u_char *bp, const u_char *ep, u_int len)
  327. {
  328.  
  329.         if (len < 8 || (bp + 8) >= ep) {
  330.                 printf(" [|]");
  331.                 return;
  332.         }
  333.         printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
  334. }
  335.  
  336. static void
  337. print_graft_ack(const u_char *bp, const u_char *ep, u_int len)
  338. {
  339.  
  340.         if (len < 8 || (bp + 8) >= ep) {
  341.                 printf(" [|]");
  342.                 return;
  343.         }
  344.         printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
  345. }
  346.