Share a single Linux ioctl helper fo setting interface up/down
authorJouni Malinen <j@w1.fi>
Sun, 3 Jan 2010 20:08:26 +0000 (22:08 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 3 Jan 2010 20:08:26 +0000 (22:08 +0200)
Number of Linux driver wrappers included this more or less identical
function, so lets add a new helper file to be able to share some more
code between the driver wrappers.

src/drivers/driver_atheros.c
src/drivers/driver_hostap.c
src/drivers/driver_madwifi.c
src/drivers/driver_nl80211.c
src/drivers/driver_ralink.c
src/drivers/driver_wext.c
src/drivers/driver_wext.h
src/drivers/drivers.mak
src/drivers/linux_ioctl.c [new file with mode: 0644]
src/drivers/linux_ioctl.h [new file with mode: 0644]

index 3d04294..4428731 100644 (file)
@@ -64,6 +64,7 @@
 #include "l2_packet/l2_packet.h"
 #include "common/ieee802_11_defs.h"
 #include "netlink.h"
+#include "linux_ioctl.h"
 
 
 struct madwifi_driver_data {
@@ -270,39 +271,6 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv,
        return 0;
 }
 
-
-static int
-madwifi_set_iface_flags(void *priv, int dev_up)
-{
-       struct madwifi_driver_data *drv = priv;
-       struct ifreq ifr;
-
-       wpa_printf(MSG_DEBUG, "%s: dev_up=%d", __func__, dev_up);
-
-       if (drv->ioctl_sock < 0)
-               return -1;
-
-       memset(&ifr, 0, sizeof(ifr));
-       os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ);
-
-       if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
-               perror("ioctl[SIOCGIFFLAGS]");
-               return -1;
-       }
-
-       if (dev_up)
-               ifr.ifr_flags |= IFF_UP;
-       else
-               ifr.ifr_flags &= ~IFF_UP;
-
-       if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
-               perror("ioctl[SIOCSIFFLAGS]");
-               return -1;
-       }
-
-       return 0;
-}
-
 static int
 madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params)
 {
@@ -1132,7 +1100,8 @@ madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params)
                goto bad;
        }
 
-       madwifi_set_iface_flags(drv, 0);        /* mark down during setup */
+       /* mark down during setup */
+       linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
        madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */
 
        madwifi_receive_probe_req(drv);
@@ -1158,7 +1127,7 @@ madwifi_deinit(void *priv)
        struct madwifi_driver_data *drv = priv;
 
        netlink_deinit(drv->netlink);
-       (void) madwifi_set_iface_flags(drv, 0);
+       (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
        if (drv->ioctl_sock >= 0)
                close(drv->ioctl_sock);
        if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
@@ -1222,7 +1191,8 @@ madwifi_set_countermeasures(void *priv, int enabled)
 static int
 madwifi_commit(void *priv)
 {
-       return madwifi_set_iface_flags(priv, 1);
+       struct madwifi_driver_data *drv = priv;
+       return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);
 }
 
 const struct wpa_driver_ops wpa_driver_atheros_ops = {
index 6b731f6..39b17b6 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "priv_netlink.h"
 #include "netlink.h"
+#include "linux_ioctl.h"
 #include "common/ieee802_11_defs.h"
 
 
@@ -371,31 +372,15 @@ static int hostap_set_iface_flags(void *priv, int dev_up)
 {
        struct hostap_driver_data *drv = priv;
        struct ifreq ifr;
+       char ifname[IFNAMSIZ];
 
-       if (drv->ioctl_sock < 0)
+       os_snprintf(ifname, IFNAMSIZ, "%sap", drv->iface);
+       if (linux_set_iface_flags(drv->ioctl_sock, ifname, dev_up) < 0)
                return -1;
 
-       memset(&ifr, 0, sizeof(ifr));
-       snprintf(ifr.ifr_name, IFNAMSIZ, "%sap", drv->iface);
-
-       if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
-               perror("ioctl[SIOCGIFFLAGS]");
-               return -1;
-       }
-
-       if (dev_up)
-               ifr.ifr_flags |= IFF_UP;
-       else
-               ifr.ifr_flags &= ~IFF_UP;
-
-       if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
-               perror("ioctl[SIOCSIFFLAGS]");
-               return -1;
-       }
-
        if (dev_up) {
                memset(&ifr, 0, sizeof(ifr));
-               snprintf(ifr.ifr_name, IFNAMSIZ, "%sap", drv->iface);
+               os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
                ifr.ifr_mtu = HOSTAPD_MTU;
                if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) {
                        perror("ioctl[SIOCSIFMTU]");
index f16b012..ad0b977 100644 (file)
@@ -74,6 +74,7 @@
 
 #include "priv_netlink.h"
 #include "netlink.h"
+#include "linux_ioctl.h"
 #include "l2_packet/l2_packet.h"
 
 
@@ -315,39 +316,6 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv,
        return 0;
 }
 
