summaryrefslogtreecommitdiffstats
path: root/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-07-16 22:23:07 +0000
committerRoy Marples <roy@marples.name>2008-07-16 22:23:07 +0000
commita26af49123674044a0216fbae83bec30db5f8ab3 (patch)
tree5024ea32e0cdc998220c80a17d3d3afba0e86ef0 /if-bsd.c
parentc4d4ee1358061ff620679a51b0d620ce4fa1326b (diff)
downloaddhcpcd-a26af49123674044a0216fbae83bec30db5f8ab3.tar.xz
Add support for link carrier detection. For Linux this involved a big change to the netlink code to add callbacks, for BSD just an extra function. We also have an option not to wait for a DHCP lease and fork right away - useful for startup scripts.
Diffstat (limited to 'if-bsd.c')
-rw-r--r--if-bsd.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/if-bsd.c b/if-bsd.c
index 2cc0c2f3..bbf1a95d 100644
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -185,3 +185,57 @@ if_route(const char *ifname, const struct in_addr *destination,
close(s);
return retval;
}
+
+int
+open_link_socket(struct interface *iface)
+{
+ 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;
+}
+
+#define BUFFER_LEN 2048
+int
+link_changed(struct interface *iface)
+{
+ char buffer[2048], *p;
+ ssize_t bytes;
+ struct rt_msghdr *rtm;
+ struct if_msghdr *ifm;
+ int i;
+
+ if ((i = if_nametoindex(iface->name)) == -1)
+ return -1;
+ for (;;) {
+ bytes = recv(iface->link_fd, buffer, BUFFER_LEN, MSG_DONTWAIT);
+ if (bytes == -1) {
+ if (errno == EAGAIN)
+ return 0;
+ if (errno == EINTR)
+ continue;
+ return -1;
+ }
+ for (p = buffer; bytes > 0;
+ bytes -= ((struct rt_msghdr *)p)->rtm_msglen,
+ p += ((struct rt_msghdr *)p)->rtm_msglen)
+ {
+ rtm = (struct rt_msghdr *)p;
+ if (rtm->rtm_type != RTM_IFINFO)
+ continue;
+ ifm = (struct if_msghdr *)p;
+ if (ifm->ifm_index != i)
+ continue;
+
+ /* Link changed */
+ return 1;
+ }
+ }
+ return 0;
+}