This diff simplifies the get_interface function and makes it more
straightforward, it also makes dhcrelay(8) throw a more informative error
message when running layer 3 mode (default) on interfaces without an
address.
I'll use this code later to be able to get_interfaces() without an IP address.
ok?
Index: bpf.c
===================================================================
RCS file: /cvs/src/usr.sbin/dhcrelay/bpf.c,v
retrieving revision 1.11
diff -u -p -r1.11 bpf.c
--- bpf.c 28 May 2016 07:00:18 -0000 1.11
+++ bpf.c 7 Dec 2016 16:29:14 -0000
@@ -75,7 +75,7 @@ if_register_bpf(struct interface_info *i
error("Can't open bpf device: %m");
/* Set the BPF device to point at this interface. */
- if (ioctl(sock, BIOCSETIF, info->ifp) == -1)
+ if (ioctl(sock, BIOCSETIF, &info->ifr) == -1)
error("Can't attach interface %s to bpf device: %m",
info->name);
Index: dhcpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/dhcrelay/dhcpd.h,v
retrieving revision 1.15
diff -u -p -r1.15 dhcpd.h
--- dhcpd.h 7 Dec 2016 13:19:18 -0000 1.15
+++ dhcpd.h 7 Dec 2016 16:29:14 -0000
@@ -76,7 +76,7 @@ struct interface_info {
size_t rbuf_max;
size_t rbuf_offset;
size_t rbuf_len;
- struct ifreq *ifp;
+ struct ifreq ifr;
int noifmedia;
int errors;
int dead;
Index: dhcrelay.c
===================================================================
RCS file: /cvs/src/usr.sbin/dhcrelay/dhcrelay.c,v
retrieving revision 1.44
diff -u -p -r1.44 dhcrelay.c
--- dhcrelay.c 7 Dec 2016 13:19:18 -0000 1.44
+++ dhcrelay.c 7 Dec 2016 16:29:14 -0000
@@ -165,6 +165,9 @@ main(int argc, char *argv[])
if (interfaces == NULL)
error("no interface given");
+ if (interfaces->primary_address.s_addr == 0)
+ error("interface '%s' does not have an address",
+ interfaces->name);
/* Default DHCP/BOOTP ports. */
server_port = htons(SERVER_PORT);
Index: dispatch.c
===================================================================
RCS file: /cvs/src/usr.sbin/dhcrelay/dispatch.c,v
retrieving revision 1.12
diff -u -p -r1.12 dispatch.c
--- dispatch.c 7 Dec 2016 13:19:18 -0000 1.12
+++ dispatch.c 7 Dec 2016 16:29:14 -0000
@@ -79,15 +79,14 @@ get_interface(const char *ifname, void (
{
struct interface_info *iface;
struct ifaddrs *ifap, *ifa;
- struct ifreq *tif;
- struct sockaddr_in foo;
+ struct sockaddr_in *sin;
if ((iface = calloc(1, sizeof(*iface))) == NULL)
error("failed to allocate memory");
if (strlcpy(iface->name, ifname, sizeof(iface->name)) >=
sizeof(iface->name))
- error("interface name too long");
+ error("interface name '%s' too long", ifname);
if (getifaddrs(&ifap) != 0)
error("getifaddrs failed");
@@ -120,31 +119,23 @@ get_interface(const char *ifname, void (
memcpy(iface->hw_address.haddr,
LLADDR(foo), foo->sdl_alen);
} else if (ifa->ifa_addr->sa_family == AF_INET) {
- struct iaddr addr;
+ /* We already have the primary address. */
+ if (iface->primary_address.s_addr != 0)
+ continue;
- memcpy(&foo, ifa->ifa_addr, sizeof(foo));
- if (foo.sin_addr.s_addr == htonl(INADDR_LOOPBACK))
+ sin = (struct sockaddr_in *)ifa->ifa_addr;
+ if (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK))
continue;
- if (!iface->ifp) {
- int len = IFNAMSIZ + ifa->ifa_addr->sa_len;
- if ((tif = malloc(len)) == NULL)
- error("no space to remember ifp");
- strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);
- memcpy(&tif->ifr_addr, ifa->ifa_addr,
- ifa->ifa_addr->sa_len);
- iface->ifp = tif;
- iface->primary_address = foo.sin_addr;
- }
- addr.len = 4;
- memcpy(addr.iabuf, &foo.sin_addr.s_addr, addr.len);
+ iface->primary_address = sin->sin_addr;
}
}
freeifaddrs(ifap);
- if (!iface->ifp)
- error("%s: not found", iface->name);
+ if (strlcpy(iface->ifr.ifr_name, ifname,
+ sizeof(iface->ifr.ifr_name)) >= sizeof(iface->ifr.ifr_name))
+ error("interface name '%s' too long", ifname);
/* Register the interface... */
if_register_receive(iface);