-
-static int
-madwifi_set_iface_flags(void *priv, int dev_up)
-{
-       struct madwifi_driver_data *drv = priv;
-       struct ifreq ifr;
-
-       wpa_printf(MSG_DEBUG, "%s: dev_up=%d", __func__, dev_up);
-
-       if (drv->ioctl_sock < 0)
-               return -1;
-
-       memset(&ifr, 0, sizeof(ifr));
-       os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ);
-
-       if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
-               perror("ioctl[SIOCGIFFLAGS]");
-               return -1;
-       }
-
-       if (dev_up)
-               ifr.ifr_flags |= IFF_UP;
-       else
-               ifr.ifr_flags &= ~IFF_UP;
-
-       if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
-               perror("ioctl[SIOCSIFFLAGS]");
-               return -1;
-       }
-
-       return 0;
-}
-
 static int
 madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params)
 {
@@ -1202,7 +1170,8 @@ madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params)
                goto bad;
        }
 
-       madwifi_set_iface_flags(drv, 0);        /* mark down during setup */
+       /* mark down during setup */
+       linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
        madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */
 
        madwifi_receive_probe_req(drv);
@@ -1228,7 +1197,7 @@ madwifi_deinit(void *priv)
        struct madwifi_driver_data *drv = priv;
 
        netlink_deinit(drv->netlink);
-       (void) madwifi_set_iface_flags(drv, 0);
+       (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
        if (drv->ioctl_sock >= 0)
                close(drv->ioctl_sock);
        if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
@@ -1292,7 +1261,8 @@ madwifi_set_countermeasures(void *priv, int enabled)
 static int
 madwifi_commit(void *priv)
 {
-       return madwifi_set_iface_flags(priv, 1);
+       struct madwifi_driver_data *drv = priv;
+       return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);
 }
 
 #else /* HOSTAPD */
index 15700e4..a6e6188 100644 (file)
@@ -31,6 +31,7 @@
 #include "eloop.h"
 #include "common/ieee802_11_defs.h"
 #include "netlink.h"
+#include "linux_ioctl.h"
 #include "radiotap.h"
 #include "radiotap_iter.h"
 #include "driver.h"
@@ -915,43 +916,6 @@ static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
 }
 
 
