aboutsummaryrefslogtreecommitdiffstats
path: root/if-bsd.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:04:11 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:04:11 -0800
commit4c5a5fb53bccceff331bae70f748bf9b4609fe0a (patch)
treed6ae69d0d3f4a4d760a3254ec326bca4a8afacfe /if-bsd.c
parente95877ecfa1170d77b1ec1f66752725cdda01b64 (diff)
downloadexternal_dhcpcd-4c5a5fb53bccceff331bae70f748bf9b4609fe0a.zip
external_dhcpcd-4c5a5fb53bccceff331bae70f748bf9b4609fe0a.tar.gz
external_dhcpcd-4c5a5fb53bccceff331bae70f748bf9b4609fe0a.tar.bz2
Code drop from //branches/cupcake/...@124589
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 2cc0c2f..bbf1a95 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;
+}