summaryrefslogtreecommitdiffstats
path: root/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-09-02 13:28:11 +0000
committerRoy Marples <roy@marples.name>2008-09-02 13:28:11 +0000
commitfd05b7dcfc61e1a8f1d4f0f7ecd27bb25a6cc7a8 (patch)
treeeefcda1304078e7ee7e7508103cb6e1775ff5513 /if-bsd.c
parentca07508a27a3048ead0c0a411f2cecc84ac97935 (diff)
downloaddhcpcd-fd05b7dcfc61e1a8f1d4f0f7ecd27bb25a6cc7a8.tar.xz
Add an event loop.
Split client.c into smaller files and functions and recode around the event loop. Add multiple interface support using the new event loop. Document changes and outstanding bugs.
Diffstat (limited to 'if-bsd.c')
-rw-r--r--if-bsd.c56
1 files changed, 26 insertions, 30 deletions
diff --git a/if-bsd.c b/if-bsd.c
index bbf1a95d..d44bf4e2 100644
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -58,7 +58,7 @@
#endif
int
-if_address(const char *ifname, const struct in_addr *address,
+if_address(const struct interface *iface, const struct in_addr *address,
const struct in_addr *netmask, const struct in_addr *broadcast,
int action)
{
@@ -74,7 +74,7 @@ if_address(const char *ifname, const struct in_addr *address,
return -1;
memset(&ifa, 0, sizeof(ifa));
- strlcpy(ifa.ifra_name, ifname, sizeof(ifa.ifra_name));
+ strlcpy(ifa.ifra_name, iface->name, sizeof(ifa.ifra_name));
#define ADDADDR(_var, _addr) \
_s.sa = &_var; \
@@ -98,7 +98,7 @@ if_address(const char *ifname, const struct in_addr *address,
}
int
-if_route(const char *ifname, const struct in_addr *destination,
+if_route(const struct interface *iface, const struct in_addr *destination,
const struct in_addr *netmask, const struct in_addr *gateway,
_unused int metric, int action)
{
@@ -120,8 +120,6 @@ if_route(const char *ifname, const struct in_addr *destination,
} rtm;
char *bp = rtm.buffer;
size_t l;
- unsigned char *hwaddr;
- size_t hwlen = 0;
int retval = 0;
if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
@@ -156,21 +154,18 @@ if_route(const char *ifname, const struct in_addr *destination,
if (gateway->s_addr == INADDR_ANY) {
/* Make us a link layer socket */
- hwaddr = xmalloc(sizeof(unsigned char) * HWADDR_LEN);
- do_interface(ifname, hwaddr, &hwlen, NULL, 0, 0);
memset(&su, 0, sizeof(su));
su.sdl.sdl_len = sizeof(su.sdl);
su.sdl.sdl_family = AF_LINK;
- su.sdl.sdl_nlen = strlen(ifname);
- memcpy(&su.sdl.sdl_data, ifname, (size_t)su.sdl.sdl_nlen);
- su.sdl.sdl_alen = hwlen;
+ su.sdl.sdl_nlen = strlen(iface->name);
+ memcpy(&su.sdl.sdl_data, iface->name, (size_t)su.sdl.sdl_nlen);
+ su.sdl.sdl_alen = iface->hwlen;
memcpy(((unsigned char *)&su.sdl.sdl_data) + su.sdl.sdl_nlen,
- hwaddr, (size_t)su.sdl.sdl_alen);
+ iface->hwaddr, (size_t)su.sdl.sdl_alen);
l = SA_SIZE(&(su.sa));
memcpy(bp, &su, l);
bp += l;
- free(hwaddr);
} else {
rtm.hdr.rtm_flags |= RTF_GATEWAY;
ADDADDR(gateway);
@@ -187,34 +182,28 @@ if_route(const char *ifname, const struct in_addr *destination,
}
int
-open_link_socket(struct interface *iface)
+open_link_socket(void)
{
int fd;
fd = socket(PF_ROUTE, SOCK_RAW, 0);
- if (fd == -1)
- return -1;
- set_cloexec(fd);
- if (iface->link_fd != -1)
- close(iface->link_fd);
- iface->link_fd = fd;
- return 0;
+ if (fd != -1)
+ set_cloexec(fd);
+ return fd;
}
#define BUFFER_LEN 2048
int
-link_changed(struct interface *iface)
+link_changed(int fd, const struct interface *ifaces)
{
char buffer[2048], *p;
ssize_t bytes;
struct rt_msghdr *rtm;
struct if_msghdr *ifm;
- int i;
+ const struct interface *iface;
- if ((i = if_nametoindex(iface->name)) == -1)
- return -1;
for (;;) {
- bytes = recv(iface->link_fd, buffer, BUFFER_LEN, MSG_DONTWAIT);
+ bytes = recv(fd, buffer, BUFFER_LEN, MSG_DONTWAIT);
if (bytes == -1) {
if (errno == EAGAIN)
return 0;
@@ -230,12 +219,19 @@ link_changed(struct interface *iface)
if (rtm->rtm_type != RTM_IFINFO)
continue;
ifm = (struct if_msghdr *)p;
- if (ifm->ifm_index != i)
- continue;
-
- /* Link changed */
- return 1;
+ for (iface = ifaces; iface; iface = iface->next)
+ if (ifm->ifm_index == if_nametoindex(iface->name))
+ return 1;
}
}
return 0;
}
+
+struct interface *
+discover_interfaces(int argc, char * const *argv)
+{
+ struct interface *ifaces = NULL;
+
+ do_interface(NULL, &ifaces, argc, argv, NULL, NULL, 2);
+ return ifaces;
+}