K2.6 patches and update.
[tomato.git] / release / src-rt / wl / eapd / wai_eap.c
blob8660c168dba8addfceff871ef7d26e79b4a73506
1 /*
2 * Application-specific portion of EAPD
3 * (WAI)
5 * Copyright (C) 2010, Broadcom Corporation
6 * All Rights Reserved.
7 *
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: wai_eap.c 241391 2011-02-18 03:35:48Z stakita $
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <net/if.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
25 #include <typedefs.h>
26 #include <bcmutils.h>
27 #include <proto/ethernet.h>
28 #include <proto/eapol.h>
29 #include <proto/eap.h>
30 #include <bcmendian.h>
31 #include <wlutils.h>
32 #include <eapd.h>
33 #include <shutils.h>
34 #include <UdpLib.h>
35 #include <security_ipc.h>
38 #define AUTH_MODE_WAPI 1
39 #define AUTH_MODE_WAPI_PSK 2
42 /* Receive wai message from wapid module
44 void
45 wai_app_recv_handler(eapd_wksp_t *nwksp, eapd_cb_t *from, uint8 *pData, int *pLen)
47 if (!nwksp || !from || !pData) {
48 EAPD_ERROR("Wrong argument...\n");
49 return;
52 /* send message data out. */
53 eapd_message_send(nwksp, from->brcmSocket, pData, *pLen);
55 return;
58 void
59 wai_app_set_eventmask(eapd_app_t *app)
61 memset(app->bitvec, 0, sizeof(app->bitvec));
63 setbit(app->bitvec, WLC_E_WAI_MSG);
64 setbit(app->bitvec, WLC_E_WAI_STA_EVENT);
65 return;
68 int
69 wai_app_init(eapd_wksp_t *nwksp)
71 int ret, reuse = 1;
72 eapd_wai_t *wai;
73 eapd_cb_t *cb;
74 struct sockaddr_in addr;
76 if (nwksp == NULL)
77 return -1;
79 wai = &nwksp->wai;
80 wai->appSocket = -1;
82 cb = wai->cb;
83 if (cb == NULL) {
84 EAPD_INFO("No any WAI application need to run.\n");
85 return 0;
88 while (cb) {
89 EAPD_INFO("wai: init brcm interface %s \n", cb->ifname);
90 cb->brcmSocket = eapd_add_brcm(nwksp, cb->ifname);
91 if (!cb->brcmSocket)
92 return -1;
93 /* set this brcmSocket have WAI capability */
94 cb->brcmSocket->flag |= EAPD_CAP_WAI;
95 cb = cb->next;
98 /* appSocket for wapid */
99 wai->appSocket = socket(AF_INET, SOCK_DGRAM, 0);
100 if (wai->appSocket < 0) {
101 EAPD_ERROR("UDP Open failed.\n");
102 return -1;
104 #if defined(__ECOS)
105 if (setsockopt(wai->appSocket, SOL_SOCKET, SO_REUSEPORT, (char*)&reuse,
106 sizeof(reuse)) < 0) {
107 EAPD_ERROR("UDP setsockopt failed.\n");
108 close(wai->appSocket);
109 wai->appSocket = -1;
110 return -1;
112 #else
113 if (setsockopt(wai->appSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse,
114 sizeof(reuse)) < 0) {
115 EAPD_ERROR("UDP setsockopt failed.\n");
116 close(wai->appSocket);
117 wai->appSocket = -1;
118 return -1;
120 #endif
122 memset(&addr, 0, sizeof(struct sockaddr_in));
123 addr.sin_family = AF_INET;
124 addr.sin_addr.s_addr = INADDR_ANY;
125 addr.sin_port = htons(EAPD_WKSP_WAI_UDP_RPORT);
126 if (bind(wai->appSocket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
127 EAPD_ERROR("UDP Bind failed, close wai appSocket %d\n", wai->appSocket);
128 close(wai->appSocket);
129 wai->appSocket = -1;
130 return -1;
132 EAPD_INFO("WAI appSocket %d opened\n", wai->appSocket);
134 return 0;
138 wai_app_deinit(eapd_wksp_t *nwksp)
140 eapd_wai_t *wai;
141 eapd_cb_t *cb, *tmp_cb;
143 if (nwksp == NULL) {
144 EAPD_ERROR("Wrong argument...\n");
145 return -1;
148 wai = &nwksp->wai;
149 cb = wai->cb;
150 while (cb) {
151 /* close brcm drvSocket */
152 if (cb->brcmSocket) {
153 EAPD_INFO("close wai brcmSocket %d\n", cb->brcmSocket->drvSocket);
154 eapd_del_brcm(nwksp, cb->brcmSocket);
157 tmp_cb = cb;
158 cb = cb->next;
159 free(tmp_cb);
162 /* close appSocke */
163 if (wai->appSocket >= 0) {
164 EAPD_INFO("close wai appSocket %d\n", wai->appSocket);
165 close(wai->appSocket);
166 wai->appSocket = -1;
169 return 0;
172 /* wai_sendup will send wai and brcm packet */
174 wai_app_sendup(eapd_wksp_t *nwksp, uint8 *pData, int pLen, char *from)
176 eapd_wai_t *wai;
178 if (nwksp == NULL) {
179 EAPD_ERROR("Wrong argument...\n");
180 return -1;
183 wai = &nwksp->wai;
184 if (wai->appSocket >= 0) {
185 /* send to wai */
186 int sentBytes = 0;
187 struct sockaddr_in to;
189 to.sin_addr.s_addr = inet_addr(EAPD_WKSP_UDP_ADDR);
190 to.sin_family = AF_INET;
191 to.sin_port = htons(EAPD_WKSP_WAI_UDP_SPORT);
193 sentBytes = sendto(wai->appSocket, pData, pLen, 0,
194 (struct sockaddr *)&to, sizeof(struct sockaddr_in));
196 if (sentBytes != pLen) {
197 EAPD_ERROR("UDP send failed; sentBytes = %d\n", sentBytes);
199 else {
200 /* EAPD_INFO("Send %d bytes to wai\n", sentBytes); */
203 else {
204 EAPD_ERROR("wai appSocket not created\n");
206 return 0;
209 #if EAPD_WKSP_AUTO_CONFIG
211 wai_app_enabled(char *name)
213 char value[128], comb[32], akm[16], prefix[8];
214 char akms[128], os_name[IFNAMSIZ];
215 char *akmnext;
216 uint wapid;
217 int unit;
219 memset(os_name, 0, sizeof(os_name));
221 if (nvifname_to_osifname(name, os_name, sizeof(os_name)))
222 return 0;
223 if (wl_probe(os_name) ||
224 wl_ioctl(os_name, WLC_GET_INSTANCE, &unit, sizeof(unit)))
225 return 0;
226 if (osifname_to_nvifname(name, prefix, sizeof(prefix)))
227 return 0;
229 strcat(prefix, "_");
230 /* ignore if disabled */
231 eapd_safe_get_conf(value, sizeof(value), strcat_r(prefix, "radio", comb));
232 if (atoi(value) == 0) {
233 EAPD_INFO("WAI:ignored interface %s. radio disabled\n", os_name);
234 return 0;
236 /* ignore shared */
237 eapd_safe_get_conf(value, sizeof(value), strcat_r(prefix, "auth", comb));
238 if (atoi(value) == 1) {
239 EAPD_INFO("WAI: ignored interface %s. Shared 802.11 auth\n", os_name);
240 return 0;
242 /* ignore if BSS is disabled */
243 eapd_safe_get_conf(value, sizeof(value), strcat_r(prefix, "bss_enabled", comb));
244 if (atoi(value) == 0) {
245 EAPD_INFO("WAI: ignored interface %s, %s is disabled \n", os_name, comb);
246 return 0;
248 /* wai mode */
249 wapid = 0;
250 eapd_safe_get_conf(akms, sizeof(akms), strcat_r(prefix, "akm", comb));
251 foreach(akm, akms, akmnext) {
252 if (!strcmp(akm, "wapi"))
253 wapid |= AUTH_MODE_WAPI;
254 if (!strcmp(akm, "wapi_psk"))
255 wapid |= AUTH_MODE_WAPI_PSK;
257 if (!wapid) {
258 EAPD_INFO("WAI:ignored interface %s. Invalid WAI mode\n", os_name);
259 return 0;
262 /* if come to here return enabled */
263 return 1;
265 #endif /* EAPD_WKSP_AUTO_CONFIG */
268 wai_app_handle_event(eapd_wksp_t *nwksp, uint8 *pData, int Len, char *from)
270 int type;
271 eapd_wai_t *wai;
272 eapd_cb_t *cb;
273 bcm_event_t *dpkt = (bcm_event_t *) pData;
274 wl_event_msg_t *event;
276 event = &(dpkt->event);
277 type = ntohl(event->event_type);
279 wai = &nwksp->wai;
280 cb = wai->cb;
281 while (cb) {
282 if (isset(wai->bitvec, type) && !strcmp(cb->ifname, from)) {
283 /* prepend ifname, we reserved IFNAMSIZ length already */
284 pData -= IFNAMSIZ;
285 Len += IFNAMSIZ;
286 memcpy(pData, event->ifname, IFNAMSIZ);
288 /* send to wai use cb->ifname */
289 wai_app_sendup(nwksp, pData, Len, cb->ifname);
290 break;
292 cb = cb->next;
295 return 0;