home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / bootpd-2.zip / PRINT-BO.C < prev    next >
C/C++ Source or Header  |  1995-09-04  |  13KB  |  498 lines

  1. /*
  2.  * Copyright (c) 1988-1990 The Regents of the University of California.
  3.  * 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.  * Format and print bootp packets.
  22.  *
  23.  * This file was copied from tcpdump-2.1.1 and modified.
  24.  * There is an e-mail list for tcpdump: <tcpdump@ee.lbl.gov>
  25.  */
  26.  
  27. #include <stdio.h>
  28.  
  29. #include <sys/param.h>
  30. #include <sys/types.h>
  31. #include <sys/socket.h>
  32.  
  33. #ifdef _AIX32
  34. #include <sys/time.h>    /* for struct timeval in net/if.h */
  35. #endif
  36. #include <net/if.h>
  37. #include <netinet/in.h>
  38.  
  39. #include <string.h>
  40. #include <ctype.h>
  41.  
  42. #include "bootp.h"
  43. #include "bootptest.h"
  44.  
  45. /* These decode the vendor data. */
  46. extern int printfn();
  47. static void rfc1048_print();
  48. static void cmu_print();
  49. static void other_print();
  50. static void dump_hex();
  51.  
  52. /*
  53.  * Print bootp requests
  54.  */
  55. void
  56. bootp_print(bp, length, sport, dport)
  57.     struct bootp *bp;
  58.     int length;
  59.     u_short sport, dport;
  60. {
  61.     static char tstr[] = " [|bootp]";
  62.     static unsigned char vm_cmu[4] = VM_CMU;
  63.     static unsigned char vm_rfc1048[4] = VM_RFC1048;
  64.     u_char *ep;
  65.     int vdlen;
  66.  
  67. #define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc
  68.  
  69.     /* Note funny sized packets */
  70.     if (length != sizeof(struct bootp))
  71.         (void) printf(" [len=%d]", length);
  72.  
  73.     /* 'ep' points to the end of avaible data. */
  74.     ep = (u_char *) snapend;
  75.  
  76.     switch (bp->bp_op) {
  77.  
  78.     case BOOTREQUEST:
  79.         /* Usually, a request goes from a client to a server */
  80.         if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS)
  81.             printf(" (request)");
  82.         break;
  83.  
  84.     case BOOTREPLY:
  85.         /* Usually, a reply goes from a server to a client */
  86.         if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC)
  87.             printf(" (reply)");
  88.         break;
  89.  
  90.     default:
  91.         printf(" bootp-#%d", bp->bp_op);
  92.     }
  93.  
  94.     /* The usual hardware address type is 1 (10Mb Ethernet) */
  95.     if (bp->bp_htype != 1)
  96.         printf(" htype:%d", bp->bp_htype);
  97.  
  98.     /* The usual length for 10Mb Ethernet address is 6 bytes */
  99.     if (bp->bp_hlen != 6)
  100.         printf(" hlen:%d", bp->bp_hlen);
  101.  
  102.     /* Client's Hardware address */
  103.     if (bp->bp_hlen) {
  104.         register struct ether_header *eh;
  105.         register char *e;
  106.  
  107.         TCHECK(bp->bp_chaddr[0], 6);
  108.         eh = (struct ether_header *) packetp;
  109.         if (bp->bp_op == BOOTREQUEST)
  110.             e = (char *) ESRC(eh);
  111.         else if (bp->bp_op == BOOTREPLY)
  112.             e = (char *) EDST(eh);
  113.         else
  114.             e = 0;
  115.         if (e == 0 || bcmp((char *) bp->bp_chaddr, e, 6))
  116.             dump_hex(bp->bp_chaddr, bp->bp_hlen);
  117.     }
  118.     /* Only print interesting fields */
  119.     if (bp->bp_hops)
  120.         printf(" hops:%d", bp->bp_hops);
  121.  
  122.     if (bp->bp_xid)
  123.         printf(" xid:%d", ntohl(bp->bp_xid));
  124.  
  125.     if (bp->bp_secs)
  126.         printf(" secs:%d", ntohs(bp->bp_secs));
  127.  
  128.     /* Client's ip address */
  129.     TCHECK(bp->bp_ciaddr, sizeof(bp->bp_ciaddr));
  130.     if (bp->bp_ciaddr.s_addr)
  131.         printf(" C:%s", ipaddr_string(&bp->bp_ciaddr));
  132.  
  133.     /* 'your' ip address (bootp client) */
  134.     TCHECK(bp->bp_yiaddr, sizeof(bp->bp_yiaddr));
  135.     if (bp->bp_yiaddr.s_addr)
  136.         printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr));
  137.  
  138.     /* Server's ip address */
  139.     TCHECK(bp->bp_siaddr, sizeof(bp->bp_siaddr));
  140.     if (bp->bp_siaddr.s_addr)
  141.         printf(" S:%s", ipaddr_string(&bp->bp_siaddr));
  142.  
  143.     /* Gateway's ip address */
  144.     TCHECK(bp->bp_giaddr, sizeof(bp->bp_giaddr));
  145.     if (bp->bp_giaddr.s_addr)
  146.         printf(" G:%s", ipaddr_string(&bp->bp_giaddr));
  147.  
  148.     TCHECK(bp->bp_sname[0], sizeof(bp->bp_sname));
  149.     if (*bp->bp_sname) {
  150.         printf(" sname:");
  151.         if (printfn(bp->bp_sname, ep)) {
  152.             fputs(tstr + 1, stdout);
  153.             return;
  154.         }
  155.     }
  156.     TCHECK(bp->bp_file[0], sizeof(bp->bp_file));
  157.     if (*bp->bp_file) {
  158.         printf(" file:");
  159.         if (printfn(bp->bp_file, ep)) {
  160.             fputs(tstr + 1, stdout);
  161.             return;
  162.         }
  163.     }
  164.     /* Don't try to decode the vendor buffer unless we're verbose */
  165.     if (vflag <= 0)
  166.         return;
  167.  
  168.     vdlen = sizeof(bp->bp_vend);
  169.     /* Vendor data can extend to the end of the packet. */
  170.     if (vdlen < (ep - bp->bp_vend))
  171.         vdlen = (ep - bp->bp_vend);
  172.  
  173.     TCHECK(bp->bp_vend[0], vdlen);
  174.     printf(" vend");
  175.     if (!bcmp(bp->bp_vend, vm_rfc1048, sizeof(u_int32)))
  176.         rfc1048_print(bp->bp_vend, vdlen);
  177.     else if (!bcmp(bp->bp_vend, vm_cmu, sizeof(u_int32)))
  178.         cmu_print(bp->bp_vend, vdlen);
  179.     else
  180.         other_print(bp->bp_vend, vdlen);
  181.  
  182.     return;
  183.  trunc:
  184.     fputs(tstr, stdout);
  185. #undef TCHECK
  186. }
  187.  
  188. /*
  189.  * Option description data follows.
  190.  * These are decribed in: RFC-1048, RFC-1395, RFC-1497, RFC-1533
  191.  *
  192.  * The first char of each option string encodes the data format:
  193.  * ?: unknown
  194.  * a: ASCII
  195.  * b: byte (8-bit)
  196.  * i: inet address
  197.  * l: int32
  198.  * s: short (16-bit)
  199.  */
  200. char *
  201. rfc1048_opts[] = {
  202.     /* Originally from RFC-1048: */
  203.     "?PAD",                /*  0: Padding - special, no data. */
  204.     "iSM",                /*  1: subnet mask (RFC950)*/
  205.     "lTZ",                /*  2: time offset, seconds from UTC */
  206.     "iGW",                /*  3: gateways (or routers) */
  207.     "iTS",                /*  4: time servers (RFC868) */
  208.     "iINS",                /*  5: IEN name servers (IEN116) */
  209.     "iDNS",                /*  6: domain name servers (RFC1035)(1034?) */
  210.     "iLOG",                /*  7: MIT log servers */
  211.     "iCS",                /*  8: cookie servers (RFC865) */
  212.     "iLPR",                /*  9: lpr server (RFC1179) */
  213.     "iIPS",                /* 10: impress servers (Imagen) */
  214.     "iRLP",                /* 11: resource location servers (RFC887) */
  215.     "aHN",                /* 12: host name (ASCII) */
  216.     "sBFS",                /* 13: boot file size (in 512 byte blocks) */
  217.  
  218.     /* Added by RFC-1395: */
  219.     "aDUMP",            /* 14: Merit Dump File */
  220.     "aDNAM",            /* 15: Domain Name (for DNS) */
  221.     "iSWAP",            /* 16: Swap Server */
  222.     "aROOT",            /* 17: Root Path */
  223.  
  224.     /* Added by RFC-1497: */
  225.     "aEXTF",            /* 18: Extensions Path (more options) */
  226.  
  227.     /* Added by RFC-1533: (many, many options...) */
  228. #if 1    /* These might not be worth recognizing by name. */
  229.  
  230.     /* IP Layer Parameters, per-host (RFC-1533, sect. 4) */
  231.     "bIP-forward",        /* 19: IP Forwarding flag */
  232.     "bIP-srcroute",        /* 20: IP Source Routing Enable flag */
  233.     "iIP-filters",        /* 21: IP Policy Filter (addr pairs) */
  234.     "sIP-maxudp",        /* 22: IP Max-UDP reassembly size */
  235.     "bIP-ttlive",        /* 23: IP Time to Live */
  236.     "lIP-pmtuage",        /* 24: IP Path MTU aging timeout */
  237.     "sIP-pmtutab",        /* 25: IP Path MTU plateau table */
  238.  
  239.     /* IP parameters, per-interface (RFC-1533, sect. 5) */
  240.     "sIP-mtu-sz",        /* 26: IP MTU size */
  241.     "bIP-mtu-sl",        /* 27: IP MTU all subnets local */
  242.     "bIP-bcast1",        /* 28: IP Broadcast Addr ones flag */
  243.     "bIP-mask-d",        /* 29: IP do mask discovery */
  244.     "bIP-mask-s",        /* 30: IP do mask supplier */
  245.     "bIP-rt-dsc",        /* 31: IP do router discovery */
  246.     "iIP-rt-sa",        /* 32: IP router solicitation addr */
  247.     "iIP-routes",        /* 33: IP static routes (dst,router) */
  248.  
  249.     /* Link Layer parameters, per-interface (RFC-1533, sect. 6) */
  250.     "bLL-trailer",        /* 34: do tralier encapsulation */
  251.     "lLL-arp-tmo",        /* 35: ARP cache timeout */
  252.     "bLL-ether2",        /* 36: Ethernet version 2 (IEEE 802.3) */
  253.  
  254.     /* TCP parameters (RFC-1533, sect. 7) */
  255.     "bTCP-def-ttl",        /* 37: default time to live */
  256.     "lTCP-KA-tmo",        /* 38: keepalive time interval */
  257.     "bTCP-KA-junk",        /* 39: keepalive sends extra junk */
  258.  
  259.     /* Application and Service Parameters (RFC-1533, sect. 8) */
  260.     "aNISDOM",            /* 40: NIS Domain (Sun YP) */
  261.     "iNISSRV",            /* 41: NIS Servers */
  262.     "iNTPSRV",            /* 42: NTP (time) Servers (RFC 1129) */
  263.     "?VSINFO",            /* 43: Vendor Specific Info (encapsulated) */
  264.     "iNBiosNS",            /* 44: NetBIOS Name Server (RFC-1001,1..2) */
  265.     "iNBiosDD",            /* 45: NetBIOS Datagram Dist. Server. */
  266.     "bNBiosNT",            /* 46: NetBIOS Note Type */
  267.     "?NBiosS",            /* 47: NetBIOS Scope */
  268.     "iXW-FS",            /* 48: X Window System Font Servers */
  269.     "iXW-DM",            /* 49: X Window System Display Managers */
  270.  
  271.     /* DHCP extensions (RFC-1533, sect. 9) PeP hic facet */
  272.     "iDHCPreq",            /* 50: DHCP requested IP address */
  273.     "lDHCPlease",            /* 51: DHCP lease time */ 
  274.     "bDHCPooptol",            /* 52: DHCP option overload */
  275.     "bDHCPtype",            /* 53: DHCP message type */
  276.     "iDHCPSid",            /* 54: DHCP server ID */
  277. #endif
  278. };
  279. #define    KNOWN_OPTIONS (sizeof(rfc1048_opts) / sizeof(rfc1048_opts[0]))
  280.  
  281. static void
  282. rfc1048_print(bp, length)
  283.     register u_char *bp;
  284.     int length;
  285. {
  286.     u_char tag;
  287.     u_char *ep;
  288.     register int len;
  289.     u_int32 ul;
  290.     u_short us;
  291.     struct in_addr ia;
  292.     char *optstr;
  293.  
  294.     printf("-rfc1395");
  295.  
  296.     /* Step over magic cookie */
  297.     bp += sizeof(int32);
  298.     /* Setup end pointer */
  299.     ep = bp + length;
  300.     while (bp < ep) {
  301.         tag = *bp++;
  302.         /* Check for tags with no data first. */
  303.         if (tag == TAG_PAD)
  304.             continue;
  305.         if (tag == TAG_END)
  306.             return;
  307.         if (tag < KNOWN_OPTIONS) {
  308.             optstr = rfc1048_opts[tag];
  309.             printf(" %s:", optstr + 1);
  310.         } else {
  311.             printf(" T%d:", tag);
  312.             optstr = "?";
  313.         }
  314.         /* Now scan the length byte. */
  315.         len = *bp++;
  316.         if (bp + len > ep) {
  317.             /* truncated option */
  318.             printf(" |(%d>%d)", len, ep - bp);
  319.             return;
  320.         }
  321.         /* Print the option value(s). */
  322.         switch (optstr[0]) {
  323.  
  324.         case 'a':                /* ASCII string */
  325.             printfn(bp, bp + len);
  326.             bp += len;
  327.             len = 0;
  328.             break;
  329.  
  330.         case 's':                /* Word formats */
  331.             while (len >= 2) {
  332.                 bcopy((char *) bp, (char *) &us, 2);
  333.                 printf("%d", ntohs(us));
  334.                 bp += 2;
  335.                 len -= 2;
  336.                 if (len) printf(",");
  337.             }
  338.             if (len) printf("(junk=%d)", len);
  339.             break;
  340.  
  341.         case 'l':                /* Long words */
  342.             while (len >= 4) {
  343.                 bcopy((char *) bp, (char *) &ul, 4);
  344.                 printf("%d", ntohl(ul));
  345.                 bp += 4;
  346.                 len -= 4;
  347.                 if (len) printf(",");
  348.             }
  349.             if (len) printf("(junk=%d)", len);
  350.             break;
  351.  
  352.         case 'i':                /* INET addresses */
  353.             while (len >= 4) {
  354.                 bcopy((char *) bp, (char *) &ia, 4);
  355.                 printf("%s", ipaddr_string(&ia));
  356.                 bp += 4;
  357.                 len -= 4;
  358.                 if (len) printf(",");
  359.             }
  360.             if (len) printf("(junk=%d)", len);
  361.             break;
  362.  
  363.         case 'b':
  364.         default:
  365.             break;
  366.  
  367.         }                        /* switch */
  368.  
  369.         /* Print as characters, if appropriate. */
  370.         if (len) {
  371.             dump_hex(bp, len);
  372.             if (isascii(*bp) && isprint(*bp)) {
  373.                 printf("(");
  374.                 printfn(bp, bp + len);
  375.                 printf(")");
  376.             }
  377.             bp += len;
  378.             len = 0;
  379.         }
  380.     } /* while bp < ep */
  381. }
  382.  
  383. static void
  384. cmu_print(bp, length)
  385.     register u_char *bp;
  386.     int length;
  387. {
  388.     struct cmu_vend *v;
  389.     u_char *ep;
  390.  
  391.     printf("-cmu");
  392.  
  393.     v = (struct cmu_vend *) bp;
  394.     if (length < sizeof(*v)) {
  395.         printf(" |L=%d", length);
  396.         return;
  397.     }
  398.     /* Setup end pointer */
  399.     ep = bp + length;
  400.  
  401.     /* Subnet mask */
  402.     if (v->v_flags & VF_SMASK) {
  403.         printf(" SM:%s", ipaddr_string(&v->v_smask));
  404.     }
  405.     /* Default gateway */
  406.     if (v->v_dgate.s_addr)
  407.         printf(" GW:%s", ipaddr_string(&v->v_dgate));
  408.  
  409.     /* Domain name servers */
  410.     if (v->v_dns1.s_addr)
  411.         printf(" DNS1:%s", ipaddr_string(&v->v_dns1));
  412.     if (v->v_dns2.s_addr)
  413.         printf(" DNS2:%s", ipaddr_string(&v->v_dns2));
  414.  
  415.     /* IEN-116 name servers */
  416.     if (v->v_ins1.s_addr)
  417.         printf(" INS1:%s", ipaddr_string(&v->v_ins1));
  418.     if (v->v_ins2.s_addr)
  419.         printf(" INS2:%s", ipaddr_string(&v->v_ins2));
  420.  
  421.     /* Time servers */
  422.     if (v->v_ts1.s_addr)
  423.         printf(" TS1:%s", ipaddr_string(&v->v_ts1));
  424.     if (v->v_ts2.s_addr)
  425.         printf(" TS2:%s", ipaddr_string(&v->v_ts2));
  426.  
  427. }
  428.  
  429.  
  430. /*
  431.  * Print out arbitrary, unknown vendor data.
  432.  */
  433.  
  434. static void
  435. other_print(bp, length)
  436.     register u_char *bp;
  437.     int length;
  438. {
  439.     u_char *ep;                    /* end pointer */
  440.     u_char *zp;                    /* points one past last non-zero byte */
  441.  
  442.     /* Setup end pointer */
  443.     ep = bp + length;
  444.  
  445.     /* Find the last non-zero byte. */
  446.     for (zp = ep; zp > bp; zp--) {
  447.         if (zp[-1] != 0)
  448.             break;
  449.     }
  450.  
  451.     /* Print the all-zero case in a compact representation. */
  452.     if (zp == bp) {
  453.         printf("-all-zero");
  454.         return;
  455.     }
  456.     printf("-unknown");
  457.  
  458.     /* Are there enough trailing zeros to make "00..." worthwhile? */
  459.     if (zp + 2 > ep)
  460.         zp = ep;                /* print them all normally */
  461.  
  462.     /* Now just print all the non-zero data. */
  463.     while (bp < zp) {
  464.         printf(".%02X", *bp);
  465.         bp++;
  466.     }
  467.  
  468.     if (zp < ep)
  469.         printf(".00...");
  470.  
  471.     return;
  472. }
  473.  
  474. static void
  475. dump_hex(bp, len)
  476.     u_char *bp;
  477.     int len;
  478. {
  479.     while (len > 0) {
  480.         printf("%02X", *bp);
  481.         bp++;
  482.         len--;
  483.         if (len) printf(".");
  484.     }
  485. }
  486.  
  487. /*
  488.  * Local Variables:
  489.  * tab-width: 4
  490.  * c-indent-level: 4
  491.  * c-argdecl-indent: 4
  492.  * c-continued-statement-offset: 4
  493.  * c-continued-brace-offset: -4
  494.  * c-label-offset: -4
  495.  * c-brace-offset: 0
  496.  * End:
  497.  */
  498.