14edb46e9SPaul Traina /* 2699fc314SBill Fenner * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 34edb46e9SPaul Traina * The Regents of the University of California. All rights reserved. 44edb46e9SPaul Traina * 54edb46e9SPaul Traina * Redistribution and use in source and binary forms, with or without 64edb46e9SPaul Traina * modification, are permitted provided that: (1) source code distributions 74edb46e9SPaul Traina * retain the above copyright notice and this paragraph in its entirety, (2) 84edb46e9SPaul Traina * distributions including binary code include the above copyright notice and 94edb46e9SPaul Traina * this paragraph in its entirety in the documentation or other materials 104edb46e9SPaul Traina * provided with the distribution, and (3) all advertising materials mentioning 114edb46e9SPaul Traina * features or use of this software display the following acknowledgement: 124edb46e9SPaul Traina * ``This product includes software developed by the University of California, 134edb46e9SPaul Traina * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 144edb46e9SPaul Traina * the University nor the names of its contributors may be used to endorse 154edb46e9SPaul Traina * or promote products derived from this software without specific prior 164edb46e9SPaul Traina * written permission. 174edb46e9SPaul Traina * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 184edb46e9SPaul Traina * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 194edb46e9SPaul Traina * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 204edb46e9SPaul Traina * 214edb46e9SPaul Traina * Format and print bootp packets. 22a88113a8SBill Fenner * 23a88113a8SBill Fenner * $FreeBSD$ 244edb46e9SPaul Traina */ 254edb46e9SPaul Traina #ifndef lint 262ebf6c05SBill Fenner static const char rcsid[] = 27a88113a8SBill Fenner "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.48 1999/11/21 09:36:49 fenner Exp $ (LBL)"; 28a88113a8SBill Fenner #endif 29a88113a8SBill Fenner 30a88113a8SBill Fenner #ifdef HAVE_CONFIG_H 31a88113a8SBill Fenner #include "config.h" 324edb46e9SPaul Traina #endif 334edb46e9SPaul Traina 344edb46e9SPaul Traina #include <sys/param.h> 354edb46e9SPaul Traina #include <sys/time.h> 364edb46e9SPaul Traina #include <sys/socket.h> 374edb46e9SPaul Traina 384edb46e9SPaul Traina #if __STDC__ 394edb46e9SPaul Traina struct mbuf; 404edb46e9SPaul Traina struct rtentry; 414edb46e9SPaul Traina #endif 424edb46e9SPaul Traina #include <net/if.h> 434edb46e9SPaul Traina 444edb46e9SPaul Traina #include <netinet/in.h> 45ee3e7633SGarrett Wollman #include <net/ethernet.h> 464edb46e9SPaul Traina 474edb46e9SPaul Traina #include <ctype.h> 48699fc314SBill Fenner #ifdef HAVE_MEMORY_H 49699fc314SBill Fenner #include <memory.h> 50699fc314SBill Fenner #endif 514edb46e9SPaul Traina #include <stdio.h> 524edb46e9SPaul Traina #include <string.h> 534edb46e9SPaul Traina 544edb46e9SPaul Traina #include "interface.h" 554edb46e9SPaul Traina #include "addrtoname.h" 564edb46e9SPaul Traina #include "bootp.h" 574edb46e9SPaul Traina 584edb46e9SPaul Traina static void rfc1048_print(const u_char *, u_int); 594edb46e9SPaul Traina static void cmu_print(const u_char *, u_int); 604edb46e9SPaul Traina 614edb46e9SPaul Traina static char tstr[] = " [|bootp]"; 624edb46e9SPaul Traina 634edb46e9SPaul Traina /* 644edb46e9SPaul Traina * Print bootp requests 654edb46e9SPaul Traina */ 664edb46e9SPaul Traina void 674edb46e9SPaul Traina bootp_print(register const u_char *cp, u_int length, 684edb46e9SPaul Traina u_short sport, u_short dport) 694edb46e9SPaul Traina { 704edb46e9SPaul Traina register const struct bootp *bp; 714edb46e9SPaul Traina static u_char vm_cmu[4] = VM_CMU; 724edb46e9SPaul Traina static u_char vm_rfc1048[4] = VM_RFC1048; 734edb46e9SPaul Traina 744edb46e9SPaul Traina bp = (struct bootp *)cp; 754edb46e9SPaul Traina TCHECK(bp->bp_op); 764edb46e9SPaul Traina switch (bp->bp_op) { 774edb46e9SPaul Traina 784edb46e9SPaul Traina case BOOTREQUEST: 794edb46e9SPaul Traina /* Usually, a request goes from a client to a server */ 804edb46e9SPaul Traina if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS) 814edb46e9SPaul Traina printf(" (request)"); 824edb46e9SPaul Traina break; 834edb46e9SPaul Traina 844edb46e9SPaul Traina case BOOTREPLY: 854edb46e9SPaul Traina /* Usually, a reply goes from a server to a client */ 864edb46e9SPaul Traina if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC) 874edb46e9SPaul Traina printf(" (reply)"); 884edb46e9SPaul Traina break; 894edb46e9SPaul Traina 904edb46e9SPaul Traina default: 914edb46e9SPaul Traina printf(" bootp-#%d", bp->bp_op); 924edb46e9SPaul Traina } 934edb46e9SPaul Traina 944edb46e9SPaul Traina TCHECK(bp->bp_secs); 954edb46e9SPaul Traina 964edb46e9SPaul Traina /* The usual hardware address type is 1 (10Mb Ethernet) */ 974edb46e9SPaul Traina if (bp->bp_htype != 1) 984edb46e9SPaul Traina printf(" htype-#%d", bp->bp_htype); 994edb46e9SPaul Traina 1004edb46e9SPaul Traina /* The usual length for 10Mb Ethernet address is 6 bytes */ 1014edb46e9SPaul Traina if (bp->bp_htype != 1 || bp->bp_hlen != 6) 1024edb46e9SPaul Traina printf(" hlen:%d", bp->bp_hlen); 1034edb46e9SPaul Traina 1044edb46e9SPaul Traina /* Only print interesting fields */ 1054edb46e9SPaul Traina if (bp->bp_hops) 1064edb46e9SPaul Traina printf(" hops:%d", bp->bp_hops); 1074edb46e9SPaul Traina if (bp->bp_xid) 1084edb46e9SPaul Traina printf(" xid:0x%x", (u_int32_t)ntohl(bp->bp_xid)); 1094edb46e9SPaul Traina if (bp->bp_secs) 1104edb46e9SPaul Traina printf(" secs:%d", ntohs(bp->bp_secs)); 111a88113a8SBill Fenner if (bp->bp_flags) 112a88113a8SBill Fenner printf(" flags:0x%x", ntohs(bp->bp_flags)); 1134edb46e9SPaul Traina 1144edb46e9SPaul Traina /* Client's ip address */ 1154edb46e9SPaul Traina TCHECK(bp->bp_ciaddr); 1164edb46e9SPaul Traina if (bp->bp_ciaddr.s_addr) 1174edb46e9SPaul Traina printf(" C:%s", ipaddr_string(&bp->bp_ciaddr)); 1184edb46e9SPaul Traina 1194edb46e9SPaul Traina /* 'your' ip address (bootp client) */ 1204edb46e9SPaul Traina TCHECK(bp->bp_yiaddr); 1214edb46e9SPaul Traina if (bp->bp_yiaddr.s_addr) 1224edb46e9SPaul Traina printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr)); 1234edb46e9SPaul Traina 1244edb46e9SPaul Traina /* Server's ip address */ 1254edb46e9SPaul Traina TCHECK(bp->bp_siaddr); 1264edb46e9SPaul Traina if (bp->bp_siaddr.s_addr) 1274edb46e9SPaul Traina printf(" S:%s", ipaddr_string(&bp->bp_siaddr)); 1284edb46e9SPaul Traina 1294edb46e9SPaul Traina /* Gateway's ip address */ 1304edb46e9SPaul Traina TCHECK(bp->bp_giaddr); 1314edb46e9SPaul Traina if (bp->bp_giaddr.s_addr) 1324edb46e9SPaul Traina printf(" G:%s", ipaddr_string(&bp->bp_giaddr)); 1334edb46e9SPaul Traina 1344edb46e9SPaul Traina /* Client's Ethernet address */ 1354edb46e9SPaul Traina if (bp->bp_htype == 1 && bp->bp_hlen == 6) { 1364edb46e9SPaul Traina register const struct ether_header *eh; 1374edb46e9SPaul Traina register const char *e; 1384edb46e9SPaul Traina 1394edb46e9SPaul Traina TCHECK2(bp->bp_chaddr[0], 6); 1404edb46e9SPaul Traina eh = (struct ether_header *)packetp; 1414edb46e9SPaul Traina if (bp->bp_op == BOOTREQUEST) 1424edb46e9SPaul Traina e = (const char *)ESRC(eh); 1434edb46e9SPaul Traina else if (bp->bp_op == BOOTREPLY) 1444edb46e9SPaul Traina e = (const char *)EDST(eh); 1454edb46e9SPaul Traina else 1464edb46e9SPaul Traina e = 0; 1474edb46e9SPaul Traina if (e == 0 || memcmp((char *)bp->bp_chaddr, e, 6) != 0) 1484edb46e9SPaul Traina printf(" ether %s", etheraddr_string(bp->bp_chaddr)); 1494edb46e9SPaul Traina } 1504edb46e9SPaul Traina 1514edb46e9SPaul Traina TCHECK2(bp->bp_sname[0], 1); /* check first char only */ 1524edb46e9SPaul Traina if (*bp->bp_sname) { 1534edb46e9SPaul Traina printf(" sname \""); 1544edb46e9SPaul Traina if (fn_print(bp->bp_sname, snapend)) { 1554edb46e9SPaul Traina putchar('"'); 1564edb46e9SPaul Traina fputs(tstr + 1, stdout); 1574edb46e9SPaul Traina return; 1584edb46e9SPaul Traina } 159699fc314SBill Fenner putchar('"'); 1604edb46e9SPaul Traina } 1614edb46e9SPaul Traina TCHECK2(bp->bp_sname[0], 1); /* check first char only */ 1624edb46e9SPaul Traina if (*bp->bp_file) { 1634edb46e9SPaul Traina printf(" file \""); 1644edb46e9SPaul Traina if (fn_print(bp->bp_file, snapend)) { 1654edb46e9SPaul Traina putchar('"'); 1664edb46e9SPaul Traina fputs(tstr + 1, stdout); 1674edb46e9SPaul Traina return; 1684edb46e9SPaul Traina } 169699fc314SBill Fenner putchar('"'); 1704edb46e9SPaul Traina } 1714edb46e9SPaul Traina 1724edb46e9SPaul Traina /* Decode the vendor buffer */ 1734edb46e9SPaul Traina TCHECK(bp->bp_vend[0]); 1744edb46e9SPaul Traina length -= sizeof(*bp) - sizeof(bp->bp_vend); 1754edb46e9SPaul Traina if (memcmp((char *)bp->bp_vend, (char *)vm_rfc1048, 1764edb46e9SPaul Traina sizeof(u_int32_t)) == 0) 1774edb46e9SPaul Traina rfc1048_print(bp->bp_vend, length); 1784edb46e9SPaul Traina else if (memcmp((char *)bp->bp_vend, (char *)vm_cmu, 1794edb46e9SPaul Traina sizeof(u_int32_t)) == 0) 1804edb46e9SPaul Traina cmu_print(bp->bp_vend, length); 1814edb46e9SPaul Traina else { 1824edb46e9SPaul Traina u_int32_t ul; 1834edb46e9SPaul Traina 1844edb46e9SPaul Traina memcpy((char *)&ul, (char *)bp->bp_vend, sizeof(ul)); 1854edb46e9SPaul Traina if (ul != 0) 1864edb46e9SPaul Traina printf("vend-#0x%x", ul); 1874edb46e9SPaul Traina } 1884edb46e9SPaul Traina 1894edb46e9SPaul Traina return; 1904edb46e9SPaul Traina trunc: 1914edb46e9SPaul Traina fputs(tstr, stdout); 1924edb46e9SPaul Traina } 1934edb46e9SPaul Traina 1944edb46e9SPaul Traina /* The first character specifies the format to print */ 1954edb46e9SPaul Traina static struct tok tag2str[] = { 1964edb46e9SPaul Traina /* RFC1048 tags */ 1974edb46e9SPaul Traina { TAG_PAD, " PAD" }, 1984edb46e9SPaul Traina { TAG_SUBNET_MASK, "iSM" }, /* subnet mask (RFC950) */ 1994edb46e9SPaul Traina { TAG_TIME_OFFSET, "lTZ" }, /* seconds from UTC */ 2004edb46e9SPaul Traina { TAG_GATEWAY, "iDG" }, /* default gateway */ 2014edb46e9SPaul Traina { TAG_TIME_SERVER, "iTS" }, /* time servers (RFC868) */ 2024edb46e9SPaul Traina { TAG_NAME_SERVER, "iIEN" }, /* IEN name servers (IEN116) */ 2034edb46e9SPaul Traina { TAG_DOMAIN_SERVER, "iNS" }, /* domain name (RFC1035) */ 2044edb46e9SPaul Traina { TAG_LOG_SERVER, "iLOG" }, /* MIT log servers */ 2054edb46e9SPaul Traina { TAG_COOKIE_SERVER, "iCS" }, /* cookie servers (RFC865) */ 2064edb46e9SPaul Traina { TAG_LPR_SERVER, "iLPR" }, /* lpr server (RFC1179) */ 2074edb46e9SPaul Traina { TAG_IMPRESS_SERVER, "iIM" }, /* impress servers (Imagen) */ 2084edb46e9SPaul Traina { TAG_RLP_SERVER, "iRL" }, /* resource location (RFC887) */ 2094edb46e9SPaul Traina { TAG_HOSTNAME, "aHN" }, /* ascii hostname */ 2104edb46e9SPaul Traina { TAG_BOOTSIZE, "sBS" }, /* 512 byte blocks */ 2114edb46e9SPaul Traina { TAG_END, " END" }, 2124edb46e9SPaul Traina /* RFC1497 tags */ 2134edb46e9SPaul Traina { TAG_DUMPPATH, "aDP" }, 2144edb46e9SPaul Traina { TAG_DOMAINNAME, "aDN" }, 2154edb46e9SPaul Traina { TAG_SWAP_SERVER, "iSS" }, 2164edb46e9SPaul Traina { TAG_ROOTPATH, "aRP" }, 2174edb46e9SPaul Traina { TAG_EXTPATH, "aEP" }, 218a88113a8SBill Fenner /* RFC2132 tags */ 219a88113a8SBill Fenner { TAG_IP_FORWARD, "BIPF" }, 220a88113a8SBill Fenner { TAG_NL_SRCRT, "BSRT" }, 221a88113a8SBill Fenner { TAG_PFILTERS, "pPF" }, 222a88113a8SBill Fenner { TAG_REASS_SIZE, "sRSZ" }, 223a88113a8SBill Fenner { TAG_DEF_TTL, "bTTL" }, 224a88113a8SBill Fenner { TAG_MTU_TIMEOUT, "lMA" }, 225a88113a8SBill Fenner { TAG_MTU_TABLE, "sMT" }, 226a88113a8SBill Fenner { TAG_INT_MTU, "sMTU" }, 227a88113a8SBill Fenner { TAG_LOCAL_SUBNETS, "BLSN" }, 228a88113a8SBill Fenner { TAG_BROAD_ADDR, "iBR" }, 229a88113a8SBill Fenner { TAG_DO_MASK_DISC, "BMD" }, 230a88113a8SBill Fenner { TAG_SUPPLY_MASK, "BMS" }, 231a88113a8SBill Fenner { TAG_DO_RDISC, "BRD" }, 232a88113a8SBill Fenner { TAG_RTR_SOL_ADDR, "iRSA" }, 233a88113a8SBill Fenner { TAG_STATIC_ROUTE, "pSR" }, 234a88113a8SBill Fenner { TAG_USE_TRAILERS, "BUT" }, 235a88113a8SBill Fenner { TAG_ARP_TIMEOUT, "lAT" }, 236a88113a8SBill Fenner { TAG_ETH_ENCAP, "BIE" }, 237a88113a8SBill Fenner { TAG_TCP_TTL, "bTT" }, 238a88113a8SBill Fenner { TAG_TCP_KEEPALIVE, "lKI" }, 239a88113a8SBill Fenner { TAG_KEEPALIVE_GO, "BKG" }, 240a88113a8SBill Fenner { TAG_NIS_DOMAIN, "aYD" }, 241a88113a8SBill Fenner { TAG_NIS_SERVERS, "iYS" }, 242a88113a8SBill Fenner { TAG_NTP_SERVERS, "iNTP" }, 243a88113a8SBill Fenner { TAG_VENDOR_OPTS, "bVO" }, 244a88113a8SBill Fenner { TAG_NETBIOS_NS, "iWNS" }, 245a88113a8SBill Fenner { TAG_NETBIOS_DDS, "iWDD" }, 246a88113a8SBill Fenner { TAG_NETBIOS_NODE, "bWNT" }, 247a88113a8SBill Fenner { TAG_NETBIOS_SCOPE, "aWSC" }, 248a88113a8SBill Fenner { TAG_XWIN_FS, "iXFS" }, 249a88113a8SBill Fenner { TAG_XWIN_DM, "iXDM" }, 250a88113a8SBill Fenner { TAG_NIS_P_DOMAIN, "sN+D" }, 251a88113a8SBill Fenner { TAG_NIS_P_SERVERS, "iN+S" }, 252a88113a8SBill Fenner { TAG_MOBILE_HOME, "iMH" }, 253a88113a8SBill Fenner { TAG_SMPT_SERVER, "iSMTP" }, 254a88113a8SBill Fenner { TAG_POP3_SERVER, "iPOP3" }, 255a88113a8SBill Fenner { TAG_NNTP_SERVER, "iNNTP" }, 256a88113a8SBill Fenner { TAG_WWW_SERVER, "iWWW" }, 257a88113a8SBill Fenner { TAG_FINGER_SERVER, "iFG" }, 258a88113a8SBill Fenner { TAG_IRC_SERVER, "iIRC" }, 259a88113a8SBill Fenner { TAG_STREETTALK_SRVR, "iSTS" }, 260a88113a8SBill Fenner { TAG_STREETTALK_STDA, "iSTDA" }, 261a88113a8SBill Fenner { TAG_REQUESTED_IP, "iRQ" }, 262a88113a8SBill Fenner { TAG_IP_LEASE, "lLT" }, 263a88113a8SBill Fenner { TAG_OPT_OVERLOAD, "bOO" }, 264a88113a8SBill Fenner { TAG_TFTP_SERVER, "aTFTP" }, 265a88113a8SBill Fenner { TAG_BOOTFILENAME, "aBF" }, 266a88113a8SBill Fenner { TAG_DHCP_MESSAGE, " DHCP" }, 267a88113a8SBill Fenner { TAG_SERVER_ID, "iSID" }, 268a88113a8SBill Fenner { TAG_PARM_REQUEST, "bPR" }, 269a88113a8SBill Fenner { TAG_MESSAGE, "aMSG" }, 270a88113a8SBill Fenner { TAG_MAX_MSG_SIZE, "sMSZ" }, 271a88113a8SBill Fenner { TAG_RENEWAL_TIME, "lRN" }, 272a88113a8SBill Fenner { TAG_REBIND_TIME, "lRB" }, 273a88113a8SBill Fenner { TAG_VENDOR_CLASS, "bVC" }, 274a88113a8SBill Fenner { TAG_CLIENT_ID, "bCID" }, 2754edb46e9SPaul Traina { 0, NULL } 2764edb46e9SPaul Traina }; 2774edb46e9SPaul Traina 2784edb46e9SPaul Traina static void 2794edb46e9SPaul Traina rfc1048_print(register const u_char *bp, register u_int length) 2804edb46e9SPaul Traina { 2814edb46e9SPaul Traina register u_char tag; 2824edb46e9SPaul Traina register u_int len, size; 2834edb46e9SPaul Traina register const char *cp; 2844edb46e9SPaul Traina register char c; 2854edb46e9SPaul Traina int first; 2864edb46e9SPaul Traina u_int32_t ul; 2874edb46e9SPaul Traina u_short us; 2884edb46e9SPaul Traina 2894edb46e9SPaul Traina printf(" vend-rfc1048"); 2904edb46e9SPaul Traina 2914edb46e9SPaul Traina /* Step over magic cookie */ 2924edb46e9SPaul Traina bp += sizeof(int32_t); 2934edb46e9SPaul Traina 2944edb46e9SPaul Traina /* Loop while we there is a tag left in the buffer */ 2954edb46e9SPaul Traina while (bp + 1 < snapend) { 2964edb46e9SPaul Traina tag = *bp++; 2974edb46e9SPaul Traina if (tag == TAG_PAD) 2984edb46e9SPaul Traina continue; 2994edb46e9SPaul Traina if (tag == TAG_END) 3004edb46e9SPaul Traina return; 3014edb46e9SPaul Traina cp = tok2str(tag2str, "?T%d", tag); 3024edb46e9SPaul Traina c = *cp++; 3034edb46e9SPaul Traina printf(" %s:", cp); 3044edb46e9SPaul Traina 3054edb46e9SPaul Traina /* Get the length; check for truncation */ 3064edb46e9SPaul Traina if (bp + 1 >= snapend) { 3074edb46e9SPaul Traina fputs(tstr, stdout); 3084edb46e9SPaul Traina return; 3094edb46e9SPaul Traina } 3104edb46e9SPaul Traina len = *bp++; 3114edb46e9SPaul Traina if (bp + len >= snapend) { 3124edb46e9SPaul Traina fputs(tstr, stdout); 3134edb46e9SPaul Traina return; 3144edb46e9SPaul Traina } 3154edb46e9SPaul Traina 316a88113a8SBill Fenner if (tag == TAG_DHCP_MESSAGE && len == 1) { 317a88113a8SBill Fenner c = *bp++; 318a88113a8SBill Fenner switch (c) { 319a88113a8SBill Fenner case DHCPDISCOVER: printf("DISCOVER"); break; 320a88113a8SBill Fenner case DHCPOFFER: printf("OFFER"); break; 321a88113a8SBill Fenner case DHCPREQUEST: printf("REQUEST"); break; 322a88113a8SBill Fenner case DHCPDECLINE: printf("DECLINE"); break; 323a88113a8SBill Fenner case DHCPACK: printf("ACK"); break; 324a88113a8SBill Fenner case DHCPNAK: printf("NACK"); break; 325a88113a8SBill Fenner case DHCPRELEASE: printf("RELEASE"); break; 326a88113a8SBill Fenner case DHCPINFORM: printf("INFORM"); break; 327a88113a8SBill Fenner default: printf("%u", c); break; 328a88113a8SBill Fenner } 329a88113a8SBill Fenner continue; 330a88113a8SBill Fenner } 331a88113a8SBill Fenner 332a88113a8SBill Fenner if (tag == TAG_PARM_REQUEST) { 333a88113a8SBill Fenner first = 1; 334a88113a8SBill Fenner while (len-- > 0) { 335a88113a8SBill Fenner c = *bp++; 336a88113a8SBill Fenner cp = tok2str(tag2str, "?%d", c); 337a88113a8SBill Fenner if (!first) 338a88113a8SBill Fenner putchar('+'); 339a88113a8SBill Fenner printf("%s", cp + 1); 340a88113a8SBill Fenner first = 0; 341a88113a8SBill Fenner } 342a88113a8SBill Fenner continue; 343a88113a8SBill Fenner } 344a88113a8SBill Fenner 3454edb46e9SPaul Traina /* Print data */ 3464edb46e9SPaul Traina size = len; 3474edb46e9SPaul Traina if (c == '?') { 3484edb46e9SPaul Traina /* Base default formats for unknown tags on data size */ 3494edb46e9SPaul Traina if (size & 1) 3504edb46e9SPaul Traina c = 'b'; 3514edb46e9SPaul Traina else if (size & 2) 3524edb46e9SPaul Traina c = 's'; 3534edb46e9SPaul Traina else 3544edb46e9SPaul Traina c = 'l'; 3554edb46e9SPaul Traina } 3564edb46e9SPaul Traina first = 1; 3574edb46e9SPaul Traina switch (c) { 3584edb46e9SPaul Traina 3594edb46e9SPaul Traina case 'a': 3604edb46e9SPaul Traina /* ascii strings */ 3614edb46e9SPaul Traina putchar('"'); 3624edb46e9SPaul Traina (void)fn_printn(bp, size, NULL); 3634edb46e9SPaul Traina putchar('"'); 3644edb46e9SPaul Traina bp += size; 3654edb46e9SPaul Traina size = 0; 3664edb46e9SPaul Traina break; 3674edb46e9SPaul Traina 3684edb46e9SPaul Traina case 'i': 3694edb46e9SPaul Traina case 'l': 3704edb46e9SPaul Traina /* ip addresses/32-bit words */ 3714edb46e9SPaul Traina while (size >= sizeof(ul)) { 3724edb46e9SPaul Traina if (!first) 3734edb46e9SPaul Traina putchar(','); 3744edb46e9SPaul Traina memcpy((char *)&ul, (char *)bp, sizeof(ul)); 3754edb46e9SPaul Traina if (c == 'i') 3764edb46e9SPaul Traina printf("%s", ipaddr_string(&ul)); 3774edb46e9SPaul Traina else 3784edb46e9SPaul Traina printf("%u", ul); 3794edb46e9SPaul Traina bp += sizeof(ul); 3804edb46e9SPaul Traina size -= sizeof(ul); 3814edb46e9SPaul Traina first = 0; 3824edb46e9SPaul Traina } 3834edb46e9SPaul Traina break; 3844edb46e9SPaul Traina 385a88113a8SBill Fenner case 'p': 386a88113a8SBill Fenner /* IP address pairs */ 387a88113a8SBill Fenner while (size >= 2*sizeof(ul)) { 388a88113a8SBill Fenner if (!first) 389a88113a8SBill Fenner putchar(','); 390a88113a8SBill Fenner memcpy((char *)&ul, (char *)bp, sizeof(ul)); 391a88113a8SBill Fenner printf("(%s:", ipaddr_string(&ul)); 392a88113a8SBill Fenner bp += sizeof(ul); 393a88113a8SBill Fenner memcpy((char *)&ul, (char *)bp, sizeof(ul)); 394a88113a8SBill Fenner printf("%s)", ipaddr_string(&ul)); 395a88113a8SBill Fenner bp += sizeof(ul); 396a88113a8SBill Fenner size -= 2*sizeof(ul); 397a88113a8SBill Fenner first = 0; 398a88113a8SBill Fenner } 399a88113a8SBill Fenner break; 400a88113a8SBill Fenner 4014edb46e9SPaul Traina case 's': 4024edb46e9SPaul Traina /* shorts */ 4034edb46e9SPaul Traina while (size >= sizeof(us)) { 4044edb46e9SPaul Traina if (!first) 4054edb46e9SPaul Traina putchar(','); 4064edb46e9SPaul Traina memcpy((char *)&us, (char *)bp, sizeof(us)); 4074edb46e9SPaul Traina printf("%d", us); 4084edb46e9SPaul Traina bp += sizeof(us); 4094edb46e9SPaul Traina size -= sizeof(us); 4104edb46e9SPaul Traina first = 0; 4114edb46e9SPaul Traina } 4124edb46e9SPaul Traina break; 4134edb46e9SPaul Traina 414a88113a8SBill Fenner case 'B': 415a88113a8SBill Fenner /* boolean */ 416a88113a8SBill Fenner while (size > 0) { 417a88113a8SBill Fenner if (!first) 418a88113a8SBill Fenner putchar(','); 419a88113a8SBill Fenner switch (*bp) { 420a88113a8SBill Fenner case 0: 421a88113a8SBill Fenner putchar('N'); 422a88113a8SBill Fenner break; 423a88113a8SBill Fenner case 1: 424a88113a8SBill Fenner putchar('Y'); 425a88113a8SBill Fenner break; 426a88113a8SBill Fenner default: 427a88113a8SBill Fenner printf("%d?", *bp); 428a88113a8SBill Fenner break; 429a88113a8SBill Fenner } 430a88113a8SBill Fenner ++bp; 431a88113a8SBill Fenner --size; 432a88113a8SBill Fenner first = 0; 433a88113a8SBill Fenner } 434a88113a8SBill Fenner break; 435a88113a8SBill Fenner 4364edb46e9SPaul Traina case 'b': 4374edb46e9SPaul Traina default: 4384edb46e9SPaul Traina /* Bytes */ 4394edb46e9SPaul Traina while (size > 0) { 4404edb46e9SPaul Traina if (!first) 4414edb46e9SPaul Traina putchar('.'); 4424edb46e9SPaul Traina printf("%d", *bp); 4434edb46e9SPaul Traina ++bp; 4444edb46e9SPaul Traina --size; 4454edb46e9SPaul Traina first = 0; 4464edb46e9SPaul Traina } 4474edb46e9SPaul Traina break; 4484edb46e9SPaul Traina } 4494edb46e9SPaul Traina /* Data left over? */ 4504edb46e9SPaul Traina if (size) 4514edb46e9SPaul Traina printf("[len %d]", len); 4524edb46e9SPaul Traina } 4534edb46e9SPaul Traina } 4544edb46e9SPaul Traina 4554edb46e9SPaul Traina static void 4564edb46e9SPaul Traina cmu_print(register const u_char *bp, register u_int length) 4574edb46e9SPaul Traina { 4584edb46e9SPaul Traina register const struct cmu_vend *cmu; 4594edb46e9SPaul Traina char *fmt = " %s:%s"; 4604edb46e9SPaul Traina 4614edb46e9SPaul Traina #define PRINTCMUADDR(m, s) { TCHECK(cmu->m); \ 4624edb46e9SPaul Traina if (cmu->m.s_addr != 0) \ 4634edb46e9SPaul Traina printf(fmt, s, ipaddr_string(&cmu->m.s_addr)); } 4644edb46e9SPaul Traina 4654edb46e9SPaul Traina printf(" vend-cmu"); 4664edb46e9SPaul Traina cmu = (struct cmu_vend *)bp; 4674edb46e9SPaul Traina 4684edb46e9SPaul Traina /* Only print if there are unknown bits */ 4694edb46e9SPaul Traina TCHECK(cmu->v_flags); 4704edb46e9SPaul Traina if ((cmu->v_flags & ~(VF_SMASK)) != 0) 4714edb46e9SPaul Traina printf(" F:0x%x", cmu->v_flags); 4724edb46e9SPaul Traina PRINTCMUADDR(v_dgate, "DG"); 4734edb46e9SPaul Traina PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*"); 4744edb46e9SPaul Traina PRINTCMUADDR(v_dns1, "NS1"); 4754edb46e9SPaul Traina PRINTCMUADDR(v_dns2, "NS2"); 4764edb46e9SPaul Traina PRINTCMUADDR(v_ins1, "IEN1"); 4774edb46e9SPaul Traina PRINTCMUADDR(v_ins2, "IEN2"); 4784edb46e9SPaul Traina PRINTCMUADDR(v_ts1, "TS1"); 4794edb46e9SPaul Traina PRINTCMUADDR(v_ts2, "TS2"); 4804edb46e9SPaul Traina return; 4814edb46e9SPaul Traina 4824edb46e9SPaul Traina trunc: 4834edb46e9SPaul Traina fputs(tstr, stdout); 4844edb46e9SPaul Traina #undef PRINTCMUADDR 4854edb46e9SPaul Traina } 486