Share a single Linux ioctl helper fo setting interface up/down

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.
This commit is contained in:
Jouni Malinen 2010-01-03 22:08:26 +02:00
parent 9c3a2284de
commit 34f2f814e0
10 changed files with 125 additions and 270 deletions

View file

@ -64,6 +64,7 @@
#include "l2_packet/l2_packet.h" #include "l2_packet/l2_packet.h"
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "netlink.h" #include "netlink.h"
#include "linux_ioctl.h"
struct madwifi_driver_data { struct madwifi_driver_data {
@ -270,39 +271,6 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv,
return 0; 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 static int
madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params) 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; 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_set_privacy(drv->iface, drv, 0); /* default to no privacy */
madwifi_receive_probe_req(drv); madwifi_receive_probe_req(drv);
@ -1158,7 +1127,7 @@ madwifi_deinit(void *priv)
struct madwifi_driver_data *drv = priv; struct madwifi_driver_data *drv = priv;
netlink_deinit(drv->netlink); 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) if (drv->ioctl_sock >= 0)
close(drv->ioctl_sock); close(drv->ioctl_sock);
if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
@ -1222,7 +1191,8 @@ madwifi_set_countermeasures(void *priv, int enabled)
static int static int
madwifi_commit(void *priv) 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 = { const struct wpa_driver_ops wpa_driver_atheros_ops = {

View file

@ -30,6 +30,7 @@
#include "priv_netlink.h" #include "priv_netlink.h"
#include "netlink.h" #include "netlink.h"
#include "linux_ioctl.h"
#include "common/ieee802_11_defs.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 hostap_driver_data *drv = priv;
struct ifreq ifr; 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; 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) { if (dev_up) {
memset(&ifr, 0, sizeof(ifr)); 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; ifr.ifr_mtu = HOSTAPD_MTU;
if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) { if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) {
perror("ioctl[SIOCSIFMTU]"); perror("ioctl[SIOCSIFMTU]");

View file

@ -74,6 +74,7 @@
#include "priv_netlink.h" #include "priv_netlink.h"
#include "netlink.h" #include "netlink.h"
#include "linux_ioctl.h"
#include "l2_packet/l2_packet.h" #include "l2_packet/l2_packet.h"
@ -315,39 +316,6 @@ madwifi_configure_wpa(struct madwifi_driver_data *drv,
return 0; 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 static int
madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params) 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; 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_set_privacy(drv->iface, drv, 0); /* default to no privacy */
madwifi_receive_probe_req(drv); madwifi_receive_probe_req(drv);
@ -1228,7 +1197,7 @@ madwifi_deinit(void *priv)
struct madwifi_driver_data *drv = priv; struct madwifi_driver_data *drv = priv;
netlink_deinit(drv->netlink); 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) if (drv->ioctl_sock >= 0)
close(drv->ioctl_sock); close(drv->ioctl_sock);
if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
@ -1292,7 +1261,8 @@ madwifi_set_countermeasures(void *priv, int enabled)
static int static int
madwifi_commit(void *priv) 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 */ #else /* HOSTAPD */

View file

@ -31,6 +31,7 @@
#include "eloop.h" #include "eloop.h"
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "netlink.h" #include "netlink.h"
#include "linux_ioctl.h"
#include "radiotap.h" #include "radiotap.h"
#include "radiotap_iter.h" #include "radiotap_iter.h"
#include "driver.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 * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
* @priv: driver_nl80211 private data * @priv: driver_nl80211 private data
@ -1289,9 +1253,9 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
"use managed mode"); "use managed mode");
} }
if (hostapd_set_iface_flags(drv, drv->ifname, 1)) { if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1)) {
wpa_printf(MSG_ERROR, "Could not set interface '%s' " wpa_printf(MSG_ERROR, "Could not set interface '%s' UP",
"UP", drv->ifname); drv->ifname);
return -1; 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); 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); wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA);
if (drv->ioctl_sock >= 0) if (drv->ioctl_sock >= 0)
@ -3078,7 +3042,7 @@ nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
if (drv->monitor_ifidx < 0) if (drv->monitor_ifidx < 0)
return -1; return -1;
if (hostapd_set_iface_flags(drv, buf, 1)) if (linux_set_iface_flags(drv->ioctl_sock, buf, 1))
goto error; goto error;
memset(&ll, 0, sizeof(ll)); 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 * take the device down, try to set the mode again, and bring the
* device back up. * 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 */ /* Try to set the mode again while the interface is down */
ret = nl80211_set_mode(drv, drv->ifindex, nlmode); 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; 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, if (nl80211_create_iface(priv, name, NL80211_IFTYPE_AP_VLAN,
NULL, 1) < 0) NULL, 1) < 0)
return -1; 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); return i802_set_sta_vlan(priv, addr, name, 0);
} else { } else {
i802_set_sta_vlan(priv, addr, drv->ifname, 0); 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 */ /* start listening for EAPOL on the default AP interface */
add_ifidx(drv, drv->ifindex); 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; goto failed;
if (params->bssid) { if (params->bssid) {
@ -4348,7 +4312,7 @@ static void *i802_init(struct hostapd_data *hapd,
goto failed; goto failed;
} }
if (hostapd_set_iface_flags(drv, drv->ifname, 1)) if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1))
goto failed; goto failed;
drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE)); 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 #ifdef HOSTAPD
if (type == WPA_IF_AP_BSS) { if (type == WPA_IF_AP_BSS) {
if (hostapd_set_iface_flags(priv, ifname, 1)) { if (linux_set_iface_flags(drv->ioctl_sock, ifname, 1)) {
nl80211_remove_iface(priv, ifidx); nl80211_remove_iface(drv, ifidx);
os_free(bss); os_free(bss);
return -1; return -1;
} }

View file

@ -25,6 +25,7 @@
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "priv_netlink.h" #include "priv_netlink.h"
#include "netlink.h" #include "netlink.h"
#include "linux_ioctl.h"
#include "driver_ralink.h" #include "driver_ralink.h"
static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx); 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; 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) static void * wpa_driver_ralink_init(void *ctx, const char *ifname)
{ {
int s; 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 */ 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); ralink_get_we_version_compiled(drv);
wpa_driver_ralink_flush_pmkid(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); wpa_driver_ralink_flush_pmkid(drv);
sleep(1); 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); eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);

