wpa_priv: Clear extended_capa pointers
[mech_eap.git] / wpa_supplicant / wpa_priv.c
index 74476e2..c8335fc 100644 (file)
@@ -29,8 +29,9 @@ struct wpa_priv_interface {
        char *sock_name;
        int fd;
 
-       struct wpa_driver_ops *driver;
+       const struct wpa_driver_ops *driver;
        void *drv_priv;
+       void *drv_global_priv;
        struct sockaddr_un drv_addr;
        int wpas_registered;
 
@@ -48,6 +49,10 @@ static void wpa_priv_cmd_register(struct wpa_priv_interface *iface,
                if (iface->driver->deinit)
                        iface->driver->deinit(iface->drv_priv);
                iface->drv_priv = NULL;
+               if (iface->drv_global_priv) {
+                       iface->driver->global_deinit(iface->drv_global_priv);
+                       iface->drv_global_priv = NULL;
+               }
                iface->wpas_registered = 0;
        }
 
@@ -58,10 +63,24 @@ static void wpa_priv_cmd_register(struct wpa_priv_interface *iface,
                iface->l2 = NULL;
        }
 
-       if (iface->driver->init == NULL)
+       if (iface->driver->init2) {
+               if (iface->driver->global_init) {
+                       iface->drv_global_priv = iface->driver->global_init();
+                       if (!iface->drv_global_priv) {
+                               wpa_printf(MSG_INFO,
+                                          "Failed to initialize driver global context");
+                               return;
+                       }
+               } else {
+                       iface->drv_global_priv = NULL;
+               }
+               iface->drv_priv = iface->driver->init2(iface, iface->ifname,
+                                                      iface->drv_global_priv);
+       } else if (iface->driver->init) {
+               iface->drv_priv = iface->driver->init(iface, iface->ifname);
+       } else {
                return;
-
-       iface->drv_priv = iface->driver->init(iface, iface->ifname);
+       }
        if (iface->drv_priv == NULL) {
                wpa_printf(MSG_DEBUG, "Failed to initialize driver wrapper");
                return;
@@ -87,6 +106,10 @@ static void wpa_priv_cmd_unregister(struct wpa_priv_interface *iface,
                if (iface->driver->deinit)
                        iface->driver->deinit(iface->drv_priv);
                iface->drv_priv = NULL;
+               if (iface->drv_global_priv) {
+                       iface->driver->global_deinit(iface->drv_global_priv);
+                       iface->drv_global_priv = NULL;
+               }
                iface->wpas_registered = 0;
        }
 }
@@ -199,10 +222,12 @@ static void wpa_priv_cmd_associate(struct wpa_priv_interface *iface,
        if (bssid[0] | bssid[1] | bssid[2] | bssid[3] | bssid[4] | bssid[5])
                params.bssid = bssid;
        params.ssid = assoc->ssid;
-       if (assoc->ssid_len > 32)
+       if (assoc->ssid_len > SSID_MAX_LEN)
                return;
        params.ssid_len = assoc->ssid_len;
-       params.freq = assoc->freq;
+       params.freq.mode = assoc->hwmode;
+       params.freq.freq = assoc->freq;
+       params.freq.channel = assoc->channel;
        if (assoc->wpa_ie_len) {
                params.wpa_ie = (u8 *) (assoc + 1);
                params.wpa_ie_len = assoc->wpa_ie_len;
@@ -242,7 +267,7 @@ fail:
 static void wpa_priv_cmd_get_ssid(struct wpa_priv_interface *iface,
                                  struct sockaddr_un *from)
 {
-       u8 ssid[sizeof(int) + 32];
+       u8 ssid[sizeof(int) + SSID_MAX_LEN];
        int res;
 
        if (iface->drv_priv == NULL)
@@ -252,7 +277,7 @@ static void wpa_priv_cmd_get_ssid(struct wpa_priv_interface *iface,
                goto fail;
 
        res = iface->driver->get_ssid(iface->drv_priv, &ssid[sizeof(int)]);
-       if (res < 0 || res > 32)
+       if (res < 0 || res > SSID_MAX_LEN)
                goto fail;
        os_memcpy(ssid, &res, sizeof(int));
 
@@ -305,6 +330,10 @@ static void wpa_priv_cmd_get_capa(struct wpa_priv_interface *iface,
            iface->driver->get_capa(iface->drv_priv, &capa) < 0)
                goto fail;
 
+       /* For now, no support for passing extended_capa pointers */
+       capa.extended_capa = NULL;
+       capa.extended_capa_mask = NULL;
+       capa.extended_capa_len = 0;
        sendto(iface->fd, &capa, sizeof(capa), 0, (struct sockaddr *) from,
               sizeof(*from));
        return;
@@ -333,7 +362,7 @@ static void wpa_priv_l2_rx(void *ctx, const u8 *src_addr, const u8 *buf,
        msg.msg_namelen = sizeof(iface->l2_addr);
 
        if (sendmsg(iface->fd, &msg, 0) < 0) {
-               perror("sendmsg(l2 rx)");
+               wpa_printf(MSG_ERROR, "sendmsg(l2 rx): %s", strerror(errno));
        }
 }
 
@@ -354,7 +383,8 @@ static void wpa_priv_cmd_l2_register(struct wpa_priv_interface *iface,
        }
 
        proto = reg_cmd[0];
-       if (proto != ETH_P_EAPOL && proto != ETH_P_RSN_PREAUTH) {
+       if (proto != ETH_P_EAPOL && proto != ETH_P_RSN_PREAUTH &&
+           proto != ETH_P_80211_ENCAP) {
                wpa_printf(MSG_DEBUG, "Refused l2_packet connection for "
                           "ethertype 0x%x", proto);
                return;
@@ -465,7 +495,7 @@ static void wpa_priv_receive(int sock, void *eloop_ctx, void *sock_ctx)
        res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &from,
                       &fromlen);
        if (res < 0) {
-               perror("recvfrom");
+               wpa_printf(MSG_ERROR, "recvfrom: %s", strerror(errno));
                return;
        }
 
@@ -552,8 +582,6 @@ static void wpa_priv_interface_deinit(struct wpa_priv_interface *iface)
 }
 
 
-extern struct wpa_driver_ops *wpa_drivers[];
-
 static struct wpa_priv_interface *
 wpa_priv_interface_init(const char *dir, const char *params)
 {
@@ -573,13 +601,11 @@ wpa_priv_interface_init(const char *dir, const char *params)
        iface->fd = -1;
 
        len = pos - params;
-       iface->driver_name = os_malloc(len + 1);
+       iface->driver_name = dup_binstr(params, len);
        if (iface->driver_name == NULL) {
                wpa_priv_interface_deinit(iface);
                return NULL;
        }
-       os_memcpy(iface->driver_name, params, len);
-       iface->driver_name[len] = '\0';
 
        for (i = 0; wpa_drivers[i]; i++) {
                if (os_strcmp(iface->driver_name,
@@ -617,7 +643,7 @@ wpa_priv_interface_init(const char *dir, const char *params)
 
        iface->fd = socket(PF_UNIX, SOCK_DGRAM, 0);
        if (iface->fd < 0) {
-               perror("socket(PF_UNIX)");
+               wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
                wpa_priv_interface_deinit(iface);
                return NULL;
        }
@@ -635,15 +661,16 @@ wpa_priv_interface_init(const char *dir, const char *params)
                                   "allow connections - assuming it was "
                                   "leftover from forced program termination");
                        if (unlink(iface->sock_name) < 0) {
-                               perror("unlink[ctrl_iface]");
-                               wpa_printf(MSG_ERROR, "Could not unlink "
-                                          "existing ctrl_iface socket '%s'",
-                                          iface->sock_name);
+                               wpa_printf(MSG_ERROR,
+                                          "Could not unlink existing ctrl_iface socket '%s': %s",
+                                          iface->sock_name, strerror(errno));
                                goto fail;
                        }
                        if (bind(iface->fd, (struct sockaddr *) &addr,
                                 sizeof(addr)) < 0) {
-                               perror("bind(PF_UNIX)");
+                               wpa_printf(MSG_ERROR,
+                                          "wpa-priv-iface-init: bind(PF_UNIX): %s",
+                                          strerror(errno));
                                goto fail;
                        }
                        wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
@@ -658,7 +685,7 @@ wpa_priv_interface_init(const char *dir, const char *params)
        }
 
        if (chmod(iface->sock_name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
-               perror("chmod");
+               wpa_printf(MSG_ERROR, "chmod: %s", strerror(errno));
                goto fail;
        }
 
@@ -690,7 +717,8 @@ static int wpa_priv_send_event(struct wpa_priv_interface *iface, int event,
        msg.msg_namelen = sizeof(iface->drv_addr);
 
        if (sendmsg(iface->fd, &msg, 0) < 0) {
-               perror("sendmsg(wpas_socket)");
+               wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s",
+                          strerror(errno));
                return -1;
        }
 
@@ -905,7 +933,8 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
        msg.msg_namelen = sizeof(iface->drv_addr);
 
        if (sendmsg(iface->fd, &msg, 0) < 0)
-               perror("sendmsg(wpas_socket)");
+               wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s",
+                          strerror(errno));
 }
 
 
@@ -943,13 +972,12 @@ static void usage(void)
               "contributors\n"
               "\n"
               "usage:\n"
-              "  wpa_priv [-Bdd] [-P<pid file>] <driver:ifname> "
-              "[driver:ifname ...]\n");
+              "  wpa_priv [-Bdd] [-c<ctrl dir>] [-P<pid file>] "
+              "<driver:ifname> \\\n"
+              "           [driver:ifname ...]\n");
 }
 
 
-extern int wpa_debug_level;
-
 int main(int argc, char *argv[])
 {
        int c, i;
@@ -983,20 +1011,20 @@ int main(int argc, char *argv[])
                        break;
                default:
                        usage();
-                       goto out;
+                       goto out2;
                }
        }
 
        if (optind >= argc) {
                usage();
-               goto out;
+               goto out2;
        }
 
        wpa_printf(MSG_DEBUG, "wpa_priv control directory: '%s'", ctrl_dir);
 
        if (eloop_init()) {
                wpa_printf(MSG_ERROR, "Failed to initialize event loop");
-               goto out;
+               goto out2;
        }
 
        for (i = optind; i < argc; i++) {
@@ -1026,7 +1054,9 @@ out:
 
        eloop_destroy();
 
-       os_daemonize_terminate(pid_file);
+out2:
+       if (daemonize)
+               os_daemonize_terminate(pid_file);
        os_free(pid_file);
        os_program_deinit();