diff --git a/contrib/wpa/src/drivers/driver_wired.c b/contrib/wpa/src/drivers/driver_wired.c index e0f0f2289bce..95dcea9354ab 100644 --- a/contrib/wpa/src/drivers/driver_wired.c +++ b/contrib/wpa/src/drivers/driver_wired.c @@ -17,6 +17,7 @@ #endif /* __linux__ */ #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) #include +#include #endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) */ #ifdef __sun__ #include @@ -453,6 +454,29 @@ static int wpa_driver_wired_set_ifflags(const char *ifname, int flags) return 0; } +static int wpa_driver_wired_get_ifstatus(const char *ifname, int *status) +{ + struct ifmediareq ifmr; + int s; + + s = socket(PF_INET, SOCK_DGRAM, 0); + if (s < 0) { + perror("socket"); + return -1; + } + + os_memset(&ifmr, 0, sizeof(ifmr)); + os_strlcpy(ifmr.ifm_name, ifname, IFNAMSIZ); + if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) { + perror("ioctl[SIOCGIFMEDIA]"); + close(s); + return -1; + } + close(s); + *status = ifmr.ifm_status & IFM_ACTIVE; + + return 0; +} static int wpa_driver_wired_multi(const char *ifname, const u8 *addr, int add) { @@ -511,7 +535,7 @@ static int wpa_driver_wired_multi(const char *ifname, const u8 *addr, int add) static void * wpa_driver_wired_init(void *ctx, const char *ifname) { struct wpa_driver_wired_data *drv; - int flags; + int flags, status; drv = os_zalloc(sizeof(*drv)); if (drv == NULL) @@ -562,6 +586,11 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname) __func__); drv->iff_allmulti = 1; } + wpa_printf(MSG_DEBUG, "%s: waiting for link to become active", + __func__); + while (wpa_driver_wired_get_ifstatus(ifname, &status) == 0 && + status == 0) + sleep(1); return drv; }