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 <pb@fasterix.freenix.org>
This commit is contained in:
parent
18352eee9a
commit
88edbb05c3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=35003
@ -27,7 +27,7 @@ The Regents of the University of California. All rights reserved.\n";
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -766,18 +766,15 @@ update_arptab(ep, ipaddr)
|
|||||||
register struct rt_msghdr *rt;
|
register struct rt_msghdr *rt;
|
||||||
register int xtype, xindex;
|
register int xtype, xindex;
|
||||||
static pid_t pid;
|
static pid_t pid;
|
||||||
static int r, seq;
|
int r;
|
||||||
static init = 0;
|
static seq;
|
||||||
|
|
||||||
if (!init) {
|
|
||||||
r = socket(PF_ROUTE, SOCK_RAW, 0);
|
r = socket(PF_ROUTE, SOCK_RAW, 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
syslog(LOG_ERR, "raw route socket: %m");
|
syslog(LOG_ERR, "raw route socket: %m");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
++init;
|
|
||||||
}
|
|
||||||
|
|
||||||
ar = &sin_inarp;
|
ar = &sin_inarp;
|
||||||
ar->sin_addr.s_addr = ipaddr;
|
ar->sin_addr.s_addr = ipaddr;
|
||||||
@ -797,6 +794,7 @@ update_arptab(ep, ipaddr)
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
if (write(r, rt, rt->rtm_msglen) < 0 && errno != ESRCH) {
|
if (write(r, rt, rt->rtm_msglen) < 0 && errno != ESRCH) {
|
||||||
syslog(LOG_ERR, "rtmsg get write: %m");
|
syslog(LOG_ERR, "rtmsg get write: %m");
|
||||||
|
close(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
@ -804,6 +802,7 @@ update_arptab(ep, ipaddr)
|
|||||||
} while (cc > 0 && (rt->rtm_seq != seq || rt->rtm_pid != pid));
|
} while (cc > 0 && (rt->rtm_seq != seq || rt->rtm_pid != pid));
|
||||||
if (cc < 0) {
|
if (cc < 0) {
|
||||||
syslog(LOG_ERR, "rtmsg get read: %m");
|
syslog(LOG_ERR, "rtmsg get read: %m");
|
||||||
|
close(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ll2 = (struct sockaddr_dl *)((u_char *)ar2 + ar2->sin_len);
|
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",
|
syslog(LOG_ERR, "bogus link family (%d) wrong net for %08X?\n",
|
||||||
ll2->sdl_family, ipaddr);
|
ll2->sdl_family, ipaddr);
|
||||||
|
close(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xtype = ll2->sdl_type;
|
xtype = ll2->sdl_type;
|
||||||
@ -841,11 +841,13 @@ update_arptab(ep, ipaddr)
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
if (write(r, rt, rt->rtm_msglen) < 0 && errno != EEXIST) {
|
if (write(r, rt, rt->rtm_msglen) < 0 && errno != EEXIST) {
|
||||||
syslog(LOG_ERR, "rtmsg add write: %m");
|
syslog(LOG_ERR, "rtmsg add write: %m");
|
||||||
|
close(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
cc = read(r, rt, sizeof(rtmsg));
|
cc = read(r, rt, sizeof(rtmsg));
|
||||||
} while (cc > 0 && (rt->rtm_seq != seq || rt->rtm_pid != pid));
|
} while (cc > 0 && (rt->rtm_seq != seq || rt->rtm_pid != pid));
|
||||||
|
close(r);
|
||||||
if (cc < 0) {
|
if (cc < 0) {
|
||||||
syslog(LOG_ERR, "rtmsg add read: %m");
|
syslog(LOG_ERR, "rtmsg add read: %m");
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user