-static int hostapd_set_iface_flags(struct wpa_driver_nl80211_data *drv,
-                                  const char *ifname, int dev_up)
-{
-       struct ifreq ifr;
-
-       if (drv->ioctl_sock < 0)
-               return -1;
-
-       os_memset(&ifr, 0, sizeof(ifr));
-       os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
-
-       if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
-               perror("ioctl[SIOCGIFFLAGS]");
-               wpa_printf(MSG_DEBUG, "Could not read interface flags (%s)",
-                          ifname);
-               return -1;
-       }
-
-       if (dev_up) {
-               if (ifr.ifr_flags & IFF_UP)
-                       return 0;
-               ifr.ifr_flags |= IFF_UP;
-       } else {
-               if (!(ifr.ifr_flags & IFF_UP))
-                       return 0;
-               ifr.ifr_flags &= ~IFF_UP;
-       }
-
-       if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
-               perror("ioctl[SIOCSIFFLAGS]");
-               return -1;
-       }
-
-       return 0;
-}
-
-
 /**
  * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
  * @priv: driver_nl80211 private data
@@ -1289,9 +1253,9 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
                           "use managed mode");
        }
 
-       if (hostapd_set_iface_flags(drv, drv->ifname, 1)) {
-               wpa_printf(MSG_ERROR, "Could not set interface '%s' "
-                          "UP", drv->ifname);
+       if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1)) {
+               wpa_printf(MSG_ERROR, "Could not set interface '%s' UP",
+                          drv->ifname);
                return -1;
        }
 
@@ -1379,7 +1343,7 @@ static void wpa_driver_nl80211_deinit(void *priv)
 
        eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
 
-       (void) hostapd_set_iface_flags(drv, drv->ifname, 0);
+       (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0);
        wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA);
 
        if (drv->ioctl_sock >= 0)
@@ -3078,7 +3042,7 @@ nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
        if (drv->monitor_ifidx < 0)
                return -1;
 
-       if (hostapd_set_iface_flags(drv, buf, 1))
+       if (linux_set_iface_flags(drv->ioctl_sock, buf, 1))
                goto error;
 
        memset(&ll, 0, sizeof(ll));
@@ -3682,10 +3646,10 @@ static int wpa_driver_nl80211_set_mode(void *priv, int mode)
         * take the device down, try to set the mode again, and bring the
         * device back up.
         */
-       if (hostapd_set_iface_flags(drv, drv->ifname, 0) == 0) {
+       if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0) == 0) {
                /* Try to set the mode again while the interface is down */
                ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
-               if (hostapd_set_iface_flags(drv, drv->ifname, 1))
+               if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1))
                        ret = -1;
        }
 
@@ -4222,7 +4186,7 @@ static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val)
                if (nl80211_create_iface(priv, name, NL80211_IFTYPE_AP_VLAN,
                                         NULL, 1) < 0)
                        return -1;
-               hostapd_set_iface_flags(drv, name, 1);
+               linux_set_iface_flags(drv->ioctl_sock, name, 1);
                return i802_set_sta_vlan(priv, addr, name, 0);
        } else {
                i802_set_sta_vlan(priv, addr, drv->ifname, 0);
@@ -4334,7 +4298,7 @@ static void *i802_init(struct hostapd_data *hapd,
        /* start listening for EAPOL on the default AP interface */
        add_ifidx(drv, drv->ifindex);
 
-       if (hostapd_set_iface_flags(drv, drv->ifname, 0))
+       if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0))
                goto failed;
 
        if (params->bssid) {
@@ -4348,7 +4312,7 @@ static void *i802_init(struct hostapd_data *hapd,
                goto failed;
        }
 
-       if (hostapd_set_iface_flags(drv, drv->ifname, 1))
+       if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1))
                goto failed;
 
        drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
