nl80211: Merge handle_frame() implementations
authorJouni Malinen <jouni.malinen@atheros.com>
Tue, 14 Apr 2009 12:35:03 +0000 (15:35 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 14 Apr 2009 12:35:03 +0000 (15:35 +0300)
src/drivers/driver_nl80211.c

index 5993c97..073494a 100644 (file)
@@ -111,25 +111,25 @@ struct wpa_driver_nl80211_data {
        u8 ssid[32];
        size_t ssid_len;
 
-#ifdef CONFIG_AP
+#if defined(CONFIG_AP) || defined(HOSTAPD)
        int beacon_int;
-       unsigned int beacon_set:1;
        int monitor_sock;
        int monitor_ifidx;
+#endif /* CONFIG_AP || HOSTAPD */
+
+#ifdef CONFIG_AP
+       unsigned int beacon_set:1;
 #endif /* CONFIG_AP */
 
 #ifdef HOSTAPD
        struct hostapd_data *hapd;
 
        int eapol_sock; /* socket for EAPOL frames */
-       int monitor_sock; /* socket for monitor */
-       int monitor_ifidx;
 
        int default_if_indices[16];
        int *if_indices;
        int num_if_indices;
 
-       int beacon_int;
        struct i802_bss bss;
        unsigned int ht_40mhz_scan:1;
 
@@ -154,10 +154,6 @@ static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
 #endif /* CONFIG_AP */
 
 #ifdef HOSTAPD
-static void handle_frame(struct wpa_driver_nl80211_data *drv,
-                        u8 *buf, size_t len,
-                        struct hostapd_frame_info *hfi,
-                        enum ieee80211_msg_type msg_type);
 static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
 static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
 static struct i802_bss * get_bss(struct wpa_driver_nl80211_data *drv,
@@ -338,13 +334,13 @@ static int wpa_driver_nl80211_send_oper_ifla(
                        RTA_LENGTH(sizeof(char));
        }
 
-       wpa_printf(MSG_DEBUG, "WEXT: Operstate: linkmode=%d, operstate=%d",
+       wpa_printf(MSG_DEBUG, "nl80211: Operstate: linkmode=%d, operstate=%d",
                   linkmode, operstate);
 
        ret = send(drv->link_event_sock, &req, req.hdr.nlmsg_len, 0);
        if (ret < 0) {
-               wpa_printf(MSG_DEBUG, "WEXT: Sending operstate IFLA failed: "
-                          "%s (assume operstate is not supported)",
+               wpa_printf(MSG_DEBUG, "nl80211: Sending operstate IFLA failed:"
+                          " %s (assume operstate is not supported)",
                           strerror(errno));
        }
 
@@ -2330,9 +2326,6 @@ static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok)
        }
 }
 
-#endif /* CONFIG_AP || HOSTAPD */
-
-#ifdef CONFIG_AP
 
 static void handle_frame(struct wpa_driver_nl80211_data *drv,
                         u8 *buf, size_t len,
@@ -2342,6 +2335,14 @@ static void handle_frame(struct wpa_driver_nl80211_data *drv,
        struct ieee80211_hdr *hdr;
        u16 fc, type, stype;
        size_t data_len = len;
+       u8 *bssid;
+       void *ctx = drv->ctx;
+#ifdef HOSTAPD
+       struct hostapd_iface *iface = drv->hapd->iface;
+       struct hostapd_data *hapd = NULL;
+       int broadcast_bssid = 0;
+       size_t i;
+#endif /* HOSTAPD */
 
        /*
         * PS-Poll frames are 16 bytes. All other frames are
@@ -2362,8 +2363,10 @@ static void handle_frame(struct wpa_driver_nl80211_data *drv,
                        return;
                switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
                case WLAN_FC_TODS:
+                       bssid = hdr->addr1;
                        break;
                case WLAN_FC_FROMDS:
+                       bssid = hdr->addr2;
                        break;
                default:
                        /* discard */
@@ -2374,23 +2377,55 @@ static void handle_frame(struct wpa_driver_nl80211_data *drv,
                /* discard non-ps-poll frames */
                if (stype != WLAN_FC_STYPE_PSPOLL)
                        return;
+               bssid = hdr->addr1;
                break;
        case WLAN_FC_TYPE_MGMT:
+               bssid = hdr->addr3;
                break;
        default:
                /* discard */
                return;
        }
 
+#ifdef HOSTAPD
+       /* find interface frame belongs to */
+       for (i = 0; i < iface->num_bss; i++) {
+               if (memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) {
+                       hapd = iface->bss[i];
+                       break;
+               }
+       }
+
+       if (hapd == NULL) {
+               hapd = iface->bss[0];
+
+               if (bssid[0] != 0xff || bssid[1] != 0xff ||
+                   bssid[2] != 0xff || bssid[3] != 0xff ||
+                   bssid[4] != 0xff || bssid[5] != 0xff) {
+                       /*
+                        * Unknown BSSID - drop frame if this is not from
+                        * passive scanning or a beacon (at least ProbeReq
+                        * frames to other APs may be allowed through RX
+                        * filtering in the wlan hw/driver)
+                        */
+                       if ((type != WLAN_FC_TYPE_MGMT ||
+                            stype != WLAN_FC_STYPE_BEACON))
+                               return;
+               } else
+                       broadcast_bssid = 1;
+       }
+       ctx = hapd;
+#endif /* HOSTAPD */
+
        switch (msg_type) {
        case ieee80211_msg_normal:
                /* continue processing */
                break;
        case ieee80211_msg_tx_callback_ack:
-               handle_tx_callback(drv->ctx, buf, data_len, 1);
+               handle_tx_callback(ctx, buf, data_len, 1);
                return;
        case ieee80211_msg_tx_callback_fail:
-               handle_tx_callback(drv->ctx, buf, data_len, 0);
+               handle_tx_callback(ctx, buf, data_len, 0);
                return;
        }
 
@@ -2399,22 +2434,36 @@ static void handle_frame(struct wpa_driver_nl80211_data *drv,
                if (stype != WLAN_FC_STYPE_BEACON &&
                    stype != WLAN_FC_STYPE_PROBE_REQ)
                        wpa_printf(MSG_MSGDUMP, "MGMT");
+#ifdef HOSTAPD
+               if (broadcast_bssid) {
+                       for (i = 0; i < iface->num_bss; i++)
+                               hostapd_mgmt_rx(iface->bss[i], buf, data_len,
+                                               stype, hfi);
+               } else
+                       hostapd_mgmt_rx(hapd, buf, data_len, stype, hfi);
+#else /* HOSTAPD */
                ap_mgmt_rx(drv->ctx, buf, data_len, stype, hfi);
+#endif /* HOSTAPD */
                break;
        case WLAN_FC_TYPE_CTRL:
                /* can only get here with PS-Poll frames */
                wpa_printf(MSG_DEBUG, "CTRL");
+#ifdef HOSTAPD
+               hostapd_rx_from_unknown_sta(drv->hapd, hdr->addr2);
+#else /* HOSTAPD */
                ap_rx_from_unknown_sta(drv->ctx, hdr->addr2);
+#endif /* HOSTAPD */
                break;
        case WLAN_FC_TYPE_DATA:
+#ifdef HOSTAPD
+               hostapd_rx_from_unknown_sta(drv->hapd, hdr->addr2);
+#else /* HOSTAPD */
                ap_rx_from_unknown_sta(drv->ctx, hdr->addr2);
+#endif /* HOSTAPD */
                break;
        }
 }
 
-#endif /* CONFIG_AP */
-
-#if defined(CONFIG_AP) || defined(HOSTAPD)
 
 static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
 {
@@ -3651,126 +3700,6 @@ static int i802_set_sta_vlan(void *priv, const u8 *addr,
 }
 
 
-static void handle_frame(struct wpa_driver_nl80211_data *drv,
-                        u8 *buf, size_t len,
-                        struct hostapd_frame_info *hfi,
-                        enum ieee80211_msg_type msg_type)
-{
-       struct hostapd_iface *iface = drv->hapd->iface;
-       struct ieee80211_hdr *hdr;
-       u16 fc, type, stype;
-       size_t data_len = len;
-       struct hostapd_data *hapd = NULL;
-       int broadcast_bssid = 0;
-       size_t i;
-       u8 *bssid;
-
-       /*
-        * PS-Poll frames are 16 bytes. All other frames are
-        * 24 bytes or longer.
-        */
-       if (len < 16)
-               return;
-
-       hdr = (struct ieee80211_hdr *) buf;
-       fc = le_to_host16(hdr->frame_control);
-
-       type = WLAN_FC_GET_TYPE(fc);
-       stype = WLAN_FC_GET_STYPE(fc);
-
-       switch (type) {
-       case WLAN_FC_TYPE_DATA:
-               if (len < 24)
-                       return;
-               switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
-               case WLAN_FC_TODS:
-                       bssid = hdr->addr1;
-                       break;
-               case WLAN_FC_FROMDS:
-                       bssid = hdr->addr2;
-                       break;
-               default:
-                       /* discard */
-                       return;
-               }
-               break;
-       case WLAN_FC_TYPE_CTRL:
-               /* discard non-ps-poll frames */
-               if (stype != WLAN_FC_STYPE_PSPOLL)
-                       return;
-               bssid = hdr->addr1;
-               break;
-       case WLAN_FC_TYPE_MGMT:
-               bssid = hdr->addr3;
-               break;
-       default:
-               /* discard */
-               return;
-       }
-
-       /* find interface frame belongs to */
-       for (i = 0; i < iface->num_bss; i++) {
-               if (memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) {
-                       hapd = iface->bss[i];
-                       break;
-               }
-       }
-
-       if (hapd == NULL) {
-               hapd = iface->bss[0];
-
-               if (bssid[0] != 0xff || bssid[1] != 0xff ||
-                   bssid[2] != 0xff || bssid[3] != 0xff ||
-                   bssid[4] != 0xff || bssid[5] != 0xff) {
-                       /*
-                        * Unknown BSSID - drop frame if this is not from
-                        * passive scanning or a beacon (at least ProbeReq
-                        * frames to other APs may be allowed through RX
-                        * filtering in the wlan hw/driver)
-                        */
-                       if ((type != WLAN_FC_TYPE_MGMT ||
-                            stype != WLAN_FC_STYPE_BEACON))
-                               return;
-               } else
-                       broadcast_bssid = 1;
-       }
-
-       switch (msg_type) {
-       case ieee80211_msg_normal:
-               /* continue processing */
-               break;
-       case ieee80211_msg_tx_callback_ack:
-               handle_tx_callback(hapd, buf, data_len, 1);
-               return;
-       case ieee80211_msg_tx_callback_fail:
-               handle_tx_callback(hapd, buf, data_len, 0);
-               return;
-       }
-
-       switch (type) {
-       case WLAN_FC_TYPE_MGMT:
-               if (stype != WLAN_FC_STYPE_BEACON &&
-                   stype != WLAN_FC_STYPE_PROBE_REQ)
-                       wpa_printf(MSG_MSGDUMP, "MGMT");
-               if (broadcast_bssid) {
-                       for (i = 0; i < iface->num_bss; i++)
-                               hostapd_mgmt_rx(iface->bss[i], buf, data_len,
-                                               stype, hfi);
-               } else
-                       hostapd_mgmt_rx(hapd, buf, data_len, stype, hfi);
-               break;
-       case WLAN_FC_TYPE_CTRL:
-               /* can only get here with PS-Poll frames */
-               wpa_printf(MSG_DEBUG, "CTRL");
-               hostapd_rx_from_unknown_sta(drv->hapd, hdr->addr2);
-               break;
-       case WLAN_FC_TYPE_DATA:
-               hostapd_rx_from_unknown_sta(drv->hapd, hdr->addr2);
-               break;
-       }
-}
-
-
 static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
 {
        struct wpa_driver_nl80211_data *drv = eloop_ctx;