diff options
| author | Roy Marples <roy@marples.name> | 2008-07-16 22:23:07 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2008-07-16 22:23:07 +0000 |
| commit | a26af49123674044a0216fbae83bec30db5f8ab3 (patch) | |
| tree | 5024ea32e0cdc998220c80a17d3d3afba0e86ef0 /net.c | |
| parent | c4d4ee1358061ff620679a51b0d620ce4fa1326b (diff) | |
| download | dhcpcd-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 'net.c')
| -rw-r--r-- | net.c | 49 |
1 files changed, 49 insertions, 0 deletions
@@ -43,6 +43,9 @@ #define __FAVOR_BSD /* Nasty glibc hack so we can use BSD semantics for UDP */ #include <netinet/udp.h> #undef __FAVOR_BSD +#ifdef SIOCGIFMEDIA +#include <net/if_media.h> +#endif #include <arpa/inet.h> #ifdef AF_LINK # include <net/if_dl.h> @@ -310,6 +313,51 @@ up_interface(const char *ifname) return retval; } +int +carrier_status(const char *ifname) +{ + int s; + struct ifreq ifr; + int retval = -1; +#ifdef SIOCGIFMEDIA + struct ifmediareq ifmr; +#endif +#ifdef __linux__ + char *p; +#endif + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + return -1; + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); +#ifdef __linux__ + /* We can only test the real interface up */ + if ((p = strchr(ifr.ifr_name, ':'))) + *p = '\0'; +#endif + if ((retval = ioctl(s, SIOCGIFFLAGS, &ifr)) == 0) { + if (ifr.ifr_flags & IFF_UP && ifr.ifr_flags & IFF_RUNNING) + retval = 1; + else + retval = 0; + } + +#ifdef SIOCGIFMEDIA + if (retval == 1) { + memset(&ifmr, 0, sizeof(ifmr)); + strncpy(ifmr.ifm_name, ifr.ifr_name, sizeof(ifmr.ifm_name)); + if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1 && + ifmr.ifm_status & IFM_AVALID) + { + if (!(ifmr.ifm_status & IFM_ACTIVE)) + retval = 0; + } + } +#endif + close(s); + return retval; +} + struct interface * read_interface(const char *ifname, _unused int metric) { @@ -389,6 +437,7 @@ read_interface(const char *ifname, _unused int metric) #ifdef ENABLE_ARP iface->arp_fd = -1; #endif + iface->link_fd = -1; eexit: close(s); |