@@ -4435,8 +4399,8 @@ static int wpa_driver_nl80211_if_add(const char *iface, void *priv,
 
 #ifdef HOSTAPD
        if (type == WPA_IF_AP_BSS) {
-               if (hostapd_set_iface_flags(priv, ifname, 1)) {
-                       nl80211_remove_iface(priv, ifidx);
+               if (linux_set_iface_flags(drv->ioctl_sock, ifname, 1)) {
+                       nl80211_remove_iface(drv, ifidx);
                        os_free(bss);
                        return -1;
                }
index 7b46772..09d1ef5 100644 (file)
@@ -25,6 +25,7 @@
 #include "common/ieee802_11_defs.h"
 #include "priv_netlink.h"
 #include "netlink.h"
+#include "linux_ioctl.h"
 #include "driver_ralink.h"
 
 static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx);
@@ -762,38 +763,6 @@ ralink_get_we_version_compiled(struct wpa_driver_ralink_data *drv)
        return 0;
 }
 
-static int
-ralink_set_iface_flags(void *priv, int dev_up)
-{
-       struct wpa_driver_ralink_data *drv = priv;
-       struct ifreq ifr;
-
-       wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
-
-       if (drv->ioctl_sock < 0)
-               return -1;
-
-       os_memset(&ifr, 0, sizeof(ifr));
-       os_snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->ifname);
-
-       if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
-               perror("ioctl[SIOCGIFFLAGS]");
-               return -1;
-       }
-
-       if (dev_up)
-               ifr.ifr_flags |= IFF_UP;
-       else
-               ifr.ifr_flags &= ~IFF_UP;
-
-       if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
-               perror("ioctl[SIOCSIFFLAGS]");
-               return -1;
-       }
-
-       return 0;
-}
-
 static void * wpa_driver_ralink_init(void *ctx, const char *ifname)
 {
        int s;
@@ -846,7 +815,7 @@ static void * wpa_driver_ralink_init(void *ctx, const char *ifname)
 
        drv->no_of_pmkid = 4; /* Number of PMKID saved supported */
 
-       ralink_set_iface_flags(drv, 1); /* mark up during setup */
+       linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1);
        ralink_get_we_version_compiled(drv);
        wpa_driver_ralink_flush_pmkid(drv);
 
@@ -897,7 +866,7 @@ static void wpa_driver_ralink_deinit(void *priv)
                wpa_driver_ralink_flush_pmkid(drv);
 
                sleep(1);
-               /* ralink_set_iface_flags(drv, 0); */
+               /* linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0); */
        }
 
        eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);
index 0fc1c54..541ea4c 100644 (file)
@@ -29,6 +29,7 @@
 #include "common/wpa_common.h"
 #include "priv_netlink.h"
 #include "netlink.h"
+#include "linux_ioctl.h"
 #include "driver.h"
 #include "driver_wext.h"
 
@@ -685,62 +686,6 @@ static void wpa_driver_wext_event_rtm_dellink(void *ctx, struct ifinfomsg *ifi,
 }
 
 
