summaryrefslogtreecommitdiffstats
path: root/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2009-01-26 22:32:42 +0000
committerRoy Marples <roy@marples.name>2009-01-26 22:32:42 +0000
commit16687a3be1f8c1e6d55cdd691e947e5760eef30c (patch)
tree81ecc57612e06ddcc51dd29a6473ec5aea736f44 /if-bsd.c
parent495c0a77ac4caba2360004b64a1f563d682ac7ee (diff)
downloaddhcpcd-16687a3be1f8c1e6d55cdd691e947e5760eef30c.tar.xz
We need to ensure that manual route deletions are deleted from our internal routing table also. Partial fix for #159.
Diffstat (limited to 'if-bsd.c')
-rw-r--r--if-bsd.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/if-bsd.c b/if-bsd.c
index cc671ee2..46a87aca 100644
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -51,10 +51,14 @@
#include "config.h"
#include "common.h"
+#include "configure.h"
#include "dhcp.h"
#include "if-options.h"
#include "net.h"
+#define ROUNDUP(a) \
+ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+
/* Darwin doesn't define this for some very odd reason */
#ifndef SA_SIZE
# define SA_SIZE(sa) \
@@ -312,6 +316,9 @@ manage_link(int fd,
struct rt_msghdr *rtm;
struct if_announcemsghdr *ifa;
struct if_msghdr *ifm;
+ struct in_addr dst, net, gate;
+ struct sockaddr *sa;
+ struct sockaddr_in *sin;
for (;;) {
bytes = read(fd, buffer, BUFFER_LEN);
@@ -343,6 +350,31 @@ manage_link(int fd,
if (if_indextoname(ifm->ifm_index, ifname))
if_carrier(ifname);
break;
+ case RTM_DELETE:
+ if (!(rtm->rtm_addrs & RTA_DST) ||
+ !(rtm->rtm_addrs & RTA_GATEWAY) ||
+ !(rtm->rtm_addrs & RTA_NETMASK))
+ break;
+ if (rtm->rtm_pid == getpid())
+ break;
+ sa = (struct sockaddr *)(rtm + 1);
+ if (sa->sa_family != AF_INET)
+ break;
+ sin = (struct sockaddr_in *)sa;
+ memcpy(&dst.s_addr, &sin->sin_addr.s_addr,
+ sizeof(dst.s_addr));
+ sa = (struct sockaddr *)
+ (ROUNDUP(sa->sa_len) + (char *)sa);
+ sin = (struct sockaddr_in *)sa;
+ memcpy(&gate.s_addr, &sin->sin_addr.s_addr,
+ sizeof(gate.s_addr));
+ sa = (struct sockaddr *)
+ (ROUNDUP(sa->sa_len) + (char *)sa);
+ sin = (struct sockaddr_in *)sa;
+ memcpy(&net.s_addr, &sin->sin_addr.s_addr,
+ sizeof(net.s_addr));
+ route_deleted(&dst, &net, &gate);
+ break;
}
}
}