K2.6 patches and update.
[tomato.git] / release / src-rt / wl / eapd / eapd_ecos.c
blobdee5638828541547dda109c3e35ecfabb0b8738d
1 /*
2 * Ecos-specific portion of EAPD
3 * (OS dependent file)
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: eapd_ecos.c 241391 2011-02-18 03:35:48Z stakita $
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <typedefs.h>
19 #include <unistd.h>
20 #include <ecos_oslib.h>
21 #include <proto/ethernet.h>
22 #include <proto/eapol.h>
23 #include <sys/socket.h>
24 #include <net/if.h>
25 #include <netinet/in.h>
26 #include <cyg/io/file.h>
27 #include <netinet/ip.h>
28 #include <netinet/udp.h>
29 #include <proto/eap.h>
30 #include <bcmnvram.h>
31 #include <eapd.h>
33 static eapd_wksp_t *eapd_nwksp = NULL;
35 static cyg_handle_t eapd_main_hdl;
36 static char eapd_main_stack[8*1024];
37 static cyg_thread eapd_thread;
38 static int _eapd_pid = 0;
40 static void
41 eapd_hup_hdlr(int sig)
43 if (eapd_nwksp)
44 eapd_nwksp->flags |= EAPD_WKSP_FLAG_SHUTDOWN;
46 return;
49 void
50 eapd_dump_hdlr(int sig)
52 if (eapd_nwksp)
53 eapd_nwksp->flags |= EAPD_WKSP_FLAG_DUMP;
55 return;
58 /* Send a canned EAPOL packet */
59 void
60 eapd_eapol_canned_send(eapd_wksp_t *nwksp, struct eapd_socket *Socket, eapd_sta_t *sta,
61 unsigned char code, unsigned char type)
63 eapol_header_t eapol;
64 eap_header_t eap;
65 int len;
66 char *packet;
67 char *ptr;
69 memcpy(&eapol.eth.ether_dhost, &sta->ea, ETHER_ADDR_LEN);
70 memcpy(&eapol.eth.ether_shost, &sta->bssid, ETHER_ADDR_LEN);
72 eapol.eth.ether_type = htons(ETHER_TYPE_802_1X);
73 eapol.version = sta->eapol_version;
74 eapol.type = EAP_PACKET;
75 /* With type, eap.type is used. So, the legnth will be 4+1 */
76 len = type ? (EAP_HEADER_LEN + 1) : EAP_HEADER_LEN;
77 eapol.length = htons(len);
79 eap.code = code;
80 eap.id = sta->pae_id;
81 eap.length = eapol.length;
83 /* This is optional, if type is 0, this field won't be used. */
84 eap.type = type;
86 /* Allocate a buffer to send ? */
87 packet = (char *)malloc(EAPOL_HEADER_LEN + len);
88 if (packet == NULL)
89 return;
91 ptr = packet;
92 memcpy(ptr, &eapol, EAPOL_HEADER_LEN);
94 ptr += EAPOL_HEADER_LEN;
95 memcpy(ptr, &eap, len);
97 /* Write to device */
98 write(Socket->drvSocket, packet, len + EAPOL_HEADER_LEN);
100 free(packet);
101 return;
104 void
105 eapd_message_send(eapd_wksp_t *nwksp, struct eapd_socket *Socket, uint8 *pData, int pLen)
107 /* We should handle fragment here */
108 write(Socket->drvSocket, pData, pLen);
112 eapd_brcm_open(eapd_wksp_t *nwksp, eapd_brcm_socket_t *sock)
114 char devname[32];
116 if (nwksp == NULL || sock == NULL) {
117 EAPD_ERROR("Wrong arguments...\n");
118 return -1;
121 sprintf(devname, "/dev/net/eapol/%s/%d", sock->ifname, ETHER_TYPE_BRCM);
122 sock->drvSocket = open(devname, O_RDWR);
123 if (sock->drvSocket < 0) {
124 EAPD_ERROR("open socket error!!\n");
125 return -1;
128 /* at least one use it */
129 sock->inuseCount = 1;
131 EAPD_INFO("%s: BRCM socket %d opened\n", sock->ifname, sock->drvSocket);
133 return 0;
137 eapd_brcm_close(int drvSocket)
139 close(drvSocket);
140 return 0;
143 #ifdef BCMWPA2
145 eapd_preauth_open(eapd_wksp_t *nwksp, eapd_preauth_socket_t *sock)
147 char devname[32];
149 if (nwksp == NULL || sock == NULL) {
150 EAPD_ERROR("Wrong arguments...\n");
151 return -1;
154 sprintf(devname, "/dev/net/eapol/%s/%d", sock->ifname, ETHER_TYPE_802_1X_PREAUTH);
155 sock->drvSocket = open(devname, O_RDWR);
156 if (sock->drvSocket < 0) {
157 EAPD_ERROR("open socket error!!\n");
158 return -1;
161 /* at least one use it */
162 sock->inuseCount = 1;
164 EAPD_INFO("%s: preauth socket %d opened\n", sock->ifname, sock->drvSocket);
166 return 0;
170 eapd_preauth_close(int drvSocket)
172 close(drvSocket);
173 return 0;
175 #endif /* BCMWPA2 */
178 * Configuration APIs
180 int eapd_safe_get_conf(char *outval, int outval_size, char *name)
182 char *val;
184 if (name == NULL || outval == NULL) {
185 if (outval)
186 memset(outval, 0, outval_size);
187 return -1;
190 val = nvram_safe_get(name);
191 if (!strcmp(val, ""))
192 memset(outval, 0, outval_size);
193 else
194 snprintf(outval, outval_size, "%s", val);
195 return 0;
198 int eapd_main(void)
200 #ifdef BCMDBG
201 char *dbg;
203 /* get eapd_msg_level from nvram */
204 if ((dbg = nvram_safe_get("eapd_dbg"))) {
205 eapd_msg_level = (uint)strtoul(dbg, NULL, 0);
207 #endif /* BCMDBG */
209 EAPD_INFO("EAP Dispatch Start...\n");
211 /* fill up EAPD task pid */
212 _eapd_pid = oslib_pid();
214 /* alloc eapd work space */
215 if (!(eapd_nwksp = eapd_wksp_alloc_workspace())) {
216 EAPD_ERROR("Unable to allocate wksp memory. Quitting...\n");
217 return -1;
220 if (eapd_wksp_auto_config(eapd_nwksp)) {
221 EAPD_ERROR("Unable to auto config. Quitting...\n");
222 eapd_wksp_cleanup(eapd_nwksp);
223 return -1;
226 /* run main loop to dispatch messages */
227 eapd_wksp_main_loop(eapd_nwksp);
229 return 0;
232 void
233 eapd_start(void)
235 if (!_eapd_pid ||
236 !oslib_waitpid(_eapd_pid, NULL)) {
237 cyg_thread_create(7,
238 (cyg_thread_entry_t *)eapd_main,
239 (cyg_addrword_t)NULL,
240 "EAPD",
241 eapd_main_stack,
242 sizeof(eapd_main_stack),
243 &eapd_main_hdl,
244 &eapd_thread);
245 cyg_thread_resume(eapd_main_hdl);
246 EAPD_PRINT("EAPD task started\n");
250 void
251 eapd_stop(void)
253 if (_eapd_pid) {
254 /* set stop flag */
255 eapd_hup_hdlr(0);
257 /* wait till the eapd_main task is dead */
258 while (oslib_waitpid(_eapd_pid, NULL))
259 cyg_thread_delay(10);
260 _eapd_pid = 0;
261 EAPD_PRINT("EAPD task stopped\n");