* Expose struct igmp_ifsoftc to userland, keyed by ifindex. * For use by ifmcstat(8). * * SMPng: NOTE: Does an unlocked ifindex space read. * VIMAGE: Assume curvnet set by caller. The node handler itself * is not directly virtualized. */
| 481 | * is not directly virtualized. |
| 482 | */ |
| 483 | static int |
| 484 | sysctl_igmp_ifinfo(SYSCTL_HANDLER_ARGS) |
| 485 | { |
| 486 | int *name; |
| 487 | int error; |
| 488 | u_int namelen; |
| 489 | struct ifnet *ifp; |
| 490 | struct igmp_ifsoftc *igi; |
| 491 | |
| 492 | name = (int *)arg1; |
| 493 | namelen = arg2; |
| 494 | |
| 495 | if (req->newptr != NULL) |
| 496 | return (EPERM); |
| 497 | |
| 498 | if (namelen != 1) |
| 499 | return (EINVAL); |
| 500 | |
| 501 | error = sysctl_wire_old_buffer(req, sizeof(struct igmp_ifinfo)); |
| 502 | if (error) |
| 503 | return (error); |
| 504 | |
| 505 | IN_MULTI_LIST_LOCK(); |
| 506 | IGMP_LOCK(); |
| 507 | |
| 508 | if (name[0] <= 0 || name[0] > V_if_index) { |
| 509 | error = ENOENT; |
| 510 | goto out_locked; |
| 511 | } |
| 512 | |
| 513 | error = ENOENT; |
| 514 | |
| 515 | ifp = ifnet_byindex(name[0]); |
| 516 | if (ifp == NULL) |
| 517 | goto out_locked; |
| 518 | |
| 519 | LIST_FOREACH(igi, &V_igi_head, igi_link) { |
| 520 | if (ifp == igi->igi_ifp) { |
| 521 | struct igmp_ifinfo info; |
| 522 | |
| 523 | info.igi_version = igi->igi_version; |
| 524 | info.igi_v1_timer = igi->igi_v1_timer; |
| 525 | info.igi_v2_timer = igi->igi_v2_timer; |
| 526 | info.igi_v3_timer = igi->igi_v3_timer; |
| 527 | info.igi_flags = igi->igi_flags; |
| 528 | info.igi_rv = igi->igi_rv; |
| 529 | info.igi_qi = igi->igi_qi; |
| 530 | info.igi_qri = igi->igi_qri; |
| 531 | info.igi_uri = igi->igi_uri; |
| 532 | error = SYSCTL_OUT(req, &info, sizeof(info)); |
| 533 | break; |
| 534 | } |
| 535 | } |
| 536 | |
| 537 | out_locked: |
| 538 | IGMP_UNLOCK(); |
| 539 | IN_MULTI_LIST_UNLOCK(); |
| 540 | return (error); |
nothing calls this directly
no test coverage detected