aboutsummaryrefslogtreecommitdiff
path: root/libexec/bootpd/hwaddr.c
diff options
context:
space:
mode:
authorPaul Traina <pst@FreeBSD.org>1996-01-23 01:35:04 +0000
committerPaul Traina <pst@FreeBSD.org>1996-01-23 01:35:04 +0000
commite08ac58bbe2be2817736b8f4b32c75f8d55359df (patch)
tree145d6ce072fde2eeda7863a006d92fd2c1eec916 /libexec/bootpd/hwaddr.c
parenta270abb407a717b6c38a10d1c996af9ac907f84a (diff)
downloadsrc-e08ac58bbe2be2817736b8f4b32c75f8d55359df.tar.gz
src-e08ac58bbe2be2817736b8f4b32c75f8d55359df.zip
Notes
Diffstat (limited to 'libexec/bootpd/hwaddr.c')
-rw-r--r--libexec/bootpd/hwaddr.c113
1 files changed, 79 insertions, 34 deletions
diff --git a/libexec/bootpd/hwaddr.c b/libexec/bootpd/hwaddr.c
index 840b95333567..191fadced5de 100644
--- a/libexec/bootpd/hwaddr.c
+++ b/libexec/bootpd/hwaddr.c
@@ -17,8 +17,19 @@
#include <fcntl.h>
#endif
+#ifdef _AIX32
+#include <sys/time.h> /* for struct timeval in net/if.h */
+#include <net/if.h> /* for struct ifnet in net/if_arp.h */
+#endif
+
#include <net/if_arp.h>
#include <netinet/in.h>
+
+#ifdef WIN_TCP
+#include <netinet/if_ether.h>
+#include <sys/dlpi.h>
+#endif
+
#include <stdio.h>
#ifndef NO_UNISTD
#include <unistd.h>
@@ -33,11 +44,8 @@
#define bcmp(a,b,c) memcmp(a,b,c)
#endif
-/* For BSD 4.4, set arp entry by writing to routing socket */
-#if defined(BSD)
-#if BSD >= 199306
-extern int bsd_arp_set __P((struct in_addr *, char *, int));
-#endif
+#ifndef ATF_INUSE /* Not defined on some systems (i.e. Linux) */
+#define ATF_INUSE 0
#endif
#include "bptypes.h"
@@ -72,21 +80,43 @@ int hwinfocnt = sizeof(hwinfolist) / sizeof(hwinfolist[0]);
* bound to hardware address 'ha' of length 'len'.
*/
void
-setarp(s, ia, ha, len)
+setarp(s, ia, hafamily, haddr, halen)
int s; /* socket fd */
- struct in_addr *ia;
- u_char *ha;
- int len;
+ struct in_addr *ia; /* protocol address */
+ int hafamily; /* HW address family */
+ u_char *haddr; /* HW address data */
+ int halen;
{
#ifdef SIOCSARP
+#ifdef WIN_TCP
+ /* This is an SVR4 with different networking code from
+ * Wollongong WIN-TCP. Not quite like the Lachman code.
+ * Code from: drew@drewsun.FEITH.COM (Andrew B. Sudell)
+ */
+#undef SIOCSARP
+#define SIOCSARP ARP_ADD
+ struct arptab arpreq; /* Arp table entry */
+
+ bzero((caddr_t) &arpreq, sizeof(arpreq));
+ arpreq.at_flags = ATF_COM;
+
+ /* Set up IP address */
+ arpreq.at_in = ia->s_addr;
+
+ /* Set up Hardware Address */
+ bcopy(haddr, arpreq.at_enaddr, halen);
+
+ /* Set the Date Link type. */
+ /* XXX - Translate (hafamily) to dltype somehow? */
+ arpreq.at_dltype = DL_ETHER;
+
+#else /* WIN_TCP */
+ /* Good old Berkeley way. */
struct arpreq arpreq; /* Arp request ioctl block */
struct sockaddr_in *si;
-#ifdef SVR4
- int fd;
- struct strioctl iocb;
-#endif /* SVR4 */
+ char *p;
- bzero((caddr_t) & arpreq, sizeof(arpreq));
+ bzero((caddr_t) &arpreq, sizeof(arpreq));
arpreq.arp_flags = ATF_INUSE | ATF_COM;
/* Set up the protocol address. */
@@ -95,7 +125,18 @@ setarp(s, ia, ha, len)
si->sin_addr = *ia;
/* Set up the hardware address. */
- bcopy(ha, arpreq.arp_ha.sa_data, len);
+#ifdef __linux__ /* XXX - Do others need this? -gwr */
+ /*
+ * Linux requires the sa_family field set.
+ * longyear@netcom.com (Al Longyear)
+ */
+ arpreq.arp_ha.sa_family = hafamily;
+#endif /* linux */
+
+ /* This variable is just to help catch type mismatches. */
+ p = arpreq.arp_ha.sa_data;
+ bcopy(haddr, p, halen);
+#endif /* WIN_TCP */
#ifdef SVR4
/*
@@ -106,18 +147,22 @@ setarp(s, ia, ha, len)
* bear@upsys.se (Bj|rn Sj|holm),
* Michael Kuschke <Michael.Kuschke@Materna.DE>,
*/
- if ((fd=open("/dev/arp", O_RDWR)) < 0) {
- report(LOG_ERR, "open /dev/arp: %s\n", get_errmsg());
- }
- iocb.ic_cmd = SIOCSARP;
- iocb.ic_timout = 0;
- iocb.ic_dp = (char *)&arpreq;
- iocb.ic_len = sizeof(arpreq);
- if (ioctl(fd, I_STR, (caddr_t)&iocb) < 0) {
- report(LOG_ERR, "ioctl I_STR: %s\n", get_errmsg());
- }
- close (fd);
+ {
+ int fd;
+ struct strioctl iocb;
+ if ((fd=open("/dev/arp", O_RDWR)) < 0) {
+ report(LOG_ERR, "open /dev/arp: %s\n", get_errmsg());
+ }
+ iocb.ic_cmd = SIOCSARP;
+ iocb.ic_timout = 0;
+ iocb.ic_dp = (char *)&arpreq;
+ iocb.ic_len = sizeof(arpreq);
+ if (ioctl(fd, I_STR, (caddr_t)&iocb) < 0) {
+ report(LOG_ERR, "ioctl I_STR: %s\n", get_errmsg());
+ }
+ close (fd);
+ }
#else /* SVR4 */
/*
* On SunOS, the ioctl sometimes returns ENXIO, and it
@@ -125,30 +170,30 @@ setarp(s, ia, ha, len)
* to add is already in the cache. (Sigh...)
* XXX - Should this error simply be ignored? -gwr
*/
- if (ioctl(s, SIOCSARP, (caddr_t) & arpreq) < 0) {
+ if (ioctl(s, SIOCSARP, (caddr_t) &arpreq) < 0) {
report(LOG_ERR, "ioctl SIOCSARP: %s", get_errmsg());
}
#endif /* SVR4 */
#else /* SIOCSARP */
-#if defined(BSD) && (BSD >= 199306)
- bsd_arp_set(ia, ha, len);
-#else /* Not BSD 4.4, and SIOCSARP not defined */
/*
* Oh well, SIOCSARP is not defined. Just run arp(8).
+ * Need to delete partial entry first on some systems.
* XXX - Gag!
*/
- char buf[256];
int status;
+ char buf[256];
+ char *a;
+ extern char *inet_ntoa();
- sprintf(buf, "arp -s %s %s temp",
- inet_ntoa(*ia), haddrtoa(ha, len));
+ a = inet_ntoa(*ia);
+ sprintf(buf, "arp -d %s; arp -s %s %s temp",
+ a, a, haddrtoa(haddr, halen));
if (debug > 2)
report(LOG_INFO, buf);
status = system(buf);
if (status)
report(LOG_ERR, "arp failed, exit code=0x%x", status);
return;
-#endif /* ! 4.4 BSD */
#endif /* SIOCSARP */
}