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);

Reply via email to