2 * Application-specific portion of EAPD
5 * Copyright (C) 2010, Broadcom Corporation
8 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
9 * the contents of this file may not be disclosed to third parties, copied
10 * or duplicated in any form, in whole or in part, without the prior
11 * written permission of Broadcom Corporation.
13 * $Id: wps_eap.c 241391 2011-02-18 03:35:48Z stakita $
20 #include <sys/types.h>
21 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
27 #include <proto/ethernet.h>
28 #include <proto/eapol.h>
29 #include <proto/eap.h>
34 #include <security_ipc.h>
35 #include <bcmconfig.h>
37 /* Receive message from wps module */
39 wps_app_recv_handler(eapd_wksp_t
*nwksp
, char *wlifname
, eapd_cb_t
*from
,
40 uint8
*pData
, int *pLen
, struct ether_addr
*ap_ea
)
42 eapol_header_t
*eapol
= (eapol_header_t
*) pData
;
45 struct ether_addr
*sta_ea
;
47 if (!nwksp
|| !wlifname
|| !from
|| !pData
) {
48 EAPD_ERROR("Wrong arguments...\n");
52 if (*pLen
< EAPOL_HEADER_LEN
) {
53 EAPD_ERROR("Message too short...\n");
57 /* send message data out. */
58 sta_ea
= (struct ether_addr
*) eapol
->eth
.ether_dhost
;
59 sta
= sta_lookup(nwksp
, sta_ea
, NULL
, wlifname
, EAPD_SEARCH_ONLY
);
61 /* monitor eapol packet */
62 if (eapol
->type
== EAPOL_START
) {
65 sta_remove(nwksp
, sta
);
67 sta
= sta_lookup(nwksp
, sta_ea
, ap_ea
, wlifname
, EAPD_SEARCH_ENTER
);
69 sta
->mode
= EAPD_STA_MODE_WPS_ENR
;
73 eap
= (eap_header_t
*) eapol
->body
;
74 /* remove sta info when FAILURE or SUCCESS */
75 if ((sta
) && (eapol
->type
== EAP_PACKET
) &&
76 (eap
->code
== EAP_FAILURE
|| eap
->code
== EAP_SUCCESS
)) {
77 sta_remove(nwksp
, sta
);
81 eapd_message_send(nwksp
, from
->brcmSocket
, pData
, *pLen
);
87 wps_app_set_eventmask(eapd_app_t
*app
)
89 memset(app
->bitvec
, 0, sizeof(app
->bitvec
));
91 setbit(app
->bitvec
, WLC_E_EAPOL_MSG
);
92 setbit(app
->bitvec
, WLC_E_PROBREQ_MSG
);
96 setbit(app
->bitvec
, WLC_E_ASSOC_IND
);
97 setbit(app
->bitvec
, WLC_E_REASSOC_IND
);
98 setbit(app
->bitvec
, WLC_E_DISASSOC_IND
);
99 setbit(app
->bitvec
, WLC_E_DEAUTH_IND
);
100 #endif /* __CONFIG_WFI__ */
107 wps_app_init(eapd_wksp_t
*nwksp
)
112 struct sockaddr_in addr
;
122 EAPD_INFO("No any interface is running WPS !\n");
127 EAPD_INFO("init brcm interface %s \n", cb
->ifname
);
128 cb
->brcmSocket
= eapd_add_brcm(nwksp
, cb
->ifname
);
131 /* set this brcmSocket have WPS capability */
132 cb
->brcmSocket
->flag
|= EAPD_CAP_WPS
;
138 * appSocket for wps-monitor, wps-monitor handle all wps
141 wps
->appSocket
= socket(AF_INET
, SOCK_DGRAM
, 0);
142 if (wps
->appSocket
< 0) {
143 EAPD_ERROR("UDP Open failed.\n");
147 if (setsockopt(wps
->appSocket
, SOL_SOCKET
, SO_REUSEPORT
, (char*)&reuse
,
148 sizeof(reuse
)) < 0) {
149 EAPD_ERROR("UDP setsockopt failed.\n");
150 close(wps
->appSocket
);
155 if (setsockopt(wps
->appSocket
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&reuse
,
156 sizeof(reuse
)) < 0) {
157 EAPD_ERROR("UDP setsockopt failed.\n");
158 close(wps
->appSocket
);
164 memset(&addr
, 0, sizeof(struct sockaddr_in
));
165 addr
.sin_family
= AF_INET
;
166 addr
.sin_addr
.s_addr
= INADDR_ANY
;
167 addr
.sin_port
= htons(EAPD_WKSP_WPS_UDP_RPORT
);
168 if (bind(wps
->appSocket
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0) {
169 EAPD_ERROR("UDP Bind failed, close wps appSocket %d\n", wps
->appSocket
);
170 close(wps
->appSocket
);
174 EAPD_INFO("WPS appSocket %d opened\n", wps
->appSocket
);
180 wps_app_deinit(eapd_wksp_t
*nwksp
)
183 eapd_cb_t
*cb
, *tmp_cb
;
186 EAPD_ERROR("Wrong argument...\n");
192 /* brcm drvSocket delete */
193 if (cb
->brcmSocket
) {
194 EAPD_INFO("close wps brcmSocket %d\n", cb
->brcmSocket
->drvSocket
);
195 eapd_del_brcm(nwksp
, cb
->brcmSocket
);
203 /* close appSocket for wps-monitor */
204 if (wps
->appSocket
>= 0) {
205 EAPD_INFO("close wps m_appSocket %d\n", wps
->appSocket
);
206 close(wps
->appSocket
);
214 wps_app_monitor_sendup(eapd_wksp_t
*nwksp
, uint8
*pData
, int Len
, char *from
)
219 EAPD_ERROR("Wrong argument...\n");
224 if (wps
->appSocket
>= 0) {
225 /* send to wps-monitor */
227 struct sockaddr_in to
;
229 to
.sin_addr
.s_addr
= inet_addr(EAPD_WKSP_UDP_ADDR
);
230 to
.sin_family
= AF_INET
;
231 to
.sin_port
= htons(EAPD_WKSP_WPS_UDP_MPORT
);
233 sentBytes
= sendto(wps
->appSocket
, (char *)pData
, Len
, 0,
234 (struct sockaddr
*)&to
, sizeof(struct sockaddr_in
));
236 if (sentBytes
!= Len
) {
237 EAPD_ERROR("UDP send to wps-monitor on %s failed; sentBytes = %d\n",
241 /* EAPD_INFO("send %d bytes to wps-monitor on %s\n", sentBytes, from); */
245 EAPD_ERROR("wps-monitor appSocket not created\n");
251 #if EAPD_WKSP_AUTO_CONFIG
253 wps_app_enabled(char *name
)
255 char value
[128], os_name
[IFNAMSIZ
], temp
[32], prefix
[8];
258 if (nvifname_to_osifname(name
, os_name
, sizeof(os_name
)) < 0)
260 if (wl_probe(os_name
) ||
261 wl_ioctl(os_name
, WLC_GET_INSTANCE
, &unit
, sizeof(unit
)))
263 /* Convert eth name to wl name */
264 if (osifname_to_nvifname(name
, prefix
, sizeof(prefix
)) != 0)
268 eapd_safe_get_conf(value
, sizeof(value
), strcat_r(prefix
, "bss_enabled", temp
));
269 if (strcmp(value
, "1"))
272 eapd_safe_get_conf(value
, sizeof(value
), strcat_r(prefix
, "wps_mode", temp
));
273 if (!strcmp(value
, "enabled") || !strcmp(value
, "enr_enabled"))
278 #endif /* EAPD_WKSP_AUTO_CONFIG */
281 wps_app_handle_event(eapd_wksp_t
*nwksp
, uint8
*pData
, int Len
, char *from
)
286 bcm_event_t
*dpkt
= (bcm_event_t
*) pData
;
287 wl_event_msg_t
*event
;
289 event
= &(dpkt
->event
);
290 type
= ntohl(event
->event_type
);
295 if (isset(wps
->bitvec
, type
) && !strcmp(cb
->ifname
, from
)) {
296 /* prepend ifname, we reserved IFNAMSIZ length already */
299 memcpy(pData
, event
->ifname
, IFNAMSIZ
);
301 /* send to wps use cb->ifname */
302 wps_app_monitor_sendup(nwksp
, pData
, Len
, cb
->ifname
);