* Parse multiple ND options. * This function is much easier to use, for ND routines that do not need * multiple options of the same type. */
| 435 | * multiple options of the same type. |
| 436 | */ |
| 437 | int |
| 438 | nd6_options(union nd_opts *ndopts) |
| 439 | { |
| 440 | struct nd_opt_hdr *nd_opt; |
| 441 | int i = 0; |
| 442 | |
| 443 | KASSERT(ndopts != NULL, ("%s: ndopts == NULL", __func__)); |
| 444 | KASSERT(ndopts->nd_opts_last != NULL, ("%s: uninitialized ndopts", |
| 445 | __func__)); |
| 446 | if (ndopts->nd_opts_search == NULL) |
| 447 | return 0; |
| 448 | |
| 449 | while (1) { |
| 450 | nd_opt = nd6_option(ndopts); |
| 451 | if (nd_opt == NULL && ndopts->nd_opts_last == NULL) { |
| 452 | /* |
| 453 | * Message validation requires that all included |
| 454 | * options have a length that is greater than zero. |
| 455 | */ |
| 456 | ICMP6STAT_INC(icp6s_nd_badopt); |
| 457 | bzero(ndopts, sizeof(*ndopts)); |
| 458 | return -1; |
| 459 | } |
| 460 | |
| 461 | if (nd_opt == NULL) |
| 462 | goto skip1; |
| 463 | |
| 464 | switch (nd_opt->nd_opt_type) { |
| 465 | case ND_OPT_SOURCE_LINKADDR: |
| 466 | case ND_OPT_TARGET_LINKADDR: |
| 467 | case ND_OPT_MTU: |
| 468 | case ND_OPT_REDIRECTED_HEADER: |
| 469 | case ND_OPT_NONCE: |
| 470 | if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) { |
| 471 | nd6log((LOG_INFO, |
| 472 | "duplicated ND6 option found (type=%d)\n", |
| 473 | nd_opt->nd_opt_type)); |
| 474 | /* XXX bark? */ |
| 475 | } else { |
| 476 | ndopts->nd_opt_array[nd_opt->nd_opt_type] |
| 477 | = nd_opt; |
| 478 | } |
| 479 | break; |
| 480 | case ND_OPT_PREFIX_INFORMATION: |
| 481 | if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) { |
| 482 | ndopts->nd_opt_array[nd_opt->nd_opt_type] |
| 483 | = nd_opt; |
| 484 | } |
| 485 | ndopts->nd_opts_pi_end = |
| 486 | (struct nd_opt_prefix_info *)nd_opt; |
| 487 | break; |
| 488 | /* What about ND_OPT_ROUTE_INFO? RFC 4191 */ |
| 489 | case ND_OPT_RDNSS: /* RFC 6106 */ |
| 490 | case ND_OPT_DNSSL: /* RFC 6106 */ |
| 491 | /* |
| 492 | * Silently ignore options we know and do not care about |
| 493 | * in the kernel. |
| 494 | */ |
no test coverage detected