2 * hostapd / Driver interaction with Prism54 PIMFOR interface
3 * Copyright (c) 2004, Bell Kin <bell_kin@pek.com.tw>
4 * based on hostap driver.c, ieee802_11.c
5 * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Alternatively, this software may be distributed under the terms of BSD
14 * See README and COPYING for more details.
18 #include <sys/ioctl.h>
19 #include <sys/select.h>
21 #ifdef USE_KERNEL_HEADERS
22 /* compat-wireless does not include linux/compiler.h to define __user, so
27 #include <asm/types.h>
28 #include <linux/if_packet.h>
29 #include <linux/if_ether.h> /* The L2 protocols */
30 #include <linux/if_arp.h>
31 #include <linux/wireless.h>
32 #else /* USE_KERNEL_HEADERS */
33 #include <net/if_arp.h>
34 #include <netpacket/packet.h>
35 #include "wireless_copy.h"
36 #endif /* USE_KERNEL_HEADERS */
40 #include "ieee802_1x.h"
42 #include "ieee802_11.h"
45 #include "radius/radius.h"
47 #include "accounting.h"
49 const int PIM_BUF_SIZE
= 4096;
51 struct prism54_driver_data
{
52 struct hostapd_data
*hapd
;
53 char iface
[IFNAMSIZ
+ 1];
54 int sock
; /* raw packet socket for 802.3 access */
55 int pim_sock
; /* socket for pimfor packet */
60 static int mac_id_refresh(struct prism54_driver_data
*data
, int id
, char *mac
)
62 if (id
< 0 || id
> 2006) {
65 memcpy(&data
->macs
[id
][0], mac
, ETH_ALEN
);
70 static char * mac_id_get(struct prism54_driver_data
*data
, int id
)
72 if (id
< 0 || id
> 2006) {
75 return &data
->macs
[id
][0];
79 /* wait for a specific pimfor, timeout in 10ms resolution */
80 /* pim_sock must be non-block to prevent dead lock from no response */
81 /* or same response type in series */
82 static int prism54_waitpim(void *priv
, unsigned long oid
, void *buf
, int len
,
85 struct prism54_driver_data
*drv
= priv
;
86 struct timeval tv
, stv
, ctv
;
96 gettimeofday(&stv
, NULL
);
98 FD_SET(drv
->pim_sock
, &pfd
);
101 if (select(drv
->pim_sock
+ 1, &pfd
, NULL
, NULL
, &tv
)) {
102 rlen
= recv(drv
->pim_sock
, pkt
, 8192, 0);
104 if (pkt
->oid
== htonl(oid
)) {
107 memcpy(buf
, pkt
, rlen
);
112 printf("buffer too small\n");
117 gettimeofday(&ctv
, NULL
);
122 gettimeofday(&ctv
, NULL
);
123 } while (((ctv
.tv_sec
- stv
.tv_sec
) * 100 +
124 (ctv
.tv_usec
- stv
.tv_usec
) / 10000) > timeout
);
130 /* send an eapol packet */
131 static int prism54_send_eapol(void *priv
, const u8
*addr
,
132 const u8
*data
, size_t data_len
, int encrypt
,
135 struct prism54_driver_data
*drv
= priv
;
141 len
= sizeof(*hdr
) + data_len
;
142 hdr
= os_zalloc(len
);
144 printf("malloc() failed for prism54_send_data(len=%lu)\n",
145 (unsigned long) len
);
149 memcpy(&hdr
->da
[0], addr
, ETH_ALEN
);
150 memcpy(&hdr
->sa
[0], own_addr
, ETH_ALEN
);
151 hdr
->type
= htons(ETH_P_PAE
);
152 pos
= (u8
*) (hdr
+ 1);
153 memcpy(pos
, data
, data_len
);
155 res
= send(drv
->sock
, hdr
, len
, 0);
159 perror("hostapd_send_eapol: send");
160 printf("hostapd_send_eapol - packet len: %lu - failed\n",
161 (unsigned long) len
);
168 /* open data channel(auth-1) or eapol only(unauth-0) */
169 static int prism54_set_sta_authorized(void *priv
, const u8
*addr
,
172 struct prism54_driver_data
*drv
= priv
;
176 hdr
= malloc(sizeof(*hdr
) + ETH_ALEN
);
179 hdr
->op
= htonl(PIMOP_SET
);
181 hdr
->oid
= htonl(DOT11_OID_EAPAUTHSTA
);
183 hdr
->oid
= htonl(DOT11_OID_EAPUNAUTHSTA
);
185 pos
= (char *) (hdr
+ 1);
186 memcpy(pos
, addr
, ETH_ALEN
);
187 send(drv
->pim_sock
, hdr
, sizeof(*hdr
) + ETH_ALEN
, 0);
188 prism54_waitpim(priv
, hdr
->oid
, hdr
, sizeof(*hdr
) + ETH_ALEN
, 10);
195 prism54_sta_set_flags(void *priv
, const u8
*addr
, int total_flags
,
196 int flags_or
, int flags_and
)
198 /* For now, only support setting Authorized flag */
199 if (flags_or
& WLAN_STA_AUTHORIZED
)
200 return prism54_set_sta_authorized(priv
, addr
, 1);
201 if (flags_and
& WLAN_STA_AUTHORIZED
)
202 return prism54_set_sta_authorized(priv
, addr
, 0);
207 /* set per station key */
208 static int prism54_set_encryption(const char *ifname
, void *priv
,
209 const char *alg
, const u8
*addr
,
210 int idx
, const u8
*key
, size_t key_len
,
213 struct prism54_driver_data
*drv
= priv
;
215 struct obj_stakey
*keys
;
220 blen
= sizeof(struct obj_stakey
) + sizeof(pimdev_hdr
);
223 printf("memory low\n");
226 keys
= (struct obj_stakey
*) &hdr
[1];
228 memset(&keys
->address
[0], 0xff, ETH_ALEN
);
230 memcpy(&keys
->address
[0], addr
, ETH_ALEN
);
232 if (!strcmp(alg
, "WEP")) {
233 keys
->type
= DOT11_PRIV_WEP
;
234 } else if (!strcmp(alg
, "TKIP")) {
235 keys
->type
= DOT11_PRIV_TKIP
;
236 } else if (!strcmp(alg
, "none")) {
237 /* the only way to clear the key is to deauth it */
238 /* and prism54 is capable to receive unencrypted packet */
239 /* so we do nothing here */
243 printf("bad auth type: %s\n", alg
);
245 buf
= (u8
*) &keys
->key
[0];
246 keys
->length
= key_len
;
248 keys
->options
= htons(DOT11_STAKEY_OPTION_DEFAULTKEY
);
251 hdr
->op
= htonl(PIMOP_SET
);
252 hdr
->oid
= htonl(DOT11_OID_STAKEY
);
254 memcpy(buf
, key
, key_len
);
256 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
261 prism54_waitpim(priv
, hdr
->oid
, hdr
, blen
, 10);
269 /* get TKIP station sequence counter, prism54 is only 6 bytes */
270 static int prism54_get_seqnum(const char *ifname
, void *priv
, const u8
*addr
,
273 struct prism54_driver_data
*drv
= priv
;
274 struct obj_stasc
*stasc
;
279 blen
= sizeof(*stasc
) + sizeof(*hdr
);
284 stasc
= (struct obj_stasc
*) &hdr
[1];
287 memset(&stasc
->address
[0], 0xff, ETH_ALEN
);
289 memcpy(&stasc
->address
[0], addr
, ETH_ALEN
);
291 hdr
->oid
= htonl(DOT11_OID_STASC
);
292 hdr
->op
= htonl(PIMOP_GET
);
294 if (send(drv
->pim_sock
,hdr
,blen
,0) <= 0) {
298 if (prism54_waitpim(priv
, DOT11_OID_STASC
, hdr
, blen
, 10) <= 0) {
301 if (hdr
->op
== (int) htonl(PIMOP_RESPONSE
)) {
302 memcpy(seq
+ 2, &stasc
->sc_high
, ETH_ALEN
);
314 /* include unencrypted, set mlme autolevel to extended */
315 static int prism54_init_1x(void *priv
)
317 struct prism54_driver_data
*drv
= priv
;
320 int blen
= sizeof(*hdr
) + sizeof(*ul
);
326 ul
= (unsigned long *) &hdr
[1];
327 hdr
->op
= htonl(PIMOP_SET
);
328 hdr
->oid
= htonl(DOT11_OID_EXUNENCRYPTED
);
329 *ul
= htonl(DOT11_BOOL_TRUE
); /* not accept */
330 send(drv
->pim_sock
, hdr
, blen
, 0);
331 prism54_waitpim(priv
, DOT11_OID_EXUNENCRYPTED
, hdr
, blen
, 10);
332 hdr
->op
= htonl(PIMOP_SET
);
333 hdr
->oid
= htonl(DOT11_OID_MLMEAUTOLEVEL
);
334 *ul
= htonl(DOT11_MLME_EXTENDED
);
335 send(drv
->pim_sock
, hdr
, blen
, 0);
336 prism54_waitpim(priv
, DOT11_OID_MLMEAUTOLEVEL
, hdr
, blen
, 10);
337 hdr
->op
= htonl(PIMOP_SET
);
338 hdr
->oid
= htonl(DOT11_OID_DOT1XENABLE
);
339 *ul
= htonl(DOT11_BOOL_TRUE
);
340 send(drv
->pim_sock
, hdr
, blen
, 0);
341 prism54_waitpim(priv
, DOT11_OID_DOT1XENABLE
, hdr
, blen
, 10);
342 hdr
->op
= htonl(PIMOP_SET
);
343 hdr
->oid
= htonl(DOT11_OID_AUTHENABLE
);
344 *ul
= htonl(DOT11_AUTH_OS
); /* OS */
345 send(drv
->pim_sock
, hdr
, blen
, 0);
346 prism54_waitpim(priv
, DOT11_OID_AUTHENABLE
, hdr
, blen
, 10);
352 static int prism54_set_privacy_invoked(const char *ifname
, void *priv
,
355 struct prism54_driver_data
*drv
= priv
;
359 int blen
= sizeof(*hdr
) + sizeof(*ul
);
363 ul
= (unsigned long *) &hdr
[1];
364 hdr
->op
= htonl(PIMOP_SET
);
365 hdr
->oid
= htonl(DOT11_OID_PRIVACYINVOKED
);
367 *ul
= htonl(DOT11_BOOL_TRUE
); /* has privacy */
371 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
373 ret
= prism54_waitpim(priv
, DOT11_OID_PRIVACYINVOKED
, hdr
,
381 static int prism54_ioctl_setiwessid(const char *ifname
, void *priv
,
382 const u8
*buf
, int len
)
385 struct prism54_driver_data
*drv
= priv
;
388 memset(&iwr
, 0, sizeof(iwr
));
389 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
390 iwr
.u
.essid
.flags
= 1; /* SSID active */
391 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
392 iwr
.u
.essid
.length
= len
+ 1;
394 if (ioctl(drv
->pim_sock
, SIOCSIWESSID
, &iwr
) < 0) {
395 perror("ioctl[SIOCSIWESSID]");
396 printf("len=%d\n", len
);
404 /* kick all stations */
405 /* does not work during init, but at least it won't crash firmware */
406 static int prism54_flush(void *priv
)
408 struct prism54_driver_data
*drv
= priv
;
409 struct obj_mlmeex
*mlme
;
414 int blen
= sizeof(*hdr
) + sizeof(*mlme
);
417 hdr
= os_zalloc(blen
);
421 mlme
= (struct obj_mlmeex
*) &hdr
[1];
422 nsta
= (long *) &hdr
[1];
423 hdr
->op
= htonl(PIMOP_GET
);
424 hdr
->oid
= htonl(DOT11_OID_CLIENTS
);
425 ret
= send(drv
->pim_sock
, hdr
, sizeof(*hdr
) + sizeof(long), 0);
426 ret
= prism54_waitpim(priv
, DOT11_OID_CLIENTS
, hdr
, blen
, 10);
427 if ((ret
< 0) || (hdr
->op
!= (int) htonl(PIMOP_RESPONSE
)) ||
428 (le_to_host32(*nsta
) > 2007)) {
432 for (i
= 0; i
< le_to_host32(*nsta
); i
++) {
434 mac_id
= mac_id_get(drv
, i
);
436 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
437 mlme
->code
= host_to_le16(WLAN_REASON_UNSPECIFIED
);
438 mlme
->state
= htons(DOT11_STATE_NONE
);
440 hdr
->op
= htonl(PIMOP_SET
);
441 hdr
->oid
= htonl(DOT11_OID_DISASSOCIATEEX
);
442 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
443 prism54_waitpim(priv
, DOT11_OID_DISASSOCIATEEX
, hdr
, blen
,
446 for (i
= 0; i
< le_to_host32(*nsta
); i
++) {
448 mac_id
= mac_id_get(drv
, i
);
450 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
451 mlme
->code
= host_to_le16(WLAN_REASON_UNSPECIFIED
);
452 mlme
->state
= htons(DOT11_STATE_NONE
);
454 hdr
->op
= htonl(PIMOP_SET
);
455 hdr
->oid
= htonl(DOT11_OID_DEAUTHENTICATEEX
);
456 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
457 prism54_waitpim(priv
, DOT11_OID_DEAUTHENTICATEEX
, hdr
, blen
,
465 static int prism54_sta_deauth(void *priv
, const u8
*addr
, int reason
)
467 struct prism54_driver_data
*drv
= priv
;
469 struct obj_mlmeex
*mlme
;
471 int blen
= sizeof(*hdr
) + sizeof(*mlme
);
475 mlme
= (struct obj_mlmeex
*) &hdr
[1];
476 hdr
->op
= htonl(PIMOP_SET
);
477 hdr
->oid
= htonl(DOT11_OID_DEAUTHENTICATEEX
);
478 memcpy(&mlme
->address
[0], addr
, ETH_ALEN
);
480 mlme
->state
= htons(DOT11_STATE_NONE
);
481 mlme
->code
= host_to_le16(reason
);
483 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
484 prism54_waitpim(priv
, DOT11_OID_DEAUTHENTICATEEX
, hdr
, blen
, 10);
490 static int prism54_sta_disassoc(void *priv
, const u8
*addr
, int reason
)
492 struct prism54_driver_data
*drv
= priv
;
494 struct obj_mlmeex
*mlme
;
496 int blen
= sizeof(*hdr
) + sizeof(*mlme
);
500 mlme
= (struct obj_mlmeex
*) &hdr
[1];
501 hdr
->op
= htonl(PIMOP_SET
);
502 hdr
->oid
= htonl(DOT11_OID_DISASSOCIATEEX
);
503 memcpy(&mlme
->address
[0], addr
, ETH_ALEN
);
505 mlme
->state
= htons(DOT11_STATE_NONE
);
506 mlme
->code
= host_to_le16(reason
);
508 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
509 prism54_waitpim(priv
, DOT11_OID_DISASSOCIATEEX
, hdr
, blen
, 10);
515 static int prism54_get_inact_sec(void *priv
, const u8
*addr
)
517 struct prism54_driver_data
*drv
= priv
;
520 int blen
= sizeof(*hdr
) + sizeof(*sta
);
526 hdr
->op
= htonl(PIMOP_GET
);
527 hdr
->oid
= htonl(DOT11_OID_CLIENTFIND
);
528 sta
= (struct obj_sta
*) &hdr
[1];
529 memcpy(&sta
->address
[0], addr
, ETH_ALEN
);
530 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
531 ret
= prism54_waitpim(priv
, DOT11_OID_CLIENTFIND
, hdr
, blen
, 10);
533 printf("get_inact_sec: bad return %d\n", ret
);
537 if (hdr
->op
!= (int) htonl(PIMOP_RESPONSE
)) {
538 printf("get_inact_sec: bad resp\n");
543 return le_to_host16(sta
->age
);
547 /* set attachments */
548 static int prism54_set_generic_elem(const char *ifname
, void *priv
,
549 const u8
*elem
, size_t elem_len
)
551 struct prism54_driver_data
*drv
= priv
;
554 struct obj_attachment_hdr
*attach
;
555 size_t blen
= sizeof(*hdr
) + sizeof(*attach
) + elem_len
;
556 hdr
= os_zalloc(blen
);
558 printf("%s: memory low\n", __func__
);
561 hdr
->op
= htonl(PIMOP_SET
);
562 hdr
->oid
= htonl(DOT11_OID_ATTACHMENT
);
563 attach
= (struct obj_attachment_hdr
*)&hdr
[1];
564 attach
->type
= DOT11_PKT_BEACON
;
566 attach
->size
= host_to_le16((short)elem_len
);
567 pos
= ((char*) attach
) + sizeof(*attach
);
569 memcpy(pos
, elem
, elem_len
);
570 send(drv
->pim_sock
, hdr
, blen
, 0);
571 attach
->type
= DOT11_PKT_PROBE_RESP
;
572 send(drv
->pim_sock
, hdr
, blen
, 0);
578 /* tell the card to auth the sta */
579 static void prism54_handle_probe(struct prism54_driver_data
*drv
,
580 void *buf
, size_t len
)
582 struct obj_mlmeex
*mlme
;
584 struct sta_info
*sta
;
585 hdr
= (pimdev_hdr
*)buf
;
586 mlme
= (struct obj_mlmeex
*) &hdr
[1];
587 sta
= ap_get_sta(drv
->hapd
, (u8
*) &mlme
->address
[0]);
589 if (sta
->flags
& (WLAN_STA_AUTH
| WLAN_STA_ASSOC
))
592 if (len
< sizeof(*mlme
)) {
593 printf("bad probe packet\n");
596 mlme
->state
= htons(DOT11_STATE_AUTHING
);
598 hdr
->op
= htonl(PIMOP_SET
);
599 hdr
->oid
= htonl(DOT11_OID_AUTHENTICATEEX
);
601 send(drv
->pim_sock
, hdr
, sizeof(*hdr
)+sizeof(*mlme
), 0);
605 static void prism54_handle_deauth(struct prism54_driver_data
*drv
,
606 void *buf
, size_t len
)
608 struct obj_mlme
*mlme
;
610 struct sta_info
*sta
;
613 hdr
= (pimdev_hdr
*) buf
;
614 mlme
= (struct obj_mlme
*) &hdr
[1];
615 sta
= ap_get_sta(drv
->hapd
, (u8
*) &mlme
->address
[0]);
616 mac_id
= mac_id_get(drv
, mlme
->id
);
617 if (sta
== NULL
|| mac_id
== NULL
)
619 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
620 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
621 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
622 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
623 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
624 ap_free_sta(drv
->hapd
, sta
);
628 static void prism54_handle_disassoc(struct prism54_driver_data
*drv
,
629 void *buf
, size_t len
)
631 struct obj_mlme
*mlme
;
633 struct sta_info
*sta
;
636 hdr
= (pimdev_hdr
*) buf
;
637 mlme
= (struct obj_mlme
*) &hdr
[1];
638 mac_id
= mac_id_get(drv
, mlme
->id
);
641 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
642 sta
= ap_get_sta(drv
->hapd
, (u8
*) &mlme
->address
[0]);
646 sta
->flags
&= ~WLAN_STA_ASSOC
;
647 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
648 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
649 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
650 accounting_sta_stop(drv
->hapd
, sta
);
651 ieee802_1x_free_station(sta
);
655 /* to auth it, just allow it now, later for os/sk */
656 static void prism54_handle_auth(struct prism54_driver_data
*drv
,
657 void *buf
, size_t len
)
659 struct obj_mlmeex
*mlme
;
661 struct sta_info
*sta
;
664 hdr
= (pimdev_hdr
*) buf
;
665 mlme
= (struct obj_mlmeex
*) &hdr
[1];
666 if (len
< sizeof(*mlme
)) {
667 printf("bad auth packet\n");
671 if (mlme
->state
== htons(DOT11_STATE_AUTHING
)) {
672 sta
= ap_sta_add(drv
->hapd
, (u8
*) &mlme
->address
[0]);
673 if (drv
->hapd
->tkip_countermeasures
) {
674 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
677 mac_id_refresh(drv
, mlme
->id
, &mlme
->address
[0]);
679 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
682 sta
->flags
&= ~WLAN_STA_PREAUTH
;
684 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
685 sta
->flags
|= WLAN_STA_AUTH
;
686 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
688 mlme
->state
=htons(DOT11_STATE_AUTH
);
689 hdr
->op
= htonl(PIMOP_SET
);
690 hdr
->oid
= htonl(DOT11_OID_AUTHENTICATEEX
);
692 sta
->timeout_next
= STA_NULLFUNC
;
693 send(drv
->pim_sock
, hdr
, sizeof(*hdr
) + sizeof(*mlme
), 0);
698 printf("auth fail: %x\n", resp
);
699 mlme
->code
= host_to_le16(resp
);
702 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
703 hdr
->oid
= htonl(DOT11_OID_DEAUTHENTICATEEX
);
704 hdr
->op
= htonl(PIMOP_SET
);
705 send(drv
->pim_sock
, hdr
, sizeof(*hdr
)+sizeof(*mlme
), 0);
709 /* do the wpa thing */
710 static void prism54_handle_assoc(struct prism54_driver_data
*drv
,
711 void *buf
, size_t len
)
714 struct obj_mlmeex
*mlme
;
715 struct ieee802_11_elems elems
;
716 struct sta_info
*sta
;
725 hdr
= (pimdev_hdr
*) buf
;
726 mlme
= (struct obj_mlmeex
*) &hdr
[1];
727 switch (ntohl(hdr
->oid
)) {
728 case DOT11_OID_ASSOCIATE
:
729 case DOT11_OID_REASSOCIATE
:
734 if ((mlme
->state
== (int) htonl(DOT11_STATE_ASSOCING
)) ||
735 (mlme
->state
== (int) htonl(DOT11_STATE_REASSOCING
))) {
736 if (len
< sizeof(pimdev_hdr
) + sizeof(struct obj_mlme
)) {
737 printf("bad assoc packet\n");
740 mac_id
= mac_id_get(drv
, mlme
->id
);
743 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
744 sta
= ap_get_sta(drv
->hapd
, (u8
*) &mlme
->address
[0]);
746 printf("cannot get sta\n");
749 cb
= (u8
*) &mlme
->data
[0];
750 if (hdr
->oid
== htonl(DOT11_OID_ASSOCIATEEX
)) {
752 } else if (hdr
->oid
== htonl(DOT11_OID_REASSOCIATEEX
)) {
755 if (le_to_host16(mlme
->size
) <= ieofs
) {
756 printf("attach too small\n");
757 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
760 if (ieee802_11_parse_elems(drv
->hapd
, cb
+ ieofs
,
761 le_to_host16(mlme
->size
) - ieofs
,
762 &elems
, 1) == ParseFailed
) {
763 printf("STA " MACSTR
" sent invalid association "
764 "request\n", MAC2STR(sta
->addr
));
765 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
768 if ((drv
->hapd
->conf
->wpa
& WPA_PROTO_RSN
) &&
770 wpa_ie
= elems
.rsn_ie
;
771 wpa_ie_len
= elems
.rsn_ie_len
;
772 } else if ((drv
->hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
774 wpa_ie
= elems
.wpa_ie
;
775 wpa_ie_len
= elems
.wpa_ie_len
;
780 if (drv
->hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
781 printf("STA " MACSTR
": No WPA/RSN IE in association "
782 "request\n", MAC2STR(sta
->addr
));
783 resp
= WLAN_STATUS_INVALID_IE
;
786 if (drv
->hapd
->conf
->wpa
) {
790 if (sta
->wpa_sm
== NULL
)
791 sta
->wpa_sm
= wpa_auth_sta_init(
792 drv
->hapd
->wpa_auth
, sta
->addr
);
793 if (sta
->wpa_sm
== NULL
) {
794 printf("Failed to initialize WPA state "
796 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
799 res
= wpa_validate_wpa_ie(drv
->hapd
->wpa_auth
,
803 if (res
== WPA_INVALID_GROUP
)
804 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
805 else if (res
== WPA_INVALID_PAIRWISE
)
806 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
807 else if (res
== WPA_INVALID_AKMP
)
808 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
809 else if (res
== WPA_ALLOC_FAIL
)
810 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
811 else if (res
!= WPA_IE_OK
)
812 resp
= WLAN_STATUS_INVALID_IE
;
813 if (resp
!= WLAN_STATUS_SUCCESS
)
816 hdr
->oid
= (hdr
->oid
== htonl(DOT11_OID_ASSOCIATEEX
)) ?
817 htonl(DOT11_OID_ASSOCIATEEX
) :
818 htonl(DOT11_OID_REASSOCIATEEX
);
819 hdr
->op
= htonl(PIMOP_SET
);
821 mlme
->state
= htons(DOT11_STATE_ASSOC
);
823 send(drv
->pim_sock
, hdr
, sizeof(*hdr
) + sizeof(*mlme
), 0);
825 } else if (mlme
->state
==htons(DOT11_STATE_ASSOC
)) {
826 if (len
< sizeof(pimdev_hdr
) + sizeof(struct obj_mlme
)) {
827 printf("bad assoc packet\n");
830 mac_id
= mac_id_get(drv
, mlme
->id
);
833 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
834 sta
= ap_get_sta(drv
->hapd
, (u8
*) &mlme
->address
[0]);
836 printf("cannot get sta\n");
839 new_assoc
= (sta
->flags
& WLAN_STA_ASSOC
) == 0;
840 sta
->flags
|= WLAN_STA_AUTH
| WLAN_STA_ASSOC
;
841 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
842 hostapd_new_assoc_sta(drv
->hapd
, sta
, !new_assoc
);
843 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
844 sta
->timeout_next
= STA_NULLFUNC
;
850 printf("Prism54: assoc fail: %x\n", resp
);
851 mlme
->code
= host_to_le16(resp
);
853 mlme
->state
= htons(DOT11_STATE_ASSOCING
);
854 hdr
->oid
= htonl(DOT11_OID_DISASSOCIATEEX
);
855 hdr
->op
= htonl(PIMOP_SET
);
856 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
857 send(drv
->pim_sock
, hdr
, sizeof(*hdr
) + sizeof(*mlme
), 0);
861 static void handle_pim(int sock
, void *eloop_ctx
, void *sock_ctx
)
863 struct prism54_driver_data
*drv
= eloop_ctx
;
867 hdr
= malloc(PIM_BUF_SIZE
);
870 len
= recv(sock
, hdr
, PIM_BUF_SIZE
, 0);
877 printf("handle_pim: too short (%d)\n", len
);
882 if (hdr
->op
!= (int) htonl(PIMOP_TRAP
)) {
886 switch (ntohl(hdr
->oid
)) {
887 case DOT11_OID_PROBE
:
888 prism54_handle_probe(drv
, hdr
, len
);
890 case DOT11_OID_DEAUTHENTICATEEX
:
891 case DOT11_OID_DEAUTHENTICATE
:
892 prism54_handle_deauth(drv
, hdr
, len
);
894 case DOT11_OID_DISASSOCIATEEX
:
895 case DOT11_OID_DISASSOCIATE
:
896 prism54_handle_disassoc(drv
, hdr
, len
);
898 case DOT11_OID_AUTHENTICATEEX
:
899 case DOT11_OID_AUTHENTICATE
:
900 prism54_handle_auth(drv
, hdr
, len
);
902 case DOT11_OID_ASSOCIATEEX
:
903 case DOT11_OID_REASSOCIATEEX
:
904 case DOT11_OID_ASSOCIATE
:
905 case DOT11_OID_REASSOCIATE
:
906 prism54_handle_assoc(drv
, hdr
, len
);
915 static void handle_802_3(int sock
, void *eloop_ctx
, void *sock_ctx
)
917 struct hostapd_data
*hapd
= (struct hostapd_data
*) eloop_ctx
;
921 hdr
= malloc(PIM_BUF_SIZE
);
924 len
= recv(sock
, hdr
, PIM_BUF_SIZE
, 0);
931 wpa_printf(MSG_MSGDUMP
, "handle_802_3: too short (%d)", len
);
935 if (hdr
->type
== htons(ETH_P_PAE
)) {
936 ieee802_1x_receive(hapd
, (u8
*) &hdr
->sa
[0], (u8
*) &hdr
[1],
943 static int prism54_init_sockets(struct prism54_driver_data
*drv
)
945 struct hostapd_data
*hapd
= drv
->hapd
;
947 struct sockaddr_ll addr
;
949 drv
->sock
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_PAE
));
951 perror("socket[PF_PACKET,SOCK_RAW]");
955 if (eloop_register_read_sock(drv
->sock
, handle_802_3
, drv
->hapd
, NULL
))
957 printf("Could not register read socket\n");
961 memset(&ifr
, 0, sizeof(ifr
));
962 if (hapd
->conf
->bridge
[0] != '\0') {
963 printf("opening bridge: %s\n", hapd
->conf
->bridge
);
964 os_strlcpy(ifr
.ifr_name
, hapd
->conf
->bridge
,
965 sizeof(ifr
.ifr_name
));
967 os_strlcpy(ifr
.ifr_name
, drv
->iface
, sizeof(ifr
.ifr_name
));
969 if (ioctl(drv
->sock
, SIOCGIFINDEX
, &ifr
) != 0) {
970 perror("ioctl(SIOCGIFINDEX)");
974 memset(&addr
, 0, sizeof(addr
));
975 addr
.sll_family
= AF_PACKET
;
976 addr
.sll_ifindex
= ifr
.ifr_ifindex
;
977 addr
.sll_protocol
= htons(ETH_P_PAE
);
978 wpa_printf(MSG_DEBUG
, "Opening raw packet socket for ifindex %d",
981 if (bind(drv
->sock
, (struct sockaddr
*) &addr
, sizeof(addr
)) < 0) {
986 memset(&ifr
, 0, sizeof(ifr
));
987 os_strlcpy(ifr
.ifr_name
, drv
->iface
, sizeof(ifr
.ifr_name
));
988 if (ioctl(drv
->sock
, SIOCGIFHWADDR
, &ifr
) != 0) {
989 perror("ioctl(SIOCGIFHWADDR)");
993 if (ifr
.ifr_hwaddr
.sa_family
!= ARPHRD_ETHER
) {
994 printf("Invalid HW-addr family 0x%04x\n",
995 ifr
.ifr_hwaddr
.sa_family
);
998 memcpy(drv
->hapd
->own_addr
, ifr
.ifr_hwaddr
.sa_data
, ETH_ALEN
);
1000 drv
->pim_sock
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_ALL
));
1001 if (drv
->pim_sock
< 0) {
1002 perror("socket[PF_PACKET,SOCK_RAW]");
1006 if (eloop_register_read_sock(drv
->pim_sock
, handle_pim
, drv
, NULL
)) {
1007 printf("Could not register read socket\n");
1011 memset(&ifr
, 0, sizeof(ifr
));
1012 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%sap", drv
->iface
);
1013 if (ioctl(drv
->pim_sock
, SIOCGIFINDEX
, &ifr
) != 0) {
1014 perror("ioctl(SIOCGIFINDEX)");
1018 memset(&addr
, 0, sizeof(addr
));
1019 addr
.sll_family
= AF_PACKET
;
1020 addr
.sll_ifindex
= ifr
.ifr_ifindex
;
1021 addr
.sll_protocol
= htons(ETH_P_ALL
);
1022 wpa_printf(MSG_DEBUG
, "Opening raw packet socket for ifindex %d",
1025 if (bind(drv
->pim_sock
, (struct sockaddr
*) &addr
, sizeof(addr
)) < 0) {
1034 static void * prism54_driver_init(struct hostapd_data
*hapd
)
1036 struct prism54_driver_data
*drv
;
1038 drv
= os_zalloc(sizeof(struct prism54_driver_data
));
1040 printf("Could not allocate memory for hostapd Prism54 driver "
1046 drv
->pim_sock
= drv
->sock
= -1;
1047 memcpy(drv
->iface
, hapd
->conf
->iface
, sizeof(drv
->iface
));
1049 if (prism54_init_sockets(drv
)) {
1053 prism54_init_1x(drv
);
1054 /* must clean previous elems */
1055 hostapd_set_generic_elem(hapd
, NULL
, 0);
1061 static void prism54_driver_deinit(void *priv
)
1063 struct prism54_driver_data
*drv
= priv
;
1065 if (drv
->pim_sock
>= 0)
1066 close(drv
->pim_sock
);
1075 const struct wpa_driver_ops wpa_driver_prism54_ops
= {
1077 .init
= prism54_driver_init
,
1078 .deinit
= prism54_driver_deinit
,
1079 /* .set_ieee8021x = prism54_init_1x, */
1080 .set_privacy
= prism54_set_privacy_invoked
,
1081 .set_encryption
= prism54_set_encryption
,
1082 .get_seqnum
= prism54_get_seqnum
,
1083 .flush
= prism54_flush
,
1084 .set_generic_elem
= prism54_set_generic_elem
,
1085 .send_eapol
= prism54_send_eapol
,
1086 .sta_set_flags
= prism54_sta_set_flags
,
1087 .sta_deauth
= prism54_sta_deauth
,
1088 .sta_disassoc
= prism54_sta_disassoc
,
1089 .set_ssid
= prism54_ioctl_setiwessid
,
1090 .get_inact_sec
= prism54_get_inact_sec
,