summaryrefslogtreecommitdiffstats
path: root/usr.sbin/arp/arp.c
diff options
context:
space:
mode:
authormaxim <maxim@FreeBSD.org>2005-01-24 13:27:24 +0000
committermaxim <maxim@FreeBSD.org>2005-01-24 13:27:24 +0000
commit85237d203bc9dfe549218c72686a611cff6368b4 (patch)
tree9b0da590b89d2ec7be77cfb0dbe113d7a2426f51 /usr.sbin/arp/arp.c
parentd5c135375c366bd87eec9c632eece3157076af35 (diff)
downloadFreeBSD-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
Diffstat (limited to 'usr.sbin/arp/arp.c')
-rw-r--r--usr.sbin/arp/arp.c20
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) {
OpenPOWER on IntegriCloud