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

Last change on this file since 32169 was 32169, checked in by brainslayer, 8 weeks ago

marvell likes it different, so we need to change the vap mac address formula to get vaps to work on wrt3200acm

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#ifdef HAVE_MVEBU
956                hwbuff[0] |= 0x2;
957                hwbuff[5] += vapid & 0xf;
958
959#else
960                hwbuff[0] ^= ((vapid - 1) << 2) | 0x2;
961#endif
962        }
963        sprintf(macaddr, "%02X:%02X:%02X:%02X:%02X:%02X", hwbuff[0], hwbuff[1], hwbuff[2], hwbuff[3], hwbuff[4], hwbuff[5]);
964//      if (!strncmp(ifname, "ath2", 4) && getRouterBrand() == ROUTER_WRT_3200ACM)
965//              MAC_ADD(macaddr);
966
967        if (!has_ad(maininterface)) {
968                fprintf(fp, "bssid=%s\n", macaddr);
969        }
970        char vathmac[16];
971        sprintf(vathmac, "%s_hwaddr", ifname);
972        nvram_set(vathmac, macaddr);
973        fprintf(stderr, "setup %s %s\n", ifname, macaddr);
974        setMacFilter(fp, ifname);
975        char isolate[32];
976        char broadcast[32];
977        sprintf(isolate, "%s_ap_isolate", ifname);
978        if (nvram_default_match(isolate, "1", "0"))
979                fprintf(fp, "ap_isolate=1\n");
980        sprintf(broadcast, "%s_closed", ifname);
981        if (nvram_default_match(broadcast, "1", "0"))
982                fprintf(fp, "ignore_broadcast_ssid=1\n");
983        else
984                fprintf(fp, "ignore_broadcast_ssid=0\n");
985        sprintf(maxassoc, "%s_maxassoc", ifname);
986        fprintf(fp, "max_num_sta=%s\n", nvram_default_get(maxassoc, "256"));
987        if (aoss) {
988                if (!strncmp(ifname, "aossa", 5))
989                        ssid = "ESSID-AOSS-1";
990                else
991                        ssid = "ESSID-AOSS";
992        } else {
993                sprintf(nssid, "%s_ssid", ifname);
994                ssid = nvram_default_get(nssid, "dd-wrt");
995        }
996
997        fprintf(fp, "ssid=%s\n", ssid);
998        // wep key support
999        if (nvram_match(akm, "wep") || aoss) {
1000//              if (!isfirst || aoss)
1001//                      fprintf(fp, "ieee80211n=0\n");
1002
1003                if (nvram_nmatch("1", "%s_bridged", ifname))
1004                        fprintf(fp, "bridge=%s\n", getBridge(ifname, tmp));
1005                if (!aoss) {
1006                        if (!strncmp(ifname, "ath0", 4))
1007                                led_control(LED_SEC0, LED_ON);
1008                        if (!strncmp(ifname, "ath1", 4))
1009                                led_control(LED_SEC1, LED_ON);
1010                }
1011                fprintf(fp, "logger_syslog=-1\n");
1012                debug = nvram_nget("%s_wpa_debug", ifname);
1013                if (debug != NULL) {
1014                        if (!strcmp(debug, "1"))
1015                                fprintf(fp, "logger_syslog_level=1\n");
1016                        else if (!strcmp(debug, "2"))
1017                                fprintf(fp, "logger_syslog_level=0\n");
1018                        else if (!strcmp(debug, "3"))
1019                                fprintf(fp, "logger_syslog_level=0\n");
1020                } else
1021                        fprintf(fp, "logger_syslog_level=2\n");
1022                fprintf(fp, "logger_stdout=-1\n");
1023                fprintf(fp, "logger_stdout_level=2\n");
1024                char *authmode = nvram_nget("%s_authmode", ifname);
1025                if (aoss)
1026                        authmode = "auto";
1027                if (!strcmp(authmode, "shared"))
1028                        fprintf(fp, "auth_algs=2\n");
1029                else if (!strcmp(authmode, "auto"))
1030                        fprintf(fp, "auth_algs=3\n");
1031                else
1032                        fprintf(fp, "auth_algs=1\n");
1033                int i;
1034                if (aoss) {
1035                        for (i = 1; i < 5; i++) {
1036                                fprintf(fp, "wep_key%d=4D454C434F\n", i - 1);
1037                        }
1038                        fprintf(fp, "wep_default_key=0\n");
1039                } else {
1040                        for (i = 1; i < 5; i++) {
1041                                char *athkey = nvram_nget("%s_key%d", ifname, i);
1042                                if (athkey != NULL && strlen(athkey) > 0) {
1043                                        fprintf(fp, "wep_key%d=%s\n", i - 1, athkey);
1044                                }
1045                        }
1046                        fprintf(fp, "wep_default_key=%d\n", atoi(nvram_nget("%s_key", ifname)) - 1);
1047                        addWPS(fp, ifname, 1);
1048                }
1049        } else if (nvram_match(akm, "disabled")) {
1050                addWPS(fp, ifname, 0);
1051        } else if (nvram_match(akm, "psk") || nvram_match(akm, "psk2") || nvram_match(akm, "psk psk2") || nvram_match(akm, "wpa") || nvram_match(akm, "wpa2")
1052                   || nvram_match(akm, "wpa wpa2")) {
1053                if (!strncmp(ifname, "ath0", 4))
1054                        led_control(LED_SEC0, LED_ON);
1055                if (!strncmp(ifname, "ath1", 4))
1056                        led_control(LED_SEC1, LED_ON);
1057                // sprintf(buf, "rsn_preauth_interfaces=%s\n", "br0");
1058                if (nvram_nmatch("1", "%s_bridged", ifname))
1059                        fprintf(fp, "bridge=%s\n", getBridge(ifname, tmp));
1060                fprintf(fp, "logger_syslog=-1\n");
1061                debug = nvram_nget("%s_wpa_debug", ifname);
1062                if (debug != NULL) {
1063                        if (!strcmp(debug, "1"))
1064                                fprintf(fp, "logger_syslog_level=1\n");
1065                        else if (!strcmp(debug, "2"))
1066                                fprintf(fp, "logger_syslog_level=0\n");
1067                        else if (!strcmp(debug, "3"))
1068                                fprintf(fp, "logger_syslog_level=0\n");
1069                } else
1070                        fprintf(fp, "logger_syslog_level=2\n");
1071                fprintf(fp, "logger_stdout=-1\n");
1072                fprintf(fp, "logger_stdout_level=2\n");
1073                // fprintf (fp, "eap_server=0\n");
1074                // fprintf (fp, "own_ip_addr=127.0.0.1\n");
1075                fprintf(fp, "eapol_version=1\n");
1076                fprintf(fp, "eapol_key_index_workaround=0\n");
1077                if (nvram_match(akm, "psk") || nvram_match(akm, "wpa"))
1078                        fprintf(fp, "wpa=1\n");
1079                if (nvram_match(akm, "psk2")
1080                    || nvram_match(akm, "wpa2"))
1081                        fprintf(fp, "wpa=2\n");
1082                if (nvram_match(akm, "psk psk2")
1083                    || nvram_match(akm, "wpa wpa2"))
1084                        fprintf(fp, "wpa=3\n");
1085                if (nvram_match(akm, "psk") || nvram_match(akm, "psk2")
1086                    || nvram_match(akm, "psk psk2")) {
1087                        if (strlen(nvram_nget("%s_wpa_psk", ifname)) == 64)
1088                                fprintf(fp, "wpa_psk=%s\n", nvram_nget("%s_wpa_psk", ifname));
1089                        else
1090                                fprintf(fp, "wpa_passphrase=%s\n", nvram_nget("%s_wpa_psk", ifname));
1091                        fprintf(fp, "wpa_key_mgmt=WPA-PSK\n");
1092                        addWPS(fp, ifname, 1);
1093                } else {
1094                        // if (nvram_invmatch (akm, "radius"))
1095                        fprintf(fp, "wpa_key_mgmt=WPA-EAP\n");
1096                        // else
1097                        // fprintf (fp, "macaddr_acl=2\n");
1098                        fprintf(fp, "ieee8021x=1\n");
1099                        // fprintf (fp, "accept_mac_file=/tmp/hostapd.accept\n");
1100                        // fprintf (fp, "deny_mac_file=/tmp/hostapd.deny\n");
1101
1102                        char local_ip[32];
1103                        sprintf(local_ip, "%s_local_ip", ifname);
1104                        char *lip = nvram_default_get(local_ip, "0.0.0.0");
1105                        if (strcmp(lip, "0.0.0.0")) {
1106                                fprintf(fp, "radius_client_addr=%s\n", lip);
1107                                fprintf(fp, "own_ip_addr=%s\n", lip);
1108                        } else {
1109                                if (nvram_match("wan_proto", "disabled"))
1110                                        fprintf(fp, "own_ip_addr=%s\n", nvram_safe_get("lan_ipaddr"));
1111                                else {
1112                                        char *wip = get_wan_ipaddr();
1113                                        if (strlen(wip))
1114                                                fprintf(fp, "own_ip_addr=%s\n", wip);
1115                                        else
1116                                                fprintf(fp, "own_ip_addr=%s\n", nvram_safe_get("lan_ipaddr"));
1117                                }
1118
1119                        }
1120
1121                        fprintf(fp, "eap_server=0\n");
1122                        fprintf(fp, "auth_algs=1\n");
1123                        char retry[32];
1124                        sprintf(retry, "%s_radius_retry", ifname);
1125                        fprintf(fp, "radius_retry_primary_interval=%s\n", nvram_default_get(retry, "600"));
1126                        types = hostapd_eap_get_types();
1127                        fprintf(fp, "%s", types);
1128                        free(types);
1129                        fprintf(fp, "auth_server_addr=%s\n", nvram_nget("%s_radius_ipaddr", ifname));
1130                        fprintf(fp, "auth_server_port=%s\n", nvram_nget("%s_radius_port", ifname));
1131                        fprintf(fp, "auth_server_shared_secret=%s\n", nvram_nget("%s_radius_key", ifname));
1132                        char check[64];
1133                        sprintf(check, "%s_radius2_ipaddr", ifname);
1134                        nvram_default_get(check, "0.0.0.0");
1135                        if (!nvram_nmatch("", "%s_radius2_ipaddr", ifname)
1136                            && !nvram_nmatch("0.0.0.0", "%s_radius2_ipaddr", ifname)
1137                            && !nvram_nmatch("", "%s_radius2_port", ifname)) {
1138                                fprintf(fp, "auth_server_addr=%s\n", nvram_nget("%s_radius2_ipaddr", ifname));
1139                                fprintf(fp, "auth_server_port=%s\n", nvram_nget("%s_radius2_port", ifname));
1140                                fprintf(fp, "auth_server_shared_secret=%s\n", nvram_nget("%s_radius2_key", ifname));
1141                        }
1142                        if (nvram_nmatch("1", "%s_acct", ifname)) {
1143                                fprintf(fp, "acct_server_addr=%s\n", nvram_nget("%s_acct_ipaddr", ifname));
1144                                fprintf(fp, "acct_server_port=%s\n", nvram_nget("%s_acct_port", ifname));
1145                                fprintf(fp, "acct_server_shared_secret=%s\n", nvram_nget("%s_acct_key", ifname));
1146                        }
1147                }
1148                if (nvram_invmatch(akm, "radius")) {
1149                        sprintf(psk, "%s_crypto", ifname);
1150                        if (nvram_match(psk, "aes"))
1151                                fprintf(fp, "wpa_pairwise=CCMP\n");
1152                        if (nvram_match(psk, "gcmp"))
1153                                fprintf(fp, "wpa_pairwise=GCMP\n");
1154                        if (nvram_match(psk, "tkip")) {
1155                                if (!isfirst)
1156                                        fprintf(fp, "ieee80211n=0\n");
1157                                fprintf(fp, "wpa_pairwise=TKIP\n");
1158                        }
1159                        if (nvram_match(psk, "tkip+aes"))
1160                                fprintf(fp, "wpa_pairwise=TKIP CCMP\n");
1161                        fprintf(fp, "wpa_group_rekey=%s\n", nvram_nget("%s_wpa_gtk_rekey", ifname));
1162                }
1163                // fprintf (fp, "jumpstart_p1=1\n");
1164        }
1165#ifdef HAVE_HOTSPOT20
1166        setupHS20(fp, ifname);
1167#endif
1168        char *v = nvram_nget("%s_config", ifname);
1169        fprintf(fp, "\n");
1170        if (v && strlen(v) > 0)
1171                fprintf(fp, "%s", v);
1172        fprintf(fp, "\n");
1173
1174        fclose(fp);
1175}
1176
1177/* das muessen wir noch machen
1178void setupradauth_ath9k(char *prefix, char *driver, int iswan) {
1179        if (nvram_match(akm, "radius")) {
1180                // wrt-radauth $IFNAME $server $port $share $override $mackey $maxun
1181                // &
1182                char *ifname = prefix;
1183                char *server = nvram_nget("%s_radius_ipaddr", prefix);
1184                char *port = nvram_nget("%s_radius_port", prefix);
1185                char *share = nvram_nget("%s_radius_key", prefix);
1186                char exec[64];
1187                char type[32];
1188
1189                sprintf(type, "%s_radmactype", prefix);
1190                char *pragma = "";
1191
1192                if (nvram_default_match(type, "0", "0"))
1193                        pragma = "-n1 ";
1194                if (nvram_matchi(type,1))
1195                        pragma = "-n2 ";
1196                if (nvram_matchi(type,2))
1197                        pragma = "-n3 ";
1198                if (nvram_matchi(type,3))
1199                        pragma = "";
1200                sleep(1);       // some delay is usefull
1201                sysprintf("wrt-radauth %s %s %s %s %s 1 1 0 &", pragma,
1202                          prefix, server, port, share);
1203        }
1204*/
1205
1206static void addvhtcaps(char *prefix, FILE * fp)
1207{
1208
1209/* must use integer mask */
1210#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE                 0x00000800
1211#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE                 0x00001000
1212#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE                 0x00080000
1213#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE                 0x00100000
1214#define IEEE80211_VHT_CAP_SHORT_GI_80                           0x00000020
1215#define IEEE80211_VHT_CAP_SHORT_GI_160                          0x00000040
1216#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT                  13
1217#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK                   \
1218                (7 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT)
1219#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT             16
1220#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK              \
1221                (7 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT)
1222
1223        unsigned int mask;
1224#ifdef HAVE_ATH10K
1225        if (has_ac(prefix)) {
1226                char shortgi[32];
1227                sprintf(shortgi, "%s_shortgi", prefix);
1228                char mubf[32];
1229                sprintf(mubf, "%s_mubf", prefix);
1230                char subf[32];
1231                sprintf(subf, "%s_subf", prefix);
1232                mask = 0;
1233                if (nvram_default_match(subf, "0", "0")) {
1234                        mask |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1235                        mask |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1236                        mask |= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
1237                        mask |= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
1238                }
1239                if (nvram_default_match(mubf, "0", "0")) {
1240                        mask |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1241                        mask |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1242                }
1243                if (nvram_default_match(shortgi, "0", "1")) {
1244                        mask |= IEEE80211_VHT_CAP_SHORT_GI_80;
1245                        mask |= IEEE80211_VHT_CAP_SHORT_GI_160;
1246                }
1247                if (mask) {
1248                        fprintf(fp, "\tvht_capa=0\n");
1249                        fprintf(fp, "\tvht_capa_mask=%d\n", mask);
1250                }
1251        }
1252#endif
1253#ifdef HAVE_ATH9K
1254        if (is_ath9k(prefix)) {
1255                char shortgi[32];
1256                sprintf(shortgi, "%s_shortgi", prefix);
1257                if (nvram_matchi(shortgi, 0))
1258                        fprintf(fp, "\tdisable_sgi=1\n");
1259        }
1260#endif
1261}
1262
1263void setupSupplicant_ath9k(char *prefix, char *ssidoverride)
1264{
1265#ifdef HAVE_REGISTER
1266        if (!isregistered())
1267                return;
1268#endif
1269        char akm[16];
1270        int i;
1271        sprintf(akm, "%s_akm", prefix);
1272        if (nvram_match(akm, "psk") || nvram_match(akm, "psk2")
1273            || nvram_match(akm, "psk psk2")) {
1274                char fstr[32];
1275                char psk[16];
1276                if (!strncmp(prefix, "ath0", 4))
1277                        led_control(LED_SEC0, LED_ON);
1278                if (!strncmp(prefix, "ath1", 4))
1279                        led_control(LED_SEC1, LED_ON);
1280                sprintf(fstr, "/tmp/%s_wpa_supplicant.conf", prefix);
1281                FILE *fp = fopen(fstr, "wb");
1282                fprintf(fp, "ap_scan=1\n");
1283                fprintf(fp, "fast_reauth=1\n");
1284                fprintf(fp, "eapol_version=1\n");
1285                // fprintf (fp, "ctrl_interface_group=0\n");
1286                // fprintf (fp, "ctrl_interface=/var/run/wpa_supplicant\n");
1287                fprintf(fp, "network={\n");
1288
1289                addvhtcaps(prefix, fp);
1290                if (!ssidoverride)
1291                        ssidoverride = nvram_nget("%s_ssid", prefix);
1292                fprintf(fp, "\tssid=\"%s\"\n", ssidoverride);
1293                char scanlist[32];
1294                sprintf(scanlist, "%s_scanlist", prefix);
1295                char *sl = nvram_default_get(scanlist, "default");
1296                if (strcmp(sl, "default")) {
1297                        fprintf(fp, "\tscan_freq=%s\n", sl);
1298                }
1299#ifdef HAVE_UNIWIP
1300                fprintf(fp, "\tbgscan=\"simple:30:-45:300\"\n");
1301#endif
1302                // fprintf (fp, "\tmode=0\n");
1303                fprintf(fp, "\tscan_ssid=1\n");
1304                fprintf(fp, "\tkey_mgmt=WPA-PSK\n");
1305                sprintf(psk, "%s_crypto", prefix);
1306                if (nvram_match(psk, "aes")) {
1307#if 1
1308                        fprintf(fp, "\tpairwise=CCMP\n");
1309                        fprintf(fp, "\tgroup=CCMP TKIP\n");
1310#else
1311                        fprintf(fp, "\tpairwise=CCMP\n");
1312                        fprintf(fp, "\tgroup=CCMP\n");
1313#endif
1314                }
1315                if (nvram_match(psk, "tkip")) {
1316                        fprintf(fp, "\tpairwise=TKIP\n");
1317                        fprintf(fp, "\tgroup=TKIP\n");
1318                }
1319                if (nvram_match(psk, "gcmp")) {
1320                        fprintf(fp, "\tpairwise=GCMP\n");
1321                        fprintf(fp, "\tgroup=GCMP\n");
1322                }
1323                if (nvram_match(psk, "tkip+aes")) {
1324                        fprintf(fp, "\tpairwise=CCMP TKIP\n");
1325                        fprintf(fp, "\tgroup=CCMP TKIP\n");
1326                }
1327                if (nvram_match(akm, "psk"))
1328                        fprintf(fp, "\tproto=WPA\n");
1329                if (nvram_match(akm, "psk2"))
1330                        fprintf(fp, "\tproto=RSN\n");
1331                if (nvram_match(akm, "psk psk2"))
1332                        fprintf(fp, "\tproto=WPA RSN\n");
1333                char *wpa_psk = nvram_nget("%s_wpa_psk", prefix);
1334                if (strlen(wpa_psk) == 64)
1335                        fprintf(fp, "\tpsk=%s\n", wpa_psk);
1336                else
1337                        fprintf(fp, "\tpsk=\"%s\"\n", wpa_psk);
1338                fprintf(fp, "}\n");
1339                char extra[32];
1340                sprintf(extra, "%s_supplicantext", prefix);
1341                if (nvram_invmatch(extra, ""))
1342                        fwritenvram(extra, fp);
1343                fclose(fp);
1344        } else if (nvram_match(akm, "8021X")) {
1345                char fstr[32];
1346                char psk[64];
1347                char ath[64];
1348                if (!strncmp(prefix, "ath0", 4))
1349                        led_control(LED_SEC0, LED_ON);
1350                if (!strncmp(prefix, "ath1", 4))
1351                        led_control(LED_SEC1, LED_ON);
1352                sprintf(fstr, "/tmp/%s_wpa_supplicant.conf", prefix);
1353                FILE *fp = fopen(fstr, "wb");
1354                fprintf(fp, "ap_scan=1\n");
1355                fprintf(fp, "fast_reauth=1\n");
1356                fprintf(fp, "eapol_version=1\n");
1357                // fprintf (fp, "ctrl_interface_group=0\n");
1358                // fprintf (fp, "ctrl_interface=/var/run/wpa_supplicant\n");
1359                fprintf(fp, "network={\n");
1360                addvhtcaps(prefix, fp);
1361                if (!ssidoverride)
1362                        ssidoverride = nvram_nget("%s_ssid", prefix);
1363                fprintf(fp, "\tssid=\"%s\"\n", ssidoverride);
1364#ifdef HAVE_UNIWIP
1365                fprintf(fp, "\tbgscan=\"simple:30:-45:300\"\n");
1366#endif
1367                fprintf(fp, "\tscan_ssid=1\n");
1368                if (nvram_prefix_match("8021xtype", prefix, "tls")) {
1369// -> added habeIchVergessen
1370                        char *keyExchng = nvram_nget("%s_tls8021xkeyxchng", prefix);
1371                        char wpaOpts[40];
1372                        if (strlen(keyExchng) == 0)
1373                                nvram_nset("wep", "%s_tls8021xkeyxchng", prefix);
1374                        sprintf(wpaOpts, "");
1375                        keyExchng = nvram_nget("%s_tls8021xkeyxchng", prefix);
1376                        if (strcmp("wpa2", keyExchng) == 0)
1377                                sprintf(wpaOpts, "\tpairwise=CCMP\n\tgroup=CCMP\n");
1378                        if (strcmp("wpa2mixed", keyExchng) == 0)
1379                                sprintf(wpaOpts, "\tpairwise=CCMP TKIP\n\tgroup=CCMP TKIP\n");
1380                        if (strcmp("wpa", keyExchng) == 0)
1381                                sprintf(wpaOpts, "\tpairwise=TKIP\n\tgroup=TKIP\n");
1382                        fprintf(fp, "\tkey_mgmt=%s\n%s", (strlen(wpaOpts) == 0 ? "IEEE8021X" : "WPA-EAP"), wpaOpts);
1383// <- added habeIchVergessen
1384                        fprintf(fp, "\teap=TLS\n");
1385                        fprintf(fp, "\tidentity=\"%s\"\n", nvram_prefix_get("tls8021xuser", prefix));
1386                        sprintf(psk, "/tmp/%s", prefix);
1387                        mkdir(psk, 0700);
1388                        sprintf(psk, "/tmp/%s/ca.pem", prefix);
1389                        sprintf(ath, "%s_tls8021xca", prefix);
1390                        write_nvram(psk, ath);
1391                        sprintf(psk, "/tmp/%s/user.pem", prefix);
1392                        sprintf(ath, "%s_tls8021xpem", prefix);
1393                        write_nvram(psk, ath);
1394                        sprintf(psk, "/tmp/%s/user.prv", prefix);
1395                        sprintf(ath, "%s_tls8021xprv", prefix);
1396                        write_nvram(psk, ath);
1397                        fprintf(fp, "\tca_cert=\"/tmp/%s/ca.pem\"\n", prefix);
1398                        fprintf(fp, "\tclient_cert=\"/tmp/%s/user.pem\"\n", prefix);
1399                        fprintf(fp, "\tprivate_key=\"/tmp/%s/user.prv\"\n", prefix);
1400                        fprintf(fp, "\tprivate_key_passwd=\"%s\"\n", nvram_prefix_get("tls8021xpasswd", prefix));
1401                        fprintf(fp, "\teapol_flags=3\n");
1402                        if (strlen(nvram_nget("%s_tls8021xphase2", prefix)) > 0) {
1403                                fprintf(fp, "\tphase2=\"%s\"\n", nvram_nget("%s_tls8021xphase2", prefix));
1404                        }
1405                        if (strlen(nvram_nget("%s_tls8021xanon", prefix)) > 0) {
1406                                fprintf(fp, "\tanonymous_identity=\"%s\"\n", nvram_nget("%s_tls8021xanon", prefix));
1407                        }
1408                        if (strlen(nvram_nget("%s_tls8021xaddopt", prefix)) > 0) {
1409                                sprintf(ath, "%s_tls8021xaddopt", prefix);
1410                                fprintf(fp, "\t");      // tab
1411                                fwritenvram(ath, fp);
1412                                fprintf(fp, "\n");      // extra new line at the end
1413                        }
1414                }
1415                if (nvram_prefix_match("8021xtype", prefix, "peap")) {
1416                        fprintf(fp, "\tkey_mgmt=WPA-EAP\n");
1417                        fprintf(fp, "\teap=PEAP\n");
1418                        fprintf(fp, "\tpairwise=CCMP TKIP\n");
1419                        fprintf(fp, "\tgroup=CCMP TKIP\n");
1420                        fprintf(fp, "\tphase1=\"peapver=0\"\n");
1421                        fprintf(fp, "\tidentity=\"%s\"\n", nvram_prefix_get("peap8021xuser", prefix));
1422                        fprintf(fp, "\tpassword=\"%s\"\n", nvram_prefix_get("peap8021xpasswd", prefix));
1423                        sprintf(psk, "/tmp/%s", prefix);
1424                        mkdir(psk, 0700);
1425                        sprintf(psk, "/tmp/%s/ca.pem", prefix);
1426                        sprintf(ath, "%s_peap8021xca", prefix);
1427                        if (!nvram_match(ath, "")) {
1428                                write_nvram(psk, ath);
1429                                fprintf(fp, "\tca_cert=\"/tmp/%s/ca.pem\"\n", prefix);
1430                        }
1431                        if (strlen(nvram_nget("%s_peap8021xphase2", prefix)) > 0) {
1432                                fprintf(fp, "\tphase2=\"%s\"\n", nvram_nget("%s_peap8021xphase2", prefix));
1433                        }
1434                        if (strlen(nvram_nget("%s_peap8021xanon", prefix)) > 0) {
1435                                fprintf(fp, "\tanonymous_identity=\"%s\"\n", nvram_nget("%s_peap8021xanon", prefix));
1436                        }
1437                        if (strlen(nvram_nget("%s_peap8021xaddopt", prefix)) > 0) {
1438                                sprintf(ath, "%s_peap8021xaddopt", prefix);
1439                                fprintf(fp, "\t");      // tab
1440                                fwritenvram(ath, fp);
1441                                fprintf(fp, "\n");      // extra new line at the end
1442                        }
1443                }
1444                if (nvram_prefix_match("8021xtype", prefix, "ttls")) {
1445                        fprintf(fp, "\tkey_mgmt=WPA-EAP\n");
1446                        fprintf(fp, "\teap=TTLS\n");
1447                        fprintf(fp, "\tpairwise=CCMP TKIP\n");
1448                        fprintf(fp, "\tgroup=CCMP TKIP\n");
1449                        fprintf(fp, "\tidentity=\"%s\"\n", nvram_prefix_get("ttls8021xuser", prefix));
1450                        fprintf(fp, "\tpassword=\"%s\"\n", nvram_prefix_get("ttls8021xpasswd", prefix));
1451                        if (strlen(nvram_nget("%s_ttls8021xca", prefix)) > 0) {
1452                                sprintf(psk, "/tmp/%s", prefix);
1453                                mkdir(psk, 0700);
1454                                sprintf(psk, "/tmp/%s/ca.pem", prefix);
1455                                sprintf(ath, "%s_ttls8021xca", prefix);
1456                                write_nvram(psk, ath);
1457                                fprintf(fp, "\tca_cert=\"/tmp/%s/ca.pem\"\n", prefix);
1458                        }
1459                        if (strlen(nvram_nget("%s_ttls8021xphase2", prefix)) > 0) {
1460                                fprintf(fp, "\tphase2=\"%s\"\n", nvram_nget("%s_ttls8021xphase2", prefix));
1461                        }
1462                        if (strlen(nvram_nget("%s_ttls8021xanon", prefix)) > 0) {
1463                                fprintf(fp, "\tanonymous_identity=\"%s\"\n", nvram_nget("%s_ttls8021xanon", prefix));
1464                        }
1465                        if (strlen(nvram_nget("%s_ttls8021xaddopt", prefix)) > 0) {
1466                                sprintf(ath, "%s_ttls8021xaddopt", prefix);
1467                                fprintf(fp, "\t");      // tab
1468                                fwritenvram(ath, fp);
1469                                fprintf(fp, "\n");      // extra new line at the end
1470                        }
1471                }
1472                if (nvram_prefix_match("8021xtype", prefix, "leap")) {
1473                        fprintf(fp, "\tkey_mgmt=WPA-EAP\n");
1474                        fprintf(fp, "\teap=LEAP\n");
1475                        fprintf(fp, "\tauth_alg=LEAP\n");
1476                        fprintf(fp, "\tproto=WPA RSN\n");
1477                        fprintf(fp, "\tpairwise=CCMP TKIP\n");
1478                        fprintf(fp, "\tgroup=CCMP TKIP\n");
1479                        fprintf(fp, "\tidentity=\"%s\"\n", nvram_prefix_get("leap8021xuser", prefix));
1480                        fprintf(fp, "\tpassword=\"%s\"\n", nvram_prefix_get("leap8021xpasswd", prefix));
1481                        // sprintf (psk, "/tmp/%s", prefix);
1482                        // mkdir (psk);
1483                        // sprintf (psk, "/tmp/%s/ca.pem", prefix);
1484                        // sprintf (ath, "%s_peap8021xca", prefix);
1485                        // write_nvram (psk, ath);
1486                        // fprintf (fp, "\tca_cert=\"/tmp/%s/ca.pem\"\n", prefix);
1487                        if (strlen(nvram_nget("%s_leap8021xphase2", prefix)) > 0) {
1488                                fprintf(fp, "\tphase2=\"%s\"\n", nvram_nget("%s_leap8021xphase2", prefix));
1489                        }
1490                        if (strlen(nvram_nget("%s_leap8021xanon", prefix)) > 0) {
1491                                fprintf(fp, "\tanonymous_identity=\"%s\"\n", nvram_nget("%s_leap8021xanon", prefix));
1492                        }
1493                        if (strlen(nvram_nget("%s_leap8021xaddopt", prefix)) > 0) {
1494                                sprintf(ath, "%s_leap8021xaddopt", prefix);
1495                                fprintf(fp, "\t");      // tab
1496                                fwritenvram(ath, fp);
1497                                fprintf(fp, "\n");      // extra new line at the end
1498                        }
1499                }
1500                fprintf(fp, "}\n");
1501                char extra[32];
1502                sprintf(extra, "%s_supplicantext", prefix);
1503                if (nvram_invmatch(extra, ""))
1504                        fwritenvram(extra, fp);
1505                fclose(fp);
1506        } else if (nvram_match(akm, "disabled") || nvram_match(akm, "wep")) {
1507                char fstr[32];
1508                char psk[16];
1509                if (nvram_match(akm, "wep")) {
1510                        if (!strncmp(prefix, "ath0", 4))
1511                                led_control(LED_SEC0, LED_ON);
1512                        if (!strncmp(prefix, "ath1", 4))
1513                                led_control(LED_SEC1, LED_ON);
1514                }
1515                sprintf(fstr, "/tmp/%s_wpa_supplicant.conf", prefix);
1516                FILE *fp = fopen(fstr, "wb");
1517                fprintf(fp, "ap_scan=1\n");
1518                // fprintf (fp, "ctrl_interface_group=0\n");
1519                // fprintf (fp, "ctrl_interface=/var/run/wpa_supplicant\n");
1520                fprintf(fp, "network={\n");
1521                addvhtcaps(prefix, fp);
1522                if (!ssidoverride)
1523                        ssidoverride = nvram_nget("%s_ssid", prefix);
1524                fprintf(fp, "\tssid=\"%s\"\n", ssidoverride);
1525#ifdef HAVE_UNIWIP
1526                fprintf(fp, "\tbgscan=\"simple:30:-45:300\"\n");
1527#endif
1528                // fprintf (fp, "\tmode=0\n");
1529                fprintf(fp, "\tscan_ssid=1\n");
1530                fprintf(fp, "\tkey_mgmt=NONE\n");
1531                if (nvram_match(akm, "wep")) {
1532                        int cnt = 0;
1533                        char *authmode = nvram_nget("%s_authmode", prefix);
1534                        if (!strcmp(authmode, "shared"))
1535                                fprintf(fp, "auth_alg=SHARED\n");
1536                        else
1537                                fprintf(fp, "auth_alg=OPEN\n");
1538                        for (i = 1; i < 5; i++) {
1539                                char *athkey = nvram_nget("%s_key%d", prefix, i);
1540                                if (athkey != NULL && strlen(athkey) > 0) {
1541                                        fprintf(fp, "wep_key%d=%s\n", i - 1, athkey);   // setup wep
1542                                }
1543                        }
1544
1545                        sprintf(psk, "%s", nvram_nget("%s_key", prefix));
1546                        fprintf(fp, "wep_tx_keyidx=%d\n", atoi(psk) - 1);
1547                }
1548                fprintf(fp, "}\n");
1549                char extra[32];
1550                sprintf(extra, "%s_supplicantext", prefix);
1551                if (nvram_invmatch(extra, ""))
1552                        fwritenvram(extra, fp);
1553                fclose(fp);
1554        }
1555
1556}
1557
1558extern void do_hostapd(char *fstr, char *prefix);
1559void ath9k_start_supplicant(int count)
1560{
1561// erst hostapd starten fuer repeater mode
1562// dann wpa_supplicant mit link zu hostapd
1563// dann bridgen und konfiguriren
1564        char *next;
1565        char var[80];
1566        char fstr[32];
1567        char bridged[32];
1568        char mode[80];
1569        char dev[10];
1570        char power[32];
1571        char *apm, *vifs;
1572        char wl[16];
1573        char ctrliface[32] = "";
1574        char wifivifs[16];
1575        char tmp[256];
1576#ifdef HAVE_CONFIG_DEBUG_SYSLOG
1577        char *background = "-Bs";
1578#else
1579        char *background = "-B";
1580#endif
1581        char *debug;
1582        char psk[16];
1583        char net[16];
1584        char wmode[16];
1585        int ctrlifneeded = 0;
1586        char wif[10];
1587        sprintf(wif, "phy%d", get_ath9k_phy_idx(count));
1588        sprintf(wl, "ath%d_mode", count);
1589        sprintf(dev, "ath%d", count);
1590        sprintf(net, "%s_net_mode", dev);
1591        char *netmode = nvram_default_get(net, "mixed");
1592        if (!strcmp(netmode, "disabled"))
1593                return;
1594        apm = nvram_safe_get(wl);
1595        sprintf(wifivifs, "ath%d_vifs", count);
1596        sprintf(power, "ath%d_txpwrdbm", count);
1597        vifs = nvram_safe_get(wifivifs);
1598        sprintf(psk, "-i%s", dev);
1599        if (has_ad(dev))
1600                sprintf(psk, "-igiwifi");
1601
1602        sprintf(wmode, "%s_mode", dev);
1603        sprintf(bridged, "%s_bridged", dev);
1604        debug = nvram_nget("%s_wpa_debug", dev);
1605#ifdef HAVE_CONFIG_DEBUG_SYSLOG
1606        if (debug != NULL) {
1607                if (!strcmp(debug, "1"))
1608                        background = "-Bds";
1609                else if (!strcmp(debug, "2"))
1610                        background = "-Bdds";
1611                else if (!strcmp(debug, "3"))
1612                        background = "-Bddds";
1613        }
1614#else
1615        if (debug != NULL) {
1616                if (!strcmp(debug, "1"))
1617                        background = "-Bd";
1618                else if (!strcmp(debug, "2"))
1619                        background = "-Bdd";
1620                else if (!strcmp(debug, "3"))
1621                        background = "-Bddd";
1622        }
1623#endif
1624        if (strcmp(apm, "sta") && strcmp(apm, "wdssta")
1625            && strcmp(apm, "wet")) {
1626                sprintf(fstr, "/tmp/%s_hostap.conf", dev);
1627                do_hostapd(fstr, dev);
1628        } else {
1629                if (strlen(vifs) > 0) {
1630                        sprintf(fstr, "/tmp/%s_hostap.conf", dev);
1631                        do_hostapd(fstr, dev);
1632                        sprintf(ctrliface, "/var/run/hostapd/%s.1", dev);
1633                        sprintf(fstr, "/tmp/%s_wpa_supplicant.conf", dev);
1634#ifdef HAVE_RELAYD
1635                        if ((nvram_match(wmode, "wdssta"))
1636                            && nvram_matchi(bridged, 1))
1637                                eval("wpa_supplicant", "-b", getBridge(dev, tmp), background, "-Dnl80211", psk, "-H", ctrliface, "-c", fstr);
1638                        else
1639                                eval("wpa_supplicant", background, "-Dnl80211", psk, "-H", ctrliface, "-c", fstr);
1640#else
1641                        if ((nvram_match(wmode, "wdssta")
1642                             || nvram_match(wmode, "wet"))
1643                            && nvram_matchi(bridged, 1))
1644                                eval("wpa_supplicant", "-b", getBridge(dev, tmp), background, "-Dnl80211", psk, "-H", ctrliface, "-c", fstr);
1645                        else
1646                                eval("wpa_supplicant", background, "-Dnl80211", psk, "-H", ctrliface, "-c", fstr);
1647#endif
1648                } else {
1649                        sprintf(fstr, "/tmp/%s_wpa_supplicant.conf", dev);
1650#ifdef HAVE_RELAYD
1651                        if ((nvram_match(wmode, "wdssta"))
1652                            && nvram_matchi(bridged, 1))
1653                                eval("wpa_supplicant", "-b", getBridge(dev, tmp), background, "-Dnl80211", psk, "-c", fstr);
1654                        else
1655                                eval("wpa_supplicant", background, "-Dnl80211", psk, "-c", fstr);
1656#else
1657                        if ((nvram_match(wmode, "wdssta")
1658                             || nvram_match(wmode, "wet"))
1659                            && nvram_matchi(bridged, 1))
1660                                eval("wpa_supplicant", "-b", getBridge(dev, tmp), background, "-Dnl80211", psk, "-c", fstr);
1661                        else
1662                                eval("wpa_supplicant", background, "-Dnl80211", psk, "-c", fstr);
1663#endif
1664                }
1665        }
1666        if (has_ad(dev))
1667                sprintf(dev, "giwifi");
1668#ifdef HAVE_RELAYD
1669        if (strcmp(apm, "sta") && strcmp(apm, "wet")) {
1670#else
1671        if (strcmp(apm, "sta")) {
1672#endif
1673                char bridged[32];
1674                sprintf(bridged, "%s_bridged", dev);
1675                if (nvram_default_match(bridged, "1", "1")) {
1676                        eval("ifconfig", dev, "0.0.0.0", "up");
1677                        br_add_interface(getBridge(dev, tmp), dev);
1678                        eval("ifconfig", dev, "0.0.0.0", "up");
1679                } else {
1680                        eval("ifconfig", dev, "mtu", getMTU(dev));
1681                        eval("ifconfig", dev, "txqueuelen", getTXQ(dev));
1682                        eval("ifconfig", dev, nvram_nget("%s_ipaddr", dev), "netmask", nvram_nget("%s_netmask", dev), "up");
1683                }
1684        } else {
1685#ifdef HAVE_RELAYD
1686                if (!strcmp(apm, "wet")) {
1687                        eval("ifconfig", dev, "0.0.0.0", "up");
1688//                      sysprintf("relayd -I %s -I %s -D -B", getBridge(dev),
1689//                                dev);
1690                }
1691#endif
1692
1693                char bridged[32];
1694                sprintf(bridged, "%s_bridged", dev);
1695                if (nvram_default_match(bridged, "0", "1")) {
1696                        eval("ifconfig", dev, "mtu", getMTU(dev));
1697                        eval("ifconfig", dev, "txqueuelen", getTXQ(dev));
1698                        eval("ifconfig", dev, nvram_nget("%s_ipaddr", dev), "netmask", nvram_nget("%s_netmask", dev), "up");
1699                }
1700        }
1701
1702        if (strlen(vifs) > 0) {
1703                foreach(var, vifs, next) {
1704                        sprintf(mode, "%s_mode", var);
1705                        char *m2 = nvram_safe_get(mode);
1706                        if (strcmp(m2, "sta")) {
1707                                char bridged[32];
1708                                sprintf(bridged, "%s_bridged", var);
1709                                if (nvram_default_match(bridged, "1", "1")) {
1710                                        eval("ifconfig", dev, "0.0.0.0", "up");
1711                                        br_add_interface(getBridge(var, tmp), var);
1712                                } else {
1713                                        eval("ifconfig", var, "mtu", getMTU(var));
1714                                        eval("ifconfig", var, "txqueuelen", getTXQ(var));
1715                                        eval("ifconfig", var, nvram_nget("%s_ipaddr", var), "netmask", nvram_nget("%s_netmask", var), "up");
1716                                }
1717                        }
1718                }
1719        }
1720        if (!strcmp(apm, "ap") || !strcmp(apm, "wdsap")) {
1721                int s;
1722                for (s = 1; s <= 10; s++) {
1723                        char wdsvarname[32] = {
1724                                0
1725                        };
1726                        char wdsdevname[32] = {
1727                                0
1728                        };
1729                        char wdsmacname[32] = {
1730                                0
1731                        };
1732                        char *wdsdev;
1733                        char *hwaddr;
1734                        sprintf(wdsvarname, "%s_wds%d_enable", dev, s);
1735                        sprintf(wdsdevname, "%s_wds%d_if", dev, s);
1736                        sprintf(wdsmacname, "%s_wds%d_hwaddr", dev, s);
1737                        wdsdev = nvram_safe_get(wdsdevname);
1738                        if (strlen(wdsdev) == 0)
1739                                continue;
1740                        if (nvram_matchi(wdsvarname, 0))
1741                                continue;
1742                        hwaddr = nvram_get(wdsmacname);
1743                        if (hwaddr != NULL) {
1744                                eval("iw", wif, "interface", "add", wdsdev, "type", "wds");
1745                                eval("iw", "dev", wdsdev, "set", "peer", hwaddr);
1746                                eval("ifconfig", wdsdev, "0.0.0.0", "up");
1747                        }
1748                }
1749        }
1750        int newpower = nvram_default_geti(power, 16);
1751        sysprintf("iw phy %s set txpower fixed %d", wif, newpower * 100);
1752}
1753#endif
Note: See TracBrowser for help on using the repository browser.