K2.6 patches and update.
[tomato.git] / release / src-rt / wl / nas / nas_wl.c
blobabd93941b83728f4acfa1384552197eed34fb37e
1 /*
2 * Broadcom 802.11 device interface
4 * Copyright (C) 2010, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
8 * the contents of this file may not be disclosed to third parties, copied
9 * or duplicated in any form, in whole or in part, without the prior
10 * written permission of Broadcom Corporation.
12 * $Id: nas_wl.c 248185 2011-03-23 06:37:49Z simonk $
15 #include <typedefs.h>
16 #include <unistd.h>
17 #include <string.h>
19 #include <bcmutils.h>
20 #include <wlutils.h>
21 #include <wlioctl.h>
23 #include <nas.h>
25 int
26 nas_authorize(nas_t *nas, struct ether_addr *ea)
28 return wl_ioctl(nas->interface, WLC_SCB_AUTHORIZE, ea, ETHER_ADDR_LEN);
31 int
32 nas_deauthorize(nas_t *nas, struct ether_addr *ea)
34 return wl_ioctl(nas->interface, WLC_SCB_DEAUTHORIZE, ea, ETHER_ADDR_LEN);
37 int
38 nas_deauthenticate(nas_t *nas, struct ether_addr *ea, int reason)
40 scb_val_t scb_val;
42 /* remove the key if one is installed */
43 nas_set_key(nas, ea, NULL, 0, 0, 0, 0, 0);
44 scb_val.val = (uint32) reason;
45 memcpy(&scb_val.ea, ea, ETHER_ADDR_LEN);
46 return wl_ioctl(nas->interface, WLC_SCB_DEAUTHENTICATE_FOR_REASON,
47 &scb_val, sizeof(scb_val));
50 int
51 nas_get_group_rsc(nas_t *nas, uint8 *buf, int index)
53 union {
54 int index;
55 uint8 rsc[EAPOL_WPA_KEY_RSC_LEN];
56 } u;
58 u.index = index;
59 if (wl_ioctl(nas->interface, WLC_GET_KEY_SEQ, &u, sizeof(u)) != 0)
60 return -1;
62 bcopy(u.rsc, buf, EAPOL_WPA_KEY_RSC_LEN);
64 return 0;
67 int
68 nas_set_key(nas_t *nas, struct ether_addr *ea, uint8 *key, int len, int index,
69 int tx, uint32 hi, uint16 lo)
71 wl_wsec_key_t wep;
72 #ifdef BCMDBG
73 char eabuf[ETHER_ADDR_STR_LEN];
74 #endif
75 char ki[] = "index XXXXXXXXXXX";
77 memset(&wep, 0, sizeof(wep));
78 wep.index = index;
79 if (ea)
80 memcpy(&wep.ea, ea, ETHER_ADDR_LEN);
81 else {
82 wep.flags = tx ? WL_PRIMARY_KEY : 0;
83 snprintf(ki, sizeof(ki), "index %d", index);
86 wep.len = len;
87 if (len)
88 memcpy(wep.data, key, MIN(len, DOT11_MAX_KEY_SIZE));
89 dbg(nas, "%s, flags %x, len %d",
90 ea ? (char *)ether_etoa((uchar *)ea, eabuf) : ki,
91 wep.flags, wep.len);
92 if (lo || hi) {
93 wep.rxiv.hi = hi;
94 wep.rxiv.lo = lo;
95 wep.iv_initialized = 1;
97 return wl_ioctl(nas->interface, WLC_SET_KEY, &wep, sizeof(wep));
101 nas_wl_tkip_countermeasures(nas_t *nas, int enable)
103 return wl_ioctl(nas->interface, WLC_TKIP_COUNTERMEASURES, &enable, sizeof(int));
107 nas_set_ssid(nas_t *nas, char *ssid)
109 wlc_ssid_t wl_ssid;
111 strncpy((char *)wl_ssid.SSID, ssid, sizeof(wl_ssid.SSID));
112 wl_ssid.SSID_len = strlen(ssid);
113 return wl_ioctl(nas->interface, WLC_SET_SSID, &wl_ssid, sizeof(wl_ssid));
117 nas_disassoc(nas_t *nas)
119 return wl_ioctl(nas->interface, WLC_DISASSOC, NULL, 0);
122 /* get WPA capabilities */
124 nas_get_wpacap(nas_t *nas, uint8 *cap)
126 int err;
127 int cap_val;
129 err = wl_iovar_getint(nas->interface, "wpa_cap", &cap_val);
130 if (!err) {
131 cap[0] = (cap_val & 0xff);
132 cap[1] = ((cap_val >> 8) & 0xff);
135 return err;
138 /* get STA info */
140 nas_get_stainfo(nas_t *nas, char *macaddr, int len, char *ret_buf, int ret_buf_len)
142 char *tmp_ptr;
144 tmp_ptr = ret_buf;
145 strcpy(ret_buf, "sta_info");
146 tmp_ptr += strlen(ret_buf);
147 tmp_ptr++;
148 memcpy(tmp_ptr, macaddr, len);
150 return wl_ioctl(nas->interface, WLC_GET_VAR, ret_buf, ret_buf_len);
154 nas_get_wpa_ie(nas_t *nas, char *ret_buf, int ret_buf_len, uint32 sta_mode)
156 int err, wpa_len = 0, ie_len = 0;
157 char buf[WLC_IOCTL_SMLEN];
158 bcm_tlv_t *ie_getbuf;
159 char *buf_ptr;
160 int i;
162 if (ret_buf == NULL)
163 return 0;
165 memset(buf, 0, sizeof(buf));
167 err = wl_iovar_getbuf(nas->interface, "wpaie", &nas->ea, 6, buf, sizeof(buf));
168 if (err != 0)
169 return 0;
171 buf_ptr = buf;
172 for (i = 0; i < 2; i++) {
173 ie_getbuf = (bcm_tlv_t *)buf_ptr;
174 wpa_len = ie_getbuf->len;
175 if (wpa_len == 0)
176 break;
178 if (ie_getbuf->id == DOT11_MNG_RSN_ID) {
179 dbg(nas, "found RSN IE of length %d\n", wpa_len);
180 if (sta_mode == WPA || sta_mode == WPA_PSK) {
181 buf_ptr += wpa_len + TLV_HDR_LEN;
182 continue;
185 else if (ie_getbuf->id != DOT11_MNG_RSN_ID) {
186 dbg(nas, "found WPA IE of length %d\n", wpa_len);
187 if (sta_mode == WPA2 || sta_mode == WPA2_PSK) {
188 buf_ptr += wpa_len + TLV_HDR_LEN;
189 continue;
193 ie_len = wpa_len + TLV_HDR_LEN;
194 /* Got WPA ie */
195 if (ie_len <= ret_buf_len) {
196 memcpy(ret_buf, buf_ptr, wpa_len + TLV_HDR_LEN);
197 printf("return %d bytes ie\n", ie_len);
198 return ie_len;
200 else {
201 dbg(nas, "Not enough buffer (%d) to copy %d bytes wpa ie\n",
202 ret_buf_len, ie_len);
203 return 0;
207 return 0;