| 494 | } |
| 495 | |
| 496 | static int |
| 497 | flushroutes_fib(int fib) |
| 498 | { |
| 499 | struct rt_msghdr *rtm; |
| 500 | size_t needed; |
| 501 | char *buf, *next, *lim; |
| 502 | int mib[7], rlen, seqno, count = 0; |
| 503 | int error; |
| 504 | |
| 505 | error = set_sofib(fib); |
| 506 | if (error) { |
| 507 | warn("fib number %d is ignored", fib); |
| 508 | return (error); |
| 509 | } |
| 510 | |
| 511 | retry: |
| 512 | mib[0] = CTL_NET; |
| 513 | mib[1] = PF_ROUTE; |
| 514 | mib[2] = 0; /* protocol */ |
| 515 | mib[3] = AF_UNSPEC; |
| 516 | mib[4] = NET_RT_DUMP; |
| 517 | mib[5] = 0; /* no flags */ |
| 518 | mib[6] = fib; |
| 519 | if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0) |
| 520 | err(EX_OSERR, "route-sysctl-estimate"); |
| 521 | if ((buf = malloc(needed)) == NULL) |
| 522 | errx(EX_OSERR, "malloc failed"); |
| 523 | if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0) { |
| 524 | if (errno == ENOMEM && count++ < 10) { |
| 525 | warnx("Routing table grew, retrying"); |
| 526 | sleep(1); |
| 527 | free(buf); |
| 528 | goto retry; |
| 529 | } |
| 530 | err(EX_OSERR, "route-sysctl-get"); |
| 531 | } |
| 532 | lim = buf + needed; |
| 533 | if (verbose) |
| 534 | (void)printf("Examining routing table from sysctl\n"); |
| 535 | seqno = 0; /* ??? */ |
| 536 | for (next = buf; next < lim; next += rtm->rtm_msglen) { |
| 537 | rtm = (struct rt_msghdr *)(void *)next; |
| 538 | if (verbose) |
| 539 | print_rtmsg(rtm, rtm->rtm_msglen); |
| 540 | if ((rtm->rtm_flags & RTF_GATEWAY) == 0) |
| 541 | continue; |
| 542 | if (af != 0) { |
| 543 | struct sockaddr *sa = (struct sockaddr *)(rtm + 1); |
| 544 | |
| 545 | if (sa->sa_family != af) |
| 546 | continue; |
| 547 | } |
| 548 | if (debugonly) |
| 549 | continue; |
| 550 | rtm->rtm_type = RTM_DELETE; |
| 551 | rtm->rtm_seq = seqno; |
| 552 | rlen = write(s, next, rtm->rtm_msglen); |
| 553 | if (rlen < 0 && errno == EPERM) |
no test coverage detected