aboutsummaryrefslogtreecommitdiffstats
path: root/if-bsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'if-bsd.c')
-rw-r--r--if-bsd.c94
1 files changed, 58 insertions, 36 deletions
diff --git a/if-bsd.c b/if-bsd.c
index 462ec2a..c3ffcac 100644
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -1,6 +1,6 @@
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2010 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2012 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
@@ -61,9 +61,11 @@
#include "if-options.h"
#include "net.h"
-#define ROUNDUP(a) \
+#ifndef RT_ROUNDUP
+#define RT_ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+#define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len))
+#endif
/* FIXME: Why do we need to check for sa_family 255 */
#define COPYOUT(sin, sa) \
@@ -88,6 +90,15 @@ if_conf(_unused struct interface *iface)
return 0;
}
+#ifdef DEBUG_MEMORY
+static void
+cleanup(void)
+{
+
+ free(link_buf);
+}
+#endif
+
int
init_sockets(void)
{
@@ -127,6 +138,7 @@ getifssid(const char *ifname, char *ssid)
strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name));
ireq.i_type = IEEE80211_IOC_SSID;
ireq.i_val = -1;
+ memset(nwid, 0, sizeof(nwid));
ireq.i_data = &nwid;
if (ioctl(socket_afnet, SIOCG80211, &ireq) == 0) {
retval = ireq.i_len;
@@ -175,9 +187,7 @@ if_address(const struct interface *iface, const struct in_addr *address,
/* ARGSUSED4 */
int
-if_route(const struct interface *iface, const struct in_addr *dest,
- const struct in_addr *net, const struct in_addr *gate,
- _unused int metric, int action)
+if_route(const struct rt *rt, int action)
{
union sockunion {
struct sockaddr sa;
@@ -193,12 +203,12 @@ if_route(const struct interface *iface, const struct in_addr *dest,
struct rt_msghdr hdr;
char buffer[sizeof(su) * 4];
} rtm;
- char *bp = rtm.buffer, *p;
+ char *bp = rtm.buffer;
size_t l;
int retval = 0;
#define ADDSU(_su) { \
- l = ROUNDUP(_su.sa.sa_len); \
+ l = RT_ROUNDUP(_su.sa.sa_len); \
memcpy(bp, &(_su), l); \
bp += l; \
}
@@ -221,12 +231,13 @@ if_route(const struct interface *iface, const struct in_addr *dest,
rtm.hdr.rtm_type = RTM_DELETE;
rtm.hdr.rtm_flags = RTF_UP;
/* None interface subnet routes are static. */
- if (gate->s_addr != INADDR_ANY ||
- net->s_addr != iface->net.s_addr ||
- dest->s_addr != (iface->addr.s_addr & iface->net.s_addr))
+ if (rt->gate.s_addr != INADDR_ANY ||
+ rt->net.s_addr != rt->iface->net.s_addr ||
+ rt->dest.s_addr != (rt->iface->addr.s_addr & rt->iface->net.s_addr))
rtm.hdr.rtm_flags |= RTF_STATIC;
rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
- if (dest->s_addr == gate->s_addr && net->s_addr == INADDR_BROADCAST)
+ if (rt->dest.s_addr == rt->gate.s_addr &&
+ rt->net.s_addr == INADDR_BROADCAST)
rtm.hdr.rtm_flags |= RTF_HOST;
else {
rtm.hdr.rtm_addrs |= RTA_NETMASK;
@@ -236,35 +247,23 @@ if_route(const struct interface *iface, const struct in_addr *dest,
rtm.hdr.rtm_addrs |= RTA_IFA;
}
- ADDADDR(dest);
+ ADDADDR(&rt->dest);
if (rtm.hdr.rtm_flags & RTF_HOST ||
!(rtm.hdr.rtm_flags & RTF_STATIC))
{
/* Make us a link layer socket for the host gateway */
memset(&su, 0, sizeof(su));
su.sdl.sdl_len = sizeof(struct sockaddr_dl);
- link_addr(iface->name, &su.sdl);
+ link_addr(rt->iface->name, &su.sdl);
ADDSU(su);
} else
- ADDADDR(gate);
+ ADDADDR(&rt->gate);
- if (rtm.hdr.rtm_addrs & RTA_NETMASK) {
- /* Ensure that netmask is set correctly */
- memset(&su, 0, sizeof(su));
- su.sin.sin_family = AF_INET;
- su.sin.sin_len = sizeof(su.sin);
- memcpy(&su.sin.sin_addr, &net->s_addr, sizeof(su.sin.sin_addr));
- p = su.sa.sa_len + (char *)&su;
- for (su.sa.sa_len = 0; p > (char *)&su;)
- if (*--p != 0) {
- su.sa.sa_len = 1 + p - (char *)&su;
- break;
- }
- ADDSU(su);
- }
+ if (rtm.hdr.rtm_addrs & RTA_NETMASK)
+ ADDADDR(&rt->net);
if (rtm.hdr.rtm_addrs & RTA_IFA)
- ADDADDR(&iface->addr);
+ ADDADDR(&rt->iface->addr);
rtm.hdr.rtm_msglen = l = bp - (char *)&rtm;
if (write(r_fd, &rtm, l) == -1)
@@ -277,6 +276,11 @@ open_link_socket(void)
{
int fd;
+#ifdef DEBUG_MEMORY
+ if (link_buf == NULL)
+ atexit(cleanup);
+#endif
+
fd = socket(PF_ROUTE, SOCK_RAW, 0);
if (fd != -1) {
set_cloexec(fd);
@@ -298,7 +302,7 @@ get_addrs(int type, char *cp, struct sockaddr **sa)
inet_ntoa(((struct sockaddr_in *)sa[i])->
sin_addr));
#endif
- ADVANCE(cp, sa[i]);
+ RT_ADVANCE(cp, sa[i]);
} else
sa[i] = NULL;
}
@@ -360,13 +364,31 @@ manage_link(int fd)
case RTM_IFINFO:
ifm = (struct if_msghdr *)(void *)p;
memset(ifname, 0, sizeof(ifname));
- if (if_indextoname(ifm->ifm_index, ifname))
- handle_interface(0, ifname);
+ if (!(if_indextoname(ifm->ifm_index, ifname)))
+ break;
+ switch (ifm->ifm_data.ifi_link_state) {
+ case LINK_STATE_DOWN:
+ len = -1;
+ break;
+ case LINK_STATE_UP:
+ len = 1;
+ break;
+ default:
+ /* handle_carrier will re-load
+ * the interface flags and check for
+ * IFF_RUNNING as some drivers that
+ * don't handle link state also don't
+ * set IFF_RUNNING when this routing
+ * message is generated.
+ * As such, it is a race ...*/
+ len = 0;
+ break;
+ }
+ handle_carrier(len, ifm->ifm_flags, ifname);
break;
case RTM_DELETE:
- if (!(rtm->rtm_addrs & RTA_DST) ||
- !(rtm->rtm_addrs & RTA_GATEWAY) ||
- !(rtm->rtm_addrs & RTA_NETMASK))
+ if (~rtm->rtm_addrs &
+ (RTA_DST | RTA_GATEWAY | RTA_NETMASK))
break;
if (rtm->rtm_pid == getpid())
break;