2 * WPA Supplicant - privilege separated driver interface
3 * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
15 #include "common/privsep_commands.h"
18 struct wpa_driver_privsep_data
{
20 u8 own_addr
[ETH_ALEN
];
22 char *own_socket_path
;
25 struct sockaddr_un priv_addr
;
30 static int wpa_priv_reg_cmd(struct wpa_driver_privsep_data
*drv
, int cmd
)
34 res
= sendto(drv
->priv_socket
, &cmd
, sizeof(cmd
), 0,
35 (struct sockaddr
*) &drv
->priv_addr
,
36 sizeof(drv
->priv_addr
));
38 wpa_printf(MSG_ERROR
, "sendto: %s", strerror(errno
));
39 return res
< 0 ? -1 : 0;
43 static int wpa_priv_cmd(struct wpa_driver_privsep_data
*drv
, int cmd
,
44 const void *data
, size_t data_len
,
45 void *reply
, size_t *reply_len
)
50 io
[0].iov_base
= &cmd
;
51 io
[0].iov_len
= sizeof(cmd
);
52 io
[1].iov_base
= (u8
*) data
;
53 io
[1].iov_len
= data_len
;
55 os_memset(&msg
, 0, sizeof(msg
));
57 msg
.msg_iovlen
= data
? 2 : 1;
58 msg
.msg_name
= &drv
->priv_addr
;
59 msg
.msg_namelen
= sizeof(drv
->priv_addr
);
61 if (sendmsg(drv
->cmd_socket
, &msg
, 0) < 0) {
62 wpa_printf(MSG_ERROR
, "sendmsg(cmd_socket): %s",
73 FD_SET(drv
->cmd_socket
, &rfds
);
76 res
= select(drv
->cmd_socket
+ 1, &rfds
, NULL
, NULL
, &tv
);
77 if (res
< 0 && errno
!= EINTR
) {
78 wpa_printf(MSG_ERROR
, "select: %s", strerror(errno
));
82 if (FD_ISSET(drv
->cmd_socket
, &rfds
)) {
83 res
= recv(drv
->cmd_socket
, reply
, *reply_len
, 0);
85 wpa_printf(MSG_ERROR
, "recv: %s",
91 wpa_printf(MSG_DEBUG
, "PRIVSEP: Timeout while waiting "
92 "for reply (cmd=%d)", cmd
);
101 static int wpa_driver_privsep_scan(void *priv
,
102 struct wpa_driver_scan_params
*params
)
104 struct wpa_driver_privsep_data
*drv
= priv
;
105 struct privsep_cmd_scan scan
;
108 wpa_printf(MSG_DEBUG
, "%s: priv=%p", __func__
, priv
);
109 os_memset(&scan
, 0, sizeof(scan
));
110 scan
.num_ssids
= params
->num_ssids
;
111 for (i
= 0; i
< params
->num_ssids
; i
++) {
112 if (!params
->ssids
[i
].ssid
)
114 scan
.ssid_lens
[i
] = params
->ssids
[i
].ssid_len
;
115 os_memcpy(scan
.ssids
[i
], params
->ssids
[i
].ssid
,
119 for (i
= 0; i
< PRIVSEP_MAX_SCAN_FREQS
&&
120 params
->freqs
&& params
->freqs
[i
]; i
++)
121 scan
.freqs
[i
] = params
->freqs
[i
];
124 return wpa_priv_cmd(drv
, PRIVSEP_CMD_SCAN
, &scan
, sizeof(scan
),
129 static struct wpa_scan_results
*
130 wpa_driver_privsep_get_scan_results2(void *priv
)
132 struct wpa_driver_privsep_data
*drv
= priv
;
135 size_t reply_len
= 60000;
136 struct wpa_scan_results
*results
;
137 struct wpa_scan_res
*r
;
139 buf
= os_malloc(reply_len
);
142 res
= wpa_priv_cmd(drv
, PRIVSEP_CMD_GET_SCAN_RESULTS
,
143 NULL
, 0, buf
, &reply_len
);
149 wpa_printf(MSG_DEBUG
, "privsep: Received %lu bytes of scan results",
150 (unsigned long) reply_len
);
151 if (reply_len
< sizeof(int)) {
152 wpa_printf(MSG_DEBUG
, "privsep: Invalid scan result len %lu",
153 (unsigned long) reply_len
);
159 end
= buf
+ reply_len
;
160 os_memcpy(&num
, pos
, sizeof(int));
161 if (num
< 0 || num
> 1000) {
167 results
= os_zalloc(sizeof(*results
));
168 if (results
== NULL
) {
173 results
->res
= os_calloc(num
, sizeof(struct wpa_scan_res
*));
174 if (results
->res
== NULL
) {
180 while (results
->num
< (size_t) num
&& end
- pos
> (int) sizeof(int)) {
182 os_memcpy(&len
, pos
, sizeof(int));
184 if (len
< 0 || len
> 10000 || len
> end
- pos
)
187 r
= os_memdup(pos
, len
);
191 if (sizeof(*r
) + r
->ie_len
+ r
->beacon_ie_len
> (size_t) len
) {
192 wpa_printf(MSG_ERROR
,
193 "privsep: Invalid scan result len (%d + %d + %d > %d)",
194 (int) sizeof(*r
), (int) r
->ie_len
,
195 (int) r
->beacon_ie_len
, len
);
200 results
->res
[results
->num
++] = r
;
208 static int wpa_driver_privsep_set_key(const char *ifname
, void *priv
,
209 enum wpa_alg alg
, const u8
*addr
,
210 int key_idx
, int set_tx
,
211 const u8
*seq
, size_t seq_len
,
212 const u8
*key
, size_t key_len
)
214 struct wpa_driver_privsep_data
*drv
= priv
;
215 struct privsep_cmd_set_key cmd
;
217 wpa_printf(MSG_DEBUG
, "%s: priv=%p alg=%d key_idx=%d set_tx=%d",
218 __func__
, priv
, alg
, key_idx
, set_tx
);
220 os_memset(&cmd
, 0, sizeof(cmd
));
223 os_memcpy(cmd
.addr
, addr
, ETH_ALEN
);
225 os_memset(cmd
.addr
, 0xff, ETH_ALEN
);
226 cmd
.key_idx
= key_idx
;
228 if (seq
&& seq_len
> 0 && seq_len
< sizeof(cmd
.seq
)) {
229 os_memcpy(cmd
.seq
, seq
, seq_len
);
230 cmd
.seq_len
= seq_len
;
232 if (key
&& key_len
> 0 && key_len
< sizeof(cmd
.key
)) {
233 os_memcpy(cmd
.key
, key
, key_len
);
234 cmd
.key_len
= key_len
;
237 return wpa_priv_cmd(drv
, PRIVSEP_CMD_SET_KEY
, &cmd
, sizeof(cmd
),
242 static int wpa_driver_privsep_authenticate(
243 void *priv
, struct wpa_driver_auth_params
*params
)
245 struct wpa_driver_privsep_data
*drv
= priv
;
246 struct privsep_cmd_authenticate
*data
;
251 wpa_printf(MSG_DEBUG
, "%s: priv=%p freq=%d bssid=" MACSTR
252 " auth_alg=%d local_state_change=%d p2p=%d",
253 __func__
, priv
, params
->freq
, MAC2STR(params
->bssid
),
254 params
->auth_alg
, params
->local_state_change
, params
->p2p
);
256 buflen
= sizeof(*data
) + params
->ie_len
+ params
->auth_data_len
;
257 data
= os_zalloc(buflen
);
261 data
->freq
= params
->freq
;
262 os_memcpy(data
->bssid
, params
->bssid
, ETH_ALEN
);
263 os_memcpy(data
->ssid
, params
->ssid
, params
->ssid_len
);
264 data
->ssid_len
= params
->ssid_len
;
265 data
->auth_alg
= params
->auth_alg
;
266 data
->ie_len
= params
->ie_len
;
267 for (i
= 0; i
< 4; i
++) {
268 if (params
->wep_key
[i
])
269 os_memcpy(data
->wep_key
[i
], params
->wep_key
[i
],
270 params
->wep_key_len
[i
]);
271 data
->wep_key_len
[i
] = params
->wep_key_len
[i
];
273 data
->wep_tx_keyidx
= params
->wep_tx_keyidx
;
274 data
->local_state_change
= params
->local_state_change
;
275 data
->p2p
= params
->p2p
;
276 pos
= (u8
*) (data
+ 1);
277 if (params
->ie_len
) {
278 os_memcpy(pos
, params
->ie
, params
->ie_len
);
279 pos
+= params
->ie_len
;
281 if (params
->auth_data_len
)
282 os_memcpy(pos
, params
->auth_data
, params
->auth_data_len
);
284 res
= wpa_priv_cmd(drv
, PRIVSEP_CMD_AUTHENTICATE
, data
, buflen
,
292 static int wpa_driver_privsep_associate(
293 void *priv
, struct wpa_driver_associate_params
*params
)
295 struct wpa_driver_privsep_data
*drv
= priv
;
296 struct privsep_cmd_associate
*data
;
300 wpa_printf(MSG_DEBUG
, "%s: priv=%p freq=%d pairwise_suite=%d "
301 "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
302 __func__
, priv
, params
->freq
.freq
, params
->pairwise_suite
,
303 params
->group_suite
, params
->key_mgmt_suite
,
304 params
->auth_alg
, params
->mode
);
306 buflen
= sizeof(*data
) + params
->wpa_ie_len
;
307 data
= os_zalloc(buflen
);
312 os_memcpy(data
->bssid
, params
->bssid
, ETH_ALEN
);
313 os_memcpy(data
->ssid
, params
->ssid
, params
->ssid_len
);
314 data
->ssid_len
= params
->ssid_len
;
315 data
->hwmode
= params
->freq
.mode
;
316 data
->freq
= params
->freq
.freq
;
317 data
->channel
= params
->freq
.channel
;
318 data
->pairwise_suite
= params
->pairwise_suite
;
319 data
->group_suite
= params
->group_suite
;
320 data
->key_mgmt_suite
= params
->key_mgmt_suite
;
321 data
->auth_alg
= params
->auth_alg
;
322 data
->mode
= params
->mode
;
323 data
->wpa_ie_len
= params
->wpa_ie_len
;
325 os_memcpy(data
+ 1, params
->wpa_ie
, params
->wpa_ie_len
);
326 /* TODO: add support for other assoc parameters */
328 res
= wpa_priv_cmd(drv
, PRIVSEP_CMD_ASSOCIATE
, data
, buflen
,
336 static int wpa_driver_privsep_get_bssid(void *priv
, u8
*bssid
)
338 struct wpa_driver_privsep_data
*drv
= priv
;
340 size_t len
= ETH_ALEN
;
342 res
= wpa_priv_cmd(drv
, PRIVSEP_CMD_GET_BSSID
, NULL
, 0, bssid
, &len
);
343 if (res
< 0 || len
!= ETH_ALEN
)
349 static int wpa_driver_privsep_get_ssid(void *priv
, u8
*ssid
)
351 struct wpa_driver_privsep_data
*drv
= priv
;
353 u8 reply
[sizeof(int) + SSID_MAX_LEN
];
354 size_t len
= sizeof(reply
);
356 res
= wpa_priv_cmd(drv
, PRIVSEP_CMD_GET_SSID
, NULL
, 0, reply
, &len
);
357 if (res
< 0 || len
< sizeof(int))
359 os_memcpy(&ssid_len
, reply
, sizeof(int));
360 if (ssid_len
< 0 || ssid_len
> SSID_MAX_LEN
||
361 sizeof(int) + ssid_len
> len
) {
362 wpa_printf(MSG_DEBUG
, "privsep: Invalid get SSID reply");
365 os_memcpy(ssid
, &reply
[sizeof(int)], ssid_len
);
370 static int wpa_driver_privsep_deauthenticate(void *priv
, const u8
*addr
,
373 //struct wpa_driver_privsep_data *drv = priv;
374 wpa_printf(MSG_DEBUG
, "%s addr=" MACSTR
" reason_code=%d",
375 __func__
, MAC2STR(addr
), reason_code
);
376 wpa_printf(MSG_DEBUG
, "%s - TODO", __func__
);
381 static void wpa_driver_privsep_event_auth(void *ctx
, u8
*buf
, size_t len
)
383 union wpa_event_data data
;
384 struct privsep_event_auth
*auth
;
386 os_memset(&data
, 0, sizeof(data
));
387 if (len
< sizeof(*auth
))
389 auth
= (struct privsep_event_auth
*) buf
;
390 if (len
< sizeof(*auth
) + auth
->ies_len
)
393 os_memcpy(data
.auth
.peer
, auth
->peer
, ETH_ALEN
);
394 os_memcpy(data
.auth
.bssid
, auth
->bssid
, ETH_ALEN
);
395 data
.auth
.auth_type
= auth
->auth_type
;
396 data
.auth
.auth_transaction
= auth
->auth_transaction
;
397 data
.auth
.status_code
= auth
->status_code
;
399 data
.auth
.ies
= (u8
*) (auth
+ 1);
400 data
.auth
.ies_len
= auth
->ies_len
;
403 wpa_supplicant_event(ctx
, EVENT_AUTH
, &data
);
407 static void wpa_driver_privsep_event_assoc(void *ctx
,
408 enum wpa_event_type event
,
411 union wpa_event_data data
;
416 os_memset(&data
, 0, sizeof(data
));
421 if (end
- pos
< (int) sizeof(int))
423 os_memcpy(&ie_len
, pos
, sizeof(int));
425 if (ie_len
< 0 || ie_len
> end
- pos
)
428 data
.assoc_info
.req_ies
= pos
;
429 data
.assoc_info
.req_ies_len
= ie_len
;
434 wpa_supplicant_event(ctx
, event
, inc_data
? &data
: NULL
);
438 static void wpa_driver_privsep_event_interface_status(void *ctx
, u8
*buf
,
441 union wpa_event_data data
;
444 if (len
< sizeof(int) ||
445 len
- sizeof(int) > sizeof(data
.interface_status
.ifname
))
448 os_memcpy(&ievent
, buf
, sizeof(int));
450 os_memset(&data
, 0, sizeof(data
));
451 data
.interface_status
.ievent
= ievent
;
452 os_memcpy(data
.interface_status
.ifname
, buf
+ sizeof(int),
454 wpa_supplicant_event(ctx
, EVENT_INTERFACE_STATUS
, &data
);
458 static void wpa_driver_privsep_event_michael_mic_failure(
459 void *ctx
, u8
*buf
, size_t len
)
461 union wpa_event_data data
;
463 if (len
!= sizeof(int))
466 os_memset(&data
, 0, sizeof(data
));
467 os_memcpy(&data
.michael_mic_failure
.unicast
, buf
, sizeof(int));
468 wpa_supplicant_event(ctx
, EVENT_MICHAEL_MIC_FAILURE
, &data
);
472 static void wpa_driver_privsep_event_pmkid_candidate(void *ctx
, u8
*buf
,
475 union wpa_event_data data
;
477 if (len
!= sizeof(struct pmkid_candidate
))
480 os_memset(&data
, 0, sizeof(data
));
481 os_memcpy(&data
.pmkid_candidate
, buf
, len
);
482 wpa_supplicant_event(ctx
, EVENT_PMKID_CANDIDATE
, &data
);
486 static void wpa_driver_privsep_event_ft_response(void *ctx
, u8
*buf
,
489 union wpa_event_data data
;
491 if (len
< sizeof(int) + ETH_ALEN
)
494 os_memset(&data
, 0, sizeof(data
));
495 os_memcpy(&data
.ft_ies
.ft_action
, buf
, sizeof(int));
496 os_memcpy(data
.ft_ies
.target_ap
, buf
+ sizeof(int), ETH_ALEN
);
497 data
.ft_ies
.ies
= buf
+ sizeof(int) + ETH_ALEN
;
498 data
.ft_ies
.ies_len
= len
- sizeof(int) - ETH_ALEN
;
499 wpa_supplicant_event(ctx
, EVENT_FT_RESPONSE
, &data
);
503 static void wpa_driver_privsep_event_rx_eapol(void *ctx
, u8
*buf
, size_t len
)
507 drv_event_eapol_rx(ctx
, buf
, buf
+ ETH_ALEN
, len
- ETH_ALEN
);
511 static void wpa_driver_privsep_receive(int sock
, void *eloop_ctx
,
514 struct wpa_driver_privsep_data
*drv
= eloop_ctx
;
518 enum privsep_event e
;
519 struct sockaddr_un from
;
520 socklen_t fromlen
= sizeof(from
);
521 const size_t buflen
= 2000;
523 buf
= os_malloc(buflen
);
526 res
= recvfrom(sock
, buf
, buflen
, 0,
527 (struct sockaddr
*) &from
, &fromlen
);
529 wpa_printf(MSG_ERROR
, "recvfrom(priv_socket): %s",
535 wpa_printf(MSG_DEBUG
, "privsep_driver: received %u bytes", res
);
537 if (res
< (int) sizeof(int)) {
538 wpa_printf(MSG_DEBUG
, "Too short event message (len=%d)", res
);
542 os_memcpy(&event
, buf
, sizeof(int));
543 event_buf
= &buf
[sizeof(int)];
544 event_len
= res
- sizeof(int);
545 wpa_printf(MSG_DEBUG
, "privsep: Event %d received (len=%lu)",
546 event
, (unsigned long) event_len
);
550 case PRIVSEP_EVENT_SCAN_RESULTS
:
551 wpa_supplicant_event(drv
->ctx
, EVENT_SCAN_RESULTS
, NULL
);
553 case PRIVSEP_EVENT_SCAN_STARTED
:
554 wpa_supplicant_event(drv
->ctx
, EVENT_SCAN_STARTED
, NULL
);
556 case PRIVSEP_EVENT_ASSOC
:
557 wpa_driver_privsep_event_assoc(drv
->ctx
, EVENT_ASSOC
,
558 event_buf
, event_len
);
560 case PRIVSEP_EVENT_DISASSOC
:
561 wpa_supplicant_event(drv
->ctx
, EVENT_DISASSOC
, NULL
);
563 case PRIVSEP_EVENT_ASSOCINFO
:
564 wpa_driver_privsep_event_assoc(drv
->ctx
, EVENT_ASSOCINFO
,
565 event_buf
, event_len
);
567 case PRIVSEP_EVENT_MICHAEL_MIC_FAILURE
:
568 wpa_driver_privsep_event_michael_mic_failure(
569 drv
->ctx
, event_buf
, event_len
);
571 case PRIVSEP_EVENT_INTERFACE_STATUS
:
572 wpa_driver_privsep_event_interface_status(drv
->ctx
, event_buf
,
575 case PRIVSEP_EVENT_PMKID_CANDIDATE
:
576 wpa_driver_privsep_event_pmkid_candidate(drv
->ctx
, event_buf
,
579 case PRIVSEP_EVENT_FT_RESPONSE
:
580 wpa_driver_privsep_event_ft_response(drv
->ctx
, event_buf
,
583 case PRIVSEP_EVENT_RX_EAPOL
:
584 wpa_driver_privsep_event_rx_eapol(drv
->ctx
, event_buf
,
587 case PRIVSEP_EVENT_AUTH
:
588 wpa_driver_privsep_event_auth(drv
->ctx
, event_buf
, event_len
);
596 static void * wpa_driver_privsep_init(void *ctx
, const char *ifname
)
598 struct wpa_driver_privsep_data
*drv
;
600 drv
= os_zalloc(sizeof(*drv
));
604 drv
->priv_socket
= -1;
605 drv
->cmd_socket
= -1;
606 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
612 static void wpa_driver_privsep_deinit(void *priv
)
614 struct wpa_driver_privsep_data
*drv
= priv
;
616 if (drv
->priv_socket
>= 0) {
617 wpa_priv_reg_cmd(drv
, PRIVSEP_CMD_UNREGISTER
);
618 eloop_unregister_read_sock(drv
->priv_socket
);
619 close(drv
->priv_socket
);
622 if (drv
->own_socket_path
) {
623 unlink(drv
->own_socket_path
);
624 os_free(drv
->own_socket_path
);
627 if (drv
->cmd_socket
>= 0) {
628 eloop_unregister_read_sock(drv
->cmd_socket
);
629 close(drv
->cmd_socket
);
632 if (drv
->own_cmd_path
) {
633 unlink(drv
->own_cmd_path
);
634 os_free(drv
->own_cmd_path
);
641 static int wpa_driver_privsep_set_param(void *priv
, const char *param
)
643 struct wpa_driver_privsep_data
*drv
= priv
;
645 char *own_dir
, *priv_dir
;
646 static unsigned int counter
= 0;
648 struct sockaddr_un addr
;
650 wpa_printf(MSG_DEBUG
, "%s: param='%s'", __func__
, param
);
654 pos
= os_strstr(param
, "own_dir=");
657 own_dir
= os_strdup(pos
+ 8);
660 end
= os_strchr(own_dir
, ' ');
664 own_dir
= os_strdup("/tmp");
672 pos
= os_strstr(param
, "priv_dir=");
675 priv_dir
= os_strdup(pos
+ 9);
676 if (priv_dir
== NULL
) {
680 end
= os_strchr(priv_dir
, ' ');
684 priv_dir
= os_strdup("/var/run/wpa_priv");
685 if (priv_dir
== NULL
) {
691 len
= os_strlen(own_dir
) + 50;
692 drv
->own_socket_path
= os_malloc(len
);
693 if (drv
->own_socket_path
== NULL
) {
698 os_snprintf(drv
->own_socket_path
, len
, "%s/wpa_privsep-%d-%d",
699 own_dir
, getpid(), counter
++);
701 len
= os_strlen(own_dir
) + 50;
702 drv
->own_cmd_path
= os_malloc(len
);
703 if (drv
->own_cmd_path
== NULL
) {
704 os_free(drv
->own_socket_path
);
705 drv
->own_socket_path
= NULL
;
710 os_snprintf(drv
->own_cmd_path
, len
, "%s/wpa_privsep-%d-%d",
711 own_dir
, getpid(), counter
++);
715 drv
->priv_addr
.sun_family
= AF_UNIX
;
716 os_snprintf(drv
->priv_addr
.sun_path
, sizeof(drv
->priv_addr
.sun_path
),
717 "%s/%s", priv_dir
, drv
->ifname
);
720 drv
->priv_socket
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
721 if (drv
->priv_socket
< 0) {
722 wpa_printf(MSG_ERROR
, "socket(PF_UNIX): %s", strerror(errno
));
723 os_free(drv
->own_socket_path
);
724 drv
->own_socket_path
= NULL
;
728 os_memset(&addr
, 0, sizeof(addr
));
729 addr
.sun_family
= AF_UNIX
;
730 os_strlcpy(addr
.sun_path
, drv
->own_socket_path
, sizeof(addr
.sun_path
));
731 if (bind(drv
->priv_socket
, (struct sockaddr
*) &addr
, sizeof(addr
)) <
733 wpa_printf(MSG_ERROR
,
734 "privsep-set-params priv-sock: bind(PF_UNIX): %s",
736 close(drv
->priv_socket
);
737 drv
->priv_socket
= -1;
738 unlink(drv
->own_socket_path
);
739 os_free(drv
->own_socket_path
);
740 drv
->own_socket_path
= NULL
;
744 eloop_register_read_sock(drv
->priv_socket
, wpa_driver_privsep_receive
,
747 drv
->cmd_socket
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
748 if (drv
->cmd_socket
< 0) {
749 wpa_printf(MSG_ERROR
, "socket(PF_UNIX): %s", strerror(errno
));
750 os_free(drv
->own_cmd_path
);
751 drv
->own_cmd_path
= NULL
;
755 os_memset(&addr
, 0, sizeof(addr
));
756 addr
.sun_family
= AF_UNIX
;
757 os_strlcpy(addr
.sun_path
, drv
->own_cmd_path
, sizeof(addr
.sun_path
));
758 if (bind(drv
->cmd_socket
, (struct sockaddr
*) &addr
, sizeof(addr
)) < 0)
760 wpa_printf(MSG_ERROR
,
761 "privsep-set-params cmd-sock: bind(PF_UNIX): %s",
763 close(drv
->cmd_socket
);
764 drv
->cmd_socket
= -1;
765 unlink(drv
->own_cmd_path
);
766 os_free(drv
->own_cmd_path
);
767 drv
->own_cmd_path
= NULL
;
771 if (wpa_priv_reg_cmd(drv
, PRIVSEP_CMD_REGISTER
) < 0) {
772 wpa_printf(MSG_ERROR
, "Failed to register with wpa_priv");
780 static int wpa_driver_privsep_get_capa(void *priv
,
781 struct wpa_driver_capa
*capa
)
783 struct wpa_driver_privsep_data
*drv
= priv
;
785 size_t len
= sizeof(*capa
);
787 res
= wpa_priv_cmd(drv
, PRIVSEP_CMD_GET_CAPA
, NULL
, 0, capa
, &len
);
788 if (res
< 0 || len
!= sizeof(*capa
))
790 /* For now, no support for passing extended_capa pointers */
791 capa
->extended_capa
= NULL
;
792 capa
->extended_capa_mask
= NULL
;
793 capa
->extended_capa_len
= 0;
798 static const u8
* wpa_driver_privsep_get_mac_addr(void *priv
)
800 struct wpa_driver_privsep_data
*drv
= priv
;
801 wpa_printf(MSG_DEBUG
, "%s", __func__
);
802 return drv
->own_addr
;
806 static int wpa_driver_privsep_set_country(void *priv
, const char *alpha2
)
808 struct wpa_driver_privsep_data
*drv
= priv
;
809 wpa_printf(MSG_DEBUG
, "%s country='%s'", __func__
, alpha2
);
810 return wpa_priv_cmd(drv
, PRIVSEP_CMD_SET_COUNTRY
, alpha2
,
811 os_strlen(alpha2
), NULL
, NULL
);
815 struct wpa_driver_ops wpa_driver_privsep_ops
= {
817 "wpa_supplicant privilege separated driver",
818 .get_bssid
= wpa_driver_privsep_get_bssid
,
819 .get_ssid
= wpa_driver_privsep_get_ssid
,
820 .set_key
= wpa_driver_privsep_set_key
,
821 .init
= wpa_driver_privsep_init
,
822 .deinit
= wpa_driver_privsep_deinit
,
823 .set_param
= wpa_driver_privsep_set_param
,
824 .scan2
= wpa_driver_privsep_scan
,
825 .deauthenticate
= wpa_driver_privsep_deauthenticate
,
826 .authenticate
= wpa_driver_privsep_authenticate
,
827 .associate
= wpa_driver_privsep_associate
,
828 .get_capa
= wpa_driver_privsep_get_capa
,
829 .get_mac_addr
= wpa_driver_privsep_get_mac_addr
,
830 .get_scan_results2
= wpa_driver_privsep_get_scan_results2
,
831 .set_country
= wpa_driver_privsep_set_country
,
835 const struct wpa_driver_ops
*const wpa_drivers
[] =
837 &wpa_driver_privsep_ops
,