* Search the arp table and do some action on matching entries */
| 559 | * Search the arp table and do some action on matching entries |
| 560 | */ |
| 561 | static int |
| 562 | search(u_long addr, action_fn *action) |
| 563 | { |
| 564 | int mib[6]; |
| 565 | size_t needed; |
| 566 | char *lim, *buf, *next; |
| 567 | struct rt_msghdr *rtm; |
| 568 | struct sockaddr_in *sin2; |
| 569 | struct sockaddr_dl *sdl; |
| 570 | char ifname[IF_NAMESIZE]; |
| 571 | int st, found_entry = 0; |
| 572 | |
| 573 | mib[0] = CTL_NET; |
| 574 | mib[1] = PF_ROUTE; |
| 575 | mib[2] = 0; |
| 576 | mib[3] = AF_INET; |
| 577 | mib[4] = NET_RT_FLAGS; |
| 578 | #ifdef RTF_LLINFO |
| 579 | mib[5] = RTF_LLINFO; |
| 580 | #else |
| 581 | mib[5] = 0; |
| 582 | #endif |
| 583 | if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) |
| 584 | xo_err(1, "route-sysctl-estimate"); |
| 585 | if (needed == 0) /* empty table */ |
| 586 | return 0; |
| 587 | buf = NULL; |
| 588 | for (;;) { |
| 589 | buf = reallocf(buf, needed); |
| 590 | if (buf == NULL) |
| 591 | xo_errx(1, "could not reallocate memory"); |
| 592 | st = sysctl(mib, 6, buf, &needed, NULL, 0); |
| 593 | if (st == 0 || errno != ENOMEM) |
| 594 | break; |
| 595 | needed += needed / 8; |
| 596 | } |
| 597 | if (st == -1) |
| 598 | xo_err(1, "actual retrieval of routing table"); |
| 599 | lim = buf + needed; |
| 600 | for (next = buf; next < lim; next += rtm->rtm_msglen) { |
| 601 | rtm = (struct rt_msghdr *)next; |
| 602 | sin2 = (struct sockaddr_in *)(rtm + 1); |
| 603 | sdl = (struct sockaddr_dl *)((char *)sin2 + SA_SIZE(sin2)); |
| 604 | if (rifname && if_indextoname(sdl->sdl_index, ifname) && |
| 605 | strcmp(ifname, rifname)) |
| 606 | continue; |
| 607 | if (addr) { |
| 608 | if (addr != sin2->sin_addr.s_addr) |
| 609 | continue; |
| 610 | found_entry = 1; |
| 611 | } |
| 612 | (*action)(sdl, sin2, rtm); |
| 613 | } |
| 614 | free(buf); |
| 615 | return (found_entry); |
| 616 | } |
| 617 | |
| 618 | /* |