source: src/router/services/networking/madwifi_ath9k.c @ 32170

Last change on this file since 32170 was 32170, checked in by brainslayer, 7 weeks ago

only affects 88w8964

File size: 51.0 KB
Line 
1/*
2 * madwifi_ath9k.c
3 * Copyright (C) 2010 Christian Scheele <chris@dd-wrt.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version 2.1
7 * as published by the Free Software Foundation
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 */
14
15#ifdef HAVE_ATH9K
16#include <sys/mman.h>
17#include <stdio.h>
18#include <unistd.h>
19#include <signal.h>
20#include <fcntl.h>
21
22#include <sys/types.h>
23#include <sys/file.h>
24#include <sys/stat.h>
25#include <sys/ioctl.h>
26#include <sys/socket.h>
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <stdint.h>
32#include <ctype.h>
33#include <getopt.h>
34#include <err.h>
35
36#include <ctype.h>
37#include <string.h>
38#include <stdlib.h>
39#include <stdio.h>
40#include <bcmnvram.h>
41#include <wlutils.h>
42#include <cymac.h>
43#include <bcmutils.h>
44#include <shutils.h>
45#include <utils.h>
46#include <unistd.h>
47#include <glob.h>
48
49#include <services.h>
50void setupHostAP_ath9k(char *maininterface, int isfirst, int vapid, int aoss);
51static void setupSupplicant_ath9k(char *prefix, char *ssidoverride);
52void setupHostAP_generic_ath9k(char *prefix, FILE * fp, int isrepeater, int aoss);
53
54void delete_ath9k_devices(char *physical_iface)
55{
56        glob_t globbuf;
57        char globstring[1024];
58        char tmp[256];
59        int globresult;
60        if (physical_iface)
61                sprintf(globstring, "/sys/class/ieee80211/%s/device/net/*", physical_iface);
62        else
63                sprintf(globstring, "/sys/class/ieee80211/phy*/device/net/*");
64        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
65        int i;
66        for (i = 0; i < globbuf.gl_pathc; i++) {
67                char *ifname;
68                ifname = strrchr(globbuf.gl_pathv[i], '/');
69                if (!ifname)
70                        continue;
71                char dev[32];
72                sprintf(dev, "%s", ifname + 1);
73                if (has_ad(dev)) {
74                        sysprintf("echo 0 > /sys/kernel/debug/ieee80211/phy2/wil6210/led_cfg");
75                        sysprintf("echo 10000 0 10000 0 10000 0 > /sys/kernel/debug/ieee80211/phy2/wil6210/led_blink_time");
76                        br_del_interface(getBridge("ath2", tmp), dev);
77                } else
78                        br_del_interface(getBridge(dev, tmp), dev);
79                eval("ifconfig", dev, "down");
80                eval("iw", dev, "del");
81        }
82}
83
84void deconfigure_single_ath9k(int count)
85{
86        int idx = get_ath9k_phy_idx(count);
87        fprintf(stderr, "ath9k deconfigure_single: phy%d ath%d\n", idx, count);
88        char wif[10];
89        sprintf(wif, "phy%d", idx);
90        sysprintf("rm -f /tmp/ath%d_hostapd.conf", idx);
91        sysprintf("rm -f /tmp/ath%d_wpa_supplicant.conf", idx);
92        delete_ath9k_devices(wif);
93}
94
95void configure_single_ath9k(int count)
96{
97        char *next;
98        char var[80];
99        char mode[80];
100        int cnt = 0;
101        char dev[10];
102        char wif[10];
103        int phy_idx = get_ath9k_phy_idx(count);
104        char mtikie[32];
105        char wl[16];
106        char channel[16];
107        char ssid[16];
108        char net[16];
109        char wifivifs[16];
110        char broadcast[16];
111        char sens[32];
112        char basedev[16];
113        char diversity[32];
114        char athmac[16];
115        char wl_poll[32];
116        char rxantenna[32];
117        char txantenna[32];
118        static int vapcount = 0;
119        int isath5k = 0;
120        char *apm;
121        char isolate[32];
122        char primary[32] = { 0 };
123        char regdomain[16];
124        char *country;
125        sprintf(dev, "ath%d", count);
126        isath5k = is_ath5k(dev);
127        // sprintf(regdomain, "%s_regdomain", dev);
128        // country = nvram_default_get(regdomain, "US");
129        // sysprintf("iw reg set %s", getIsoName(country));
130        // // sleep(3);
131        if (count == 0)
132                vapcount = 0;
133        sprintf(wif, "phy%d", phy_idx);
134        sprintf(wifivifs, "ath%d_vifs", count);
135        fprintf(stderr, "ath9k configure_single: phy%d ath%d\n", phy_idx, count);
136        sprintf(channel, "ath%d_channel", count);
137        sprintf(sens, "ath%d_distance", count);
138        sprintf(diversity, "ath%d_diversity", count);
139        sprintf(athmac, "ath%d_hwaddr", count);
140        sprintf(rxantenna, "ath%d_rxantenna", count);
141        sprintf(txantenna, "ath%d_txantenna", count);
142        // create base device
143        cprintf("configure base interface %d / %s\n", count, dev);
144        sprintf(net, "%s_net_mode", dev);
145        char *netmode = nvram_default_get(net, "mixed");
146        if (!strcmp(netmode, "disabled"))
147                return;
148        char bw[32];
149
150        // set channelbw ht40 is also 20!
151
152        sprintf(bw, "%s_channelbw", dev);
153        if (isath5k) {
154                if (nvram_matchi(bw, 5))
155                        sysprintf("echo 5 > /sys/kernel/debug/ieee80211/%s/ath5k/bwmode", wif);
156                else if (nvram_matchi(bw, 10))
157                        sysprintf("echo 10 > /sys/kernel/debug/ieee80211/%s/ath5k/bwmode", wif);
158                else if (nvram_matchi(bw, 40))
159                        sysprintf("echo 40 > /sys/kernel/debug/ieee80211/%s/ath5k/bwmode", wif);
160                else
161                        sysprintf("echo 20 > /sys/kernel/debug/ieee80211/%s/ath5k/bwmode", wif);
162        } else {
163                if (nvram_matchi(bw, 5))
164                        sysprintf("echo 5 > /sys/kernel/debug/ieee80211/%s/ath9k/chanbw", wif);
165                else if (nvram_matchi(bw, 10))
166                        sysprintf("echo 10 > /sys/kernel/debug/ieee80211/%s/ath9k/chanbw", wif);
167                else
168                        sysprintf("echo 20 > /sys/kernel/debug/ieee80211/%s/ath9k/chanbw", wif);
169        }
170        char wl_intmit[32];
171
172        sprintf(wl_intmit, "%s_intmit", dev);
173
174#ifdef HAVE_ATH10K
175        if (is_ath10k(dev))
176                sysprintf("echo %s > /sys/kernel/debug/ieee80211/%s/ath10k/ani_enable", nvram_default_get(wl_intmit, "0"), wif);
177        else
178#endif
179                sysprintf("echo %s > /sys/kernel/debug/ieee80211/%s/ath9k/ani", nvram_default_get(wl_intmit, "1"), wif);
180#ifdef HAVE_REGISTER
181        int cpeonly = iscpe();
182#else
183        int cpeonly = 0;
184#endif
185        int maxrxchain = mac80211_get_avail_rx_antenna(phy_idx);
186        int maxtxchain = mac80211_get_avail_tx_antenna(phy_idx);
187        int txchain;
188        int rxchain;
189        if (strlen(nvram_safe_get(rxantenna)) == 0 || strlen(nvram_safe_get(txantenna)) == 0) {
190                txchain = maxtxchain;
191                rxchain = maxrxchain;
192        } else {
193                txchain = nvram_geti(txantenna);
194                rxchain = nvram_geti(rxantenna);
195        }
196        int reset = 0;
197        if (txchain > maxtxchain) {
198                reset = 1;
199                txchain = maxtxchain;
200        }
201        if (rxchain > maxrxchain) {
202                reset = 1;
203                rxchain = maxrxchain;
204        }
205
206        char rxdefstr[32];
207        char txdefstr[32];
208        sprintf(txdefstr, "%d", rxchain);
209        sprintf(rxdefstr, "%d", txchain);
210        if (reset) {
211                nvram_set(txantenna, txdefstr);
212                nvram_set(rxantenna, rxdefstr);
213        } else {
214                nvram_default_get(txantenna, txdefstr);
215                nvram_default_get(rxantenna, rxdefstr);
216        }
217        if (!has_ad(dev))
218                mac80211_set_antennas(phy_idx, txchain, rxchain);
219
220        sprintf(wl, "ath%d_mode", count);
221        apm = nvram_default_get(wl, "ap");
222
223        if (!strcmp(apm, "ap") || !strcmp(apm, "wdsap") || !strcmp(apm, "sta")
224            || !strcmp(apm, "wet")) {
225
226                eval("iw", wif, "interface", "add", dev, "type", "managed");
227
228                strcpy(primary, dev);
229        } else if (!strcmp(apm, "wdssta")) {
230                eval("iw", wif, "interface", "add", dev, "type", "managed", "4addr", "on");
231
232                strcpy(primary, dev);
233        } else {
234                eval("iw", wif, "interface", "add", dev, "type", "ibss");
235                // still TBD ;-)
236                // ifconfig ath0 up
237                // iw dev ath0 ibss join AdHocNetworkName 2412
238        }
239
240        char macaddr[32];
241        // interface is created at this point, so that should work
242#if defined(HAVE_MVEBU) || defined(HAVE_IPQ806X)
243        getWirelessMac(macaddr, count);
244        eval("ifconfig", dev, "hw", "ether", macaddr);
245#else
246        getMacAddr(dev, macaddr);
247#endif
248        nvram_set(athmac, macaddr);
249        int distance = nvram_default_geti(sens, 2000);  // to meter
250        char dist[32];
251        if (distance > 0)
252                sprintf(dist, "%d", distance);
253        else
254                sprintf(dist, "auto");
255        eval("iw", "phy", wif, "set", "distance", dist);
256#ifdef HAVE_ATH10K
257//      if (is_ath10k(dev) && !is_mvebu(dev)) { // evil hack for QCA
258//              set_ath10kdistance(dev, distance);
259//      }
260#endif
261// das scheint noch aerger zu machen
262        eval("iw", "dev", dev, "set", "power_save", "off");
263
264        cprintf("done()\n");
265
266        cprintf("setup encryption");
267        // setup encryption
268        int isfirst = 1;
269        if (strcmp(apm, "sta") && strcmp(apm, "wdssta") && strcmp(apm, "wet")) {
270                setupHostAP_ath9k(dev, isfirst, 0, 0);
271                isfirst = 0;
272        } else {
273                char *clonename = "def_whwaddr";
274                if (!strcmp(apm, "sta"))
275                        clonename = "def_hwaddr";
276                if (nvram_matchi("mac_clone_enable", 1)
277                    && nvram_invmatch(clonename, "00:00:00:00:00:00")
278                    && nvram_invmatch(clonename, "")) {
279                        eval("ifconfig", dev, "hw", "ether", nvram_safe_get(clonename));
280                }
281
282                setupSupplicant_ath9k(dev, NULL);
283        }
284        char *vifs = nvram_safe_get(wifivifs);
285        int countvaps = 1;
286        foreach(var, vifs, next) {
287                countvaps++;
288        }
289        if (countvaps < 4)
290                countvaps = 4;
291        if (countvaps > vapcount)
292                vapcount = countvaps;
293        int counter = 1;
294        if (strlen(vifs) > 0)
295                foreach(var, vifs, next) {
296                fprintf(stderr, "setup vifs %s %d\n", var, counter);
297                // create the first main hostapd interface when this is repeater mode
298                if (isfirst)
299                        sysprintf("iw %s interface add %s.%d type managed", wif, dev, counter);
300                setupHostAP_ath9k(dev, isfirst, counter, 0);
301                isfirst = 0;
302                counter++;
303                }
304        if (has_ad(dev)) {
305                sysprintf("echo 0 > /sys/kernel/debug/ieee80211/phy2/wil6210/led_polarity");
306                sysprintf("echo 1 > /sys/kernel/debug/ieee80211/phy2/wil6210/led_cfg");
307                sysprintf("echo 10000 0 200 200 100 100 > /sys/kernel/debug/ieee80211/phy2/wil6210/led_blink_time");
308
309        }
310
311}
312
313void setupHostAP_generic_ath9k(char *prefix, FILE * fp, int isrepeater, int aoss)
314{
315        struct wifi_channels *chan;
316        int channel = 0;
317        int freq = 0;
318        char nfreq[16];
319        int i = 0;
320        char *caps;
321        int isath5k = is_ath5k(prefix);
322        fprintf(fp, "driver=nl80211\n");
323        fprintf(fp, "ctrl_interface=/var/run/hostapd\n");
324        fprintf(fp, "wmm_ac_bk_cwmin=4\n");
325        fprintf(fp, "wmm_ac_bk_cwmax=10\n");
326        fprintf(fp, "wmm_ac_bk_aifs=7\n");
327        fprintf(fp, "wmm_ac_bk_txop_limit=0\n");
328        fprintf(fp, "wmm_ac_bk_acm=0\n");
329        fprintf(fp, "wmm_ac_be_aifs=3\n");
330        fprintf(fp, "wmm_ac_be_cwmin=4\n");
331        fprintf(fp, "wmm_ac_be_cwmax=10\n");
332        fprintf(fp, "wmm_ac_be_acm=0\n");
333        fprintf(fp, "wmm_ac_vi_aifs=2\n");
334        fprintf(fp, "wmm_ac_vi_cwmin=3\n");
335        fprintf(fp, "wmm_ac_vi_cwmax=4\n");
336        fprintf(fp, "wmm_ac_vi_txop_limit=94\n");
337        fprintf(fp, "wmm_ac_vi_acm=0\n");
338        fprintf(fp, "wmm_ac_vo_aifs=2\n");
339        fprintf(fp, "wmm_ac_vo_cwmin=2\n");
340        fprintf(fp, "wmm_ac_vo_cwmax=3\n");
341        fprintf(fp, "wmm_ac_vo_txop_limit=47\n");
342        fprintf(fp, "wmm_ac_vo_acm=0\n");
343        fprintf(fp, "tx_queue_data3_aifs=7\n");
344        fprintf(fp, "tx_queue_data3_cwmin=15\n");
345        fprintf(fp, "tx_queue_data3_cwmax=1023\n");
346        fprintf(fp, "tx_queue_data3_burst=0\n");
347        fprintf(fp, "tx_queue_data2_aifs=3\n");
348        fprintf(fp, "tx_queue_data2_cwmin=15\n");
349        fprintf(fp, "tx_queue_data2_cwmax=63\n");
350        fprintf(fp, "tx_queue_data1_aifs=1\n");
351        fprintf(fp, "tx_queue_data1_cwmin=7\n");
352        fprintf(fp, "tx_queue_data1_cwmax=15\n");
353        fprintf(fp, "tx_queue_data1_burst=3.0\n");
354        fprintf(fp, "tx_queue_data0_aifs=1\n");
355        fprintf(fp, "tx_queue_data0_cwmin=3\n");
356        fprintf(fp, "tx_queue_data0_cwmax=7\n");
357        fprintf(fp, "tx_queue_data0_burst=1.5\n");
358        char *country = getIsoName(nvram_default_get("ath0_regdomain", "UNITED_STATES"));
359        if (!country)
360                country = "DE";
361        fprintf(fp, "country_code=%s\n", country);
362        char *netmode = nvram_nget("%s_net_mode", prefix);
363        if (isath5k || !(!strcmp(netmode, "n2-only") || !strcmp(netmode, "n5-only"))) {
364                fprintf(fp, "tx_queue_data2_burst=2.0\n");
365                fprintf(fp, "wmm_ac_be_txop_limit=64\n");
366        } else {
367                fprintf(fp, "tx_queue_data2_burst=0\n");
368                fprintf(fp, "wmm_ac_be_txop_limit=0\n");
369        }
370
371        char *akm = nvram_nget("%s_akm", prefix);
372        char *crypto = nvram_nget("%s_crypto", prefix);
373        char *ht = NULL;
374        int iht = 0;
375        int channeloffset = 6;
376        char bw[32];
377        sprintf(bw, "%s_channelbw", prefix);
378        int usebw = 20;
379        if (nvram_matchi(bw, 40))
380                usebw = 40;
381        if (nvram_matchi(bw, 2040))
382                usebw = 40;
383        if (nvram_matchi(bw, 80))
384                usebw = 80;
385        if (nvram_matchi(bw, 160))
386                usebw = 160;
387        if (nvram_match(bw, "80+80"))
388                usebw = 8080;
389
390        if ((!strcmp(netmode, "ng-only") ||     //
391             !strcmp(netmode, "na-only") ||     //
392             !strcmp(netmode, "n2-only") ||     //
393             !strcmp(netmode, "n5-only") ||     //
394             !strcmp(netmode, "ac-only") ||     //
395             !strcmp(netmode, "acn-mixed") ||   //
396             !strcmp(netmode, "mixed"))
397            && strcmp(akm, "wep")
398            && !aoss) {
399
400                if (strcmp(netmode, "mixed") && strcmp(netmode, "ng-only")
401                    && strcmp(netmode, "na-only")) {
402                        if (!isath5k)
403                                fprintf(fp, "require_ht=1\n");
404                }
405                if (!isath5k && !has_ad(prefix)) {
406                        fprintf(fp, "ieee80211n=1\n");
407                        if (nvram_matchi(bw, 2040)) {
408                                fprintf(fp, "dynamic_ht40=1\n");
409                        } else {
410                                fprintf(fp, "dynamic_ht40=0\n");
411                        }
412                }
413                char sb[32];
414                sprintf(sb, "%s_nctrlsb", prefix);
415                switch (usebw) {
416                case 40:
417                        if (nvram_default_match(sb, "ull", "luu") || nvram_match(sb, "upper")) {
418                                ht = "HT40+";
419                                iht = 1;
420                        }
421                        if (nvram_match(sb, "luu") || nvram_match(sb, "lower")) {
422                                ht = "HT40-";
423                                iht = -1;
424                        }
425                        break;
426                case 80:
427                case 8080:
428                        if (nvram_default_match(sb, "ulu", "lul") || nvram_match(sb, "upper")) {
429                                ht = "HT40+";
430                                iht = 1;
431                                channeloffset = 6;
432                        }
433                        if (nvram_match(sb, "ull")) {
434                                ht = "HT40+";
435                                iht = 1;
436                                channeloffset = 2;
437                        }
438                        if (nvram_match(sb, "luu")) {
439                                ht = "HT40-";
440                                iht = -1;
441                                channeloffset = 2;
442                        }
443                        if (nvram_match(sb, "lul") || nvram_match(sb, "lower")) {
444                                ht = "HT40-";
445                                iht = -1;
446                                channeloffset = 6;
447                        }
448                        break;
449                case 160:
450                        if (nvram_default_match(sb, "uuu", "lll") || nvram_match(sb, "upper")) {
451                                ht = "HT40+";
452                                iht = 1;
453                                channeloffset = 14;
454                        }
455                        if (nvram_match(sb, "uul")) {
456                                ht = "HT40+";
457                                iht = 1;
458                                channeloffset = 10;
459                        }
460                        if (nvram_match(sb, "ulu")) {
461                                ht = "HT40+";
462                                iht = 1;
463                                channeloffset = 6;
464                        }
465                        if (nvram_match(sb, "ull")) {
466                                ht = "HT40+";
467                                iht = 1;
468                                channeloffset = 2;
469                        }
470                        if (nvram_match(sb, "luu")) {
471                                ht = "HT40-";
472                                iht = -1;
473                                channeloffset = 2;
474                        }
475                        if (nvram_match(sb, "lul")) {
476                                ht = "HT40-";
477                                iht = -1;
478                                channeloffset = 6;
479                        }
480                        if (nvram_match(sb, "llu")) {
481                                ht = "HT40-";
482                                iht = -1;
483                                channeloffset = 10;
484                        }
485                        if (nvram_match(sb, "lll") || nvram_match(sb, "lower")) {
486                                ht = "HT40-";
487                                iht = -1;
488                                channeloffset = 14;
489                        }
490                        break;
491                case 20:
492                default:
493                        ht = "HT20";
494                        break;
495                }
496        } else {
497                ht = "HT20";
498        }
499        char regdomain[16];
500        sprintf(regdomain, "%s_regdomain", prefix);
501
502        chan = mac80211_get_channels(prefix, country, usebw, 0xff);
503        if (isrepeater) {
504                // for ht40- take second channel otherwise hostapd is unhappy (and does not start)
505                if (has_2ghz(prefix)) {
506                        if (iht == -1) {
507                                i = 4;  // in 2.4 mhz channel spacing is different
508                        }
509                }
510                if (has_5ghz(prefix)) {
511                        if (iht == -1) {
512                                i = 1;
513                        }
514                }
515                switch (usebw) {
516                case 160:
517                        channel = 100;
518                        ht = "HT40+";
519                        iht = 1;
520                        channeloffset = 14;
521                        freq = 5500;
522                        break;
523                case 80:
524                case 8080:
525                        channel = 100;
526                        ht = "HT40+";
527                        channeloffset = 6;
528                        iht = 1;
529                        freq = 5500;
530                        break;
531                case 40:
532                        ht = "HT40+";
533                        if (has_2ghz(prefix)) {
534                                channel = 6;
535                                freq = 2437;
536                        }
537                        if (has_5ghz(prefix)) {
538                                channel = 100;
539                                freq = 5500;
540                        }
541                        break;
542                case 20:
543                        ht = "HT20";
544                default:
545                        if (has_2ghz(prefix)) {
546                                channel = 6;
547                                freq = 2437;
548                        }
549                        if (has_5ghz(prefix)) {
550                                channel = 100;
551                                freq = 5500;
552                        }
553                        break;
554                }
555        } else {
556                // also we still should take care on the selected mode
557                sprintf(nfreq, "%s_channel", prefix);
558                freq = nvram_default_geti(nfreq, 0);
559
560                if (freq == 0) {
561                        if (has_ad(prefix)) {
562                                channel = 1;
563                                freq = 53320;
564                        } else {
565                                struct mac80211_ac *acs;
566                                fprintf(stderr, "call mac80211autochannel for interface: %s\n", prefix);
567                                eval("ifconfig", prefix, "up");
568                                switch (usebw) {
569                                case 40:
570                                        acs = mac80211autochannel(prefix, NULL, 2, 1, 0, AUTO_FORCEHT40);
571                                        break;
572                                case 80:
573                                        acs = mac80211autochannel(prefix, NULL, 2, 1, 0, AUTO_FORCEVHT80);
574                                        break;
575                                case 160:
576                                case 8080:
577                                        acs = mac80211autochannel(prefix, NULL, 2, 1, 0, AUTO_FORCEVHT160);
578                                        break;
579                                default:
580                                        acs = mac80211autochannel(prefix, NULL, 2, 1, 0, AUTO_ALL);
581                                }
582                                if (acs != NULL) {
583                                        freq = acs->freq;
584                                        channel = ieee80211_mhz2ieee(freq);
585                                        fprintf(stderr, "mac80211autochannel interface: %s frequency: %d\n", prefix, freq);
586                                        int i = 0;
587                                        while (chan[i].freq != -1) {
588                                                if (chan[i].freq == freq)
589                                                        break;
590                                                i++;
591                                        }
592                                        switch (usebw) {
593                                        case 40:
594                                                if (chan[i].luu) {
595                                                        ht = "HT40-";
596                                                        iht = -1;
597                                                } else if (chan[i].ull) {
598                                                        ht = "HT40+";
599                                                        iht = 1;
600                                                }
601                                                break;
602                                        case 80:
603                                        case 8080:
604                                                if (chan[i].luu) {
605                                                        ht = "HT40-";
606                                                        channeloffset = 2;
607                                                        iht = -1;
608                                                } else if (chan[i].ulu) {
609                                                        ht = "HT40+";
610                                                        iht = 1;
611                                                        channeloffset = 6;
612                                                } else if (chan[i].lul) {
613                                                        ht = "HT40-";
614                                                        channeloffset = 6;
615                                                        iht = -1;
616                                                } else if (chan[i].ull) {
617                                                        ht = "HT40+";
618                                                        iht = 1;
619                                                        channeloffset = 2;
620                                                }
621                                                break;
622                                        case 160:
623                                                if (chan[i].uuu) {
624                                                        ht = "HT40+";
625                                                        iht = 1;
626                                                        channeloffset = 14;
627                                                } else if (chan[i].uul) {
628                                                        ht = "HT40+";
629                                                        iht = 1;
630                                                        channeloffset = 10;
631                                                } else if (chan[i].ulu) {
632                                                        ht = "HT40+";
633                                                        iht = 1;
634                                                        channeloffset = 6;
635                                                } else if (chan[i].ull) {
636                                                        ht = "HT40+";
637                                                        iht = 1;
638                                                        channeloffset = 2;
639                                                } else if (chan[i].luu) {
640                                                        ht = "HT40-";
641                                                        iht = -1;
642                                                        channeloffset = 2;
643                                                } else if (chan[i].lul) {
644                                                        ht = "HT40-";
645                                                        iht = -1;
646                                                        channeloffset = 6;
647                                                } else if (chan[i].llu) {
648                                                        ht = "HT40-";
649                                                        iht = -1;
650                                                        channeloffset = 10;
651                                                } else if (chan[i].lll) {
652                                                        ht = "HT40-";
653                                                        iht = -1;
654                                                        channeloffset = 14;
655                                                }
656                                                break;
657                                        default:
658                                        case 20:
659                                                ht = "HT20";
660                                                break;
661                                        }
662                                        free_mac80211_ac(acs);
663                                } else {
664                                        if (has_2ghz(prefix)) {
665                                                channel = 6;
666                                                freq = 2437;
667                                        }
668                                        if (has_5ghz(prefix)) {
669                                                switch (usebw) {
670                                                case 8080:
671                                                case 80:
672                                                        channel = 100;
673                                                        ht = "HT40+";
674                                                        iht = 1;
675                                                        channeloffset = 6;
676                                                        freq = 5500;
677                                                        break;
678                                                case 160:
679                                                        channel = 100;
680                                                        ht = "HT40+";
681                                                        iht = 1;
682                                                        channeloffset = 14;
683                                                        freq = 5500;
684                                                        break;
685                                                case 40:
686                                                        channel = 100;
687                                                        ht = "HT40+";
688                                                        iht = 1;
689                                                        freq = 5500;
690                                                        break;
691                                                case 20:
692                                                default:
693                                                        ht = "HT20";
694                                                        channel = 100;
695                                                        freq = 5500;
696                                                        break;
697
698                                                }
699                                        }
700                                }
701                        }
702                } else {
703                        channel = ieee80211_mhz2ieee(freq);
704                }
705        }
706        if (!isath5k && !has_ad(prefix)) {
707                char shortgi[32];
708                sprintf(shortgi, "%s_shortgi", prefix);
709                char greenfield[32];
710                sprintf(greenfield, "%s_gf", prefix);
711                caps = mac80211_get_caps(prefix, nvram_default_match(shortgi, "1", "1") ? 1 : 0, nvram_default_match(greenfield, "1", "0") ? 1 : 0);
712                if (ht) {
713                        fprintf(fp, "ht_capab=[%s]%s\n", ht, caps);
714                } else {
715                        fprintf(fp, "ht_capab=%s\n", caps);
716                }
717                free(caps);
718        }
719#ifdef HAVE_ATH10K
720        if (has_ac(prefix) && has_2ghz(prefix) && usebw < 80) {
721                if (nvram_nmatch("1", "%s_turbo_qam", prefix)) {
722                        char mubf[32];
723                        sprintf(mubf, "%s_mubf", prefix);
724                        char subf[32];
725                        sprintf(subf, "%s_subf", prefix);
726                        caps = mac80211_get_vhtcaps(prefix, 0, 0, 0, 0, nvram_default_match(subf, "1", "0"), nvram_default_match(mubf, "1", "0"));
727                        fprintf(fp, "vht_capab=%s\n", caps);
728                        //fprintf(fp, "ieee80211ac=1\n");
729                        //fprintf(fp, "require_vht=1\n");
730                        fprintf(fp, "vendor_vht=1\n");
731                        free(caps);
732                }
733
734        }
735        if (has_ac(prefix) && has_5ghz(prefix)) {
736                if ((!strcmp(netmode, "mixed") ||       //
737                     !strcmp(netmode, "ac-only") || !strcmp(netmode, "acn-mixed"))) {
738                        char shortgi[32];
739                        sprintf(shortgi, "%s_shortgi", prefix);
740                        char mubf[32];
741                        sprintf(mubf, "%s_mubf", prefix);
742                        char subf[32];
743                        sprintf(subf, "%s_subf", prefix);
744                        caps =
745                            mac80211_get_vhtcaps(prefix, nvram_default_match(shortgi, "1", "1") ? 1 : 0, (usebw == 80 || usebw == 160 || usebw == 8080) ? 1 : 0, usebw == 160 ? 1 : 0, usebw == 8080 ? 1 : 0,
746                                                 nvram_default_match(subf, "1", "0"), nvram_default_match(mubf, "1", "0"));
747                        if (strlen(caps)) {
748                                fprintf(fp, "vht_capab=%s\n", caps);
749                                free(caps);
750                                fprintf(fp, "ieee80211ac=1\n");
751                                if (!strcmp(netmode, "ac-only")) {
752                                        fprintf(fp, "require_vht=1\n");
753                                        fprintf(fp, "ieee80211d=1\n");
754                                        fprintf(fp, "ieee80211h=1\n");
755                                        //might be needed for dfs
756                                        //fprintf(fp, "spectrum_mgmt_required=1\n");
757                                        //fprintf(fp, "local_pwr_constraint=3\n");
758                                }
759
760                                if (!strcmp(netmode, "acn-mixed")) {
761                                        fprintf(fp, "require_ht=1\n");
762                                        fprintf(fp, "ieee80211d=1\n");
763                                        fprintf(fp, "ieee80211h=1\n");
764                                        //might be needed for dfs
765                                        //fprintf(fp, "spectrum_mgmt_required=1\n");
766                                        //fprintf(fp, "local_pwr_constraint=3\n");
767                                }
768                                switch (usebw) {
769                                case 40:
770                                        fprintf(fp, "vht_oper_chwidth=0\n");
771                                        fprintf(fp, "vht_oper_centr_freq_seg0_idx=%d\n", channel + (2 * iht));
772                                        break;
773                                case 80:
774                                        fprintf(fp, "vht_oper_chwidth=1\n");
775                                        fprintf(fp, "vht_oper_centr_freq_seg0_idx=%d\n", channel + (channeloffset * iht));
776                                        break;
777                                case 160:
778                                        fprintf(fp, "vht_oper_chwidth=2\n");
779                                        fprintf(fp, "vht_oper_centr_freq_seg0_idx=%d\n", channel + (channeloffset * iht));
780                                        break;
781                                case 8080:
782                                        fprintf(fp, "vht_oper_chwidth=3\n");
783                                        fprintf(fp, "vht_oper_centr_freq_seg0_idx=%d\n", channel + (channeloffset * iht));
784                                        fprintf(fp, "vht_oper_centr_freq_seg1_idx=155\n");
785                                        break;
786                                default:
787                                        fprintf(fp, "vht_oper_chwidth=0\n");
788                                        break;
789
790                                }
791                        }
792
793                }
794
795        }
796#endif
797
798        if (chan)
799                free(chan);
800        if (has_ad(prefix)) {
801                fprintf(fp, "hw_mode=ad\n");
802        } else if (freq < 4000) {
803                if (!strcmp(netmode, "b-only")) {
804                        fprintf(fp, "hw_mode=b\n");
805                        fprintf(fp, "supported_rates=10 20 55 110\n");
806                } else {
807                        fprintf(fp, "hw_mode=g\n");
808                }
809        } else {
810                fprintf(fp, "hw_mode=a\n");
811                if (!strcmp(netmode, "a-only")) {
812                        fprintf(fp, "supported_rates=60 90 120 180 240 360 480 540\n");
813                }
814
815        }
816
817        fprintf(fp, "channel=%d\n", channel);
818        if (!has_ad(prefix))
819                fprintf(fp, "frequency=%d\n", freq);
820        char bcn[32];
821        sprintf(bcn, "%s_bcn", prefix);
822        fprintf(fp, "beacon_int=%s\n", nvram_default_get(bcn, "100"));
823        fprintf(fp, "\n");
824
825        char dtim[32];
826        sprintf(dtim, "%s_dtim", prefix);
827        fprintf(fp, "dtim_period=%s\n", nvram_default_get(dtim, "2"));
828        fprintf(fp, "\n");
829}
830
831static void setMacFilter(FILE * fp, char *iface)
832{
833        char *next;
834        char var[32];
835        char nvvar[32];
836        sprintf(nvvar, "%s_macmode", iface);
837        if (nvram_match(nvvar, "deny")) {
838                fprintf(fp, "deny_mac_file=/tmp/%s_deny\n", iface);
839                fprintf(fp, "macaddr_acl=0\n");
840                char nvlist[32];
841                sprintf(nvlist, "%s_maclist", iface);
842                char name[32];
843                sprintf(name, "/tmp/%s_deny", iface);
844                FILE *out = fopen(name, "wb");
845                foreach(var, nvram_safe_get(nvlist), next) {
846                        fprintf(out, "%s\n", var);
847                }
848                fclose(out);
849        } else if (nvram_match(nvvar, "allow")) {
850
851                fprintf(fp, "accept_mac_file=/tmp/%s_accept\n", iface);
852                fprintf(fp, "macaddr_acl=1\n");
853                char nvlist[32];
854                sprintf(nvlist, "%s_maclist", iface);
855                char name[32];
856                sprintf(name, "/tmp/%s_accept", iface);
857                FILE *out = fopen(name, "wb");
858                foreach(var, nvram_safe_get(nvlist), next) {
859                        fprintf(out, "%s\n", var);
860                }
861                fclose(out);
862        }
863
864}
865
866static int ieee80211_aton(char *str, unsigned char mac[6])
867{
868        unsigned int addr[6];
869        int i;
870        if (sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6)
871                return -1;
872        /*
873         * sscanf needs an unsigned int, but mac address bytes cannot exceed 0xff
874         */
875        for (i = 0; i < 6; i++)
876                mac[i] = addr[i] & 0xff;
877        return 0;
878}
879
880extern char *hostapd_eap_get_types(void);
881extern void addWPS(FILE * fp, char *prefix, int configured);
882extern void setupHS20(FILE * fp, char *prefix);
883
884void setupHostAP_ath9k(char *maininterface, int isfirst, int vapid, int aoss)
885{
886#ifdef HAVE_REGISTER
887        if (!isregistered())
888                return;
889#endif
890        char psk[32];
891        char akm[16];
892        char fstr[32];
893        FILE *fp = NULL;
894        char *ssid;
895        char nssid[16];
896        char maxassoc[32];
897        char ifname[10];
898        int isrepeater = 0;
899        unsigned char hwbuff[16];
900        char macaddr[32];
901        char *types;
902        char *debug;
903        char tmp[256];
904        if (isfirst && vapid == 0) {
905                sprintf(ifname, "%s", maininterface);
906        } else {
907                sprintf(ifname, "%s.%d", maininterface, vapid);
908                isrepeater = 1;
909        }
910#ifdef HAVE_WZRHPAG300NH
911        if (aoss) {
912                if (!strncmp(ifname, "ath0", 4))
913                        sprintf(ifname, "aossg");
914                else
915                        sprintf(ifname, "aossa");
916        }
917#else
918        if (aoss)
919                sprintf(ifname, "aoss");
920#endif
921        sprintf(akm, "%s_akm", ifname);
922        if (nvram_match(akm, "8021X"))
923                return;
924        sprintf(fstr, "/tmp/%s_hostap.conf", maininterface);
925        if (isfirst) {
926                fp = fopen(fstr, "wb");
927                setupHostAP_generic_ath9k(maininterface, fp, isrepeater, aoss);
928                if (has_ad(ifname))
929                        fprintf(fp, "interface=giwifi\n");
930                else
931                        fprintf(fp, "interface=%s\n", ifname);
932        } else {
933                fp = fopen(fstr, "ab");
934                fprintf(stderr, "setup vap %d bss %s\n", vapid, ifname);
935                fprintf(fp, "bss=%s\n", ifname);
936        }
937        fprintf(fp, "disassoc_low_ack=1\n");
938        char *mode = nvram_nget("%s_mode", ifname);
939        if (!strcmp(mode, "wdsap"))
940                fprintf(fp, "wds_sta=1\n");
941
942        char wmm[32];
943        sprintf(wmm, "%s_wmm", ifname);
944        fprintf(fp, "wmm_enabled=%s\n", nvram_default_get(wmm, "1"));
945        if (nvram_matchi("mac_clone_enable", 1)
946            && nvram_invmatch("def_whwaddr", "00:00:00:00:00:00")
947            && nvram_invmatch("def_whwaddr", "")
948            && !strcmp(maininterface, "ath0")) {
949                ieee80211_aton(nvram_safe_get("def_whwaddr"), hwbuff);
950        } else {
951                int i = wl_hwaddr(maininterface, hwbuff);
952        }
953
954        if (vapid > 0) {
955                if (getRouterBrand() == ROUTER_WRT_3200ACM) {
956                        hwbuff[0] |= 0x2;
957                        hwbuff[5] += vapid & 0xf;
958                } else {
959                        hwbuff[0] ^= ((vapid - 1) << 2) | 0x2;
960                }
961
962        }
963        sprintf(macaddr, "%02X:%02X:%02X:%02X:%02X:%02X", hwbuff[0], hwbuff[1], hwbuff[2], hwbuff[3], hwbuff[4], hwbuff[5]);
964//              MAC_ADD(macaddr);
965
966        if (!has_ad(maininterface)) {
967                fprintf(fp, "bssid=%s\n", macaddr);
968        }
969        char vathmac[16];
970        sprintf(vathmac, "%s_hwaddr", ifname);
971        nvram_set(vathmac, macaddr);
972        fprintf(stderr, "setup %s %s\n", ifname, macaddr);
973        setMacFilter(fp, ifname);
974        char isolate[32];
975        char broadcast[32];
976        sprintf(isolate, "%s_ap_isolate", ifname);
977        if (nvram_default_match(isolate, "1", "0"))
978                fprintf(fp, "ap_isolate=1\n");
979        sprintf(broadcast, "%s_closed", ifname);
980        if (nvram_default_match(broadcast, "1", "0"))
981                fprintf(fp, "ignore_broadcast_ssid=1\n");
982        else
983                fprintf(fp, "ignore_broadcast_ssid=0\n");
984        sprintf(maxassoc, "%s_maxassoc", ifname);
985        fprintf(fp, "max_num_sta=%s\n", nvram_default_get(maxassoc, "256"));
986        if (aoss) {
987                if (!strncmp(ifname, "aossa", 5))
988                        ssid = "ESSID-AOSS-1";
989                else
990                        ssid = "ESSID-AOSS";
991        } else {
992                sprintf(nssid, "%s_ssid", ifname);
993                ssid = nvram_default_get(nssid, "dd-wrt");
994        }
995
996        fprintf(fp, "ssid=%s\n", ssid);
997        // wep key support
998        if (nvram_match(akm, "wep") || aoss) {
999//              if (!isfirst || aoss)
1000//                      fprintf(fp, "ieee80211n=0\n");
1001
1002                if (nvram_nmatch("1", "%s_bridged", ifname))
1003                        fprintf(fp, "bridge=%s\n", getBridge(ifname, tmp));
1004                if (!aoss) {
1005                        if (!strncmp(ifname, "ath0", 4))
1006                                led_control(LED_SEC0, LED_ON);
1007                        if (!strncmp(ifname, "ath1", 4))
1008                                led_control(LED_SEC1, LED_ON);
1009                }
1010                fprintf(fp, "logger_syslog=-1\n");
1011                debug = nvram_nget("%s_wpa_debug", ifname);
1012                if (debug != NULL) {
1013                        if (!strcmp(debug, "1"))
1014                                fprintf(fp, "logger_syslog_level=1\n");
1015                        else if (!strcmp(debug, "2"))
1016                                fprintf(fp, "logger_syslog_level=0\n");
1017                        else if (!strcmp(debug, "3"))
1018                                fprintf(fp, "logger_syslog_level=0\n");
1019                } else
1020                        fprintf(fp, "logger_syslog_level=2\n");
1021                fprintf(fp, "logger_stdout=-1\n");
1022                fprintf(fp, "logger_stdout_level=2\n");
1023                char *authmode = nvram_nget("%s_authmode", ifname);
1024                if (aoss)
1025                        authmode = "auto";
1026                if (!strcmp(authmode, "shared"))
1027                        fprintf(fp, "auth_algs=2\n");
1028                else if (!strcmp(authmode, "auto"))
1029                        fprintf(fp, "auth_algs=3\n");
1030                else
1031                        fprintf(fp, "auth_algs=1\n");
1032                int i;
1033                if (aoss) {
1034                        for (i = 1; i < 5; i++) {
1035                                fprintf(fp, "wep_key%d=4D454C434F\n", i - 1);
1036                        }
1037                        fprintf(fp, "wep_default_key=0\n");
1038                } else {
1039                        for (i = 1; i < 5; i++) {
1040                                char *athkey = nvram_nget("%s_key%d", ifname, i);
1041                                if (athkey != NULL && strlen(athkey) > 0) {
1042                                        fprintf(fp, "wep_key%d=%s\n", i - 1, athkey);
1043                                }
1044                        }
1045                        fprintf(fp, "wep_default_key=%d\n", atoi(nvram_nget("%s_key", ifname)) - 1);
1046                        addWPS(fp, ifname, 1);
1047                }
1048        } else if (nvram_match(akm, "disabled")) {
1049                addWPS(fp, ifname, 0);
1050        } else if (nvram_match(akm, "psk") || nvram_match(akm, "psk2") || nvram_match(akm, "psk psk2") || nvram_match(akm, "wpa") || nvram_match(akm, "wpa2")
1051                   || nvram_match(akm, "wpa wpa2")) {
1052                if (!strncmp(ifname, "ath0", 4))
1053                        led_control(LED_SEC0, LED_ON);
1054                if (!strncmp(ifname, "ath1", 4))
1055                        led_control(LED_SEC1, LED_ON);
1056                // sprintf(buf, "rsn_preauth_interfaces=%s\n", "br0");
1057                if (nvram_nmatch("1", "%s_bridged", ifname))
1058                        fprintf(fp, "bridge=%s\n", getBridge(ifname, tmp));
1059                fprintf(fp, "logger_syslog=-1\n");
1060                debug = nvram_nget("%s_wpa_debug", ifname);
1061                if (debug != NULL) {
1062                        if (!strcmp(debug, "1"))
1063                                fprintf(fp, "logger_syslog_level=1\n");
1064                        else if (!strcmp(debug, "2"))
1065                                fprintf(fp, "logger_syslog_level=0\n");
1066                        else if (!strcmp(debug, "3"))
1067                                fprintf(fp, "logger_syslog_level=0\n");
1068                } else
1069                        fprintf(fp, "logger_syslog_level=2\n");
1070                fprintf(fp, "logger_stdout=-1\n");
1071                fprintf(fp, "logger_stdout_level=2\n");
1072                // fprintf (fp, "eap_server=0\n");
1073                // fprintf (fp, "own_ip_addr=127.0.0.1\n");
1074                fprintf(fp, "eapol_version=1\n");
1075                fprintf(fp, "eapol_key_index_workaround=0\n");
1076                if (nvram_match(akm, "psk") || nvram_match(akm, "wpa"))
1077                        fprintf(fp, "wpa=1\n");
1078                if (nvram_match(akm, "psk2")
1079                    || nvram_match(akm, "wpa2"))
1080                        fprintf(fp, "wpa=2\n");
1081                if (nvram_match(akm, "psk psk2")
1082                    || nvram_match(akm, "wpa wpa2"))
1083                        fprintf(fp, "wpa=3\n");
1084                if (nvram_match(akm, "psk") || nvram_match(akm, "psk2")
1085                    || nvram_match(akm, "psk psk2")) {
1086                        if (strlen(nvram_nget("%s_wpa_psk", ifname)) == 64)
1087                                fprintf(fp, "wpa_psk=%s\n", nvram_nget("%s_wpa_psk", ifname));
1088                        else
1089                                fprintf(fp, "wpa_passphrase=%s\n", nvram_nget("%s_wpa_psk", ifname));
1090                        fprintf(fp, "wpa_key_mgmt=WPA-PSK\n");
1091                        addWPS(fp, ifname, 1);
1092                } else {
1093                        // if (nvram_invmatch (akm, "radius"))
1094                        fprintf(fp, "wpa_key_mgmt=WPA-EAP\n");
1095                        // else
1096                        // fprintf (fp, "macaddr_acl=2\n");
1097                        fprintf(fp, "ieee8021x=1\n");
1098                        // fprintf (fp, "accept_mac_file=/tmp/hostapd.accept\n");
1099                        // fprintf (fp, "deny_mac_file=/tmp/hostapd.deny\n");
1100
1101                        char local_ip[32];
1102                        sprintf(local_ip, "%s_local_ip", ifname);
1103                        char *lip = nvram_default_get(local_ip, "0.0.0.0");
1104                        if (strcmp(lip, "0.0.0.0")) {
1105                                fprintf(fp, "radius_client_addr=%s\n", lip);
1106                                fprintf(fp, "own_ip_addr=%s\n", lip);
1107                        } else {
1108                                if (nvram_match("wan_proto", "disabled"))
1109                                        fprintf(fp, "own_ip_addr=%s\n", nvram_safe_get("lan_ipaddr"));
1110                                else {
1111                                        char *wip = get_wan_ipaddr();
1112                                        if (strlen(wip))
1113                                                fprintf(fp, "own_ip_addr=%s\n", wip);
1114                                        else
1115                                                fprintf(fp, "own_ip_addr=%s\n", nvram_safe_get("lan_ipaddr"));
1116                                }
1117
1118                        }
1119
1120                        fprintf(fp, "eap_server=0\n");
1121                        fprintf(fp, "auth_algs=1\n");
1122                        char retry[32];
1123                        sprintf(retry, "%s_radius_retry", ifname);
1124                        fprintf(fp, "radius_retry_primary_interval=%s\n", nvram_default_get(retry, "600"));
1125                        types = hostapd_eap_get_types();
1126                        fprintf(fp, "%s", types);
1127                        free(types);
1128                        fprintf(fp, "auth_server_addr=%s\n", nvram_nget("%s_radius_ipaddr", ifname));
1129                        fprintf(fp, "auth_server_port=%s\n", nvram_nget("%s_radius_port", ifname));
1130                        fprintf(fp, "auth_server_shared_secret=%s\n", nvram_nget("%s_radius_key", ifname));
1131                        char check[64];
1132                        sprintf(check, "%s_radius2_ipaddr", ifname);
1133                        nvram_default_get(check, "0.0.0.0");
1134                        if (!nvram_nmatch("", "%s_radius2_ipaddr", ifname)
1135                            && !nvram_nmatch("0.0.0.0", "%s_radius2_ipaddr", ifname)
1136                            && !nvram_nmatch("", "%s_radius2_port", ifname)) {
1137                                fprintf(fp, "auth_server_addr=%s\n", nvram_nget("%s_radius2_ipaddr", ifname));
1138                                fprintf(fp, "auth_server_port=%s\n", nvram_nget("%s_radius2_port", ifname));
1139                                fprintf(fp, "auth_server_shared_secret=%s\n", nvram_nget("%s_radius2_key", ifname));
1140                        }
1141                        if (nvram_nmatch("1", "%s_acct", ifname)) {
1142                                fprintf(fp, "acct_server_addr=%s\n", nvram_nget("%s_acct_ipaddr", ifname));
1143                                fprintf(fp, "acct_server_port=%s\n", nvram_nget("%s_acct_port", ifname));
1144                                fprintf(fp, "acct_server_shared_secret=%s\n", nvram_nget("%s_acct_key", ifname));
1145                        }
1146                }
1147                if (nvram_invmatch(akm, "radius")) {
1148                        sprintf(psk, "%s_crypto", ifname);
1149                        if (nvram_match(psk, "aes"))
1150                                fprintf(fp, "wpa_pairwise=CCMP\n");
1151                        if (nvram_match(psk, "gcmp"))
1152                                fprintf(fp, "wpa_pairwise=GCMP\n");
1153                        if (nvram_match(psk, "tkip")) {
1154                                if (!isfirst)
1155                                        fprintf(fp, "ieee80211n=0\n");
1156                                fprintf(fp, "wpa_pairwise=TKIP\n");
1157                        }
1158                        if (nvram_match(psk, "tkip+aes"))
1159                                fprintf(fp, "wpa_pairwise=TKIP CCMP\n");
1160                        fprintf(fp, "wpa_group_rekey=%s\n", nvram_nget("%s_wpa_gtk_rekey", ifname));
1161                }
1162                // fprintf (fp, "jumpstart_p1=1\n");
1163        }
1164#ifdef HAVE_HOTSPOT20
1165        setupHS20(fp, ifname);
1166#endif
1167        char *v = nvram_nget("%s_config", ifname);
1168        fprintf(fp, "\n");
1169        if (v && strlen(v) > 0)
1170                fprintf(fp, "%s", v);
1171        fprintf(fp, "\n");
1172
1173        fclose(fp);
1174}
1175
1176/* das muessen wir noch machen
1177void setupradauth_ath9k(char *prefix, char *driver, int iswan) {
1178        if (nvram_match(akm, "radius")) {
1179                // wrt-radauth $IFNAME $server $port $share $override $mackey $maxun
1180                // &
1181                char *ifname = prefix;
1182                char *server = nvram_nget("%s_radius_ipaddr", prefix);
1183                char *port = nvram_nget("%s_radius_port", prefix);
1184                char *share = nvram_nget("%s_radius_key", prefix);
1185                char exec[64];
1186                char type[32];
1187
1188                sprintf(type, "%s_radmactype", prefix);
1189                char *pragma = "";
1190
1191                if (nvram_default_match(type, "0", "0"))
1192                        pragma = "-n1 ";
1193                if (nvram_matchi(type,1))
1194                        pragma = "-n2 ";
1195                if (nvram_matchi(type,2))
1196                        pragma = "-n3 ";
1197                if (nvram_matchi(type,3))
1198                        pragma = "";
1199                sleep(1);       // some delay is usefull
1200                sysprintf("wrt-radauth %s %s %s %s %s 1 1 0 &", pragma,
1201                          prefix, server, port, share);
1202        }
1203*/
1204
1205static void addvhtcaps(char *prefix, FILE * fp)
1206{
1207
1208/* must use integer mask */
1209#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE                 0x00000800
1210#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE                 0x00001000
1211#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE                 0x00080000
1212#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE                 0x00100000
1213#define IEEE80211_VHT_CAP_SHORT_GI_80                           0x00000020
1214#define IEEE80211_VHT_CAP_SHORT_GI_160                          0x00000040
1215#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT                  13
1216#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK                   \
1217                (7 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT)
1218#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT             16
1219#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK              \
1220                (7 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT)
1221
1222        unsigned int mask;
1223#ifdef HAVE_ATH10K
1224        if (has_ac(prefix)) {
1225                char shortgi[32];
1226                sprintf(shortgi, "%s_shortgi", prefix);
1227                char mubf[32];
1228                sprintf(mubf, "%s_mubf", prefix);
1229                char subf[32];
1230                sprintf(subf, "%s_subf", prefix);
1231                mask = 0;
1232                if (nvram_default_match(subf, "0", "0")) {
1233                        mask |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1234                        mask |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1235                        mask |= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
1236                        mask |= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
1237                }
1238                if (nvram_default_match(mubf, "0", "0")) {
1239                        mask |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1240                        mask |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1241                }
1242                if (nvram_default_match(shortgi, "0", "1")) {
1243                        mask |= IEEE80211_VHT_CAP_SHORT_GI_80;
1244                        mask |= IEEE80211_VHT_CAP_SHORT_GI_160;
1245                }
1246                if (mask) {
1247                        fprintf(fp, "\tvht_capa=0\n");
1248                        fprintf(fp, "\tvht_capa_mask=%d\n", mask);
1249                }
1250        }
1251#endif
1252#ifdef HAVE_ATH9K
1253        if (is_ath9k(prefix)) {
1254                char shortgi[32];
1255                sprintf(shortgi, "%s_shortgi", prefix);
1256                if (nvram_matchi(shortgi, 0))
1257                        fprintf(fp, "\tdisable_sgi=1\n");
1258        }
1259#endif
1260}
1261
1262void setupSupplicant_ath9k(char *prefix, char *ssidoverride)
1263{
1264#ifdef HAVE_REGISTER
1265        if (!isregistered())
1266                return;
1267#endif
1268        char akm[16];
1269        int i;
1270        sprintf(akm, "%s_akm", prefix);
1271        if (nvram_match(akm, "psk") || nvram_match(akm, "psk2")
1272            || nvram_match(akm, "psk psk2")) {
1273                char fstr[32];
1274                char psk[16];
1275                if (!strncmp(prefix, "ath0", 4))
1276                        led_control(LED_SEC0, LED_ON);
1277                if (!strncmp(prefix, "ath1", 4))
1278                        led_control(LED_SEC1, LED_ON);
1279                sprintf(fstr, "/tmp/%s_wpa_supplicant.conf", prefix);
1280                FILE *fp = fopen(fstr, "wb");
1281                fprintf(fp, "ap_scan=1\n");
1282                fprintf(fp, "fast_reauth=1\n");
1283                fprintf(fp, "eapol_version=1\n");
1284                // fprintf (fp, "ctrl_interface_group=0\n");
1285                // fprintf (fp, "ctrl_interface=/var/run/wpa_supplicant\n");
1286                fprintf(fp, "network={\n");
1287
1288                addvhtcaps(prefix, fp);
1289                if (!ssidoverride)
1290                        ssidoverride = nvram_nget("%s_ssid", prefix);
1291                fprintf(fp, "\tssid=\"%s\"\n", ssidoverride);
1292                char scanlist[32];
1293                sprintf(scanlist, "%s_scanlist", prefix);
1294                char *sl = nvram_default_get(scanlist, "default");
1295                if (strcmp(sl, "default")) {
1296                        fprintf(fp, "\tscan_freq=%s\n", sl);
1297                }
1298#ifdef HAVE_UNIWIP
1299                fprintf(fp, "\tbgscan=\"simple:30:-45:300\"\n");
1300#endif
1301                // fprintf (fp, "\tmode=0\n");
1302                fprintf(fp, "\tscan_ssid=1\n");
1303                fprintf(fp, "\tkey_mgmt=WPA-PSK\n");
1304                sprintf(psk, "%s_crypto", prefix);
1305                if (nvram_match(psk, "aes")) {
1306#if 1
1307                        fprintf(fp, "\tpairwise=CCMP\n");
1308                        fprintf(fp, "\tgroup=CCMP TKIP\n");
1309#else
1310                        fprintf(fp, "\tpairwise=CCMP\n");
1311                        fprintf(fp, "\tgroup=CCMP\n");
1312#endif
1313                }
1314                if (nvram_match(psk, "tkip")) {
1315                        fprintf(fp, "\tpairwise=TKIP\n");
1316                        fprintf(fp, "\tgroup=TKIP\n");
1317                }
1318                if (nvram_match(psk, "gcmp")) {
1319                        fprintf(fp, "\tpairwise=GCMP\n");
1320                        fprintf(fp, "\tgroup=GCMP\n");
1321                }
1322                if (nvram_match(psk, "tkip+aes")) {
1323                        fprintf(fp, "\tpairwise=CCMP TKIP\n");
1324                        fprintf(fp, "\tgroup=CCMP TKIP\n");
1325                }
1326                if (nvram_match(akm, "psk"))
1327                        fprintf(fp, "\tproto=WPA\n");
1328                if (nvram_match(akm, "psk2"))
1329                        fprintf(fp, "\tproto=RSN\n");
1330                if (nvram_match(akm, "psk psk2"))
1331                        fprintf(fp, "\tproto=WPA RSN\n");
1332                char *wpa_psk = nvram_nget("%s_wpa_psk", prefix);
1333                if (strlen(wpa_psk) == 64)
1334                        fprintf(fp, "\tpsk=%s\n", wpa_psk);
1335                else
1336                        fprintf(fp, "\tpsk=\"%s\"\n", wpa_psk);
1337                fprintf(fp, "}\n");
1338                char extra[32];
1339                sprintf(extra, "%s_supplicantext", prefix);
1340                if (nvram_invmatch(extra, ""))
1341                        fwritenvram(extra, fp);
1342                fclose(fp);
1343        } else if (nvram_match(akm, "8021X")) {
1344                char fstr[32];
1345                char psk[64];
1346                char ath[64];
1347                if (!strncmp(prefix, "ath0", 4))
1348                        led_control(LED_SEC0, LED_ON);
1349                if (!strncmp(prefix, "ath1", 4))
1350                        led_control(LED_SEC1, LED_ON);
1351                sprintf(fstr, "/tmp/%s_wpa_supplicant.conf", prefix);
1352                FILE *fp = fopen(fstr, "wb");
1353                fprintf(fp, "ap_scan=1\n");
1354                fprintf(fp, "fast_reauth=1\n");
1355                fprintf(fp, "eapol_version=1\n");
1356                // fprintf (fp, "ctrl_interface_group=0\n");
1357                // fprintf (fp, "ctrl_interface=/var/run/wpa_supplicant\n");
1358                fprintf(fp, "network={\n");
1359                addvhtcaps(prefix, fp);
1360                if (!ssidoverride)
1361                        ssidoverride = nvram_nget("%s_ssid", prefix);
1362                fprintf(fp, "\tssid=\"%s\"\n", ssidoverride);
1363#ifdef HAVE_UNIWIP
1364                fprintf(fp, "\tbgscan=\"simple:30:-45:300\"\n");
1365#endif
1366                fprintf(fp, "\tscan_ssid=1\n");
1367                if (nvram_prefix_match("8021xtype", prefix, "tls")) {
1368// -> added habeIchVergessen
1369                        char *keyExchng = nvram_nget("%s_tls8021xkeyxchng", prefix);
1370                        char wpaOpts[40];
1371                        if (strlen(keyExchng) == 0)
1372                                nvram_nset("wep", "%s_tls8021xkeyxchng", prefix);
1373                        sprintf(wpaOpts, "");
1374                        keyExchng = nvram_nget("%s_tls8021xkeyxchng", prefix);
1375                        if (strcmp("wpa2", keyExchng) == 0)
1376                                sprintf(wpaOpts, "\tpairwise=CCMP\n\tgroup=CCMP\n");
1377                        if (strcmp("wpa2mixed", keyExchng) == 0)
1378                                sprintf(wpaOpts, "\tpairwise=CCMP TKIP\n\tgroup=CCMP TKIP\n");
1379                        if (strcmp("wpa", keyExchng) == 0)
1380                                sprintf(wpaOpts, "\tpairwise=TKIP\n\tgroup=TKIP\n");
1381                        fprintf(fp, "\tkey_mgmt=%s\n%s", (strlen(wpaOpts) == 0 ? "IEEE8021X" : "WPA-EAP"), wpaOpts);
1382// <- added habeIchVergessen
1383                        fprintf(fp, "\teap=TLS\n");
1384                        fprintf(fp, "\tidentity=\"%s\"\n", nvram_prefix_get("tls8021xuser", prefix));
1385                        sprintf(psk, "/tmp/%s", prefix);
1386                        mkdir(psk, 0700);
1387                        sprintf(psk, "/tmp/%s/ca.pem", prefix);
1388                        sprintf(ath, "%s_tls8021xca", prefix);
1389                        write_nvram(psk, ath);
1390                        sprintf(psk, "/tmp/%s/user.pem", prefix);
1391                        sprintf(ath, "%s_tls8021xpem", prefix);
1392                        write_nvram(psk, ath);
1393                        sprintf(psk, "/tmp/%s/user.prv", prefix);
1394                        sprintf(ath, "%s_tls8021xprv", prefix);
1395                        write_nvram(psk, ath);
1396                        fprintf(fp, "\tca_cert=\"/tmp/%s/ca.pem\"\n", prefix);
1397                        fprintf(fp, "\tclient_cert=\"/tmp/%s/user.pem\"\n", prefix);
1398                        fprintf(fp, "\tprivate_key=\"/tmp/%s/user.prv\"\n", prefix);
1399                        fprintf(fp, "\tprivate_key_passwd=\"%s\"\n", nvram_prefix_get("tls8021xpasswd", prefix));
1400                        fprintf(fp, "\teapol_flags=3\n");
1401                        if (strlen(nvram_nget("%s_tls8021xphase2", prefix)) > 0) {
1402                                fprintf(fp, "\tphase2=\"%s\"\n", nvram_nget("%s_tls8021xphase2", prefix));
1403                        }
1404                        if (strlen(nvram_nget("%s_tls8021xanon", prefix)) > 0) {
1405                                fprintf(fp, "\tanonymous_identity=\"%s\"\n", nvram_nget("%s_tls8021xanon", prefix));
1406                        }
1407                        if (strlen(nvram_nget("%s_tls8021xaddopt", prefix)) > 0) {
1408                                sprintf(ath, "%s_tls8021xaddopt", prefix);
1409                                fprintf(fp, "\t");      // tab
1410                                fwritenvram(ath, fp);
1411                                fprintf(fp, "\n");      // extra new line at the end
1412                        }
1413                }
1414                if (nvram_prefix_match("8021xtype", prefix, "peap")) {
1415                        fprintf(fp, "\tkey_mgmt=WPA-EAP\n");
1416                        fprintf(fp, "\teap=PEAP\n");
1417                        fprintf(fp, "\tpairwise=CCMP TKIP\n");
1418                        fprintf(fp, "\tgroup=CCMP TKIP\n");
1419                        fprintf(fp, "\tphase1=\"peapver=0\"\n");
1420                        fprintf(fp, "\tidentity=\"%s\"\n", nvram_prefix_get("peap8021xuser", prefix));
1421                        fprintf(fp, "\tpassword=\"%s\"\n", nvram_prefix_get("peap8021xpasswd", prefix));
1422                        sprintf(psk, "/tmp/%s", prefix);
1423                        mkdir(psk, 0700);
1424                        sprintf(psk, "/tmp/%s/ca.pem", prefix);
1425                        sprintf(ath, "%s_peap8021xca", prefix);
1426                        if (!nvram_match(ath, "")) {
1427                                write_nvram(psk, ath);
1428                                fprintf(fp, "\tca_cert=\"/tmp/%s/ca.pem\"\n", prefix);
1429                        }
1430                        if (strlen(nvram_nget("%s_peap8021xphase2", prefix)) > 0) {
1431                                fprintf(fp, "\tphase2=\"%s\"\n", nvram_nget("%s_peap8021xphase2", prefix));
1432                        }
1433                        if (strlen(nvram_nget("%s_peap8021xanon", prefix)) > 0) {
1434                                fprintf(fp, "\tanonymous_identity=\"%s\"\n", nvram_nget("%s_peap8021xanon", prefix));
1435                        }
1436                        if (strlen(nvram_nget("%s_peap8021xaddopt", prefix)) > 0) {
1437                                sprintf(ath, "%s_peap8021xaddopt", prefix);
1438                                fprintf(fp, "\t");      // tab
1439                                fwritenvram(ath, fp);
1440                                fprintf(fp, "\n");      // extra new line at the end
1441                        }
1442                }
1443                if (nvram_prefix_match("8021xtype", prefix, "ttls")) {
1444                        fprintf(fp, "\tkey_mgmt=WPA-EAP\n");
1445                        fprintf(fp, "\teap=TTLS\n");
1446                        fprintf(fp, "\tpairwise=CCMP TKIP\n");
1447                        fprintf(fp, "\tgroup=CCMP TKIP\n");
1448                        fprintf(fp, "\tidentity=\"%s\"\n", nvram_prefix_get("ttls8021xuser", prefix));
1449                        fprintf(fp, "\tpassword=\"%s\"\n", nvram_prefix_get("ttls8021xpasswd", prefix));
1450                        if (strlen(nvram_nget("%s_ttls8021xca", prefix)) > 0) {
1451                                sprintf(psk, "/tmp/%s", prefix);
1452                                mkdir(psk, 0700);
1453                                sprintf(psk, "/tmp/%s/ca.pem", prefix);
1454                                sprintf(ath, "%s_ttls8021xca", prefix);
1455                                write_nvram(psk, ath);
1456                                fprintf(fp, "\tca_cert=\"/tmp/%s/ca.pem\"\n", prefix);
1457                        }
1458                        if (strlen(nvram_nget("%s_ttls8021xphase2", prefix)) > 0) {
1459                                fprintf(fp, "\tphase2=\"%s\"\n", nvram_nget("%s_ttls8021xphase2", prefix));
1460                        }
1461                        if (strlen(nvram_nget("%s_ttls8021xanon", prefix)) > 0) {
1462                                fprintf(fp, "\tanonymous_identity=\"%s\"\n", nvram_nget("%s_ttls8021xanon", prefix));
1463                        }
1464                        if (strlen(nvram_nget("%s_ttls8021xaddopt", prefix)) > 0) {
1465                                sprintf(ath, "%s_ttls8021xaddopt", prefix);
1466                                fprintf(fp, "\t");      // tab
1467                                fwritenvram(ath, fp);
1468                                fprintf(fp, "\n");      // extra new line at the end
1469                        }
1470                }
1471                if (nvram_prefix_match("8021xtype", prefix, "leap")) {
1472                        fprintf(fp, "\tkey_mgmt=WPA-EAP\n");
1473                        fprintf(fp, "\teap=LEAP\n");
1474                        fprintf(fp, "\tauth_alg=LEAP\n");
1475                        fprintf(fp, "\tproto=WPA RSN\n");
1476                        fprintf(fp, "\tpairwise=CCMP TKIP\n");
1477                        fprintf(fp, "\tgroup=CCMP TKIP\n");
1478                        fprintf(fp, "\tidentity=\"%s\"\n", nvram_prefix_get("leap8021xuser", prefix));
1479                        fprintf(fp, "\tpassword=\"%s\"\n", nvram_prefix_get("leap8021xpasswd", prefix));
1480                        // sprintf (psk, "/tmp/%s", prefix);
1481                        // mkdir (psk);
1482                        // sprintf (psk, "/tmp/%s/ca.pem", prefix);
1483                        // sprintf (ath, "%s_peap8021xca", prefix);
1484                        // write_nvram (psk, ath);
1485                        // fprintf (fp, "\tca_cert=\"/tmp/%s/ca.pem\"\n", prefix);
1486                        if (strlen(nvram_nget("%s_leap8021xphase2", prefix)) > 0) {
1487                                fprintf(fp, "\tphase2=\"%s\"\n", nvram_nget("%s_leap8021xphase2", prefix));
1488                        }
1489                        if (strlen(nvram_nget("%s_leap8021xanon", prefix)) > 0) {
1490                                fprintf(fp, "\tanonymous_identity=\"%s\"\n", nvram_nget("%s_leap8021xanon", prefix));
1491                        }
1492                        if (strlen(nvram_nget("%s_leap8021xaddopt", prefix)) > 0) {
1493                                sprintf(ath, "%s_leap8021xaddopt", prefix);
1494                                fprintf(fp, "\t");      // tab
1495                                fwritenvram(ath, fp);
1496                                fprintf(fp, "\n");      // extra new line at the end
1497                        }
1498                }
1499                fprintf(fp, "}\n");
1500                char extra[32];
1501                sprintf(extra, "%s_supplicantext", prefix);
1502                if (nvram_invmatch(extra, ""))
1503                        fwritenvram(extra, fp);
1504                fclose(fp);
1505        } else if (nvram_match(akm, "disabled") || nvram_match(akm, "wep")) {
1506                char fstr[32];
1507                char psk[16];
1508                if (nvram_match(akm, "wep")) {
1509                        if (!strncmp(prefix, "ath0", 4))
1510                                led_control(LED_SEC0, LED_ON);
1511                        if (!strncmp(prefix, "ath1", 4))
1512                                led_control(LED_SEC1, LED_ON);
1513                }
1514                sprintf(fstr, "/tmp/%s_wpa_supplicant.conf", prefix);
1515                FILE *fp = fopen(fstr, "wb");
1516                fprintf(fp, "ap_scan=1\n");
1517                // fprintf (fp, "ctrl_interface_group=0\n");
1518                // fprintf (fp, "ctrl_interface=/var/run/wpa_supplicant\n");
1519                fprintf(fp, "network={\n");
1520                addvhtcaps(prefix, fp);
1521                if (!ssidoverride)
1522                        ssidoverride = nvram_nget("%s_ssid", prefix);
1523                fprintf(fp, "\tssid=\"%s\"\n", ssidoverride);
1524#ifdef HAVE_UNIWIP
1525                fprintf(fp, "\tbgscan=\"simple:30:-45:300\"\n");
1526#endif
1527                // fprintf (fp, "\tmode=0\n");
1528                fprintf(fp, "\tscan_ssid=1\n");
1529                fprintf(fp, "\tkey_mgmt=NONE\n");
1530                if (nvram_match(akm, "wep")) {
1531                        int cnt = 0;
1532                        char *authmode = nvram_nget("%s_authmode", prefix);
1533                        if (!strcmp(authmode, "shared"))
1534                                fprintf(fp, "auth_alg=SHARED\n");
1535                        else
1536                                fprintf(fp, "auth_alg=OPEN\n");
1537                        for (i = 1; i < 5; i++) {
1538                                char *athkey = nvram_nget("%s_key%d", prefix, i);
1539                                if (athkey != NULL && strlen(athkey) > 0) {
1540                                        fprintf(fp, "wep_key%d=%s\n", i - 1, athkey);   // setup wep
1541                                }
1542                        }
1543
1544                        sprintf(psk, "%s", nvram_nget("%s_key", prefix));
1545                        fprintf(fp, "wep_tx_keyidx=%d\n", atoi(psk) - 1);
1546                }
1547                fprintf(fp, "}\n");
1548                char extra[32];
1549                sprintf(extra, "%s_supplicantext", prefix);
1550                if (nvram_invmatch(extra, ""))
1551                        fwritenvram(extra, fp);
1552                fclose(fp);
1553        }
1554
1555}
1556
1557extern void do_hostapd(char *fstr, char *prefix);
1558void ath9k_start_supplicant(int count)
1559{
1560// erst hostapd starten fuer repeater mode
1561// dann wpa_supplicant mit link zu hostapd
1562// dann bridgen und konfiguriren
1563        char *next;
1564        char var[80];
1565        char fstr[32];
1566        char bridged[32];
1567        char mode[80];
1568        char dev[10];
1569        char power[32];
1570        char *apm, *vifs;
1571        char wl[16];
1572        char ctrliface[32] = "";
1573        char wifivifs[16];
1574        char tmp[256];
1575#ifdef HAVE_CONFIG_DEBUG_SYSLOG
1576        char *background = "-Bs";
1577#else
1578        char *background = "-B";
1579#endif
1580        char *debug;
1581        char psk[16];
1582        char net[16];
1583        char wmode[16];
1584        int ctrlifneeded = 0;
1585        char wif[10];
1586        sprintf(wif, "phy%d", get_ath9k_phy_idx(count));
1587        sprintf(wl, "ath%d_mode", count);
1588        sprintf(dev, "ath%d", count);
1589        sprintf(net, "%s_net_mode", dev);
1590        char *netmode = nvram_default_get(net, "mixed");
1591        if (!strcmp(netmode, "disabled"))
1592                return;
1593        apm = nvram_safe_get(wl);
1594        sprintf(wifivifs, "ath%d_vifs", count);
1595        sprintf(power, "ath%d_txpwrdbm", count);
1596        vifs = nvram_safe_get(wifivifs);
1597        sprintf(psk, "-i%s", dev);
1598        if (has_ad(dev))
1599                sprintf(psk, "-igiwifi");
1600
1601        sprintf(wmode, "%s_mode", dev);
1602        sprintf(bridged, "%s_bridged", dev);
1603        debug = nvram_nget("%s_wpa_debug", dev);
1604#ifdef HAVE_CONFIG_DEBUG_SYSLOG
1605        if (debug != NULL) {
1606                if (!strcmp(debug, "1"))
1607                        background = "-Bds";
1608                else if (!strcmp(debug, "2"))
1609                        background = "-Bdds";
1610                else if (!strcmp(debug, "3"))
1611                        background = "-Bddds";
1612        }
1613#else
1614        if (debug != NULL) {
1615                if (!strcmp(debug, "1"))
1616                        background = "-Bd";
1617                else if (!strcmp(debug, "2"))
1618                        background = "-Bdd";
1619                else if (!strcmp(debug, "3"))
1620                        background = "-Bddd";
1621        }
1622#endif
1623        if (strcmp(apm, "sta") && strcmp(apm, "wdssta")
1624            && strcmp(apm, "wet")) {
1625                sprintf(fstr, "/tmp/%s_hostap.conf", dev);
1626                do_hostapd(fstr, dev);
1627        } else {
1628                if (strlen(vifs) > 0) {
1629                        sprintf(fstr, "/tmp/%s_hostap.conf", dev);
1630                        do_hostapd(fstr, dev);
1631                        sprintf(ctrliface, "/var/run/hostapd/%s.1", dev);
1632                        sprintf(fstr, "/tmp/%s_wpa_supplicant.conf", dev);
1633#ifdef HAVE_RELAYD
1634                        if ((nvram_match(wmode, "wdssta"))
1635                            && nvram_matchi(bridged, 1))
1636                                eval("wpa_supplicant", "-b", getBridge(dev, tmp), background, "-Dnl80211", psk, "-H", ctrliface, "-c", fstr);
1637                        else
1638                                eval("wpa_supplicant", background, "-Dnl80211", psk, "-H", ctrliface, "-c", fstr);
1639#else
1640                        if ((nvram_match(wmode, "wdssta")
1641                             || nvram_match(wmode, "wet"))
1642                            && nvram_matchi(bridged, 1))
1643                                eval("wpa_supplicant", "-b", getBridge(dev, tmp), background, "-Dnl80211", psk, "-H", ctrliface, "-c", fstr);
1644                        else
1645                                eval("wpa_supplicant", background, "-Dnl80211", psk, "-H", ctrliface, "-c", fstr);
1646#endif
1647                } else {
1648                        sprintf(fstr, "/tmp/%s_wpa_supplicant.conf", dev);
1649#ifdef HAVE_RELAYD
1650                        if ((nvram_match(wmode, "wdssta"))
1651                            && nvram_matchi(bridged, 1))
1652                                eval("wpa_supplicant", "-b", getBridge(dev, tmp), background, "-Dnl80211", psk, "-c", fstr);
1653                        else
1654                                eval("wpa_supplicant", background, "-Dnl80211", psk, "-c", fstr);
1655#else
1656                        if ((nvram_match(wmode, "wdssta")
1657                             || nvram_match(wmode, "wet"))
1658                            && nvram_matchi(bridged, 1))
1659                                eval("wpa_supplicant", "-b", getBridge(dev, tmp), background, "-Dnl80211", psk, "-c", fstr);
1660                        else
1661                                eval("wpa_supplicant", background, "-Dnl80211", psk, "-c", fstr);
1662#endif
1663                }
1664        }
1665        if (has_ad(dev))
1666                sprintf(dev, "giwifi");
1667#ifdef HAVE_RELAYD
1668        if (strcmp(apm, "sta") && strcmp(apm, "wet")) {
1669#else
1670        if (strcmp(apm, "sta")) {
1671#endif
1672                char bridged[32];
1673                sprintf(bridged, "%s_bridged", dev);
1674                if (nvram_default_match(bridged, "1", "1")) {
1675                        eval("ifconfig", dev, "0.0.0.0", "up");
1676                        br_add_interface(getBridge(dev, tmp), dev);
1677                        eval("ifconfig", dev, "0.0.0.0", "up");
1678                } else {
1679                        eval("ifconfig", dev, "mtu", getMTU(dev));
1680                        eval("ifconfig", dev, "txqueuelen", getTXQ(dev));
1681                        eval("ifconfig", dev, nvram_nget("%s_ipaddr", dev), "netmask", nvram_nget("%s_netmask", dev), "up");
1682                }
1683        } else {
1684#ifdef HAVE_RELAYD
1685                if (!strcmp(apm, "wet")) {
1686                        eval("ifconfig", dev, "0.0.0.0", "up");
1687//                      sysprintf("relayd -I %s -I %s -D -B", getBridge(dev),
1688//                                dev);
1689                }
1690#endif
1691
1692                char bridged[32];
1693                sprintf(bridged, "%s_bridged", dev);
1694                if (nvram_default_match(bridged, "0", "1")) {
1695                        eval("ifconfig", dev, "mtu", getMTU(dev));
1696                        eval("ifconfig", dev, "txqueuelen", getTXQ(dev));
1697                        eval("ifconfig", dev, nvram_nget("%s_ipaddr", dev), "netmask", nvram_nget("%s_netmask", dev), "up");
1698                }
1699        }
1700
1701        if (strlen(vifs) > 0) {
1702                foreach(var, vifs, next) {
1703                        sprintf(mode, "%s_mode", var);
1704                        char *m2 = nvram_safe_get(mode);
1705                        if (strcmp(m2, "sta")) {
1706                                char bridged[32];
1707                                sprintf(bridged, "%s_bridged", var);
1708                                if (nvram_default_match(bridged, "1", "1")) {
1709                                        eval("ifconfig", dev, "0.0.0.0", "up");
1710                                        br_add_interface(getBridge(var, tmp), var);
1711                                } else {
1712                                        eval("ifconfig", var, "mtu", getMTU(var));
1713                                        eval("ifconfig", var, "txqueuelen", getTXQ(var));
1714                                        eval("ifconfig", var, nvram_nget("%s_ipaddr", var), "netmask", nvram_nget("%s_netmask", var), "up");
1715                                }
1716                        }
1717                }
1718        }
1719        if (!strcmp(apm, "ap") || !strcmp(apm, "wdsap")) {
1720                int s;
1721                for (s = 1; s <= 10; s++) {
1722                        char wdsvarname[32] = {
1723                                0
1724                        };
1725                        char wdsdevname[32] = {
1726                                0
1727                        };
1728                        char wdsmacname[32] = {
1729                                0
1730                        };
1731                        char *wdsdev;
1732                        char *hwaddr;
1733                        sprintf(wdsvarname, "%s_wds%d_enable", dev, s);
1734                        sprintf(wdsdevname, "%s_wds%d_if", dev, s);
1735                        sprintf(wdsmacname, "%s_wds%d_hwaddr", dev, s);
1736                        wdsdev = nvram_safe_get(wdsdevname);
1737                        if (strlen(wdsdev) == 0)
1738                                continue;
1739                        if (nvram_matchi(wdsvarname, 0))
1740                                continue;
1741                        hwaddr = nvram_get(wdsmacname);
1742                        if (hwaddr != NULL) {
1743                                eval("iw", wif, "interface", "add", wdsdev, "type", "wds");
1744                                eval("iw", "dev", wdsdev, "set", "peer", hwaddr);
1745                                eval("ifconfig", wdsdev, "0.0.0.0", "up");
1746                        }
1747                }
1748        }
1749        int newpower = nvram_default_geti(power, 16);
1750        sysprintf("iw phy %s set txpower fixed %d", wif, newpower * 100);
1751}
1752#endif
Note: See TracBrowser for help on using the repository browser.