[PATCH 5/5] driver_bsd.c: Move route and socket fds to global init
Roy Marples
roy
Tue May 26 14:25:18 PDT 2009
This allows the driver to raise events for any interface and allows
wpa_supplicant to dynamically add/remove interfaces.
Signed-off-by: Roy Marples <roy at marples.name>
---
src/drivers/driver_bsd.c | 150 ++++++++++++++++++++++++++++++---------------
1 files changed, 100 insertions(+), 50 deletions(-)
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index c6f9b9a..f2fac5a 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -849,9 +849,14 @@ const struct wpa_driver_ops wpa_driver_bsd_ops = {
#else /* HOSTAPD */
-struct wpa_driver_bsd_data {
+struct wpa_driver_bsd_global {
int sock; /* open socket for 802.11 ioctls */
int route; /* routing socket for events */
+ void *global;
+};
+
+struct wpa_driver_bsd_data {
+ struct wpa_driver_bsd_global *global;
char ifname[IFNAMSIZ+1]; /* interface name */
unsigned int ifindex; /* interface index */
void *ctx;
@@ -863,19 +868,19 @@ struct wpa_driver_bsd_data {
static int
set80211var(struct wpa_driver_bsd_data *drv, int op, const void *arg, int arg_len)
{
- return bsd_set80211var(drv->sock, drv->ifname, op, arg, arg_len);
+ return bsd_set80211var(drv->global->sock, drv->ifname, op, arg, arg_len);
}
static int
get80211var(struct wpa_driver_bsd_data *drv, int op, void *arg, int arg_len)
{
- return bsd_get80211var(drv->sock, drv->ifname, op, arg, arg_len);
+ return bsd_get80211var(drv->global->sock, drv->ifname, op, arg, arg_len);
}
static int
set80211param(struct wpa_driver_bsd_data *drv, int op, int arg)
{
- return bsd_set80211param(drv->sock, drv->ifname, op, arg);
+ return bsd_set80211param(drv->global->sock, drv->ifname, op, arg);
}
static int
@@ -887,7 +892,7 @@ get80211param(struct wpa_driver_bsd_data *drv, int op)
os_strlcpy(ireq.i_name, drv->ifname, sizeof(ireq.i_name));
ireq.i_type = op;
- if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) {
+ if (ioctl(drv->global->sock, SIOCG80211, &ireq) < 0) {
fprintf(stderr, "ioctl[SIOCG80211, op %u]: %s\n",
op, strerror(errno));
return -1;
@@ -902,7 +907,7 @@ getifflags(struct wpa_driver_bsd_data *drv, int *flags)
os_memset(&ifr, 0, sizeof(ifr));
os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
- if (ioctl(drv->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
+ if (ioctl(drv->global->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
perror("SIOCGIFFLAGS");
return errno;
}
@@ -918,7 +923,7 @@ setifflags(struct wpa_driver_bsd_data *drv, int flags)
os_memset(&ifr, 0, sizeof(ifr));
os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
ifr.ifr_flags = flags & 0xffff;
- if (ioctl(drv->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
+ if (ioctl(drv->global->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
perror("SIOCSIFFLAGS");
return errno;
}
@@ -933,7 +938,7 @@ wpa_driver_bsd_get_bssid(void *priv, u8 *bssid)
struct ieee80211_bssid bs;
os_strncpy(bs.i_name, drv->ifname, sizeof(bs.i_name));
- if (ioctl(drv->sock, SIOCG80211BSSID, &bs) < 0)
+ if (ioctl(drv->global->sock, SIOCG80211BSSID, &bs) < 0)
return -1;
os_memcpy(bssid, bs.i_bssid, sizeof(bs.i_bssid));
return 0;
@@ -959,7 +964,7 @@ wpa_driver_bsd_get_ssid(void *priv, u8 *ssid)
{
struct wpa_driver_bsd_data *drv = priv;
- return bsd_get_ssid(drv->sock, drv->ifname, ssid);
+ return bsd_get_ssid(drv->global->sock, drv->ifname, ssid);
}
static int
@@ -968,7 +973,7 @@ wpa_driver_bsd_set_ssid(void *priv, const u8 *ssid,
{
struct wpa_driver_bsd_data *drv = priv;
- return bsd_set_ssid(drv->sock, drv->ifname, ssid, ssid_len);
+ return bsd_set_ssid(drv->global->sock, drv->ifname, ssid, ssid_len);
}
static int
@@ -1237,7 +1242,7 @@ wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len)
static void
wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
{
- struct wpa_driver_bsd_data *drv = sock_ctx;
+ struct wpa_driver_bsd_global *g = sock_ctx;
char buf[2048];
struct if_announcemsghdr *ifan;
struct if_msghdr *ifm;
@@ -1263,13 +1268,13 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
switch (rtm->rtm_type) {
case RTM_IFANNOUNCE:
ifan = (struct if_announcemsghdr *) rtm;
- if (ifan->ifan_index != drv->ifindex)
- break;
- strlcpy(event.interface_status.ifname, drv->ifname,
- sizeof(event.interface_status.ifname));
switch (ifan->ifan_what) {
+ case IFAN_ARRIVAL:
+ event.interface_status.ievent = EVENT_INTERFACE_ADDED;
+ break;
case IFAN_DEPARTURE:
event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
+ break;
default:
return;
}
@@ -1277,22 +1282,27 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
event.interface_status.ifname,
ifan->ifan_what == IFAN_DEPARTURE ?
"removed" : "added");
- wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
+ strlcpy(event.interface_status.ifname, ifan->ifan_name,
+ sizeof(event.interface_status.ifname));
+ wpa_supplicant_event2(g->global, EVENT_INTERFACE_STATUS,
+ &event);
break;
case RTM_IEEE80211:
ifan = (struct if_announcemsghdr *) rtm;
- if (ifan->ifan_index != drv->ifindex)
- break;
+ strlcpy(event.interface_status.ifname, ifan->ifan_name,
+ sizeof(event.interface_status.ifname));
switch (ifan->ifan_what) {
case RTM_IEEE80211_ASSOC:
case RTM_IEEE80211_REASSOC:
- wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
+ wpa_supplicant_event2(g->global, EVENT_ASSOC, &event);
break;
case RTM_IEEE80211_DISASSOC:
- wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL);
+ wpa_supplicant_event2(g->global, EVENT_DISASSOC,
+ &event);
break;
case RTM_IEEE80211_SCAN:
- wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
+ wpa_supplicant_event2(g->global, EVENT_SCAN_RESULTS,
+ &event);
break;
case RTM_IEEE80211_REPLAY:
/* ignore */
@@ -1307,23 +1317,38 @@ wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
os_memset(&event, 0, sizeof(event));
event.michael_mic_failure.unicast =
!IEEE80211_IS_MULTICAST(mic->iev_dst);
- wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE,
- &event);
+ wpa_supplicant_event2(g->global,
+ EVENT_MICHAEL_MIC_FAILURE, &event);
break;
}
break;
case RTM_IFINFO:
ifm = (struct if_msghdr *) rtm;
- if (ifm->ifm_index != drv->ifindex)
+ if (if_indextoname(ifm->ifm_index,
+ event.interface_status.ifname) == NULL)
break;
- if ((rtm->rtm_flags & RTF_UP) == 0) {
- strlcpy(event.interface_status.ifname, drv->ifname,
- sizeof(event.interface_status.ifname));
+ if ((ifm->ifm_flags & RTF_UP) == 0)
event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
- wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
- event.interface_status.ifname);
- wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
- }
+ else
+ event.interface_status.ievent = EVENT_INTERFACE_ADDED;
+ wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' %s",
+ event.interface_status.ifname,
+ event.interface_status.ievent == EVENT_INTERFACE_REMOVED ?
+ "DOWN" : "UP");
+ wpa_supplicant_event2(g->global, EVENT_INTERFACE_STATUS,
+ &event);
+ break;
+ case RTM_ADD: /* FALLTHROUGH */
+ case RTM_DELETE: /* FALLTHROUGH */
+ case RTM_CHANGE: /* FALLTHROUGH */
+ case RTM_NEWADDR: /* FALLTHROUGH */
+ case RTM_DELADDR: /* FALLTHROUGH */
+ case RTM_LOSING: /* FALLTHROUGH */
+ case RTM_REDIRECT: /* FALLTHROUGH */
+ case RTM_MISS: /* FALLTRHOUGH */
+ break;
+ default:
+ wpa_printf(MSG_DEBUG, "RTM_???: %d", rtm->rtm_type);
break;
}
}
@@ -1419,7 +1444,7 @@ wpa_driver_bsd_get_scan_results2(void *priv)
}
static void *
-wpa_driver_bsd_init(void *ctx, const char *ifname)
+wpa_driver_bsd_init2(void *ctx, const char *ifname, void *global_priv)
{
#define GETPARAM(drv, param, v) \
(((v) = get80211param(drv, param)) != -1)
@@ -1437,19 +1462,12 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
drv->ifindex = if_nametoindex(ifname);
if (drv->ifindex == 0) {
wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",
- __func__, ifname);
- goto fail1;
- }
- drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
- if (drv->sock < 0)
- goto fail1;
- drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
- if (drv->route < 0)
+ __func__, ifname);
goto fail;
- eloop_register_read_sock(drv->route,
- wpa_driver_bsd_event_receive, ctx, drv);
+ }
drv->ctx = ctx;
+ drv->global = global_priv;
os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
@@ -1481,8 +1499,6 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
return drv;
fail:
- close(drv->sock);
-fail1:
os_free(drv);
return NULL;
#undef GETPARAM
@@ -1494,8 +1510,6 @@ wpa_driver_bsd_deinit(void *priv)
struct wpa_driver_bsd_data *drv = priv;
int flags;
- eloop_unregister_read_sock(drv->route);
-
/* NB: mark interface down */
if (getifflags(drv, &flags) == 0)
(void) setifflags(drv, flags &~ IFF_UP);
@@ -1503,18 +1517,54 @@ wpa_driver_bsd_deinit(void *priv)
wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);
if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0)
wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",
- __func__);
+ __func__);
- (void) close(drv->route); /* ioctl socket */
- (void) close(drv->sock); /* event socket */
os_free(drv);
}
+static void *
+wpa_driver_bsd_global_init(void *priv)
+{
+ struct wpa_driver_bsd_global *global;
+
+ global = os_zalloc(sizeof(*global));
+ global->sock = socket(PF_INET, SOCK_DGRAM, 0);
+ if (global->sock < 0)
+ goto fail1;
+ global->route = socket(PF_ROUTE, SOCK_RAW, 0);
+ if (global->route < 0)
+ goto fail;
+
+ global->global = priv;
+ eloop_register_read_sock(global->route,
+ wpa_driver_bsd_event_receive, NULL, global);
+ return global;
+
+fail:
+ close(global->sock);
+fail1:
+ os_free(global);
+ return NULL;
+}
+
+static void
+wpa_driver_bsd_global_deinit(void *priv)
+{
+ struct wpa_driver_bsd_global *global = priv;
+
+ eloop_unregister_read_sock(global->route);
+ (void) close(global->route);
+ (void) close(global->sock);
+ os_free(global);
+}
+
const struct wpa_driver_ops wpa_driver_bsd_ops = {
.name = "bsd",
.desc = "BSD 802.11 support",
- .init = wpa_driver_bsd_init,
+ .global_init = wpa_driver_bsd_global_init,
+ .global_deinit = wpa_driver_bsd_global_deinit,
+ .init2 = wpa_driver_bsd_init2,
.deinit = wpa_driver_bsd_deinit,
.get_bssid = wpa_driver_bsd_get_bssid,
.get_ssid = wpa_driver_bsd_get_ssid,
--
1.6.2.5
More information about the Hostap
mailing list