5 #include <sys/socket.h>
7 #include <linux/wireless.h>
8 #include <net/ethernet.h>
16 #define AUTH_ALG_OPEN_SYSTEM 0x01
17 #define AUTH_ALG_SHARED_KEY 0x02
18 #define AUTH_ALG_LEAP 0x04
20 typedef enum { WPA_ALG_NONE
, WPA_ALG_WEP
, WPA_ALG_TKIP
, WPA_ALG_CCMP
} wpa_alg
;
25 struct wpa_driver_ops
{
26 int (*set_wpa
)(const char *ifnmae
, int enabled
);
27 int (*set_auth_alg
)(const char *ifname
, int auth_alg
);
28 int (*set_key
)(const char *ifname
, wpa_alg alg
, unsigned char *addr
,
29 int key_idx
, int set_tx
, u8
*seq
, size_t seq_len
,
30 u8
*key
, size_t key_len
);
33 struct wpa_driver_ops wpa_driver_hostap_ops
;
34 struct wpa_driver_ops wpa_driver_prism54_ops
;
35 struct wpa_driver_ops wpa_driver_hermes_ops
;
36 struct wpa_driver_ops wpa_driver_madwifi_ops
;
37 struct wpa_driver_ops wpa_driver_atmel_ops
;
38 struct wpa_driver_ops wpa_driver_wext_ops
;
39 struct wpa_driver_ops wpa_driver_ndiswrapper_ops
;
40 struct wpa_driver_ops wpa_driver_ipw_ops
;
42 /* the iw_ functions are copied from libiw, so we do not need to
45 int iw_sockets_open(void)
47 static const int families
[] = {
48 AF_INET
, AF_IPX
, AF_AX25
, AF_APPLETALK
54 * Now pick any (exisiting) useful socket family for generic queries
55 * Note : don't open all the socket, only returns when one matches,
56 * all protocols might not be valid.
57 * Workaround by Jim Kaba <jkaba@sarnoff.com>
58 * Note : in 99% of the case, we will just open the inet_sock.
59 * The remaining 1% case are not fully correct...
62 /* Try all families we support */
63 for(i
= 0; i
< sizeof(families
)/sizeof(int); ++i
)
65 /* Try to open the socket, if success returns it */
66 sock
= socket(families
[i
], SOCK_DGRAM
, 0);
75 iw_get_ext(int skfd
, /* Socket to the kernel */
76 const char * ifname
, /* Device name */
77 int request
, /* WE ID */
78 struct iwreq
* pwrq
) /* Fixed part of the request */
81 strncpy(pwrq
->ifr_name
, ifname
, IFNAMSIZ
);
83 return(ioctl(skfd
, request
, pwrq
));
86 int iw_get_range_info(int skfd
,
88 struct iw_range
* range
)
91 char buffer
[sizeof(struct iw_range
) * 2]; /* Large enough */
92 struct iw_range
* range_raw
;
95 bzero(buffer
, sizeof(buffer
));
97 wrq
.u
.data
.pointer
= (caddr_t
) buffer
;
98 wrq
.u
.data
.length
= sizeof(buffer
);
100 if(iw_get_ext(skfd
, ifname
, SIOCGIWRANGE
, &wrq
) < 0)
103 /* Point to the buffer */
104 range_raw
= (struct iw_range
*) buffer
;
106 /* For new versions, we can check the version directly, for old versions
107 * we use magic. 300 bytes is a also magic number, don't touch... */
108 if(wrq
.u
.data
.length
< 300) {
109 /* That's v10 or earlier. Ouch ! Let's make a guess...*/
110 range_raw
->we_version_compiled
= 9;
113 /* Check how it needs to be processed */
114 if(range_raw
->we_version_compiled
> 15) {
115 /* This is our native format, that's easy... */
116 /* Copy stuff at the right place, ignore extra */
117 memcpy((char *) range
, buffer
, sizeof(struct iw_range
));
127 double iw_freq2float(const struct iw_freq
* in
)
130 double res
= (double) in
->m
;
131 for(i
= 0; i
< in
->e
; i
++)
136 void hd_scan_wlan(hd_data_t
*hd_data
)
140 struct iw_range range
;
143 struct wpa_driver_ops
*wpa_drv
=NULL
;
145 if(!hd_probe_feature(hd_data
, pr_wlan
)) return;
147 hd_data
->module
= mod_wlan
;
149 PROGRESS(1, 0, "detecting wlan features");
151 if ((skfd
= iw_sockets_open()) < 0) {
152 ADD2LOG( "could not open socket, wlan feature query failed\n" );
156 for(hd
= hd_data
->hd
; hd
; hd
= hd
->next
) {
158 hd
->base_class
.id
== bc_network
&&
159 hd
->unix_dev_name
) {
160 /* Get list of frequencies / channels */
161 if(iw_get_range_info(skfd
, hd
->unix_dev_name
, &range
) < 0) {
162 /* this failed, maybe device does not support wireless extensions */
165 ADD2LOG("*** device %s is wireless ***\n", hd
->unix_dev_name
);
167 res
= new_mem(sizeof *res
);
168 res
->any
.type
= res_wlan
;
170 if(range
.num_frequency
> 0) {
172 for(k
= 0; k
< range
.num_frequency
; k
++) {
173 snprintf(buff
, 19, "%i", range
.freq
[k
].i
);
174 add_str_list(&res
->wlan
.channels
, buff
);
175 snprintf(buff
, 19, "%g", (float)iw_freq2float(&(range
.freq
[k
]))/1000000000);
176 add_str_list(&res
->wlan
.frequencies
, buff
);
178 for(k
= 0; k
< range
.num_bitrates
; k
++) {
179 snprintf(buff
, 19, "%g", (float)range
.bitrate
[k
]/1000000);
180 add_str_list(&res
->wlan
.bitrates
, buff
);
182 for(k
= 0; k
< range
.num_encoding_sizes
; k
++) {
183 snprintf(buff
, 19, "WEP%i", range
.encoding_size
[k
]*8);
184 add_str_list(&res
->wlan
.enc_modes
, buff
);
187 /* open mode is always supported */
188 add_str_list(&res
->wlan
.auth_modes
, "open");
189 /* if WEP is supported, be assume shared key auth support */
190 if(range
.num_encoding_sizes
) {
191 add_str_list(&res
->wlan
.auth_modes
, "sharedkey");
194 /* detect WPA capabilities */
196 if (search_str_list(hd
->drivers
, "hostap_cs") ||
197 search_str_list(hd
->drivers
, "hostap_pci") ||
198 search_str_list(hd
->drivers
, "hostap_plx") )
199 wpa_drv
= &wpa_driver_hostap_ops
;
200 /* prism54 is not ready yet
201 else if (search_str_list(hd->drivers, "prism54")==0)
202 wpa_drv = &wpa_driver_prism54_ops;
204 else if (search_str_list(hd
->drivers
, "ath_pci"))
205 wpa_drv
= &wpa_driver_madwifi_ops
;
206 else if (strncmp(hd
->drivers
->str
, "at76", 4)==0)
207 wpa_drv
= &wpa_driver_atmel_ops
;
208 else if (search_str_list(hd
->drivers
, "ndiswrapper"))
209 wpa_drv
= &wpa_driver_ndiswrapper_ops
;
210 else if ((search_str_list(hd
->drivers
, "ipw2100")) ||
211 (search_str_list(hd
->drivers
, "ipw2200")) )
212 wpa_drv
= &wpa_driver_ipw_ops
;
216 if (wpa_drv
->set_wpa(hd
->unix_dev_name
, 1) == 0) {
217 add_str_list(&res
->wlan
.auth_modes
, "wpa-psk");
218 add_str_list(&res
->wlan
.auth_modes
, "wpa-eap");
219 if (wpa_drv
->set_auth_alg
&&
220 wpa_drv
->set_auth_alg(hd
->unix_dev_name
, AUTH_ALG_LEAP
)==0)
221 add_str_list(&res
->wlan
.auth_modes
, "wpa-leap");
222 if (wpa_drv
->set_key(hd
->unix_dev_name
, WPA_ALG_TKIP
, "ff:ff:ff:ff:ff:ff",
224 "00000000000000000000000000000000", 32) ==0)
225 add_str_list(&res
->wlan
.enc_modes
, "TKIP");
226 if (wpa_drv
->set_key(hd
->unix_dev_name
, WPA_ALG_CCMP
, "ff:ff:ff:ff:ff:ff",
228 "0000000000000000", 16) ==0)
229 add_str_list(&res
->wlan
.enc_modes
, "CCMP");
230 wpa_drv
->set_wpa(hd
->unix_dev_name
, 0);
234 add_res_entry(&hd
->res
, res
);
239 /* following functions are copied from wpa_supplicant
240 they are used to detect WPA capabilities */
244 #define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0)
245 #define PRISM2_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 14)
246 #define HOSTAP_CRYPT_ALG_NAME_LEN 16
247 #define HOSTAP_CRYPT_FLAG_SET_TX_KEY (1 << (0))
248 #define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
249 ((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
252 PRISM2_SET_ENCRYPTION
= 6,
253 PRISM2_HOSTAPD_SET_GENERIC_ELEMENT
= 12,
254 PRISM2_PARAM_AP_AUTH_ALGS
= 15,
255 PRISM2_PARAM_HOST_ROAMING
= 21,
256 PRISM2_PARAM_WPA
= 36,
257 PRISM2_PARAM_PRIVACY_INVOKED
= 37,
260 struct prism2_hostapd_param
{
262 u8 sta_addr
[ETH_ALEN
];
273 u8 alg
[HOSTAP_CRYPT_ALG_NAME_LEN
];
277 u8 seq
[8]; /* sequence counter (set: RX, get: TX) */
306 int hostapd_ioctl(const char *dev
, struct prism2_hostapd_param
*param
,
307 int len
, int show_err
)
313 s
= socket(PF_INET
, SOCK_DGRAM
, 0);
318 memset(&iwr
, 0, sizeof(iwr
));
319 strncpy(iwr
.ifr_name
, dev
, IFNAMSIZ
);
320 iwr
.u
.data
.pointer
= (caddr_t
) param
;
321 iwr
.u
.data
.length
= len
;
323 if (ioctl(s
, PRISM2_IOCTL_HOSTAPD
, &iwr
) < 0) {
331 int prism2param(const char *ifname
, int param
, int value
)
336 s
= socket(PF_INET
, SOCK_DGRAM
, 0);
341 memset(&iwr
, 0, sizeof(iwr
));
342 strncpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
343 i
= (int *) iwr
.u
.name
;
347 if (ioctl(s
, PRISM2_IOCTL_PRISM2_PARAM
, &iwr
) < 0) {
354 int wpa_driver_hostap_set_auth_alg(const char *ifname
, int auth_alg
)
358 if (auth_alg
& AUTH_ALG_OPEN_SYSTEM
)
360 if (auth_alg
& AUTH_ALG_SHARED_KEY
)
362 if (auth_alg
& AUTH_ALG_LEAP
)
365 algs
= 1; /* at least one algorithm should be set */
367 return prism2param(ifname
, PRISM2_PARAM_AP_AUTH_ALGS
, algs
);
370 int wpa_driver_hostap_set_wpa(const char *ifname
, int enabled
)
374 if (prism2param(ifname
, PRISM2_PARAM_HOST_ROAMING
,
375 enabled
? 2 : 0) < 0)
377 if (prism2param(ifname
, PRISM2_PARAM_PRIVACY_INVOKED
, enabled
) < 0)
379 if (prism2param(ifname
, PRISM2_PARAM_WPA
, enabled
) < 0)
385 int wpa_driver_hostap_set_key(const char *ifname
, wpa_alg alg
,
386 unsigned char *addr
, int key_idx
,
387 int set_tx
, u8
*seq
, size_t seq_len
,
388 u8
*key
, size_t key_len
)
390 struct prism2_hostapd_param
*param
;
416 blen
= sizeof(*param
) + key_len
;
420 memset(buf
, 0, blen
);
422 param
= (struct prism2_hostapd_param
*) buf
;
423 param
->cmd
= PRISM2_SET_ENCRYPTION
;
424 memset(param
->sta_addr
, 0xff, ETH_ALEN
);
426 strncpy(param
->u
.crypt
.alg
, alg_name
, HOSTAP_CRYPT_ALG_NAME_LEN
);
427 param
->u
.crypt
.flags
= set_tx
? HOSTAP_CRYPT_FLAG_SET_TX_KEY
: 0;
428 param
->u
.crypt
.idx
= key_idx
;
429 memcpy(param
->u
.crypt
.seq
, seq
, seq_len
);
430 param
->u
.crypt
.key_len
= key_len
;
431 memcpy((u8
*) (param
+ 1), key
, key_len
);
433 if (hostapd_ioctl(ifname
, param
, blen
, 1)) {
441 struct wpa_driver_ops wpa_driver_hostap_ops
= {
442 .set_wpa
= wpa_driver_hostap_set_wpa
,
443 .set_key
= wpa_driver_hostap_set_key
,
444 .set_auth_alg
= wpa_driver_hostap_set_auth_alg
,
451 #define IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0)
452 #define IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+2)
453 #define IEEE80211_CIPHER_WEP 0
454 #define IEEE80211_CIPHER_TKIP 1
455 #define IEEE80211_CIPHER_AES_CCM 3
456 #define IEEE80211_ADDR_LEN 6
457 #define IEEE80211_KEY_XMIT 0x01
458 #define IEEE80211_KEY_RECV 0x02
459 #define IEEE80211_KEYBUF_SIZE 16
460 #define IEEE80211_MICBUF_SIZE 16
463 IEEE80211_PARAM_WPA
= 10, /* WPA mode (0,1,2) */
464 IEEE80211_PARAM_ROAMING
= 12, /* roaming mode */
465 IEEE80211_PARAM_PRIVACY
= 13, /* privacy invoked */
468 struct ieee80211req_key
{
469 u_int8_t ik_type
; /* key/cipher type */
471 u_int16_t ik_keyix
; /* key index */
472 u_int8_t ik_keylen
; /* key length in bytes */
474 #define IEEE80211_KEY_DEFAULT 0x80 /* default xmit key */
475 u_int8_t ik_macaddr
[IEEE80211_ADDR_LEN
];
476 u_int64_t ik_keyrsc
; /* key receive sequence counter */
477 u_int64_t ik_keytsc
; /* key transmit sequence counter */
478 u_int8_t ik_keydata
[IEEE80211_KEYBUF_SIZE
+IEEE80211_MICBUF_SIZE
];
482 set80211param(const char *dev
, int op
, int arg
)
487 if (s
< 0 ? (s
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1 : 0) {
491 memset(&iwr
, 0, sizeof(iwr
));
492 strncpy(iwr
.ifr_name
, dev
, IFNAMSIZ
);
494 memcpy(iwr
.u
.name
+sizeof(__u32
), &arg
, sizeof(arg
));
496 if (ioctl(s
, IEEE80211_IOCTL_SETPARAM
, &iwr
) < 0) {
503 wpa_driver_madwifi_set_wpa(const char *ifname
, int enabled
)
507 if (set80211param(ifname
, IEEE80211_PARAM_ROAMING
, enabled
? 2 : 0) < 0)
509 if (set80211param(ifname
, IEEE80211_PARAM_PRIVACY
, enabled
) < 0)
511 if (set80211param(ifname
, IEEE80211_PARAM_WPA
, enabled
? 3 : 0) < 0)
518 set80211priv(const char *dev
, int op
, void *data
, int len
)
523 if (s
< 0 ? (s
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1 : 0) {
527 memset(&iwr
, 0, sizeof(iwr
));
528 strncpy(iwr
.ifr_name
, dev
, IFNAMSIZ
);
529 if (len
< IFNAMSIZ
) {
531 * Argument data fits inline; put it there.
533 memcpy(iwr
.u
.name
, data
, len
);
536 * Argument data too big for inline transfer; setup a
537 * parameter block instead; the kernel will transfer
538 * the data for the driver.
540 iwr
.u
.data
.pointer
= data
;
541 iwr
.u
.data
.length
= len
;
544 if (ioctl(s
, op
, &iwr
) < 0) {
551 wpa_driver_madwifi_set_key(const char *ifname
, wpa_alg alg
,
552 unsigned char *addr
, int key_idx
,
553 int set_tx
, u8
*seq
, size_t seq_len
,
554 u8
*key
, size_t key_len
)
556 struct ieee80211req_key wk
;
560 if (alg
== WPA_ALG_NONE
)
566 cipher
= IEEE80211_CIPHER_WEP
;
570 cipher
= IEEE80211_CIPHER_TKIP
;
574 cipher
= IEEE80211_CIPHER_AES_CCM
;
580 if (seq_len
> sizeof(u_int64_t
)) {
583 if (key_len
> sizeof(wk
.ik_keydata
)) {
587 memset(&wk
, 0, sizeof(wk
));
589 wk
.ik_flags
= IEEE80211_KEY_RECV
;
591 wk
.ik_flags
|= IEEE80211_KEY_XMIT
| IEEE80211_KEY_DEFAULT
;
592 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
594 memset(wk
.ik_macaddr
, 0, IEEE80211_ADDR_LEN
);
595 wk
.ik_keyix
= key_idx
;
596 wk
.ik_keylen
= key_len
;
597 memcpy(&wk
.ik_keyrsc
, seq
, seq_len
);
598 memcpy(wk
.ik_keydata
, key
, key_len
);
600 return set80211priv(ifname
, IEEE80211_IOCTL_SETKEY
, &wk
, sizeof(wk
));
603 struct wpa_driver_ops wpa_driver_madwifi_ops
= {
604 .set_wpa
= wpa_driver_madwifi_set_wpa
,
605 .set_key
= wpa_driver_madwifi_set_key
,
612 #define IPW_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
613 #define IPW_CMD_SET_WPA_PARAM 1
614 #define IPW_CMD_SET_ENCRYPTION 3
615 #define IPW_PARAM_WPA_ENABLED 1
616 #define IPW_PARAM_AUTH_ALGS 5
617 #define IPW_CRYPT_ALG_NAME_LEN 16
621 u8 sta_addr
[ETH_ALEN
];
636 u8 alg
[IPW_CRYPT_ALG_NAME_LEN
];
648 int ipw_ioctl(const char *dev
, struct ipw_param
*param
, int len
)
654 s
= socket(PF_INET
, SOCK_DGRAM
, 0);
659 memset(&iwr
, 0, sizeof(iwr
));
660 strncpy(iwr
.ifr_name
, dev
, IFNAMSIZ
);
661 iwr
.u
.data
.pointer
= (caddr_t
) param
;
662 iwr
.u
.data
.length
= len
;
664 if (ioctl(s
, IPW_IOCTL_WPA_SUPPLICANT
, &iwr
) < 0) {
672 int wpa_driver_ipw_set_wpa(const char *ifname
, int enabled
)
675 struct ipw_param param
;
677 memset(¶m
, 0, sizeof(param
));
678 param
.cmd
= IPW_CMD_SET_WPA_PARAM
;
679 param
.u
.wpa_param
.name
= IPW_PARAM_WPA_ENABLED
;
680 param
.u
.wpa_param
.value
= enabled
;
682 if (ipw_ioctl(ifname
, ¶m
, sizeof(param
)) < 0)
688 int wpa_driver_ipw_set_key(const char *ifname
, wpa_alg alg
,
689 unsigned char *addr
, int key_idx
, int set_tx
,
690 u8
*seq
, size_t seq_len
,
691 u8
*key
, size_t key_len
)
693 struct ipw_param
*param
;
719 blen
= sizeof(*param
) + key_len
;
723 memset(buf
, 0, blen
);
725 param
= (struct ipw_param
*) buf
;
726 param
->cmd
= IPW_CMD_SET_ENCRYPTION
;
727 memset(param
->sta_addr
, 0xff, ETH_ALEN
);
728 strncpy(param
->u
.crypt
.alg
, alg_name
, IPW_CRYPT_ALG_NAME_LEN
);
729 param
->u
.crypt
.set_tx
= set_tx
? 1 : 0;
730 param
->u
.crypt
.idx
= key_idx
;
731 memcpy(param
->u
.crypt
.seq
, seq
, seq_len
);
732 param
->u
.crypt
.key_len
= key_len
;
733 memcpy((u8
*) (param
+ 1), key
, key_len
);
735 if (ipw_ioctl(ifname
, param
, blen
)) {
743 int wpa_driver_ipw_set_auth_alg(const char *ifname
, int auth_alg
)
746 struct ipw_param param
;
748 if (auth_alg
& AUTH_ALG_OPEN_SYSTEM
)
750 if (auth_alg
& AUTH_ALG_SHARED_KEY
)
752 if (auth_alg
& AUTH_ALG_LEAP
)
755 algs
= 1; /* at least one algorithm should be set */
757 memset(¶m
, 0, sizeof(param
));
758 param
.cmd
= IPW_CMD_SET_WPA_PARAM
;
759 param
.u
.wpa_param
.name
= IPW_PARAM_AUTH_ALGS
;
760 param
.u
.wpa_param
.value
= algs
;
762 return ipw_ioctl(ifname
, ¶m
, sizeof(param
));
765 struct wpa_driver_ops wpa_driver_ipw_ops
= {
766 .set_wpa
= wpa_driver_ipw_set_wpa
,
767 .set_key
= wpa_driver_ipw_set_key
,
768 .set_auth_alg
= wpa_driver_ipw_set_auth_alg
775 #define ATMEL_WPA_IOCTL (SIOCIWFIRSTPRIV + 2)
776 #define ATMEL_WPA_IOCTL_PARAM (SIOCIWFIRSTPRIV + 3)
777 #define ATMEL_WPA_IOCTL_GET_PARAM (SIOCIWFIRSTPRIV + 4)
779 #define MAX_KEY_LENGTH 40
781 /* ATMEL_WPA_IOCTL ioctl() cmd: */
783 SET_WPA_ENCRYPTION
= 1,
784 SET_CIPHER_SUITES
= 2,
787 /* ATMEL_WPA_IOCTL_PARAM ioctl() cmd: */
790 ATMEL_PARAM_PRIVACY_INVOKED
= 2,
791 ATMEL_PARAM_WPA_TYPE
= 3,
795 unsigned char sta_addr
[6];
803 u8 key
[MAX_KEY_LENGTH
];
813 int atmel_ioctl(const char *dev
, struct atmel_param
*param
, int len
)
819 s
= socket(PF_INET
, SOCK_DGRAM
, 0);
824 memset(&iwr
, 0, sizeof(iwr
));
825 strncpy(iwr
.ifr_name
, dev
, IFNAMSIZ
);
826 iwr
.u
.data
.pointer
= (caddr_t
) param
;
827 iwr
.u
.data
.length
= len
;
829 if (ioctl(s
, ATMEL_WPA_IOCTL
, &iwr
) < 0) {
837 int atmel2param(const char *ifname
, int param
, int value
)
842 s
= socket(PF_INET
, SOCK_DGRAM
, 0);
847 memset(&iwr
, 0, sizeof(iwr
));
848 strncpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
849 i
= (int *) iwr
.u
.name
;
853 if (ioctl(s
, ATMEL_WPA_IOCTL_PARAM
, &iwr
) < 0) {
860 int wpa_driver_atmel_set_wpa(const char *ifname
, int enabled
)
864 if (atmel2param(ifname
, ATMEL_PARAM_PRIVACY_INVOKED
, enabled
) < 0)
866 if (atmel2param(ifname
, ATMEL_PARAM_WPA
, enabled
) < 0)
872 int wpa_driver_atmel_set_key(const char *ifname
, wpa_alg alg
,
873 unsigned char *addr
, int key_idx
,
874 int set_tx
, u8
*seq
, size_t seq_len
,
875 u8
*key
, size_t key_len
)
878 struct atmel_param
*param
;
909 blen
= sizeof(*param
) + key_len
;
913 memset(buf
, 0, blen
);
915 param
= (struct atmel_param
*) buf
;
917 param
->cmd
= SET_WPA_ENCRYPTION
;
920 memset(param
->sta_addr
, 0xff, ETH_ALEN
);
922 memcpy(param
->sta_addr
, addr
, ETH_ALEN
);
924 param
->alg
= alg_type
;
925 param
->key_idx
= key_idx
;
926 param
->set_tx
= set_tx
;
927 memcpy(param
->seq
, seq
, seq_len
);
928 param
->seq_len
= seq_len
;
929 param
->key_len
= key_len
;
930 memcpy((u8
*)param
->key
, key
, key_len
);
932 if (atmel_ioctl(ifname
, param
, blen
)) {
940 struct wpa_driver_ops wpa_driver_atmel_ops
= {
941 .set_wpa
= wpa_driver_atmel_set_wpa
,
942 .set_key
= wpa_driver_atmel_set_key
,
947 /* begin ndiswrapper */
949 #define WPA_SET_WPA SIOCIWFIRSTPRIV+1
950 #define WPA_SET_KEY SIOCIWFIRSTPRIV+2
951 #define WPA_SET_AUTH_ALG SIOCIWFIRSTPRIV+8
965 int wpa_ndiswrapper_set_ext(const char *ifname
, int request
, struct iwreq
*pwrq
)
970 s
= socket( AF_INET
, SOCK_DGRAM
, 0);
974 strncpy(pwrq
->ifr_name
, ifname
, IFNAMSIZ
);
975 ret
= ioctl(s
, request
, pwrq
);
980 int wpa_ndiswrapper_set_wpa(const char *ifname
, int enabled
)
982 struct iwreq priv_req
;
985 memset(&priv_req
, 0, sizeof(priv_req
));
987 priv_req
.u
.data
.flags
= enabled
;
988 if (wpa_ndiswrapper_set_ext(ifname
, WPA_SET_WPA
, &priv_req
) < 0)
993 int wpa_ndiswrapper_set_key(const char *ifname
, wpa_alg alg
, u8
*addr
,
994 int key_idx
, int set_tx
, u8
*seq
,
995 size_t seq_len
, u8
*key
, size_t key_len
)
997 struct wpa_key wpa_key
;
999 struct iwreq priv_req
;
1001 memset(&priv_req
, 0, sizeof(priv_req
));
1004 wpa_key
.addr
= addr
;
1005 wpa_key
.key_index
= key_idx
;
1006 wpa_key
.set_tx
= set_tx
;
1008 wpa_key
.seq_len
= seq_len
;
1010 wpa_key
.key_len
= key_len
;
1012 priv_req
.u
.data
.pointer
= (void *)&wpa_key
;
1014 if (wpa_ndiswrapper_set_ext(ifname
, WPA_SET_KEY
, &priv_req
) < 0)
1019 static int wpa_ndiswrapper_set_auth_alg(const char *ifname
, int auth_alg
)
1022 struct iwreq priv_req
;
1024 memset(&priv_req
, 0, sizeof(priv_req
));
1026 priv_req
.u
.param
.value
= auth_alg
;
1027 if (wpa_ndiswrapper_set_ext(ifname
, WPA_SET_AUTH_ALG
, &priv_req
) < 0)
1032 struct wpa_driver_ops wpa_driver_ndiswrapper_ops
= {
1033 .set_wpa
= wpa_ndiswrapper_set_wpa
,
1034 .set_key
= wpa_ndiswrapper_set_key
,
1035 .set_auth_alg
= wpa_ndiswrapper_set_auth_alg
,
1038 /* end ndiswrapper */
1040 #endif /* !defined(LIBHD_TINY) */