mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-27 16:39:08 +00:00
Fix up new rarpd.
This includes the following changes: - Support for poking ARP entries into the local table is now built in, so the arptab.c module I hacked together is no longer needed. - rarp_process() and rarp_reply() now accept a len argument which is passed down from rarp_loop() which tells rarp_reply() exactly how long the original RARP frame was. (Usually, it's 60 bytes, which is the minimum.) Previously, the length was calculated using the sum of sizeof(struct ether_header) + sizeof(struct ether_arp) (plus the ethernet frame header, I think). The result was a total packet length of 42 bytes. Now, rarp_reply() sends out packets that are the same size as those it recieves (60 bytes). This agrees with the behavior of rarpd on SunOS (as observed with tcpdump). The unused extra bytes are zeroed.
This commit is contained in:
parent
557201898b
commit
867de4336b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=19859
@ -1,9 +1,10 @@
|
||||
# from: @(#)Makefile 5.8 (Berkeley) 7/28/90
|
||||
# $Id: Makefile,v 1.2 1995/03/03 22:20:12 wpaul Exp $
|
||||
# $Id: Makefile,v 1.3 1995/04/02 01:35:53 wpaul Exp $
|
||||
|
||||
PROG= rarpd
|
||||
MAN8= rarpd.8
|
||||
SRCS= rarpd.c arptab.c
|
||||
SRCS= rarpd.c
|
||||
|
||||
CFLAGS+= -DTFTP_DIR=\"/tftpboot\"
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,219 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1984, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1984, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)arp.c 8.2 (Berkeley) 1/2/94";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* set arp table entries
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <nlist.h>
|
||||
#include <stdio.h>
|
||||
#include <paths.h>
|
||||
#include <syslog.h>
|
||||
|
||||
extern int errno;
|
||||
static int pid;
|
||||
static int s = -1;
|
||||
|
||||
getsocket() {
|
||||
if (s < 0) {
|
||||
s = socket(PF_ROUTE, SOCK_RAW, 0);
|
||||
if (s < 0) {
|
||||
perror("arp: socket");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct sockaddr_in so_mask = {8, 0, 0, { 0xffffffff}};
|
||||
struct sockaddr_inarp blank_sin = {sizeof(blank_sin), AF_INET }, sin_m;
|
||||
struct sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m;
|
||||
int expire_time, flags, export_only, doing_proxy;
|
||||
struct {
|
||||
struct rt_msghdr m_rtm;
|
||||
char m_space[512];
|
||||
} m_rtmsg;
|
||||
|
||||
/*
|
||||
* Set an individual arp entry
|
||||
*/
|
||||
arptab_set(eaddr, host)
|
||||
u_char *eaddr;
|
||||
u_long host;
|
||||
{
|
||||
register struct sockaddr_inarp *sin = &sin_m;
|
||||
register struct sockaddr_dl *sdl;
|
||||
register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm);
|
||||
struct timeval time;
|
||||
|
||||
getsocket();
|
||||
pid = getpid();
|
||||
sdl_m = blank_sdl;
|
||||
sin_m = blank_sin;
|
||||
sin->sin_addr.s_addr = host;
|
||||
bcopy((char *)eaddr, (u_char *)LLADDR(&sdl_m), 6);
|
||||
sdl_m.sdl_alen = 6;
|
||||
doing_proxy = flags = export_only = expire_time = 0;
|
||||
gettimeofday(&time, 0);
|
||||
expire_time = time.tv_sec + 20 * 60;
|
||||
|
||||
tryagain:
|
||||
if (rtmsg(RTM_GET) < 0) {
|
||||
syslog(LOG_ERR,"%s: %m", inet_ntoa(sin->sin_addr));
|
||||
return (1);
|
||||
}
|
||||
sin = (struct sockaddr_inarp *)(rtm + 1);
|
||||
sdl = (struct sockaddr_dl *)(sin->sin_len + (char *)sin);
|
||||
if (sin->sin_addr.s_addr == sin_m.sin_addr.s_addr) {
|
||||
if (sdl->sdl_family == AF_LINK &&
|
||||
(rtm->rtm_flags & RTF_LLINFO) &&
|
||||
!(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) {
|
||||
case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
|
||||
case IFT_ISO88024: case IFT_ISO88025:
|
||||
goto overwrite;
|
||||
}
|
||||
if (doing_proxy == 0) {
|
||||
syslog(LOG_ERR, "arptab_set: can only proxy for %s\n", inet_ntoa(sin->sin_addr));
|
||||
return (1);
|
||||
}
|
||||
if (sin_m.sin_other & SIN_PROXY) {
|
||||
syslog(LOG_ERR,"arptab_set: proxy entry exists for non 802 device\n");
|
||||
return(1);
|
||||
}
|
||||
sin_m.sin_other = SIN_PROXY;
|
||||
export_only = 1;
|
||||
goto tryagain;
|
||||
}
|
||||
overwrite:
|
||||
if (sdl->sdl_family != AF_LINK) {
|
||||
syslog(LOG_ERR,"arptab_set: cannot intuit interface index and type for %s\n", inet_ntoa(sin->sin_addr));
|
||||
return (1);
|
||||
}
|
||||
sdl_m.sdl_type = sdl->sdl_type;
|
||||
sdl_m.sdl_index = sdl->sdl_index;
|
||||
return (rtmsg(RTM_ADD));
|
||||
}
|
||||
|
||||
rtmsg(cmd)
|
||||
{
|
||||
static int seq;
|
||||
int rlen;
|
||||
register struct rt_msghdr *rtm = &m_rtmsg.m_rtm;
|
||||
register char *cp = m_rtmsg.m_space;
|
||||
register int l;
|
||||
|
||||
errno = 0;
|
||||
if (cmd == RTM_DELETE)
|
||||
goto doit;
|
||||
bzero((char *)&m_rtmsg, sizeof(m_rtmsg));
|
||||
rtm->rtm_flags = flags;
|
||||
rtm->rtm_version = RTM_VERSION;
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
syslog(LOG_ERR, "arptap_set: internal wrong cmd\n");
|
||||
exit(1);
|
||||
case RTM_ADD:
|
||||
rtm->rtm_addrs |= RTA_GATEWAY;
|
||||
rtm->rtm_rmx.rmx_expire = expire_time;
|
||||
rtm->rtm_inits = RTV_EXPIRE;
|
||||
rtm->rtm_flags |= (RTF_HOST | RTF_STATIC);
|
||||
sin_m.sin_other = 0;
|
||||
if (doing_proxy) {
|
||||
if (export_only)
|
||||
sin_m.sin_other = SIN_PROXY;
|
||||
else {
|
||||
rtm->rtm_addrs |= RTA_NETMASK;
|
||||
rtm->rtm_flags &= ~RTF_HOST;
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case RTM_GET:
|
||||
rtm->rtm_addrs |= RTA_DST;
|
||||
}
|
||||
#define NEXTADDR(w, s) \
|
||||
if (rtm->rtm_addrs & (w)) { \
|
||||
bcopy((char *)&s, cp, sizeof(s)); cp += sizeof(s);}
|
||||
|
||||
NEXTADDR(RTA_DST, sin_m);
|
||||
NEXTADDR(RTA_GATEWAY, sdl_m);
|
||||
NEXTADDR(RTA_NETMASK, so_mask);
|
||||
|
||||
rtm->rtm_msglen = cp - (char *)&m_rtmsg;
|
||||
doit:
|
||||
l = rtm->rtm_msglen;
|
||||
rtm->rtm_seq = ++seq;
|
||||
rtm->rtm_type = cmd;
|
||||
if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) {
|
||||
if (errno != ESRCH && errno != EEXIST) {
|
||||
syslog(LOG_ERR, "writing to routing socket: %m");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
do {
|
||||
l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
|
||||
} while (l > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid));
|
||||
if (l < 0)
|
||||
syslog(LOG_ERR, "arptab_set: read from routing socket: %m");
|
||||
return (0);
|
||||
}
|
@ -1,224 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1990, 1993 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"@(#) $Header: etherent.c,v 1.4 96/06/14 20:34:25 leres Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef ETHERS_FILE
|
||||
#define ETHERS_FILE "/etc/ethers"
|
||||
#endif
|
||||
|
||||
struct etherent {
|
||||
u_char addr[6];
|
||||
char name[122];
|
||||
};
|
||||
|
||||
static FILE *ether_fp = NULL;
|
||||
|
||||
|
||||
/* Hex digit to integer. */
|
||||
static inline int
|
||||
xdtoi(c)
|
||||
int c;
|
||||
{
|
||||
|
||||
if (isdigit(c))
|
||||
return c - '0';
|
||||
else if (islower(c))
|
||||
return c - 'a' + 10;
|
||||
else
|
||||
return c - 'A' + 10;
|
||||
}
|
||||
|
||||
static inline int
|
||||
skip_space(f)
|
||||
FILE *f;
|
||||
{
|
||||
int c;
|
||||
|
||||
do {
|
||||
c = getc(f);
|
||||
} while (isspace(c) && c != '\n');
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline int
|
||||
skip_line(f)
|
||||
FILE *f;
|
||||
{
|
||||
int c;
|
||||
|
||||
do
|
||||
c = getc(f);
|
||||
while (c != '\n' && c != EOF);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static struct etherent *
|
||||
next_etherent(fp)
|
||||
FILE *fp;
|
||||
{
|
||||
register int c, d, i;
|
||||
char *bp;
|
||||
static struct etherent e;
|
||||
static int nline = 1;
|
||||
top:
|
||||
while (nline) {
|
||||
/* Find addr */
|
||||
c = skip_space(fp);
|
||||
if (c == '\n')
|
||||
continue;
|
||||
/* If this is a comment, or first thing on line
|
||||
cannot be etehrnet address, skip the line. */
|
||||
else if (!isxdigit(c))
|
||||
c = skip_line(fp);
|
||||
else {
|
||||
/* must be the start of an address */
|
||||
for (i = 0; i < 6; i += 1) {
|
||||
d = xdtoi(c);
|
||||
c = getc(fp);
|
||||
if (c != ':') {
|
||||
d <<= 4;
|
||||
d |= xdtoi(c);
|
||||
c = getc(fp);
|
||||
}
|
||||
e.addr[i] = d;
|
||||
if (c != ':')
|
||||
break;
|
||||
c = getc(fp);
|
||||
}
|
||||
nline = 0;
|
||||
}
|
||||
if (c == EOF)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If we started a new line, 'c' holds the char past the ether addr,
|
||||
which we assume is white space. If we are continuing a line,
|
||||
'c' is garbage. In either case, we can throw it away. */
|
||||
|
||||
c = skip_space(fp);
|
||||
if (c == '\n') {
|
||||
nline = 1;
|
||||
goto top;
|
||||
}
|
||||
else if (c == '#') {
|
||||
(void)skip_line(fp);
|
||||
nline = 1;
|
||||
goto top;
|
||||
}
|
||||
else if (c == EOF)
|
||||
return NULL;
|
||||
|
||||
/* Must be a name. */
|
||||
bp = e.name;
|
||||
/* Use 'd' to prevent buffer overflow. */
|
||||
d = sizeof(e.name) - 1;
|
||||
do {
|
||||
*bp++ = c;
|
||||
c = getc(fp);
|
||||
} while (!isspace(c) && c != EOF && --d > 0);
|
||||
*bp = '\0';
|
||||
if (c == '\n')
|
||||
nline = 1;
|
||||
|
||||
return &e;
|
||||
}
|
||||
|
||||
/* Open/rewind the ethers files; returns 1 if file was reopened */
|
||||
int
|
||||
ether_rewind()
|
||||
{
|
||||
struct stat st;
|
||||
static long mtime = 0, ctime = 0;
|
||||
|
||||
if (ether_fp != NULL) {
|
||||
if (fstat(fileno(ether_fp), &st) < 0 ||
|
||||
mtime != st.st_mtime || ctime != st.st_ctime ||
|
||||
fseek(ether_fp, 0L, SEEK_SET) < 0) {
|
||||
fclose(ether_fp);
|
||||
ether_fp = NULL;
|
||||
}
|
||||
}
|
||||
if (ether_fp == NULL) {
|
||||
ether_fp = fopen(ETHERS_FILE, "r");
|
||||
if (ether_fp == NULL)
|
||||
return (-1);
|
||||
if (fstat(fileno(ether_fp), &st) < 0) {
|
||||
fclose(ether_fp);
|
||||
ether_fp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
mtime = st.st_mtime;
|
||||
ctime = st.st_ctime;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Map an ethernet address to a name; returns 0 on success, else 1. */
|
||||
int
|
||||
ether_ntohost(name, ea)
|
||||
register char *name;
|
||||
register u_char *ea;
|
||||
{
|
||||
register struct etherent *ep;
|
||||
|
||||
if (ether_rewind() < 0)
|
||||
return (1);
|
||||
|
||||
while ((ep = next_etherent(ether_fp)) != NULL)
|
||||
if (bcmp(ep->addr, ea, 6) == 0) {
|
||||
strcpy(name, ep->name);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Map an ethernet name to an address; returns 0 on success, else 1. */
|
||||
int
|
||||
ether_hostton(name, ea)
|
||||
register char *name;
|
||||
register u_char *ea;
|
||||
{
|
||||
register struct etherent *ep;
|
||||
|
||||
if (ether_rewind() < 0)
|
||||
return (1);
|
||||
|
||||
while ((ep = next_etherent(ether_fp)) != NULL)
|
||||
if (strcmp(ep->name, name) == 0) {
|
||||
bcopy(ep->addr, ea, 6);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user