source: trunk/openwrt/package/openwrt/wlconf.c @ 1128

Last change on this file since 1128 was 1128, checked in by wbx, 12 years ago

will be removed as soon as we have another solution, seems to be compatible with wl 3.9 driver

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 18.3 KB
Line 
1/*
2 * no license, extracted from wag54gv2-AU_v1.00.39 GPL
3 *
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <assert.h>
10
11#include <typedefs.h>
12#include <bcmnvram.h>
13#include <bcmutils.h>
14#include <shutils.h>
15#include <wlutils.h>
16
17/* phy types */
18#define PHY_TYPE_A              0
19#define PHY_TYPE_B              1
20#define PHY_TYPE_G              2
21#define PHY_TYPE_NULL           0xf
22
23/* parts of an idcode: */
24#define IDCODE_MFG_MASK         0x00000fff
25#define IDCODE_MFG_SHIFT        0
26#define IDCODE_ID_MASK          0x0ffff000
27#define IDCODE_ID_SHIFT         12
28#define IDCODE_REV_MASK         0xf0000000
29#define IDCODE_REV_SHIFT        28
30
31#define WL_IOCTL(name, cmd, buf, len) ((void) wl_ioctl((name), (cmd), (buf), (len)))
32
33/* set WEP key */
34static int
35wlconf_set_wep_key(char *name, char *prefix, int i)
36{
37        wsec_key_t key;
38        char wl_key[] = "wlXXXXXXXXXX_keyXXXXXXXXXX";
39        char *keystr, hex[] = "XX";
40        unsigned char *data = key.data;
41        int ret = 0;
42
43        memset(&key, 0, sizeof(key));
44        key.index = i - 1;
45        sprintf(wl_key, "%skey%d", prefix, i);
46        keystr = nvram_safe_get(wl_key);
47
48        switch (strlen(keystr)) {
49        case WEP1_KEY_SIZE:
50        case WEP128_KEY_SIZE:
51                key.len = strlen(keystr);
52                strcpy(key.data, keystr);
53                break;
54        case WEP1_KEY_HEX_SIZE:
55        case WEP128_KEY_HEX_SIZE:
56                key.len = strlen(keystr) / 2;
57                while (*keystr) {
58                        strncpy(hex, keystr, 2);
59                        *data++ = (unsigned char) strtoul(hex, NULL, 16);
60                        keystr += 2;
61                }
62                break;
63        default:
64                key.len = 0;
65                break;
66        }
67
68        /* Set current WEP key */
69        if (key.len && i == atoi(nvram_safe_get(strcat_r(prefix, "key", wl_key))))
70                key.flags = WSEC_PRIMARY_KEY;
71
72        WL_IOCTL(name, WLC_SET_KEY, &key, sizeof(key));
73
74        return ret;
75}
76
77extern struct nvram_tuple router_defaults[];
78
79/* Keep this table in order */
80static struct {
81        int locale;
82        char **names;
83        char *abbr;
84} countries[] = {
85        { WLC_WW,  ((char *[]) { "Worldwide", "WW", NULL }), "AU" },
86        { WLC_THA, ((char *[]) { "Thailand", "THA", NULL }), "TH" },
87        { WLC_ISR, ((char *[]) { "Israel", "ISR", NULL }), "IL" },
88        { WLC_JDN, ((char *[]) { "Jordan", "JDN", NULL }), "JO" },
89        { WLC_PRC, ((char *[]) { "China", "P.R. China", "PRC", NULL }), "CN" },
90        { WLC_JPN, ((char *[]) { "Japan", "JPN", NULL }), "JP" },
91        { WLC_FCC, ((char *[]) { "USA", "Canada", "ANZ", "New Zealand", "FCC", NULL }), "US" },
92        { WLC_EUR, ((char *[]) { "Europe", "EUR", NULL }), "DE" },
93        { WLC_USL, ((char *[]) { "USA Low", "USALow", "USL", NULL }), "US" },
94        { WLC_JPH, ((char *[]) { "Japan High", "JapanHigh", "JPH", NULL }), "JP" },
95        { WLC_ALL, ((char *[]) { "All", "AllTheChannels", NULL }), "All" },
96};
97
98/* validate/restore all per-interface related variables */
99static void
100wlconf_validate_all(char *prefix, bool restore)
101{
102        struct nvram_tuple *t;
103        char tmp[100];
104        char *v;
105        for (t = router_defaults; t->name; t++) {
106                if (!strncmp(t->name, "wl_", 3)) {
107                        strcat_r(prefix, &t->name[3], tmp);
108                        if (!restore && nvram_get(tmp))
109                                continue;
110                        v = nvram_get(t->name);
111                        nvram_set(tmp, v ? v : t->value);
112                }
113        }
114}
115
116/* restore specific per-interface variable */
117static void
118wlconf_restore_var(char *prefix, char *name)
119{
120        struct nvram_tuple *t;
121        char tmp[100];
122        for (t = router_defaults; t->name; t++) {
123                if (!strncmp(t->name, "wl_", 3) && !strcmp(&t->name[3], name)) {
124                        nvram_set(strcat_r(prefix, name, tmp), t->value);
125                        break;
126                }
127        }
128}
129
130/* Set up wsec */
131static int
132wlconf_set_wsec(char *ifname, char *prefix)
133{
134        char tmp[100];
135        int val;
136        strcat_r(prefix, "wep", tmp);
137        if (nvram_match(tmp, "wep") || nvram_match(tmp, "on") || nvram_match(tmp, "restricted"))
138                val = WEP_ENABLED;
139        else if (nvram_match(tmp, "tkip"))
140                val = TKIP_ENABLED;
141        else if (nvram_match(tmp, "aes"))
142                val = AES_ENABLED;
143        else if (nvram_match(tmp, "tkip+aes"))
144                val = TKIP_ENABLED | AES_ENABLED;
145        else
146                val = 0;
147        return wl_ioctl(ifname, WLC_SET_WSEC, &val, sizeof(val));
148}
149
150/*
151* For debugging only
152*/
153#define WLCONF_DBG(fmt, arg...)
154
155#if defined(linux)
156#include <unistd.h>
157static void
158sleep_ms(const unsigned int ms)
159{
160        usleep(1000*ms);
161}
162#endif
163
164/*
165* The following condition(s) must be met when Auto Channel Selection
166* is enabled.
167*  - the I/F is up (change radio channel requires it is up?)
168*  - the AP must not be associated (setting SSID to empty should
169*    make sure it for us)
170*/
171static uint8
172wlconf_auto_channel(char *name)
173{
174        int chosen = 0;
175        wl_uint32_list_t request;
176        int phytype;
177        /* query the phy type */
178        wl_ioctl(name, WLC_GET_PHYTYPE, &phytype, sizeof(phytype));
179        request.count = 0;      /* let the ioctl decide */
180        if (!wl_ioctl(name, WLC_START_CHANNEL_SEL, &request, sizeof(request))) {
181                sleep_ms(phytype == PHY_TYPE_A ? 1000 : 750);
182                while (wl_ioctl(name, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen)))
183                        sleep_ms(100);
184        }
185        WLCONF_DBG("interface %s: channel selected %d\n", name, chosen);
186        return chosen;
187}
188
189/* PHY type/BAND conversion */
190#define WLCONF_PHYTYPE2BAND(phy)        ((phy) == PHY_TYPE_A ? WLC_BAND_A : WLC_BAND_B)
191/* PHY type conversion */
192#define WLCONF_PHYTYPE2STR(phy) ((phy) == PHY_TYPE_A ? "a" : \
193                                 (phy) == PHY_TYPE_B ? "b" : "g")
194#define WLCONF_STR2PHYTYPE(phy) ((phy) && (phy)[0] == 'a' ? PHY_TYPE_A : \
195                                 (phy) && (phy)[0] == 'b' ? PHY_TYPE_B : PHY_TYPE_G)
196                                 
197/* configure the specified wireless interface */
198int
199wlconf(char *name)
200{
201        int restore_defaults, val, unit, phytype, gmode = 0, ret = 0;
202        char tmp[100], prefix[] = "wlXXXXXXXXXX_";
203        char var[80], *next, phy[] = "a", *str;
204        unsigned char buf[WLC_IOCTL_MAXLEN];
205        char *country;
206        wlc_rev_info_t rev;
207        channel_info_t ci;
208        struct maclist *maclist;
209        struct ether_addr *ea;
210        wlc_ssid_t ssid;
211        wl_rateset_t rs;
212        unsigned int i;
213        char eaddr[32];
214        int ap, sta = 0, wet = 0;
215        char country_code[4];
216
217        /* Check interface (fail silently for non-wl interfaces) */
218        if ((ret = wl_probe(name)))
219                return ret;
220
221        /* Get MAC address */
222        (void) wl_hwaddr(name, buf);
223
224        /* Get instance */
225        WL_IOCTL(name, WLC_GET_INSTANCE, &unit, sizeof(unit));
226        snprintf(prefix, sizeof(prefix), "wl%d_", unit);
227
228        /* Restore defaults if per-interface parameters do not exist */
229        restore_defaults = !nvram_get(strcat_r(prefix, "ifname", tmp));
230        wlconf_validate_all(prefix, restore_defaults);
231        nvram_set(strcat_r(prefix, "ifname", tmp), name);
232        nvram_set(strcat_r(prefix, "hwaddr", tmp), ether_etoa(buf, eaddr));
233        snprintf(buf, sizeof(buf), "%d", unit);
234        nvram_set(strcat_r(prefix, "unit", tmp), buf);
235
236        /*
237        * Nuke SSID first so that the AP won't be associated when WLC_UP.
238        * This must be done here if Auto Channel Selection is enabled.
239        */
240        WL_IOCTL(name, WLC_GET_UP, &val, sizeof(val));
241        if (val) {
242                /* Nuke SSID  */
243                ssid.SSID_len = 0;
244                ssid.SSID[0] = '\0';
245                WL_IOCTL(name, WLC_SET_SSID, &ssid, sizeof(ssid));
246
247                /* Bring the interface down */
248                WL_IOCTL(name, WLC_DOWN, NULL, sizeof(val));
249        }
250
251        /* Set mode : AP, STA */
252        ap = nvram_match(strcat_r(prefix, "mode", tmp), "ap");
253        val = (ap + nvram_match(strcat_r(prefix, "mode", tmp), "wds")) ? 1 : 0;
254        WL_IOCTL(name, WLC_SET_AP, &val, sizeof(val));
255
256        /* Set STA specific parameters */
257        if (!ap) {
258                /* Set mode: WET */
259                if ((wet = nvram_match(strcat_r(prefix, "mode", tmp), "wet")))
260                        WL_IOCTL(name, WLC_SET_WET, &wet, sizeof(wet));
261                /* Set infra: BSS/IBSS */
262                if (wet || (sta = nvram_match(strcat_r(prefix, "mode", tmp), "sta"))) {
263                        val = atoi(nvram_safe_get(strcat_r(prefix, "infra", tmp)));
264                        WL_IOCTL(name, WLC_SET_INFRA, &val, sizeof(val));
265                }
266        }
267
268        /* Set network type */
269        val = atoi(nvram_safe_get(strcat_r(prefix, "closed", tmp)));
270        WL_IOCTL(name, WLC_SET_CLOSED, &val, sizeof(val));
271
272        /* Set up the country code */
273        (void) strcat_r(prefix, "country_code", tmp);
274        country = nvram_get(tmp);
275        if (country) {
276                strncpy(country_code, country, sizeof(country_code));
277                WL_IOCTL(name, WLC_SET_COUNTRY, country_code, strlen(country_code)+1);
278        }
279        else {
280                /* If country_code doesn't exist, check for country to be backward compatible */
281                (void) strcat_r(prefix, "country", tmp);
282                country = nvram_safe_get(tmp);
283                for (val = 0; val < ARRAYSIZE(countries); val++) {
284                        char **synonym;
285                        for (synonym = countries[val].names; *synonym; synonym++)
286                                if (!strcmp(country, *synonym))
287                                        break;
288                        if (*synonym)
289                                break;
290                }
291
292                /* Get the default country code if undefined or invalid and set the NVRAM */
293                if (val >= ARRAYSIZE(countries)) {
294                        WL_IOCTL(name, WLC_GET_COUNTRY, country_code, sizeof(country_code));
295                }
296                else {
297                        strncpy(country_code, countries[val].abbr, sizeof(country_code));
298                        WL_IOCTL(name, WLC_SET_COUNTRY, country_code, strlen(country_code)+1);
299                }
300
301                /* Add the new NVRAM variable */
302                nvram_set("wl_country_code", country_code);
303                (void) strcat_r(prefix, "country_code", tmp);
304                nvram_set(tmp, country_code);
305        }
306       
307        /* Set the MAC list */
308        maclist = (struct maclist *) buf;
309        maclist->count = 0;
310        if (!nvram_match(strcat_r(prefix, "macmode", tmp), "disabled")) {
311                ea = maclist->ea;
312                foreach(var, nvram_safe_get(strcat_r(prefix, "maclist", tmp)), next) {
313                        if ((&ea[1])->octet > &buf[sizeof(buf)])
314                                break;
315                        if (ether_atoe(var, ea->octet)) {
316                                maclist->count++;
317                                ea++;
318                        }
319                }
320        }
321        WL_IOCTL(name, WLC_SET_MACLIST, buf, sizeof(buf));
322
323        /* Set the MAC list mode */
324        (void) strcat_r(prefix, "macmode", tmp);
325        if (nvram_match(tmp, "deny"))
326                val = WLC_MACMODE_DENY;
327        else if (nvram_match(tmp, "allow"))
328                val = WLC_MACMODE_ALLOW;
329        else
330                val = WLC_MACMODE_DISABLED;
331        WL_IOCTL(name, WLC_SET_MACMODE, &val, sizeof(val));
332
333        /* Enable or disable the radio */
334        val = nvram_match(strcat_r(prefix, "radio", tmp), "0");
335        WL_IOCTL(name, WLC_SET_RADIO, &val, sizeof(val));
336
337        /* Get supported phy types */
338        WL_IOCTL(name, WLC_GET_PHYLIST, var, sizeof(var));
339        nvram_set(strcat_r(prefix, "phytypes", tmp), var);
340
341        /* Get radio IDs */
342        *(next = buf) = '\0';
343        for (i = 0; i < strlen(var); i++) {
344                /* Switch to band */
345                phy[0] = var[i];
346                val = WLCONF_STR2PHYTYPE(phy);
347                val = WLCONF_PHYTYPE2BAND(val);
348                WL_IOCTL(name, WLC_SET_BAND, &val, sizeof(val));
349                /* Get radio ID on this band */
350                WL_IOCTL(name, WLC_GET_REVINFO, &rev, sizeof(rev));
351                next += sprintf(next, "%sBCM%X", i ? " " : "",
352                                (rev.radiorev & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT);
353        }
354        nvram_set(strcat_r(prefix, "radioids", tmp), buf);
355
356        /* Set band */
357        str = nvram_get(strcat_r(prefix, "phytype", tmp));
358        val = WLCONF_STR2PHYTYPE(str);
359        val = WLCONF_PHYTYPE2BAND(val);
360        /* Check errors (card may have changed) */
361        if (wl_ioctl(name, WLC_SET_BAND, &val, sizeof(val))) {
362                /* default band to the first band in band list */
363                phy[0] = var[0];
364                val = WLCONF_STR2PHYTYPE(phy);
365                val = WLCONF_PHYTYPE2BAND(val);
366                WL_IOCTL(name, WLC_SET_BAND, &val, sizeof(val));
367        }
368
369        /* Get current core revision */
370        WL_IOCTL(name, WLC_GET_REVINFO, &rev, sizeof(rev));
371        snprintf(buf, sizeof(buf), "%d", rev.corerev);
372        nvram_set(strcat_r(prefix, "corerev", tmp), buf);
373
374        /* Get current phy type */
375        WL_IOCTL(name, WLC_GET_PHYTYPE, &phytype, sizeof(phytype));
376        snprintf(buf, sizeof(buf), "%s", WLCONF_PHYTYPE2STR(phytype));
377        nvram_set(strcat_r(prefix, "phytype", tmp), buf);
378
379        /* Set channel before setting gmode or rateset */
380        /* Manual Channel Selection - when channel # is not 0 */
381        val = atoi(nvram_safe_get(strcat_r(prefix, "channel", tmp)));
382        if (val) {
383                if (wl_ioctl(name, WLC_SET_CHANNEL, &val, sizeof(val))) {
384                        /* Use current channel (card may have changed) */
385                        WL_IOCTL(name, WLC_GET_CHANNEL, &ci, sizeof(ci));
386                        snprintf(buf, sizeof(buf), "%d", ci.target_channel);
387                        nvram_set(strcat_r(prefix, "channel", tmp), buf);
388                }
389        }
390       
391        /* Reset to hardware rateset (band may have changed) */
392        WL_IOCTL(name, WLC_GET_RATESET, &rs, sizeof (wl_rateset_t));
393        WL_IOCTL(name, WLC_SET_RATESET, &rs, sizeof (wl_rateset_t));
394
395        /* Set gmode */
396        if (phytype == PHY_TYPE_G) {
397
398                /* Set gmode */
399
400                gmode = atoi(nvram_safe_get(strcat_r(prefix, "gmode", tmp)));
401                if (gmode == GMODE_AFTERBURNER) {
402                        if (wl_get_int(name, "abcap", &val) || !val) {
403                                gmode = GMODE_AUTO;
404                                snprintf(buf, sizeof(buf), "%d", gmode);
405                                nvram_set(tmp, buf);
406                        }
407                }
408                WL_IOCTL(name, WLC_SET_GMODE, &gmode, sizeof(gmode));
409
410                /* Set gmode protection override and control algorithm */
411                if (gmode != GMODE_AFTERBURNER) {
412                        int override = WLC_G_PROTECTION_OFF;
413                        int control = WLC_G_PROTECTION_CTL_OFF;
414                        strcat_r(prefix, "gmode_protection", tmp);
415                        if (nvram_match(tmp, "auto")) {
416                                override = WLC_G_PROTECTION_AUTO;
417                                control = WLC_G_PROTECTION_CTL_OVERLAP;
418                        }
419                        WL_IOCTL(name, WLC_SET_GMODE_PROTECTION_OVERRIDE, &override, sizeof(override));
420                        WL_IOCTL(name, WLC_SET_GMODE_PROTECTION_CONTROL, &control, sizeof(control));
421                }
422        }
423
424        /* Get current rateset (gmode may have changed) */
425        WL_IOCTL(name, WLC_GET_CURR_RATESET, &rs, sizeof (wl_rateset_t));
426
427        strcat_r(prefix, "rateset", tmp);
428        if (nvram_match(tmp, "all"))  {
429                /* Make all rates basic */
430                for (i = 0; i < rs.count; i++)
431                        rs.rates[i] |= 0x80;
432        } else if (nvram_match(tmp, "12")) {
433                /* Make 1 and 2 basic */
434                for (i = 0; i < rs.count; i++) {
435                        if ((rs.rates[i] & 0x7f) == 2 || (rs.rates[i] & 0x7f) == 4)
436                                rs.rates[i] |= 0x80;
437                        else
438                                rs.rates[i] &= ~0x80;
439                }
440        }
441
442        /* Set rateset */
443        WL_IOCTL(name, WLC_SET_RATESET, &rs, sizeof (wl_rateset_t));
444
445        /* Allow short preamble override for b cards */
446        if (phytype == PHY_TYPE_B || gmode == 0) {
447                strcat_r(prefix, "plcphdr", tmp);               
448                if (nvram_match(tmp, "long"))
449                        val = WLC_PLCP_AUTO;
450                else
451                        val = WLC_PLCP_SHORT;
452                WL_IOCTL(name, WLC_SET_PLCPHDR, &val, sizeof(val));
453        }
454
455        /* Set rate in 500 Kbps units */
456        val = atoi(nvram_safe_get(strcat_r(prefix, "rate", tmp))) / 500000;
457        if (wl_ioctl(name, WLC_SET_RATE, &val, sizeof(val))) {
458                /* Try default rate (card may have changed) */
459                val = 0;
460                WL_IOCTL(name, WLC_SET_RATE, &val, sizeof(val));
461                snprintf(buf, sizeof(buf), "%d", val);
462                nvram_set(strcat_r(prefix, "rate", tmp), buf);
463        }
464
465        /* Set fragmentation threshold */
466        val = atoi(nvram_safe_get(strcat_r(prefix, "frag", tmp)));
467        WL_IOCTL(name, WLC_SET_FRAG, &val, sizeof(val));
468
469        /* Set RTS threshold */
470        val = atoi(nvram_safe_get(strcat_r(prefix, "rts", tmp)));
471        WL_IOCTL(name, WLC_SET_RTS, &val, sizeof(val));
472
473        /* Set DTIM period */
474        val = atoi(nvram_safe_get(strcat_r(prefix, "dtim", tmp)));
475        WL_IOCTL(name, WLC_SET_DTIMPRD, &val, sizeof(val));
476
477        /* Set beacon period */
478        val = atoi(nvram_safe_get(strcat_r(prefix, "bcn", tmp)));
479        WL_IOCTL(name, WLC_SET_BCNPRD, &val, sizeof(val));
480
481        /* Set lazy WDS mode */
482        val = atoi(nvram_safe_get(strcat_r(prefix, "lazywds", tmp)));
483        WL_IOCTL(name, WLC_SET_LAZYWDS, &val, sizeof(val));
484
485        /* Set the WDS list */
486        maclist = (struct maclist *) buf;
487        maclist->count = 0;
488        ea = maclist->ea;
489        foreach(var, nvram_safe_get(strcat_r(prefix, "wds", tmp)), next) {
490                if (ea->octet > &buf[sizeof(buf)])
491                        break;
492                ether_atoe(var, ea->octet);
493                maclist->count++;
494                ea++;
495        }
496        WL_IOCTL(name, WLC_SET_WDSLIST, buf, sizeof(buf));
497
498        /* Set framebursting mode */
499        val = nvram_match(strcat_r(prefix, "frameburst", tmp), "on");
500        WL_IOCTL(name, WLC_SET_FAKEFRAG, &val, sizeof(val));
501       
502        /* Bring the interface back up */
503        WL_IOCTL(name, WLC_UP, NULL, 0);
504
505        /* Set antenna */
506        val = atoi(nvram_safe_get(strcat_r(prefix, "antdiv", tmp)));
507        WL_IOCTL(name, WLC_SET_ANTDIV, &val, sizeof(val));
508
509        /* Auto Channel Selection - when channel # is 0 in AP mode */
510        /*
511        * The following condition(s) must be met in order for
512        * Auto Channel Selection to work.
513        *  - the I/F must be up (change radio channel requires it is up?)
514        *  - the AP must not be associated (setting SSID to empty should
515        *    make sure it for us)
516        */
517        if (ap) {
518                if (!(val = atoi(nvram_safe_get(strcat_r(prefix, "channel", tmp))))) {
519                        /* select a channel */
520                        val = wlconf_auto_channel(name);
521                        /* switch to the selected channel */
522                        WL_IOCTL(name, WLC_SET_CHANNEL, &val, sizeof(val));
523                        /* set the auto channel scan timer in the driver when in auto mode */
524                        val = 15;       /* 15 minutes for now */
525                        WL_IOCTL(name, WLC_SET_CS_SCAN_TIMER, &val, sizeof(val));
526                }
527                else {
528                        /* reset the channel scan timer in the driver when not in auto mode */
529                        val = 0;
530                        WL_IOCTL(name, WLC_SET_CS_SCAN_TIMER, &val, sizeof(val));
531                }
532        }
533
534        /* Set WEP keys */
535        for (i = 1; i <= WLC_MAX_DEFAULT_KEYS; i++)
536                wlconf_set_wep_key(name, prefix, i);
537
538        /* Set WSEC */
539        /*
540        * Need to check errors (card may have changed) and change to
541        * defaults since the new chip may not support the requested
542        * encryptions after the card has been changed.
543        */
544        if (wlconf_set_wsec(name, prefix)) {
545                /* change nvram only, code below will pass them on */
546                wlconf_restore_var(prefix, "auth_mode");
547                wlconf_restore_var(prefix, "auth");
548                /* reset wep to default */
549                wlconf_restore_var(prefix, "wep");
550                wlconf_set_wsec(name, prefix);
551        }
552
553        /* Set WPA authentication mode - radius/wpa/psk */
554        strcat_r(prefix, "auth_mode", tmp);
555        if (nvram_match(tmp, "radius"))
556                val = WPA_AUTH_DISABLED;
557        else if (nvram_match(tmp, "wpa"))
558                val = WPA_AUTH_UNSPECIFIED;
559        else if (nvram_match(tmp, "psk"))
560                val = WPA_AUTH_PSK;
561        else /* if (nvram_match(tmp, "disabled")) */
562                val = WPA_AUTH_DISABLED;
563        WL_IOCTL(name, WLC_SET_WPA_AUTH, &val, sizeof(val));
564       
565        /* Set non-WPA authentication mode - open/shared */
566        val = atoi(nvram_safe_get(strcat_r(prefix, "auth", tmp)));
567        WL_IOCTL(name, WLC_SET_AUTH, &val, sizeof(val));
568
569        /* Set WEP restrict if WEP is not disabled */
570        val = nvram_invmatch(strcat_r(prefix, "wep", tmp), "off");
571        WL_IOCTL(name, WLC_SET_WEP_RESTRICT, &val, sizeof(val));
572
573        /* Set SSID/Join network */
574        if (ap | sta | wet) {
575                strcat_r(prefix, "ssid", tmp);
576                ssid.SSID_len = strlen(nvram_safe_get(tmp));
577                if (ssid.SSID_len > sizeof(ssid.SSID))
578                        ssid.SSID_len = sizeof(ssid.SSID);
579                strncpy(ssid.SSID, nvram_safe_get(tmp), ssid.SSID_len);
580        } else {
581                /* A zero length SSID turns off the AP */
582                ssid.SSID_len = 0;
583                ssid.SSID[0] = '\0';
584        }               
585        WL_IOCTL(name, WLC_SET_SSID, &ssid, sizeof(ssid));
586       
587        return 0;
588}
589
590int
591wlconf_down(char *name)
592{
593        int val, ret = 0;
594        unsigned char buf[WLC_IOCTL_MAXLEN];
595        struct maclist *maclist;
596        wlc_ssid_t ssid;
597
598        /* Check interface (fail silently for non-wl interfaces) */
599        if ((ret = wl_probe(name)))
600                return ret;
601
602        /* Bring down the interface */
603        WL_IOCTL(name, WLC_GET_UP, &val, sizeof(val));
604        if (val) {
605                /* Nuke SSID  */
606                ssid.SSID_len = 0;
607                ssid.SSID[0] = '\0';
608                WL_IOCTL(name, WLC_SET_SSID, &ssid, sizeof(ssid));
609
610                /* Bring the interface down */
611                WL_IOCTL(name, WLC_DOWN, NULL, sizeof(val));
612        }
613
614        /* Nuke the WDS list */
615        maclist = (struct maclist *) buf;
616        maclist->count = 0;
617        WL_IOCTL(name, WLC_SET_WDSLIST, buf, sizeof(buf));
618
619        return 0;
620}
621
622int
623main(int argc, char *argv[])
624{
625        int ret = -1;
626       
627        /* Check parameters and branch based on action */
628        if (argc == 3 && !strcmp(argv[2], "up"))
629                ret = wlconf(argv[1]);
630        else if (argc == 3 && !strcmp(argv[2], "down"))
631                ret = wlconf_down(argv[1]);
632        else {
633                fprintf(stderr, "Usage: wlconf <ifname> up|down\n");
634                return -1;
635        }
636        /* Check result */
637        if (ret) {
638                fprintf(stderr, "wlconf: %s failed (%d)\n", argv[1], ret);
639                return ret;
640        }
641        return 0;
642}
Note: See TracBrowser for help on using the repository browser.