home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / tcpdumpb.zip / print-ospf.c < prev    next >
C/C++ Source or Header  |  1997-02-14  |  18KB  |  571 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.  * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
  22.  */
  23.  
  24. #ifndef lint
  25. static char rcsid[] =
  26.     "@(#) $Header: print-ospf.c,v 1.19 96/07/14 19:39:03 leres Exp $ (LBL)";
  27. #endif
  28.  
  29. #include <sys/param.h>
  30. #include <sys/time.h>
  31. #include <sys/socket.h>
  32.  
  33. #include <netinet/in.h>
  34. #include <netinet/in_systm.h>
  35. #include <netinet/ip.h>
  36. #ifndef __EMX__
  37. #include <netinet/ip_var.h>
  38. #endif
  39.  
  40. #include <ctype.h>
  41. #include <stdio.h>
  42.  
  43. #include "interface.h"
  44. #include "addrtoname.h"
  45.  
  46. #include "ospf.h"
  47.  
  48. struct bits {
  49.     u_int32_t bit;
  50.     const char *str;
  51. };
  52.  
  53. static const struct bits ospf_option_bits[] = {
  54.         { OSPF_OPTION_T,        "T" },
  55.         { OSPF_OPTION_E,        "E" },
  56.         { OSPF_OPTION_MC,       "MC" },
  57.         { 0,                    NULL }
  58. };
  59.  
  60. static const struct bits ospf_rla_flag_bits[] = {
  61.         { RLA_FLAG_B,           "B" },
  62.         { RLA_FLAG_E,           "E" },
  63.         { RLA_FLAG_W1,          "W1" },
  64.         { RLA_FLAG_W2,          "W2" },
  65.         { 0,                    NULL }
  66. };
  67.  
  68. static const char *ospf_types[OSPF_TYPE_MAX] = {
  69.   (char *) 0,
  70.   "hello",
  71.   "dd",
  72.   "ls_req",
  73.   "ls_upd",
  74.   "ls_ack"
  75. };
  76.  
  77. static inline void
  78. ospf_print_seqage(register u_int32_t seq, register time_t us)
  79. {
  80.     register time_t sec = us % 60;
  81.     register time_t mins = (us / 60) % 60;
  82.     register time_t hour = us/3600;
  83.  
  84.     printf(" S %X age ", seq);
  85.     if (hour) {
  86.         printf("%u:%02u:%02u",
  87.                (u_int32_t)hour,
  88.                (u_int32_t)mins,
  89.                (u_int32_t)sec);
  90.     } else if (mins) {
  91.         printf("%u:%02u",
  92.                (u_int32_t)mins,
  93.                (u_int32_t)sec);
  94.     } else {
  95.         printf("%u",
  96.                (u_int32_t)sec);
  97.     }
  98. }
  99.  
  100.  
  101. static inline void
  102. ospf_print_bits(register const struct bits *bp, register u_char options)
  103. {
  104.     char sep = ' ';
  105.  
  106.     do {
  107.         if (options & bp->bit) {
  108.             printf("%c%s",
  109.                    sep,
  110.                    bp->str);
  111.             sep = '/';
  112.         }
  113.     } while ((++bp)->bit) ;
  114. }
  115.  
  116.  
  117. #define LS_PRINT(lsp, type) switch (type) { \
  118.     case LS_TYPE_ROUTER: \
  119.         printf(" rtr %s ", ipaddr_string(&lsp->ls_router)); break; \
  120.     case LS_TYPE_NETWORK: \
  121.         printf(" net dr %s if %s", ipaddr_string(&lsp->ls_router), ipaddr_string(&lsp->ls_stateid)); break; \
  122.     case LS_TYPE_SUM_IP: \
  123.         printf(" sum %s abr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
  124.     case LS_TYPE_SUM_ABR: \
  125.         printf(" abr %s rtr %s", ipaddr_string(&lsp->ls_router), ipaddr_string(&lsp->ls_stateid)); break; \
  126.     case LS_TYPE_ASE: \
  127.         printf(" ase %s asbr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
  128.     case LS_TYPE_GROUP: \
  129.         printf(" group %s rtr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
  130.     }
  131.  
  132. static int
  133. ospf_print_lshdr(register const struct lsa_hdr *lshp, const caddr_t end)
  134. {
  135.     if ((caddr_t) (lshp + 1) > end) {
  136.         return 1;
  137.     }
  138.  
  139.     printf(" {");                                               /* } (ctags) */
  140.  
  141.     if (!lshp->ls_type || lshp->ls_type >= LS_TYPE_MAX) {
  142.         printf(" ??LS type %d?? }", lshp->ls_type);             /* { (ctags) */
  143.         return 1;
  144.     }
  145.  
  146.     ospf_print_bits(ospf_option_bits, lshp->ls_options);
  147.     ospf_print_seqage(ntohl(lshp->ls_seq), ntohs(lshp->ls_age));
  148.  
  149.     LS_PRINT(lshp, lshp->ls_type);
  150.  
  151.     return 0;
  152. }
  153.  
  154.  
  155. /*
  156.  * Print a single link state advertisement.  If truncated return 1, else 0.
  157.  */
  158.  
  159. static int
  160. ospf_print_lsa(register const struct lsa *lsap, const caddr_t end)
  161. {
  162.     register const char *ls_end;
  163.     const struct rlalink *rlp;
  164.     const struct tos_metric *tosp;
  165.     const struct in_addr *ap;
  166.     const struct aslametric *almp;
  167.     const struct mcla *mcp;
  168.     const u_int32_t *lp;
  169.     int j, k;
  170.  
  171.     if (ospf_print_lshdr(&lsap->ls_hdr, end)) {
  172.         return 1;
  173.     }
  174.  
  175.     ls_end = (caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length);
  176.  
  177.     if (ls_end > end) {
  178.         printf(" }");                                           /* { (ctags) */
  179.         return 1;
  180.     }
  181.  
  182.     switch (lsap->ls_hdr.ls_type) {
  183.     case LS_TYPE_ROUTER:
  184.         ospf_print_bits(ospf_rla_flag_bits, lsap->lsa_un.un_rla.rla_flags);
  185.  
  186.         j = ntohs(lsap->lsa_un.un_rla.rla_count);
  187.         rlp = lsap->lsa_un.un_rla.rla_link;
  188.         while (j--) {
  189.             struct rlalink *rln = (struct rlalink *) ((caddr_t) (rlp + 1) + ((rlp->link_toscount) * sizeof (struct tos_metric)));
  190.  
  191.             if ((caddr_t) rln > ls_end) {
  192.                 break;
  193.             }
  194.             printf(" {");                                       /* } (ctags) */
  195.  
  196.             switch (rlp->link_type) {
  197.             case RLA_TYPE_VIRTUAL:
  198.                 printf(" virt");
  199.                 /* Fall through */
  200.  
  201.             case RLA_TYPE_ROUTER:
  202.                 printf(" nbrid %s if %s",
  203.                        ipaddr_string(&rlp->link_id),
  204.                        ipaddr_string(&rlp->link_data));
  205.                 break;
  206.  
  207.             case RLA_TYPE_TRANSIT:
  208.                 printf(" dr %s if %s",
  209.                        ipaddr_string(&rlp->link_id),
  210.                        ipaddr_string(&rlp->link_data));
  211.                 break;
  212.  
  213.             case RLA_TYPE_STUB:
  214.                 printf(" net %s mask %s",
  215.                        ipaddr_string(&rlp->link_id),
  216.                        ipaddr_string(&rlp->link_data));
  217.                 break;
  218.  
  219.             default:
  220.                 printf(" ??RouterLinksType %d?? }",             /* { (ctags) */
  221.                        rlp->link_type);
  222.                 return 0;
  223.             }
  224.             printf(" tos 0 metric %d",
  225.                    ntohs(rlp->link_tos0metric));
  226.             tosp = (struct tos_metric *) ((sizeof rlp->link_tos0metric) + (caddr_t) rlp);
  227.             for (k = 0; k < rlp->link_toscount; k++, tosp++) {
  228.                 printf(" tos %d metric %d",
  229.                        tosp->tos_type,
  230.                        ntohs(tosp->tos_metric));
  231.             }
  232.             printf(" }");                                       /* { (ctags) */
  233.             rlp = rln;
  234.         }
  235.         break;
  236.  
  237.     case LS_TYPE_NETWORK:
  238.         printf(" mask %s rtrs",
  239.                ipaddr_string(&lsap->lsa_un.un_nla.nla_mask));
  240.         for (ap = lsap->lsa_un.un_nla.nla_router;
  241.              (caddr_t) (ap + 1) <= ls_end;
  242.              ap++) {
  243.             printf(" %s",
  244.                    ipaddr_string(ap));
  245.         }
  246.         break;
  247.  
  248.     case LS_TYPE_SUM_IP:
  249.         printf(" mask %s",
  250.                ipaddr_string(&lsap->lsa_un.un_sla.sla_mask));
  251.         /* Fall through */
  252.  
  253.     case LS_TYPE_SUM_ABR:
  254.  
  255.         for (lp = lsap->lsa_un.un_sla.sla_tosmetric;
  256.              (caddr_t) (lp + 1) <= ls_end;
  257.              lp++) {
  258.             u_int32_t ul = ntohl(*lp);
  259.  
  260.             printf(" tos %d metric %d",
  261.                    (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
  262.                    ul & SLA_MASK_METRIC);
  263.         }
  264.         break;
  265.  
  266.     case LS_TYPE_ASE:
  267.         printf(" mask %s",
  268.                ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));
  269.  
  270.         for (almp = lsap->lsa_un.un_asla.asla_metric;
  271.              (caddr_t) (almp + 1) <= ls_end;
  272.              almp++) {
  273.             u_int32_t ul = ntohl(almp->asla_tosmetric);
  274.  
  275.             printf(" type %d tos %d metric %d",
  276.                    (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1,
  277.                    (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS,
  278.                    (ul & ASLA_MASK_METRIC));
  279.             if (almp->asla_forward.s_addr) {
  280.                 printf(" forward %s",
  281.                        ipaddr_string(&almp->asla_forward));
  282.             }
  283.             if (almp->asla_tag.s_addr) {
  284.                 printf(" tag %s",
  285.                        ipaddr_string(&almp->asla_tag));
  286.             }
  287.         }
  288.         break;
  289.  
  290.     case LS_TYPE_GROUP:
  291.         /* Multicast extensions as of 23 July 1991 */
  292.         for (mcp = lsap->lsa_un.un_mcla;
  293.              (caddr_t) (mcp + 1) <= ls_end;
  294.              mcp++) {
  295.             switch (ntohl(mcp->mcla_vtype)) {
  296.             case MCLA_VERTEX_ROUTER:
  297.                 printf(" rtr rtrid %s",
  298.                        ipaddr_string(&mcp->mcla_vid));
  299.                 break;
  300.  
  301.             case MCLA_VERTEX_NETWORK:
  302.                 printf(" net dr %s",
  303.                        ipaddr_string(&mcp->mcla_vid));
  304.                 break;
  305.  
  306.             default:
  307.                 printf(" ??VertexType %u??",
  308.                        (u_int32_t)ntohl(mcp->mcla_vtype));
  309.                 break;
  310.             }
  311.         }
  312.     }
  313.  
  314.     printf(" }");                                               /* { (ctags) */
  315.     return 0;
  316. }
  317.  
  318.  
  319. void
  320. ospf_print(register const u_char *bp, register u_int length,
  321.            register const u_char *bp2)
  322. {
  323.     register const struct ospfhdr *op;
  324.     register const struct ip *ip;
  325.     register const caddr_t end = (caddr_t)snapend;
  326.     register const struct lsa *lsap;
  327.     register const struct lsa_hdr *lshp;
  328.     char sep;
  329.     int i, j;
  330.     const struct in_addr *ap;
  331.     const struct lsr *lsrp;
  332.  
  333.     op = (struct ospfhdr *)bp;
  334.     ip = (struct ip  *)bp2;
  335.     /* Print the source and destination address */
  336.     (void) printf("%s > %s:",
  337.                   ipaddr_string(&ip->ip_src),
  338.                   ipaddr_string(&ip->ip_dst));
  339.  
  340.     if ((caddr_t) (&op->ospf_len + 1) > end) {
  341.         goto trunc_test;
  342.     }
  343.  
  344.     /* If the type is valid translate it, or just print the type */
  345.     /* value.  If it's not valid, say so and return */
  346.     if (op->ospf_type || op->ospf_type < OSPF_TYPE_MAX) {
  347.         printf(" OSPFv%d-%s %d:",
  348.                op->ospf_version,
  349.                ospf_types[op->ospf_type],
  350.                length);
  351.     } else {
  352.         printf(" ospf-v%d-??type %d?? %d:",
  353.                op->ospf_version,
  354.                op->ospf_type,
  355.                length);
  356.         return;
  357.     }
  358.  
  359.     if (length != ntohs(op->ospf_len)) {
  360.         printf(" ??len %d??",
  361.                ntohs(op->ospf_len));
  362.         goto trunc_test;
  363.     }
  364.  
  365.     if ((caddr_t) (&op->ospf_routerid + 1) > end) {
  366.         goto trunc_test;
  367.     }
  368.  
  369.     /* Print the routerid if it is not the same as the source */
  370.     if (ip->ip_src.s_addr != op->ospf_routerid.s_addr) {
  371.         printf(" rtrid %s",
  372.                ipaddr_string(&op->ospf_routerid));
  373.     }
  374.  
  375.     if ((caddr_t) (&op->ospf_areaid + 1) > end) {
  376.         goto trunc_test;
  377.     }
  378.  
  379.     if (op->ospf_areaid.s_addr) {
  380.         printf(" area %s",
  381.                ipaddr_string(&op->ospf_areaid));
  382.     } else {
  383.         printf(" backbone");
  384.     }
  385.  
  386.     if ((caddr_t) (op->ospf_authdata + OSPF_AUTH_SIZE) > end) {
  387.         goto trunc_test;
  388.     }
  389.  
  390.     if (vflag) {
  391.         /* Print authentication data (should we really do this?) */
  392.         switch (ntohs(op->ospf_authtype)) {
  393.         case OSPF_AUTH_NONE:
  394.             break;
  395.  
  396.         case OSPF_AUTH_SIMPLE:
  397.             printf(" auth ");
  398.             j = 0;
  399.             for (i = 0; i < sizeof (op->ospf_authdata); i++) {
  400.                 if (!isprint(op->ospf_authdata[i])) {
  401.                     j = 1;
  402.                     break;
  403.                 }
  404.             }
  405.             if (j) {
  406.                 /* Print the auth-data as a string of octets */
  407.                 printf("%s.%s",
  408.                        ipaddr_string((struct in_addr *) op->ospf_authdata),
  409.                        ipaddr_string((struct in_addr *) &op->ospf_authdata[sizeof (struct in_addr)]));
  410.             } else {
  411.                 /* Print the auth-data as a text string */
  412.                 printf("'%.8s'",
  413.                        op->ospf_authdata);
  414.             }
  415.             break;
  416.  
  417.         default:
  418.             printf(" ??authtype-%d??",
  419.                    ntohs(op->ospf_authtype));
  420.             return;
  421.         }
  422.     }
  423.  
  424.  
  425.     /* Do rest according to version.    */
  426.     switch (op->ospf_version) {
  427.     case 2:
  428.         /* ospf version 2       */
  429.         switch (op->ospf_type) {
  430.         case OSPF_TYPE_UMD:             /* Rob Coltun's special monitoring packets; do nothing  */
  431.             break;
  432.  
  433.         case OSPF_TYPE_HELLO:
  434.             if ((caddr_t) (&op->ospf_hello.hello_deadint + 1) > end) {
  435.                 break;
  436.             }
  437.             if (vflag) {
  438.                 ospf_print_bits(ospf_option_bits, op->ospf_hello.hello_options);
  439.                 printf(" mask %s int %d pri %d dead %u",
  440.                        ipaddr_string(&op->ospf_hello.hello_mask),
  441.                        ntohs(op->ospf_hello.hello_helloint),
  442.                        op->ospf_hello.hello_priority,
  443.                        (u_int32_t)ntohl(op->ospf_hello.hello_deadint));
  444.             }
  445.  
  446.             if ((caddr_t) (&op->ospf_hello.hello_dr + 1) > end) {
  447.                 break;
  448.             }
  449.             if (op->ospf_hello.hello_dr.s_addr) {
  450.                 printf(" dr %s",
  451.                        ipaddr_string(&op->ospf_hello.hello_dr));
  452.             }
  453.  
  454.             if ((caddr_t) (&op->ospf_hello.hello_bdr + 1) > end) {
  455.                 break;
  456.             }
  457.             if (op->ospf_hello.hello_bdr.s_addr) {
  458.                 printf(" bdr %s",
  459.                        ipaddr_string(&op->ospf_hello.hello_bdr));
  460.             }
  461.  
  462.             if (vflag) {
  463.                 if ((caddr_t) (op->ospf_hello.hello_neighbor + 1) > end) {
  464.                     break;
  465.                 }
  466.                 printf(" nbrs");
  467.                 for (ap = op->ospf_hello.hello_neighbor;
  468.                      (caddr_t) (ap + 1) <= end;
  469.                      ap++) {
  470.                     printf(" %s",
  471.                            ipaddr_string(ap));
  472.                 }
  473.             }
  474.             break;                      /*  HELLO       */
  475.  
  476.         case OSPF_TYPE_DB:
  477.             if ((caddr_t) (&op->ospf_db.db_seq + 1) > end) {
  478.                 break;
  479.             }
  480.             ospf_print_bits(ospf_option_bits, op->ospf_db.db_options);
  481.             sep = ' ';
  482.             if (op->ospf_db.db_flags & OSPF_DB_INIT) {
  483.                 printf("%cI",
  484.                        sep);
  485.                 sep = '/';
  486.             }
  487.             if (op->ospf_db.db_flags & OSPF_DB_MORE) {
  488.                 printf("%cM",
  489.                        sep);
  490.                 sep = '/';
  491.             }
  492.             if (op->ospf_db.db_flags & OSPF_DB_MASTER) {
  493.                 printf("%cMS",
  494.                        sep);
  495.                 sep = '/';
  496.             }
  497.             printf(" S %X", (u_int32_t)ntohl(op->ospf_db.db_seq));
  498.  
  499.             if (vflag) {
  500.                 /* Print all the LS adv's */
  501.                 lshp = op->ospf_db.db_lshdr;
  502.  
  503.                 while (!ospf_print_lshdr(lshp, end)) {
  504.                     printf(" }");                               /* { (ctags) */
  505.                     lshp++;
  506.                 }
  507.             }
  508.             break;
  509.  
  510.         case OSPF_TYPE_LSR:
  511.             if (vflag) {
  512.                 for (lsrp = op->ospf_lsr; (caddr_t) (lsrp+1) <= end; lsrp++) {
  513.                     int32_t type;
  514.  
  515.                     if ((caddr_t) (lsrp + 1) > end) {
  516.                         break;
  517.                     }
  518.  
  519.                     printf(" {");                               /* } (ctags) */
  520.                     if (!(type = ntohl(lsrp->ls_type)) || type >= LS_TYPE_MAX) {
  521.                         printf(" ??LinkStateType %d }", type);  /* { (ctags) */
  522.                         printf(" }");                           /* { (ctags) */
  523.                         break;
  524.                     }
  525.  
  526.                     LS_PRINT(lsrp, type);
  527.                     printf(" }");                               /* { (ctags) */
  528.                 }
  529.             }
  530.             break;
  531.  
  532.         case OSPF_TYPE_LSU:
  533.             if (vflag) {
  534.                 lsap = op->ospf_lsu.lsu_lsa;
  535.                 i = ntohl(op->ospf_lsu.lsu_count);
  536.  
  537.                 while (i-- &&
  538.                        !ospf_print_lsa(lsap, end)) {
  539.                     lsap = (struct lsa *) ((caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length));
  540.                 }
  541.             }
  542.             break;
  543.  
  544.  
  545.         case OSPF_TYPE_LSA:
  546.             if (vflag) {
  547.                 lshp = op->ospf_lsa.lsa_lshdr;
  548.  
  549.                 while (!ospf_print_lshdr(lshp, end)) {
  550.                     printf(" }");                               /* { (ctags) */
  551.                     lshp++;
  552.                 }
  553.                 break;
  554.             }
  555.         }                       /* end switch on v2 packet type */
  556.         break;
  557.  
  558.     default:
  559.         printf(" ospf [version %d]",
  560.                op->ospf_version);
  561.         break;
  562.     }                                   /* end switch on version        */
  563.  
  564.   trunc_test:
  565.     if ((snapend - bp) < length) {
  566.         printf(" [|]");
  567.     }
  568.  
  569.     return;                             /* from ospf_print      */
  570. }
  571.