Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Jan 2005 02:20:24 GMT
From:      Maxim Konovalov <maxim@macomnet.ru>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/76075: arp program failures due to ARP table growth
Message-ID:  <200501230220.j0N2KOHQ020212@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/76075; it has been noted by GNATS.

From: Maxim Konovalov <maxim@macomnet.ru>
To: Dmitrij Tejblum <tejblum@yandex-team.ru>
Cc: bug-followup@freebsd.org
Subject: Re: bin/76075: arp program failures due to ARP table growth
Date: Sun, 23 Jan 2005 05:16:35 +0300 (MSK)

 [...]
 > >Description:
 >
 > The arp -an command sometimes fail with
 >
 > arp: actual retrieval of routing table: Cannot allocate memory
 >
 > if ARP tables has been grown after its size was estimated.
 >
 > >How-To-Repeat:
 > >Fix:
 >
 > Allocate a bit more memory for ARP table, so the event will be less likely.
 >
 >
 > --- arp.c	Tue Jan 11 02:00:45 2005
 > +++ arp.c	Tue Jan 11 02:05:15 2005
 > @@ -471,10 +471,11 @@
 >  	mib[5] = RTF_LLINFO;
 >  	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
 >  		err(1, "route-sysctl-estimate");
 >  	if (needed == 0)	/* empty table */
 >  		return 0;
 > +	needed += needed / 2;
 >  	if ((buf = malloc(needed)) == NULL)
 >  		err(1, "malloc");
 >  	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
 >  		err(1, "actual retrieval of routing table");
 >  	lim = buf + needed;
 
 What is your opinion about an enclosed diff (a bit more adaptable
 algorithm stolen from killall(1))?
 
 Index: arp.c
 ===================================================================
 RCS file: /home/ncvs/src/usr.sbin/arp/arp.c,v
 retrieving revision 1.54
 diff -u -r1.54 arp.c
 --- arp.c	24 Dec 2004 22:16:38 -0000	1.54
 +++ arp.c	23 Jan 2005 02:14:10 -0000
 @@ -456,12 +456,12 @@
  {
  	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;
 @@ -475,7 +475,19 @@
  		return 0;
  	if ((buf = malloc(needed)) == NULL)
  		err(1, "malloc");
 -	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
 +	st = sysctl(mib, 6, NULL, &needed, NULL, 0);
 +	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) {
 %%%
 
 --
 Maxim Konovalov



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501230220.j0N2KOHQ020212>