summaryrefslogtreecommitdiff
path: root/contrib/lease-tools/dhcp_release.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/lease-tools/dhcp_release.c')
-rw-r--r--contrib/lease-tools/dhcp_release.c19
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));