Index: bpf.c =================================================================== RCS file: /cvs/src/usr.sbin/dhcpd/bpf.c,v diff -u -p -r1.21 bpf.c --- bpf.c 7 Feb 2025 21:48:26 -0000 1.21 +++ bpf.c 10 Jun 2025 06:48:17 -0000 @@ -75,13 +75,17 @@ ssize_t send_packet (struct interface_i int if_register_bpf(struct interface_info *info) { + struct ifreq ifr; int sock; if ((sock = open("/dev/bpf", O_RDWR)) == -1) fatal("Can't open bpf device"); + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, info->name, sizeof(ifr.ifr_name)); + /* Set the BPF device to point at this interface. */ - if (ioctl(sock, BIOCSETIF, info->ifp) == -1) + if (ioctl(sock, BIOCSETIF, &ifr) == -1) fatal("Can't attach interface %s to bpf device", info->name); info->send_packet = send_packet; Index: dhcpd.h =================================================================== RCS file: /cvs/src/usr.sbin/dhcpd/dhcpd.h,v diff -u -p -r1.73 dhcpd.h --- dhcpd.h 10 Jun 2025 06:29:53 -0000 1.73 +++ dhcpd.h 10 Jun 2025 06:48:17 -0000 @@ -264,8 +264,6 @@ struct interface_info { size_t rbuf_offset; /* Current offset into buffer. */ size_t rbuf_len; /* Length of data in buffer. */ - struct ifreq *ifp; /* Pointer to ifreq struct. */ - int noifmedia; int errors; int dead; Index: dispatch.c =================================================================== RCS file: /cvs/src/usr.sbin/dhcpd/dispatch.c,v diff -u -p -r1.50 dispatch.c --- dispatch.c 10 Jun 2025 06:29:53 -0000 1.50 +++ dispatch.c 10 Jun 2025 06:48:17 -0000 @@ -91,7 +91,6 @@ discover_interfaces(void) struct shared_network *share; struct sockaddr_in foo; int ir; - struct ifreq *tif; struct ifaddrs *ifap, *ifa; if (getifaddrs(&ifap) != 0) @@ -159,21 +158,9 @@ discover_interfaces(void) if (foo.sin_addr.s_addr == htonl (INADDR_LOOPBACK)) continue; - /* If this is the first real IP address we've - found, keep a pointer to ifreq structure in - which we found it. */ - if (!tmp->ifp) { - int len = (IFNAMSIZ + ifa->ifa_addr->sa_len); - tif = malloc(len); - if (!tif) - fatalx("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); - tmp->ifp = tif; + /* Is this is the first real IP address we've found? */ + if (tmp->primary_address.s_addr == htonl(INADDR_ANY)) tmp->primary_address = foo.sin_addr; - } } } @@ -195,7 +182,7 @@ discover_interfaces(void) continue; } - if (!tmp->ifp) { + if (tmp->primary_address.s_addr == htonl(INADDR_ANY)) { log_warnx("Can't listen on %s - it has no IP address.", tmp->name); /* Remove tmp from the list of interfaces. */ @@ -206,11 +193,9 @@ discover_interfaces(void) continue; } - memcpy(&foo, &tmp->ifp->ifr_addr, sizeof tmp->ifp->ifr_addr); - /* Grab the address... */ addr.len = 4; - memcpy(addr.iabuf, &foo.sin_addr.s_addr, addr.len); + memcpy(addr.iabuf, &tmp->primary_address.s_addr, addr.len); /* If there's a registered subnet for this address, connect it together... */ Index: udpsock.c =================================================================== RCS file: /cvs/src/usr.sbin/dhcpd/udpsock.c,v diff -u -p -r1.12 udpsock.c --- udpsock.c 22 May 2025 04:24:11 -0000 1.12 +++ udpsock.c 10 Jun 2025 06:48:17 -0000 @@ -62,10 +62,15 @@ udpsock_startup(struct in_addr bindaddr) fatal("creating a socket failed for udp"); onoff = 1; - if (setsockopt(sock, IPPROTO_IP, IP_RECVIF, &onoff, sizeof(onoff)) != - 0) + if (setsockopt(sock, IPPROTO_IP, IP_RECVIF, + &onoff, sizeof(onoff)) != 0) fatal("setsocketopt IP_RECVIF failed for udp"); + onoff = 1; + if (setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, + &onoff, sizeof(onoff)) != 0) + fatal("setsocketopt IP_RECVDSTADDR failed for udp"); + sin4.sin_family = AF_INET; sin4.sin_len = sizeof(sin4); sin4.sin_addr = bindaddr; @@ -84,8 +89,7 @@ udpsock_startup(struct in_addr bindaddr) void udpsock_handler(struct protocol *protocol) { - int sockio; - char cbuf[256], ifname[IF_NAMESIZE]; + char ifname[IF_NAMESIZE]; ssize_t len; struct udpsock *udpsock = protocol->local; struct msghdr m; @@ -95,11 +99,12 @@ udpsock_handler(struct protocol *protoco struct sockaddr_in *sin4; struct sockaddr_dl *sdl = NULL; struct interface_info iface; + char cbuf[CMSG_SPACE(sizeof(*sdl)) + + CMSG_SPACE(sizeof(iface.primary_address))]; struct iaddr from, addr; unsigned char packetbuf[4095]; struct dhcp_packet *packet = (struct dhcp_packet *)packetbuf; struct hardware hw; - struct ifreq ifr; struct subnet *subnet; memset(&hw, 0, sizeof(hw)); @@ -130,6 +135,11 @@ udpsock_handler(struct protocol *protoco if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVIF) sdl = (struct sockaddr_dl *)CMSG_DATA(cm); + else if (cm->cmsg_level == IPPROTO_IP && + cm->cmsg_type == IP_RECVDSTADDR) { + iface.primary_address = + *(struct in_addr *)CMSG_DATA(cm); + } } if (sdl == NULL) { log_warnx("could not get the received interface by IP_RECVIF"); @@ -137,28 +147,10 @@ udpsock_handler(struct protocol *protoco } if_indextoname(sdl->sdl_index, ifname); - if ((sockio = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - log_warn("socket creation failed"); - return; - } - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sockio, SIOCGIFADDR, &ifr, sizeof(ifr)) == -1) { - log_warn("Failed to get address for %s", ifname); - close(sockio); - return; - } - close(sockio); - - if (ifr.ifr_addr.sa_family != AF_INET) - return; - iface.is_udpsock = 1; iface.send_packet = udpsock_send_packet; iface.wfdesc = udpsock->sock; - iface.ifp = 𝔦 iface.index = sdl->sdl_index; - iface.primary_address = - ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; strlcpy(iface.name, ifname, sizeof(iface.name)); addr.len = 4;