K2.6 patches and update.
[tomato.git] / release / src-rt / wl / nas / nas_rte.c
blobdd8fc83d83032f7840d68ff4043f0448844f81c6
1 /* Network Authentication Service deamon (RTE)
3 * Copyright (C) 2010, Broadcom Corporation
4 * All Rights Reserved.
5 *
6 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
7 * the contents of this file may not be disclosed to third parties, copied
8 * or duplicated in any form, in whole or in part, without the prior
9 * written permission of Broadcom Corporation.
11 * $Id: nas_rte.c 241388 2011-02-18 03:33:22Z stakita $
15 #include <typedefs.h>
16 #include <time.h>
17 #include <osl.h>
18 #include <hndrte.h>
19 #include <wlutils.h>
20 #include <assert.h>
22 #include <bcmcrypto/md5.h>
24 #include <relay_rte.h>
26 #include "nas_wksp.h"
28 /* RTE Layer 2 protocol handlers */
29 /* WPA */
30 static bool wpa_recv(hndrte_dev_t *dev, void *ctx, struct lbuf *lb, uint16 ethtype);
31 static ethtype_handler_t wpa_handler = {NULL, ETHER_TYPE_BRCM, wpa_recv, };
33 extern void bsp_reboot(void);
35 hndrte_dev_t *wldev;
36 int naswl_sendpkt(struct lbuf *lbf);
39 void nas_sleep_ms(uint ms);
40 void nas_rand128(uint8 *rand128);
41 void nas_reset_board(void);
42 static int nas_get_wlrand(char *ifname, uint16 *val);
43 int nas_init(int argc, char *argv[]);
44 void nasStart(char *type);
47 /* Might be better to put this somewhere else, this doesn't have to be NAS
48 * specific - it's implementing POSIX-like functionality
50 time_t
51 time(time_t *t)
53 if (!t)
54 return 0;
56 *t = hndrte_time();
57 return *t;
60 /* Might be better to put this somewhere else, this doesn't have to be NAS
61 * specific - it's implementing POSIX-like functionality
63 int
64 gettimeofday(struct timeval *tv, struct timezone *tz)
66 uint32 milliseconds = hndrte_time();
68 memset(tz, 0, sizeof(struct timezone));
69 memset(tv, 0, sizeof(struct timeval));
71 tv->tv_sec = milliseconds / 1000;
73 return 0;
77 int
78 naswl_sendpkt(struct lbuf *lbf)
80 return wldev->dev_funcs->xmit(NULL, wldev, lbf);
84 void
85 nas_sleep_ms(uint ms)
87 hndrte_delay(ms*1000);
90 static int
91 nas_get_wlrand(char *ifname, uint16 *val)
93 char buf[WLC_IOCTL_SMLEN];
94 int ret;
96 strcpy(buf, "rand");
97 if ((ret = wl_ioctl(ifname, WLC_GET_VAR, buf, sizeof(buf))))
98 return ret;
100 *val = *(uint16 *)buf;
101 return 0;
104 void
105 nas_rand128(uint8 *rand128)
107 struct timeval tv;
108 struct timezone tz;
109 uint16 rand_val;
110 MD5_CTX md5;
112 gettimeofday(&tv, &tz);
114 if (nas_get_wlrand("wl0", &rand_val) == 0)
115 tv.tv_sec ^= rand_val;
116 else
117 NASDBG("NAS - nas_rad128 couldn't get random number from WL!!!\n");
118 MD5Init(&md5);
119 MD5Update(&md5, (unsigned char *) &tv, sizeof(tv));
120 MD5Update(&md5, (unsigned char *) &tz, sizeof(tz));
121 MD5Final(rand128, &md5);
124 /* establish connection to receive wpa message */
126 nas_wksp_open_wpa(nas_wksp_t *nwksp)
128 /* set the context for this handler to use */
129 wpa_handler.ctx = nwksp;
131 /* Register with the relay to receive for packets */
132 bcmrelay.dev_funcs->ioctl(&bcmrelay, RELAY_PROTOREGISTER,
133 &wpa_handler,
134 sizeof(ethtype_handler_t *), NULL, NULL, 0);
136 NASDBG("%s: registered with relay for wpa messages\n", nwksp->lan);
137 return 0;
140 static bool
141 wpa_recv(hndrte_dev_t *dev, void *ctx, struct lbuf *lb, uint16 ethtype)
143 uint8 *pkt = lb->data;
144 int len = lb->len;
145 nas_wksp_t *nwksp = (nas_wksp_t *)ctx;
146 nas_wpa_cb_t *nwcb;
147 bcm_event_t *pvt_data = (bcm_event_t *)pkt;
149 /* recv wpa message from relay */
150 /* validate the recv packet */
151 if (nas_validate_wlpvt_message(len, pkt) != 0) {
152 goto error0;
154 pvt_data = (bcm_event_t *)pkt;
156 nwcb = nas_wksp_find_nwcb_by_mac(nwksp, pvt_data->eth.ether_dhost,
157 pvt_data->event.ifname);
159 if (nwcb && !(nwcb->flags & NAS_WPA_CB_FLAG_ERROR))
160 nas_handle_wlpvt_messages(nwcb, (void *)pvt_data, len, 1);
162 lb_free(lb);
163 return TRUE;
165 error0:
166 /* way to say not our message */
167 NASDBG("Not a WPA NAS packet, returning pkt to relay 0x%p\n", lb);
168 return FALSE;
171 /* transmit preauth message thru the relay */
173 nas_preauth_send_packet(nas_t *nas, struct iovec *frags, int nfrags)
175 printf("\nUnsupported - nas_preauth_send_packet\n\n");
176 return 1;
180 /* open connections to network to receive/send eapol packets */
182 nas_wksp_open_eapol(nas_wksp_t *nwksp)
184 /* not needed for HNDRTE - all EAPOL messages are
185 * encapsulated in BRCM ethertype from wl
187 return 0;
190 /* send eapol packet out to the net */
192 nas_eapol_send_packet(nas_t *nas, struct iovec *frags, int nfrags)
194 struct lbuf *lbf;
195 int i, count;
196 uchar *buf;
198 /* Convert iov to mbuf chain */
199 if (nfrags > 1)
201 for (i = 0, count = 0; i < nfrags; i++)
202 count += frags[i].iov_len;
203 if (!(lbf = lb_alloc(count, __FILE__, __LINE__)))
205 NASDBG("%s: lb_alloc error\n", nas->interface);
206 return 1;
208 buf = lbf->data;
209 for (i = 0, count = 0; i < nfrags; i++)
211 memcpy(&buf[count], frags[i].iov_base, frags[i].iov_len);
212 count += frags[i].iov_len;
215 else if (nfrags == 1)
217 lbf = lb_alloc(frags[0].iov_len, __FILE__, __LINE__);
218 memcpy(lbf->data, frags[0].iov_base, frags[0].iov_len);
219 NASDBG("%s: nfrags = 1 and Length of Message %d\n",
220 nas->interface, frags[0].iov_len);
222 else
224 NASDBG("%s: nfrags == 0 error\n", nas->interface);
225 return 1;
227 if (!lbf)
229 NASDBG("%s: failed to allocate mblk\n", nas->interface);
230 return 1;
233 /* send packet to network thru the interface */
234 return naswl_sendpkt(lbf);
237 void
238 nas_reset_board(void)
240 bsp_reboot();
241 return;
244 /* nas task entry */
246 nas_init(int argc, char *argv[])
248 nas_wksp_t *nwksp = NULL;
250 /* alloc nas/wpa work space */
251 if (!(nwksp = nas_wksp_alloc_workspace())) {
252 NASMSG("Unable to allocate memory. Quitting...\n");
253 goto exit0;
256 /* init nas/wpa work space */
257 if (nas_wksp_parse_cmd_line(argc, argv, nwksp)) {
258 NASMSG("Command line parsing error. Quitting...\n");
259 goto exit1;
261 if (!nwksp->nwcbs) {
262 NASMSG("No interface specified. Quitting...\n");
263 goto exit1;
266 /* init nas */
267 if (nas_wksp_init(nwksp)) {
268 NASMSG("Unable to initialize NAS. Quitting...\n");
269 goto exit1;
271 goto exit0;
273 /* error handling */
274 exit1:
275 nas_wksp_free_workspace(nwksp);
276 exit0:
277 return 0;
280 void
281 nasStart(char *type)
283 static char *nas_argv[NAS_WKSP_MAX_CMD_LINE_ARGS];
284 int nas_argc = NAS_WKSP_MAX_CMD_LINE_ARGS;
286 wldev = hndrte_get_dev("wl0");
288 if (nas_wksp_build_cmd_line(type, NULL, &nas_argc, nas_argv))
289 NASDBG("NAS error - couldn't build command line.\n");
290 else if (nas_init(nas_argc, nas_argv) != 0)
291 NASDBG("NAS error - init failed.\n");
293 return;