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 #include <asm/types.h>
23 #include <linux/if_packet.h>
24 #include <linux/if_ether.h> /* The L2 protocols */
25 #include <linux/if_arp.h>
26 #include <linux/wireless.h>
27 #else /* USE_KERNEL_HEADERS */
28 #include <net/if_arp.h>
29 #include <netpacket/packet.h>
30 #include "wireless_copy.h"
31 #endif /* USE_KERNEL_HEADERS */
35 #include "ieee802_1x.h"
37 #include "ieee802_11.h"
40 #include "radius/radius.h"
42 #include "accounting.h"
44 const int PIM_BUF_SIZE
= 4096;
46 struct prism54_driver_data
{
47 struct hostapd_data
*hapd
;
48 char iface
[IFNAMSIZ
+ 1];
49 int sock
; /* raw packet socket for 802.3 access */
50 int pim_sock
; /* socket for pimfor packet */
55 static int mac_id_refresh(struct prism54_driver_data
*data
, int id
, char *mac
)
57 if (id
< 0 || id
> 2006) {
60 memcpy(&data
->macs
[id
][0], mac
, ETH_ALEN
);
65 static char * mac_id_get(struct prism54_driver_data
*data
, int id
)
67 if (id
< 0 || id
> 2006) {
70 return &data
->macs
[id
][0];
74 /* wait for a specific pimfor, timeout in 10ms resolution */
75 /* pim_sock must be non-block to prevent dead lock from no response */
76 /* or same response type in series */
77 static int prism54_waitpim(void *priv
, unsigned long oid
, void *buf
, int len
,
80 struct prism54_driver_data
*drv
= priv
;
81 struct timeval tv
, stv
, ctv
;
91 gettimeofday(&stv
, NULL
);
93 FD_SET(drv
->pim_sock
, &pfd
);
96 if (select(drv
->pim_sock
+ 1, &pfd
, NULL
, NULL
, &tv
)) {
97 rlen
= recv(drv
->pim_sock
, pkt
, 8192, 0);
99 if (pkt
->oid
== htonl(oid
)) {
102 memcpy(buf
, pkt
, rlen
);
107 printf("buffer too small\n");
112 gettimeofday(&ctv
, NULL
);
117 gettimeofday(&ctv
, NULL
);
118 } while (((ctv
.tv_sec
- stv
.tv_sec
) * 100 +
119 (ctv
.tv_usec
- stv
.tv_usec
) / 10000) > timeout
);
125 /* send an eapol packet */
126 static int prism54_send_eapol(void *priv
, const u8
*addr
,
127 const u8
*data
, size_t data_len
, int encrypt
,
130 struct prism54_driver_data
*drv
= priv
;
136 len
= sizeof(*hdr
) + data_len
;
137 hdr
= os_zalloc(len
);
139 printf("malloc() failed for prism54_send_data(len=%lu)\n",
140 (unsigned long) len
);
144 memcpy(&hdr
->da
[0], addr
, ETH_ALEN
);
145 memcpy(&hdr
->sa
[0], own_addr
, ETH_ALEN
);
146 hdr
->type
= htons(ETH_P_PAE
);
147 pos
= (u8
*) (hdr
+ 1);
148 memcpy(pos
, data
, data_len
);
150 res
= send(drv
->sock
, hdr
, len
, 0);
154 perror("hostapd_send_eapol: send");
155 printf("hostapd_send_eapol - packet len: %lu - failed\n",
156 (unsigned long) len
);
163 /* open data channel(auth-1) or eapol only(unauth-0) */
164 static int prism54_set_sta_authorized(void *priv
, const u8
*addr
,
167 struct prism54_driver_data
*drv
= priv
;
171 hdr
= malloc(sizeof(*hdr
) + ETH_ALEN
);
174 hdr
->op
= htonl(PIMOP_SET
);
176 hdr
->oid
= htonl(DOT11_OID_EAPAUTHSTA
);
178 hdr
->oid
= htonl(DOT11_OID_EAPUNAUTHSTA
);
180 pos
= (char *) (hdr
+ 1);
181 memcpy(pos
, addr
, ETH_ALEN
);
182 send(drv
->pim_sock
, hdr
, sizeof(*hdr
) + ETH_ALEN
, 0);
183 prism54_waitpim(priv
, hdr
->oid
, hdr
, sizeof(*hdr
) + ETH_ALEN
, 10);
190 prism54_sta_set_flags(void *priv
, const u8
*addr
, int total_flags
,
191 int flags_or
, int flags_and
)
193 /* For now, only support setting Authorized flag */
194 if (flags_or
& WLAN_STA_AUTHORIZED
)
195 return prism54_set_sta_authorized(priv
, addr
, 1);
196 if (flags_and
& WLAN_STA_AUTHORIZED
)
197 return prism54_set_sta_authorized(priv
, addr
, 0);
202 /* set per station key */
203 static int prism54_set_encryption(const char *ifname
, void *priv
,
204 const char *alg
, const u8
*addr
,
205 int idx
, const u8
*key
, size_t key_len
,
208 struct prism54_driver_data
*drv
= priv
;
210 struct obj_stakey
*keys
;
215 blen
= sizeof(struct obj_stakey
) + sizeof(pimdev_hdr
);
218 printf("memory low\n");
221 keys
= (struct obj_stakey
*) &hdr
[1];
223 memset(&keys
->address
[0], 0xff, ETH_ALEN
);
225 memcpy(&keys
->address
[0], addr
, ETH_ALEN
);
227 if (!strcmp(alg
, "WEP")) {
228 keys
->type
= DOT11_PRIV_WEP
;
229 } else if (!strcmp(alg
, "TKIP")) {
230 keys
->type
= DOT11_PRIV_TKIP
;
231 } else if (!strcmp(alg
, "none")) {
232 /* the only way to clear the key is to deauth it */
233 /* and prism54 is capable to receive unencrypted packet */
234 /* so we do nothing here */
238 printf("bad auth type: %s\n", alg
);
240 buf
= (u8
*) &keys
->key
[0];
241 keys
->length
= key_len
;
243 keys
->options
= htons(DOT11_STAKEY_OPTION_DEFAULTKEY
);
246 hdr
->op
= htonl(PIMOP_SET
);
247 hdr
->oid
= htonl(DOT11_OID_STAKEY
);
249 memcpy(buf
, key
, key_len
);
251 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
256 prism54_waitpim(priv
, hdr
->oid
, hdr
, blen
, 10);
264 /* get TKIP station sequence counter, prism54 is only 6 bytes */
265 static int prism54_get_seqnum(const char *ifname
, void *priv
, const u8
*addr
,
268 struct prism54_driver_data
*drv
= priv
;
269 struct obj_stasc
*stasc
;
274 blen
= sizeof(*stasc
) + sizeof(*hdr
);
279 stasc
= (struct obj_stasc
*) &hdr
[1];
282 memset(&stasc
->address
[0], 0xff, ETH_ALEN
);
284 memcpy(&stasc
->address
[0], addr
, ETH_ALEN
);
286 hdr
->oid
= htonl(DOT11_OID_STASC
);
287 hdr
->op
= htonl(PIMOP_GET
);
289 if (send(drv
->pim_sock
,hdr
,blen
,0) <= 0) {
293 if (prism54_waitpim(priv
, DOT11_OID_STASC
, hdr
, blen
, 10) <= 0) {
296 if (hdr
->op
== (int) htonl(PIMOP_RESPONSE
)) {
297 memcpy(seq
+ 2, &stasc
->sc_high
, ETH_ALEN
);
309 /* include unencrypted, set mlme autolevel to extended */
310 static int prism54_init_1x(void *priv
)
312 struct prism54_driver_data
*drv
= priv
;
315 int blen
= sizeof(*hdr
) + sizeof(*ul
);
321 ul
= (unsigned long *) &hdr
[1];
322 hdr
->op
= htonl(PIMOP_SET
);
323 hdr
->oid
= htonl(DOT11_OID_EXUNENCRYPTED
);
324 *ul
= htonl(DOT11_BOOL_TRUE
); /* not accept */
325 send(drv
->pim_sock
, hdr
, blen
, 0);
326 prism54_waitpim(priv
, DOT11_OID_EXUNENCRYPTED
, hdr
, blen
, 10);
327 hdr
->op
= htonl(PIMOP_SET
);
328 hdr
->oid
= htonl(DOT11_OID_MLMEAUTOLEVEL
);
329 *ul
= htonl(DOT11_MLME_EXTENDED
);
330 send(drv
->pim_sock
, hdr
, blen
, 0);
331 prism54_waitpim(priv
, DOT11_OID_MLMEAUTOLEVEL
, hdr
, blen
, 10);
332 hdr
->op
= htonl(PIMOP_SET
);
333 hdr
->oid
= htonl(DOT11_OID_DOT1XENABLE
);
334 *ul
= htonl(DOT11_BOOL_TRUE
);
335 send(drv
->pim_sock
, hdr
, blen
, 0);
336 prism54_waitpim(priv
, DOT11_OID_DOT1XENABLE
, hdr
, blen
, 10);
337 hdr
->op
= htonl(PIMOP_SET
);
338 hdr
->oid
= htonl(DOT11_OID_AUTHENABLE
);
339 *ul
= htonl(DOT11_AUTH_OS
); /* OS */
340 send(drv
->pim_sock
, hdr
, blen
, 0);
341 prism54_waitpim(priv
, DOT11_OID_AUTHENABLE
, hdr
, blen
, 10);
347 static int prism54_set_privacy_invoked(const char *ifname
, void *priv
,
350 struct prism54_driver_data
*drv
= priv
;
354 int blen
= sizeof(*hdr
) + sizeof(*ul
);
358 ul
= (unsigned long *) &hdr
[1];
359 hdr
->op
= htonl(PIMOP_SET
);
360 hdr
->oid
= htonl(DOT11_OID_PRIVACYINVOKED
);
362 *ul
= htonl(DOT11_BOOL_TRUE
); /* has privacy */
366 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
368 ret
= prism54_waitpim(priv
, DOT11_OID_PRIVACYINVOKED
, hdr
,
376 static int prism54_ioctl_setiwessid(const char *ifname
, void *priv
,
377 const u8
*buf
, int len
)
380 struct prism54_driver_data
*drv
= priv
;
383 memset(&iwr
, 0, sizeof(iwr
));
384 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
385 iwr
.u
.essid
.flags
= 1; /* SSID active */
386 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
387 iwr
.u
.essid
.length
= len
+ 1;
389 if (ioctl(drv
->pim_sock
, SIOCSIWESSID
, &iwr
) < 0) {
390 perror("ioctl[SIOCSIWESSID]");
391 printf("len=%d\n", len
);
399 /* kick all stations */
400 /* does not work during init, but at least it won't crash firmware */
401 static int prism54_flush(void *priv
)
403 struct prism54_driver_data
*drv
= priv
;
404 struct obj_mlmeex
*mlme
;
409 int blen
= sizeof(*hdr
) + sizeof(*mlme
);
412 hdr
= os_zalloc(blen
);
416 mlme
= (struct obj_mlmeex
*) &hdr
[1];
417 nsta
= (long *) &hdr
[1];
418 hdr
->op
= htonl(PIMOP_GET
);
419 hdr
->oid
= htonl(DOT11_OID_CLIENTS
);
420 ret
= send(drv
->pim_sock
, hdr
, sizeof(*hdr
) + sizeof(long), 0);
421 ret
= prism54_waitpim(priv
, DOT11_OID_CLIENTS
, hdr
, blen
, 10);
422 if ((ret
< 0) || (hdr
->op
!= (int) htonl(PIMOP_RESPONSE
)) ||
423 (le_to_host32(*nsta
) > 2007)) {
427 for (i
= 0; i
< le_to_host32(*nsta
); i
++) {
429 mac_id
= mac_id_get(drv
, i
);
431 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
432 mlme
->code
= host_to_le16(WLAN_REASON_UNSPECIFIED
);
433 mlme
->state
= htons(DOT11_STATE_NONE
);
435 hdr
->op
= htonl(PIMOP_SET
);
436 hdr
->oid
= htonl(DOT11_OID_DISASSOCIATEEX
);
437 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
438 prism54_waitpim(priv
, DOT11_OID_DISASSOCIATEEX
, hdr
, blen
,
441 for (i
= 0; i
< le_to_host32(*nsta
); i
++) {
443 mac_id
= mac_id_get(drv
, i
);
445 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
446 mlme
->code
= host_to_le16(WLAN_REASON_UNSPECIFIED
);
447 mlme
->state
= htons(DOT11_STATE_NONE
);
449 hdr
->op
= htonl(PIMOP_SET
);
450 hdr
->oid
= htonl(DOT11_OID_DEAUTHENTICATEEX
);
451 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
452 prism54_waitpim(priv
, DOT11_OID_DEAUTHENTICATEEX
, hdr
, blen
,
460 static int prism54_sta_deauth(void *priv
, const u8
*addr
, int reason
)
462 struct prism54_driver_data
*drv
= priv
;
464 struct obj_mlmeex
*mlme
;
466 int blen
= sizeof(*hdr
) + sizeof(*mlme
);
470 mlme
= (struct obj_mlmeex
*) &hdr
[1];
471 hdr
->op
= htonl(PIMOP_SET
);
472 hdr
->oid
= htonl(DOT11_OID_DEAUTHENTICATEEX
);
473 memcpy(&mlme
->address
[0], addr
, ETH_ALEN
);
475 mlme
->state
= htons(DOT11_STATE_NONE
);
476 mlme
->code
= host_to_le16(reason
);
478 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
479 prism54_waitpim(priv
, DOT11_OID_DEAUTHENTICATEEX
, hdr
, blen
, 10);
485 static int prism54_sta_disassoc(void *priv
, const u8
*addr
, int reason
)
487 struct prism54_driver_data
*drv
= priv
;
489 struct obj_mlmeex
*mlme
;
491 int blen
= sizeof(*hdr
) + sizeof(*mlme
);
495 mlme
= (struct obj_mlmeex
*) &hdr
[1];
496 hdr
->op
= htonl(PIMOP_SET
);
497 hdr
->oid
= htonl(DOT11_OID_DISASSOCIATEEX
);
498 memcpy(&mlme
->address
[0], addr
, ETH_ALEN
);
500 mlme
->state
= htons(DOT11_STATE_NONE
);
501 mlme
->code
= host_to_le16(reason
);
503 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
504 prism54_waitpim(priv
, DOT11_OID_DISASSOCIATEEX
, hdr
, blen
, 10);
510 static int prism54_get_inact_sec(void *priv
, const u8
*addr
)
512 struct prism54_driver_data
*drv
= priv
;
515 int blen
= sizeof(*hdr
) + sizeof(*sta
);
521 hdr
->op
= htonl(PIMOP_GET
);
522 hdr
->oid
= htonl(DOT11_OID_CLIENTFIND
);
523 sta
= (struct obj_sta
*) &hdr
[1];
524 memcpy(&sta
->address
[0], addr
, ETH_ALEN
);
525 ret
= send(drv
->pim_sock
, hdr
, blen
, 0);
526 ret
= prism54_waitpim(priv
, DOT11_OID_CLIENTFIND
, hdr
, blen
, 10);
528 printf("get_inact_sec: bad return %d\n", ret
);
532 if (hdr
->op
!= (int) htonl(PIMOP_RESPONSE
)) {
533 printf("get_inact_sec: bad resp\n");
538 return le_to_host16(sta
->age
);
542 /* set attachments */
543 static int prism54_set_generic_elem(const char *ifname
, void *priv
,
544 const u8
*elem
, size_t elem_len
)
546 struct prism54_driver_data
*drv
= priv
;
549 struct obj_attachment_hdr
*attach
;
550 size_t blen
= sizeof(*hdr
) + sizeof(*attach
) + elem_len
;
551 hdr
= os_zalloc(blen
);
553 printf("%s: memory low\n", __func__
);
556 hdr
->op
= htonl(PIMOP_SET
);
557 hdr
->oid
= htonl(DOT11_OID_ATTACHMENT
);
558 attach
= (struct obj_attachment_hdr
*)&hdr
[1];
559 attach
->type
= DOT11_PKT_BEACON
;
561 attach
->size
= host_to_le16((short)elem_len
);
562 pos
= ((char*) attach
) + sizeof(*attach
);
564 memcpy(pos
, elem
, elem_len
);
565 send(drv
->pim_sock
, hdr
, blen
, 0);
566 attach
->type
= DOT11_PKT_PROBE_RESP
;
567 send(drv
->pim_sock
, hdr
, blen
, 0);
573 /* tell the card to auth the sta */
574 static void prism54_handle_probe(struct prism54_driver_data
*drv
,
575 void *buf
, size_t len
)
577 struct obj_mlmeex
*mlme
;
579 struct sta_info
*sta
;
580 hdr
= (pimdev_hdr
*)buf
;
581 mlme
= (struct obj_mlmeex
*) &hdr
[1];
582 sta
= ap_get_sta(drv
->hapd
, (u8
*) &mlme
->address
[0]);
584 if (sta
->flags
& (WLAN_STA_AUTH
| WLAN_STA_ASSOC
))
587 if (len
< sizeof(*mlme
)) {
588 printf("bad probe packet\n");
591 mlme
->state
= htons(DOT11_STATE_AUTHING
);
593 hdr
->op
= htonl(PIMOP_SET
);
594 hdr
->oid
= htonl(DOT11_OID_AUTHENTICATEEX
);
596 send(drv
->pim_sock
, hdr
, sizeof(*hdr
)+sizeof(*mlme
), 0);
600 static void prism54_handle_deauth(struct prism54_driver_data
*drv
,
601 void *buf
, size_t len
)
603 struct obj_mlme
*mlme
;
605 struct sta_info
*sta
;
608 hdr
= (pimdev_hdr
*) buf
;
609 mlme
= (struct obj_mlme
*) &hdr
[1];
610 sta
= ap_get_sta(drv
->hapd
, (u8
*) &mlme
->address
[0]);
611 mac_id
= mac_id_get(drv
, mlme
->id
);
612 if (sta
== NULL
|| mac_id
== NULL
)
614 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
615 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
616 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
617 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
618 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
619 ap_free_sta(drv
->hapd
, sta
);
623 static void prism54_handle_disassoc(struct prism54_driver_data
*drv
,
624 void *buf
, size_t len
)
626 struct obj_mlme
*mlme
;
628 struct sta_info
*sta
;
631 hdr
= (pimdev_hdr
*) buf
;
632 mlme
= (struct obj_mlme
*) &hdr
[1];
633 mac_id
= mac_id_get(drv
, mlme
->id
);
636 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
637 sta
= ap_get_sta(drv
->hapd
, (u8
*) &mlme
->address
[0]);
641 sta
->flags
&= ~WLAN_STA_ASSOC
;
642 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
643 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
644 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
645 accounting_sta_stop(drv
->hapd
, sta
);
646 ieee802_1x_free_station(sta
);
650 /* to auth it, just allow it now, later for os/sk */
651 static void prism54_handle_auth(struct prism54_driver_data
*drv
,
652 void *buf
, size_t len
)
654 struct obj_mlmeex
*mlme
;
656 struct sta_info
*sta
;
659 hdr
= (pimdev_hdr
*) buf
;
660 mlme
= (struct obj_mlmeex
*) &hdr
[1];
661 if (len
< sizeof(*mlme
)) {
662 printf("bad auth packet\n");
666 if (mlme
->state
== htons(DOT11_STATE_AUTHING
)) {
667 sta
= ap_sta_add(drv
->hapd
, (u8
*) &mlme
->address
[0]);
668 if (drv
->hapd
->tkip_countermeasures
) {
669 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
672 mac_id_refresh(drv
, mlme
->id
, &mlme
->address
[0]);
674 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
677 sta
->flags
&= ~WLAN_STA_PREAUTH
;
679 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
680 sta
->flags
|= WLAN_STA_AUTH
;
681 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
683 mlme
->state
=htons(DOT11_STATE_AUTH
);
684 hdr
->op
= htonl(PIMOP_SET
);
685 hdr
->oid
= htonl(DOT11_OID_AUTHENTICATEEX
);
687 sta
->timeout_next
= STA_NULLFUNC
;
688 send(drv
->pim_sock
, hdr
, sizeof(*hdr
) + sizeof(*mlme
), 0);
693 printf("auth fail: %x\n", resp
);
694 mlme
->code
= host_to_le16(resp
);
697 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
698 hdr
->oid
= htonl(DOT11_OID_DEAUTHENTICATEEX
);
699 hdr
->op
= htonl(PIMOP_SET
);
700 send(drv
->pim_sock
, hdr
, sizeof(*hdr
)+sizeof(*mlme
), 0);
704 /* do the wpa thing */
705 static void prism54_handle_assoc(struct prism54_driver_data
*drv
,
706 void *buf
, size_t len
)
709 struct obj_mlmeex
*mlme
;
710 struct ieee802_11_elems elems
;
711 struct sta_info
*sta
;
720 hdr
= (pimdev_hdr
*) buf
;
721 mlme
= (struct obj_mlmeex
*) &hdr
[1];
722 switch (ntohl(hdr
->oid
)) {
723 case DOT11_OID_ASSOCIATE
:
724 case DOT11_OID_REASSOCIATE
:
729 if ((mlme
->state
== (int) htonl(DOT11_STATE_ASSOCING
)) ||
730 (mlme
->state
== (int) htonl(DOT11_STATE_REASSOCING
))) {
731 if (len
< sizeof(pimdev_hdr
) + sizeof(struct obj_mlme
)) {
732 printf("bad assoc packet\n");
735 mac_id
= mac_id_get(drv
, mlme
->id
);
738 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
739 sta
= ap_get_sta(drv
->hapd
, (u8
*) &mlme
->address
[0]);
741 printf("cannot get sta\n");
744 cb
= (u8
*) &mlme
->data
[0];
745 if (hdr
->oid
== htonl(DOT11_OID_ASSOCIATEEX
)) {
747 } else if (hdr
->oid
== htonl(DOT11_OID_REASSOCIATEEX
)) {
750 if (le_to_host16(mlme
->size
) <= ieofs
) {
751 printf("attach too small\n");
752 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
755 if (ieee802_11_parse_elems(drv
->hapd
, cb
+ ieofs
,
756 le_to_host16(mlme
->size
) - ieofs
,
757 &elems
, 1) == ParseFailed
) {
758 printf("STA " MACSTR
" sent invalid association "
759 "request\n", MAC2STR(sta
->addr
));
760 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
763 if ((drv
->hapd
->conf
->wpa
& WPA_PROTO_RSN
) &&
765 wpa_ie
= elems
.rsn_ie
;
766 wpa_ie_len
= elems
.rsn_ie_len
;
767 } else if ((drv
->hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
769 wpa_ie
= elems
.wpa_ie
;
770 wpa_ie_len
= elems
.wpa_ie_len
;
775 if (drv
->hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
776 printf("STA " MACSTR
": No WPA/RSN IE in association "
777 "request\n", MAC2STR(sta
->addr
));
778 resp
= WLAN_STATUS_INVALID_IE
;
781 if (drv
->hapd
->conf
->wpa
) {
785 if (sta
->wpa_sm
== NULL
)
786 sta
->wpa_sm
= wpa_auth_sta_init(
787 drv
->hapd
->wpa_auth
, sta
->addr
);
788 if (sta
->wpa_sm
== NULL
) {
789 printf("Failed to initialize WPA state "
791 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
794 res
= wpa_validate_wpa_ie(drv
->hapd
->wpa_auth
,
798 if (res
== WPA_INVALID_GROUP
)
799 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
800 else if (res
== WPA_INVALID_PAIRWISE
)
801 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
802 else if (res
== WPA_INVALID_AKMP
)
803 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
804 else if (res
== WPA_ALLOC_FAIL
)
805 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
806 else if (res
!= WPA_IE_OK
)
807 resp
= WLAN_STATUS_INVALID_IE
;
808 if (resp
!= WLAN_STATUS_SUCCESS
)
811 hdr
->oid
= (hdr
->oid
== htonl(DOT11_OID_ASSOCIATEEX
)) ?
812 htonl(DOT11_OID_ASSOCIATEEX
) :
813 htonl(DOT11_OID_REASSOCIATEEX
);
814 hdr
->op
= htonl(PIMOP_SET
);
816 mlme
->state
= htons(DOT11_STATE_ASSOC
);
818 send(drv
->pim_sock
, hdr
, sizeof(*hdr
) + sizeof(*mlme
), 0);
820 } else if (mlme
->state
==htons(DOT11_STATE_ASSOC
)) {
821 if (len
< sizeof(pimdev_hdr
) + sizeof(struct obj_mlme
)) {
822 printf("bad assoc packet\n");
825 mac_id
= mac_id_get(drv
, mlme
->id
);
828 memcpy(&mlme
->address
[0], mac_id
, ETH_ALEN
);
829 sta
= ap_get_sta(drv
->hapd
, (u8
*) &mlme
->address
[0]);
831 printf("cannot get sta\n");
834 new_assoc
= (sta
->flags
& WLAN_STA_ASSOC
) == 0;
835 sta
->flags
|= WLAN_STA_AUTH
| WLAN_STA_ASSOC
;
836 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
837 hostapd_new_assoc_sta(drv
->hapd
, sta
, !new_assoc
);
838 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
839 sta
->timeout_next
= STA_NULLFUNC
;
845 printf("Prism54: assoc fail: %x\n", resp
);
846 mlme
->code
= host_to_le16(resp
);
848 mlme
->state
= htons(DOT11_STATE_ASSOCING
);
849 hdr
->oid
= htonl(DOT11_OID_DISASSOCIATEEX
);
850 hdr
->op
= htonl(PIMOP_SET
);
851 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
852 send(drv
->pim_sock
, hdr
, sizeof(*hdr
) + sizeof(*mlme
), 0);
856 static void handle_pim(int sock
, void *eloop_ctx
, void *sock_ctx
)
858 struct prism54_driver_data
*drv
= eloop_ctx
;
862 hdr
= malloc(PIM_BUF_SIZE
);
865 len
= recv(sock
, hdr
, PIM_BUF_SIZE
, 0);
872 printf("handle_pim: too short (%d)\n", len
);
877 if (hdr
->op
!= (int) htonl(PIMOP_TRAP
)) {
881 switch (ntohl(hdr
->oid
)) {
882 case DOT11_OID_PROBE
:
883 prism54_handle_probe(drv
, hdr
, len
);
885 case DOT11_OID_DEAUTHENTICATEEX
:
886 case DOT11_OID_DEAUTHENTICATE
:
887 prism54_handle_deauth(drv
, hdr
, len
);
889 case DOT11_OID_DISASSOCIATEEX
:
890 case DOT11_OID_DISASSOCIATE
:
891 prism54_handle_disassoc(drv
, hdr
, len
);
893 case DOT11_OID_AUTHENTICATEEX
:
894 case DOT11_OID_AUTHENTICATE
:
895 prism54_handle_auth(drv
, hdr
, len
);
897 case DOT11_OID_ASSOCIATEEX
:
898 case DOT11_OID_REASSOCIATEEX
:
899 case DOT11_OID_ASSOCIATE
:
900 case DOT11_OID_REASSOCIATE
:
901 prism54_handle_assoc(drv
, hdr
, len
);
910 static void handle_802_3(int sock
, void *eloop_ctx
, void *sock_ctx
)
912 struct hostapd_data
*hapd
= (struct hostapd_data
*) eloop_ctx
;
916 hdr
= malloc(PIM_BUF_SIZE
);
919 len
= recv(sock
, hdr
, PIM_BUF_SIZE
, 0);
926 wpa_printf(MSG_MSGDUMP
, "handle_802_3: too short (%d)", len
);
930 if (hdr
->type
== htons(ETH_P_PAE
)) {
931 ieee802_1x_receive(hapd
, (u8
*) &hdr
->sa
[0], (u8
*) &hdr
[1],
938 static int prism54_init_sockets(struct prism54_driver_data
*drv
)
940 struct hostapd_data
*hapd
= drv
->hapd
;
942 struct sockaddr_ll addr
;
944 drv
->sock
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_PAE
));
946 perror("socket[PF_PACKET,SOCK_RAW]");
950 if (eloop_register_read_sock(drv
->sock
, handle_802_3
, drv
->hapd
, NULL
))
952 printf("Could not register read socket\n");
956 memset(&ifr
, 0, sizeof(ifr
));
957 if (hapd
->conf
->bridge
[0] != '\0') {
958 printf("opening bridge: %s\n", hapd
->conf
->bridge
);
959 os_strlcpy(ifr
.ifr_name
, hapd
->conf
->bridge
,
960 sizeof(ifr
.ifr_name
));
962 os_strlcpy(ifr
.ifr_name
, drv
->iface
, sizeof(ifr
.ifr_name
));
964 if (ioctl(drv
->sock
, SIOCGIFINDEX
, &ifr
) != 0) {
965 perror("ioctl(SIOCGIFINDEX)");
969 memset(&addr
, 0, sizeof(addr
));
970 addr
.sll_family
= AF_PACKET
;
971 addr
.sll_ifindex
= ifr
.ifr_ifindex
;
972 addr
.sll_protocol
= htons(ETH_P_PAE
);
973 wpa_printf(MSG_DEBUG
, "Opening raw packet socket for ifindex %d",
976 if (bind(drv
->sock
, (struct sockaddr
*) &addr
, sizeof(addr
)) < 0) {
981 memset(&ifr
, 0, sizeof(ifr
));
982 os_strlcpy(ifr
.ifr_name
, drv
->iface
, sizeof(ifr
.ifr_name
));
983 if (ioctl(drv
->sock
, SIOCGIFHWADDR
, &ifr
) != 0) {
984 perror("ioctl(SIOCGIFHWADDR)");
988 if (ifr
.ifr_hwaddr
.sa_family
!= ARPHRD_ETHER
) {
989 printf("Invalid HW-addr family 0x%04x\n",
990 ifr
.ifr_hwaddr
.sa_family
);
993 memcpy(drv
->hapd
->own_addr
, ifr
.ifr_hwaddr
.sa_data
, ETH_ALEN
);
995 drv
->pim_sock
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_ALL
));
996 if (drv
->pim_sock
< 0) {
997 perror("socket[PF_PACKET,SOCK_RAW]");
1001 if (eloop_register_read_sock(drv
->pim_sock
, handle_pim
, drv
, NULL
)) {
1002 printf("Could not register read socket\n");
1006 memset(&ifr
, 0, sizeof(ifr
));
1007 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%sap", drv
->iface
);
1008 if (ioctl(drv
->pim_sock
, SIOCGIFINDEX
, &ifr
) != 0) {
1009 perror("ioctl(SIOCGIFINDEX)");
1013 memset(&addr
, 0, sizeof(addr
));
1014 addr
.sll_family
= AF_PACKET
;
1015 addr
.sll_ifindex
= ifr
.ifr_ifindex
;
1016 addr
.sll_protocol
= htons(ETH_P_ALL
);
1017 wpa_printf(MSG_DEBUG
, "Opening raw packet socket for ifindex %d",
1020 if (bind(drv
->pim_sock
, (struct sockaddr
*) &addr
, sizeof(addr
)) < 0) {
1029 static void * prism54_driver_init(struct hostapd_data
*hapd
)
1031 struct prism54_driver_data
*drv
;
1033 drv
= os_zalloc(sizeof(struct prism54_driver_data
));
1035 printf("Could not allocate memory for hostapd Prism54 driver "
1041 drv
->pim_sock
= drv
->sock
= -1;
1042 memcpy(drv
->iface
, hapd
->conf
->iface
, sizeof(drv
->iface
));
1044 if (prism54_init_sockets(drv
)) {
1048 prism54_init_1x(drv
);
1049 /* must clean previous elems */
1050 hostapd_set_generic_elem(hapd
, NULL
, 0);
1056 static void prism54_driver_deinit(void *priv
)
1058 struct prism54_driver_data
*drv
= priv
;
1060 if (drv
->pim_sock
>= 0)
1061 close(drv
->pim_sock
);
1070 const struct wpa_driver_ops wpa_driver_prism54_ops
= {
1072 .init
= prism54_driver_init
,
1073 .deinit
= prism54_driver_deinit
,
1074 /* .set_ieee8021x = prism54_init_1x, */
1075 .set_privacy
= prism54_set_privacy_invoked
,
1076 .set_encryption
= prism54_set_encryption
,
1077 .get_seqnum
= prism54_get_seqnum
,
1078 .flush
= prism54_flush
,
1079 .set_generic_elem
= prism54_set_generic_elem
,
1080 .send_eapol
= prism54_send_eapol
,
1081 .sta_set_flags
= prism54_sta_set_flags
,
1082 .sta_deauth
= prism54_sta_deauth
,
1083 .sta_disassoc
= prism54_sta_disassoc
,
1084 .set_ssid
= prism54_ioctl_setiwessid
,
1085 .get_inact_sec
= prism54_get_inact_sec
,