diff options
Diffstat (limited to 'contrib/lease-tools/dhcp_release.c')
-rw-r--r-- | contrib/lease-tools/dhcp_release.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/contrib/lease-tools/dhcp_release.c b/contrib/lease-tools/dhcp_release.c index 201fcd3..30e77c6 100644 --- a/contrib/lease-tools/dhcp_release.c +++ b/contrib/lease-tools/dhcp_release.c @@ -178,7 +178,7 @@ static int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask) return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr); } -static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index) +static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index, int ifrfd, struct ifreq *ifr) { struct sockaddr_nl addr; struct nlmsghdr *h; @@ -218,7 +218,17 @@ static struct in_addr find_interface(struct in_addr client, int fd, unsigned int for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len)) if (h->nlmsg_type == NLMSG_DONE) - exit(0); + { + /* No match found, return first address as src/dhcp.c code does */ + ifr->ifr_addr.sa_family = AF_INET; + if (ioctl(ifrfd, SIOCGIFADDR, ifr) != -1) + return ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; + else + { + fprintf(stderr, "error: local IPv4 address not found\n"); + exit(1); + } + } else if (h->nlmsg_type == RTM_NEWADDR) { struct ifaddrmsg *ifa = NLMSG_DATA(h); @@ -270,7 +280,8 @@ int main(int argc, char **argv) /* This voodoo fakes up a packet coming from the correct interface, which really matters for a DHCP server */ - strcpy(ifr.ifr_name, argv[1]); + strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)-1); + ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0'; if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1) { perror("cannot setup interface"); @@ -284,7 +295,7 @@ int main(int argc, char **argv) } lease.s_addr = inet_addr(argv[2]); - server = find_interface(lease, nl, if_nametoindex(argv[1])); + server = find_interface(lease, nl, if_nametoindex(argv[1]), fd, &ifr); memset(&packet, 0, sizeof(packet)); |