From 88edbb05c3a116bcdcda7b4fe113bea3d342fff8 Mon Sep 17 00:00:00 2001 From: Ollivier Robert Date: Thu, 2 Apr 1998 13:20:15 +0000 Subject: [PATCH] Fix bug in rarpd: Explanation of the bug: when processing its first request, rarpd opens a routing socket to send requests to the arp table. It keeps that socket open afterwards, while waiting for new RARP requests. Meanwhile, the data received on the routing socket fill up until they are about 8Kbytes in size. Any additional data is lost. When rarpd receives its next RARP request, it tries to access the ARP table via a routing socket call, then waits for the answer to its own request. This answer is lost because the received data is already filled: when looking for the reply, rarpd receives only 8kbytes worth of data, then loops waiting forever. Someone please test it on -STABLE and commit it. We can close the PR when testing on STABLE is done. PR: bin/5669 Submitted by: Pierre Beyssac --- usr.sbin/rarpd/rarpd.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/usr.sbin/rarpd/rarpd.c b/usr.sbin/rarpd/rarpd.c index 619e30753095..f09c1d668121 100644 --- a/usr.sbin/rarpd/rarpd.c +++ b/usr.sbin/rarpd/rarpd.c @@ -27,7 +27,7 @@ The Regents of the University of California. All rights reserved.\n"; #ifndef lint static const char rcsid[] = - "$Id: rarpd.c,v 1.17 1997/10/13 11:03:36 charnier Exp $"; + "$Id: rarpd.c,v 1.18 1998/01/16 17:38:54 bde Exp $"; #endif /* not lint */ /* @@ -766,18 +766,15 @@ update_arptab(ep, ipaddr) register struct rt_msghdr *rt; register int xtype, xindex; static pid_t pid; - static int r, seq; - static init = 0; + int r; + static seq; - if (!init) { - r = socket(PF_ROUTE, SOCK_RAW, 0); - if (r < 0) { - syslog(LOG_ERR, "raw route socket: %m"); - exit(1); - } - pid = getpid(); - ++init; + r = socket(PF_ROUTE, SOCK_RAW, 0); + if (r < 0) { + syslog(LOG_ERR, "raw route socket: %m"); + exit(1); } + pid = getpid(); ar = &sin_inarp; ar->sin_addr.s_addr = ipaddr; @@ -797,6 +794,7 @@ update_arptab(ep, ipaddr) errno = 0; if (write(r, rt, rt->rtm_msglen) < 0 && errno != ESRCH) { syslog(LOG_ERR, "rtmsg get write: %m"); + close(r); return; } do { @@ -804,6 +802,7 @@ update_arptab(ep, ipaddr) } while (cc > 0 && (rt->rtm_seq != seq || rt->rtm_pid != pid)); if (cc < 0) { syslog(LOG_ERR, "rtmsg get read: %m"); + close(r); return; } ll2 = (struct sockaddr_dl *)((u_char *)ar2 + ar2->sin_len); @@ -815,6 +814,7 @@ update_arptab(ep, ipaddr) */ syslog(LOG_ERR, "bogus link family (%d) wrong net for %08X?\n", ll2->sdl_family, ipaddr); + close(r); return; } xtype = ll2->sdl_type; @@ -841,11 +841,13 @@ update_arptab(ep, ipaddr) errno = 0; if (write(r, rt, rt->rtm_msglen) < 0 && errno != EEXIST) { syslog(LOG_ERR, "rtmsg add write: %m"); + close(r); return; } do { cc = read(r, rt, sizeof(rtmsg)); } while (cc > 0 && (rt->rtm_seq != seq || rt->rtm_pid != pid)); + close(r); if (cc < 0) { syslog(LOG_ERR, "rtmsg add read: %m"); return;