View file

@ -29,6 +29,7 @@
#include "common/wpa_common.h" #include "common/wpa_common.h"
#include "priv_netlink.h" #include "priv_netlink.h"
#include "netlink.h" #include "netlink.h"
#include "linux_ioctl.h"
#include "driver.h" #include "driver.h"
#include "driver_wext.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 * wpa_driver_wext_init - Initialize WE driver interface
* @ctx: context to be used when calling wpa_supplicant functions, * @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) static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
{ {
int flags; if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0)
if (wpa_driver_wext_get_ifflags(drv, &flags) != 0) {
wpa_printf(MSG_ERROR, "Could not get interface '%s' flags",
drv->ifname);
return -1; 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. * 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) void wpa_driver_wext_deinit(void *priv)
{ {
struct wpa_driver_wext_data *drv = priv; struct wpa_driver_wext_data *drv = priv;
int flags;
wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 0); 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) if (drv->mlme_sock >= 0)
eloop_unregister_read_sock(drv->mlme_sock); eloop_unregister_read_sock(drv->mlme_sock);
if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0);
(void) wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP);
close(drv->ioctl_sock); close(drv->ioctl_sock);
if (drv->mlme_sock >= 0) 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 wpa_driver_wext_data *drv = priv;
struct iwreq iwr; struct iwreq iwr;
int ret = -1, flags; int ret = -1;
unsigned int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA; unsigned int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA;
os_memset(&iwr, 0, sizeof(iwr)); os_memset(&iwr, 0, sizeof(iwr));
@ -2092,9 +2011,7 @@ int wpa_driver_wext_set_mode(void *priv, int mode)
goto done; goto done;
} }
if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) { if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0) == 0) {
(void) wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP);
/* Try to set the mode again while the interface is down */ /* Try to set the mode again while the interface is down */
iwr.u.mode = new_mode; iwr.u.mode = new_mode;
if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0)
@ -2102,11 +2019,7 @@ int wpa_driver_wext_set_mode(void *priv, int mode)
else else
ret = 0; ret = 0;
/* Ignore return value of get_ifflags to ensure that the device (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1);
* 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);
} }
done: done:

View file

@ -45,8 +45,6 @@ struct wpa_driver_wext_data {
int scan_complete_events; 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_get_bssid(void *priv, u8 *bssid);
int wpa_driver_wext_set_bssid(void *priv, const u8 *bssid); int wpa_driver_wext_set_bssid(void *priv, const u8 *bssid);
int wpa_driver_wext_get_ssid(void *priv, u8 *ssid); int wpa_driver_wext_get_ssid(void *priv, u8 *ssid);

View file

@ -6,6 +6,7 @@ DRV_OBJS += ../src/drivers/driver_hostap.o
CONFIG_WIRELESS_EXTENSION=y CONFIG_WIRELESS_EXTENSION=y
NEED_AP_MLME=y NEED_AP_MLME=y
NEED_NETLINK=y NEED_NETLINK=y
NEED_LINUX_IOCTL=y
endif endif
ifdef CONFIG_DRIVER_WIRED ifdef CONFIG_DRIVER_WIRED
@ -19,6 +20,7 @@ DRV_OBJS += ../src/drivers/driver_madwifi.o
CONFIG_WIRELESS_EXTENSION=y CONFIG_WIRELESS_EXTENSION=y
CONFIG_L2_PACKET=linux CONFIG_L2_PACKET=linux
NEED_NETLINK=y NEED_NETLINK=y
NEED_LINUX_IOCTL=y
endif endif
ifdef CONFIG_DRIVER_NL80211 ifdef CONFIG_DRIVER_NL80211
@ -28,6 +30,7 @@ DRV_OBJS += ../src/utils/radiotap.o
NEED_SME=y NEED_SME=y
NEED_AP_MLME=y NEED_AP_MLME=y
NEED_NETLINK=y NEED_NETLINK=y
NEED_LINUX_IOCTL=y
DRV_LIBS += -lnl DRV_LIBS += -lnl
ifdef CONFIG_LIBNL20 ifdef CONFIG_LIBNL20
@ -72,6 +75,7 @@ ifdef CONFIG_DRIVER_WEXT
DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
CONFIG_WIRELESS_EXTENSION=y CONFIG_WIRELESS_EXTENSION=y
NEED_NETLINK=y NEED_NETLINK=y
NEED_LINUX_IOCTL=y
endif endif
ifdef CONFIG_DRIVER_HERMES ifdef CONFIG_DRIVER_HERMES
@ -96,6 +100,7 @@ ifdef CONFIG_DRIVER_RALINK
DRV_WPA_CFLAGS += -DCONFIG_DRIVER_RALINK DRV_WPA_CFLAGS += -DCONFIG_DRIVER_RALINK
DRV_WPA_OBJS += ../src/drivers/driver_ralink.o DRV_WPA_OBJS += ../src/drivers/driver_ralink.o
NEED_NETLINK=y NEED_NETLINK=y
NEED_LINUX_IOCTL=y
endif endif
ifdef CONFIG_DRIVER_BROADCOM ifdef CONFIG_DRIVER_BROADCOM
@ -158,6 +163,11 @@ ifdef NEED_NETLINK
DRV_OBJS += ../src/drivers/netlink.o DRV_OBJS += ../src/drivers/netlink.o
endif endif
ifdef NEED_LINUX_IOCTL
DRV_OBJS += ../src/drivers/linux_ioctl.o
endif
##### COMMON VARS ##### COMMON VARS
DRV_BOTH_CFLAGS := $(DRV_CFLAGS) $(DRV_WPA_CFLAGS) $(DRV_AP_CFLAGS) DRV_BOTH_CFLAGS := $(DRV_CFLAGS) $(DRV_WPA_CFLAGS) $(DRV_AP_CFLAGS)
DRV_WPA_CFLAGS += $(DRV_CFLAGS) DRV_WPA_CFLAGS += $(DRV_CFLAGS)

56
src/drivers/linux_ioctl.c Normal file
View file

@ -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;
}

20
src/drivers/linux_ioctl.h Normal file
View file

@ -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 */