117680Spst/* 239300Sfenner * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2017680Spst * 2117680Spst * Format and print bootp packets. 2256896Sfenner * 2356896Sfenner * $FreeBSD: releng/11.0/contrib/tcpdump/print-bootp.c 285275 2015-07-08 16:19:32Z pkelsey $ 2417680Spst */ 2517680Spst 26276788Sdelphij#define NETDISSECT_REWORKED 2756896Sfenner#ifdef HAVE_CONFIG_H 2856896Sfenner#include "config.h" 2956896Sfenner#endif 3056896Sfenner 31127675Sbms#include <tcpdump-stdinc.h> 3217680Spst 3317680Spst#include <string.h> 3417680Spst 3517680Spst#include "interface.h" 3617680Spst#include "addrtoname.h" 3775118Sfenner#include "extract.h" 3817680Spst 39276788Sdelphijstatic const char tstr[] = " [|bootp]"; 40276788Sdelphij 41285275Spkelsey/* 42285275Spkelsey * Bootstrap Protocol (BOOTP). RFC951 and RFC1048. 43285275Spkelsey * 44285275Spkelsey * This file specifies the "implementation-independent" BOOTP protocol 45285275Spkelsey * information which is common to both client and server. 46285275Spkelsey * 47285275Spkelsey * Copyright 1988 by Carnegie Mellon. 48285275Spkelsey * 49285275Spkelsey * Permission to use, copy, modify, and distribute this program for any 50285275Spkelsey * purpose and without fee is hereby granted, provided that this copyright 51285275Spkelsey * and permission notice appear on all copies and supporting documentation, 52285275Spkelsey * the name of Carnegie Mellon not be used in advertising or publicity 53285275Spkelsey * pertaining to distribution of the program without specific prior 54285275Spkelsey * permission, and notice be given in supporting documentation that copying 55285275Spkelsey * and distribution is by permission of Carnegie Mellon and Stanford 56285275Spkelsey * University. Carnegie Mellon makes no representations about the 57285275Spkelsey * suitability of this software for any purpose. It is provided "as is" 58285275Spkelsey * without express or implied warranty. 59285275Spkelsey */ 60285275Spkelsey 61285275Spkelseystruct bootp { 62285275Spkelsey uint8_t bp_op; /* packet opcode type */ 63285275Spkelsey uint8_t bp_htype; /* hardware addr type */ 64285275Spkelsey uint8_t bp_hlen; /* hardware addr length */ 65285275Spkelsey uint8_t bp_hops; /* gateway hops */ 66285275Spkelsey uint32_t bp_xid; /* transaction ID */ 67285275Spkelsey uint16_t bp_secs; /* seconds since boot began */ 68285275Spkelsey uint16_t bp_flags; /* flags - see bootp_flag_values[] 69285275Spkelsey in print-bootp.c */ 70285275Spkelsey struct in_addr bp_ciaddr; /* client IP address */ 71285275Spkelsey struct in_addr bp_yiaddr; /* 'your' IP address */ 72285275Spkelsey struct in_addr bp_siaddr; /* server IP address */ 73285275Spkelsey struct in_addr bp_giaddr; /* gateway IP address */ 74285275Spkelsey uint8_t bp_chaddr[16]; /* client hardware address */ 75285275Spkelsey uint8_t bp_sname[64]; /* server host name */ 76285275Spkelsey uint8_t bp_file[128]; /* boot file name */ 77285275Spkelsey uint8_t bp_vend[64]; /* vendor-specific area */ 78285275Spkelsey} UNALIGNED; 79285275Spkelsey 80285275Spkelsey#define BOOTPREPLY 2 81285275Spkelsey#define BOOTPREQUEST 1 82285275Spkelsey 83285275Spkelsey/* 84285275Spkelsey * Vendor magic cookie (v_magic) for CMU 85285275Spkelsey */ 86285275Spkelsey#define VM_CMU "CMU" 87285275Spkelsey 88285275Spkelsey/* 89285275Spkelsey * Vendor magic cookie (v_magic) for RFC1048 90285275Spkelsey */ 91285275Spkelsey#define VM_RFC1048 { 99, 130, 83, 99 } 92285275Spkelsey 93285275Spkelsey/* 94285275Spkelsey * RFC1048 tag values used to specify what information is being supplied in 95285275Spkelsey * the vendor field of the packet. 96285275Spkelsey */ 97285275Spkelsey 98285275Spkelsey#define TAG_PAD ((uint8_t) 0) 99285275Spkelsey#define TAG_SUBNET_MASK ((uint8_t) 1) 100285275Spkelsey#define TAG_TIME_OFFSET ((uint8_t) 2) 101285275Spkelsey#define TAG_GATEWAY ((uint8_t) 3) 102285275Spkelsey#define TAG_TIME_SERVER ((uint8_t) 4) 103285275Spkelsey#define TAG_NAME_SERVER ((uint8_t) 5) 104285275Spkelsey#define TAG_DOMAIN_SERVER ((uint8_t) 6) 105285275Spkelsey#define TAG_LOG_SERVER ((uint8_t) 7) 106285275Spkelsey#define TAG_COOKIE_SERVER ((uint8_t) 8) 107285275Spkelsey#define TAG_LPR_SERVER ((uint8_t) 9) 108285275Spkelsey#define TAG_IMPRESS_SERVER ((uint8_t) 10) 109285275Spkelsey#define TAG_RLP_SERVER ((uint8_t) 11) 110285275Spkelsey#define TAG_HOSTNAME ((uint8_t) 12) 111285275Spkelsey#define TAG_BOOTSIZE ((uint8_t) 13) 112285275Spkelsey#define TAG_END ((uint8_t) 255) 113285275Spkelsey/* RFC1497 tags */ 114285275Spkelsey#define TAG_DUMPPATH ((uint8_t) 14) 115285275Spkelsey#define TAG_DOMAINNAME ((uint8_t) 15) 116285275Spkelsey#define TAG_SWAP_SERVER ((uint8_t) 16) 117285275Spkelsey#define TAG_ROOTPATH ((uint8_t) 17) 118285275Spkelsey#define TAG_EXTPATH ((uint8_t) 18) 119285275Spkelsey/* RFC2132 */ 120285275Spkelsey#define TAG_IP_FORWARD ((uint8_t) 19) 121285275Spkelsey#define TAG_NL_SRCRT ((uint8_t) 20) 122285275Spkelsey#define TAG_PFILTERS ((uint8_t) 21) 123285275Spkelsey#define TAG_REASS_SIZE ((uint8_t) 22) 124285275Spkelsey#define TAG_DEF_TTL ((uint8_t) 23) 125285275Spkelsey#define TAG_MTU_TIMEOUT ((uint8_t) 24) 126285275Spkelsey#define TAG_MTU_TABLE ((uint8_t) 25) 127285275Spkelsey#define TAG_INT_MTU ((uint8_t) 26) 128285275Spkelsey#define TAG_LOCAL_SUBNETS ((uint8_t) 27) 129285275Spkelsey#define TAG_BROAD_ADDR ((uint8_t) 28) 130285275Spkelsey#define TAG_DO_MASK_DISC ((uint8_t) 29) 131285275Spkelsey#define TAG_SUPPLY_MASK ((uint8_t) 30) 132285275Spkelsey#define TAG_DO_RDISC ((uint8_t) 31) 133285275Spkelsey#define TAG_RTR_SOL_ADDR ((uint8_t) 32) 134285275Spkelsey#define TAG_STATIC_ROUTE ((uint8_t) 33) 135285275Spkelsey#define TAG_USE_TRAILERS ((uint8_t) 34) 136285275Spkelsey#define TAG_ARP_TIMEOUT ((uint8_t) 35) 137285275Spkelsey#define TAG_ETH_ENCAP ((uint8_t) 36) 138285275Spkelsey#define TAG_TCP_TTL ((uint8_t) 37) 139285275Spkelsey#define TAG_TCP_KEEPALIVE ((uint8_t) 38) 140285275Spkelsey#define TAG_KEEPALIVE_GO ((uint8_t) 39) 141285275Spkelsey#define TAG_NIS_DOMAIN ((uint8_t) 40) 142285275Spkelsey#define TAG_NIS_SERVERS ((uint8_t) 41) 143285275Spkelsey#define TAG_NTP_SERVERS ((uint8_t) 42) 144285275Spkelsey#define TAG_VENDOR_OPTS ((uint8_t) 43) 145285275Spkelsey#define TAG_NETBIOS_NS ((uint8_t) 44) 146285275Spkelsey#define TAG_NETBIOS_DDS ((uint8_t) 45) 147285275Spkelsey#define TAG_NETBIOS_NODE ((uint8_t) 46) 148285275Spkelsey#define TAG_NETBIOS_SCOPE ((uint8_t) 47) 149285275Spkelsey#define TAG_XWIN_FS ((uint8_t) 48) 150285275Spkelsey#define TAG_XWIN_DM ((uint8_t) 49) 151285275Spkelsey#define TAG_NIS_P_DOMAIN ((uint8_t) 64) 152285275Spkelsey#define TAG_NIS_P_SERVERS ((uint8_t) 65) 153285275Spkelsey#define TAG_MOBILE_HOME ((uint8_t) 68) 154285275Spkelsey#define TAG_SMPT_SERVER ((uint8_t) 69) 155285275Spkelsey#define TAG_POP3_SERVER ((uint8_t) 70) 156285275Spkelsey#define TAG_NNTP_SERVER ((uint8_t) 71) 157285275Spkelsey#define TAG_WWW_SERVER ((uint8_t) 72) 158285275Spkelsey#define TAG_FINGER_SERVER ((uint8_t) 73) 159285275Spkelsey#define TAG_IRC_SERVER ((uint8_t) 74) 160285275Spkelsey#define TAG_STREETTALK_SRVR ((uint8_t) 75) 161285275Spkelsey#define TAG_STREETTALK_STDA ((uint8_t) 76) 162285275Spkelsey/* DHCP options */ 163285275Spkelsey#define TAG_REQUESTED_IP ((uint8_t) 50) 164285275Spkelsey#define TAG_IP_LEASE ((uint8_t) 51) 165285275Spkelsey#define TAG_OPT_OVERLOAD ((uint8_t) 52) 166285275Spkelsey#define TAG_TFTP_SERVER ((uint8_t) 66) 167285275Spkelsey#define TAG_BOOTFILENAME ((uint8_t) 67) 168285275Spkelsey#define TAG_DHCP_MESSAGE ((uint8_t) 53) 169285275Spkelsey#define TAG_SERVER_ID ((uint8_t) 54) 170285275Spkelsey#define TAG_PARM_REQUEST ((uint8_t) 55) 171285275Spkelsey#define TAG_MESSAGE ((uint8_t) 56) 172285275Spkelsey#define TAG_MAX_MSG_SIZE ((uint8_t) 57) 173285275Spkelsey#define TAG_RENEWAL_TIME ((uint8_t) 58) 174285275Spkelsey#define TAG_REBIND_TIME ((uint8_t) 59) 175285275Spkelsey#define TAG_VENDOR_CLASS ((uint8_t) 60) 176285275Spkelsey#define TAG_CLIENT_ID ((uint8_t) 61) 177285275Spkelsey/* RFC 2241 */ 178285275Spkelsey#define TAG_NDS_SERVERS ((uint8_t) 85) 179285275Spkelsey#define TAG_NDS_TREE_NAME ((uint8_t) 86) 180285275Spkelsey#define TAG_NDS_CONTEXT ((uint8_t) 87) 181285275Spkelsey/* RFC 2242 */ 182285275Spkelsey#define TAG_NDS_IPDOMAIN ((uint8_t) 62) 183285275Spkelsey#define TAG_NDS_IPINFO ((uint8_t) 63) 184285275Spkelsey/* RFC 2485 */ 185285275Spkelsey#define TAG_OPEN_GROUP_UAP ((uint8_t) 98) 186285275Spkelsey/* RFC 2563 */ 187285275Spkelsey#define TAG_DISABLE_AUTOCONF ((uint8_t) 116) 188285275Spkelsey/* RFC 2610 */ 189285275Spkelsey#define TAG_SLP_DA ((uint8_t) 78) 190285275Spkelsey#define TAG_SLP_SCOPE ((uint8_t) 79) 191285275Spkelsey/* RFC 2937 */ 192285275Spkelsey#define TAG_NS_SEARCH ((uint8_t) 117) 193285275Spkelsey/* RFC 3004 - The User Class Option for DHCP */ 194285275Spkelsey#define TAG_USER_CLASS ((uint8_t) 77) 195285275Spkelsey/* RFC 3011 */ 196285275Spkelsey#define TAG_IP4_SUBNET_SELECT ((uint8_t) 118) 197285275Spkelsey/* RFC 3442 */ 198285275Spkelsey#define TAG_CLASSLESS_STATIC_RT ((uint8_t) 121) 199285275Spkelsey#define TAG_CLASSLESS_STA_RT_MS ((uint8_t) 249) 200285275Spkelsey/* RFC 5859 - TFTP Server Address Option for DHCPv4 */ 201285275Spkelsey#define TAG_TFTP_SERVER_ADDRESS ((uint8_t) 150) 202285275Spkelsey/* ftp://ftp.isi.edu/.../assignments/bootp-dhcp-extensions */ 203285275Spkelsey#define TAG_SLP_NAMING_AUTH ((uint8_t) 80) 204285275Spkelsey#define TAG_CLIENT_FQDN ((uint8_t) 81) 205285275Spkelsey#define TAG_AGENT_CIRCUIT ((uint8_t) 82) 206285275Spkelsey#define TAG_AGENT_REMOTE ((uint8_t) 83) 207285275Spkelsey#define TAG_AGENT_MASK ((uint8_t) 84) 208285275Spkelsey#define TAG_TZ_STRING ((uint8_t) 88) 209285275Spkelsey#define TAG_FQDN_OPTION ((uint8_t) 89) 210285275Spkelsey#define TAG_AUTH ((uint8_t) 90) 211285275Spkelsey#define TAG_VINES_SERVERS ((uint8_t) 91) 212285275Spkelsey#define TAG_SERVER_RANK ((uint8_t) 92) 213285275Spkelsey#define TAG_CLIENT_ARCH ((uint8_t) 93) 214285275Spkelsey#define TAG_CLIENT_NDI ((uint8_t) 94) 215285275Spkelsey#define TAG_CLIENT_GUID ((uint8_t) 97) 216285275Spkelsey#define TAG_LDAP_URL ((uint8_t) 95) 217285275Spkelsey#define TAG_6OVER4 ((uint8_t) 96) 218285275Spkelsey#define TAG_PRINTER_NAME ((uint8_t) 100) 219285275Spkelsey#define TAG_MDHCP_SERVER ((uint8_t) 101) 220285275Spkelsey#define TAG_IPX_COMPAT ((uint8_t) 110) 221285275Spkelsey#define TAG_NETINFO_PARENT ((uint8_t) 112) 222285275Spkelsey#define TAG_NETINFO_PARENT_TAG ((uint8_t) 113) 223285275Spkelsey#define TAG_URL ((uint8_t) 114) 224285275Spkelsey#define TAG_FAILOVER ((uint8_t) 115) 225285275Spkelsey#define TAG_EXTENDED_REQUEST ((uint8_t) 126) 226285275Spkelsey#define TAG_EXTENDED_OPTION ((uint8_t) 127) 227285275Spkelsey 228285275Spkelsey/* DHCP Message types (values for TAG_DHCP_MESSAGE option) */ 229285275Spkelsey#define DHCPDISCOVER 1 230285275Spkelsey#define DHCPOFFER 2 231285275Spkelsey#define DHCPREQUEST 3 232285275Spkelsey#define DHCPDECLINE 4 233285275Spkelsey#define DHCPACK 5 234285275Spkelsey#define DHCPNAK 6 235285275Spkelsey#define DHCPRELEASE 7 236285275Spkelsey#define DHCPINFORM 8 237285275Spkelsey 238285275Spkelsey/* 239285275Spkelsey * "vendor" data permitted for CMU bootp clients. 240285275Spkelsey */ 241285275Spkelsey 242285275Spkelseystruct cmu_vend { 243285275Spkelsey uint8_t v_magic[4]; /* magic number */ 244285275Spkelsey uint32_t v_flags; /* flags/opcodes, etc. */ 245285275Spkelsey struct in_addr v_smask; /* Subnet mask */ 246285275Spkelsey struct in_addr v_dgate; /* Default gateway */ 247285275Spkelsey struct in_addr v_dns1, v_dns2; /* Domain name servers */ 248285275Spkelsey struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */ 249285275Spkelsey struct in_addr v_ts1, v_ts2; /* Time servers */ 250285275Spkelsey uint8_t v_unused[24]; /* currently unused */ 251285275Spkelsey} UNALIGNED; 252285275Spkelsey 253285275Spkelsey 254285275Spkelsey/* v_flags values */ 255285275Spkelsey#define VF_SMASK 1 /* Subnet mask field contains valid data */ 256285275Spkelsey 257285275Spkelsey/* RFC 4702 DHCP Client FQDN Option */ 258285275Spkelsey 259285275Spkelsey#define CLIENT_FQDN_FLAGS_S 0x01 260285275Spkelsey#define CLIENT_FQDN_FLAGS_O 0x02 261285275Spkelsey#define CLIENT_FQDN_FLAGS_E 0x04 262285275Spkelsey#define CLIENT_FQDN_FLAGS_N 0x08 263285275Spkelsey/* end of original bootp.h */ 264285275Spkelsey 265276788Sdelphijstatic void rfc1048_print(netdissect_options *, const u_char *); 266276788Sdelphijstatic void cmu_print(netdissect_options *, const u_char *); 267172686Smlaierstatic char *client_fqdn_flags(u_int flags); 26817680Spst 269127675Sbmsstatic const struct tok bootp_flag_values[] = { 270285275Spkelsey { 0x8000, "Broadcast" }, 271285275Spkelsey { 0, NULL} 272127675Sbms}; 273127675Sbms 274127675Sbmsstatic const struct tok bootp_op_values[] = { 275285275Spkelsey { BOOTPREQUEST, "Request" }, 276285275Spkelsey { BOOTPREPLY, "Reply" }, 277285275Spkelsey { 0, NULL} 278127675Sbms}; 279127675Sbms 28017680Spst/* 28117680Spst * Print bootp requests 28217680Spst */ 28317680Spstvoid 284276788Sdelphijbootp_print(netdissect_options *ndo, 285285275Spkelsey register const u_char *cp, u_int length) 28617680Spst{ 28717680Spst register const struct bootp *bp; 28898527Sfenner static const u_char vm_cmu[4] = VM_CMU; 28998527Sfenner static const u_char vm_rfc1048[4] = VM_RFC1048; 29017680Spst 29198527Sfenner bp = (const struct bootp *)cp; 292276788Sdelphij ND_TCHECK(bp->bp_op); 29317680Spst 294276788Sdelphij ND_PRINT((ndo, "BOOTP/DHCP, %s", 295285275Spkelsey tok2str(bootp_op_values, "unknown (0x%02x)", bp->bp_op))); 29617680Spst 297127675Sbms if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { 298276788Sdelphij ND_TCHECK2(bp->bp_chaddr[0], 6); 299276788Sdelphij ND_PRINT((ndo, " from %s", etheraddr_string(ndo, bp->bp_chaddr))); 30017680Spst } 30117680Spst 302276788Sdelphij ND_PRINT((ndo, ", length %u", length)); 303127675Sbms 304276788Sdelphij if (!ndo->ndo_vflag) 305276788Sdelphij return; 306127675Sbms 307276788Sdelphij ND_TCHECK(bp->bp_secs); 30817680Spst 30917680Spst /* The usual hardware address type is 1 (10Mb Ethernet) */ 31017680Spst if (bp->bp_htype != 1) 311276788Sdelphij ND_PRINT((ndo, ", htype %d", bp->bp_htype)); 31217680Spst 31317680Spst /* The usual length for 10Mb Ethernet address is 6 bytes */ 31417680Spst if (bp->bp_htype != 1 || bp->bp_hlen != 6) 315276788Sdelphij ND_PRINT((ndo, ", hlen %d", bp->bp_hlen)); 31617680Spst 31717680Spst /* Only print interesting fields */ 31817680Spst if (bp->bp_hops) 319276788Sdelphij ND_PRINT((ndo, ", hops %d", bp->bp_hops)); 320276788Sdelphij if (EXTRACT_32BITS(&bp->bp_xid)) 321276788Sdelphij ND_PRINT((ndo, ", xid 0x%x", EXTRACT_32BITS(&bp->bp_xid))); 322276788Sdelphij if (EXTRACT_16BITS(&bp->bp_secs)) 323276788Sdelphij ND_PRINT((ndo, ", secs %d", EXTRACT_16BITS(&bp->bp_secs))); 32417680Spst 325276788Sdelphij ND_PRINT((ndo, ", Flags [%s]", 326285275Spkelsey bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags)))); 327276788Sdelphij if (ndo->ndo_vflag > 1) 328276788Sdelphij ND_PRINT((ndo, " (0x%04x)", EXTRACT_16BITS(&bp->bp_flags))); 329127675Sbms 33017680Spst /* Client's ip address */ 331276788Sdelphij ND_TCHECK(bp->bp_ciaddr); 332276788Sdelphij if (EXTRACT_32BITS(&bp->bp_ciaddr.s_addr)) 333276788Sdelphij ND_PRINT((ndo, "\n\t Client-IP %s", ipaddr_string(ndo, &bp->bp_ciaddr))); 33417680Spst 33517680Spst /* 'your' ip address (bootp client) */ 336276788Sdelphij ND_TCHECK(bp->bp_yiaddr); 337276788Sdelphij if (EXTRACT_32BITS(&bp->bp_yiaddr.s_addr)) 338276788Sdelphij ND_PRINT((ndo, "\n\t Your-IP %s", ipaddr_string(ndo, &bp->bp_yiaddr))); 33917680Spst 34017680Spst /* Server's ip address */ 341276788Sdelphij ND_TCHECK(bp->bp_siaddr); 342276788Sdelphij if (EXTRACT_32BITS(&bp->bp_siaddr.s_addr)) 343276788Sdelphij ND_PRINT((ndo, "\n\t Server-IP %s", ipaddr_string(ndo, &bp->bp_siaddr))); 34417680Spst 34517680Spst /* Gateway's ip address */ 346276788Sdelphij ND_TCHECK(bp->bp_giaddr); 347276788Sdelphij if (EXTRACT_32BITS(&bp->bp_giaddr.s_addr)) 348276788Sdelphij ND_PRINT((ndo, "\n\t Gateway-IP %s", ipaddr_string(ndo, &bp->bp_giaddr))); 34917680Spst 35017680Spst /* Client's Ethernet address */ 35117680Spst if (bp->bp_htype == 1 && bp->bp_hlen == 6) { 352276788Sdelphij ND_TCHECK2(bp->bp_chaddr[0], 6); 353276788Sdelphij ND_PRINT((ndo, "\n\t Client-Ethernet-Address %s", etheraddr_string(ndo, bp->bp_chaddr))); 35417680Spst } 35517680Spst 356276788Sdelphij ND_TCHECK2(bp->bp_sname[0], 1); /* check first char only */ 35717680Spst if (*bp->bp_sname) { 358276788Sdelphij ND_PRINT((ndo, "\n\t sname \"")); 359276788Sdelphij if (fn_print(ndo, bp->bp_sname, ndo->ndo_snapend)) { 360276788Sdelphij ND_PRINT((ndo, "\"")); 361276788Sdelphij ND_PRINT((ndo, "%s", tstr + 1)); 36217680Spst return; 36317680Spst } 364276788Sdelphij ND_PRINT((ndo, "\"")); 36517680Spst } 366276788Sdelphij ND_TCHECK2(bp->bp_file[0], 1); /* check first char only */ 36717680Spst if (*bp->bp_file) { 368276788Sdelphij ND_PRINT((ndo, "\n\t file \"")); 369276788Sdelphij if (fn_print(ndo, bp->bp_file, ndo->ndo_snapend)) { 370276788Sdelphij ND_PRINT((ndo, "\"")); 371276788Sdelphij ND_PRINT((ndo, "%s", tstr + 1)); 37217680Spst return; 37317680Spst } 374276788Sdelphij ND_PRINT((ndo, "\"")); 37517680Spst } 37617680Spst 37717680Spst /* Decode the vendor buffer */ 378276788Sdelphij ND_TCHECK(bp->bp_vend[0]); 37998527Sfenner if (memcmp((const char *)bp->bp_vend, vm_rfc1048, 380285275Spkelsey sizeof(uint32_t)) == 0) 381276788Sdelphij rfc1048_print(ndo, bp->bp_vend); 38298527Sfenner else if (memcmp((const char *)bp->bp_vend, vm_cmu, 383285275Spkelsey sizeof(uint32_t)) == 0) 384276788Sdelphij cmu_print(ndo, bp->bp_vend); 38517680Spst else { 386276788Sdelphij uint32_t ul; 38717680Spst 38875118Sfenner ul = EXTRACT_32BITS(&bp->bp_vend); 38917680Spst if (ul != 0) 390276788Sdelphij ND_PRINT((ndo, "\n\t Vendor-#0x%x", ul)); 39117680Spst } 39217680Spst 39317680Spst return; 39417680Spsttrunc: 395276788Sdelphij ND_PRINT((ndo, "%s", tstr)); 39617680Spst} 39717680Spst 39898527Sfenner/* 39998527Sfenner * The first character specifies the format to print: 40098527Sfenner * i - ip address (32 bits) 40198527Sfenner * p - ip address pairs (32 bits + 32 bits) 40298527Sfenner * l - long (32 bits) 40398527Sfenner * L - unsigned long (32 bits) 40498527Sfenner * s - short (16 bits) 40598527Sfenner * b - period-seperated decimal bytes (variable length) 40698527Sfenner * x - colon-seperated hex bytes (variable length) 40798527Sfenner * a - ascii string (variable length) 40898527Sfenner * B - on/off (8 bits) 40998527Sfenner * $ - special (explicit code to handle) 41098527Sfenner */ 411276788Sdelphijstatic const struct tok tag2str[] = { 41217680Spst/* RFC1048 tags */ 41317680Spst { TAG_PAD, " PAD" }, 414172686Smlaier { TAG_SUBNET_MASK, "iSubnet-Mask" }, /* subnet mask (RFC950) */ 415172686Smlaier { TAG_TIME_OFFSET, "LTime-Zone" }, /* seconds from UTC */ 416172686Smlaier { TAG_GATEWAY, "iDefault-Gateway" }, /* default gateway */ 417172686Smlaier { TAG_TIME_SERVER, "iTime-Server" }, /* time servers (RFC868) */ 418172686Smlaier { TAG_NAME_SERVER, "iIEN-Name-Server" }, /* IEN name servers (IEN116) */ 419172686Smlaier { TAG_DOMAIN_SERVER, "iDomain-Name-Server" }, /* domain name (RFC1035) */ 42017680Spst { TAG_LOG_SERVER, "iLOG" }, /* MIT log servers */ 42117680Spst { TAG_COOKIE_SERVER, "iCS" }, /* cookie servers (RFC865) */ 422172686Smlaier { TAG_LPR_SERVER, "iLPR-Server" }, /* lpr server (RFC1179) */ 42317680Spst { TAG_IMPRESS_SERVER, "iIM" }, /* impress servers (Imagen) */ 42417680Spst { TAG_RLP_SERVER, "iRL" }, /* resource location (RFC887) */ 425172686Smlaier { TAG_HOSTNAME, "aHostname" }, /* ascii hostname */ 42617680Spst { TAG_BOOTSIZE, "sBS" }, /* 512 byte blocks */ 42717680Spst { TAG_END, " END" }, 42817680Spst/* RFC1497 tags */ 42917680Spst { TAG_DUMPPATH, "aDP" }, 430172686Smlaier { TAG_DOMAINNAME, "aDomain-Name" }, 43117680Spst { TAG_SWAP_SERVER, "iSS" }, 43217680Spst { TAG_ROOTPATH, "aRP" }, 43317680Spst { TAG_EXTPATH, "aEP" }, 43456896Sfenner/* RFC2132 tags */ 43556896Sfenner { TAG_IP_FORWARD, "BIPF" }, 43656896Sfenner { TAG_NL_SRCRT, "BSRT" }, 43756896Sfenner { TAG_PFILTERS, "pPF" }, 43856896Sfenner { TAG_REASS_SIZE, "sRSZ" }, 43956896Sfenner { TAG_DEF_TTL, "bTTL" }, 440172686Smlaier { TAG_MTU_TIMEOUT, "lMTU-Timeout" }, 441172686Smlaier { TAG_MTU_TABLE, "sMTU-Table" }, 44256896Sfenner { TAG_INT_MTU, "sMTU" }, 44356896Sfenner { TAG_LOCAL_SUBNETS, "BLSN" }, 44456896Sfenner { TAG_BROAD_ADDR, "iBR" }, 44556896Sfenner { TAG_DO_MASK_DISC, "BMD" }, 44656896Sfenner { TAG_SUPPLY_MASK, "BMS" }, 447172686Smlaier { TAG_DO_RDISC, "BRouter-Discovery" }, 44856896Sfenner { TAG_RTR_SOL_ADDR, "iRSA" }, 449172686Smlaier { TAG_STATIC_ROUTE, "pStatic-Route" }, 45056896Sfenner { TAG_USE_TRAILERS, "BUT" }, 45156896Sfenner { TAG_ARP_TIMEOUT, "lAT" }, 45256896Sfenner { TAG_ETH_ENCAP, "BIE" }, 45356896Sfenner { TAG_TCP_TTL, "bTT" }, 45456896Sfenner { TAG_TCP_KEEPALIVE, "lKI" }, 45556896Sfenner { TAG_KEEPALIVE_GO, "BKG" }, 45656896Sfenner { TAG_NIS_DOMAIN, "aYD" }, 45756896Sfenner { TAG_NIS_SERVERS, "iYS" }, 45856896Sfenner { TAG_NTP_SERVERS, "iNTP" }, 459172686Smlaier { TAG_VENDOR_OPTS, "bVendor-Option" }, 460172686Smlaier { TAG_NETBIOS_NS, "iNetbios-Name-Server" }, 46156896Sfenner { TAG_NETBIOS_DDS, "iWDD" }, 462172686Smlaier { TAG_NETBIOS_NODE, "$Netbios-Node" }, 463172686Smlaier { TAG_NETBIOS_SCOPE, "aNetbios-Scope" }, 46456896Sfenner { TAG_XWIN_FS, "iXFS" }, 46556896Sfenner { TAG_XWIN_DM, "iXDM" }, 46656896Sfenner { TAG_NIS_P_DOMAIN, "sN+D" }, 46756896Sfenner { TAG_NIS_P_SERVERS, "iN+S" }, 46856896Sfenner { TAG_MOBILE_HOME, "iMH" }, 46956896Sfenner { TAG_SMPT_SERVER, "iSMTP" }, 47056896Sfenner { TAG_POP3_SERVER, "iPOP3" }, 47156896Sfenner { TAG_NNTP_SERVER, "iNNTP" }, 47256896Sfenner { TAG_WWW_SERVER, "iWWW" }, 47356896Sfenner { TAG_FINGER_SERVER, "iFG" }, 47456896Sfenner { TAG_IRC_SERVER, "iIRC" }, 47556896Sfenner { TAG_STREETTALK_SRVR, "iSTS" }, 47656896Sfenner { TAG_STREETTALK_STDA, "iSTDA" }, 477172686Smlaier { TAG_REQUESTED_IP, "iRequested-IP" }, 478172686Smlaier { TAG_IP_LEASE, "lLease-Time" }, 47998527Sfenner { TAG_OPT_OVERLOAD, "$OO" }, 48056896Sfenner { TAG_TFTP_SERVER, "aTFTP" }, 48156896Sfenner { TAG_BOOTFILENAME, "aBF" }, 482172686Smlaier { TAG_DHCP_MESSAGE, " DHCP-Message" }, 483172686Smlaier { TAG_SERVER_ID, "iServer-ID" }, 484172686Smlaier { TAG_PARM_REQUEST, "bParameter-Request" }, 48556896Sfenner { TAG_MESSAGE, "aMSG" }, 48656896Sfenner { TAG_MAX_MSG_SIZE, "sMSZ" }, 48756896Sfenner { TAG_RENEWAL_TIME, "lRN" }, 48856896Sfenner { TAG_REBIND_TIME, "lRB" }, 489172686Smlaier { TAG_VENDOR_CLASS, "aVendor-Class" }, 490172686Smlaier { TAG_CLIENT_ID, "$Client-ID" }, 49175118Sfenner/* RFC 2485 */ 49275118Sfenner { TAG_OPEN_GROUP_UAP, "aUAP" }, 49375118Sfenner/* RFC 2563 */ 49475118Sfenner { TAG_DISABLE_AUTOCONF, "BNOAUTO" }, 49575118Sfenner/* RFC 2610 */ 49675118Sfenner { TAG_SLP_DA, "bSLP-DA" }, /*"b" is a little wrong */ 49775118Sfenner { TAG_SLP_SCOPE, "bSLP-SCOPE" }, /*"b" is a little wrong */ 49875118Sfenner/* RFC 2937 */ 49975118Sfenner { TAG_NS_SEARCH, "sNSSEARCH" }, /* XXX 's' */ 500285275Spkelsey/* RFC 3004 - The User Class Option for DHCP */ 501285275Spkelsey { TAG_USER_CLASS, "$User-Class" }, 50275118Sfenner/* RFC 3011 */ 50375118Sfenner { TAG_IP4_SUBNET_SELECT, "iSUBNET" }, 504172686Smlaier/* RFC 3442 */ 505172686Smlaier { TAG_CLASSLESS_STATIC_RT, "$Classless-Static-Route" }, 506172686Smlaier { TAG_CLASSLESS_STA_RT_MS, "$Classless-Static-Route-Microsoft" }, 507285275Spkelsey/* RFC 5859 - TFTP Server Address Option for DHCPv4 */ 508285275Spkelsey { TAG_TFTP_SERVER_ADDRESS, "iTFTP-Server-Address" }, 509127675Sbms/* http://www.iana.org/assignments/bootp-dhcp-extensions/index.htm */ 51075118Sfenner { TAG_SLP_NAMING_AUTH, "aSLP-NA" }, 51198527Sfenner { TAG_CLIENT_FQDN, "$FQDN" }, 512172686Smlaier { TAG_AGENT_CIRCUIT, "$Agent-Information" }, 51375118Sfenner { TAG_AGENT_REMOTE, "bARMT" }, 51475118Sfenner { TAG_AGENT_MASK, "bAMSK" }, 51575118Sfenner { TAG_TZ_STRING, "aTZSTR" }, 51675118Sfenner { TAG_FQDN_OPTION, "bFQDNS" }, /* XXX 'b' */ 51775118Sfenner { TAG_AUTH, "bAUTH" }, /* XXX 'b' */ 51875118Sfenner { TAG_VINES_SERVERS, "iVINES" }, 51975118Sfenner { TAG_SERVER_RANK, "sRANK" }, 52075118Sfenner { TAG_CLIENT_ARCH, "sARCH" }, 52175118Sfenner { TAG_CLIENT_NDI, "bNDI" }, /* XXX 'b' */ 52275118Sfenner { TAG_CLIENT_GUID, "bGUID" }, /* XXX 'b' */ 52375118Sfenner { TAG_LDAP_URL, "aLDAP" }, 52475118Sfenner { TAG_6OVER4, "i6o4" }, 52575118Sfenner { TAG_PRINTER_NAME, "aPRTR" }, 52675118Sfenner { TAG_MDHCP_SERVER, "bMDHCP" }, /* XXX 'b' */ 52775118Sfenner { TAG_IPX_COMPAT, "bIPX" }, /* XXX 'b' */ 52875118Sfenner { TAG_NETINFO_PARENT, "iNI" }, 52975118Sfenner { TAG_NETINFO_PARENT_TAG, "aNITAG" }, 53075118Sfenner { TAG_URL, "aURL" }, 53175118Sfenner { TAG_FAILOVER, "bFAIL" }, /* XXX 'b' */ 532285275Spkelsey { 0, NULL } 53317680Spst}; 53475118Sfenner/* 2-byte extended tags */ 535276788Sdelphijstatic const struct tok xtag2str[] = { 536285275Spkelsey { 0, NULL } 53775118Sfenner}; 53817680Spst 53998527Sfenner/* DHCP "options overload" types */ 540276788Sdelphijstatic const struct tok oo2str[] = { 541285275Spkelsey { 1, "file" }, 542285275Spkelsey { 2, "sname" }, 543285275Spkelsey { 3, "file+sname" }, 544285275Spkelsey { 0, NULL } 54598527Sfenner}; 54698527Sfenner 54798527Sfenner/* NETBIOS over TCP/IP node type options */ 548276788Sdelphijstatic const struct tok nbo2str[] = { 549285275Spkelsey { 0x1, "b-node" }, 550285275Spkelsey { 0x2, "p-node" }, 551285275Spkelsey { 0x4, "m-node" }, 552285275Spkelsey { 0x8, "h-node" }, 553285275Spkelsey { 0, NULL } 55498527Sfenner}; 55598527Sfenner 55698527Sfenner/* ARP Hardware types, for Client-ID option */ 557276788Sdelphijstatic const struct tok arp2str[] = { 558285275Spkelsey { 0x1, "ether" }, 559285275Spkelsey { 0x6, "ieee802" }, 560285275Spkelsey { 0x7, "arcnet" }, 561285275Spkelsey { 0xf, "frelay" }, 562285275Spkelsey { 0x17, "strip" }, 563285275Spkelsey { 0x18, "ieee1394" }, 564285275Spkelsey { 0, NULL } 56598527Sfenner}; 56698527Sfenner 567276788Sdelphijstatic const struct tok dhcp_msg_values[] = { 568285275Spkelsey { DHCPDISCOVER, "Discover" }, 569285275Spkelsey { DHCPOFFER, "Offer" }, 570285275Spkelsey { DHCPREQUEST, "Request" }, 571285275Spkelsey { DHCPDECLINE, "Decline" }, 572285275Spkelsey { DHCPACK, "ACK" }, 573285275Spkelsey { DHCPNAK, "NACK" }, 574285275Spkelsey { DHCPRELEASE, "Release" }, 575285275Spkelsey { DHCPINFORM, "Inform" }, 576285275Spkelsey { 0, NULL } 577172686Smlaier}; 578172686Smlaier 579285275Spkelsey#define AGENT_SUBOPTION_CIRCUIT_ID 1 /* RFC 3046 */ 580285275Spkelsey#define AGENT_SUBOPTION_REMOTE_ID 2 /* RFC 3046 */ 581285275Spkelsey#define AGENT_SUBOPTION_SUBSCRIBER_ID 6 /* RFC 3993 */ 582276788Sdelphijstatic const struct tok agent_suboption_values[] = { 583285275Spkelsey { AGENT_SUBOPTION_CIRCUIT_ID, "Circuit-ID" }, 584285275Spkelsey { AGENT_SUBOPTION_REMOTE_ID, "Remote-ID" }, 585285275Spkelsey { AGENT_SUBOPTION_SUBSCRIBER_ID, "Subscriber-ID" }, 586285275Spkelsey { 0, NULL } 587172686Smlaier}; 588172686Smlaier 589172686Smlaier 59017680Spststatic void 591276788Sdelphijrfc1048_print(netdissect_options *ndo, 592285275Spkelsey register const u_char *bp) 59317680Spst{ 594276788Sdelphij register uint16_t tag; 595172686Smlaier register u_int len; 59617680Spst register const char *cp; 59717680Spst register char c; 598172686Smlaier int first, idx; 599276788Sdelphij uint32_t ul; 600276788Sdelphij uint16_t us; 601276788Sdelphij uint8_t uc, subopt, suboptlen; 60217680Spst 603276788Sdelphij ND_PRINT((ndo, "\n\t Vendor-rfc1048 Extensions")); 60417680Spst 60517680Spst /* Step over magic cookie */ 606276788Sdelphij ND_PRINT((ndo, "\n\t Magic Cookie 0x%08x", EXTRACT_32BITS(bp))); 60717680Spst bp += sizeof(int32_t); 60817680Spst 60917680Spst /* Loop while we there is a tag left in the buffer */ 610276788Sdelphij while (ND_TTEST2(*bp, 1)) { 61117680Spst tag = *bp++; 612276788Sdelphij if (tag == TAG_PAD && ndo->ndo_vflag < 3) 61317680Spst continue; 614276788Sdelphij if (tag == TAG_END && ndo->ndo_vflag < 3) 61517680Spst return; 61675118Sfenner if (tag == TAG_EXTENDED_OPTION) { 617276788Sdelphij ND_TCHECK2(*(bp + 1), 2); 61875118Sfenner tag = EXTRACT_16BITS(bp + 1); 61975118Sfenner /* XXX we don't know yet if the IANA will 62075118Sfenner * preclude overlap of 1-byte and 2-byte spaces. 62175118Sfenner * If not, we need to offset tag after this step. 62275118Sfenner */ 623111729Sfenner cp = tok2str(xtag2str, "?xT%u", tag); 62475118Sfenner } else 625111729Sfenner cp = tok2str(tag2str, "?T%u", tag); 62617680Spst c = *cp++; 62717680Spst 628172686Smlaier if (tag == TAG_PAD || tag == TAG_END) 629172686Smlaier len = 0; 630172686Smlaier else { 631172686Smlaier /* Get the length; check for truncation */ 632276788Sdelphij ND_TCHECK2(*bp, 1); 633172686Smlaier len = *bp++; 63417680Spst } 635172686Smlaier 636276788Sdelphij ND_PRINT((ndo, "\n\t %s Option %u, length %u%s", cp, tag, len, 637285275Spkelsey len > 0 ? ": " : "")); 638172686Smlaier 639276788Sdelphij if (tag == TAG_PAD && ndo->ndo_vflag > 2) { 640172686Smlaier u_int ntag = 1; 641276788Sdelphij while (ND_TTEST2(*bp, 1) && *bp == TAG_PAD) { 642172686Smlaier bp++; 643172686Smlaier ntag++; 644172686Smlaier } 645172686Smlaier if (ntag > 1) 646276788Sdelphij ND_PRINT((ndo, ", occurs %u", ntag)); 647172686Smlaier } 648172686Smlaier 649276788Sdelphij if (!ND_TTEST2(*bp, len)) { 650276788Sdelphij ND_PRINT((ndo, "[|rfc1048 %u]", len)); 65117680Spst return; 65217680Spst } 65317680Spst 65456896Sfenner if (tag == TAG_DHCP_MESSAGE && len == 1) { 655111729Sfenner uc = *bp++; 656276788Sdelphij ND_PRINT((ndo, "%s", tok2str(dhcp_msg_values, "Unknown (%u)", uc))); 657276788Sdelphij continue; 65856896Sfenner } 65956896Sfenner 66056896Sfenner if (tag == TAG_PARM_REQUEST) { 661172686Smlaier idx = 0; 66256896Sfenner while (len-- > 0) { 663111729Sfenner uc = *bp++; 664172686Smlaier cp = tok2str(tag2str, "?Option %u", uc); 665172686Smlaier if (idx % 4 == 0) 666276788Sdelphij ND_PRINT((ndo, "\n\t ")); 667172686Smlaier else 668276788Sdelphij ND_PRINT((ndo, ", ")); 669276788Sdelphij ND_PRINT((ndo, "%s", cp + 1)); 670172686Smlaier idx++; 67156896Sfenner } 67256896Sfenner continue; 67356896Sfenner } 674172686Smlaier 67575118Sfenner if (tag == TAG_EXTENDED_REQUEST) { 67675118Sfenner first = 1; 67775118Sfenner while (len > 1) { 67875118Sfenner len -= 2; 679111729Sfenner us = EXTRACT_16BITS(bp); 68075118Sfenner bp += 2; 681111729Sfenner cp = tok2str(xtag2str, "?xT%u", us); 68275118Sfenner if (!first) 683276788Sdelphij ND_PRINT((ndo, "+")); 684276788Sdelphij ND_PRINT((ndo, "%s", cp + 1)); 68575118Sfenner first = 0; 68675118Sfenner } 68775118Sfenner continue; 68875118Sfenner } 68956896Sfenner 69017680Spst /* Print data */ 69117680Spst if (c == '?') { 69217680Spst /* Base default formats for unknown tags on data size */ 693172686Smlaier if (len & 1) 69417680Spst c = 'b'; 695172686Smlaier else if (len & 2) 69617680Spst c = 's'; 69717680Spst else 69817680Spst c = 'l'; 69917680Spst } 70017680Spst first = 1; 70117680Spst switch (c) { 70217680Spst 70317680Spst case 'a': 70417680Spst /* ascii strings */ 705276788Sdelphij ND_PRINT((ndo, "\"")); 706276788Sdelphij if (fn_printn(ndo, bp, len, ndo->ndo_snapend)) { 707276788Sdelphij ND_PRINT((ndo, "\"")); 708147904Ssam goto trunc; 709147904Ssam } 710276788Sdelphij ND_PRINT((ndo, "\"")); 711172686Smlaier bp += len; 712172686Smlaier len = 0; 71317680Spst break; 71417680Spst 71517680Spst case 'i': 71617680Spst case 'l': 71775118Sfenner case 'L': 71817680Spst /* ip addresses/32-bit words */ 719172686Smlaier while (len >= sizeof(ul)) { 72017680Spst if (!first) 721276788Sdelphij ND_PRINT((ndo, ",")); 72275118Sfenner ul = EXTRACT_32BITS(bp); 72375118Sfenner if (c == 'i') { 72475118Sfenner ul = htonl(ul); 725276788Sdelphij ND_PRINT((ndo, "%s", ipaddr_string(ndo, &ul))); 72675118Sfenner } else if (c == 'L') 727276788Sdelphij ND_PRINT((ndo, "%d", ul)); 72817680Spst else 729276788Sdelphij ND_PRINT((ndo, "%u", ul)); 73017680Spst bp += sizeof(ul); 731172686Smlaier len -= sizeof(ul); 73217680Spst first = 0; 73317680Spst } 73417680Spst break; 73517680Spst 73656896Sfenner case 'p': 73756896Sfenner /* IP address pairs */ 738172686Smlaier while (len >= 2*sizeof(ul)) { 73956896Sfenner if (!first) 740276788Sdelphij ND_PRINT((ndo, ",")); 74198527Sfenner memcpy((char *)&ul, (const char *)bp, sizeof(ul)); 742276788Sdelphij ND_PRINT((ndo, "(%s:", ipaddr_string(ndo, &ul))); 74356896Sfenner bp += sizeof(ul); 74498527Sfenner memcpy((char *)&ul, (const char *)bp, sizeof(ul)); 745276788Sdelphij ND_PRINT((ndo, "%s)", ipaddr_string(ndo, &ul))); 74656896Sfenner bp += sizeof(ul); 747172686Smlaier len -= 2*sizeof(ul); 74856896Sfenner first = 0; 74956896Sfenner } 75056896Sfenner break; 75156896Sfenner 75217680Spst case 's': 75317680Spst /* shorts */ 754172686Smlaier while (len >= sizeof(us)) { 75517680Spst if (!first) 756276788Sdelphij ND_PRINT((ndo, ",")); 75775118Sfenner us = EXTRACT_16BITS(bp); 758276788Sdelphij ND_PRINT((ndo, "%u", us)); 75917680Spst bp += sizeof(us); 760172686Smlaier len -= sizeof(us); 76117680Spst first = 0; 76217680Spst } 76317680Spst break; 76417680Spst 76556896Sfenner case 'B': 76656896Sfenner /* boolean */ 767172686Smlaier while (len > 0) { 76856896Sfenner if (!first) 769276788Sdelphij ND_PRINT((ndo, ",")); 77056896Sfenner switch (*bp) { 77156896Sfenner case 0: 772276788Sdelphij ND_PRINT((ndo, "N")); 77356896Sfenner break; 77456896Sfenner case 1: 775276788Sdelphij ND_PRINT((ndo, "Y")); 77656896Sfenner break; 77756896Sfenner default: 778276788Sdelphij ND_PRINT((ndo, "%u?", *bp)); 77956896Sfenner break; 78056896Sfenner } 78156896Sfenner ++bp; 782172686Smlaier --len; 78356896Sfenner first = 0; 78456896Sfenner } 78556896Sfenner break; 78656896Sfenner 78717680Spst case 'b': 78875118Sfenner case 'x': 78917680Spst default: 79017680Spst /* Bytes */ 791172686Smlaier while (len > 0) { 79217680Spst if (!first) 793276788Sdelphij ND_PRINT((ndo, c == 'x' ? ":" : ".")); 79498527Sfenner if (c == 'x') 795276788Sdelphij ND_PRINT((ndo, "%02x", *bp)); 79698527Sfenner else 797276788Sdelphij ND_PRINT((ndo, "%u", *bp)); 79817680Spst ++bp; 799172686Smlaier --len; 80017680Spst first = 0; 80117680Spst } 80217680Spst break; 80398527Sfenner 80498527Sfenner case '$': 80598527Sfenner /* Guys we can't handle with one of the usual cases */ 80698527Sfenner switch (tag) { 80798527Sfenner 80898527Sfenner case TAG_NETBIOS_NODE: 809172686Smlaier /* this option should be at least 1 byte long */ 810285275Spkelsey if (len < 1) { 811285275Spkelsey ND_PRINT((ndo, "ERROR: length < 1 bytes")); 812172686Smlaier break; 813172686Smlaier } 81498527Sfenner tag = *bp++; 815172686Smlaier --len; 816276788Sdelphij ND_PRINT((ndo, "%s", tok2str(nbo2str, NULL, tag))); 81798527Sfenner break; 81898527Sfenner 81998527Sfenner case TAG_OPT_OVERLOAD: 820172686Smlaier /* this option should be at least 1 byte long */ 821285275Spkelsey if (len < 1) { 822285275Spkelsey ND_PRINT((ndo, "ERROR: length < 1 bytes")); 823172686Smlaier break; 824172686Smlaier } 82598527Sfenner tag = *bp++; 826172686Smlaier --len; 827276788Sdelphij ND_PRINT((ndo, "%s", tok2str(oo2str, NULL, tag))); 82898527Sfenner break; 82998527Sfenner 83098527Sfenner case TAG_CLIENT_FQDN: 831172686Smlaier /* this option should be at least 3 bytes long */ 832285275Spkelsey if (len < 3) { 833285275Spkelsey ND_PRINT((ndo, "ERROR: length < 3 bytes")); 834172686Smlaier bp += len; 835172686Smlaier len = 0; 836127675Sbms break; 837147904Ssam } 83898527Sfenner if (*bp) 839276788Sdelphij ND_PRINT((ndo, "[%s] ", client_fqdn_flags(*bp))); 840172686Smlaier bp++; 841172686Smlaier if (*bp || *(bp+1)) 842276788Sdelphij ND_PRINT((ndo, "%u/%u ", *bp, *(bp+1))); 84398527Sfenner bp += 2; 844276788Sdelphij ND_PRINT((ndo, "\"")); 845276788Sdelphij if (fn_printn(ndo, bp, len - 3, ndo->ndo_snapend)) { 846276788Sdelphij ND_PRINT((ndo, "\"")); 847147904Ssam goto trunc; 848147904Ssam } 849276788Sdelphij ND_PRINT((ndo, "\"")); 850172686Smlaier bp += len - 3; 851172686Smlaier len = 0; 85298527Sfenner break; 85398527Sfenner 85498527Sfenner case TAG_CLIENT_ID: 855285275Spkelsey { 856285275Spkelsey int type; 857172686Smlaier 858172686Smlaier /* this option should be at least 1 byte long */ 859285275Spkelsey if (len < 1) { 860285275Spkelsey ND_PRINT((ndo, "ERROR: length < 1 bytes")); 861172686Smlaier break; 862172686Smlaier } 863172686Smlaier type = *bp++; 864172686Smlaier len--; 86598527Sfenner if (type == 0) { 866276788Sdelphij ND_PRINT((ndo, "\"")); 867276788Sdelphij if (fn_printn(ndo, bp, len, ndo->ndo_snapend)) { 868276788Sdelphij ND_PRINT((ndo, "\"")); 869147904Ssam goto trunc; 870147904Ssam } 871276788Sdelphij ND_PRINT((ndo, "\"")); 872172686Smlaier bp += len; 873172686Smlaier len = 0; 87498527Sfenner break; 87598527Sfenner } else { 876276788Sdelphij ND_PRINT((ndo, "%s ", tok2str(arp2str, "hardware-type %u,", type))); 877172686Smlaier while (len > 0) { 878172686Smlaier if (!first) 879276788Sdelphij ND_PRINT((ndo, ":")); 880276788Sdelphij ND_PRINT((ndo, "%02x", *bp)); 881172686Smlaier ++bp; 882172686Smlaier --len; 883172686Smlaier first = 0; 884172686Smlaier } 88598527Sfenner } 886172686Smlaier break; 887172686Smlaier } 888172686Smlaier 889172686Smlaier case TAG_AGENT_CIRCUIT: 890172686Smlaier while (len >= 2) { 891172686Smlaier subopt = *bp++; 892172686Smlaier suboptlen = *bp++; 893172686Smlaier len -= 2; 894172686Smlaier if (suboptlen > len) { 895276788Sdelphij ND_PRINT((ndo, "\n\t %s SubOption %u, length %u: length goes past end of option", 896285275Spkelsey tok2str(agent_suboption_values, "Unknown", subopt), 897285275Spkelsey subopt, 898285275Spkelsey suboptlen)); 899172686Smlaier bp += len; 900172686Smlaier len = 0; 901172686Smlaier break; 902172686Smlaier } 903276788Sdelphij ND_PRINT((ndo, "\n\t %s SubOption %u, length %u: ", 904285275Spkelsey tok2str(agent_suboption_values, "Unknown", subopt), 905285275Spkelsey subopt, 906285275Spkelsey suboptlen)); 907172686Smlaier switch (subopt) { 908172686Smlaier 909276788Sdelphij case AGENT_SUBOPTION_CIRCUIT_ID: /* fall through */ 910276788Sdelphij case AGENT_SUBOPTION_REMOTE_ID: 911276788Sdelphij case AGENT_SUBOPTION_SUBSCRIBER_ID: 912285275Spkelsey if (fn_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) 913285275Spkelsey goto trunc; 914276788Sdelphij break; 915172686Smlaier 916172686Smlaier default: 917276788Sdelphij print_unknown_data(ndo, bp, "\n\t\t", suboptlen); 918172686Smlaier } 919172686Smlaier 920172686Smlaier len -= suboptlen; 921172686Smlaier bp += suboptlen; 922285275Spkelsey } 923285275Spkelsey break; 924172686Smlaier 925172686Smlaier case TAG_CLASSLESS_STATIC_RT: 926172686Smlaier case TAG_CLASSLESS_STA_RT_MS: 927285275Spkelsey { 928172686Smlaier u_int mask_width, significant_octets, i; 929172686Smlaier 930172686Smlaier /* this option should be at least 5 bytes long */ 931285275Spkelsey if (len < 5) { 932285275Spkelsey ND_PRINT((ndo, "ERROR: length < 5 bytes")); 933172686Smlaier bp += len; 934172686Smlaier len = 0; 935172686Smlaier break; 936172686Smlaier } 937172686Smlaier while (len > 0) { 93898527Sfenner if (!first) 939276788Sdelphij ND_PRINT((ndo, ",")); 940172686Smlaier mask_width = *bp++; 941172686Smlaier len--; 942172686Smlaier /* mask_width <= 32 */ 943172686Smlaier if (mask_width > 32) { 944285275Spkelsey ND_PRINT((ndo, "[ERROR: Mask width (%d) > 32]", mask_width)); 945172686Smlaier bp += len; 946172686Smlaier len = 0; 947172686Smlaier break; 948172686Smlaier } 949172686Smlaier significant_octets = (mask_width + 7) / 8; 950172686Smlaier /* significant octets + router(4) */ 951172686Smlaier if (len < significant_octets + 4) { 952285275Spkelsey ND_PRINT((ndo, "[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4)); 953172686Smlaier bp += len; 954172686Smlaier len = 0; 955172686Smlaier break; 956172686Smlaier } 957276788Sdelphij ND_PRINT((ndo, "(")); 958172686Smlaier if (mask_width == 0) 959276788Sdelphij ND_PRINT((ndo, "default")); 960172686Smlaier else { 961172686Smlaier for (i = 0; i < significant_octets ; i++) { 962172686Smlaier if (i > 0) 963276788Sdelphij ND_PRINT((ndo, ".")); 964276788Sdelphij ND_PRINT((ndo, "%d", *bp++)); 965172686Smlaier } 966172686Smlaier for (i = significant_octets ; i < 4 ; i++) 967276788Sdelphij ND_PRINT((ndo, ".0")); 968276788Sdelphij ND_PRINT((ndo, "/%d", mask_width)); 969172686Smlaier } 970172686Smlaier memcpy((char *)&ul, (const char *)bp, sizeof(ul)); 971276788Sdelphij ND_PRINT((ndo, ":%s)", ipaddr_string(ndo, &ul))); 972172686Smlaier bp += sizeof(ul); 973172686Smlaier len -= (significant_octets + 4); 97498527Sfenner first = 0; 97598527Sfenner } 976285275Spkelsey break; 977285275Spkelsey } 97898527Sfenner 979285275Spkelsey case TAG_USER_CLASS: 980285275Spkelsey { 981285275Spkelsey u_int suboptnumber = 1; 982285275Spkelsey 983285275Spkelsey first = 1; 984285275Spkelsey if (len < 2) { 985285275Spkelsey ND_PRINT((ndo, "ERROR: length < 2 bytes")); 986285275Spkelsey bp += len; 987285275Spkelsey len = 0; 988285275Spkelsey break; 989285275Spkelsey } 990285275Spkelsey while (len > 0) { 991285275Spkelsey suboptlen = *bp++; 992285275Spkelsey len--; 993285275Spkelsey ND_PRINT((ndo, "\n\t ")); 994285275Spkelsey ND_PRINT((ndo, "instance#%u: ", suboptnumber)); 995285275Spkelsey if (suboptlen == 0) { 996285275Spkelsey ND_PRINT((ndo, "ERROR: suboption length must be non-zero")); 997285275Spkelsey bp += len; 998285275Spkelsey len = 0; 999285275Spkelsey break; 1000285275Spkelsey } 1001285275Spkelsey if (len < suboptlen) { 1002285275Spkelsey ND_PRINT((ndo, "ERROR: malformed option")); 1003285275Spkelsey bp += len; 1004285275Spkelsey len = 0; 1005285275Spkelsey break; 1006285275Spkelsey } 1007285275Spkelsey ND_PRINT((ndo, "\"")); 1008285275Spkelsey if (fn_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) { 1009285275Spkelsey ND_PRINT((ndo, "\"")); 1010285275Spkelsey goto trunc; 1011285275Spkelsey } 1012285275Spkelsey ND_PRINT((ndo, "\"")); 1013285275Spkelsey ND_PRINT((ndo, ", length %d", suboptlen)); 1014285275Spkelsey suboptnumber++; 1015285275Spkelsey len -= suboptlen; 1016285275Spkelsey bp += suboptlen; 1017285275Spkelsey } 1018285275Spkelsey break; 1019285275Spkelsey } 1020285275Spkelsey 102198527Sfenner default: 1022276788Sdelphij ND_PRINT((ndo, "[unknown special tag %u, size %u]", 1023285275Spkelsey tag, len)); 1024172686Smlaier bp += len; 1025172686Smlaier len = 0; 102698527Sfenner break; 102798527Sfenner } 102898527Sfenner break; 102917680Spst } 103017680Spst /* Data left over? */ 1031172686Smlaier if (len) { 1032276788Sdelphij ND_PRINT((ndo, "\n\t trailing data length %u", len)); 1033172686Smlaier bp += len; 1034127675Sbms } 103517680Spst } 103675118Sfenner return; 103775118Sfennertrunc: 1038276788Sdelphij ND_PRINT((ndo, "|[rfc1048]")); 103917680Spst} 104017680Spst 104117680Spststatic void 1042276788Sdelphijcmu_print(netdissect_options *ndo, 1043285275Spkelsey register const u_char *bp) 104417680Spst{ 104517680Spst register const struct cmu_vend *cmu; 104617680Spst 1047276788Sdelphij#define PRINTCMUADDR(m, s) { ND_TCHECK(cmu->m); \ 104817680Spst if (cmu->m.s_addr != 0) \ 1049276788Sdelphij ND_PRINT((ndo, " %s:%s", s, ipaddr_string(ndo, &cmu->m.s_addr))); } 105017680Spst 1051276788Sdelphij ND_PRINT((ndo, " vend-cmu")); 105298527Sfenner cmu = (const struct cmu_vend *)bp; 105317680Spst 105417680Spst /* Only print if there are unknown bits */ 1055276788Sdelphij ND_TCHECK(cmu->v_flags); 105617680Spst if ((cmu->v_flags & ~(VF_SMASK)) != 0) 1057276788Sdelphij ND_PRINT((ndo, " F:0x%x", cmu->v_flags)); 105817680Spst PRINTCMUADDR(v_dgate, "DG"); 105917680Spst PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*"); 106017680Spst PRINTCMUADDR(v_dns1, "NS1"); 106117680Spst PRINTCMUADDR(v_dns2, "NS2"); 106217680Spst PRINTCMUADDR(v_ins1, "IEN1"); 106317680Spst PRINTCMUADDR(v_ins2, "IEN2"); 106417680Spst PRINTCMUADDR(v_ts1, "TS1"); 106517680Spst PRINTCMUADDR(v_ts2, "TS2"); 106617680Spst return; 106717680Spst 106817680Spsttrunc: 1069276788Sdelphij ND_PRINT((ndo, "%s", tstr)); 107017680Spst#undef PRINTCMUADDR 107117680Spst} 1072172686Smlaier 1073172686Smlaierstatic char * 1074172686Smlaierclient_fqdn_flags(u_int flags) 1075172686Smlaier{ 1076172686Smlaier static char buf[8+1]; 1077172686Smlaier int i = 0; 1078172686Smlaier 1079172686Smlaier if (flags & CLIENT_FQDN_FLAGS_S) 1080172686Smlaier buf[i++] = 'S'; 1081172686Smlaier if (flags & CLIENT_FQDN_FLAGS_O) 1082172686Smlaier buf[i++] = 'O'; 1083172686Smlaier if (flags & CLIENT_FQDN_FLAGS_E) 1084172686Smlaier buf[i++] = 'E'; 1085172686Smlaier if (flags & CLIENT_FQDN_FLAGS_N) 1086172686Smlaier buf[i++] = 'N'; 1087172686Smlaier buf[i] = '\0'; 1088172686Smlaier 1089172686Smlaier return buf; 1090172686Smlaier} 1091