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