-static int wpa_driver_wext_get_ifflags_ifname(struct wpa_driver_wext_data *drv,
-                                             const char *ifname, int *flags)
-{
-       struct ifreq ifr;
-
-       os_memset(&ifr, 0, sizeof(ifr));
-       os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
-       if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
-               perror("ioctl[SIOCGIFFLAGS]");
-               return -1;
-       }
-       *flags = ifr.ifr_flags & 0xffff;
-       return 0;
-}
-
-
-/**
- * wpa_driver_wext_get_ifflags - Get interface flags (SIOCGIFFLAGS)
- * @drv: driver_wext private data
- * @flags: Pointer to returned flags value
- * Returns: 0 on success, -1 on failure
- */
-int wpa_driver_wext_get_ifflags(struct wpa_driver_wext_data *drv, int *flags)
-{
-       return wpa_driver_wext_get_ifflags_ifname(drv, drv->ifname, flags);
-}
-
-
-static int wpa_driver_wext_set_ifflags_ifname(struct wpa_driver_wext_data *drv,
-                                             const char *ifname, int flags)
-{
-       struct ifreq ifr;
-
-       os_memset(&ifr, 0, sizeof(ifr));
-       os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
-       ifr.ifr_flags = flags & 0xffff;
-       if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
-               perror("SIOCSIFFLAGS");
-               return -1;
-       }
-       return 0;
-}
-
-
-/**
- * wpa_driver_wext_set_ifflags - Set interface flags (SIOCSIFFLAGS)
- * @drv: driver_wext private data
- * @flags: New value for flags
- * Returns: 0 on success, -1 on failure
- */
-int wpa_driver_wext_set_ifflags(struct wpa_driver_wext_data *drv, int flags)
-{
-       return wpa_driver_wext_set_ifflags_ifname(drv, drv->ifname, flags);
-}
-
-
 /**
  * wpa_driver_wext_init - Initialize WE driver interface
  * @ctx: context to be used when calling wpa_supplicant functions,
@@ -798,32 +743,8 @@ err1:
 
 static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
 {
-       int flags;
-
-       if (wpa_driver_wext_get_ifflags(drv, &flags) != 0) {
-               wpa_printf(MSG_ERROR, "Could not get interface '%s' flags",
-                          drv->ifname);
+       if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0)
                return -1;
-       }
-
-       if (!(flags & IFF_UP)) {
-               if (wpa_driver_wext_set_ifflags(drv, flags | IFF_UP) != 0) {
-                       wpa_printf(MSG_ERROR, "Could not set interface '%s' "
-                                  "UP", drv->ifname);
-                       return -1;
-               } else {
-                       /*
-                        * Wait some time to allow driver to initialize before
-                        * starting configuring the driver. This seems to be
-                        * needed at least some drivers that load firmware etc.
-                        * when the interface is set up.
-                        */
-                       wpa_printf(MSG_DEBUG, "Interface %s set UP - waiting "
-                                  "a second for the driver to complete "
-                                  "initialization", drv->ifname);
-                       sleep(1);
-               }
-       }
 
        /*
         * Make sure that the driver does not have any obsolete PMKID entries.
@@ -879,7 +800,6 @@ static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
 void wpa_driver_wext_deinit(void *priv)
 {
        struct wpa_driver_wext_data *drv = priv;
-       int flags;
 
        wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 0);
 
@@ -897,8 +817,7 @@ void wpa_driver_wext_deinit(void *priv)
        if (drv->mlme_sock >= 0)
                eloop_unregister_read_sock(drv->mlme_sock);
 
-       if (wpa_driver_wext_get_ifflags(drv, &flags) == 0)
-               (void) wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP);
+       (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0);
 
        close(drv->ioctl_sock);
        if (drv->mlme_sock >= 0)
@@ -2062,7 +1981,7 @@ int wpa_driver_wext_set_mode(void *priv, int mode)
 {
        struct wpa_driver_wext_data *drv = priv;
        struct iwreq iwr;
-       int ret = -1, flags;
+       int ret = -1;
        unsigned int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA;
 
        os_memset(&iwr, 0, sizeof(iwr));
@@ -2092,9 +2011,7 @@ int wpa_driver_wext_set_mode(void *priv, int mode)
                goto done;
        }
 
-       if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) {
-               (void) wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP);
-
+       if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0) == 0) {
                /* Try to set the mode again while the interface is down */
                iwr.u.mode = new_mode;
                if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0)
@@ -2102,11 +2019,7 @@ int wpa_driver_wext_set_mode(void *priv, int mode)
                else
                        ret = 0;
 
-               /* Ignore return value of get_ifflags to ensure that the device
-                * is always up like it was before this function was called.
-                */
-               (void) wpa_driver_wext_get_ifflags(drv, &flags);
-               (void) wpa_driver_wext_set_ifflags(drv, flags | IFF_UP);
+               (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1);
        }
 
 done:
index edc32a7..81ec25f 100644 (file)
@@ -45,8 +45,6 @@ struct wpa_driver_wext_data {
        int scan_complete_events;
 };
 
-int wpa_driver_wext_get_ifflags(struct wpa_driver_wext_data *drv, int *flags);
-int wpa_driver_wext_set_ifflags(struct wpa_driver_wext_data *drv, int flags);
 int wpa_driver_wext_get_bssid(void *priv, u8 *bssid);
 int wpa_driver_wext_set_bssid(void *priv, const u8 *bssid);
 int wpa_driver_wext_get_ssid(void *priv, u8 *ssid);
