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 26cc391cceSBruce M Simpson static const char rcsid[] _U_ = 27abf25193SMax Laier "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.78.2.9 2007/08/21 22:02:08 guy Exp $ (LBL)"; 28a88113a8SBill Fenner #endif 29a88113a8SBill Fenner 30a88113a8SBill Fenner #ifdef HAVE_CONFIG_H 31a88113a8SBill Fenner #include "config.h" 324edb46e9SPaul Traina #endif 334edb46e9SPaul Traina 34cc391cceSBruce M Simpson #include <tcpdump-stdinc.h> 354edb46e9SPaul Traina 364edb46e9SPaul Traina #include <stdio.h> 374edb46e9SPaul Traina #include <string.h> 384edb46e9SPaul Traina 394edb46e9SPaul Traina #include "interface.h" 404edb46e9SPaul Traina #include "addrtoname.h" 41943ee2b1SBill Fenner #include "extract.h" 42943ee2b1SBill Fenner #include "ether.h" 434edb46e9SPaul Traina #include "bootp.h" 444edb46e9SPaul Traina 45a1c2090eSBill Fenner static void rfc1048_print(const u_char *); 46a1c2090eSBill Fenner static void cmu_print(const u_char *); 47abf25193SMax Laier static char *client_fqdn_flags(u_int flags); 484edb46e9SPaul Traina 494edb46e9SPaul Traina static char tstr[] = " [|bootp]"; 504edb46e9SPaul Traina 51cc391cceSBruce M Simpson static const struct tok bootp_flag_values[] = { 52cc391cceSBruce M Simpson { 0x8000, "Broadcast" }, 53cc391cceSBruce M Simpson { 0, NULL} 54cc391cceSBruce M Simpson }; 55cc391cceSBruce M Simpson 56cc391cceSBruce M Simpson static const struct tok bootp_op_values[] = { 57cc391cceSBruce M Simpson { BOOTPREQUEST, "Request" }, 58cc391cceSBruce M Simpson { BOOTPREPLY, "Reply" }, 59cc391cceSBruce M Simpson { 0, NULL} 60cc391cceSBruce M Simpson }; 61cc391cceSBruce M Simpson 624edb46e9SPaul Traina /* 634edb46e9SPaul Traina * Print bootp requests 644edb46e9SPaul Traina */ 654edb46e9SPaul Traina void 66cc391cceSBruce M Simpson bootp_print(register const u_char *cp, u_int length) 674edb46e9SPaul Traina { 684edb46e9SPaul Traina register const struct bootp *bp; 69a1c2090eSBill Fenner static const u_char vm_cmu[4] = VM_CMU; 70a1c2090eSBill Fenner static const u_char vm_rfc1048[4] = VM_RFC1048; 714edb46e9SPaul Traina 72a1c2090eSBill Fenner bp = (const struct bootp *)cp; 734edb46e9SPaul Traina TCHECK(bp->bp_op); 744edb46e9SPaul Traina 75cc391cceSBruce M Simpson printf("BOOTP/DHCP, %s", 76cc391cceSBruce M Simpson tok2str(bootp_op_values, "unknown (0x%02x)", bp->bp_op)); 774edb46e9SPaul Traina 78cc391cceSBruce M Simpson if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { 79cc391cceSBruce M Simpson TCHECK2(bp->bp_chaddr[0], 6); 80cc391cceSBruce M Simpson printf(" from %s", etheraddr_string(bp->bp_chaddr)); 814edb46e9SPaul Traina } 824edb46e9SPaul Traina 83abf25193SMax Laier printf(", length %u", length); 84cc391cceSBruce M Simpson 85cc391cceSBruce M Simpson if (!vflag) 86cc391cceSBruce M Simpson return; 87cc391cceSBruce M Simpson 884edb46e9SPaul Traina TCHECK(bp->bp_secs); 894edb46e9SPaul Traina 904edb46e9SPaul Traina /* The usual hardware address type is 1 (10Mb Ethernet) */ 914edb46e9SPaul Traina if (bp->bp_htype != 1) 92abf25193SMax Laier printf(", htype %d", bp->bp_htype); 934edb46e9SPaul Traina 944edb46e9SPaul Traina /* The usual length for 10Mb Ethernet address is 6 bytes */ 954edb46e9SPaul Traina if (bp->bp_htype != 1 || bp->bp_hlen != 6) 96abf25193SMax Laier printf(", hlen %d", bp->bp_hlen); 974edb46e9SPaul Traina 984edb46e9SPaul Traina /* Only print interesting fields */ 994edb46e9SPaul Traina if (bp->bp_hops) 100abf25193SMax Laier printf(", hops %d", bp->bp_hops); 1014edb46e9SPaul Traina if (bp->bp_xid) 102abf25193SMax Laier printf(", xid 0x%x", EXTRACT_32BITS(&bp->bp_xid)); 1034edb46e9SPaul Traina if (bp->bp_secs) 104abf25193SMax Laier printf(", secs %d", EXTRACT_16BITS(&bp->bp_secs)); 105cc391cceSBruce M Simpson 106abf25193SMax Laier printf(", Flags [%s]", 107cc391cceSBruce M Simpson bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags))); 108cc391cceSBruce M Simpson if (vflag > 1) 109cc391cceSBruce M Simpson printf(" (0x%04x)", EXTRACT_16BITS(&bp->bp_flags)); 1104edb46e9SPaul Traina 1114edb46e9SPaul Traina /* Client's ip address */ 1124edb46e9SPaul Traina TCHECK(bp->bp_ciaddr); 1134edb46e9SPaul Traina if (bp->bp_ciaddr.s_addr) 114abf25193SMax Laier printf("\n\t Client-IP %s", ipaddr_string(&bp->bp_ciaddr)); 1154edb46e9SPaul Traina 1164edb46e9SPaul Traina /* 'your' ip address (bootp client) */ 1174edb46e9SPaul Traina TCHECK(bp->bp_yiaddr); 1184edb46e9SPaul Traina if (bp->bp_yiaddr.s_addr) 119abf25193SMax Laier printf("\n\t Your-IP %s", ipaddr_string(&bp->bp_yiaddr)); 1204edb46e9SPaul Traina 1214edb46e9SPaul Traina /* Server's ip address */ 1224edb46e9SPaul Traina TCHECK(bp->bp_siaddr); 1234edb46e9SPaul Traina if (bp->bp_siaddr.s_addr) 124abf25193SMax Laier printf("\n\t Server-IP %s", ipaddr_string(&bp->bp_siaddr)); 1254edb46e9SPaul Traina 1264edb46e9SPaul Traina /* Gateway's ip address */ 1274edb46e9SPaul Traina TCHECK(bp->bp_giaddr); 1284edb46e9SPaul Traina if (bp->bp_giaddr.s_addr) 129abf25193SMax Laier printf("\n\t Gateway-IP %s", ipaddr_string(&bp->bp_giaddr)); 1304edb46e9SPaul Traina 1314edb46e9SPaul Traina /* Client's Ethernet address */ 1324edb46e9SPaul Traina if (bp->bp_htype == 1 && bp->bp_hlen == 6) { 1334edb46e9SPaul Traina TCHECK2(bp->bp_chaddr[0], 6); 134abf25193SMax Laier printf("\n\t Client-Ethernet-Address %s", etheraddr_string(bp->bp_chaddr)); 1354edb46e9SPaul Traina } 1364edb46e9SPaul Traina 1374edb46e9SPaul Traina TCHECK2(bp->bp_sname[0], 1); /* check first char only */ 1384edb46e9SPaul Traina if (*bp->bp_sname) { 139cc391cceSBruce M Simpson printf("\n\t sname \""); 1404edb46e9SPaul Traina if (fn_print(bp->bp_sname, snapend)) { 1414edb46e9SPaul Traina putchar('"'); 1424edb46e9SPaul Traina fputs(tstr + 1, stdout); 1434edb46e9SPaul Traina return; 1444edb46e9SPaul Traina } 145699fc314SBill Fenner putchar('"'); 1464edb46e9SPaul Traina } 147cc391cceSBruce M Simpson TCHECK2(bp->bp_file[0], 1); /* check first char only */ 1484edb46e9SPaul Traina if (*bp->bp_file) { 149cc391cceSBruce M Simpson printf("\n\t file \""); 1504edb46e9SPaul Traina if (fn_print(bp->bp_file, snapend)) { 1514edb46e9SPaul Traina putchar('"'); 1524edb46e9SPaul Traina fputs(tstr + 1, stdout); 1534edb46e9SPaul Traina return; 1544edb46e9SPaul Traina } 155699fc314SBill Fenner putchar('"'); 1564edb46e9SPaul Traina } 1574edb46e9SPaul Traina 1584edb46e9SPaul Traina /* Decode the vendor buffer */ 1594edb46e9SPaul Traina TCHECK(bp->bp_vend[0]); 160a1c2090eSBill Fenner if (memcmp((const char *)bp->bp_vend, vm_rfc1048, 1614edb46e9SPaul Traina sizeof(u_int32_t)) == 0) 162a1c2090eSBill Fenner rfc1048_print(bp->bp_vend); 163a1c2090eSBill Fenner else if (memcmp((const char *)bp->bp_vend, vm_cmu, 1644edb46e9SPaul Traina sizeof(u_int32_t)) == 0) 165a1c2090eSBill Fenner cmu_print(bp->bp_vend); 1664edb46e9SPaul Traina else { 1674edb46e9SPaul Traina u_int32_t ul; 1684edb46e9SPaul Traina 169943ee2b1SBill Fenner ul = EXTRACT_32BITS(&bp->bp_vend); 1704edb46e9SPaul Traina if (ul != 0) 171cc391cceSBruce M Simpson printf("\n\t Vendor-#0x%x", ul); 1724edb46e9SPaul Traina } 1734edb46e9SPaul Traina 1744edb46e9SPaul Traina return; 1754edb46e9SPaul Traina trunc: 1764edb46e9SPaul Traina fputs(tstr, stdout); 1774edb46e9SPaul Traina } 1784edb46e9SPaul Traina 179a1c2090eSBill Fenner /* 180a1c2090eSBill Fenner * The first character specifies the format to print: 181a1c2090eSBill Fenner * i - ip address (32 bits) 182a1c2090eSBill Fenner * p - ip address pairs (32 bits + 32 bits) 183a1c2090eSBill Fenner * l - long (32 bits) 184a1c2090eSBill Fenner * L - unsigned long (32 bits) 185a1c2090eSBill Fenner * s - short (16 bits) 186a1c2090eSBill Fenner * b - period-seperated decimal bytes (variable length) 187a1c2090eSBill Fenner * x - colon-seperated hex bytes (variable length) 188a1c2090eSBill Fenner * a - ascii string (variable length) 189a1c2090eSBill Fenner * B - on/off (8 bits) 190a1c2090eSBill Fenner * $ - special (explicit code to handle) 191a1c2090eSBill Fenner */ 1924edb46e9SPaul Traina static struct tok tag2str[] = { 1934edb46e9SPaul Traina /* RFC1048 tags */ 1944edb46e9SPaul Traina { TAG_PAD, " PAD" }, 195abf25193SMax Laier { TAG_SUBNET_MASK, "iSubnet-Mask" }, /* subnet mask (RFC950) */ 196abf25193SMax Laier { TAG_TIME_OFFSET, "LTime-Zone" }, /* seconds from UTC */ 197abf25193SMax Laier { TAG_GATEWAY, "iDefault-Gateway" }, /* default gateway */ 198abf25193SMax Laier { TAG_TIME_SERVER, "iTime-Server" }, /* time servers (RFC868) */ 199abf25193SMax Laier { TAG_NAME_SERVER, "iIEN-Name-Server" }, /* IEN name servers (IEN116) */ 200abf25193SMax Laier { TAG_DOMAIN_SERVER, "iDomain-Name-Server" }, /* domain name (RFC1035) */ 2014edb46e9SPaul Traina { TAG_LOG_SERVER, "iLOG" }, /* MIT log servers */ 2024edb46e9SPaul Traina { TAG_COOKIE_SERVER, "iCS" }, /* cookie servers (RFC865) */ 203abf25193SMax Laier { TAG_LPR_SERVER, "iLPR-Server" }, /* lpr server (RFC1179) */ 2044edb46e9SPaul Traina { TAG_IMPRESS_SERVER, "iIM" }, /* impress servers (Imagen) */ 2054edb46e9SPaul Traina { TAG_RLP_SERVER, "iRL" }, /* resource location (RFC887) */ 206abf25193SMax Laier { TAG_HOSTNAME, "aHostname" }, /* ascii hostname */ 2074edb46e9SPaul Traina { TAG_BOOTSIZE, "sBS" }, /* 512 byte blocks */ 2084edb46e9SPaul Traina { TAG_END, " END" }, 2094edb46e9SPaul Traina /* RFC1497 tags */ 2104edb46e9SPaul Traina { TAG_DUMPPATH, "aDP" }, 211abf25193SMax Laier { TAG_DOMAINNAME, "aDomain-Name" }, 2124edb46e9SPaul Traina { TAG_SWAP_SERVER, "iSS" }, 2134edb46e9SPaul Traina { TAG_ROOTPATH, "aRP" }, 2144edb46e9SPaul Traina { TAG_EXTPATH, "aEP" }, 215a88113a8SBill Fenner /* RFC2132 tags */ 216a88113a8SBill Fenner { TAG_IP_FORWARD, "BIPF" }, 217a88113a8SBill Fenner { TAG_NL_SRCRT, "BSRT" }, 218a88113a8SBill Fenner { TAG_PFILTERS, "pPF" }, 219a88113a8SBill Fenner { TAG_REASS_SIZE, "sRSZ" }, 220a88113a8SBill Fenner { TAG_DEF_TTL, "bTTL" }, 221abf25193SMax Laier { TAG_MTU_TIMEOUT, "lMTU-Timeout" }, 222abf25193SMax Laier { TAG_MTU_TABLE, "sMTU-Table" }, 223a88113a8SBill Fenner { TAG_INT_MTU, "sMTU" }, 224a88113a8SBill Fenner { TAG_LOCAL_SUBNETS, "BLSN" }, 225a88113a8SBill Fenner { TAG_BROAD_ADDR, "iBR" }, 226a88113a8SBill Fenner { TAG_DO_MASK_DISC, "BMD" }, 227a88113a8SBill Fenner { TAG_SUPPLY_MASK, "BMS" }, 228abf25193SMax Laier { TAG_DO_RDISC, "BRouter-Discovery" }, 229a88113a8SBill Fenner { TAG_RTR_SOL_ADDR, "iRSA" }, 230abf25193SMax Laier { TAG_STATIC_ROUTE, "pStatic-Route" }, 231a88113a8SBill Fenner { TAG_USE_TRAILERS, "BUT" }, 232a88113a8SBill Fenner { TAG_ARP_TIMEOUT, "lAT" }, 233a88113a8SBill Fenner { TAG_ETH_ENCAP, "BIE" }, 234a88113a8SBill Fenner { TAG_TCP_TTL, "bTT" }, 235a88113a8SBill Fenner { TAG_TCP_KEEPALIVE, "lKI" }, 236a88113a8SBill Fenner { TAG_KEEPALIVE_GO, "BKG" }, 237a88113a8SBill Fenner { TAG_NIS_DOMAIN, "aYD" }, 238a88113a8SBill Fenner { TAG_NIS_SERVERS, "iYS" }, 239a88113a8SBill Fenner { TAG_NTP_SERVERS, "iNTP" }, 240abf25193SMax Laier { TAG_VENDOR_OPTS, "bVendor-Option" }, 241abf25193SMax Laier { TAG_NETBIOS_NS, "iNetbios-Name-Server" }, 242a88113a8SBill Fenner { TAG_NETBIOS_DDS, "iWDD" }, 243abf25193SMax Laier { TAG_NETBIOS_NODE, "$Netbios-Node" }, 244abf25193SMax Laier { TAG_NETBIOS_SCOPE, "aNetbios-Scope" }, 245a88113a8SBill Fenner { TAG_XWIN_FS, "iXFS" }, 246a88113a8SBill Fenner { TAG_XWIN_DM, "iXDM" }, 247a88113a8SBill Fenner { TAG_NIS_P_DOMAIN, "sN+D" }, 248a88113a8SBill Fenner { TAG_NIS_P_SERVERS, "iN+S" }, 249a88113a8SBill Fenner { TAG_MOBILE_HOME, "iMH" }, 250a88113a8SBill Fenner { TAG_SMPT_SERVER, "iSMTP" }, 251a88113a8SBill Fenner { TAG_POP3_SERVER, "iPOP3" }, 252a88113a8SBill Fenner { TAG_NNTP_SERVER, "iNNTP" }, 253a88113a8SBill Fenner { TAG_WWW_SERVER, "iWWW" }, 254a88113a8SBill Fenner { TAG_FINGER_SERVER, "iFG" }, 255a88113a8SBill Fenner { TAG_IRC_SERVER, "iIRC" }, 256a88113a8SBill Fenner { TAG_STREETTALK_SRVR, "iSTS" }, 257a88113a8SBill Fenner { TAG_STREETTALK_STDA, "iSTDA" }, 258abf25193SMax Laier { TAG_REQUESTED_IP, "iRequested-IP" }, 259abf25193SMax Laier { TAG_IP_LEASE, "lLease-Time" }, 260a1c2090eSBill Fenner { TAG_OPT_OVERLOAD, "$OO" }, 261a88113a8SBill Fenner { TAG_TFTP_SERVER, "aTFTP" }, 262a88113a8SBill Fenner { TAG_BOOTFILENAME, "aBF" }, 263abf25193SMax Laier { TAG_DHCP_MESSAGE, " DHCP-Message" }, 264abf25193SMax Laier { TAG_SERVER_ID, "iServer-ID" }, 265abf25193SMax Laier { TAG_PARM_REQUEST, "bParameter-Request" }, 266a88113a8SBill Fenner { TAG_MESSAGE, "aMSG" }, 267a88113a8SBill Fenner { TAG_MAX_MSG_SIZE, "sMSZ" }, 268a88113a8SBill Fenner { TAG_RENEWAL_TIME, "lRN" }, 269a88113a8SBill Fenner { TAG_REBIND_TIME, "lRB" }, 270abf25193SMax Laier { TAG_VENDOR_CLASS, "aVendor-Class" }, 271abf25193SMax Laier { TAG_CLIENT_ID, "$Client-ID" }, 272943ee2b1SBill Fenner /* RFC 2485 */ 273943ee2b1SBill Fenner { TAG_OPEN_GROUP_UAP, "aUAP" }, 274943ee2b1SBill Fenner /* RFC 2563 */ 275943ee2b1SBill Fenner { TAG_DISABLE_AUTOCONF, "BNOAUTO" }, 276943ee2b1SBill Fenner /* RFC 2610 */ 277943ee2b1SBill Fenner { TAG_SLP_DA, "bSLP-DA" }, /*"b" is a little wrong */ 278943ee2b1SBill Fenner { TAG_SLP_SCOPE, "bSLP-SCOPE" }, /*"b" is a little wrong */ 279943ee2b1SBill Fenner /* RFC 2937 */ 280943ee2b1SBill Fenner { TAG_NS_SEARCH, "sNSSEARCH" }, /* XXX 's' */ 281943ee2b1SBill Fenner /* RFC 3011 */ 282943ee2b1SBill Fenner { TAG_IP4_SUBNET_SELECT, "iSUBNET" }, 283abf25193SMax Laier /* RFC 3442 */ 284abf25193SMax Laier { TAG_CLASSLESS_STATIC_RT, "$Classless-Static-Route" }, 285abf25193SMax Laier { TAG_CLASSLESS_STA_RT_MS, "$Classless-Static-Route-Microsoft" }, 286cc391cceSBruce M Simpson /* http://www.iana.org/assignments/bootp-dhcp-extensions/index.htm */ 287943ee2b1SBill Fenner { TAG_USER_CLASS, "aCLASS" }, 288943ee2b1SBill Fenner { TAG_SLP_NAMING_AUTH, "aSLP-NA" }, 289a1c2090eSBill Fenner { TAG_CLIENT_FQDN, "$FQDN" }, 290abf25193SMax Laier { TAG_AGENT_CIRCUIT, "$Agent-Information" }, 291943ee2b1SBill Fenner { TAG_AGENT_REMOTE, "bARMT" }, 292943ee2b1SBill Fenner { TAG_AGENT_MASK, "bAMSK" }, 293943ee2b1SBill Fenner { TAG_TZ_STRING, "aTZSTR" }, 294943ee2b1SBill Fenner { TAG_FQDN_OPTION, "bFQDNS" }, /* XXX 'b' */ 295943ee2b1SBill Fenner { TAG_AUTH, "bAUTH" }, /* XXX 'b' */ 296943ee2b1SBill Fenner { TAG_VINES_SERVERS, "iVINES" }, 297943ee2b1SBill Fenner { TAG_SERVER_RANK, "sRANK" }, 298943ee2b1SBill Fenner { TAG_CLIENT_ARCH, "sARCH" }, 299943ee2b1SBill Fenner { TAG_CLIENT_NDI, "bNDI" }, /* XXX 'b' */ 300943ee2b1SBill Fenner { TAG_CLIENT_GUID, "bGUID" }, /* XXX 'b' */ 301943ee2b1SBill Fenner { TAG_LDAP_URL, "aLDAP" }, 302943ee2b1SBill Fenner { TAG_6OVER4, "i6o4" }, 303943ee2b1SBill Fenner { TAG_PRINTER_NAME, "aPRTR" }, 304943ee2b1SBill Fenner { TAG_MDHCP_SERVER, "bMDHCP" }, /* XXX 'b' */ 305943ee2b1SBill Fenner { TAG_IPX_COMPAT, "bIPX" }, /* XXX 'b' */ 306943ee2b1SBill Fenner { TAG_NETINFO_PARENT, "iNI" }, 307943ee2b1SBill Fenner { TAG_NETINFO_PARENT_TAG, "aNITAG" }, 308943ee2b1SBill Fenner { TAG_URL, "aURL" }, 309943ee2b1SBill Fenner { TAG_FAILOVER, "bFAIL" }, /* XXX 'b' */ 310943ee2b1SBill Fenner { 0, NULL } 311943ee2b1SBill Fenner }; 312943ee2b1SBill Fenner /* 2-byte extended tags */ 313943ee2b1SBill Fenner static struct tok xtag2str[] = { 3144edb46e9SPaul Traina { 0, NULL } 3154edb46e9SPaul Traina }; 3164edb46e9SPaul Traina 317a1c2090eSBill Fenner /* DHCP "options overload" types */ 318a1c2090eSBill Fenner static struct tok oo2str[] = { 319a1c2090eSBill Fenner { 1, "file" }, 320a1c2090eSBill Fenner { 2, "sname" }, 321a1c2090eSBill Fenner { 3, "file+sname" }, 322a1c2090eSBill Fenner { 0, NULL } 323a1c2090eSBill Fenner }; 324a1c2090eSBill Fenner 325a1c2090eSBill Fenner /* NETBIOS over TCP/IP node type options */ 326a1c2090eSBill Fenner static struct tok nbo2str[] = { 327a1c2090eSBill Fenner { 0x1, "b-node" }, 328a1c2090eSBill Fenner { 0x2, "p-node" }, 329a1c2090eSBill Fenner { 0x4, "m-node" }, 330a1c2090eSBill Fenner { 0x8, "h-node" }, 331a1c2090eSBill Fenner { 0, NULL } 332a1c2090eSBill Fenner }; 333a1c2090eSBill Fenner 334a1c2090eSBill Fenner /* ARP Hardware types, for Client-ID option */ 335a1c2090eSBill Fenner static struct tok arp2str[] = { 336a1c2090eSBill Fenner { 0x1, "ether" }, 337a1c2090eSBill Fenner { 0x6, "ieee802" }, 338a1c2090eSBill Fenner { 0x7, "arcnet" }, 339a1c2090eSBill Fenner { 0xf, "frelay" }, 340a1c2090eSBill Fenner { 0x17, "strip" }, 341a1c2090eSBill Fenner { 0x18, "ieee1394" }, 342a1c2090eSBill Fenner { 0, NULL } 343a1c2090eSBill Fenner }; 344a1c2090eSBill Fenner 345abf25193SMax Laier static struct tok dhcp_msg_values[] = { 346abf25193SMax Laier { DHCPDISCOVER, "Discover" }, 347abf25193SMax Laier { DHCPOFFER, "Offer" }, 348abf25193SMax Laier { DHCPREQUEST, "Request" }, 349abf25193SMax Laier { DHCPDECLINE, "Decline" }, 350abf25193SMax Laier { DHCPACK, "ACK" }, 351abf25193SMax Laier { DHCPNAK, "NACK" }, 352abf25193SMax Laier { DHCPRELEASE, "Release" }, 353abf25193SMax Laier { DHCPINFORM, "Inform" }, 354abf25193SMax Laier { 0, NULL } 355abf25193SMax Laier }; 356abf25193SMax Laier 357abf25193SMax Laier #define AGENT_SUBOPTION_CIRCUIT_ID 1 358abf25193SMax Laier static struct tok agent_suboption_values[] = { 359abf25193SMax Laier { AGENT_SUBOPTION_CIRCUIT_ID, "Circuit-ID" }, 360abf25193SMax Laier { 0, NULL } 361abf25193SMax Laier }; 362abf25193SMax Laier 363abf25193SMax Laier 3644edb46e9SPaul Traina static void 365a1c2090eSBill Fenner rfc1048_print(register const u_char *bp) 3664edb46e9SPaul Traina { 3670e0def19SBill Fenner register u_int16_t tag; 368abf25193SMax Laier register u_int len; 3694edb46e9SPaul Traina register const char *cp; 3704edb46e9SPaul Traina register char c; 371abf25193SMax Laier int first, idx; 3724edb46e9SPaul Traina u_int32_t ul; 3730e0def19SBill Fenner u_int16_t us; 374abf25193SMax Laier u_int8_t uc, subopt, suboptlen; 3754edb46e9SPaul Traina 376abf25193SMax Laier printf("\n\t Vendor-rfc1048 Extensions"); 3774edb46e9SPaul Traina 3784edb46e9SPaul Traina /* Step over magic cookie */ 379abf25193SMax Laier printf("\n\t Magic Cookie 0x%08x", EXTRACT_32BITS(bp)); 3804edb46e9SPaul Traina bp += sizeof(int32_t); 3814edb46e9SPaul Traina 3824edb46e9SPaul Traina /* Loop while we there is a tag left in the buffer */ 383abf25193SMax Laier while (TTEST2(*bp, 1)) { 3844edb46e9SPaul Traina tag = *bp++; 385abf25193SMax Laier if (tag == TAG_PAD && vflag < 3) 3864edb46e9SPaul Traina continue; 387abf25193SMax Laier if (tag == TAG_END && vflag < 3) 3884edb46e9SPaul Traina return; 389943ee2b1SBill Fenner if (tag == TAG_EXTENDED_OPTION) { 390943ee2b1SBill Fenner TCHECK2(*(bp + 1), 2); 391943ee2b1SBill Fenner tag = EXTRACT_16BITS(bp + 1); 392943ee2b1SBill Fenner /* XXX we don't know yet if the IANA will 393943ee2b1SBill Fenner * preclude overlap of 1-byte and 2-byte spaces. 394943ee2b1SBill Fenner * If not, we need to offset tag after this step. 395943ee2b1SBill Fenner */ 3960e0def19SBill Fenner cp = tok2str(xtag2str, "?xT%u", tag); 397943ee2b1SBill Fenner } else 3980e0def19SBill Fenner cp = tok2str(tag2str, "?T%u", tag); 3994edb46e9SPaul Traina c = *cp++; 4004edb46e9SPaul Traina 401abf25193SMax Laier if (tag == TAG_PAD || tag == TAG_END) 402abf25193SMax Laier len = 0; 403abf25193SMax Laier else { 4044edb46e9SPaul Traina /* Get the length; check for truncation */ 405abf25193SMax Laier TCHECK2(*bp, 1); 4064edb46e9SPaul Traina len = *bp++; 407abf25193SMax Laier } 408abf25193SMax Laier 409abf25193SMax Laier printf("\n\t %s Option %u, length %u%s", cp, tag, len, 410abf25193SMax Laier len > 0 ? ": " : ""); 411abf25193SMax Laier 412abf25193SMax Laier if (tag == TAG_PAD && vflag > 2) { 413abf25193SMax Laier u_int ntag = 1; 414abf25193SMax Laier while (TTEST2(*bp, 1) && *bp == TAG_PAD) { 415abf25193SMax Laier bp++; 416abf25193SMax Laier ntag++; 417abf25193SMax Laier } 418abf25193SMax Laier if (ntag > 1) 419abf25193SMax Laier printf(", occurs %u", ntag); 420abf25193SMax Laier } 421abf25193SMax Laier 422abf25193SMax Laier if (!TTEST2(*bp, len)) { 423abf25193SMax Laier printf("[|rfc1048 %u]", len); 4244edb46e9SPaul Traina return; 4254edb46e9SPaul Traina } 4264edb46e9SPaul Traina 427a88113a8SBill Fenner if (tag == TAG_DHCP_MESSAGE && len == 1) { 4280e0def19SBill Fenner uc = *bp++; 429abf25193SMax Laier printf("%s", tok2str(dhcp_msg_values, "Unknown (%u)", uc)); 430a88113a8SBill Fenner continue; 431a88113a8SBill Fenner } 432a88113a8SBill Fenner 433a88113a8SBill Fenner if (tag == TAG_PARM_REQUEST) { 434abf25193SMax Laier idx = 0; 435a88113a8SBill Fenner while (len-- > 0) { 4360e0def19SBill Fenner uc = *bp++; 437abf25193SMax Laier cp = tok2str(tag2str, "?Option %u", uc); 438abf25193SMax Laier if (idx % 4 == 0) 439abf25193SMax Laier printf("\n\t "); 440abf25193SMax Laier else 441abf25193SMax Laier printf(", "); 442943ee2b1SBill Fenner printf("%s", cp + 1); 443abf25193SMax Laier idx++; 444943ee2b1SBill Fenner } 445943ee2b1SBill Fenner continue; 446943ee2b1SBill Fenner } 447abf25193SMax Laier 448943ee2b1SBill Fenner if (tag == TAG_EXTENDED_REQUEST) { 449943ee2b1SBill Fenner first = 1; 450943ee2b1SBill Fenner while (len > 1) { 451943ee2b1SBill Fenner len -= 2; 4520e0def19SBill Fenner us = EXTRACT_16BITS(bp); 453943ee2b1SBill Fenner bp += 2; 4540e0def19SBill Fenner cp = tok2str(xtag2str, "?xT%u", us); 455a88113a8SBill Fenner if (!first) 456a88113a8SBill Fenner putchar('+'); 457a88113a8SBill Fenner printf("%s", cp + 1); 458a88113a8SBill Fenner first = 0; 459a88113a8SBill Fenner } 460a88113a8SBill Fenner continue; 461a88113a8SBill Fenner } 462a88113a8SBill Fenner 4634edb46e9SPaul Traina /* Print data */ 4644edb46e9SPaul Traina if (c == '?') { 4654edb46e9SPaul Traina /* Base default formats for unknown tags on data size */ 466abf25193SMax Laier if (len & 1) 4674edb46e9SPaul Traina c = 'b'; 468abf25193SMax Laier else if (len & 2) 4694edb46e9SPaul Traina c = 's'; 4704edb46e9SPaul Traina else 4714edb46e9SPaul Traina c = 'l'; 4724edb46e9SPaul Traina } 4734edb46e9SPaul Traina first = 1; 4744edb46e9SPaul Traina switch (c) { 4754edb46e9SPaul Traina 4764edb46e9SPaul Traina case 'a': 4774edb46e9SPaul Traina /* ascii strings */ 4784edb46e9SPaul Traina putchar('"'); 479abf25193SMax Laier if (fn_printn(bp, len, snapend)) { 48029292c17SSam Leffler putchar('"'); 48129292c17SSam Leffler goto trunc; 48229292c17SSam Leffler } 4834edb46e9SPaul Traina putchar('"'); 484abf25193SMax Laier bp += len; 485abf25193SMax Laier len = 0; 4864edb46e9SPaul Traina break; 4874edb46e9SPaul Traina 4884edb46e9SPaul Traina case 'i': 4894edb46e9SPaul Traina case 'l': 490943ee2b1SBill Fenner case 'L': 4914edb46e9SPaul Traina /* ip addresses/32-bit words */ 492abf25193SMax Laier while (len >= sizeof(ul)) { 4934edb46e9SPaul Traina if (!first) 4944edb46e9SPaul Traina putchar(','); 495943ee2b1SBill Fenner ul = EXTRACT_32BITS(bp); 496943ee2b1SBill Fenner if (c == 'i') { 497943ee2b1SBill Fenner ul = htonl(ul); 4984edb46e9SPaul Traina printf("%s", ipaddr_string(&ul)); 499943ee2b1SBill Fenner } else if (c == 'L') 500943ee2b1SBill Fenner printf("%d", ul); 5014edb46e9SPaul Traina else 5024edb46e9SPaul Traina printf("%u", ul); 5034edb46e9SPaul Traina bp += sizeof(ul); 504abf25193SMax Laier len -= sizeof(ul); 5054edb46e9SPaul Traina first = 0; 5064edb46e9SPaul Traina } 5074edb46e9SPaul Traina break; 5084edb46e9SPaul Traina 509a88113a8SBill Fenner case 'p': 510a88113a8SBill Fenner /* IP address pairs */ 511abf25193SMax Laier while (len >= 2*sizeof(ul)) { 512a88113a8SBill Fenner if (!first) 513a88113a8SBill Fenner putchar(','); 514a1c2090eSBill Fenner memcpy((char *)&ul, (const char *)bp, sizeof(ul)); 515a88113a8SBill Fenner printf("(%s:", ipaddr_string(&ul)); 516a88113a8SBill Fenner bp += sizeof(ul); 517a1c2090eSBill Fenner memcpy((char *)&ul, (const char *)bp, sizeof(ul)); 518a88113a8SBill Fenner printf("%s)", ipaddr_string(&ul)); 519a88113a8SBill Fenner bp += sizeof(ul); 520abf25193SMax Laier len -= 2*sizeof(ul); 521a88113a8SBill Fenner first = 0; 522a88113a8SBill Fenner } 523a88113a8SBill Fenner break; 524a88113a8SBill Fenner 5254edb46e9SPaul Traina case 's': 5264edb46e9SPaul Traina /* shorts */ 527abf25193SMax Laier while (len >= sizeof(us)) { 5284edb46e9SPaul Traina if (!first) 5294edb46e9SPaul Traina putchar(','); 530943ee2b1SBill Fenner us = EXTRACT_16BITS(bp); 5310e0def19SBill Fenner printf("%u", us); 5324edb46e9SPaul Traina bp += sizeof(us); 533abf25193SMax Laier len -= sizeof(us); 5344edb46e9SPaul Traina first = 0; 5354edb46e9SPaul Traina } 5364edb46e9SPaul Traina break; 5374edb46e9SPaul Traina 538a88113a8SBill Fenner case 'B': 539a88113a8SBill Fenner /* boolean */ 540abf25193SMax Laier while (len > 0) { 541a88113a8SBill Fenner if (!first) 542a88113a8SBill Fenner putchar(','); 543a88113a8SBill Fenner switch (*bp) { 544a88113a8SBill Fenner case 0: 545a88113a8SBill Fenner putchar('N'); 546a88113a8SBill Fenner break; 547a88113a8SBill Fenner case 1: 548a88113a8SBill Fenner putchar('Y'); 549a88113a8SBill Fenner break; 550a88113a8SBill Fenner default: 5510e0def19SBill Fenner printf("%u?", *bp); 552a88113a8SBill Fenner break; 553a88113a8SBill Fenner } 554a88113a8SBill Fenner ++bp; 555abf25193SMax Laier --len; 556a88113a8SBill Fenner first = 0; 557a88113a8SBill Fenner } 558a88113a8SBill Fenner break; 559a88113a8SBill Fenner 5604edb46e9SPaul Traina case 'b': 561943ee2b1SBill Fenner case 'x': 5624edb46e9SPaul Traina default: 5634edb46e9SPaul Traina /* Bytes */ 564abf25193SMax Laier while (len > 0) { 5654edb46e9SPaul Traina if (!first) 566943ee2b1SBill Fenner putchar(c == 'x' ? ':' : '.'); 567a1c2090eSBill Fenner if (c == 'x') 568a1c2090eSBill Fenner printf("%02x", *bp); 569a1c2090eSBill Fenner else 5700e0def19SBill Fenner printf("%u", *bp); 5714edb46e9SPaul Traina ++bp; 572abf25193SMax Laier --len; 5734edb46e9SPaul Traina first = 0; 5744edb46e9SPaul Traina } 5754edb46e9SPaul Traina break; 576a1c2090eSBill Fenner 577a1c2090eSBill Fenner case '$': 578a1c2090eSBill Fenner /* Guys we can't handle with one of the usual cases */ 579a1c2090eSBill Fenner switch (tag) { 580a1c2090eSBill Fenner 581a1c2090eSBill Fenner case TAG_NETBIOS_NODE: 582abf25193SMax Laier /* this option should be at least 1 byte long */ 583abf25193SMax Laier if (len < 1) { 584abf25193SMax Laier printf("ERROR: option %u len %u < 1 bytes", 585abf25193SMax Laier TAG_NETBIOS_NODE, len); 586abf25193SMax Laier bp += len; 587abf25193SMax Laier len = 0; 588abf25193SMax Laier break; 589abf25193SMax Laier } 590a1c2090eSBill Fenner tag = *bp++; 591abf25193SMax Laier --len; 592a1c2090eSBill Fenner fputs(tok2str(nbo2str, NULL, tag), stdout); 593a1c2090eSBill Fenner break; 594a1c2090eSBill Fenner 595a1c2090eSBill Fenner case TAG_OPT_OVERLOAD: 596abf25193SMax Laier /* this option should be at least 1 byte long */ 597abf25193SMax Laier if (len < 1) { 598abf25193SMax Laier printf("ERROR: option %u len %u < 1 bytes", 599abf25193SMax Laier TAG_OPT_OVERLOAD, len); 600abf25193SMax Laier bp += len; 601abf25193SMax Laier len = 0; 602abf25193SMax Laier break; 603abf25193SMax Laier } 604a1c2090eSBill Fenner tag = *bp++; 605abf25193SMax Laier --len; 606a1c2090eSBill Fenner fputs(tok2str(oo2str, NULL, tag), stdout); 607a1c2090eSBill Fenner break; 608a1c2090eSBill Fenner 609a1c2090eSBill Fenner case TAG_CLIENT_FQDN: 610abf25193SMax Laier /* this option should be at least 3 bytes long */ 611abf25193SMax Laier if (len < 3) { 612abf25193SMax Laier printf("ERROR: option %u len %u < 3 bytes", 613abf25193SMax Laier TAG_CLIENT_FQDN, len); 614abf25193SMax Laier bp += len; 615abf25193SMax Laier len = 0; 616cc391cceSBruce M Simpson break; 61729292c17SSam Leffler } 618a1c2090eSBill Fenner if (*bp) 619abf25193SMax Laier printf("[%s] ", client_fqdn_flags(*bp)); 620abf25193SMax Laier bp++; 621abf25193SMax Laier if (*bp || *(bp+1)) 622abf25193SMax Laier printf("%u/%u ", *bp, *(bp+1)); 623a1c2090eSBill Fenner bp += 2; 624a1c2090eSBill Fenner putchar('"'); 625abf25193SMax Laier if (fn_printn(bp, len - 3, snapend)) { 62629292c17SSam Leffler putchar('"'); 62729292c17SSam Leffler goto trunc; 62829292c17SSam Leffler } 629a1c2090eSBill Fenner putchar('"'); 630abf25193SMax Laier bp += len - 3; 631abf25193SMax Laier len = 0; 632a1c2090eSBill Fenner break; 633a1c2090eSBill Fenner 634a1c2090eSBill Fenner case TAG_CLIENT_ID: 635abf25193SMax Laier { int type; 636abf25193SMax Laier 637abf25193SMax Laier /* this option should be at least 1 byte long */ 638abf25193SMax Laier if (len < 1) { 639abf25193SMax Laier printf("ERROR: option %u len %u < 1 bytes", 640abf25193SMax Laier TAG_CLIENT_ID, len); 641abf25193SMax Laier bp += len; 642abf25193SMax Laier len = 0; 643abf25193SMax Laier break; 644abf25193SMax Laier } 645abf25193SMax Laier type = *bp++; 646abf25193SMax Laier len--; 647a1c2090eSBill Fenner if (type == 0) { 648a1c2090eSBill Fenner putchar('"'); 649abf25193SMax Laier if (fn_printn(bp, len, snapend)) { 65029292c17SSam Leffler putchar('"'); 65129292c17SSam Leffler goto trunc; 65229292c17SSam Leffler } 653a1c2090eSBill Fenner putchar('"'); 654abf25193SMax Laier bp += len; 655abf25193SMax Laier len = 0; 656a1c2090eSBill Fenner break; 657a1c2090eSBill Fenner } else { 658abf25193SMax Laier printf("%s ", tok2str(arp2str, "hardware-type %u,", type)); 659abf25193SMax Laier while (len > 0) { 660a1c2090eSBill Fenner if (!first) 661a1c2090eSBill Fenner putchar(':'); 662a1c2090eSBill Fenner printf("%02x", *bp); 663a1c2090eSBill Fenner ++bp; 664abf25193SMax Laier --len; 665a1c2090eSBill Fenner first = 0; 666a1c2090eSBill Fenner } 667abf25193SMax Laier } 668a1c2090eSBill Fenner break; 669a1c2090eSBill Fenner } 670a1c2090eSBill Fenner 671abf25193SMax Laier case TAG_AGENT_CIRCUIT: 672abf25193SMax Laier while (len >= 2) { 673abf25193SMax Laier subopt = *bp++; 674abf25193SMax Laier suboptlen = *bp++; 675abf25193SMax Laier len -= 2; 676abf25193SMax Laier if (suboptlen > len) { 677abf25193SMax Laier printf("\n\t %s SubOption %u, length %u: length goes past end of option", 678abf25193SMax Laier tok2str(agent_suboption_values, "Unknown", subopt), 679abf25193SMax Laier subopt, 680abf25193SMax Laier suboptlen); 681abf25193SMax Laier bp += len; 682abf25193SMax Laier len = 0; 683abf25193SMax Laier break; 684abf25193SMax Laier } 685abf25193SMax Laier printf("\n\t %s SubOption %u, length %u: ", 686abf25193SMax Laier tok2str(agent_suboption_values, "Unknown", subopt), 687abf25193SMax Laier subopt, 688abf25193SMax Laier suboptlen); 689abf25193SMax Laier switch (subopt) { 690abf25193SMax Laier 691abf25193SMax Laier case AGENT_SUBOPTION_CIRCUIT_ID: 692abf25193SMax Laier fn_printn(bp, suboptlen, NULL); 693abf25193SMax Laier break; 694abf25193SMax Laier 695abf25193SMax Laier default: 696abf25193SMax Laier print_unknown_data(bp, "\n\t\t", suboptlen); 697abf25193SMax Laier } 698abf25193SMax Laier 699abf25193SMax Laier len -= suboptlen; 700abf25193SMax Laier bp += suboptlen; 701abf25193SMax Laier } 702abf25193SMax Laier break; 703abf25193SMax Laier 704abf25193SMax Laier case TAG_CLASSLESS_STATIC_RT: 705abf25193SMax Laier case TAG_CLASSLESS_STA_RT_MS: 706abf25193SMax Laier { 707abf25193SMax Laier u_int mask_width, significant_octets, i; 708abf25193SMax Laier 709abf25193SMax Laier /* this option should be at least 5 bytes long */ 710abf25193SMax Laier if (len < 5) { 711abf25193SMax Laier printf("ERROR: option %u len %u < 5 bytes", 712abf25193SMax Laier TAG_CLASSLESS_STATIC_RT, len); 713abf25193SMax Laier bp += len; 714abf25193SMax Laier len = 0; 715abf25193SMax Laier break; 716abf25193SMax Laier } 717abf25193SMax Laier while (len > 0) { 718abf25193SMax Laier if (!first) 719abf25193SMax Laier putchar(','); 720abf25193SMax Laier mask_width = *bp++; 721abf25193SMax Laier len--; 722abf25193SMax Laier /* mask_width <= 32 */ 723abf25193SMax Laier if (mask_width > 32) { 724abf25193SMax Laier printf("[ERROR: Mask width (%d) > 32]", mask_width); 725abf25193SMax Laier bp += len; 726abf25193SMax Laier len = 0; 727abf25193SMax Laier break; 728abf25193SMax Laier } 729abf25193SMax Laier significant_octets = (mask_width + 7) / 8; 730abf25193SMax Laier /* significant octets + router(4) */ 731abf25193SMax Laier if (len < significant_octets + 4) { 732abf25193SMax Laier printf("[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4); 733abf25193SMax Laier bp += len; 734abf25193SMax Laier len = 0; 735abf25193SMax Laier break; 736abf25193SMax Laier } 737abf25193SMax Laier putchar('('); 738abf25193SMax Laier if (mask_width == 0) 739abf25193SMax Laier printf("default"); 740abf25193SMax Laier else { 741abf25193SMax Laier for (i = 0; i < significant_octets ; i++) { 742abf25193SMax Laier if (i > 0) 743abf25193SMax Laier putchar('.'); 744abf25193SMax Laier printf("%d", *bp++); 745abf25193SMax Laier } 746abf25193SMax Laier for (i = significant_octets ; i < 4 ; i++) 747abf25193SMax Laier printf(".0"); 748abf25193SMax Laier printf("/%d", mask_width); 749abf25193SMax Laier } 750abf25193SMax Laier memcpy((char *)&ul, (const char *)bp, sizeof(ul)); 751abf25193SMax Laier printf(":%s)", ipaddr_string(&ul)); 752abf25193SMax Laier bp += sizeof(ul); 753abf25193SMax Laier len -= (significant_octets + 4); 754abf25193SMax Laier first = 0; 755abf25193SMax Laier } 756abf25193SMax Laier } 757abf25193SMax Laier break; 758abf25193SMax Laier 759a1c2090eSBill Fenner default: 7600e0def19SBill Fenner printf("[unknown special tag %u, size %u]", 761abf25193SMax Laier tag, len); 762abf25193SMax Laier bp += len; 763abf25193SMax Laier len = 0; 764a1c2090eSBill Fenner break; 765a1c2090eSBill Fenner } 766a1c2090eSBill Fenner break; 7674edb46e9SPaul Traina } 7684edb46e9SPaul Traina /* Data left over? */ 769abf25193SMax Laier if (len) { 770abf25193SMax Laier printf("\n\t trailing data length %u", len); 771abf25193SMax Laier bp += len; 772cc391cceSBruce M Simpson } 7734edb46e9SPaul Traina } 774943ee2b1SBill Fenner return; 775943ee2b1SBill Fenner trunc: 776943ee2b1SBill Fenner printf("|[rfc1048]"); 7774edb46e9SPaul Traina } 7784edb46e9SPaul Traina 7794edb46e9SPaul Traina static void 780a1c2090eSBill Fenner cmu_print(register const u_char *bp) 7814edb46e9SPaul Traina { 7824edb46e9SPaul Traina register const struct cmu_vend *cmu; 7834edb46e9SPaul Traina 7844edb46e9SPaul Traina #define PRINTCMUADDR(m, s) { TCHECK(cmu->m); \ 7854edb46e9SPaul Traina if (cmu->m.s_addr != 0) \ 786a1c2090eSBill Fenner printf(" %s:%s", s, ipaddr_string(&cmu->m.s_addr)); } 7874edb46e9SPaul Traina 7884edb46e9SPaul Traina printf(" vend-cmu"); 789a1c2090eSBill Fenner cmu = (const struct cmu_vend *)bp; 7904edb46e9SPaul Traina 7914edb46e9SPaul Traina /* Only print if there are unknown bits */ 7924edb46e9SPaul Traina TCHECK(cmu->v_flags); 7934edb46e9SPaul Traina if ((cmu->v_flags & ~(VF_SMASK)) != 0) 7944edb46e9SPaul Traina printf(" F:0x%x", cmu->v_flags); 7954edb46e9SPaul Traina PRINTCMUADDR(v_dgate, "DG"); 7964edb46e9SPaul Traina PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*"); 7974edb46e9SPaul Traina PRINTCMUADDR(v_dns1, "NS1"); 7984edb46e9SPaul Traina PRINTCMUADDR(v_dns2, "NS2"); 7994edb46e9SPaul Traina PRINTCMUADDR(v_ins1, "IEN1"); 8004edb46e9SPaul Traina PRINTCMUADDR(v_ins2, "IEN2"); 8014edb46e9SPaul Traina PRINTCMUADDR(v_ts1, "TS1"); 8024edb46e9SPaul Traina PRINTCMUADDR(v_ts2, "TS2"); 8034edb46e9SPaul Traina return; 8044edb46e9SPaul Traina 8054edb46e9SPaul Traina trunc: 8064edb46e9SPaul Traina fputs(tstr, stdout); 8074edb46e9SPaul Traina #undef PRINTCMUADDR 8084edb46e9SPaul Traina } 809abf25193SMax Laier 810abf25193SMax Laier static char * 811abf25193SMax Laier client_fqdn_flags(u_int flags) 812abf25193SMax Laier { 813abf25193SMax Laier static char buf[8+1]; 814abf25193SMax Laier int i = 0; 815abf25193SMax Laier 816abf25193SMax Laier if (flags & CLIENT_FQDN_FLAGS_S) 817abf25193SMax Laier buf[i++] = 'S'; 818abf25193SMax Laier if (flags & CLIENT_FQDN_FLAGS_O) 819abf25193SMax Laier buf[i++] = 'O'; 820abf25193SMax Laier if (flags & CLIENT_FQDN_FLAGS_E) 821abf25193SMax Laier buf[i++] = 'E'; 822abf25193SMax Laier if (flags & CLIENT_FQDN_FLAGS_N) 823abf25193SMax Laier buf[i++] = 'N'; 824abf25193SMax Laier buf[i] = '\0'; 825abf25193SMax Laier 826abf25193SMax Laier return buf; 827abf25193SMax Laier } 828