X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/0509a46f271cda237881a7ed244e9b14760c4654..96d396033d082871cc975277a78f7bf3eccfe877:/package/wificonf/wificonf.c?ds=sidebyside diff --git a/package/wificonf/wificonf.c b/package/wificonf/wificonf.c index 44ca8a40d..b76f697b8 100644 --- a/package/wificonf/wificonf.c +++ b/package/wificonf/wificonf.c @@ -36,21 +36,18 @@ do { \ ERR_SET_EXT(rname, request); \ fprintf(stderr, " too few arguments.\n"); \ - return; \ } while(0) #define ABORT_ARG_TYPE(rname, request, arg) \ do { \ ERR_SET_EXT(rname, request); \ fprintf(stderr, " invalid argument \"%s\".\n", arg); \ - return; \ } while(0) #define ABORT_ARG_SIZE(rname, request, max) \ do { \ ERR_SET_EXT(rname, request); \ fprintf(stderr, " argument too big (max %d)\n", max); \ - return; \ } while(0) /*------------------------------------------------------------------*/ @@ -64,7 +61,6 @@ ERR_SET_EXT(rname, request); \ fprintf(stderr, " SET failed on device %-1.16s ; %s.\n", \ ifname, strerror(errno)); \ - return; \ } } while(0) /*------------------------------------------------------------------*/ @@ -78,11 +74,13 @@ ERR_SET_EXT(rname, request); \ fprintf(stderr, " GET failed on device %-1.16s ; %s.\n", \ ifname, strerror(errno)); \ - return; \ } } while(0) +void set_wext_ssid(int skfd, char *ifname); + char *prefix; char buffer[128]; +int wpa_enc = 0; char *wl_var(char *name) { @@ -115,8 +113,6 @@ int bcom_ioctl(int skfd, char *ifname, int cmd, void *buf, int len) strncpy(ifr.ifr_name, ifname, IFNAMSIZ); ret = ioctl(skfd, SIOCDEVPRIVATE, &ifr); - if (ret < 0) - fprintf(stderr, "bcom_ioctl [cmd=%d, buf=%08x, len=%d] failed: %d\n", cmd, buf, len, ret); return ret; } @@ -131,7 +127,7 @@ int bcom_set_val(int skfd, char *ifname, char *var, void *val, int len) strcpy(buf, var); - if ((ret = bcom_ioctl(skfd, ifname, WLC_GET_VAR, buf, sizeof(buf)))) + if ((ret = bcom_ioctl(skfd, ifname, WLC_SET_VAR, buf, sizeof(buf)))) return ret; memcpy(val, buf, len); @@ -143,32 +139,50 @@ int bcom_set_int(int skfd, char *ifname, char *var, int val) return bcom_set_val(skfd, ifname, var, &val, sizeof(val)); } -void setup_bcom(int skfd, char *ifname) +void stop_bcom(int skfd, char *ifname) { int val = 0; - char *v; + wlc_ssid_t ssid; if (bcom_ioctl(skfd, ifname, WLC_GET_MAGIC, &val, sizeof(val)) < 0) return; - + + ssid.SSID_len = 0; + ssid.SSID[0] = 0; + bcom_ioctl(skfd, ifname, WLC_SET_SSID, &ssid, sizeof(ssid)); bcom_ioctl(skfd, ifname, WLC_DOWN, NULL, 0); + +} + +void start_bcom(int skfd, char *ifname) +{ + int val = 0; - /* Set up WPA */ - if (nvram_match(wl_var("crypto"), "tkip")) - val = TKIP_ENABLED; - else if (nvram_match(wl_var("crypto"), "aes")) - val = AES_ENABLED; - else if (nvram_match(wl_var("crypto"), "tkip+aes")) - val = TKIP_ENABLED | AES_ENABLED; - else - val = 0; - bcom_ioctl(skfd, ifname, WLC_SET_WSEC, &val, sizeof(val)); + if (bcom_ioctl(skfd, ifname, WLC_GET_MAGIC, &val, sizeof(val)) < 0) + return; + + bcom_ioctl(skfd, ifname, WLC_UP, &val, sizeof(val)); + set_wext_ssid(skfd, ifname); +} - if (val && nvram_get(wl_var("wpa_psk"))) { - val = 1; - bcom_ioctl(skfd, ifname, WLC_SET_EAP_RESTRICT, &val, sizeof(val)); - } +void setup_bcom(int skfd, char *ifname) +{ + int val = 0; + char buf[8192]; + char wbuf[80]; + char *v; + + if (bcom_ioctl(skfd, ifname, WLC_GET_MAGIC, &val, sizeof(val)) < 0) + return; + + stop_bcom(skfd, ifname); + + /* Set Country */ + strncpy(buf, nvram_safe_get(wl_var("country_code")), 4); + buf[3] = 0; + bcom_ioctl(skfd, ifname, WLC_SET_COUNTRY, buf, 4); + /* Set up afterburner */ val = ABO_AUTO; if (nvram_enabled(wl_var("afterburner"))) @@ -178,20 +192,36 @@ void setup_bcom(int skfd, char *ifname) bcom_set_val(skfd, ifname, "afterburner_override", &val, sizeof(val)); /* Set other options */ - val = atoi(nvram_safe_get(wl_var("lazywds"))); + val = nvram_enabled(wl_var("lazywds")); bcom_ioctl(skfd, ifname, WLC_SET_LAZYWDS, &val, sizeof(val)); - val = atoi(nvram_safe_get(wl_var("frag"))); - bcom_ioctl(skfd, ifname, WLC_SET_FRAG, &val, sizeof(val)); - val = atoi(nvram_safe_get(wl_var("dtim"))); - bcom_ioctl(skfd, ifname, WLC_SET_DTIMPRD, &val, sizeof(val)); - val = atoi(nvram_safe_get(wl_var("bcn"))); - bcom_ioctl(skfd, ifname, WLC_SET_BCNPRD, &val, sizeof(val)); - val = atoi(nvram_safe_get(wl_var("rts"))); - bcom_ioctl(skfd, ifname, WLC_SET_RTS, &val, sizeof(val)); - val = atoi(nvram_safe_get(wl_var("antdiv"))); - bcom_ioctl(skfd, ifname, WLC_SET_ANTDIV, &val, sizeof(val)); - val = atoi(nvram_safe_get(wl_var("txant"))); - bcom_ioctl(skfd, ifname, WLC_SET_TXANT, &val, sizeof(val)); + + if (v = nvram_get(wl_var("frag"))) { + val = atoi(v); + bcom_ioctl(skfd, ifname, WLC_SET_FRAG, &val, sizeof(val)); + } + if (v = nvram_get(wl_var("dtim"))) { + val = atoi(v); + bcom_ioctl(skfd, ifname, WLC_SET_DTIMPRD, &val, sizeof(val)); + } + if (v = nvram_get(wl_var("bcn"))) { + val = atoi(v); + bcom_ioctl(skfd, ifname, WLC_SET_BCNPRD, &val, sizeof(val)); + } + if (v = nvram_get(wl_var("rts"))) { + val = atoi(v); + bcom_ioctl(skfd, ifname, WLC_SET_RTS, &val, sizeof(val)); + } + if (v = nvram_get(wl_var("antdiv"))) { + val = atoi(v); + bcom_ioctl(skfd, ifname, WLC_SET_ANTDIV, &val, sizeof(val)); + } + if (v = nvram_get(wl_var("txant"))) { + val = atoi(v); + bcom_ioctl(skfd, ifname, WLC_SET_TXANT, &val, sizeof(val)); + } + + val = nvram_enabled(wl_var("closed")); + bcom_ioctl(skfd, ifname, WLC_SET_CLOSED, &val, sizeof(val)); val = nvram_enabled(wl_var("ap_isolate")); bcom_set_int(skfd, ifname, "ap_isolate", val); @@ -208,7 +238,6 @@ void setup_bcom(int skfd, char *ifname) val = WLC_MACMODE_DISABLED; if ((val != WLC_MACMODE_DISABLED) && (v = nvram_get(wl_var("maclist")))) { - char buf[8192]; struct maclist *mac_list; struct ether_addr *addr; char *next; @@ -217,19 +246,32 @@ void setup_bcom(int skfd, char *ifname) mac_list = (struct maclist *) buf; addr = mac_list->ea; - v = malloc(80); - foreach(v, nvram_safe_get(wl_var("maclist")), next) { - if (ether_atoe(v, addr->ether_addr_octet)) { + foreach(wbuf, v, next) { + if (ether_atoe(wbuf, addr->ether_addr_octet)) { mac_list->count++; addr++; } } - free(v); bcom_ioctl(skfd, ifname, WLC_SET_MACLIST, buf, sizeof(buf)); } else { val = WLC_MACMODE_DISABLED; } bcom_ioctl(skfd, ifname, WLC_SET_MACMODE, &val, sizeof(val)); + + if (v = nvram_get(wl_var("wds"))) { + struct maclist *wdslist = (struct maclist *) buf; + struct ether_addr *addr = wdslist->ea; + char *next; + + memset(buf, 0, 8192); + foreach(wbuf, v, next) { + if (ether_atoe(wbuf, addr->ether_addr_octet)) { + wdslist->count++; + addr++; + } + } + bcom_ioctl(skfd, ifname, WLC_SET_WDSLIST, buf, sizeof(buf)); + } /* Set up G mode */ bcom_ioctl(skfd, ifname, WLC_GET_PHYTYPE, &val, sizeof(val)); @@ -237,9 +279,14 @@ void setup_bcom(int skfd, char *ifname) int override = WLC_G_PROTECTION_OFF; int control = WLC_G_PROTECTION_CTL_OFF; - val = atoi(nvram_safe_get(wl_var("gmode"))); + if (v = nvram_get(wl_var("gmode"))) + val = atoi(v); + else + val = 1; + if (val > 5) val = 1; + bcom_ioctl(skfd, ifname, WLC_SET_GMODE, &val, sizeof(val)); if (nvram_match(wl_var("gmode_protection"), "auto")) { @@ -252,40 +299,85 @@ void setup_bcom(int skfd, char *ifname) } bcom_ioctl(skfd, ifname, WLC_SET_GMODE_PROTECTION_CONTROL, &override, sizeof(control)); bcom_ioctl(skfd, ifname, WLC_SET_GMODE_PROTECTION_OVERRIDE, &override, sizeof(override)); + + if (val = 0) { + if (nvram_match(wl_var("plcphdr"), "long")) + val = WLC_PLCP_AUTO; + else + val = WLC_PLCP_SHORT; + + bcom_ioctl(skfd, ifname, WLC_SET_PLCPHDR, &val, sizeof(val)); + } } -} -void set_wext_ssid(int skfd, char *ifname) -{ - char *buffer; - struct iwreq wrq; + start_bcom(skfd, ifname); - if (buffer = nvram_get(wl_var("ssid"))) { - if (strlen(buffer) > IW_ESSID_MAX_SIZE) { - ABORT_ARG_SIZE("Set ESSID", SIOCSIWESSID, IW_ESSID_MAX_SIZE); - } else { - char essid[IW_ESSID_MAX_SIZE + 1]; - - wrq.u.essid.flags = 1; - strcpy(essid, buffer); - wrq.u.essid.pointer = (caddr_t) essid; - wrq.u.essid.length = strlen(essid) + 1; - IW_SET_EXT_ERR(skfd, ifname, SIOCSIWESSID, &wrq, "Set ESSID"); + if (!(v = nvram_get(wl_var("akm")))) + v = nvram_safe_get(wl_var("auth_mode")); + + if (strstr(v, "wpa") || strstr(v, "psk")) { + wpa_enc = 1; + + /* Set up WPA */ + if (nvram_match(wl_var("crypto"), "tkip")) + val = TKIP_ENABLED; + else if (nvram_match(wl_var("crypto"), "aes")) + val = AES_ENABLED; + else if (nvram_match(wl_var("crypto"), "tkip+aes")) + val = TKIP_ENABLED | AES_ENABLED; + else + val = 0; + bcom_ioctl(skfd, ifname, WLC_SET_WSEC, &val, sizeof(val)); + + if (val && strstr(v, "psk")) { + v = nvram_safe_get(wl_var("wpa_psk")); + + if ((strlen(v) >= 8) && (strlen(v) < 63)) { + val = 4; + bcom_ioctl(skfd, ifname, WLC_SET_WPA_AUTH, &val, sizeof(val)); + + bcom_ioctl(skfd, ifname, WLC_GET_AP, &val, sizeof(val)); + if (!val) { + /* Enable in-driver WPA supplicant */ + wsec_pmk_t pmk; + + pmk.key_len = (unsigned short) strlen(v); + pmk.flags = WSEC_PASSPHRASE; + strcpy(pmk.key, v); + bcom_ioctl(skfd, ifname, WLC_SET_WSEC_PMK, &pmk, sizeof(pmk)); + bcom_set_int(skfd, ifname, "sup_wpa", 1); + } + } + } else { + val = 1; + bcom_ioctl(skfd, ifname, WLC_SET_EAP_RESTRICT, &val, sizeof(val)); } + } else { + val = 0; + + bcom_ioctl(skfd, ifname, WLC_SET_WSEC, &val, sizeof(val)); + bcom_ioctl(skfd, ifname, WLC_SET_WPA_AUTH, &val, sizeof(val)); + bcom_ioctl(skfd, ifname, WLC_SET_EAP_RESTRICT, &val, sizeof(val)); + bcom_set_int(skfd, ifname, "sup_wpa", 0); } } -void start_bcom(int skfd, char *ifname) +void set_wext_ssid(int skfd, char *ifname) { - int val = 0; - - if (bcom_ioctl(skfd, ifname, WLC_GET_MAGIC, &val, sizeof(val)) < 0) - return; + char *buffer; + char essid[IW_ESSID_MAX_SIZE + 1]; + struct iwreq wrq; - bcom_ioctl(skfd, ifname, WLC_UP, &val, sizeof(val)); + buffer = nvram_get(wl_var("ssid")); - /* Need to re-set SSID after WLC_UP */ - set_wext_ssid(skfd, ifname); + if (!buffer || (strlen(buffer) > IW_ESSID_MAX_SIZE)) + buffer = "OpenWrt"; + + wrq.u.essid.flags = 1; + strcpy(essid, buffer); + wrq.u.essid.pointer = (caddr_t) essid; + wrq.u.essid.length = strlen(essid) + 1; + IW_SET_EXT_ERR(skfd, ifname, SIOCSIWESSID, &wrq, "Set ESSID"); } void setup_wext_wep(int skfd, char *ifname) @@ -295,7 +387,8 @@ void setup_wext_wep(int skfd, char *ifname) char keystr[5]; char *keyval; unsigned char key[IW_ENCODING_TOKEN_MAX]; - + + memset(&wrq, 0, sizeof(wrq)); strcpy(keystr, "key1"); for (i = 1; i <= 4; i++) { if (keyval = nvram_get(wl_var(keystr))) { @@ -311,7 +404,7 @@ void setup_wext_wep(int skfd, char *ifname) keystr[3]++; } - + memset(&wrq, 0, sizeof(wrq)); i = atoi(nvram_safe_get(wl_var("key"))); if (i > 0 && i < 4) { wrq.u.data.flags = i | IW_ENCODE_RESTRICTED; @@ -319,14 +412,25 @@ void setup_wext_wep(int skfd, char *ifname) } } +void set_wext_mode(skfd, ifname) +{ + struct iwreq wrq; + int ap = 0, infra = 0, wet = 0; + + /* Set operation mode */ + ap = !nvram_match(wl_var("mode"), "sta") && !nvram_match(wl_var("mode"), "wet"); + infra = !nvram_disabled(wl_var("infra")); + wet = nvram_enabled(wl_var("wet")) || !nvram_match(wl_var("mode"), "wet"); + + wrq.u.mode = (!infra ? IW_MODE_ADHOC : (ap ? IW_MODE_MASTER : (wet ? IW_MODE_REPEAT : IW_MODE_INFRA))); + IW_SET_EXT_ERR(skfd, ifname, SIOCSIWMODE, &wrq, "Set Mode"); +} + void setup_wext(int skfd, char *ifname) { char *buffer; struct iwreq wrq; - /* Set ESSID */ - set_wext_ssid(skfd, ifname); - /* Set channel */ int channel = atoi(nvram_safe_get(wl_var("channel"))); @@ -337,33 +441,24 @@ void setup_wext(int skfd, char *ifname) if (channel > 0) { wrq.u.freq.flags = IW_FREQ_FIXED; wrq.u.freq.m = channel; + IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFREQ, &wrq, "Set Frequency"); } - IW_SET_EXT_ERR(skfd, ifname, SIOCSIWFREQ, &wrq, "Set Frequency"); - - /* Set operation mode */ - int ap = 0, infra = 0, wet = 0; - - ap = (nvram_match(wl_var("mode"), "ap") || nvram_match(wl_var("mode"), "wds")); - infra = nvram_enabled(wl_var("infra")); - wet = nvram_enabled(wl_var("wet")); - wrq.u.mode = (!infra ? IW_MODE_ADHOC : (ap ? IW_MODE_MASTER : (wet ? IW_MODE_REPEAT : IW_MODE_INFRA))); - IW_SET_EXT_ERR(skfd, ifname, SIOCSIWMODE, &wrq, "Set Mode"); /* Disable radio if wlX_radio is set and not enabled */ - if (nvram_disabled(wl_var("radio"))) - wrq.u.txpower.disabled = 1; - else - wrq.u.txpower.disabled = 0; + wrq.u.txpower.disabled = nvram_disabled(wl_var("radio")); wrq.u.txpower.value = -1; wrq.u.txpower.fixed = 1; - wrq.u.txpower.flags = IW_TXPOW_MWATT; + wrq.u.txpower.flags = IW_TXPOW_DBM; IW_SET_EXT_ERR(skfd, ifname, SIOCSIWTXPOW, &wrq, "Set Tx Power"); /* Set up WEP */ - if (nvram_enabled(wl_var("wep"))) + if (nvram_enabled(wl_var("wep")) && !wpa_enc) setup_wext_wep(skfd, ifname); + + /* Set ESSID */ + set_wext_ssid(skfd, ifname); } @@ -379,9 +474,16 @@ static int setup_interfaces(int skfd, char *ifname, char *args[], int count) if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0) return 0; - setup_bcom(skfd, ifname); - setup_wext(skfd, ifname); - start_bcom(skfd, ifname); + if (strncmp(ifname, "ath", 3) == 0) { + set_wext_mode(skfd, ifname); + setup_wext(skfd, ifname); + } else { + stop_bcom(skfd, ifname); + set_wext_mode(skfd, ifname); + setup_bcom(skfd, ifname); + setup_wext(skfd, ifname); + } + prefix[2]++; }