diff options
author | maxim <maxim@FreeBSD.org> | 2005-01-24 13:27:24 +0000 |
---|---|---|
committer | maxim <maxim@FreeBSD.org> | 2005-01-24 13:27:24 +0000 |
commit | 85237d203bc9dfe549218c72686a611cff6368b4 (patch) | |
tree | 9b0da590b89d2ec7be77cfb0dbe113d7a2426f51 | |
parent | d5c135375c366bd87eec9c632eece3157076af35 (diff) | |
download | FreeBSD-src-85237d203bc9dfe549218c72686a611cff6368b4.zip FreeBSD-src-85237d203bc9dfe549218c72686a611cff6368b4.tar.gz |
o Try hard to guess a buffer size for a fast growing routing table.
An approach taken from killall/killall.c.
PR: bin/76075
Submitted by: Dmitrij Tejblum
MFC after: 3 weeks
-rw-r--r-- | usr.sbin/arp/arp.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c index 9c794ae..32c0bc2 100644 --- a/usr.sbin/arp/arp.c +++ b/usr.sbin/arp/arp.c @@ -456,12 +456,12 @@ search(u_long addr, action_fn *action) { int mib[6]; size_t needed; - char *lim, *buf, *next; + char *lim, *buf, *newbuf, *next; struct rt_msghdr *rtm; struct sockaddr_inarp *sin2; struct sockaddr_dl *sdl; char ifname[IF_NAMESIZE]; - int found_entry = 0; + int st, found_entry = 0; mib[0] = CTL_NET; mib[1] = PF_ROUTE; @@ -473,9 +473,19 @@ search(u_long addr, action_fn *action) err(1, "route-sysctl-estimate"); if (needed == 0) /* empty table */ return 0; - if ((buf = malloc(needed)) == NULL) - err(1, "malloc"); - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + buf = NULL; + do { + needed += needed / 2; + newbuf = realloc(buf, needed); + if (newbuf == NULL) { + if (buf != NULL) + free(buf); + errx(1, "could not reallocate memory"); + } + buf = newbuf; + st = sysctl(mib, 6, buf, &needed, NULL, 0); + } while (st == -1 && errno == ENOMEM); + if (st == -1) err(1, "actual retrieval of routing table"); lim = buf + needed; for (next = buf; next < lim; next += rtm->rtm_msglen) { |