index 9d6c071..09a15ce 100644 (file)
@@ -6,6 +6,7 @@ DRV_OBJS += ../src/drivers/driver_hostap.o
 CONFIG_WIRELESS_EXTENSION=y
 NEED_AP_MLME=y
 NEED_NETLINK=y
+NEED_LINUX_IOCTL=y
 endif
 
 ifdef CONFIG_DRIVER_WIRED
@@ -19,6 +20,7 @@ DRV_OBJS += ../src/drivers/driver_madwifi.o
 CONFIG_WIRELESS_EXTENSION=y
 CONFIG_L2_PACKET=linux
 NEED_NETLINK=y
+NEED_LINUX_IOCTL=y
 endif
 
 ifdef CONFIG_DRIVER_NL80211
@@ -28,6 +30,7 @@ DRV_OBJS += ../src/utils/radiotap.o
 NEED_SME=y
 NEED_AP_MLME=y
 NEED_NETLINK=y
+NEED_LINUX_IOCTL=y
 DRV_LIBS += -lnl
 
 ifdef CONFIG_LIBNL20
@@ -72,6 +75,7 @@ ifdef CONFIG_DRIVER_WEXT
 DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
 CONFIG_WIRELESS_EXTENSION=y
 NEED_NETLINK=y
+NEED_LINUX_IOCTL=y
 endif
 
 ifdef CONFIG_DRIVER_HERMES
@@ -96,6 +100,7 @@ ifdef CONFIG_DRIVER_RALINK
 DRV_WPA_CFLAGS += -DCONFIG_DRIVER_RALINK
 DRV_WPA_OBJS += ../src/drivers/driver_ralink.o
 NEED_NETLINK=y
+NEED_LINUX_IOCTL=y
 endif
 
 ifdef CONFIG_DRIVER_BROADCOM
@@ -158,6 +163,11 @@ ifdef NEED_NETLINK
 DRV_OBJS += ../src/drivers/netlink.o
 endif
 
+ifdef NEED_LINUX_IOCTL
+DRV_OBJS += ../src/drivers/linux_ioctl.o
+endif
+
+
 ##### COMMON VARS
 DRV_BOTH_CFLAGS := $(DRV_CFLAGS) $(DRV_WPA_CFLAGS) $(DRV_AP_CFLAGS)
 DRV_WPA_CFLAGS += $(DRV_CFLAGS)
diff --git a/src/drivers/linux_ioctl.c b/src/drivers/linux_ioctl.c
new file mode 100644 (file)
index 0000000..733bdb2
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Linux ioctl helper functions for driver wrappers
+ * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "utils/includes.h"
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#include "utils/common.h"
+#include "linux_ioctl.h"
+
+
+int linux_set_iface_flags(int sock, const char *ifname, int dev_up)
+{
+       struct ifreq ifr;
+
+       if (sock < 0)
+               return -1;
+
+       os_memset(&ifr, 0, sizeof(ifr));
+       os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+       if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
+               wpa_printf(MSG_ERROR, "Could not read interface %s flags: %s",
+                          ifname, strerror(errno));
+               return -1;
+       }
+
+       if (dev_up) {
+               if (ifr.ifr_flags & IFF_UP)
+                       return 0;
+               ifr.ifr_flags |= IFF_UP;
+       } else {
+               if (!(ifr.ifr_flags & IFF_UP))
+                       return 0;
+               ifr.ifr_flags &= ~IFF_UP;
+       }
+
+       if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
+               wpa_printf(MSG_ERROR, "Could not set interface %s flags: %s",
+                          ifname, strerror(errno));
+               return -1;
+       }
+
+       return 0;
+}
diff --git a/src/drivers/linux_ioctl.h b/src/drivers/linux_ioctl.h
new file mode 100644 (file)
index 0000000..8498b9a
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Linux ioctl helper functions for driver wrappers
+ * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef LINUX_IOCTL_H
+#define LINUX_IOCTL_H
+
+int linux_set_iface_flags(int sock, const char *ifname, int dev_up);
+
+#endif /* LINUX_IOCTL_H */