1*d04ccbb3Scarlsonj /* 2*d04ccbb3Scarlsonj * CDDL HEADER START 3*d04ccbb3Scarlsonj * 4*d04ccbb3Scarlsonj * The contents of this file are subject to the terms of the 5*d04ccbb3Scarlsonj * Common Development and Distribution License (the "License"). 6*d04ccbb3Scarlsonj * You may not use this file except in compliance with the License. 7*d04ccbb3Scarlsonj * 8*d04ccbb3Scarlsonj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*d04ccbb3Scarlsonj * or http://www.opensolaris.org/os/licensing. 10*d04ccbb3Scarlsonj * See the License for the specific language governing permissions 11*d04ccbb3Scarlsonj * and limitations under the License. 12*d04ccbb3Scarlsonj * 13*d04ccbb3Scarlsonj * When distributing Covered Code, include this CDDL HEADER in each 14*d04ccbb3Scarlsonj * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*d04ccbb3Scarlsonj * If applicable, add the following below this CDDL HEADER, with the 16*d04ccbb3Scarlsonj * fields enclosed by brackets "[]" replaced with your own identifying 17*d04ccbb3Scarlsonj * information: Portions Copyright [yyyy] [name of copyright owner] 18*d04ccbb3Scarlsonj * 19*d04ccbb3Scarlsonj * CDDL HEADER END 20*d04ccbb3Scarlsonj */ 21*d04ccbb3Scarlsonj 22*d04ccbb3Scarlsonj /* 23*d04ccbb3Scarlsonj * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*d04ccbb3Scarlsonj * Use is subject to license terms. 25*d04ccbb3Scarlsonj */ 26*d04ccbb3Scarlsonj 27*d04ccbb3Scarlsonj #pragma ident "%Z%%M% %I% %E% SMI" 28*d04ccbb3Scarlsonj 29*d04ccbb3Scarlsonj /* 30*d04ccbb3Scarlsonj * Dynamic Host Configuration Protocol version 6, for IPv6. Supports 31*d04ccbb3Scarlsonj * RFCs 3315, 3319, 3646, 3898, 4075, 4242, 4280, 4580, 4649, and 4704. 32*d04ccbb3Scarlsonj */ 33*d04ccbb3Scarlsonj 34*d04ccbb3Scarlsonj #include <stdio.h> 35*d04ccbb3Scarlsonj #include <stdlib.h> 36*d04ccbb3Scarlsonj #include <string.h> 37*d04ccbb3Scarlsonj #include <time.h> 38*d04ccbb3Scarlsonj #include <sys/types.h> 39*d04ccbb3Scarlsonj #include <sys/socket.h> 40*d04ccbb3Scarlsonj #include <netinet/in.h> 41*d04ccbb3Scarlsonj #include <netinet/dhcp6.h> 42*d04ccbb3Scarlsonj #include <arpa/inet.h> 43*d04ccbb3Scarlsonj #include <dhcp_impl.h> 44*d04ccbb3Scarlsonj #include <dhcp_inittab.h> 45*d04ccbb3Scarlsonj 46*d04ccbb3Scarlsonj #include "snoop.h" 47*d04ccbb3Scarlsonj 48*d04ccbb3Scarlsonj static const char *mtype_to_str(uint8_t); 49*d04ccbb3Scarlsonj static const char *option_to_str(uint8_t); 50*d04ccbb3Scarlsonj static const char *duidtype_to_str(uint16_t); 51*d04ccbb3Scarlsonj static const char *status_to_str(uint16_t); 52*d04ccbb3Scarlsonj static const char *entr_to_str(uint32_t); 53*d04ccbb3Scarlsonj static const char *reconf_to_str(uint8_t); 54*d04ccbb3Scarlsonj static const char *authproto_to_str(uint8_t); 55*d04ccbb3Scarlsonj static const char *authalg_to_str(uint8_t, uint8_t); 56*d04ccbb3Scarlsonj static const char *authrdm_to_str(uint8_t); 57*d04ccbb3Scarlsonj static const char *cwhat_to_str(uint8_t); 58*d04ccbb3Scarlsonj static const char *catype_to_str(uint8_t); 59*d04ccbb3Scarlsonj static void show_hex(const uint8_t *, int, const char *); 60*d04ccbb3Scarlsonj static void show_ascii(const uint8_t *, int, const char *); 61*d04ccbb3Scarlsonj static void show_address(const char *, const void *); 62*d04ccbb3Scarlsonj static void show_options(const uint8_t *, int); 63*d04ccbb3Scarlsonj 64*d04ccbb3Scarlsonj int 65*d04ccbb3Scarlsonj interpret_dhcpv6(int flags, const uint8_t *data, int len) 66*d04ccbb3Scarlsonj { 67*d04ccbb3Scarlsonj int olen = len; 68*d04ccbb3Scarlsonj char *line, *lstart; 69*d04ccbb3Scarlsonj dhcpv6_relay_t d6r; 70*d04ccbb3Scarlsonj dhcpv6_message_t d6m; 71*d04ccbb3Scarlsonj uint_t optlen; 72*d04ccbb3Scarlsonj uint16_t statuscode; 73*d04ccbb3Scarlsonj 74*d04ccbb3Scarlsonj if (len <= 0) { 75*d04ccbb3Scarlsonj (void) strlcpy(get_sum_line(), "DHCPv6?", MAXLINE); 76*d04ccbb3Scarlsonj return (0); 77*d04ccbb3Scarlsonj } 78*d04ccbb3Scarlsonj if (flags & F_SUM) { 79*d04ccbb3Scarlsonj uint_t ias; 80*d04ccbb3Scarlsonj dhcpv6_option_t *d6o; 81*d04ccbb3Scarlsonj in6_addr_t link, peer; 82*d04ccbb3Scarlsonj char linkstr[INET6_ADDRSTRLEN]; 83*d04ccbb3Scarlsonj char peerstr[INET6_ADDRSTRLEN]; 84*d04ccbb3Scarlsonj 85*d04ccbb3Scarlsonj line = lstart = get_sum_line(); 86*d04ccbb3Scarlsonj line += snprintf(line, MAXLINE, "DHCPv6 %s", 87*d04ccbb3Scarlsonj mtype_to_str(data[0])); 88*d04ccbb3Scarlsonj if (data[0] == DHCPV6_MSG_RELAY_FORW || 89*d04ccbb3Scarlsonj data[0] == DHCPV6_MSG_RELAY_REPL) { 90*d04ccbb3Scarlsonj if (len < sizeof (d6r)) { 91*d04ccbb3Scarlsonj (void) strlcpy(line, "?", 92*d04ccbb3Scarlsonj MAXLINE - (line - lstart)); 93*d04ccbb3Scarlsonj return (olen); 94*d04ccbb3Scarlsonj } 95*d04ccbb3Scarlsonj /* Not much in DHCPv6 is aligned. */ 96*d04ccbb3Scarlsonj (void) memcpy(&d6r, data, sizeof (d6r)); 97*d04ccbb3Scarlsonj (void) memcpy(&link, d6r.d6r_linkaddr, sizeof (link)); 98*d04ccbb3Scarlsonj (void) memcpy(&peer, d6r.d6r_peeraddr, sizeof (peer)); 99*d04ccbb3Scarlsonj line += snprintf(line, MAXLINE - (line - lstart), 100*d04ccbb3Scarlsonj " HC=%d link=%s peer=%s", d6r.d6r_hop_count, 101*d04ccbb3Scarlsonj inet_ntop(AF_INET6, &link, linkstr, 102*d04ccbb3Scarlsonj sizeof (linkstr)), 103*d04ccbb3Scarlsonj inet_ntop(AF_INET6, &peer, peerstr, 104*d04ccbb3Scarlsonj sizeof (peerstr))); 105*d04ccbb3Scarlsonj data += sizeof (d6r); 106*d04ccbb3Scarlsonj len -= sizeof (d6r); 107*d04ccbb3Scarlsonj } else { 108*d04ccbb3Scarlsonj if (len < sizeof (d6m)) { 109*d04ccbb3Scarlsonj (void) strlcpy(line, "?", 110*d04ccbb3Scarlsonj MAXLINE - (line - lstart)); 111*d04ccbb3Scarlsonj return (olen); 112*d04ccbb3Scarlsonj } 113*d04ccbb3Scarlsonj (void) memcpy(&d6m, data, sizeof (d6m)); 114*d04ccbb3Scarlsonj line += snprintf(line, MAXLINE - (line - lstart), 115*d04ccbb3Scarlsonj " xid=%x", DHCPV6_GET_TRANSID(&d6m)); 116*d04ccbb3Scarlsonj data += sizeof (d6m); 117*d04ccbb3Scarlsonj len -= sizeof (d6m); 118*d04ccbb3Scarlsonj } 119*d04ccbb3Scarlsonj ias = 0; 120*d04ccbb3Scarlsonj d6o = NULL; 121*d04ccbb3Scarlsonj while ((d6o = dhcpv6_find_option(data, len, d6o, 122*d04ccbb3Scarlsonj DHCPV6_OPT_IA_NA, NULL)) != NULL) 123*d04ccbb3Scarlsonj ias++; 124*d04ccbb3Scarlsonj if (ias > 0) 125*d04ccbb3Scarlsonj line += snprintf(line, MAXLINE - (line - lstart), 126*d04ccbb3Scarlsonj " IAs=%u", ias); 127*d04ccbb3Scarlsonj d6o = dhcpv6_find_option(data, len, NULL, 128*d04ccbb3Scarlsonj DHCPV6_OPT_STATUS_CODE, &optlen); 129*d04ccbb3Scarlsonj optlen -= sizeof (*d6o); 130*d04ccbb3Scarlsonj if (d6o != NULL && optlen >= sizeof (statuscode)) { 131*d04ccbb3Scarlsonj (void) memcpy(&statuscode, d6o + 1, 132*d04ccbb3Scarlsonj sizeof (statuscode)); 133*d04ccbb3Scarlsonj line += snprintf(line, MAXLINE - (line - lstart), 134*d04ccbb3Scarlsonj " status=%u", ntohs(statuscode)); 135*d04ccbb3Scarlsonj optlen -= sizeof (statuscode); 136*d04ccbb3Scarlsonj if (optlen > 0) { 137*d04ccbb3Scarlsonj line += snprintf(line, 138*d04ccbb3Scarlsonj MAXLINE - (line - lstart), " \"%.*s\"", 139*d04ccbb3Scarlsonj optlen, (char *)(d6o + 1) + 2); 140*d04ccbb3Scarlsonj } 141*d04ccbb3Scarlsonj } 142*d04ccbb3Scarlsonj d6o = dhcpv6_find_option(data, len, NULL, 143*d04ccbb3Scarlsonj DHCPV6_OPT_RELAY_MSG, &optlen); 144*d04ccbb3Scarlsonj optlen -= sizeof (*d6o); 145*d04ccbb3Scarlsonj if (d6o != NULL && optlen >= 1) { 146*d04ccbb3Scarlsonj line += snprintf(line, MAXLINE - (line - lstart), 147*d04ccbb3Scarlsonj " relay=%s", mtype_to_str(*(uint8_t *)(d6o + 1))); 148*d04ccbb3Scarlsonj } 149*d04ccbb3Scarlsonj } else if (flags & F_DTAIL) { 150*d04ccbb3Scarlsonj show_header("DHCPv6: ", 151*d04ccbb3Scarlsonj "Dynamic Host Configuration Protocol Version 6", len); 152*d04ccbb3Scarlsonj show_space(); 153*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 154*d04ccbb3Scarlsonj "Message type (msg-type) = %u (%s)", data[0], 155*d04ccbb3Scarlsonj mtype_to_str(data[0])); 156*d04ccbb3Scarlsonj if (data[0] == DHCPV6_MSG_RELAY_FORW || 157*d04ccbb3Scarlsonj data[0] == DHCPV6_MSG_RELAY_REPL) { 158*d04ccbb3Scarlsonj if (len < sizeof (d6r)) { 159*d04ccbb3Scarlsonj (void) strlcpy(get_line(0, 0), "Truncated", 160*d04ccbb3Scarlsonj get_line_remain()); 161*d04ccbb3Scarlsonj return (olen); 162*d04ccbb3Scarlsonj } 163*d04ccbb3Scarlsonj (void) memcpy(&d6r, data, sizeof (d6r)); 164*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 165*d04ccbb3Scarlsonj "Hop count = %u", d6r.d6r_hop_count); 166*d04ccbb3Scarlsonj show_address("Link address", d6r.d6r_linkaddr); 167*d04ccbb3Scarlsonj show_address("Peer address", d6r.d6r_peeraddr); 168*d04ccbb3Scarlsonj data += sizeof (d6r); 169*d04ccbb3Scarlsonj len -= sizeof (d6r); 170*d04ccbb3Scarlsonj } else { 171*d04ccbb3Scarlsonj if (len < sizeof (d6m)) { 172*d04ccbb3Scarlsonj (void) strlcpy(get_line(0, 0), "Truncated", 173*d04ccbb3Scarlsonj get_line_remain()); 174*d04ccbb3Scarlsonj return (olen); 175*d04ccbb3Scarlsonj } 176*d04ccbb3Scarlsonj (void) memcpy(&d6m, data, sizeof (d6m)); 177*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 178*d04ccbb3Scarlsonj "Transaction ID = %x", DHCPV6_GET_TRANSID(&d6m)); 179*d04ccbb3Scarlsonj data += sizeof (d6m); 180*d04ccbb3Scarlsonj len -= sizeof (d6m); 181*d04ccbb3Scarlsonj } 182*d04ccbb3Scarlsonj show_space(); 183*d04ccbb3Scarlsonj show_options(data, len); 184*d04ccbb3Scarlsonj show_space(); 185*d04ccbb3Scarlsonj } 186*d04ccbb3Scarlsonj return (olen); 187*d04ccbb3Scarlsonj } 188*d04ccbb3Scarlsonj 189*d04ccbb3Scarlsonj static const char * 190*d04ccbb3Scarlsonj mtype_to_str(uint8_t mtype) 191*d04ccbb3Scarlsonj { 192*d04ccbb3Scarlsonj switch (mtype) { 193*d04ccbb3Scarlsonj case DHCPV6_MSG_SOLICIT: 194*d04ccbb3Scarlsonj return ("Solicit"); 195*d04ccbb3Scarlsonj case DHCPV6_MSG_ADVERTISE: 196*d04ccbb3Scarlsonj return ("Advertise"); 197*d04ccbb3Scarlsonj case DHCPV6_MSG_REQUEST: 198*d04ccbb3Scarlsonj return ("Request"); 199*d04ccbb3Scarlsonj case DHCPV6_MSG_CONFIRM: 200*d04ccbb3Scarlsonj return ("Confirm"); 201*d04ccbb3Scarlsonj case DHCPV6_MSG_RENEW: 202*d04ccbb3Scarlsonj return ("Renew"); 203*d04ccbb3Scarlsonj case DHCPV6_MSG_REBIND: 204*d04ccbb3Scarlsonj return ("Rebind"); 205*d04ccbb3Scarlsonj case DHCPV6_MSG_REPLY: 206*d04ccbb3Scarlsonj return ("Reply"); 207*d04ccbb3Scarlsonj case DHCPV6_MSG_RELEASE: 208*d04ccbb3Scarlsonj return ("Release"); 209*d04ccbb3Scarlsonj case DHCPV6_MSG_DECLINE: 210*d04ccbb3Scarlsonj return ("Decline"); 211*d04ccbb3Scarlsonj case DHCPV6_MSG_RECONFIGURE: 212*d04ccbb3Scarlsonj return ("Reconfigure"); 213*d04ccbb3Scarlsonj case DHCPV6_MSG_INFO_REQ: 214*d04ccbb3Scarlsonj return ("Information-Request"); 215*d04ccbb3Scarlsonj case DHCPV6_MSG_RELAY_FORW: 216*d04ccbb3Scarlsonj return ("Relay-Forward"); 217*d04ccbb3Scarlsonj case DHCPV6_MSG_RELAY_REPL: 218*d04ccbb3Scarlsonj return ("Relay-Reply"); 219*d04ccbb3Scarlsonj default: 220*d04ccbb3Scarlsonj return ("Unknown"); 221*d04ccbb3Scarlsonj } 222*d04ccbb3Scarlsonj } 223*d04ccbb3Scarlsonj 224*d04ccbb3Scarlsonj static const char * 225*d04ccbb3Scarlsonj option_to_str(uint8_t mtype) 226*d04ccbb3Scarlsonj { 227*d04ccbb3Scarlsonj switch (mtype) { 228*d04ccbb3Scarlsonj case DHCPV6_OPT_CLIENTID: 229*d04ccbb3Scarlsonj return ("Client Identifier"); 230*d04ccbb3Scarlsonj case DHCPV6_OPT_SERVERID: 231*d04ccbb3Scarlsonj return ("Server Identifier"); 232*d04ccbb3Scarlsonj case DHCPV6_OPT_IA_NA: 233*d04ccbb3Scarlsonj return ("Identity Association for Non-temporary Addresses"); 234*d04ccbb3Scarlsonj case DHCPV6_OPT_IA_TA: 235*d04ccbb3Scarlsonj return ("Identity Association for Temporary Addresses"); 236*d04ccbb3Scarlsonj case DHCPV6_OPT_IAADDR: 237*d04ccbb3Scarlsonj return ("IA Address"); 238*d04ccbb3Scarlsonj case DHCPV6_OPT_ORO: 239*d04ccbb3Scarlsonj return ("Option Request"); 240*d04ccbb3Scarlsonj case DHCPV6_OPT_PREFERENCE: 241*d04ccbb3Scarlsonj return ("Preference"); 242*d04ccbb3Scarlsonj case DHCPV6_OPT_ELAPSED_TIME: 243*d04ccbb3Scarlsonj return ("Elapsed Time"); 244*d04ccbb3Scarlsonj case DHCPV6_OPT_RELAY_MSG: 245*d04ccbb3Scarlsonj return ("Relay Message"); 246*d04ccbb3Scarlsonj case DHCPV6_OPT_AUTH: 247*d04ccbb3Scarlsonj return ("Authentication"); 248*d04ccbb3Scarlsonj case DHCPV6_OPT_UNICAST: 249*d04ccbb3Scarlsonj return ("Server Unicast"); 250*d04ccbb3Scarlsonj case DHCPV6_OPT_STATUS_CODE: 251*d04ccbb3Scarlsonj return ("Status Code"); 252*d04ccbb3Scarlsonj case DHCPV6_OPT_RAPID_COMMIT: 253*d04ccbb3Scarlsonj return ("Rapid Commit"); 254*d04ccbb3Scarlsonj case DHCPV6_OPT_USER_CLASS: 255*d04ccbb3Scarlsonj return ("User Class"); 256*d04ccbb3Scarlsonj case DHCPV6_OPT_VENDOR_CLASS: 257*d04ccbb3Scarlsonj return ("Vendor Class"); 258*d04ccbb3Scarlsonj case DHCPV6_OPT_VENDOR_OPT: 259*d04ccbb3Scarlsonj return ("Vendor-specific Information"); 260*d04ccbb3Scarlsonj case DHCPV6_OPT_INTERFACE_ID: 261*d04ccbb3Scarlsonj return ("Interface-Id"); 262*d04ccbb3Scarlsonj case DHCPV6_OPT_RECONF_MSG: 263*d04ccbb3Scarlsonj return ("Reconfigure Message"); 264*d04ccbb3Scarlsonj case DHCPV6_OPT_RECONF_ACC: 265*d04ccbb3Scarlsonj return ("Reconfigure Accept"); 266*d04ccbb3Scarlsonj case DHCPV6_OPT_SIP_NAMES: 267*d04ccbb3Scarlsonj return ("SIP Servers Domain Name List"); 268*d04ccbb3Scarlsonj case DHCPV6_OPT_SIP_ADDR: 269*d04ccbb3Scarlsonj return ("SIP Servers IPv6 Address List"); 270*d04ccbb3Scarlsonj case DHCPV6_OPT_DNS_ADDR: 271*d04ccbb3Scarlsonj return ("DNS Recursive Name Server"); 272*d04ccbb3Scarlsonj case DHCPV6_OPT_DNS_SEARCH: 273*d04ccbb3Scarlsonj return ("Domain Search List"); 274*d04ccbb3Scarlsonj case DHCPV6_OPT_IA_PD: 275*d04ccbb3Scarlsonj return ("Identity Association for Prefix Delegation"); 276*d04ccbb3Scarlsonj case DHCPV6_OPT_IAPREFIX: 277*d04ccbb3Scarlsonj return ("IA_PD Prefix"); 278*d04ccbb3Scarlsonj case DHCPV6_OPT_NIS_SERVERS: 279*d04ccbb3Scarlsonj return ("Network Information Service Servers"); 280*d04ccbb3Scarlsonj case DHCPV6_OPT_NISP_SERVERS: 281*d04ccbb3Scarlsonj return ("Network Information Service V2 Servers"); 282*d04ccbb3Scarlsonj case DHCPV6_OPT_NIS_DOMAIN: 283*d04ccbb3Scarlsonj return ("Network Information Service Domain Name"); 284*d04ccbb3Scarlsonj case DHCPV6_OPT_NISP_DOMAIN: 285*d04ccbb3Scarlsonj return ("Network Information Service V2 Domain Name"); 286*d04ccbb3Scarlsonj case DHCPV6_OPT_SNTP_SERVERS: 287*d04ccbb3Scarlsonj return ("Simple Network Time Protocol Servers"); 288*d04ccbb3Scarlsonj case DHCPV6_OPT_INFO_REFTIME: 289*d04ccbb3Scarlsonj return ("Information Refresh Time"); 290*d04ccbb3Scarlsonj case DHCPV6_OPT_BCMCS_SRV_D: 291*d04ccbb3Scarlsonj return ("BCMCS Controller Domain Name List"); 292*d04ccbb3Scarlsonj case DHCPV6_OPT_BCMCS_SRV_A: 293*d04ccbb3Scarlsonj return ("BCMCS Controller IPv6 Address"); 294*d04ccbb3Scarlsonj case DHCPV6_OPT_GEOCONF_CVC: 295*d04ccbb3Scarlsonj return ("Civic Location"); 296*d04ccbb3Scarlsonj case DHCPV6_OPT_REMOTE_ID: 297*d04ccbb3Scarlsonj return ("Relay Agent Remote-ID"); 298*d04ccbb3Scarlsonj case DHCPV6_OPT_SUBSCRIBER: 299*d04ccbb3Scarlsonj return ("Relay Agent Subscriber-ID"); 300*d04ccbb3Scarlsonj case DHCPV6_OPT_CLIENT_FQDN: 301*d04ccbb3Scarlsonj return ("Client FQDN"); 302*d04ccbb3Scarlsonj default: 303*d04ccbb3Scarlsonj return ("Unknown"); 304*d04ccbb3Scarlsonj } 305*d04ccbb3Scarlsonj } 306*d04ccbb3Scarlsonj 307*d04ccbb3Scarlsonj static const char * 308*d04ccbb3Scarlsonj duidtype_to_str(uint16_t dtype) 309*d04ccbb3Scarlsonj { 310*d04ccbb3Scarlsonj switch (dtype) { 311*d04ccbb3Scarlsonj case DHCPV6_DUID_LLT: 312*d04ccbb3Scarlsonj return ("Link-layer Address Plus Time"); 313*d04ccbb3Scarlsonj case DHCPV6_DUID_EN: 314*d04ccbb3Scarlsonj return ("Enterprise Number"); 315*d04ccbb3Scarlsonj case DHCPV6_DUID_LL: 316*d04ccbb3Scarlsonj return ("Link-layer Address"); 317*d04ccbb3Scarlsonj default: 318*d04ccbb3Scarlsonj return ("Unknown"); 319*d04ccbb3Scarlsonj } 320*d04ccbb3Scarlsonj } 321*d04ccbb3Scarlsonj 322*d04ccbb3Scarlsonj static const char * 323*d04ccbb3Scarlsonj status_to_str(uint16_t status) 324*d04ccbb3Scarlsonj { 325*d04ccbb3Scarlsonj switch (status) { 326*d04ccbb3Scarlsonj case DHCPV6_STAT_SUCCESS: 327*d04ccbb3Scarlsonj return ("Success"); 328*d04ccbb3Scarlsonj case DHCPV6_STAT_UNSPECFAIL: 329*d04ccbb3Scarlsonj return ("Failure, reason unspecified"); 330*d04ccbb3Scarlsonj case DHCPV6_STAT_NOADDRS: 331*d04ccbb3Scarlsonj return ("No addresses for IAs"); 332*d04ccbb3Scarlsonj case DHCPV6_STAT_NOBINDING: 333*d04ccbb3Scarlsonj return ("Client binding unavailable"); 334*d04ccbb3Scarlsonj case DHCPV6_STAT_NOTONLINK: 335*d04ccbb3Scarlsonj return ("Prefix not on link"); 336*d04ccbb3Scarlsonj case DHCPV6_STAT_USEMCAST: 337*d04ccbb3Scarlsonj return ("Use multicast"); 338*d04ccbb3Scarlsonj case DHCPV6_STAT_NOPREFIX: 339*d04ccbb3Scarlsonj return ("No prefix available"); 340*d04ccbb3Scarlsonj default: 341*d04ccbb3Scarlsonj return ("Unknown"); 342*d04ccbb3Scarlsonj } 343*d04ccbb3Scarlsonj } 344*d04ccbb3Scarlsonj 345*d04ccbb3Scarlsonj static const char * 346*d04ccbb3Scarlsonj entr_to_str(uint32_t entr) 347*d04ccbb3Scarlsonj { 348*d04ccbb3Scarlsonj switch (entr) { 349*d04ccbb3Scarlsonj case DHCPV6_SUN_ENT: 350*d04ccbb3Scarlsonj return ("Sun Microsystems"); 351*d04ccbb3Scarlsonj default: 352*d04ccbb3Scarlsonj return ("Unknown"); 353*d04ccbb3Scarlsonj } 354*d04ccbb3Scarlsonj } 355*d04ccbb3Scarlsonj 356*d04ccbb3Scarlsonj static const char * 357*d04ccbb3Scarlsonj reconf_to_str(uint8_t msgtype) 358*d04ccbb3Scarlsonj { 359*d04ccbb3Scarlsonj switch (msgtype) { 360*d04ccbb3Scarlsonj case DHCPV6_RECONF_RENEW: 361*d04ccbb3Scarlsonj return ("Renew"); 362*d04ccbb3Scarlsonj case DHCPV6_RECONF_INFO: 363*d04ccbb3Scarlsonj return ("Information-request"); 364*d04ccbb3Scarlsonj default: 365*d04ccbb3Scarlsonj return ("Unknown"); 366*d04ccbb3Scarlsonj } 367*d04ccbb3Scarlsonj } 368*d04ccbb3Scarlsonj 369*d04ccbb3Scarlsonj static const char * 370*d04ccbb3Scarlsonj authproto_to_str(uint8_t aproto) 371*d04ccbb3Scarlsonj { 372*d04ccbb3Scarlsonj switch (aproto) { 373*d04ccbb3Scarlsonj case DHCPV6_PROTO_DELAYED: 374*d04ccbb3Scarlsonj return ("Delayed"); 375*d04ccbb3Scarlsonj case DHCPV6_PROTO_RECONFIG: 376*d04ccbb3Scarlsonj return ("Reconfigure Key"); 377*d04ccbb3Scarlsonj default: 378*d04ccbb3Scarlsonj return ("Unknown"); 379*d04ccbb3Scarlsonj } 380*d04ccbb3Scarlsonj } 381*d04ccbb3Scarlsonj 382*d04ccbb3Scarlsonj static const char * 383*d04ccbb3Scarlsonj authalg_to_str(uint8_t aproto, uint8_t aalg) 384*d04ccbb3Scarlsonj { 385*d04ccbb3Scarlsonj switch (aproto) { 386*d04ccbb3Scarlsonj case DHCPV6_PROTO_DELAYED: 387*d04ccbb3Scarlsonj case DHCPV6_PROTO_RECONFIG: 388*d04ccbb3Scarlsonj switch (aalg) { 389*d04ccbb3Scarlsonj case DHCPV6_ALG_HMAC_MD5: 390*d04ccbb3Scarlsonj return ("HMAC-MD5 Signature"); 391*d04ccbb3Scarlsonj default: 392*d04ccbb3Scarlsonj return ("Unknown"); 393*d04ccbb3Scarlsonj } 394*d04ccbb3Scarlsonj break; 395*d04ccbb3Scarlsonj default: 396*d04ccbb3Scarlsonj return ("Unknown"); 397*d04ccbb3Scarlsonj } 398*d04ccbb3Scarlsonj } 399*d04ccbb3Scarlsonj 400*d04ccbb3Scarlsonj static const char * 401*d04ccbb3Scarlsonj authrdm_to_str(uint8_t ardm) 402*d04ccbb3Scarlsonj { 403*d04ccbb3Scarlsonj switch (ardm) { 404*d04ccbb3Scarlsonj case DHCPV6_RDM_MONOCNT: 405*d04ccbb3Scarlsonj return ("Monotonic Counter"); 406*d04ccbb3Scarlsonj default: 407*d04ccbb3Scarlsonj return ("Unknown"); 408*d04ccbb3Scarlsonj } 409*d04ccbb3Scarlsonj } 410*d04ccbb3Scarlsonj 411*d04ccbb3Scarlsonj static const char * 412*d04ccbb3Scarlsonj cwhat_to_str(uint8_t what) 413*d04ccbb3Scarlsonj { 414*d04ccbb3Scarlsonj switch (what) { 415*d04ccbb3Scarlsonj case DHCPV6_CWHAT_SERVER: 416*d04ccbb3Scarlsonj return ("Server"); 417*d04ccbb3Scarlsonj case DHCPV6_CWHAT_NETWORK: 418*d04ccbb3Scarlsonj return ("Network"); 419*d04ccbb3Scarlsonj case DHCPV6_CWHAT_CLIENT: 420*d04ccbb3Scarlsonj return ("Client"); 421*d04ccbb3Scarlsonj default: 422*d04ccbb3Scarlsonj return ("Unknown"); 423*d04ccbb3Scarlsonj } 424*d04ccbb3Scarlsonj } 425*d04ccbb3Scarlsonj 426*d04ccbb3Scarlsonj static const char * 427*d04ccbb3Scarlsonj catype_to_str(uint8_t catype) 428*d04ccbb3Scarlsonj { 429*d04ccbb3Scarlsonj switch (catype) { 430*d04ccbb3Scarlsonj case CIVICADDR_LANG: 431*d04ccbb3Scarlsonj return ("Language; RFC 2277"); 432*d04ccbb3Scarlsonj case CIVICADDR_A1: 433*d04ccbb3Scarlsonj return ("National division (state)"); 434*d04ccbb3Scarlsonj case CIVICADDR_A2: 435*d04ccbb3Scarlsonj return ("County"); 436*d04ccbb3Scarlsonj case CIVICADDR_A3: 437*d04ccbb3Scarlsonj return ("City"); 438*d04ccbb3Scarlsonj case CIVICADDR_A4: 439*d04ccbb3Scarlsonj return ("City division"); 440*d04ccbb3Scarlsonj case CIVICADDR_A5: 441*d04ccbb3Scarlsonj return ("Neighborhood"); 442*d04ccbb3Scarlsonj case CIVICADDR_A6: 443*d04ccbb3Scarlsonj return ("Street group"); 444*d04ccbb3Scarlsonj case CIVICADDR_PRD: 445*d04ccbb3Scarlsonj return ("Leading street direction"); 446*d04ccbb3Scarlsonj case CIVICADDR_POD: 447*d04ccbb3Scarlsonj return ("Trailing street suffix"); 448*d04ccbb3Scarlsonj case CIVICADDR_STS: 449*d04ccbb3Scarlsonj return ("Street suffix or type"); 450*d04ccbb3Scarlsonj case CIVICADDR_HNO: 451*d04ccbb3Scarlsonj return ("House number"); 452*d04ccbb3Scarlsonj case CIVICADDR_HNS: 453*d04ccbb3Scarlsonj return ("House number suffix"); 454*d04ccbb3Scarlsonj case CIVICADDR_LMK: 455*d04ccbb3Scarlsonj return ("Landmark"); 456*d04ccbb3Scarlsonj case CIVICADDR_LOC: 457*d04ccbb3Scarlsonj return ("Additional location information"); 458*d04ccbb3Scarlsonj case CIVICADDR_NAM: 459*d04ccbb3Scarlsonj return ("Name/occupant"); 460*d04ccbb3Scarlsonj case CIVICADDR_PC: 461*d04ccbb3Scarlsonj return ("Postal Code/ZIP"); 462*d04ccbb3Scarlsonj case CIVICADDR_BLD: 463*d04ccbb3Scarlsonj return ("Building"); 464*d04ccbb3Scarlsonj case CIVICADDR_UNIT: 465*d04ccbb3Scarlsonj return ("Unit/apt/suite"); 466*d04ccbb3Scarlsonj case CIVICADDR_FLR: 467*d04ccbb3Scarlsonj return ("Floor"); 468*d04ccbb3Scarlsonj case CIVICADDR_ROOM: 469*d04ccbb3Scarlsonj return ("Room number"); 470*d04ccbb3Scarlsonj case CIVICADDR_TYPE: 471*d04ccbb3Scarlsonj return ("Place type"); 472*d04ccbb3Scarlsonj case CIVICADDR_PCN: 473*d04ccbb3Scarlsonj return ("Postal community name"); 474*d04ccbb3Scarlsonj case CIVICADDR_POBOX: 475*d04ccbb3Scarlsonj return ("Post office box"); 476*d04ccbb3Scarlsonj case CIVICADDR_ADDL: 477*d04ccbb3Scarlsonj return ("Additional code"); 478*d04ccbb3Scarlsonj case CIVICADDR_SEAT: 479*d04ccbb3Scarlsonj return ("Seat/desk"); 480*d04ccbb3Scarlsonj case CIVICADDR_ROAD: 481*d04ccbb3Scarlsonj return ("Primary road or street"); 482*d04ccbb3Scarlsonj case CIVICADDR_RSEC: 483*d04ccbb3Scarlsonj return ("Road section"); 484*d04ccbb3Scarlsonj case CIVICADDR_RBRA: 485*d04ccbb3Scarlsonj return ("Road branch"); 486*d04ccbb3Scarlsonj case CIVICADDR_RSBR: 487*d04ccbb3Scarlsonj return ("Road sub-branch"); 488*d04ccbb3Scarlsonj case CIVICADDR_SPRE: 489*d04ccbb3Scarlsonj return ("Street name pre-modifier"); 490*d04ccbb3Scarlsonj case CIVICADDR_SPOST: 491*d04ccbb3Scarlsonj return ("Street name post-modifier"); 492*d04ccbb3Scarlsonj case CIVICADDR_SCRIPT: 493*d04ccbb3Scarlsonj return ("Script"); 494*d04ccbb3Scarlsonj default: 495*d04ccbb3Scarlsonj return ("Unknown"); 496*d04ccbb3Scarlsonj } 497*d04ccbb3Scarlsonj } 498*d04ccbb3Scarlsonj 499*d04ccbb3Scarlsonj static void 500*d04ccbb3Scarlsonj show_hex(const uint8_t *data, int len, const char *name) 501*d04ccbb3Scarlsonj { 502*d04ccbb3Scarlsonj char buffer[16 * 3 + 1]; 503*d04ccbb3Scarlsonj int nlen; 504*d04ccbb3Scarlsonj int i; 505*d04ccbb3Scarlsonj char sep; 506*d04ccbb3Scarlsonj 507*d04ccbb3Scarlsonj nlen = strlen(name); 508*d04ccbb3Scarlsonj sep = '='; 509*d04ccbb3Scarlsonj while (len > 0) { 510*d04ccbb3Scarlsonj for (i = 0; i < 16 && i < len; i++) 511*d04ccbb3Scarlsonj (void) snprintf(buffer + 3 * i, 4, " %02x", *data++); 512*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), "%*s %c%s", 513*d04ccbb3Scarlsonj nlen, name, sep, buffer); 514*d04ccbb3Scarlsonj name = ""; 515*d04ccbb3Scarlsonj sep = ' '; 516*d04ccbb3Scarlsonj len -= i; 517*d04ccbb3Scarlsonj } 518*d04ccbb3Scarlsonj } 519*d04ccbb3Scarlsonj 520*d04ccbb3Scarlsonj static void 521*d04ccbb3Scarlsonj show_ascii(const uint8_t *data, int len, const char *name) 522*d04ccbb3Scarlsonj { 523*d04ccbb3Scarlsonj char buffer[64], *bp; 524*d04ccbb3Scarlsonj int nlen; 525*d04ccbb3Scarlsonj int i; 526*d04ccbb3Scarlsonj char sep; 527*d04ccbb3Scarlsonj 528*d04ccbb3Scarlsonj nlen = strlen(name); 529*d04ccbb3Scarlsonj sep = '='; 530*d04ccbb3Scarlsonj while (len > 0) { 531*d04ccbb3Scarlsonj bp = buffer; 532*d04ccbb3Scarlsonj for (i = 0; i < sizeof (buffer) - 4 && len > 0; len--) { 533*d04ccbb3Scarlsonj if (!isascii(*data) || !isprint(*data)) 534*d04ccbb3Scarlsonj bp += snprintf(bp, 5, "\\%03o", *data++); 535*d04ccbb3Scarlsonj else 536*d04ccbb3Scarlsonj *bp++; 537*d04ccbb3Scarlsonj } 538*d04ccbb3Scarlsonj *bp = '\0'; 539*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 540*d04ccbb3Scarlsonj "%*s %c \"%s\"", nlen, name, sep, buffer); 541*d04ccbb3Scarlsonj sep = ' '; 542*d04ccbb3Scarlsonj name = ""; 543*d04ccbb3Scarlsonj } 544*d04ccbb3Scarlsonj } 545*d04ccbb3Scarlsonj 546*d04ccbb3Scarlsonj static void 547*d04ccbb3Scarlsonj show_address(const char *addrname, const void *aptr) 548*d04ccbb3Scarlsonj { 549*d04ccbb3Scarlsonj char *hname; 550*d04ccbb3Scarlsonj char addrstr[INET6_ADDRSTRLEN]; 551*d04ccbb3Scarlsonj in6_addr_t addr; 552*d04ccbb3Scarlsonj 553*d04ccbb3Scarlsonj (void) memcpy(&addr, aptr, sizeof (in6_addr_t)); 554*d04ccbb3Scarlsonj (void) inet_ntop(AF_INET6, &addr, addrstr, sizeof (addrstr)); 555*d04ccbb3Scarlsonj hname = addrtoname(AF_INET6, &addr); 556*d04ccbb3Scarlsonj if (strcmp(hname, addrstr) == 0) { 557*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), "%s = %s", 558*d04ccbb3Scarlsonj addrname, addrstr); 559*d04ccbb3Scarlsonj } else { 560*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 561*d04ccbb3Scarlsonj "%s = %s (%s)", addrname, addrstr, hname); 562*d04ccbb3Scarlsonj } 563*d04ccbb3Scarlsonj } 564*d04ccbb3Scarlsonj 565*d04ccbb3Scarlsonj static void 566*d04ccbb3Scarlsonj nest_options(const uint8_t *data, uint_t olen, char *prefix, char *title) 567*d04ccbb3Scarlsonj { 568*d04ccbb3Scarlsonj char *str, *oldnest, *oldprefix; 569*d04ccbb3Scarlsonj 570*d04ccbb3Scarlsonj if (olen <= 0) 571*d04ccbb3Scarlsonj return; 572*d04ccbb3Scarlsonj oldprefix = prot_prefix; 573*d04ccbb3Scarlsonj oldnest = prot_nest_prefix; 574*d04ccbb3Scarlsonj str = malloc(strlen(prot_nest_prefix) + strlen(prot_prefix) + 1); 575*d04ccbb3Scarlsonj if (str == NULL) { 576*d04ccbb3Scarlsonj prot_nest_prefix = prot_prefix; 577*d04ccbb3Scarlsonj } else { 578*d04ccbb3Scarlsonj (void) sprintf(str, "%s%s", prot_nest_prefix, prot_prefix); 579*d04ccbb3Scarlsonj prot_nest_prefix = str; 580*d04ccbb3Scarlsonj } 581*d04ccbb3Scarlsonj show_header(prefix, title, 0); 582*d04ccbb3Scarlsonj show_options(data, olen); 583*d04ccbb3Scarlsonj free(str); 584*d04ccbb3Scarlsonj prot_prefix = oldprefix; 585*d04ccbb3Scarlsonj prot_nest_prefix = oldnest; 586*d04ccbb3Scarlsonj } 587*d04ccbb3Scarlsonj 588*d04ccbb3Scarlsonj static void 589*d04ccbb3Scarlsonj show_options(const uint8_t *data, int len) 590*d04ccbb3Scarlsonj { 591*d04ccbb3Scarlsonj dhcpv6_option_t d6o; 592*d04ccbb3Scarlsonj uint_t olen, retlen; 593*d04ccbb3Scarlsonj uint16_t val16; 594*d04ccbb3Scarlsonj uint16_t type; 595*d04ccbb3Scarlsonj uint32_t val32; 596*d04ccbb3Scarlsonj const uint8_t *ostart; 597*d04ccbb3Scarlsonj char *str, *sp; 598*d04ccbb3Scarlsonj char *oldnest; 599*d04ccbb3Scarlsonj 600*d04ccbb3Scarlsonj /* 601*d04ccbb3Scarlsonj * Be very careful with negative numbers; ANSI signed/unsigned 602*d04ccbb3Scarlsonj * comparison doesn't work as expected. 603*d04ccbb3Scarlsonj */ 604*d04ccbb3Scarlsonj while (len >= (signed)sizeof (d6o)) { 605*d04ccbb3Scarlsonj (void) memcpy(&d6o, data, sizeof (d6o)); 606*d04ccbb3Scarlsonj d6o.d6o_code = ntohs(d6o.d6o_code); 607*d04ccbb3Scarlsonj d6o.d6o_len = olen = ntohs(d6o.d6o_len); 608*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 609*d04ccbb3Scarlsonj "Option Code = %u (%s)", d6o.d6o_code, 610*d04ccbb3Scarlsonj option_to_str(d6o.d6o_code)); 611*d04ccbb3Scarlsonj ostart = data += sizeof (d6o); 612*d04ccbb3Scarlsonj len -= sizeof (d6o); 613*d04ccbb3Scarlsonj if (olen > len) { 614*d04ccbb3Scarlsonj (void) strlcpy(get_line(0, 0), "Option truncated", 615*d04ccbb3Scarlsonj get_line_remain()); 616*d04ccbb3Scarlsonj olen = len; 617*d04ccbb3Scarlsonj } 618*d04ccbb3Scarlsonj switch (d6o.d6o_code) { 619*d04ccbb3Scarlsonj case DHCPV6_OPT_CLIENTID: 620*d04ccbb3Scarlsonj case DHCPV6_OPT_SERVERID: 621*d04ccbb3Scarlsonj if (olen < sizeof (val16)) 622*d04ccbb3Scarlsonj break; 623*d04ccbb3Scarlsonj (void) memcpy(&val16, data, sizeof (val16)); 624*d04ccbb3Scarlsonj data += sizeof (val16); 625*d04ccbb3Scarlsonj olen -= sizeof (val16); 626*d04ccbb3Scarlsonj type = ntohs(val16); 627*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 628*d04ccbb3Scarlsonj " DUID Type = %u (%s)", type, 629*d04ccbb3Scarlsonj duidtype_to_str(type)); 630*d04ccbb3Scarlsonj if (type == DHCPV6_DUID_LLT || type == DHCPV6_DUID_LL) { 631*d04ccbb3Scarlsonj if (olen < sizeof (val16)) 632*d04ccbb3Scarlsonj break; 633*d04ccbb3Scarlsonj (void) memcpy(&val16, data, sizeof (val16)); 634*d04ccbb3Scarlsonj data += sizeof (val16); 635*d04ccbb3Scarlsonj olen -= sizeof (val16); 636*d04ccbb3Scarlsonj val16 = ntohs(val16); 637*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 638*d04ccbb3Scarlsonj get_line_remain(), 639*d04ccbb3Scarlsonj " Hardware Type = %u (%s)", val16, 640*d04ccbb3Scarlsonj arp_htype(type)); 641*d04ccbb3Scarlsonj } 642*d04ccbb3Scarlsonj if (type == DHCPV6_DUID_LLT) { 643*d04ccbb3Scarlsonj time_t timevalue; 644*d04ccbb3Scarlsonj 645*d04ccbb3Scarlsonj if (olen < sizeof (val32)) 646*d04ccbb3Scarlsonj break; 647*d04ccbb3Scarlsonj (void) memcpy(&val32, data, sizeof (val32)); 648*d04ccbb3Scarlsonj data += sizeof (val32); 649*d04ccbb3Scarlsonj olen -= sizeof (val32); 650*d04ccbb3Scarlsonj timevalue = ntohl(val32) + DUID_TIME_BASE; 651*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 652*d04ccbb3Scarlsonj get_line_remain(), 653*d04ccbb3Scarlsonj " Time = %lu (%.24s)", ntohl(val32), 654*d04ccbb3Scarlsonj ctime(&timevalue)); 655*d04ccbb3Scarlsonj } 656*d04ccbb3Scarlsonj if (type == DHCPV6_DUID_EN) { 657*d04ccbb3Scarlsonj if (olen < sizeof (val32)) 658*d04ccbb3Scarlsonj break; 659*d04ccbb3Scarlsonj (void) memcpy(&val32, data, sizeof (val32)); 660*d04ccbb3Scarlsonj data += sizeof (val32); 661*d04ccbb3Scarlsonj olen -= sizeof (val32); 662*d04ccbb3Scarlsonj val32 = ntohl(val32); 663*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 664*d04ccbb3Scarlsonj get_line_remain(), 665*d04ccbb3Scarlsonj " Enterprise Number = %lu (%s)", val32, 666*d04ccbb3Scarlsonj entr_to_str(val32)); 667*d04ccbb3Scarlsonj } 668*d04ccbb3Scarlsonj if (olen == 0) 669*d04ccbb3Scarlsonj break; 670*d04ccbb3Scarlsonj if ((str = malloc(olen * 3)) == NULL) 671*d04ccbb3Scarlsonj pr_err("interpret_dhcpv6: no mem"); 672*d04ccbb3Scarlsonj sp = str + snprintf(str, 3, "%02x", *data++); 673*d04ccbb3Scarlsonj while (--olen > 0) { 674*d04ccbb3Scarlsonj *sp++ = (type == DHCPV6_DUID_LLT || 675*d04ccbb3Scarlsonj type == DHCPV6_DUID_LL) ? ':' : ' '; 676*d04ccbb3Scarlsonj sp = sp + snprintf(sp, 3, "%02x", *data++); 677*d04ccbb3Scarlsonj } 678*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 679*d04ccbb3Scarlsonj (type == DHCPV6_DUID_LLT || 680*d04ccbb3Scarlsonj type == DHCPV6_DUID_LL) ? 681*d04ccbb3Scarlsonj " Link Layer Address = %s" : 682*d04ccbb3Scarlsonj " Identifier = %s", str); 683*d04ccbb3Scarlsonj free(str); 684*d04ccbb3Scarlsonj break; 685*d04ccbb3Scarlsonj case DHCPV6_OPT_IA_NA: 686*d04ccbb3Scarlsonj case DHCPV6_OPT_IA_PD: { 687*d04ccbb3Scarlsonj dhcpv6_ia_na_t d6in; 688*d04ccbb3Scarlsonj 689*d04ccbb3Scarlsonj if (olen < sizeof (d6in) - sizeof (d6o)) 690*d04ccbb3Scarlsonj break; 691*d04ccbb3Scarlsonj (void) memcpy(&d6in, data - sizeof (d6o), 692*d04ccbb3Scarlsonj sizeof (d6in)); 693*d04ccbb3Scarlsonj data += sizeof (d6in) - sizeof (d6o); 694*d04ccbb3Scarlsonj olen -= sizeof (d6in) - sizeof (d6o); 695*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 696*d04ccbb3Scarlsonj " IAID = %u", ntohl(d6in.d6in_iaid)); 697*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 698*d04ccbb3Scarlsonj " T1 (renew) = %u seconds", ntohl(d6in.d6in_t1)); 699*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 700*d04ccbb3Scarlsonj " T2 (rebind) = %u seconds", ntohl(d6in.d6in_t2)); 701*d04ccbb3Scarlsonj nest_options(data, olen, "IA: ", 702*d04ccbb3Scarlsonj "Identity Association"); 703*d04ccbb3Scarlsonj break; 704*d04ccbb3Scarlsonj } 705*d04ccbb3Scarlsonj case DHCPV6_OPT_IA_TA: { 706*d04ccbb3Scarlsonj dhcpv6_ia_ta_t d6it; 707*d04ccbb3Scarlsonj 708*d04ccbb3Scarlsonj if (olen < sizeof (d6it) - sizeof (d6o)) 709*d04ccbb3Scarlsonj break; 710*d04ccbb3Scarlsonj (void) memcpy(&d6it, data - sizeof (d6o), 711*d04ccbb3Scarlsonj sizeof (d6it)); 712*d04ccbb3Scarlsonj data += sizeof (d6it) - sizeof (d6o); 713*d04ccbb3Scarlsonj olen -= sizeof (d6it) - sizeof (d6o); 714*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 715*d04ccbb3Scarlsonj " IAID = %u", ntohl(d6it.d6it_iaid)); 716*d04ccbb3Scarlsonj nest_options(data, olen, "IA: ", 717*d04ccbb3Scarlsonj "Identity Association"); 718*d04ccbb3Scarlsonj break; 719*d04ccbb3Scarlsonj } 720*d04ccbb3Scarlsonj case DHCPV6_OPT_IAADDR: { 721*d04ccbb3Scarlsonj dhcpv6_iaaddr_t d6ia; 722*d04ccbb3Scarlsonj 723*d04ccbb3Scarlsonj if (olen < sizeof (d6ia) - sizeof (d6o)) 724*d04ccbb3Scarlsonj break; 725*d04ccbb3Scarlsonj (void) memcpy(&d6ia, data - sizeof (d6o), 726*d04ccbb3Scarlsonj sizeof (d6ia)); 727*d04ccbb3Scarlsonj data += sizeof (d6ia) - sizeof (d6o); 728*d04ccbb3Scarlsonj olen -= sizeof (d6ia) - sizeof (d6o); 729*d04ccbb3Scarlsonj show_address(" Address", &d6ia.d6ia_addr); 730*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 731*d04ccbb3Scarlsonj " Preferred lifetime = %u seconds", 732*d04ccbb3Scarlsonj ntohl(d6ia.d6ia_preflife)); 733*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 734*d04ccbb3Scarlsonj " Valid lifetime = %u seconds", 735*d04ccbb3Scarlsonj ntohl(d6ia.d6ia_vallife)); 736*d04ccbb3Scarlsonj nest_options(data, olen, "ADDR: ", "Address"); 737*d04ccbb3Scarlsonj break; 738*d04ccbb3Scarlsonj } 739*d04ccbb3Scarlsonj case DHCPV6_OPT_ORO: 740*d04ccbb3Scarlsonj while (olen >= sizeof (val16)) { 741*d04ccbb3Scarlsonj (void) memcpy(&val16, data, sizeof (val16)); 742*d04ccbb3Scarlsonj val16 = ntohs(val16); 743*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 744*d04ccbb3Scarlsonj get_line_remain(), 745*d04ccbb3Scarlsonj " Requested Option Code = %u (%s)", val16, 746*d04ccbb3Scarlsonj option_to_str(val16)); 747*d04ccbb3Scarlsonj data += sizeof (val16); 748*d04ccbb3Scarlsonj olen -= sizeof (val16); 749*d04ccbb3Scarlsonj } 750*d04ccbb3Scarlsonj break; 751*d04ccbb3Scarlsonj case DHCPV6_OPT_PREFERENCE: 752*d04ccbb3Scarlsonj if (olen > 0) { 753*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 754*d04ccbb3Scarlsonj get_line_remain(), 755*d04ccbb3Scarlsonj *data == 255 ? 756*d04ccbb3Scarlsonj " Preference = %u (immediate)" : 757*d04ccbb3Scarlsonj " Preference = %u", *data); 758*d04ccbb3Scarlsonj } 759*d04ccbb3Scarlsonj break; 760*d04ccbb3Scarlsonj case DHCPV6_OPT_ELAPSED_TIME: 761*d04ccbb3Scarlsonj if (olen == sizeof (val16)) { 762*d04ccbb3Scarlsonj (void) memcpy(&val16, data, sizeof (val16)); 763*d04ccbb3Scarlsonj val16 = ntohs(val16); 764*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 765*d04ccbb3Scarlsonj get_line_remain(), 766*d04ccbb3Scarlsonj " Elapsed Time = %u.%02u seconds", 767*d04ccbb3Scarlsonj val16 / 100, val16 % 100); 768*d04ccbb3Scarlsonj } 769*d04ccbb3Scarlsonj break; 770*d04ccbb3Scarlsonj case DHCPV6_OPT_RELAY_MSG: 771*d04ccbb3Scarlsonj if (olen > 0) { 772*d04ccbb3Scarlsonj oldnest = prot_nest_prefix; 773*d04ccbb3Scarlsonj prot_nest_prefix = prot_prefix; 774*d04ccbb3Scarlsonj retlen = interpret_dhcpv6(F_DTAIL, data, olen); 775*d04ccbb3Scarlsonj prot_prefix = prot_nest_prefix; 776*d04ccbb3Scarlsonj prot_nest_prefix = oldnest; 777*d04ccbb3Scarlsonj } 778*d04ccbb3Scarlsonj break; 779*d04ccbb3Scarlsonj case DHCPV6_OPT_AUTH: { 780*d04ccbb3Scarlsonj dhcpv6_auth_t d6a; 781*d04ccbb3Scarlsonj 782*d04ccbb3Scarlsonj if (olen < DHCPV6_AUTH_SIZE - sizeof (d6o)) 783*d04ccbb3Scarlsonj break; 784*d04ccbb3Scarlsonj (void) memcpy(&d6a, data - sizeof (d6o), 785*d04ccbb3Scarlsonj DHCPV6_AUTH_SIZE); 786*d04ccbb3Scarlsonj data += DHCPV6_AUTH_SIZE - sizeof (d6o); 787*d04ccbb3Scarlsonj olen += DHCPV6_AUTH_SIZE - sizeof (d6o); 788*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 789*d04ccbb3Scarlsonj " Protocol = %u (%s)", d6a.d6a_proto, 790*d04ccbb3Scarlsonj authproto_to_str(d6a.d6a_proto)); 791*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 792*d04ccbb3Scarlsonj " Algorithm = %u (%s)", d6a.d6a_alg, 793*d04ccbb3Scarlsonj authalg_to_str(d6a.d6a_proto, d6a.d6a_alg)); 794*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 795*d04ccbb3Scarlsonj " Replay Detection Method = %u (%s)", d6a.d6a_rdm, 796*d04ccbb3Scarlsonj authrdm_to_str(d6a.d6a_rdm)); 797*d04ccbb3Scarlsonj show_hex(d6a.d6a_replay, sizeof (d6a.d6a_replay), 798*d04ccbb3Scarlsonj " RDM Data"); 799*d04ccbb3Scarlsonj if (olen > 0) 800*d04ccbb3Scarlsonj show_hex(data, olen, " Auth Info"); 801*d04ccbb3Scarlsonj break; 802*d04ccbb3Scarlsonj } 803*d04ccbb3Scarlsonj case DHCPV6_OPT_UNICAST: 804*d04ccbb3Scarlsonj if (olen >= sizeof (in6_addr_t)) 805*d04ccbb3Scarlsonj show_address(" Server Address", data); 806*d04ccbb3Scarlsonj break; 807*d04ccbb3Scarlsonj case DHCPV6_OPT_STATUS_CODE: 808*d04ccbb3Scarlsonj if (olen < sizeof (val16)) 809*d04ccbb3Scarlsonj break; 810*d04ccbb3Scarlsonj (void) memcpy(&val16, data, sizeof (val16)); 811*d04ccbb3Scarlsonj val16 = ntohs(val16); 812*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 813*d04ccbb3Scarlsonj " Status Code = %u (%s)", val16, 814*d04ccbb3Scarlsonj status_to_str(val16)); 815*d04ccbb3Scarlsonj data += sizeof (val16); 816*d04ccbb3Scarlsonj olen -= sizeof (val16); 817*d04ccbb3Scarlsonj if (olen > 0) 818*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 819*d04ccbb3Scarlsonj get_line_remain(), " Text = \"%.*s\"", 820*d04ccbb3Scarlsonj olen, data); 821*d04ccbb3Scarlsonj break; 822*d04ccbb3Scarlsonj case DHCPV6_OPT_VENDOR_CLASS: 823*d04ccbb3Scarlsonj if (olen < sizeof (val32)) 824*d04ccbb3Scarlsonj break; 825*d04ccbb3Scarlsonj (void) memcpy(&val32, data, sizeof (val32)); 826*d04ccbb3Scarlsonj data += sizeof (val32); 827*d04ccbb3Scarlsonj olen -= sizeof (val32); 828*d04ccbb3Scarlsonj val32 = ntohl(val32); 829*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 830*d04ccbb3Scarlsonj " Enterprise Number = %lu (%s)", val32, 831*d04ccbb3Scarlsonj entr_to_str(val32)); 832*d04ccbb3Scarlsonj /* FALLTHROUGH */ 833*d04ccbb3Scarlsonj case DHCPV6_OPT_USER_CLASS: 834*d04ccbb3Scarlsonj while (olen >= sizeof (val16)) { 835*d04ccbb3Scarlsonj (void) memcpy(&val16, data, sizeof (val16)); 836*d04ccbb3Scarlsonj data += sizeof (val16); 837*d04ccbb3Scarlsonj olen -= sizeof (val16); 838*d04ccbb3Scarlsonj val16 = ntohs(val16); 839*d04ccbb3Scarlsonj if (val16 > olen) { 840*d04ccbb3Scarlsonj (void) strlcpy(get_line(0, 0), 841*d04ccbb3Scarlsonj " Truncated class", 842*d04ccbb3Scarlsonj get_line_remain()); 843*d04ccbb3Scarlsonj val16 = olen; 844*d04ccbb3Scarlsonj } 845*d04ccbb3Scarlsonj show_hex(data, olen, " Class"); 846*d04ccbb3Scarlsonj data += val16; 847*d04ccbb3Scarlsonj olen -= val16; 848*d04ccbb3Scarlsonj } 849*d04ccbb3Scarlsonj break; 850*d04ccbb3Scarlsonj case DHCPV6_OPT_VENDOR_OPT: { 851*d04ccbb3Scarlsonj dhcpv6_option_t sd6o; 852*d04ccbb3Scarlsonj 853*d04ccbb3Scarlsonj if (olen < sizeof (val32)) 854*d04ccbb3Scarlsonj break; 855*d04ccbb3Scarlsonj (void) memcpy(&val32, data, sizeof (val32)); 856*d04ccbb3Scarlsonj data += sizeof (val32); 857*d04ccbb3Scarlsonj olen -= sizeof (val32); 858*d04ccbb3Scarlsonj val32 = ntohl(val32); 859*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 860*d04ccbb3Scarlsonj " Enterprise Number = %lu (%s)", val32, 861*d04ccbb3Scarlsonj entr_to_str(val32)); 862*d04ccbb3Scarlsonj while (olen >= sizeof (sd6o)) { 863*d04ccbb3Scarlsonj (void) memcpy(&sd6o, data, sizeof (sd6o)); 864*d04ccbb3Scarlsonj sd6o.d6o_code = ntohs(sd6o.d6o_code); 865*d04ccbb3Scarlsonj sd6o.d6o_len = ntohs(sd6o.d6o_len); 866*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 867*d04ccbb3Scarlsonj get_line_remain(), 868*d04ccbb3Scarlsonj " Vendor Option Code = %u", d6o.d6o_code); 869*d04ccbb3Scarlsonj data += sizeof (d6o); 870*d04ccbb3Scarlsonj olen -= sizeof (d6o); 871*d04ccbb3Scarlsonj if (sd6o.d6o_len > olen) { 872*d04ccbb3Scarlsonj (void) strlcpy(get_line(0, 0), 873*d04ccbb3Scarlsonj " Vendor Option truncated", 874*d04ccbb3Scarlsonj get_line_remain()); 875*d04ccbb3Scarlsonj sd6o.d6o_len = olen; 876*d04ccbb3Scarlsonj } 877*d04ccbb3Scarlsonj if (sd6o.d6o_len > 0) { 878*d04ccbb3Scarlsonj show_hex(data, sd6o.d6o_len, 879*d04ccbb3Scarlsonj " Data"); 880*d04ccbb3Scarlsonj data += sd6o.d6o_len; 881*d04ccbb3Scarlsonj olen -= sd6o.d6o_len; 882*d04ccbb3Scarlsonj } 883*d04ccbb3Scarlsonj } 884*d04ccbb3Scarlsonj break; 885*d04ccbb3Scarlsonj } 886*d04ccbb3Scarlsonj case DHCPV6_OPT_REMOTE_ID: 887*d04ccbb3Scarlsonj if (olen < sizeof (val32)) 888*d04ccbb3Scarlsonj break; 889*d04ccbb3Scarlsonj (void) memcpy(&val32, data, sizeof (val32)); 890*d04ccbb3Scarlsonj data += sizeof (val32); 891*d04ccbb3Scarlsonj olen -= sizeof (val32); 892*d04ccbb3Scarlsonj val32 = ntohl(val32); 893*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 894*d04ccbb3Scarlsonj " Enterprise Number = %lu (%s)", val32, 895*d04ccbb3Scarlsonj entr_to_str(val32)); 896*d04ccbb3Scarlsonj /* FALLTHROUGH */ 897*d04ccbb3Scarlsonj case DHCPV6_OPT_INTERFACE_ID: 898*d04ccbb3Scarlsonj case DHCPV6_OPT_SUBSCRIBER: 899*d04ccbb3Scarlsonj if (olen > 0) 900*d04ccbb3Scarlsonj show_hex(data, olen, " ID"); 901*d04ccbb3Scarlsonj break; 902*d04ccbb3Scarlsonj case DHCPV6_OPT_RECONF_MSG: 903*d04ccbb3Scarlsonj if (olen > 0) { 904*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 905*d04ccbb3Scarlsonj get_line_remain(), 906*d04ccbb3Scarlsonj " Message Type = %u (%s)", *data, 907*d04ccbb3Scarlsonj reconf_to_str(*data)); 908*d04ccbb3Scarlsonj } 909*d04ccbb3Scarlsonj break; 910*d04ccbb3Scarlsonj case DHCPV6_OPT_SIP_NAMES: 911*d04ccbb3Scarlsonj case DHCPV6_OPT_DNS_SEARCH: 912*d04ccbb3Scarlsonj case DHCPV6_OPT_NIS_DOMAIN: 913*d04ccbb3Scarlsonj case DHCPV6_OPT_NISP_DOMAIN: 914*d04ccbb3Scarlsonj case DHCPV6_OPT_BCMCS_SRV_D: { 915*d04ccbb3Scarlsonj dhcp_symbol_t *symp; 916*d04ccbb3Scarlsonj char *sp2; 917*d04ccbb3Scarlsonj 918*d04ccbb3Scarlsonj symp = inittab_getbycode( 919*d04ccbb3Scarlsonj ITAB_CAT_STANDARD | ITAB_CAT_V6, ITAB_CONS_SNOOP, 920*d04ccbb3Scarlsonj d6o.d6o_code); 921*d04ccbb3Scarlsonj if (symp != NULL) { 922*d04ccbb3Scarlsonj str = inittab_decode(symp, data, olen, B_TRUE); 923*d04ccbb3Scarlsonj if (str != NULL) { 924*d04ccbb3Scarlsonj sp = str; 925*d04ccbb3Scarlsonj do { 926*d04ccbb3Scarlsonj sp2 = strchr(sp, ' '); 927*d04ccbb3Scarlsonj if (sp2 != NULL) 928*d04ccbb3Scarlsonj *sp2++ = '\0'; 929*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 930*d04ccbb3Scarlsonj get_line_remain(), 931*d04ccbb3Scarlsonj " Name = %s", sp); 932*d04ccbb3Scarlsonj } while ((sp = sp2) != NULL); 933*d04ccbb3Scarlsonj free(str); 934*d04ccbb3Scarlsonj } 935*d04ccbb3Scarlsonj free(symp); 936*d04ccbb3Scarlsonj } 937*d04ccbb3Scarlsonj break; 938*d04ccbb3Scarlsonj } 939*d04ccbb3Scarlsonj case DHCPV6_OPT_SIP_ADDR: 940*d04ccbb3Scarlsonj case DHCPV6_OPT_DNS_ADDR: 941*d04ccbb3Scarlsonj case DHCPV6_OPT_NIS_SERVERS: 942*d04ccbb3Scarlsonj case DHCPV6_OPT_NISP_SERVERS: 943*d04ccbb3Scarlsonj case DHCPV6_OPT_SNTP_SERVERS: 944*d04ccbb3Scarlsonj case DHCPV6_OPT_BCMCS_SRV_A: 945*d04ccbb3Scarlsonj while (olen >= sizeof (in6_addr_t)) { 946*d04ccbb3Scarlsonj show_address(" Address", data); 947*d04ccbb3Scarlsonj data += sizeof (in6_addr_t); 948*d04ccbb3Scarlsonj olen -= sizeof (in6_addr_t); 949*d04ccbb3Scarlsonj } 950*d04ccbb3Scarlsonj break; 951*d04ccbb3Scarlsonj case DHCPV6_OPT_IAPREFIX: { 952*d04ccbb3Scarlsonj dhcpv6_iaprefix_t d6ip; 953*d04ccbb3Scarlsonj 954*d04ccbb3Scarlsonj if (olen < DHCPV6_IAPREFIX_SIZE - sizeof (d6o)) 955*d04ccbb3Scarlsonj break; 956*d04ccbb3Scarlsonj (void) memcpy(&d6ip, data - sizeof (d6o), 957*d04ccbb3Scarlsonj DHCPV6_IAPREFIX_SIZE); 958*d04ccbb3Scarlsonj data += DHCPV6_IAPREFIX_SIZE - sizeof (d6o); 959*d04ccbb3Scarlsonj olen -= DHCPV6_IAPREFIX_SIZE - sizeof (d6o); 960*d04ccbb3Scarlsonj show_address(" Prefix", d6ip.d6ip_addr); 961*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 962*d04ccbb3Scarlsonj " Preferred lifetime = %u seconds", 963*d04ccbb3Scarlsonj ntohl(d6ip.d6ip_preflife)); 964*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 965*d04ccbb3Scarlsonj " Valid lifetime = %u seconds", 966*d04ccbb3Scarlsonj ntohl(d6ip.d6ip_vallife)); 967*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 968*d04ccbb3Scarlsonj " Prefix length = %u", d6ip.d6ip_preflen); 969*d04ccbb3Scarlsonj nest_options(data, olen, "ADDR: ", "Address"); 970*d04ccbb3Scarlsonj break; 971*d04ccbb3Scarlsonj } 972*d04ccbb3Scarlsonj case DHCPV6_OPT_INFO_REFTIME: 973*d04ccbb3Scarlsonj if (olen < sizeof (val32)) 974*d04ccbb3Scarlsonj break; 975*d04ccbb3Scarlsonj (void) memcpy(&val32, data, sizeof (val32)); 976*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 977*d04ccbb3Scarlsonj " Refresh Time = %lu seconds", ntohl(val32)); 978*d04ccbb3Scarlsonj break; 979*d04ccbb3Scarlsonj case DHCPV6_OPT_GEOCONF_CVC: { 980*d04ccbb3Scarlsonj dhcpv6_civic_t d6c; 981*d04ccbb3Scarlsonj int solen; 982*d04ccbb3Scarlsonj 983*d04ccbb3Scarlsonj if (olen < DHCPV6_CIVIC_SIZE - sizeof (d6o)) 984*d04ccbb3Scarlsonj break; 985*d04ccbb3Scarlsonj (void) memcpy(&d6c, data - sizeof (d6o), 986*d04ccbb3Scarlsonj DHCPV6_CIVIC_SIZE); 987*d04ccbb3Scarlsonj data += DHCPV6_CIVIC_SIZE - sizeof (d6o); 988*d04ccbb3Scarlsonj olen -= DHCPV6_CIVIC_SIZE - sizeof (d6o); 989*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 990*d04ccbb3Scarlsonj " What Location = %u (%s)", d6c.d6c_what, 991*d04ccbb3Scarlsonj cwhat_to_str(d6c.d6c_what)); 992*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 993*d04ccbb3Scarlsonj " Country Code = %.*s", sizeof (d6c.d6c_cc), 994*d04ccbb3Scarlsonj d6c.d6c_cc); 995*d04ccbb3Scarlsonj while (olen >= 2) { 996*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 997*d04ccbb3Scarlsonj get_line_remain(), 998*d04ccbb3Scarlsonj " CA Element = %u (%s)", *data, 999*d04ccbb3Scarlsonj catype_to_str(*data)); 1000*d04ccbb3Scarlsonj solen = data[1]; 1001*d04ccbb3Scarlsonj data += 2; 1002*d04ccbb3Scarlsonj olen -= 2; 1003*d04ccbb3Scarlsonj if (solen > olen) { 1004*d04ccbb3Scarlsonj (void) strlcpy(get_line(0, 0), 1005*d04ccbb3Scarlsonj " CA Element truncated", 1006*d04ccbb3Scarlsonj get_line_remain()); 1007*d04ccbb3Scarlsonj solen = olen; 1008*d04ccbb3Scarlsonj } 1009*d04ccbb3Scarlsonj if (solen > 0) { 1010*d04ccbb3Scarlsonj show_ascii(data, solen, " CA Data"); 1011*d04ccbb3Scarlsonj data += solen; 1012*d04ccbb3Scarlsonj olen -= solen; 1013*d04ccbb3Scarlsonj } 1014*d04ccbb3Scarlsonj } 1015*d04ccbb3Scarlsonj break; 1016*d04ccbb3Scarlsonj } 1017*d04ccbb3Scarlsonj case DHCPV6_OPT_CLIENT_FQDN: { 1018*d04ccbb3Scarlsonj dhcp_symbol_t *symp; 1019*d04ccbb3Scarlsonj 1020*d04ccbb3Scarlsonj if (olen == 0) 1021*d04ccbb3Scarlsonj break; 1022*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 1023*d04ccbb3Scarlsonj " Flags = %02x", *data); 1024*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 1025*d04ccbb3Scarlsonj " %s", getflag(*data, DHCPV6_FQDNF_S, 1026*d04ccbb3Scarlsonj "Perform AAAA RR updates", "No AAAA RR updates")); 1027*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 1028*d04ccbb3Scarlsonj " %s", getflag(*data, DHCPV6_FQDNF_O, 1029*d04ccbb3Scarlsonj "Server override updates", 1030*d04ccbb3Scarlsonj "No server override updates")); 1031*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), get_line_remain(), 1032*d04ccbb3Scarlsonj " %s", getflag(*data, DHCPV6_FQDNF_N, 1033*d04ccbb3Scarlsonj "Server performs no updates", 1034*d04ccbb3Scarlsonj "Server performs updates")); 1035*d04ccbb3Scarlsonj symp = inittab_getbycode( 1036*d04ccbb3Scarlsonj ITAB_CAT_STANDARD | ITAB_CAT_V6, ITAB_CONS_SNOOP, 1037*d04ccbb3Scarlsonj d6o.d6o_code); 1038*d04ccbb3Scarlsonj if (symp != NULL) { 1039*d04ccbb3Scarlsonj str = inittab_decode(symp, data, olen, B_TRUE); 1040*d04ccbb3Scarlsonj if (str != NULL) { 1041*d04ccbb3Scarlsonj (void) snprintf(get_line(0, 0), 1042*d04ccbb3Scarlsonj get_line_remain(), 1043*d04ccbb3Scarlsonj " FQDN = %s", str); 1044*d04ccbb3Scarlsonj free(str); 1045*d04ccbb3Scarlsonj } 1046*d04ccbb3Scarlsonj free(symp); 1047*d04ccbb3Scarlsonj } 1048*d04ccbb3Scarlsonj break; 1049*d04ccbb3Scarlsonj } 1050*d04ccbb3Scarlsonj } 1051*d04ccbb3Scarlsonj data = ostart + d6o.d6o_len; 1052*d04ccbb3Scarlsonj len -= d6o.d6o_len; 1053*d04ccbb3Scarlsonj } 1054*d04ccbb3Scarlsonj if (len != 0) { 1055*d04ccbb3Scarlsonj (void) strlcpy(get_line(0, 0), "Option entry truncated", 1056*d04ccbb3Scarlsonj get_line_remain()); 1057*d04ccbb3Scarlsonj } 1058*d04ccbb3Scarlsonj } 1059