parent
4a9fd58443
commit
d71c0bca30
@ -1,642 +0,0 @@ |
||||
/*
|
||||
* no license, extracted from wag54gv2-AU_v1.00.39 GPL |
||||
*
|
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <assert.h> |
||||
|
||||
#include <typedefs.h> |
||||
#include <bcmnvram.h> |
||||
#include <bcmutils.h> |
||||
#include <shutils.h> |
||||
#include <wlutils.h> |
||||
|
||||
/* phy types */ |
||||
#define PHY_TYPE_A 0 |
||||
#define PHY_TYPE_B 1 |
||||
#define PHY_TYPE_G 2 |
||||
#define PHY_TYPE_NULL 0xf |
||||
|
||||
/* parts of an idcode: */ |
||||
#define IDCODE_MFG_MASK 0x00000fff |
||||
#define IDCODE_MFG_SHIFT 0 |
||||
#define IDCODE_ID_MASK 0x0ffff000 |
||||
#define IDCODE_ID_SHIFT 12 |
||||
#define IDCODE_REV_MASK 0xf0000000 |
||||
#define IDCODE_REV_SHIFT 28 |
||||
|
||||
#define WL_IOCTL(name, cmd, buf, len) ((void) wl_ioctl((name), (cmd), (buf), (len))) |
||||
|
||||
/* set WEP key */ |
||||
static int |
||||
wlconf_set_wep_key(char *name, char *prefix, int i) |
||||
{ |
||||
wsec_key_t key; |
||||
char wl_key[] = "wlXXXXXXXXXX_keyXXXXXXXXXX"; |
||||
char *keystr, hex[] = "XX"; |
||||
unsigned char *data = key.data; |
||||
int ret = 0; |
||||
|
||||
memset(&key, 0, sizeof(key)); |
||||
key.index = i - 1; |
||||
sprintf(wl_key, "%skey%d", prefix, i); |
||||
keystr = nvram_safe_get(wl_key); |
||||
|
||||
switch (strlen(keystr)) { |
||||
case WEP1_KEY_SIZE: |
||||
case WEP128_KEY_SIZE: |
||||
key.len = strlen(keystr); |
||||
strcpy(key.data, keystr); |
||||
break; |
||||
case WEP1_KEY_HEX_SIZE: |
||||
case WEP128_KEY_HEX_SIZE: |
||||
key.len = strlen(keystr) / 2; |
||||
while (*keystr) { |
||||
strncpy(hex, keystr, 2); |
||||
*data++ = (unsigned char) strtoul(hex, NULL, 16); |
||||
keystr += 2; |
||||
} |
||||
break; |
||||
default: |
||||
key.len = 0; |
||||
break; |
||||
} |
||||
|
||||
/* Set current WEP key */ |
||||
if (key.len && i == atoi(nvram_safe_get(strcat_r(prefix, "key", wl_key)))) |
||||
key.flags = WSEC_PRIMARY_KEY; |
||||
|
||||
WL_IOCTL(name, WLC_SET_KEY, &key, sizeof(key)); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
extern struct nvram_tuple router_defaults[]; |
||||
|
||||
/* Keep this table in order */ |
||||
static struct { |
||||
int locale; |
||||
char **names; |
||||
char *abbr; |
||||
} countries[] = { |
||||
{ WLC_WW, ((char *[]) { "Worldwide", "WW", NULL }), "AU" }, |
||||
{ WLC_THA, ((char *[]) { "Thailand", "THA", NULL }), "TH" }, |
||||
{ WLC_ISR, ((char *[]) { "Israel", "ISR", NULL }), "IL" }, |
||||
{ WLC_JDN, ((char *[]) { "Jordan", "JDN", NULL }), "JO" }, |
||||
{ WLC_PRC, ((char *[]) { "China", "P.R. China", "PRC", NULL }), "CN" }, |
||||
{ WLC_JPN, ((char *[]) { "Japan", "JPN", NULL }), "JP" }, |
||||
{ WLC_FCC, ((char *[]) { "USA", "Canada", "ANZ", "New Zealand", "FCC", NULL }), "US" }, |
||||
{ WLC_EUR, ((char *[]) { "Europe", "EUR", NULL }), "DE" }, |
||||
{ WLC_USL, ((char *[]) { "USA Low", "USALow", "USL", NULL }), "US" }, |
||||
{ WLC_JPH, ((char *[]) { "Japan High", "JapanHigh", "JPH", NULL }), "JP" }, |
||||
{ WLC_ALL, ((char *[]) { "All", "AllTheChannels", NULL }), "All" }, |
||||
}; |
||||
|
||||
/* validate/restore all per-interface related variables */ |
||||
static void |
||||
wlconf_validate_all(char *prefix, bool restore) |
||||
{ |
||||
struct nvram_tuple *t; |
||||
char tmp[100]; |
||||
char *v; |
||||
for (t = router_defaults; t->name; t++) { |
||||
if (!strncmp(t->name, "wl_", 3)) { |
||||
strcat_r(prefix, &t->name[3], tmp); |
||||
if (!restore && nvram_get(tmp)) |
||||
continue; |
||||
v = nvram_get(t->name); |
||||
nvram_set(tmp, v ? v : t->value); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* restore specific per-interface variable */ |
||||
static void |
||||
wlconf_restore_var(char *prefix, char *name) |
||||
{ |
||||
struct nvram_tuple *t; |
||||
char tmp[100]; |
||||
for (t = router_defaults; t->name; t++) { |
||||
if (!strncmp(t->name, "wl_", 3) && !strcmp(&t->name[3], name)) { |
||||
nvram_set(strcat_r(prefix, name, tmp), t->value); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* Set up wsec */ |
||||
static int |
||||
wlconf_set_wsec(char *ifname, char *prefix) |
||||
{ |
||||
char tmp[100]; |
||||
int val; |
||||
strcat_r(prefix, "wep", tmp); |
||||
if (nvram_match(tmp, "wep") || nvram_match(tmp, "on") || nvram_match(tmp, "restricted")) |
||||
val = WEP_ENABLED; |
||||
else if (nvram_match(tmp, "tkip")) |
||||
val = TKIP_ENABLED; |
||||
else if (nvram_match(tmp, "aes")) |
||||
val = AES_ENABLED; |
||||
else if (nvram_match(tmp, "tkip+aes")) |
||||
val = TKIP_ENABLED | AES_ENABLED; |
||||
else |
||||
val = 0; |
||||
return wl_ioctl(ifname, WLC_SET_WSEC, &val, sizeof(val)); |
||||
} |
||||
|
||||
/*
|
||||
* For debugging only |
||||
*/ |
||||
#define WLCONF_DBG(fmt, arg...) |
||||
|
||||
#if defined(linux) |
||||
#include <unistd.h> |
||||
static void |
||||
sleep_ms(const unsigned int ms) |
||||
{ |
||||
usleep(1000*ms); |
||||
} |
||||
#endif |
||||
|
||||
/*
|
||||
* The following condition(s) must be met when Auto Channel Selection
|
||||
* is enabled. |
||||
* - the I/F is up (change radio channel requires it is up?) |
||||
* - the AP must not be associated (setting SSID to empty should
|
||||
* make sure it for us) |
||||
*/ |
||||
static uint8 |
||||
wlconf_auto_channel(char *name) |
||||
{ |
||||
int chosen = 0; |
||||
wl_uint32_list_t request; |
||||
int phytype; |
||||
/* query the phy type */ |
||||
wl_ioctl(name, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)); |
||||
request.count = 0; /* let the ioctl decide */ |
||||
if (!wl_ioctl(name, WLC_START_CHANNEL_SEL, &request, sizeof(request))) { |
||||
sleep_ms(phytype == PHY_TYPE_A ? 1000 : 750); |
||||
while (wl_ioctl(name, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen))) |
||||
sleep_ms(100); |
||||
} |
||||
WLCONF_DBG("interface %s: channel selected %d\n", name, chosen); |
||||
return chosen; |
||||
} |
||||
|
||||
/* PHY type/BAND conversion */ |
||||
#define WLCONF_PHYTYPE2BAND(phy) ((phy) == PHY_TYPE_A ? WLC_BAND_A : WLC_BAND_B) |
||||
/* PHY type conversion */ |
||||
#define WLCONF_PHYTYPE2STR(phy) ((phy) == PHY_TYPE_A ? "a" : \ |
||||
(phy) == PHY_TYPE_B ? "b" : "g") |
||||
#define WLCONF_STR2PHYTYPE(phy) ((phy) && (phy)[0] == 'a' ? PHY_TYPE_A : \ |
||||
(phy) && (phy)[0] == 'b' ? PHY_TYPE_B : PHY_TYPE_G) |
||||
|
||||
/* configure the specified wireless interface */ |
||||
int |
||||
wlconf(char *name) |
||||
{ |
||||
int restore_defaults, val, unit, phytype, gmode = 0, ret = 0; |
||||
char tmp[100], prefix[] = "wlXXXXXXXXXX_"; |
||||
char var[80], *next, phy[] = "a", *str; |
||||
unsigned char buf[WLC_IOCTL_MAXLEN]; |
||||
char *country; |
||||
wlc_rev_info_t rev; |
||||
channel_info_t ci; |
||||
struct maclist *maclist; |
||||
struct ether_addr *ea; |
||||
wlc_ssid_t ssid; |
||||
wl_rateset_t rs; |
||||
unsigned int i; |
||||
char eaddr[32]; |
||||
int ap, sta = 0, wet = 0; |
||||
char country_code[4]; |
||||
|
||||
/* Check interface (fail silently for non-wl interfaces) */ |
||||
if ((ret = wl_probe(name))) |
||||
return ret; |
||||
|
||||
/* Get MAC address */ |
||||
(void) wl_hwaddr(name, buf); |
||||
|
||||
/* Get instance */ |
||||
WL_IOCTL(name, WLC_GET_INSTANCE, &unit, sizeof(unit)); |
||||
snprintf(prefix, sizeof(prefix), "wl%d_", unit); |
||||
|
||||
/* Restore defaults if per-interface parameters do not exist */ |
||||
restore_defaults = !nvram_get(strcat_r(prefix, "ifname", tmp)); |
||||
wlconf_validate_all(prefix, restore_defaults); |
||||
nvram_set(strcat_r(prefix, "ifname", tmp), name); |
||||
nvram_set(strcat_r(prefix, "hwaddr", tmp), ether_etoa(buf, eaddr)); |
||||
snprintf(buf, sizeof(buf), "%d", unit); |
||||
nvram_set(strcat_r(prefix, "unit", tmp), buf); |
||||
|
||||
/*
|
||||
* Nuke SSID first so that the AP won't be associated when WLC_UP. |
||||
* This must be done here if Auto Channel Selection is enabled. |
||||
*/ |
||||
WL_IOCTL(name, WLC_GET_UP, &val, sizeof(val)); |
||||
if (val) { |
||||
/* Nuke SSID */ |
||||
ssid.SSID_len = 0; |
||||
ssid.SSID[0] = '\0'; |
||||
WL_IOCTL(name, WLC_SET_SSID, &ssid, sizeof(ssid)); |
||||
|
||||
/* Bring the interface down */ |
||||
WL_IOCTL(name, WLC_DOWN, NULL, sizeof(val)); |
||||
} |
||||
|
||||
/* Set mode : AP, STA */ |
||||
ap = nvram_match(strcat_r(prefix, "mode", tmp), "ap"); |
||||
val = (ap + nvram_match(strcat_r(prefix, "mode", tmp), "wds")) ? 1 : 0; |
||||
WL_IOCTL(name, WLC_SET_AP, &val, sizeof(val)); |
||||
|
||||
/* Set STA specific parameters */ |
||||
if (!ap) { |
||||
/* Set mode: WET */ |
||||
if ((wet = nvram_match(strcat_r(prefix, "mode", tmp), "wet"))) |
||||
WL_IOCTL(name, WLC_SET_WET, &wet, sizeof(wet)); |
||||
/* Set infra: BSS/IBSS */ |
||||
if (wet || (sta = nvram_match(strcat_r(prefix, "mode", tmp), "sta"))) { |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "infra", tmp))); |
||||
WL_IOCTL(name, WLC_SET_INFRA, &val, sizeof(val)); |
||||
} |
||||
} |
||||
|
||||
/* Set network type */ |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "closed", tmp))); |
||||
WL_IOCTL(name, WLC_SET_CLOSED, &val, sizeof(val)); |
||||
|
||||
/* Set up the country code */ |
||||
(void) strcat_r(prefix, "country_code", tmp); |
||||
country = nvram_get(tmp); |
||||
if (country) { |
||||
strncpy(country_code, country, sizeof(country_code)); |
||||
WL_IOCTL(name, WLC_SET_COUNTRY, country_code, strlen(country_code)+1); |
||||
} |
||||
else { |
||||
/* If country_code doesn't exist, check for country to be backward compatible */ |
||||
(void) strcat_r(prefix, "country", tmp); |
||||
country = nvram_safe_get(tmp); |
||||
for (val = 0; val < ARRAYSIZE(countries); val++) { |
||||
char **synonym; |
||||
for (synonym = countries[val].names; *synonym; synonym++) |
||||
if (!strcmp(country, *synonym)) |
||||
break; |
||||
if (*synonym) |
||||
break; |
||||
} |
||||
|
||||
/* Get the default country code if undefined or invalid and set the NVRAM */ |
||||
if (val >= ARRAYSIZE(countries)) { |
||||
WL_IOCTL(name, WLC_GET_COUNTRY, country_code, sizeof(country_code)); |
||||
} |
||||
else { |
||||
strncpy(country_code, countries[val].abbr, sizeof(country_code)); |
||||
WL_IOCTL(name, WLC_SET_COUNTRY, country_code, strlen(country_code)+1); |
||||
} |
||||
|
||||
/* Add the new NVRAM variable */ |
||||
nvram_set("wl_country_code", country_code); |
||||
(void) strcat_r(prefix, "country_code", tmp); |
||||
nvram_set(tmp, country_code); |
||||
} |
||||
|
||||
/* Set the MAC list */ |
||||
maclist = (struct maclist *) buf; |
||||
maclist->count = 0; |
||||
if (!nvram_match(strcat_r(prefix, "macmode", tmp), "disabled")) { |
||||
ea = maclist->ea; |
||||
foreach(var, nvram_safe_get(strcat_r(prefix, "maclist", tmp)), next) { |
||||
if ((&ea[1])->octet > &buf[sizeof(buf)]) |
||||
break; |
||||
if (ether_atoe(var, ea->octet)) { |
||||
maclist->count++; |
||||
ea++; |
||||
} |
||||
} |
||||
} |
||||
WL_IOCTL(name, WLC_SET_MACLIST, buf, sizeof(buf)); |
||||
|
||||
/* Set the MAC list mode */ |
||||
(void) strcat_r(prefix, "macmode", tmp); |
||||
if (nvram_match(tmp, "deny")) |
||||
val = WLC_MACMODE_DENY; |
||||
else if (nvram_match(tmp, "allow")) |
||||
val = WLC_MACMODE_ALLOW; |
||||
else |
||||
val = WLC_MACMODE_DISABLED; |
||||
WL_IOCTL(name, WLC_SET_MACMODE, &val, sizeof(val)); |
||||
|
||||
/* Enable or disable the radio */ |
||||
val = nvram_match(strcat_r(prefix, "radio", tmp), "0"); |
||||
WL_IOCTL(name, WLC_SET_RADIO, &val, sizeof(val)); |
||||
|
||||
/* Get supported phy types */ |
||||
WL_IOCTL(name, WLC_GET_PHYLIST, var, sizeof(var)); |
||||
nvram_set(strcat_r(prefix, "phytypes", tmp), var); |
||||
|
||||
/* Get radio IDs */ |
||||
*(next = buf) = '\0'; |
||||
for (i = 0; i < strlen(var); i++) { |
||||
/* Switch to band */ |
||||
phy[0] = var[i]; |
||||
val = WLCONF_STR2PHYTYPE(phy); |
||||
val = WLCONF_PHYTYPE2BAND(val); |
||||
WL_IOCTL(name, WLC_SET_BAND, &val, sizeof(val)); |
||||
/* Get radio ID on this band */ |
||||
WL_IOCTL(name, WLC_GET_REVINFO, &rev, sizeof(rev)); |
||||
next += sprintf(next, "%sBCM%X", i ? " " : "", |
||||
(rev.radiorev & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT); |
||||
} |
||||
nvram_set(strcat_r(prefix, "radioids", tmp), buf); |
||||
|
||||
/* Set band */ |
||||
str = nvram_get(strcat_r(prefix, "phytype", tmp)); |
||||
val = WLCONF_STR2PHYTYPE(str); |
||||
val = WLCONF_PHYTYPE2BAND(val); |
||||
/* Check errors (card may have changed) */ |
||||
if (wl_ioctl(name, WLC_SET_BAND, &val, sizeof(val))) { |
||||
/* default band to the first band in band list */ |
||||
phy[0] = var[0]; |
||||
val = WLCONF_STR2PHYTYPE(phy); |
||||
val = WLCONF_PHYTYPE2BAND(val); |
||||
WL_IOCTL(name, WLC_SET_BAND, &val, sizeof(val)); |
||||
} |
||||
|
||||
/* Get current core revision */ |
||||
WL_IOCTL(name, WLC_GET_REVINFO, &rev, sizeof(rev)); |
||||
snprintf(buf, sizeof(buf), "%d", rev.corerev); |
||||
nvram_set(strcat_r(prefix, "corerev", tmp), buf); |
||||
|
||||
/* Get current phy type */ |
||||
WL_IOCTL(name, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)); |
||||
snprintf(buf, sizeof(buf), "%s", WLCONF_PHYTYPE2STR(phytype)); |
||||
nvram_set(strcat_r(prefix, "phytype", tmp), buf); |
||||
|
||||
/* Set channel before setting gmode or rateset */ |
||||
/* Manual Channel Selection - when channel # is not 0 */ |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "channel", tmp))); |
||||
if (val) { |
||||
if (wl_ioctl(name, WLC_SET_CHANNEL, &val, sizeof(val))) { |
||||
/* Use current channel (card may have changed) */ |
||||
WL_IOCTL(name, WLC_GET_CHANNEL, &ci, sizeof(ci)); |
||||
snprintf(buf, sizeof(buf), "%d", ci.target_channel); |
||||
nvram_set(strcat_r(prefix, "channel", tmp), buf); |
||||
} |
||||
} |
||||
|
||||
/* Reset to hardware rateset (band may have changed) */ |
||||
WL_IOCTL(name, WLC_GET_RATESET, &rs, sizeof (wl_rateset_t)); |
||||
WL_IOCTL(name, WLC_SET_RATESET, &rs, sizeof (wl_rateset_t)); |
||||
|
||||
/* Set gmode */ |
||||
if (phytype == PHY_TYPE_G) { |
||||
|
||||
/* Set gmode */ |
||||
|
||||
gmode = atoi(nvram_safe_get(strcat_r(prefix, "gmode", tmp))); |
||||
if (gmode == GMODE_AFTERBURNER) { |
||||
if (wl_get_int(name, "abcap", &val) || !val) { |
||||
gmode = GMODE_AUTO; |
||||
snprintf(buf, sizeof(buf), "%d", gmode); |
||||
nvram_set(tmp, buf); |
||||
} |
||||
} |
||||
WL_IOCTL(name, WLC_SET_GMODE, &gmode, sizeof(gmode)); |
||||
|
||||
/* Set gmode protection override and control algorithm */ |
||||
if (gmode != GMODE_AFTERBURNER) { |
||||
int override = WLC_G_PROTECTION_OFF; |
||||
int control = WLC_G_PROTECTION_CTL_OFF; |
||||
strcat_r(prefix, "gmode_protection", tmp); |
||||
if (nvram_match(tmp, "auto")) { |
||||
override = WLC_G_PROTECTION_AUTO; |
||||
control = WLC_G_PROTECTION_CTL_OVERLAP; |
||||
} |
||||
WL_IOCTL(name, WLC_SET_GMODE_PROTECTION_OVERRIDE, &override, sizeof(override)); |
||||
WL_IOCTL(name, WLC_SET_GMODE_PROTECTION_CONTROL, &control, sizeof(control)); |
||||
} |
||||
} |
||||
|
||||
/* Get current rateset (gmode may have changed) */ |
||||
WL_IOCTL(name, WLC_GET_CURR_RATESET, &rs, sizeof (wl_rateset_t)); |
||||
|
||||
strcat_r(prefix, "rateset", tmp); |
||||
if (nvram_match(tmp, "all")) { |
||||
/* Make all rates basic */ |
||||
for (i = 0; i < rs.count; i++) |
||||
rs.rates[i] |= 0x80; |
||||
} else if (nvram_match(tmp, "12")) { |
||||
/* Make 1 and 2 basic */ |
||||
for (i = 0; i < rs.count; i++) { |
||||
if ((rs.rates[i] & 0x7f) == 2 || (rs.rates[i] & 0x7f) == 4) |
||||
rs.rates[i] |= 0x80; |
||||
else |
||||
rs.rates[i] &= ~0x80; |
||||
} |
||||
} |
||||
|
||||
/* Set rateset */ |
||||
WL_IOCTL(name, WLC_SET_RATESET, &rs, sizeof (wl_rateset_t)); |
||||
|
||||
/* Allow short preamble override for b cards */ |
||||
if (phytype == PHY_TYPE_B || gmode == 0) { |
||||
strcat_r(prefix, "plcphdr", tmp);
|
||||
if (nvram_match(tmp, "long")) |
||||
val = WLC_PLCP_AUTO; |
||||
else |
||||
val = WLC_PLCP_SHORT; |
||||
WL_IOCTL(name, WLC_SET_PLCPHDR, &val, sizeof(val)); |
||||
} |
||||
|
||||
/* Set rate in 500 Kbps units */ |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "rate", tmp))) / 500000; |
||||
if (wl_ioctl(name, WLC_SET_RATE, &val, sizeof(val))) { |
||||
/* Try default rate (card may have changed) */ |
||||
val = 0; |
||||
WL_IOCTL(name, WLC_SET_RATE, &val, sizeof(val)); |
||||
snprintf(buf, sizeof(buf), "%d", val); |
||||
nvram_set(strcat_r(prefix, "rate", tmp), buf); |
||||
} |
||||
|
||||
/* Set fragmentation threshold */ |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "frag", tmp))); |
||||
WL_IOCTL(name, WLC_SET_FRAG, &val, sizeof(val)); |
||||
|
||||
/* Set RTS threshold */ |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "rts", tmp))); |
||||
WL_IOCTL(name, WLC_SET_RTS, &val, sizeof(val)); |
||||
|
||||
/* Set DTIM period */ |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "dtim", tmp))); |
||||
WL_IOCTL(name, WLC_SET_DTIMPRD, &val, sizeof(val)); |
||||
|
||||
/* Set beacon period */ |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "bcn", tmp))); |
||||
WL_IOCTL(name, WLC_SET_BCNPRD, &val, sizeof(val)); |
||||
|
||||
/* Set lazy WDS mode */ |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "lazywds", tmp))); |
||||
WL_IOCTL(name, WLC_SET_LAZYWDS, &val, sizeof(val)); |
||||
|
||||
/* Set the WDS list */ |
||||
maclist = (struct maclist *) buf; |
||||
maclist->count = 0; |
||||
ea = maclist->ea; |
||||
foreach(var, nvram_safe_get(strcat_r(prefix, "wds", tmp)), next) { |
||||
if (ea->octet > &buf[sizeof(buf)]) |
||||
break; |
||||
ether_atoe(var, ea->octet); |
||||
maclist->count++; |
||||
ea++; |
||||
} |
||||
WL_IOCTL(name, WLC_SET_WDSLIST, buf, sizeof(buf)); |
||||
|
||||
/* Set framebursting mode */ |
||||
val = nvram_match(strcat_r(prefix, "frameburst", tmp), "on"); |
||||
WL_IOCTL(name, WLC_SET_FAKEFRAG, &val, sizeof(val)); |
||||
|
||||
/* Bring the interface back up */ |
||||
WL_IOCTL(name, WLC_UP, NULL, 0); |
||||
|
||||
/* Set antenna */ |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "antdiv", tmp))); |
||||
WL_IOCTL(name, WLC_SET_ANTDIV, &val, sizeof(val)); |
||||
|
||||
/* Auto Channel Selection - when channel # is 0 in AP mode */ |
||||
/*
|
||||
* The following condition(s) must be met in order for
|
||||
* Auto Channel Selection to work. |
||||
* - the I/F must be up (change radio channel requires it is up?) |
||||
* - the AP must not be associated (setting SSID to empty should
|
||||
* make sure it for us) |
||||
*/ |
||||
if (ap) { |
||||
if (!(val = atoi(nvram_safe_get(strcat_r(prefix, "channel", tmp))))) { |
||||
/* select a channel */ |
||||
val = wlconf_auto_channel(name); |
||||
/* switch to the selected channel */ |
||||
WL_IOCTL(name, WLC_SET_CHANNEL, &val, sizeof(val)); |
||||
/* set the auto channel scan timer in the driver when in auto mode */ |
||||
val = 15; /* 15 minutes for now */ |
||||
WL_IOCTL(name, WLC_SET_CS_SCAN_TIMER, &val, sizeof(val)); |
||||
} |
||||
else { |
||||
/* reset the channel scan timer in the driver when not in auto mode */ |
||||
val = 0; |
||||
WL_IOCTL(name, WLC_SET_CS_SCAN_TIMER, &val, sizeof(val)); |
||||
} |
||||
} |
||||
|
||||
/* Set WEP keys */ |
||||
for (i = 1; i <= WLC_MAX_DEFAULT_KEYS; i++) |
||||
wlconf_set_wep_key(name, prefix, i); |
||||
|
||||
/* Set WSEC */ |
||||
/*
|
||||
* Need to check errors (card may have changed) and change to |
||||
* defaults since the new chip may not support the requested
|
||||
* encryptions after the card has been changed. |
||||
*/ |
||||
if (wlconf_set_wsec(name, prefix)) { |
||||
/* change nvram only, code below will pass them on */ |
||||
wlconf_restore_var(prefix, "auth_mode"); |
||||
wlconf_restore_var(prefix, "auth"); |
||||
/* reset wep to default */ |
||||
wlconf_restore_var(prefix, "wep"); |
||||
wlconf_set_wsec(name, prefix); |
||||
} |
||||
|
||||
/* Set WPA authentication mode - radius/wpa/psk */ |
||||
strcat_r(prefix, "auth_mode", tmp); |
||||
if (nvram_match(tmp, "radius")) |
||||
val = WPA_AUTH_DISABLED; |
||||
else if (nvram_match(tmp, "wpa")) |
||||
val = WPA_AUTH_UNSPECIFIED; |
||||
else if (nvram_match(tmp, "psk")) |
||||
val = WPA_AUTH_PSK; |
||||
else /* if (nvram_match(tmp, "disabled")) */ |
||||
val = WPA_AUTH_DISABLED; |
||||
WL_IOCTL(name, WLC_SET_WPA_AUTH, &val, sizeof(val)); |
||||
|
||||
/* Set non-WPA authentication mode - open/shared */ |
||||
val = atoi(nvram_safe_get(strcat_r(prefix, "auth", tmp))); |
||||
WL_IOCTL(name, WLC_SET_AUTH, &val, sizeof(val)); |
||||
|
||||
/* Set WEP restrict if WEP is not disabled */ |
||||
val = nvram_invmatch(strcat_r(prefix, "wep", tmp), "off"); |
||||
WL_IOCTL(name, WLC_SET_WEP_RESTRICT, &val, sizeof(val)); |
||||
|
||||
/* Set SSID/Join network */ |
||||
if (ap | sta | wet) { |
||||
strcat_r(prefix, "ssid", tmp); |
||||
ssid.SSID_len = strlen(nvram_safe_get(tmp)); |
||||
if (ssid.SSID_len > sizeof(ssid.SSID)) |
||||
ssid.SSID_len = sizeof(ssid.SSID); |
||||
strncpy(ssid.SSID, nvram_safe_get(tmp), ssid.SSID_len); |
||||
} else { |
||||
/* A zero length SSID turns off the AP */ |
||||
ssid.SSID_len = 0; |
||||
ssid.SSID[0] = '\0'; |
||||
}
|
||||
WL_IOCTL(name, WLC_SET_SSID, &ssid, sizeof(ssid)); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int |
||||
wlconf_down(char *name) |
||||
{ |
||||
int val, ret = 0; |
||||
unsigned char buf[WLC_IOCTL_MAXLEN]; |
||||
struct maclist *maclist; |
||||
wlc_ssid_t ssid; |
||||
|
||||
/* Check interface (fail silently for non-wl interfaces) */ |
||||
if ((ret = wl_probe(name))) |
||||
return ret; |
||||
|
||||
/* Bring down the interface */ |
||||
WL_IOCTL(name, WLC_GET_UP, &val, sizeof(val)); |
||||
if (val) { |
||||
/* Nuke SSID */ |
||||
ssid.SSID_len = 0; |
||||
ssid.SSID[0] = '\0'; |
||||
WL_IOCTL(name, WLC_SET_SSID, &ssid, sizeof(ssid)); |
||||
|
||||
/* Bring the interface down */ |
||||
WL_IOCTL(name, WLC_DOWN, NULL, sizeof(val)); |
||||
} |
||||
|
||||
/* Nuke the WDS list */ |
||||
maclist = (struct maclist *) buf; |
||||
maclist->count = 0; |
||||
WL_IOCTL(name, WLC_SET_WDSLIST, buf, sizeof(buf)); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int |
||||
main(int argc, char *argv[]) |
||||
{ |
||||
int ret = -1; |
||||
|
||||
/* Check parameters and branch based on action */ |
||||
if (argc == 3 && !strcmp(argv[2], "up")) |
||||
ret = wlconf(argv[1]); |
||||
else if (argc == 3 && !strcmp(argv[2], "down")) |
||||
ret = wlconf_down(argv[1]); |
||||
else { |
||||
fprintf(stderr, "Usage: wlconf <ifname> up|down\n"); |
||||
return -1; |
||||
} |
||||
/* Check result */ |
||||
if (ret) { |
||||
fprintf(stderr, "wlconf: %s failed (%d)\n", argv[1], ret); |
||||
return ret; |
||||
} |
||||
return 0; |
||||
} |
@ -1,5 +0,0 @@ |
||||
#!/bin/ash |
||||
alias debug=${DEBUG:-:} |
||||
debug "### wifi $1 ###" |
||||
if=$(cat /proc/net/dev | awk -F: '/eth/ {wifi=$1;} END { print wifi}') |
||||
$DEBUG wlconf $if $1 |
Loading…
Reference in new issue