source: src/router/libutils/utils.c @ 31860

Last change on this file since 31860 was 31860, checked in by brainslayer, 2 months ago

fix unresolved symbol

File size: 232.4 KB
Line 
1/*
2
3 * utils.c
4 *
5 * Copyright (C) 2007 Sebastian Gottschall <gottschall@dd-wrt.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 * $Id:
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <errno.h>
28#include <net/if.h>
29#include <dirent.h>
30#include <unistd.h>
31#include <ctype.h>
32#include <syslog.h>
33#include <sys/socket.h>
34#include <sys/stat.h>
35#include <sys/statfs.h>
36#include <fcntl.h>
37#include <netinet/in.h>
38#include <stdarg.h>
39#include <sys/ioctl.h>
40#include <sys/sysinfo.h>
41#include <arpa/inet.h>
42#include <netpacket/packet.h>
43#include <netdb.h>
44#include <resolv.h>
45#include <signal.h>
46#include <glob.h>
47
48#include <utils.h>
49#include <wlutils.h>
50#include <bcmnvram.h>
51#include <shutils.h>
52#include <cy_conf.h>
53#include <code_pattern.h>
54#include <bcmdevs.h>
55#include <net/route.h>
56#include <cy_conf.h>
57#include <bcmdevs.h>
58#include <linux/if_ether.h>
59// #include <linux/mii.h>
60#include <linux/sockios.h>
61#include <cymac.h>
62#include <broadcom.h>
63#ifdef HAVE_IPV6
64#include <ifaddrs.h>
65#endif
66#ifndef IP_ALEN
67#define IP_ALEN 4
68#endif
69
70#ifndef unlikely
71#define unlikely(x)     __builtin_expect((x),0)
72#endif
73
74#define SIOCGMIIREG     0x8948  /* Read MII PHY register.  */
75#define SIOCSMIIREG     0x8949  /* Write MII PHY register.  */
76
77struct mii_ioctl_data {
78        unsigned short phy_id;
79        unsigned short reg_num;
80        unsigned short val_in;
81        unsigned short val_out;
82};
83
84#define TRX_MAGIC_F7D3301                       0x20100322      /* Belkin Share Max; router's birthday ? */
85#define TRX_MAGIC_F7D3302                       0x20090928      /* Belkin Share; router's birthday ? */
86#define TRX_MAGIC_F7D4302                       0x20091006      /* Belkin Play; router's birthday ? */
87
88#ifdef HAVE_FONERA
89static void inline getBoardMAC(char *mac)
90{
91        // 102
92        int i;
93        char op[32];
94        unsigned char data[256];
95        FILE *in;
96
97        sprintf(op, "/dev/mtdblock/%d", getMTD("board_config"));
98        in = fopen(op, "rb");
99        if (in == NULL)
100                return;
101        fread(data, 256, 1, in);
102        fclose(in);
103        sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", data[102] & 0xff, data[103] & 0xff, data[104] & 0xff, data[105] & 0xff, data[106] & 0xff, data[107] & 0xff);
104}
105#endif
106
107int count_processes(char *pidName)
108{
109        FILE *fp;
110        char line[254];
111        char safename[64];
112
113        sprintf(safename, " %s ", pidName);
114        char zombie[64];
115
116        sprintf(zombie, "Z   [%s]", pidName);   // do not count zombies
117        int i = 0;
118
119        cprintf("Search for %s\n", pidName);
120        if ((fp = popen("ps", "r"))) {
121                while (fgets(line, sizeof(line), fp) != NULL) {
122                        int len = strlen(line);
123                        if (len > 254)
124                                len = 254;
125                        line[len - 1] = ' ';
126                        line[len] = 0;
127                        if (strstr(line, safename) && !strstr(line, zombie)) {
128                                i++;
129                        }
130                }
131                pclose(fp);
132        }
133        cprintf("Search done... %d\n", i);
134
135        return i;
136}
137
138/*
139 * This function returns the number of days for the given month in the given
140 * year
141 */
142unsigned int daysformonth(unsigned int month, unsigned int year)
143{
144        return (30 + (((month & 9) == 8)
145                      || ((month & 9) == 1)) - (month == 2) - (!(((year % 4) == 0)
146                                                                 && (((year % 100) != 0)
147                                                                     || ((year % 400) == 0)))
148                                                               && (month == 2)));
149}
150
151#ifdef HAVE_IPV6
152const char *getifaddr(char *ifname, int family, int linklocal)
153{
154        static char buf[INET6_ADDRSTRLEN];
155        void *addr = NULL;
156        struct ifaddrs *ifap, *ifa;
157
158        if (getifaddrs(&ifap) != 0) {
159                dprintf("getifaddrs failed: %s\n", strerror(errno));
160                return NULL;
161        }
162
163        for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
164                if ((ifa->ifa_addr == NULL) || (strncmp(ifa->ifa_name, ifname, IFNAMSIZ) != 0) || (ifa->ifa_addr->sa_family != family))
165                        continue;
166
167                if (ifa->ifa_addr->sa_family == AF_INET6) {
168                        struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
169                        if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr) ^ linklocal)
170                                continue;
171                        addr = (void *)&(s6->sin6_addr);
172                } else {
173                        struct sockaddr_in *s = (struct sockaddr_in *)(ifa->ifa_addr);
174                        addr = (void *)&(s->sin_addr);
175                }
176
177                if ((addr) && inet_ntop(ifa->ifa_addr->sa_family, addr, buf, sizeof(buf)) != NULL) {
178                        freeifaddrs(ifap);
179                        return buf;
180                }
181        }
182
183        freeifaddrs(ifap);
184        return NULL;
185}
186#endif
187#ifdef HAVE_VLANTAGGING
188char *getBridge(char *ifname, char *word)
189{
190        char *next, *wordlist;
191
192        wordlist = nvram_safe_get("bridgesif");
193        foreach(word, wordlist, next) {
194                char *port = word;
195                char *tag = strsep(&port, ">");
196                char *prio = port;
197
198                strsep(&prio, ">");
199                if (!tag || !port)
200                        break;
201                if (!strcmp(port, ifname))
202                        return tag;
203        }
204        return nvram_safe_get("lan_ifname");
205}
206#else
207char *getBridge(char *ifname, char *word)
208{
209        return nvram_safe_get("lan_ifname");
210}
211#endif
212
213char *getBridgeMTU(const char *ifname, char *word)
214{
215        char *next, *wordlist;
216
217        wordlist = nvram_safe_get("bridges");
218        foreach(word, wordlist, next) {
219                char *stp = word;
220                char *bridge = strsep(&stp, ">");
221                char *mtu = stp;
222                char *prio = strsep(&mtu, ">");
223
224                if (prio)
225                        strsep(&mtu, ">");
226
227                if (!bridge || !stp)
228                        break;
229                if (!strcmp(bridge, ifname)) {
230                        if (!prio || !mtu)
231                                return "1500";
232                        else
233                                return mtu;
234                }
235        }
236        return "1500";
237}
238
239char *getMTU(char *ifname)
240{
241        if (!ifname)
242                return "1500";
243        char *mtu = nvram_nget("%s_mtu", ifname);
244        if (!mtu || strlen(mtu) == 0)
245                return "1500";
246        return mtu;
247}
248
249char *getTXQ(char *ifname)
250{
251        if (!ifname)
252                return "1000";
253        char *txq = nvram_nget("%s_txq", ifname);
254        if (!txq || strlen(txq) == 0) {
255                int s;
256                struct ifreq ifr;
257                memset(&ifr, 0, sizeof(ifr));
258                if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
259                        return "0";
260                strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
261                ioctl(s, SIOCGIFTXQLEN, &ifr);
262                close(s);
263                static char rtxq[32];
264                sprintf(rtxq, "%d", ifr.ifr_qlen);
265                // get default len from interface
266                return rtxq;
267        }
268        return txq;
269}
270
271#ifdef HAVE_SVQOS
272char
273*get_wshaper_dev(void)
274{
275        if (nvram_match("wshaper_dev", "WAN"))
276                return get_wan_face();
277        else
278                return "br0";
279}
280
281char
282*get_mtu_val(char *buf)
283{
284        if (nvram_match("wshaper_dev", "WAN")
285            && !strcmp(get_wshaper_dev(), "ppp0"))
286                return nvram_safe_get("wan_mtu");
287        else if (nvram_match("wshaper_dev", "WAN")) {
288                if (nvram_matchi("wan_mtu", 1500))
289                        return getMTU(get_wshaper_dev());
290                else
291                        return nvram_safe_get("wan_mtu");
292        } else
293                return getBridgeMTU(get_wshaper_dev(), buf);
294}
295
296void add_client_dev_srvfilter(char *name, char *type, char *data, char *level, int base, char *chain)
297{
298        int idx = atoi(level) / 10;
299
300        if (idx == 10)
301                idx = 0;
302
303        if (strstr(type, "udp") || strstr(type, "both")) {
304                eval("iptables", "-t", "mangle", "-A", chain, "-p", "udp", "-m", "udp", "--dport", data, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
305                eval("iptables", "-t", "mangle", "-A", chain, "-p", "udp", "-m", "udp", "--sport", data, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
306        }
307
308        if (strstr(type, "tcp") || strstr(type, "both")) {
309                eval("iptables", "-t", "mangle", "-A", chain, "-p", "tcp", "-m", "tcp", "--dport", data, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
310                eval("iptables", "-t", "mangle", "-A", chain, "-p", "tcp", "-m", "tcp", "--sport", data, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
311        }
312
313        if (strstr(type, "l7")) {
314                insmod("ipt_layer7");
315                insmod("xt_layer7");
316                eval("iptables", "-t", "mangle", "-A", chain, "-m", "layer7", "--l7proto", name, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
317        }
318#ifdef HAVE_OPENDPI
319        if (strstr(type, "dpi")) {
320                char ndpi[32];
321                snprintf(ndpi, 32, "--%s", name);
322                insmod("xt_ndpi");
323                eval("iptables", "-t", "mangle", "-A", chain, "-m", "ndpi", ndpi, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
324        }
325#endif
326
327        if (strstr(type, "p2p")) {
328                char *proto = NULL;
329                char *realname = name;
330
331                if (!strcasecmp(realname, "applejuice"))
332                        proto = "apple";
333                else if (!strcasecmp(realname, "ares"))
334                        proto = "ares";
335                else if (!strcasecmp(realname, "bearshare"))
336                        proto = "gnu";
337                else if (!strcasecmp(realname, "bittorrent"))
338                        proto = "bit";
339                else if (!strcasecmp(realname, "directconnect"))
340                        proto = "dc";
341                else if (!strcasecmp(realname, "edonkey"))
342                        proto = "edk";
343                else if (!strcasecmp(realname, "gnutella"))
344                        proto = "gnu";
345                else if (!strcasecmp(realname, "kazaa"))
346                        proto = "kazaa";
347                else if (!strcasecmp(realname, "mute"))
348                        proto = "mute";
349                else if (!strcasecmp(realname, "soulseek"))
350                        proto = "soul";
351                else if (!strcasecmp(realname, "waste"))
352                        proto = "waste";
353                else if (!strcasecmp(realname, "winmx"))
354                        proto = "winmx";
355                else if (!strcasecmp(realname, "xdcc"))
356                        proto = "xdcc";
357                if (proto) {
358                        insmod("ipt_ipp2p");
359                        char ipp2p[32];
360                        snprintf(ipp2p, 32, "--%s", proto);
361
362                        eval("iptables", "-t", "mangle", "-A", chain, "-p", "tcp", "-m", "ipp2p", ipp2p, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
363
364                        if (!strcmp(proto, "bit")) {
365                                // bittorrent detection enhanced
366#ifdef HAVE_MICRO
367                                eval("iptables", "-t", "mangle", "-A", chain, "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
368#else
369                                eval("iptables", "-t", "mangle", "-A", chain, "-m", "length", "--length", "0:550", "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
370#endif
371                                eval("iptables", "-t", "mangle", "-A", chain, "-m", "layer7", "--l7proto", "bt1", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
372                                eval("iptables", "-t", "mangle", "-A", chain, "-m", "layer7", "--l7proto", "bt2", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
373                        }
374                }
375        }
376}
377
378void add_client_mac_srvfilter(char *name, char *type, char *data, char *level, int base, char *client)
379{
380        int idx = atoi(level) / 10;
381
382        if (idx == 10)
383                idx = 0;
384
385        if (strstr(type, "udp") || strstr(type, "both")) {
386                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "udp", "-m", "udp", "--dport", data, "-m", "mac", "--mac-source", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
387                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "udp", "-m", "udp", "--sport", data, "-m", "mac", "--mac-source", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
388        }
389
390        if (strstr(type, "tcp") || strstr(type, "both")) {
391                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "tcp", "-m", "tcp", "--dport", data, "-m", "mac", "--mac-source", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
392                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "tcp", "-m", "tcp", "--sport", data, "-m", "mac", "--mac-source", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
393        }
394
395        if (strstr(type, "l7")) {
396                insmod("ipt_layer7");
397                insmod("xt_layer7");
398                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-m", "mac", "--mac-source", client, "-m", "layer7", "--l7proto", name, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
399        }
400#ifdef HAVE_OPENDPI
401        if (strstr(type, "dpi")) {
402                char ndpi[32];
403                snprintf(ndpi, 32, "--%s", name);
404                insmod("xt_ndpi");
405                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-m", "mac", "--mac-source", client, "-m", "ndpi", ndpi, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
406        }
407#endif
408
409        if (strstr(type, "p2p")) {
410                char *proto = NULL;
411                char *realname = name;
412
413                if (!strcasecmp(realname, "applejuice"))
414                        proto = "apple";
415                else if (!strcasecmp(realname, "ares"))
416                        proto = "ares";
417                else if (!strcasecmp(realname, "bearshare"))
418                        proto = "gnu";
419                else if (!strcasecmp(realname, "bittorrent"))
420                        proto = "bit";
421                else if (!strcasecmp(realname, "directconnect"))
422                        proto = "dc";
423                else if (!strcasecmp(realname, "edonkey"))
424                        proto = "edk";
425                else if (!strcasecmp(realname, "gnutella"))
426                        proto = "gnu";
427                else if (!strcasecmp(realname, "kazaa"))
428                        proto = "kazaa";
429                else if (!strcasecmp(realname, "mute"))
430                        proto = "mute";
431                else if (!strcasecmp(realname, "soulseek"))
432                        proto = "soul";
433                else if (!strcasecmp(realname, "waste"))
434                        proto = "waste";
435                else if (!strcasecmp(realname, "winmx"))
436                        proto = "winmx";
437                else if (!strcasecmp(realname, "xdcc"))
438                        proto = "xdcc";
439                if (proto) {
440                        insmod("ipt_ipp2p");
441                        char ipp2p[32];
442                        snprintf(ipp2p, 32, "--%s", proto);
443
444                        eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "tcp", "-m", "mac", "--mac-source", client, "-m", "ipp2p", ipp2p, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
445
446                        if (!strcmp(proto, "bit")) {
447                                // bittorrent detection enhanced
448#ifdef HAVE_MICRO
449                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-m", "mac", "--mac-source", client, "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
450#else
451                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-m", "mac", "--mac-source", client, "-m", "length", "--length", "0:550", "-m", "layer7", "--l7proto", "bt", "-j", "MARK",
452                                     "--set-mark", qos_nfmark(base + idx));
453#endif
454                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-m", "mac", "--mac-source", client, "-m", "layer7", "--l7proto", "bt1", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
455                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-m", "mac", "--mac-source", client, "-m", "layer7", "--l7proto", "bt2", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
456                        }
457                }
458        }
459}
460
461void add_client_ip_srvfilter(char *name, char *type, char *data, char *level, int base, char *client)
462{
463        int idx = atoi(level) / 10;
464
465        if (idx == 10)
466                idx = 0;
467
468        if (strstr(type, "udp") || strstr(type, "both")) {
469                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-p", "udp", "-m", "udp", "--dport", data, "-s", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
470                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-p", "udp", "-m", "udp", "--sport", data, "-s", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
471                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-p", "udp", "-m", "udp", "--dport", data, "-d", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
472                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-p", "udp", "-m", "udp", "--sport", data, "-d", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
473
474                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "udp", "-m", "udp", "--dport", data, "-s", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
475                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "udp", "-m", "udp", "--sport", data, "-s", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
476                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "udp", "-m", "udp", "--dport", data, "-d", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
477                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "udp", "-m", "udp", "--sport", data, "-d", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
478        }
479
480        if (strstr(type, "tcp") || strstr(type, "both")) {
481
482                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-p", "tcp", "-m", "tcp", "--dport", data, "-s", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
483                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-p", "tcp", "-m", "tcp", "--sport", data, "-s", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
484                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-p", "tcp", "-m", "tcp", "--dport", data, "-d", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
485                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-p", "tcp", "-m", "tcp", "--sport", data, "-d", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
486
487                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "tcp", "-m", "tcp", "--dport", data, "-s", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
488                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "tcp", "-m", "tcp", "--sport", data, "-s", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
489                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "tcp", "-m", "tcp", "--dport", data, "-d", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
490                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-p", "tcp", "-m", "tcp", "--sport", data, "-d", client, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
491        }
492
493        if (strstr(type, "l7")) {
494                insmod("ipt_layer7");
495                insmod("xt_layer7");
496                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-s", client, "-m", "layer7", "--l7proto", name, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
497                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-d", client, "-m", "layer7", "--l7proto", name, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
498                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-s", client, "-m", "layer7", "--l7proto", name, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
499                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-d", client, "-m", "layer7", "--l7proto", name, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
500        }
501#ifdef HAVE_OPENDPI
502        if (strstr(type, "dpi")) {
503                char ndpi[32];
504                snprintf(ndpi, 32, "--%s", name);
505                insmod("xt_ndpi");
506
507                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-s", client, "-m", "ndpi", ndpi, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
508                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-d", client, "-m", "ndpi", ndpi, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
509                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-s", client, "-m", "ndpi", ndpi, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
510                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-d", client, "-m", "ndpi", ndpi, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
511
512        }
513#endif
514
515        if (strstr(type, "p2p")) {
516                char *proto = NULL;
517                char *realname = name;
518
519                if (!strcasecmp(realname, "applejuice"))
520                        proto = "apple";
521                else if (!strcasecmp(realname, "ares"))
522                        proto = "ares";
523                else if (!strcasecmp(realname, "bearshare"))
524                        proto = "gnu";
525                else if (!strcasecmp(realname, "bittorrent"))
526                        proto = "bit";
527                else if (!strcasecmp(realname, "directconnect"))
528                        proto = "dc";
529                else if (!strcasecmp(realname, "edonkey"))
530                        proto = "edk";
531                else if (!strcasecmp(realname, "gnutella"))
532                        proto = "gnu";
533                else if (!strcasecmp(realname, "kazaa"))
534                        proto = "kazaa";
535                else if (!strcasecmp(realname, "mute"))
536                        proto = "mute";
537                else if (!strcasecmp(realname, "soulseek"))
538                        proto = "soul";
539                else if (!strcasecmp(realname, "waste"))
540                        proto = "waste";
541                else if (!strcasecmp(realname, "winmx"))
542                        proto = "winmx";
543                else if (!strcasecmp(realname, "xdcc"))
544                        proto = "xdcc";
545                if (proto) {
546                        insmod("ipt_ipp2p");
547                        char ipp2p[32];
548                        snprintf(ipp2p, 32, "--%s", proto);
549
550                        eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-s", client, "-m", "ipp2p", ipp2p, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
551                        eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-d", client, "-m", "ipp2p", ipp2p, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
552                        eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-s", client, "-m", "ipp2p", ipp2p, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
553                        eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-d", client, "-m", "ipp2p", ipp2p, "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
554
555                        if (!strcmp(proto, "bit")) {
556                                // bittorrent detection enhanced
557#ifdef HAVE_MICRO
558
559                                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-s", client, "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
560                                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-d", client, "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
561                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-s", client, "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
562                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-d", client, "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
563
564#else
565                                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-s", client, "--length", "0:550", "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
566                                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-d", client, "--length", "0:550", "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
567                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-s", client, "--length", "0:550", "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
568                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-d", client, "--length", "0:550", "-m", "layer7", "--l7proto", "bt", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
569#endif
570                                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-s", client, "-m", "layer7", "--l7proto", "bt1", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
571                                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-d", client, "-m", "layer7", "--l7proto", "bt1", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
572                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-s", client, "-m", "layer7", "--l7proto", "bt1", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
573                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-d", client, "-m", "layer7", "--l7proto", "bt1", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
574                                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-s", client, "-m", "layer7", "--l7proto", "bt2", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
575                                eval("iptables", "-t", "mangle", "-I", "FILTER_OUT", "3", "-d", client, "-m", "layer7", "--l7proto", "bt2", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
576                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-s", client, "-m", "layer7", "--l7proto", "bt2", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
577                                eval("iptables", "-t", "mangle", "-I", "FILTER_IN", "3", "-d", client, "-m", "layer7", "--l7proto", "bt2", "-j", "MARK", "--set-mark", qos_nfmark(base + idx));
578                        }
579                }
580        }
581}
582
583#if !defined(ARCH_broadcom) || defined(HAVE_BCMMODERN)
584char *get_tcfmark(uint32 mark)
585{
586        static char tcfmark[24];
587        char nfmark[24];
588        char *ntoken = NULL;
589
590        memset(&tcfmark, 0, sizeof(tcfmark));
591        memset(&nfmark, 0, sizeof(nfmark));
592
593        strcpy(nfmark, qos_nfmark(mark));
594
595        ntoken = strtok(nfmark, "/");
596        strcat(tcfmark, ntoken);
597
598        ntoken = strtok(NULL, "/");
599        strcat(tcfmark, " ");
600        strcat(tcfmark, ntoken);
601
602        return tcfmark;
603}
604#endif
605
606#ifdef HAVE_AQOS
607void add_client_classes(unsigned int base, unsigned int uprate, unsigned int downrate, unsigned int lanrate, unsigned int level)
608{
609        char *wan_dev = get_wan_face();
610
611        unsigned int uplimit = atoi(nvram_get("wshaper_uplink"));
612        unsigned int downlimit = atoi(nvram_get("wshaper_downlink"));
613        unsigned int lanlimit = 1000000;
614        unsigned int prio;
615        unsigned int parent;
616        char buf[256];
617        char target[64] = "";
618
619        int max = 50;
620        int sec = 0;
621        if (uprate <= 2000) {
622                sec = max - (uprate / 50);
623                sprintf(target, "target %dms noecn", sec);
624        }
625
626        unsigned int quantum = atoi(get_mtu_val(buf)) + 14;
627
628        if (lanrate < 1)
629                lanrate = lanlimit;
630
631#else
632void add_client_classes(unsigned int base, unsigned int level)
633{
634        char *wan_dev = get_wan_face();
635
636        unsigned int uplimit = atoi(nvram_get("wshaper_uplink"));
637        unsigned int downlimit = atoi(nvram_get("wshaper_downlink"));
638        unsigned int lanlimit = 1000000;
639        unsigned int prio;
640        unsigned int parent;
641        char buf[256];
642
643        unsigned int quantum = atoi(get_mtu_val(buf)) + 14;
644
645        unsigned int uprate = 0, downrate = 0;
646        int lanrate = lanlimit;
647#endif
648
649        char *aqd = nvram_safe_get("svqos_aqd");
650
651        switch (level) {
652        case 100:
653                uprate = uplimit * 75 / 100;
654                downrate = downlimit * 75 / 100;
655                lanrate = lanlimit * 75 / 100;
656                prio = 2;
657                parent = 2;
658                break;
659        case 10:
660                uprate = uplimit * 50 / 100;
661                downrate = downlimit * 50 / 100;
662                lanrate = lanlimit * 50 / 100;
663                prio = 3;
664                parent = 3;
665                break;
666        case 20:
667                uprate = uplimit * 25 / 100;
668                downrate = downlimit * 25 / 100;
669                lanrate = lanlimit * 25 / 100;
670                prio = 4;
671                parent = 4;
672                break;
673        case 30:
674                uprate = uplimit * 15 / 100;
675                downrate = downlimit * 15 / 100;
676                lanrate = lanlimit * 15 / 100;
677                prio = 5;
678                parent = 5;
679                break;
680        case 40:
681                uprate = uprate * 5 / 100;
682                downrate = downlimit * 5 / 100;
683                lanrate = lanlimit * 5 / 100;
684                prio = 6;
685                parent = 6;
686                break;
687        default:
688                if (uprate)
689                        uplimit = uprate;
690                if (downrate)
691                        downlimit = downrate;
692                if (lanrate)
693                        lanlimit = lanrate;
694                prio = 3;
695                parent = 1;
696                break;
697        }
698
699        if (nvram_matchi("qos_type", 0)) {
700                // HTB
701                // internal
702                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d", wan_dev, parent, base, uprate, uplimit, quantum);
703                // maximum
704                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio 0", wan_dev, base, base + 1, uprate * 75 / 100, uplimit, quantum);
705                // premium
706                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio %d", wan_dev, base, base + 2, uprate * 50 / 100, uplimit, quantum, prio);
707                // express
708                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio %d", wan_dev, base, base + 3, uprate * 25 / 100, uplimit, quantum, prio + 1);
709                // standard
710                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio %d", wan_dev, base, base + 4, uprate * 15 / 100, uplimit, quantum, prio + 1);
711                // bulk
712                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio 7", wan_dev, base, base + 5, uprate * 5 / 100, uplimit, quantum);
713
714                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d", "imq0", parent, base, downrate, downlimit, quantum);
715                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio 0", "imq0", base, base + 1, downrate * 75 / 100, downlimit, quantum);
716                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio %d", "imq0", base, base + 2, downrate * 50 / 100, downlimit, quantum, prio);
717                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio %d", "imq0", base, base + 3, downrate * 25 / 100, downlimit, quantum, prio + 1);
718                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio %d", "imq0", base, base + 4, downrate * 15 / 100, downlimit, quantum, prio + 1);
719                sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio 7", "imq0", base, base + 5, downrate * 5 / 100, downlimit, quantum);
720
721                if (nvram_match("wshaper_dev", "LAN")) {
722                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d", "imq1", parent, base, lanrate, lanlimit, quantum);
723                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio 0", "imq1", base, base + 1, lanrate * 75 / 100, lanlimit, quantum);
724                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio %d", "imq1", base, base + 2, lanrate * 50 / 100, lanlimit, quantum, prio);
725                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio %d", "imq1", base, base + 3, lanrate * 25 / 100, lanlimit, quantum, prio + 1);
726                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio %d", "imq1", base, base + 4, lanrate * 15 / 100, lanlimit, quantum, prio + 1);
727                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit quantum %d prio 7", "imq1", base, base + 5, lanrate * 5 / 100, lanlimit, quantum);
728                }
729
730        } else {
731                // HFSC
732                // internal
733                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", wan_dev, 1, base, uprate, uplimit);
734                // maximum
735                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", wan_dev, base, base + 1, uprate * 75 / 100, uplimit);
736                // premium
737                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", wan_dev, base, base + 2, uprate * 50 / 100, uplimit);
738                // express
739                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", wan_dev, base, base + 3, uprate * 25 / 100, uplimit);
740                // standard
741                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", wan_dev, base, base + 4, uprate * 15 / 100, uplimit);
742                // bulk
743                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", wan_dev, base, base + 5, uprate * 5 / 100, uplimit);
744
745                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq0", 1, base, uprate, downlimit);
746                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq0", base, base + 1, uprate * 75 / 100, downlimit);
747                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq0", base, base + 2, uprate * 50 / 100, downlimit);
748                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq0", base, base + 3, uprate * 25 / 100, downlimit);
749                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq0", base, base + 4, uprate * 15 / 100, downlimit);
750                sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq0", base, base + 5, uprate * 5 / 100, downlimit);
751
752                if (nvram_match("wshaper_dev", "LAN")) {
753                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq1", 1, base, uprate, lanlimit);
754                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq1", base, base + 1, uprate * 75 / 100, lanlimit);
755                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq1", base, base + 2, uprate * 50 / 100, lanlimit);
756                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq1", base, base + 3, uprate * 25 / 100, lanlimit);
757                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq1", base, base + 4, uprate * 15 / 100, lanlimit);
758                        sysprintf("tc class add dev %s parent 1:%d classid 1:%d hfsc sc rate %dkbit ul rate %dkbit", "imq1", base, base + 5, uprate * 5 / 100, lanlimit);
759                }
760
761        }
762
763#if defined(ARCH_broadcom) && !defined(HAVE_BCMMODERN)
764        // filter rules
765        sysprintf("tc filter add dev %s protocol ip pref 1 handle 0x%x fw classid 1:%d", wan_dev, base, base + 1);
766        sysprintf("tc filter add dev %s protocol ip pref 3 handle 0x%x fw classid 1:%d", wan_dev, base + 1, base + 2);
767        sysprintf("tc filter add dev %s protocol ip pref 5 handle 0x%x fw classid 1:%d", wan_dev, base + 2, base + 3);
768        sysprintf("tc filter add dev %s protocol ip pref 8 handle 0x%x fw classid 1:%d", wan_dev, base + 3, base + 4);
769        sysprintf("tc filter add dev %s protocol ip pref 9 handle 0x%x fw classid 1:%d", wan_dev, base + 4, base + 5);
770
771        sysprintf("tc filter add dev %s protocol ip pref 1 handle 0x%x fw classid 1:%d", "imq0", base, base + 1);
772        sysprintf("tc filter add dev %s protocol ip pref 3 handle 0x%x fw classid 1:%d", "imq0", base + 1, base + 2);
773        sysprintf("tc filter add dev %s protocol ip pref 5 handle 0x%x fw classid 1:%d", "imq0", base + 2, base + 3);
774        sysprintf("tc filter add dev %s protocol ip pref 8 handle 0x%x fw classid 1:%d", "imq0", base + 3, base + 4);
775        sysprintf("tc filter add dev %s protocol ip pref 9 handle 0x%x fw classid 1:%d", "imq0", base + 4, base + 5);
776
777        if (nvram_match("wshaper_dev", "LAN")) {
778                sysprintf("tc filter add dev %s protocol ip pref 1 handle 0x%x fw classid 1:%d", "imq1", base, base + 1);
779                sysprintf("tc filter add dev %s protocol ip pref 3 handle 0x%x fw classid 1:%d", "imq1", base + 1, base + 2);
780                sysprintf("tc filter add dev %s protocol ip pref 5 handle 0x%x fw classid 1:%d", "imq1", base + 2, base + 3);
781                sysprintf("tc filter add dev %s protocol ip pref 8 handle 0x%x fw classid 1:%d", "imq1", base + 3, base + 4);
782                sysprintf("tc filter add dev %s protocol ip pref 9 handle 0x%x‚        fw classid 1:%d", "imq1", base + 4, base + 5);
783        }
784#else
785        sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", wan_dev, get_tcfmark(base), base + 1);
786        sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", wan_dev, get_tcfmark(base + 1), base + 2);
787        sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", wan_dev, get_tcfmark(base + 2), base + 3);
788        sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", wan_dev, get_tcfmark(base + 3), base + 4);
789        sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", wan_dev, get_tcfmark(base + 4), base + 5);
790
791        sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq0", get_tcfmark(base), base + 1);
792        sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq0", get_tcfmark(base + 1), base + 2);
793        sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq0", get_tcfmark(base + 2), base + 3);
794        sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq0", get_tcfmark(base + 3), base + 4);
795        sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq0", get_tcfmark(base + 4), base + 5);
796
797        if (nvram_match("wshaper_dev", "LAN")) {
798                sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq1", get_tcfmark(base), base + 1);
799                sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq1", get_tcfmark(base + 1), base + 2);
800                sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq1", get_tcfmark(base + 2), base + 3);
801                sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq1", get_tcfmark(base + 3), base + 4);
802                sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq1", get_tcfmark(base + 4), base + 5);
803        }
804#endif
805
806        // leaf qdiscs
807        if (!strcmp(aqd, "sfq")) {
808                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", wan_dev, base + 1, base + 1, quantum);
809                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", wan_dev, base + 2, base + 2, quantum);
810                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", wan_dev, base + 3, base + 3, quantum);
811                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", wan_dev, base + 4, base + 4, quantum);
812                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", wan_dev, base + 5, base + 5, quantum);
813
814                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", "imq0", base + 1, base + 1, quantum);
815                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", "imq0", base + 2, base + 2, quantum);
816                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", "imq0", base + 3, base + 3, quantum);
817                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", "imq0", base + 4, base + 4, quantum);
818                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", "imq0", base + 5, base + 5, quantum);
819
820                if (nvram_match("wshaper_dev", "LAN")) {
821                        sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", "imq1", base + 1, base + 1, quantum);
822                        sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", "imq1", base + 2, base + 2, quantum);
823                        sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", "imq1", base + 3, base + 3, quantum);
824                        sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", "imq1", base + 4, base + 4, quantum);
825                        sysprintf("tc qdisc add dev %s parent 1:%d handle %d: sfq quantum %d perturb 10", "imq1", base + 5, base + 5, quantum);
826                }
827        }
828#if defined(HAVE_CODEL) || defined(HAVE_FQ_CODEL)
829        if (!strcmp(aqd, "codel")
830            || !strcmp(aqd, "fq_codel")
831            || !strcmp(aqd, "pie")) {
832                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s %s", wan_dev, base + 1, base + 1, aqd, target);
833                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s %s", wan_dev, base + 2, base + 2, aqd, target);
834                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s %s", wan_dev, base + 3, base + 3, aqd, target);
835                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s %s", wan_dev, base + 4, base + 4, aqd, target);
836                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s %s", wan_dev, base + 5, base + 5, aqd, target);
837
838                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s", "imq0", base + 1, base + 1, aqd);
839                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s", "imq0", base + 2, base + 2, aqd);
840                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s", "imq0", base + 3, base + 3, aqd);
841                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s", "imq0", base + 4, base + 4, aqd);
842                sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s", "imq0", base + 5, base + 5, aqd);
843
844                if (nvram_match("wshaper_dev", "LAN")) {
845                        sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s", "imq1", base + 1, base + 1, aqd);
846                        sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s", "imq1", base + 2, base + 2, aqd);
847                        sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s", "imq1", base + 3, base + 3, aqd);
848                        sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s", "imq1", base + 4, base + 4, aqd);
849                        sysprintf("tc qdisc add dev %s parent 1:%d handle %d: %s", "imq1", base + 5, base + 5, aqd);
850                }
851        }
852#endif
853}
854
855#ifdef HAVE_AQOS
856
857void add_usermac(char *mac, int base, char *upstream, char *downstream, char *lanstream)
858{
859        unsigned int uprate = atoi(upstream);
860        unsigned int downrate = atoi(downstream);
861        unsigned int lanrate = atoi(lanstream);
862
863        char srvname[32], srvtype[32], srvdata[32], srvlevel[32];
864        char *qos_svcs = nvram_safe_get("svqos_svcs");
865
866        char nullmask[24];
867        strcpy(nullmask, qos_nfmark(0));
868
869        eval("iptables", "-t", "mangle", "-D", "FILTER_IN", "-j", "CONNMARK", "--save");
870        eval("iptables", "-t", "mangle", "-D", "FILTER_IN", "-j", "RETURN");
871
872        add_client_classes(base, uprate, downrate, lanrate, 0);
873
874        do {
875                if (sscanf(qos_svcs, "%31s %31s %31s %31s ", srvname, srvtype, srvdata, srvlevel) < 4)
876                        break;
877
878                add_client_mac_srvfilter(srvname, srvtype, srvdata, srvlevel, base, mac);
879        } while ((qos_svcs = strpbrk(++qos_svcs, "|")) && qos_svcs++);
880
881        eval("iptables", "-t", "mangle", "-A", "FILTER_IN", "-m", "mac", "--mac-source", mac, "-m", "mark", "--mark", nullmask, "-j", "MARK", "--set-mark", qos_nfmark(base));
882
883        eval("iptables", "-t", "mangle", "-A", "FILTER_IN", "-j", "CONNMARK", "--save");
884        eval("iptables", "-t", "mangle", "-A", "FILTER_IN", "-j", "RETURN");
885}
886
887void add_userip(char *ip, int base, char *upstream, char *downstream, char *lanstream)
888{
889        unsigned int uprate = atoi(upstream);
890        unsigned int downrate = atoi(downstream);
891        unsigned int lanrate = atoi(lanstream);
892
893//      int ret;
894        char srvname[32], srvtype[32], srvdata[32], srvlevel[32];
895        char *qos_svcs = nvram_safe_get("svqos_svcs");
896
897        char nullmask[24];
898        strcpy(nullmask, qos_nfmark(0));
899
900        eval("iptables", "-t", "mangle", "-D", "FILTER_IN", "-j", "CONNMARK", "--save");
901        eval("iptables", "-t", "mangle", "-D", "FILTER_IN", "-j", "RETURN");
902
903        eval("iptables", "-t", "mangle", "-D", "FILTER_OUT", "-j", "VPN_DSCP");
904        eval("iptables", "-t", "mangle", "-D", "FILTER_OUT", "-j", "CONNMARK", "--save");
905        eval("iptables", "-t", "mangle", "-D", "FILTER_OUT", "-j", "RETURN");
906
907        add_client_classes(base, uprate, downrate, lanrate, 0);
908
909        do {
910                if (sscanf(qos_svcs, "%31s %31s %31s %31s ", srvname, srvtype, srvdata, srvlevel) < 4)
911                        break;
912
913                add_client_ip_srvfilter(srvname, srvtype, srvdata, srvlevel, base, ip);
914        } while ((qos_svcs = strpbrk(++qos_svcs, "|")) && qos_svcs++);
915
916        eval("iptables", "-t", "mangle", "-A", "FILTER_OUT", "-s", ip, "-m", "mark", "--mark", nullmask, "-j", "MARK", "--set-mark", qos_nfmark(base));
917        eval("iptables", "-t", "mangle", "-A", "FILTER_OUT", "-d", ip, "-m", "mark", "--mark", nullmask, "-j", "MARK", "--set-mark", qos_nfmark(base));
918        eval("iptables", "-t", "mangle", "-A", "FILTER_IN", "-s", ip, "-m", "mark", "--mark", nullmask, "-j", "MARK", "--set-mark", qos_nfmark(base));
919        eval("iptables", "-t", "mangle", "-A", "FILTER_IN", "-d", ip, "-m", "mark", "--mark", nullmask, "-j", "MARK", "--set-mark", qos_nfmark(base));
920
921        eval("iptables", "-t", "mangle", "-A", "FILTER_IN", "-j", "CONNMARK", "--save");
922        eval("iptables", "-t", "mangle", "-A", "FILTER_IN", "-j", "RETURN");
923
924        eval("iptables", "-t", "mangle", "-A", "FILTER_OUT", "-j", "VPN_DSCP");
925        eval("iptables", "-t", "mangle", "-A", "FILTER_OUT", "-j", "CONNMARK", "--save");
926        eval("iptables", "-t", "mangle", "-A", "FILTER_OUT", "-j", "RETURN");
927}
928#endif
929#endif                          // HAVE_SVQOS
930
931int buf_to_file(char *path, char *buf)
932{
933        FILE *fp;
934
935        if ((fp = fopen(path, "w"))) {
936                fprintf(fp, "%s", buf);
937                fclose(fp);
938                return 1;
939        }
940
941        return 0;
942}
943
944int check_action(void)
945{
946        char buf[80] = "";
947
948        if (file_to_buf(ACTION_FILE, buf, sizeof(buf))) {
949                if (!strcmp(buf, "ACT_TFTP_UPGRADE")) {
950                        fprintf(stderr, "Upgrading from tftp now ...\n");
951                        return ACT_TFTP_UPGRADE;
952                }
953#ifdef HAVE_HTTPS
954                else if (!strcmp(buf, "ACT_WEBS_UPGRADE")) {
955                        fprintf(stderr, "Upgrading from web (https) now ...\n");
956                        return ACT_WEBS_UPGRADE;
957                }
958#endif
959                else if (!strcmp(buf, "ACT_WEB_UPGRADE")) {
960                        fprintf(stderr, "Upgrading from web (http) now ...\n");
961                        return ACT_WEB_UPGRADE;
962                } else if (!strcmp(buf, "ACT_SW_RESTORE")) {
963                        fprintf(stderr, "Receiving restore command from web ...\n");
964                        return ACT_SW_RESTORE;
965                } else if (!strcmp(buf, "ACT_HW_RESTORE")) {
966                        fprintf(stderr, "Receiving restore command from resetbutton ...\n");
967                        return ACT_HW_RESTORE;
968                } else if (!strcmp(buf, "ACT_NVRAM_COMMIT")) {
969                        fprintf(stderr, "Committing nvram now ...\n");
970                        return ACT_NVRAM_COMMIT;
971                } else if (!strcmp(buf, "ACT_ERASE_NVRAM")) {
972                        fprintf(stderr, "Erasing nvram now ...\n");
973                        return ACT_ERASE_NVRAM;
974                }
975        }
976        // fprintf(stderr, "Waiting for upgrading....\n");
977        return ACT_IDLE;
978}
979
980int check_vlan_support(void)
981{
982#if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX)  || defined(HAVE_RB600) || defined(HAVE_FONERA) || defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_WHRAG108) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_LSX) || defined(HAVE_DANUBE) || defined(HAVE_STORM) || defined(HAVE_ADM5120) || defined(HAVE_RT2880) || defined(HAVE_OPENRISC)
983        return 0;
984#else
985
986        int brand = getRouterBrand();
987
988        switch (brand) {
989#ifndef HAVE_BUFFALO
990        case ROUTER_ASUS_WL500GD:
991        case ROUTER_WRT54G1X:
992                return 1;
993                break;
994#endif
995        case ROUTER_BUFFALO_WLAG54C:
996        case ROUTER_BUFFALO_WLA2G54C:
997#ifndef HAVE_BUFFALO
998        case ROUTER_LINKSYS_WRT55AG:
999        case ROUTER_MOTOROLA_V1:
1000        case ROUTER_MOTOROLA_WE800G:
1001        case ROUTER_WAP54G_V1:
1002        case ROUTER_SITECOM_WL105B:
1003        case ROUTER_SITECOM_WL111:
1004        case ROUTER_BUFFALO_WLI2_TX1_G54:
1005        case ROUTER_BUFFALO_WLI_TX4_G54HP:
1006        case ROUTER_BRCM4702_GENERIC:
1007        case ROUTER_ASUS_WL500G:
1008        case ROUTER_BELKIN_F5D7230_V2000:
1009        case ROUTER_ASKEY_RT220XD:
1010#endif
1011                return 0;
1012                break;
1013        }
1014
1015        unsigned long boardflags = strtoul(nvram_safe_get("boardflags"), NULL, 0);
1016        if (boardflags & BFL_ENETVLAN)
1017                return 1;
1018        if (nvram_match("boardtype", "bcm94710dev"))
1019                return 1;
1020        if (nvram_match("boardtype", "0x0101"))
1021                return 1;
1022        if (boardflags & 0x0100)
1023                return 1;
1024
1025        return 0;
1026#endif
1027}
1028
1029void setRouter(char *name)
1030{
1031#ifdef HAVE_POWERNOC_WORT54G
1032        nvram_set(NVROUTER, "WORT54G");
1033#elif HAVE_POWERNOC_WOAP54G
1034        nvram_set(NVROUTER, "WOAP54G");
1035#elif HAVE_ERC
1036        char *pic = NULL;
1037        pic = nvram_safe_get("ree_pic");
1038
1039        if (!strncmp(pic, "1", 1))
1040                nvram_set(NVROUTER, "ServiceGate v1.0");
1041        else
1042                nvram_set(NVROUTER, "ServiceGate Lite v2.0");
1043#elif HAVE_OMNI
1044        nvram_set(NVROUTER, "Omni Wifi Router");
1045#elif HAVE_ALFA_BRANDING
1046        nvram_set(NVROUTER, "WLAN base-station");
1047        if (name)
1048                nvram_set("DD_BOARD2", name);
1049#elif HAVE_MAKSAT
1050        if (name)
1051                nvram_set("DD_BOARD2", name);
1052#ifdef HAVE_MAKSAT_BLANK
1053        nvram_set(NVROUTER, "default");
1054#else
1055        nvram_set(NVROUTER, "MAKSAT");
1056#endif
1057#elif HAVE_TMK
1058        if (name)
1059                nvram_set("DD_BOARD2", name);
1060        nvram_set(NVROUTER, "KMT-WAS");
1061#elif HAVE_BKM
1062        if (name)
1063                nvram_set("DD_BOARD2", name);
1064        nvram_set(NVROUTER, "BKM-HSDL");
1065#elif HAVE_TRIMAX
1066        if (name)
1067                nvram_set("DD_BOARD2", name);
1068        nvram_set(NVROUTER, "M2M Dynamics");
1069#elif HAVE_WIKINGS
1070        if (name)
1071                nvram_set("DD_BOARD2", name);
1072#ifdef HAVE_SUB3
1073        nvram_set(NVROUTER, "ExcelMin");
1074#elif HAVE_SUB6
1075        nvram_set(NVROUTER, "ExcelMed");
1076#else
1077        nvram_set(NVROUTER, "Excellent");
1078#endif
1079#elif HAVE_SANSFIL
1080        nvram_set("DD_BOARD", "SANSFIL");
1081        nvram_set("DD_BOARD2", name);
1082#elif HAVE_ONNET
1083#ifdef HAVE_MMS344
1084#ifdef HAVE_WILLY
1085        nvram_set("DD_BOARD", "9342-AN4g");
1086        nvram_set("DD_BOARD2", "9342-AN4g");
1087#else
1088        nvram_set("DD_BOARD", "DBDC344");
1089        nvram_set("DD_BOARD2", "DBDC344");
1090#endif
1091#else
1092        if (name)
1093                nvram_set(NVROUTER, name);
1094#endif
1095#elif HAVE_RAYTRONIK
1096#ifdef HAVE_AC722
1097        nvram_set("DD_BOARD", "RN-150M");
1098        nvram_set("DD_BOARD2", "RN-150M");
1099#else
1100        if (name)
1101                nvram_set(NVROUTER, name);
1102#endif
1103#elif HAVE_ESPOD
1104        if (name)
1105                nvram_set("DD_BOARD2", name);
1106#ifdef HAVE_SUB3
1107        nvram_set(NVROUTER, "ESPOD ES-3680");
1108#elif HAVE_SUB6
1109        nvram_set(NVROUTER, "ESPOD ES-3680");
1110#else
1111        nvram_set(NVROUTER, "ESPOD ES-3680");
1112#endif
1113#elif HAVE_CARLSONWIRELESS
1114        nvram_set(NVROUTER, "LH-135/270 ST");
1115#elif HAVE_IPR
1116        nvram_set(NVROUTER, "IPR-DATKS-501");
1117#else
1118        if (name)
1119                nvram_set(NVROUTER, name);
1120#endif
1121        cprintf("router is %s\n", getRouter());
1122}
1123
1124char *getRouter()
1125{
1126        char *n = nvram_get(NVROUTER);
1127
1128        return n != NULL ? n : "Unknown Model";
1129}
1130
1131int internal_getRouterBrand()
1132{
1133#if defined(HAVE_ALLNETWRT) && !defined(HAVE_ECB9750)
1134        unsigned long boardnum = strtoul(nvram_safe_get("boardnum"), NULL, 0);
1135
1136        if (boardnum == 8 && nvram_match("boardtype", "0x048e")
1137            && nvram_match("boardrev", "0x11")) {
1138                setRouter("ALLNET EUROWRT 54");
1139                return ROUTER_ALLNET01;
1140        }
1141        eval("event", "3", "1", "15");
1142        return 0;
1143#elif defined(HAVE_ALLNETWRT) && defined(HAVE_EOC5610)
1144        setRouter("Allnet Outdoor A/B/G CPE");
1145        return ROUTER_BOARD_LS2;
1146#else
1147#ifdef HAVE_NP28G
1148        setRouter("Compex NP28G");
1149        return ROUTER_BOARD_NP28G;
1150#elif HAVE_E200
1151        setRouter("Ubiquiti Edgerouter Pro");
1152        return ROUTER_UBNT_EROUTERPRO;
1153#elif HAVE_EROUTER
1154        setRouter("Ubiquiti Edgerouter Lite");
1155        return ROUTER_UBNT_EROUTERLITE;
1156#elif HAVE_WP54G
1157        setRouter("Compex WP54G");
1158        return ROUTER_BOARD_WP54G;
1159#elif HAVE_ADM5120
1160        if (!nvram_match("DD_BOARD", "OSBRiDGE 5LXi"))
1161                setRouter("Tonze AP-120");
1162        return ROUTER_BOARD_ADM5120;
1163#elif HAVE_RB500
1164        setRouter("Mikrotik RB500");
1165        return ROUTER_BOARD_500;
1166#elif HAVE_GEMTEK
1167        setRouter("SuperGerry");
1168        return ROUTER_SUPERGERRY;
1169#elif HAVE_NORTHSTAR
1170        unsigned long boardnum = strtoul(nvram_safe_get("boardnum"), NULL, 0);
1171
1172        if (boardnum == 00 && nvram_match("boardtype", "0xF646")
1173            && nvram_match("boardrev", "0x1100")
1174            && nvram_match("melco_id", "RD_BB12068")) {
1175#ifdef HAVE_BUFFALO
1176                setRouter("WZR-1750DHP");
1177#else
1178                setRouter("Buffalo WZR-1750DHP");
1179#endif
1180                return ROUTER_BUFFALO_WZR1750;
1181        }
1182
1183        if (boardnum == 00 && nvram_match("boardtype", "0x0665")
1184            && nvram_match("boardrev", "0x1103")
1185            && nvram_match("melco_id", "RD_BB13049")) {
1186#ifdef HAVE_BUFFALO
1187                setRouter("WXR-1900DHP");
1188#else
1189                setRouter("Buffalo WXR-1900DHP");
1190#endif
1191                return ROUTER_BUFFALO_WXR1900DHP;
1192        }
1193
1194        if ((!strncmp(nvram_safe_get("boardnum"), "2013", 4) || !strncmp(nvram_safe_get("boardnum"), "2014", 4)) && nvram_match("boardtype", "0x0646")
1195            && nvram_match("boardrev", "0x1110")
1196            && nvram_matchi("0:rxchain", 7)) {
1197#ifdef HAVE_BUFFALO
1198                setRouter("WZR-900DHP");
1199#else
1200                setRouter("Buffalo WZR-900DHP");
1201#endif
1202                return ROUTER_BUFFALO_WZR900DHP;
1203        }
1204
1205        if ((!strncmp(nvram_safe_get("boardnum"), "2013", 4) || !strncmp(nvram_safe_get("boardnum"), "2014", 4)) && nvram_match("boardtype", "0x0646")
1206            && nvram_match("boardrev", "0x1110")
1207            && nvram_matchi("0:rxchain", 3)) {
1208#ifdef HAVE_BUFFALO
1209                setRouter("WZR-600DHP2");
1210#else
1211                setRouter("Buffalo WZR-600DHP2");
1212#endif
1213                return ROUTER_BUFFALO_WZR600DHP2;
1214        }
1215        if (nvram_match("boardtype", "0x0665") && nvram_match("boardrev", "0x1102") && boardnum == 1) {
1216                setRouter("TPLINK Archer C9");
1217
1218                return ROUTER_TPLINK_ARCHERC9;
1219        }
1220
1221        if (nvram_match("boardtype", "0x0646") && nvram_match("boardrev", "0x1112") && boardnum == 1) {
1222                setRouter("TPLINK Archer C8");
1223
1224                return ROUTER_TPLINK_ARCHERC9;
1225        }
1226
1227        if (nvram_match("boardtype", "0x072F") && nvram_match("boardrev", "0x1101") && (boardnum == 1234 || boardnum == 10)) {
1228                setRouter("TPLINK Archer C3150");
1229
1230                return ROUTER_TPLINK_ARCHERC3150;
1231        }
1232
1233        if (nvram_match("boardtype", "0xD646") && nvram_match("boardrev", "0x1100") && nvram_match("0:devid", "0x43A1")) {
1234                setRouter("Linksys EA6900");
1235
1236                return ROUTER_LINKSYS_EA6900;
1237        }
1238
1239        if (nvram_match("boardtype", "0x0646") && nvram_match("boardrev", "0x1100") && nvram_match("boardnum", "01") && !strncmp(nvram_safe_get("modelNumber"), "EA6400", 6)) {
1240                setRouter("Linksys EA6400");
1241
1242                return ROUTER_LINKSYS_EA6400;
1243        }
1244
1245        if (nvram_match("boardtype", "0x0646") && nvram_match("boardrev", "0x1100") && nvram_match("boardnum", "01") && !strncmp(nvram_safe_get("modelNumber"), "EA6300", 6)) {
1246                setRouter("Linksys EA6300");
1247
1248                return ROUTER_LINKSYS_EA6400;
1249        }
1250
1251        if (nvram_match("boardtype", "0xF646") && nvram_match("boardrev", "0x1100") && nvram_match("0:devid", "0x4332")) {
1252                setRouter("Linksys EA6700");
1253
1254                return ROUTER_LINKSYS_EA6700;
1255        }
1256
1257        if (nvram_match("boardtype", "0xE646") && nvram_match("boardrev", "0x1200") && nvram_matchi("boardnum", 20140309)) {
1258                setRouter("Linksys EA6350");
1259
1260                return ROUTER_LINKSYS_EA6350;
1261        }
1262
1263        if (nvram_match("boardtype", "0xE646") && nvram_match("boardrev", "0x1100") && nvram_matchi("boardnum", 20130125)) {
1264                setRouter("Linksys EA6200");
1265
1266                return ROUTER_LINKSYS_EA6350;
1267        }
1268
1269        if (nvram_match("boardtype", "0xF646") && nvram_match("boardrev", "0x1100")) {
1270                setRouter("Linksys EA6500 V2");
1271
1272                return ROUTER_LINKSYS_EA6500V2;
1273        }
1274
1275        if (nvram_match("productid", "RT-AC56U")) {
1276                setRouter("Asus RT-AC56U");
1277                return ROUTER_ASUS_AC56U;
1278        }
1279
1280        if (nvram_match("productid", "RT-AC67U")) {
1281                setRouter("Asus RT-AC67U");
1282                return ROUTER_ASUS_AC67U;
1283        }
1284
1285        if (nvram_match("odmpid", "RT-AC68R")) {
1286                setRouter("Asus RT-AC68R");
1287                return ROUTER_ASUS_AC67U;
1288        }
1289
1290        if (nvram_match("odmpid", "RT-AC68A")) {
1291                setRouter("Asus RT-AC68A");
1292                return ROUTER_ASUS_AC67U;
1293        }
1294
1295        if (nvram_match("model", "RT-AC1200G+")) {
1296                setRouter("Asus RT-AC1200G+");
1297                return ROUTER_ASUS_AC1200;
1298        }
1299
1300        if (nvram_match("productid", "RT-AC68U") && nvram_match("boardrev", "0x1100")) {
1301                setRouter("Asus RT-AC68U");
1302                return ROUTER_ASUS_AC67U;
1303        }
1304
1305        if (nvram_match("productid", "RT-AC68U") && nvram_match("boardrev", "0x1103") && nvram_match("boardtype", "0x0665")) {
1306                setRouter("Asus RT-AC68U B1");
1307                return ROUTER_ASUS_AC67U;
1308        }
1309
1310        if (nvram_match("productid", "RT-AC68U") && nvram_match("boardrev", "0x1103")) {
1311                setRouter("Asus RT-AC68U C1");
1312                return ROUTER_ASUS_AC67U;
1313        }
1314
1315        if (nvram_match("model", "RT-AC68U") && nvram_match("boardrev", "0x1100")) {
1316                setRouter("Asus RT-AC68U");
1317                return ROUTER_ASUS_AC67U;
1318        }
1319
1320        if (nvram_match("model", "RT-AC68U") && nvram_match("boardrev", "0x1103") && nvram_match("boardtype", "0x0665")) {
1321                setRouter("Asus RT-AC68U B1");
1322                return ROUTER_ASUS_AC67U;
1323        }
1324
1325        if (nvram_match("model", "RT-AC68U") && nvram_match("boardrev", "0x1103")) {
1326                setRouter("Asus RT-AC68U C1");
1327                return ROUTER_ASUS_AC67U;
1328        }
1329
1330        if (nvram_match("productid", "RT-AC87U") || nvram_match("model", "RT-AC87U")) {
1331                setRouter("Asus RT-AC87U");
1332                return ROUTER_ASUS_AC87U;
1333        }
1334
1335        if (nvram_match("model", "RT-AC88U")) {
1336                setRouter("Asus RT-AC88U");
1337                return ROUTER_ASUS_AC88U;
1338        }
1339
1340        if (nvram_match("model", "RT-AC3100")) {
1341                setRouter("Asus RT-AC3100");
1342                return ROUTER_ASUS_AC3100;
1343        }
1344        if (nvram_match("productid", "RT-AC3100")) {
1345                setRouter("Asus RT-AC3100");
1346                return ROUTER_ASUS_AC3100;
1347        }
1348
1349        if (nvram_match("odmpid", "RT-AC3100")) {
1350                setRouter("Asus RT-AC3100");
1351                return ROUTER_ASUS_AC3100;
1352        }
1353
1354        if (nvram_match("model", "RT-AC5300")) {
1355                setRouter("Asus RT-AC5300");
1356                return ROUTER_ASUS_AC5300;
1357        }
1358
1359        if (nvram_match("productid", "RT-AC3200") || nvram_match("model", "RT-AC3200")) {
1360                setRouter("Asus RT-AC3200");
1361                return ROUTER_ASUS_AC3200;
1362        }
1363
1364        if (nvram_match("boardtype", "0x0665")
1365            && nvram_match("boardrev", "0x1103")
1366            && !nvram_match("melco_id", "RD_BB13049")) {
1367                setRouter("Asus RT-AC87U");
1368                return ROUTER_ASUS_AC87U;
1369        }
1370
1371        if (nvram_match("odmpid", "RT-AC87U")) {
1372                setRouter("Asus RT-AC87U");
1373                return ROUTER_ASUS_AC87U;
1374        }
1375
1376        if (nvram_match("model", "RT-N18U")) {
1377                setRouter("Asus RT-N18U");
1378                return ROUTER_ASUS_RTN18U;
1379        }
1380
1381        if (boardnum == 24 && nvram_match("boardtype", "0x0646")
1382            && nvram_match("boardrev", "0x1100")
1383            && nvram_match("gpio8", "wps_button")) {
1384                setRouter("Dlink-DIR860L-A1");
1385                return ROUTER_DLINK_DIR860;
1386        }
1387        if (boardnum == 24 && nvram_match("boardtype", "0x0646")
1388            && nvram_match("boardrev", "0x1110")
1389            && nvram_match("gpio7", "wps_button") && !nvram_match("gpio6", "wps_led") && nvram_get("pci/1/1/venid")) {
1390                setRouter("Dlink-DIR868L");
1391                return ROUTER_DLINK_DIR868;
1392        }
1393
1394        if (boardnum == 24 && nvram_match("boardtype", "0x0646")
1395            && nvram_match("boardrev", "0x1101")
1396            && nvram_match("gpio7", "wps_button") && !nvram_match("gpio6", "wps_led")) {
1397                setRouter("Dlink-DIR868L rev C");
1398                return ROUTER_DLINK_DIR868C;
1399        }
1400
1401        if (boardnum == 24 && nvram_match("boardtype", "0x0646")
1402            && nvram_match("boardrev", "0x1110")
1403            && nvram_match("gpio7", "wps_button") && nvram_match("gpio6", "wps_led")) {
1404                setRouter("Dlink-DIR880L");
1405                return ROUTER_DLINK_DIR880;
1406        }
1407
1408        if ((boardnum == 24 || nvram_match("boardnum", "N/A")) && nvram_match("boardtype", "0x072F") && nvram_match("2:devid", "0x43c5")
1409            && nvram_match("boardrev", "0x1101")
1410            && nvram_match("gpio7", "wps_button")) {
1411                setRouter("Dlink-DIR895L");
1412                return ROUTER_DLINK_DIR895;
1413        }
1414
1415        if ((boardnum == 24 || nvram_match("boardnum", "N/A")) && nvram_match("boardtype", "0x072F") && nvram_match("1:devid", "0x43c5")
1416            && nvram_match("boardrev", "0x1101")
1417            && nvram_match("gpio7", "wps_button")) {
1418                setRouter("Dlink-DIR885L");
1419                return ROUTER_DLINK_DIR885;
1420        }
1421
1422        if (boardnum == 24 && nvram_match("boardtype", "0x072F")
1423            && nvram_match("boardrev", "0x1101")
1424            && nvram_match("gpio7", "wps_button")) {
1425                setRouter("Dlink-DIR890L");
1426                return ROUTER_DLINK_DIR890;
1427        }
1428
1429        if (boardnum == 00 && nvram_match("boardtype", "0x0646")
1430            && nvram_match("boardrev", "0x1100")
1431            && nvram_match("gpio15", "wps_button")) {
1432                setRouter("Asus RT-AC56U");
1433                return ROUTER_ASUS_AC56U;
1434        }
1435
1436        if (boardnum == 1234 && nvram_match("boardtype", "0x072F")
1437            && nvram_match("boardrev", "0x1202")
1438            && nvram_match("gpio7", "wps_button")) {
1439                setRouter("Trendnet TEW828DRU");
1440                return ROUTER_TRENDNET_TEW828;
1441        }
1442
1443        if (boardnum == 1234 && nvram_match("boardtype", "0x0646") && nvram_match("1:devid", "0x43A2")
1444            && nvram_match("boardrev", "0x1100")
1445            && nvram_match("gpio7", "wps_button")) {
1446                setRouter("Trendnet TEW812DRU");
1447                return ROUTER_TRENDNET_TEW812;
1448        }
1449
1450        if (boardnum == 1234 && nvram_match("boardtype", "0xC646")
1451            && nvram_match("boardrev", "0x1200")
1452            && nvram_match("gpio7", "wps_button")) {
1453                setRouter("Trendnet TEW818DRU");
1454                return ROUTER_TRENDNET_TEW812;
1455        }
1456
1457        if (boardnum == 1234 && nvram_match("boardtype", "0xD646") && nvram_match("1:devid", "0x43A2")
1458            && nvram_match("boardrev", "0x1100")
1459            && nvram_match("gpio7", "wps_button")) {
1460                setRouter("Trendnet TEW812DRU");
1461                return ROUTER_TRENDNET_TEW812;
1462        }
1463
1464        if (boardnum == 1234 && nvram_match("boardtype", "0xD646") && nvram_match("1:devid", "0x43A9")
1465            && nvram_match("boardrev", "0x1100")
1466            && nvram_match("gpio7", "wps_button")) {
1467                setRouter("Trendnet TEW811DRU");
1468                return ROUTER_TRENDNET_TEW812;
1469        }
1470
1471        if (boardnum != 24 && nvram_match("boardtype", "0x0646")
1472            && nvram_match("boardrev", "0x1100")
1473            && nvram_match("gpio7", "wps_button")) {
1474                setRouter("Asus RT-AC68U");
1475                return ROUTER_ASUS_AC67U;
1476        }
1477
1478        if (boardnum == 679 && nvram_match("boardtype", "0x0646")
1479            && nvram_match("boardrev", "0x1110")) {
1480                int mtd = getMTD("board_data");
1481                char devname[32];
1482                sprintf(devname, "/dev/mtdblock/%d", mtd);
1483                FILE *model = fopen(devname, "rb");
1484                if (model) {
1485#define R6300V2 "U12H240T00_NETGEAR"
1486#define R6300V2CH "U12H240T70_NETGEAR"
1487#define AC1450 "U12H240T99_NETGEAR"
1488#define EX6200 "U12H269T00_NETGEAR"
1489                        char modelstr[32];
1490                        fread(modelstr, 1, strlen(R6300V2), model);
1491                        if (!strncmp(modelstr, R6300V2, strlen(R6300V2)) || !strncmp(modelstr, R6300V2CH, strlen(R6300V2CH))) {
1492                                setRouter("Netgear R6300V2");
1493                                fclose(model);
1494                                return ROUTER_NETGEAR_R6300V2;
1495                        } else if (!strncmp(modelstr, AC1450, strlen(AC1450))) {
1496                                setRouter("Netgear AC1450");
1497                                fclose(model);
1498                                return ROUTER_NETGEAR_AC1450;
1499                        } else if (!strncmp(modelstr, EX6200, strlen(EX6200))) {
1500                                setRouter("Netgear EX6200");
1501                                fclose(model);
1502                                return ROUTER_NETGEAR_EX6200;
1503                        } else {
1504                                setRouter("Netgear R6250");
1505                                fclose(model);
1506                                return ROUTER_NETGEAR_R6250;
1507                        }
1508                }
1509        }
1510
1511        if (boardnum == 32 && nvram_match("boardtype", "0x0646")
1512            && nvram_match("boardrev", "0x1601")) {
1513                setRouter("Netgear R6400");
1514                return ROUTER_NETGEAR_R6400;
1515        }
1516
1517        if (boardnum == 32 && nvram_match("boardtype", "0x0665")
1518            && nvram_match("boardrev", "0x1301")) {
1519                if (nvram_match("board_id", "U12H270T10_NETGEAR")) {
1520                        setRouter("Netgear R6700");
1521                } else {
1522                        setRouter("Netgear R7000");
1523                }
1524                return ROUTER_NETGEAR_R7000;
1525        }
1526
1527        if (boardnum == 32 && nvram_match("boardtype", "0x0665")
1528            && nvram_match("boardrev", "0x1101")) {
1529                setRouter("Netgear R8000");
1530                return ROUTER_NETGEAR_R8000;
1531        }
1532
1533        if (boardnum == 32 && nvram_match("boardtype", "0x072F")
1534            && nvram_match("boardrev", "0x1101")) {
1535                setRouter("Netgear R8500");
1536                return ROUTER_NETGEAR_R8500;
1537        }
1538
1539        setRouter("Broadcom Northstar");
1540        return ROUTER_BOARD_NORTHSTAR;
1541#elif HAVE_VENTANA
1542        char *filename = "/sys/devices/soc0/soc.0/2100000.aips-bus/21a0000.i2c/i2c-0/0-0051/eeprom";    /* bank2=0x100 kernel 3.0 */
1543        FILE *file = fopen(filename, "rb");
1544        if (!file) {
1545                filename = "/sys/devices/soc0/soc/2100000.aips-bus/21a0000.i2c/i2c-0/0-0051/eeprom";    /* bank2=0x100 kernel 3.18 */
1546                file = fopen(filename, "rb");
1547        }
1548        if (!file) {
1549                setRouter("Gateworks Ventana GW54XX");
1550        } else {
1551                char gwid[9];
1552                fseek(file, 0x30, SEEK_SET);
1553                fread(&gwid[0], 9, 1, file);
1554                fclose(file);
1555                if (!strncmp(gwid, "GW5400-B", 8)) {
1556                        setRouter("Gateworks Ventana GW5400-B");
1557                } else if (!strncmp(gwid, "GW5400-C", 8)) {
1558                        setRouter("Gateworks Ventana GW5400-C");
1559                } else if (!strncmp(gwid, "GW5400-A", 8)) {
1560                        setRouter("Gateworks Ventana GW5400-A");
1561                } else if (!strncmp(gwid, "GW5400", 6)) {
1562                        setRouter("Gateworks Ventana GW5400-X");
1563                } else if (!strncmp(gwid, "GW5410-B", 8)) {
1564                        setRouter("Gateworks Ventana GW5410-B");
1565                } else if (!strncmp(gwid, "GW5410-C", 8)) {
1566                        setRouter("Gateworks Ventana GW5410-C");
1567                } else if (!strncmp(gwid, "GW5410", 6)) {
1568                        setRouter("Gateworks Ventana GW5410-X");
1569                } else if (!strncmp(gwid, "GW5100", 6)) {
1570                        setRouter("Gateworks Ventana GW5100");
1571                        return ROUTER_BOARD_GW2380;
1572                } else if (!strncmp(gwid, "GW5200", 6)) {
1573                        setRouter("Gateworks Ventana GW5200");
1574                        return ROUTER_BOARD_GW2380;
1575                } else if (!strncmp(gwid, "GW5300", 6)) {
1576                        setRouter("Gateworks Ventana GW5300");
1577                } else if (!strncmp(gwid, "GW5310", 6)) {
1578                        setRouter("Gateworks Ventana GW5310");
1579                } else
1580                        setRouter("Gateworks Ventana GW54XX");
1581        }
1582        return ROUTER_BOARD_GW2388;
1583#elif HAVE_LAGUNA
1584        char *filename = "/sys/devices/platform/cns3xxx-i2c.0/i2c-0/0-0050/eeprom";     /* bank2=0x100 kernel 3.0 */
1585        FILE *file = fopen(filename, "rb");
1586        if (!file) {
1587                filename = "/sys/devices/platform/cns3xxx-i2c.0/i2c-adapter/i2c-0/0-0050/eeprom";       /* bank2=0x100 older kernel */
1588                file = fopen(filename, "r");
1589        }
1590        if (file) {
1591                fseek(file, 0x130, SEEK_SET);
1592                char gwid[9];
1593                fread(&gwid[0], 9, 1, file);
1594                fclose(file);
1595                if (!strncmp(gwid, "GW2388", 6)) {
1596                        setRouter("Gateworks Laguna GW2388");
1597                        return ROUTER_BOARD_GW2388;
1598                } else if (!strncmp(gwid, "GW2389", 6)) {
1599                        setRouter("Gateworks Laguna GW2389");
1600                        return ROUTER_BOARD_GW2388;
1601                } else if (!strncmp(gwid, "GW2384", 6)) {
1602                        setRouter("Gateworks Laguna GW2384");
1603                        return ROUTER_BOARD_GW2380;
1604                } else if (!strncmp(gwid, "GW2394", 6)) {
1605                        setRouter("Gateworks Laguna GW2394");
1606                        return ROUTER_BOARD_GW2380;
1607                } else if (!strncmp(gwid, "GW2386", 6)) {
1608                        setRouter("Gateworks Laguna GW2386");
1609                        return ROUTER_BOARD_GW2380;
1610                } else if (!strncmp(gwid, "GW2385", 6)) {
1611                        setRouter("Gateworks Laguna GW2385");
1612                        return ROUTER_BOARD_GW2380;
1613                } else if (!strncmp(gwid, "GW2382", 6)) {
1614                        setRouter("Gateworks Laguna GW2382");
1615                        return ROUTER_BOARD_GW2380;
1616                } else if (!strncmp(gwid, "GW2380", 6)) {
1617                        setRouter("Gateworks Laguna GW2380");
1618                        return ROUTER_BOARD_GW2380;
1619                } else if (!strncmp(gwid, "GW2391", 6)) {
1620                        setRouter("Gateworks Laguna GW2391");
1621                        return ROUTER_BOARD_GW2380;
1622                } else if (!strncmp(gwid, "GW2393", 6)) {
1623                        setRouter("Gateworks Laguna GW2393");
1624                        return ROUTER_BOARD_GW2380;
1625                } else if (!strncmp(gwid, "GW2387", 6)) {
1626                        setRouter("Gateworks Laguna GW2387");
1627                        return ROUTER_BOARD_GW2380;
1628                } else {
1629                        setRouter("Gateworks Laguna GWXXXX");
1630                        return ROUTER_BOARD_GW2388;
1631                }
1632        } else {
1633                setRouter("Gateworks Laguna UNKNOWN");
1634                return ROUTER_BOARD_GW2388;
1635
1636        }
1637#elif HAVE_MI424WR
1638        setRouter("Actiontec MI424WR");
1639        return ROUTER_BOARD_GATEWORX_GW2345;
1640#elif HAVE_USR8200
1641        setRouter("US Robotics USR8200");
1642        return ROUTER_BOARD_GATEWORX;
1643#elif HAVE_TONZE
1644        setRouter("Tonze AP-425");
1645        return ROUTER_BOARD_GATEWORX;
1646#elif HAVE_NOP8670
1647        setRouter("Senao NOP-8670");
1648        return ROUTER_BOARD_GATEWORX;
1649#elif HAVE_WRT300NV2
1650        setRouter("Linksys WRT300N v2");
1651        return ROUTER_BOARD_GATEWORX;
1652#elif HAVE_WG302V1
1653        setRouter("Netgear WG302 v1");
1654        return ROUTER_BOARD_GATEWORX;
1655#elif HAVE_WG302
1656        setRouter("Netgear WG302 v2");
1657        return ROUTER_BOARD_GATEWORX;
1658#elif HAVE_PRONGHORN
1659        setRouter("ADI Engineering Pronghorn Metro");
1660        return ROUTER_BOARD_GATEWORX;
1661#elif HAVE_GATEWORX
1662        char *filename = "/sys/devices/platform/IXP4XX-I2C.0/i2c-adapter:i2c-0/0-0051/eeprom";  /* bank2=0x100
1663                                                                                                 */
1664        FILE *file = fopen(filename, "r");
1665        if (!file) {
1666                filename = "/sys/devices/platform/IXP4XX-I2C.0/i2c-0/0-0051/eeprom";    //for 2.6.34.6
1667                file = fopen(filename, "r");
1668        }
1669        if (file)               // new detection scheme
1670        {
1671
1672                char *gwid;
1673                char temp[64];
1674                int ret = fread(temp, 40, 1, file);
1675                if (ret < 1) {
1676                        fclose(file);
1677                        goto old_way;
1678                }
1679                gwid = &temp[32];
1680                gwid[8] = 0;
1681                fclose(file);
1682                if (!strncmp(gwid, "GW2347", 6)) {
1683                        setRouter("Gateworks Avila GW2347");
1684                        return ROUTER_BOARD_GATEWORX_SWAP;
1685                }
1686                if (!strncmp(gwid, "GW2357", 6)) {
1687                        setRouter("Gateworks Avila GW2357");
1688                        return ROUTER_BOARD_GATEWORX_SWAP;
1689                }
1690                if (!strncmp(gwid, "GW2353", 6)) {
1691                        setRouter("Gateworks Avila GW2353");
1692                        return ROUTER_BOARD_GATEWORX;
1693                }
1694                if (!strncmp(gwid, "GW2348-2", 8)) {
1695                        setRouter("Gateworks Avila GW2348-2");
1696                        return ROUTER_BOARD_GATEWORX;
1697                }
1698                if (!strncmp(gwid, "GW2348-4", 8)) {
1699                        setRouter("Gateworks Avila GW2348-4");
1700                        return ROUTER_BOARD_GATEWORX;
1701                }
1702                if (!strncmp(gwid, "GW2348", 6)) {
1703                        setRouter("Gateworks Avila GW2348-4/2");
1704                        return ROUTER_BOARD_GATEWORX;
1705                }
1706                if (!strncmp(gwid, "GW2358", 6)) {
1707                        setRouter("Gateworks Cambria GW2358-4");
1708                        return ROUTER_BOARD_GATEWORX;
1709                }
1710                if (!strncmp(gwid, "GW2350", 6)) {
1711                        setRouter("Gateworks Cambria GW2350");
1712                        return ROUTER_BOARD_GATEWORX;
1713                }
1714                if (!strncmp(gwid, "GW2369", 6)) {
1715                        setRouter("Gateworks Avila GW2369");
1716                        return ROUTER_BOARD_GATEWORX_GW2369;
1717                }
1718                if (!strncmp(gwid, "GW2355", 6)) {
1719                        setRouter("Gateworks Avila GW2355");
1720                        return ROUTER_BOARD_GATEWORX_GW2345;
1721                }
1722                if (!strncmp(gwid, "GW2345", 6)) {
1723                        setRouter("Gateworks Avila GW2345");
1724                        return ROUTER_BOARD_GATEWORX_GW2345;
1725                }
1726        }
1727      old_way:;
1728        struct mii_ioctl_data *data;
1729        struct ifreq iwr;
1730        int s = socket(AF_INET, SOCK_DGRAM, 0);
1731
1732        if (s < 0) {
1733                fprintf(stderr, "socket(SOCK_DRAGM)\n");
1734                setRouter("Gateworks Avila");
1735                return ROUTER_BOARD_GATEWORX;
1736        }
1737        (void)strncpy(iwr.ifr_name, "ixp0", sizeof("ixp0"));
1738        data = (struct mii_ioctl_data *)&iwr.ifr_data;
1739        data->phy_id = 1;
1740#define IX_ETH_ACC_MII_PHY_ID1_REG  0x2 /* PHY identifier 1 Register */
1741#define IX_ETH_ACC_MII_PHY_ID2_REG  0x3 /* PHY identifier 2 Register */
1742        data->reg_num = IX_ETH_ACC_MII_PHY_ID1_REG;
1743        ioctl(s, SIOCGMIIREG, &iwr);
1744        data->phy_id = 1;
1745        data->reg_num = IX_ETH_ACC_MII_PHY_ID1_REG;
1746        ioctl(s, SIOCGMIIREG, &iwr);
1747        int reg1 = data->val_out;
1748
1749        data->phy_id = 1;
1750        data->reg_num = IX_ETH_ACC_MII_PHY_ID2_REG;
1751        ioctl(s, SIOCGMIIREG, &iwr);
1752        int reg2 = data->val_out;
1753
1754        close(s);
1755        if (reg1 == 0x2000 && reg2 == 0x5c90) {
1756                setRouter("Avila GW2347");
1757                return ROUTER_BOARD_GATEWORX_SWAP;
1758        } else if (reg1 == 0x13 && reg2 == 0x7a11) {
1759#if HAVE_ALFA_BRANDING
1760                setRouter("WLAN base-station");
1761#else
1762                setRouter("Gateworks Avila GW2348-4/2");
1763#endif
1764                return ROUTER_BOARD_GATEWORX;
1765        } else if (reg1 == 0x143 && reg2 == 0xbc31)     // broadcom phy
1766        {
1767                setRouter("ADI Engineering Pronghorn Metro");
1768                return ROUTER_BOARD_GATEWORX;
1769        } else if (reg1 == 0x22 && reg2 == 0x1450)      // kendin switch
1770        {
1771                setRouter("Gateworks Avila GW2345");
1772                return ROUTER_BOARD_GATEWORX_GW2345;
1773        } else if (reg1 == 0x0 && reg2 == 0x8201)       // realtek
1774        {
1775                setRouter("Compex WP188");
1776                return ROUTER_BOARD_GATEWORX;
1777        } else {
1778                setRouter("Unknown");
1779                return ROUTER_BOARD_GATEWORX;
1780        }
1781#elif HAVE_RT2880
1782
1783#ifdef HAVE_ECB9750
1784#ifdef HAVE_ALLNETWRT
1785        setRouter("Allnet 802.11n Router");
1786#else
1787        setRouter("Senao ECB-9750");
1788#endif
1789        return ROUTER_BOARD_ECB9750;
1790#elif HAVE_ALLNET11N
1791        setRouter("Allnet 802.11n Router");
1792        return ROUTER_BOARD_WHRG300N;
1793#elif HAVE_TECHNAXX3G
1794        setRouter("Technaxx 3G Router");
1795        return ROUTER_BOARD_TECHNAXX3G;
1796#elif HAVE_AR670W
1797        setRouter("Airlink 101 AR670W");
1798        return ROUTER_BOARD_AR670W;
1799#elif HAVE_AR690W
1800        setRouter("Airlink 101 AR690W");
1801        return ROUTER_BOARD_AR690W;
1802#elif HAVE_RT15N
1803        setRouter("Asus RT-N15");
1804        return ROUTER_BOARD_RT15N;
1805#elif HAVE_BR6574N
1806        setRouter("Edimax BR-6574N");
1807        return ROUTER_BOARD_BR6574N;
1808#elif HAVE_ESR6650
1809        setRouter("Senao ESR-6650");
1810        return ROUTER_BOARD_ESR6650;
1811#elif HAVE_EAP9550
1812        setRouter("Senao EAP-9550");
1813        return ROUTER_BOARD_EAP9550;
1814#elif HAVE_ESR9752
1815        setRouter("Senao ESR-9752");
1816        return ROUTER_BOARD_ESR9752;
1817#elif HAVE_ACXNR22
1818        setRouter("Aceex NR22");
1819        return ROUTER_BOARD_ACXNR22;
1820#elif HAVE_W502U
1821        setRouter("Alfa AIP-W502U");
1822        return ROUTER_BOARD_W502U;
1823#elif HAVE_DIR615H
1824        setRouter("Dlink-DIR615 rev h");
1825        return ROUTER_BOARD_DIR615D;
1826#elif HAVE_ALL02310N
1827        setRouter("Allnet ALL02310N");
1828        return ROUTER_BOARD_DIR615D;
1829#elif HAVE_DIR615
1830        setRouter("Dlink-DIR615 rev d");
1831        return ROUTER_BOARD_DIR615D;
1832#elif HAVE_RT3352
1833        setRouter("Ralink RT3352 Device");
1834        return ROUTER_BOARD_RT3352;
1835#elif HAVE_RUT500
1836        setRouter("Teltonika RUT500");
1837        return ROUTER_BOARD_NEPTUNE;
1838#elif HAVE_NEPTUNE
1839        setRouter("Neptune-Mini");
1840        return ROUTER_BOARD_NEPTUNE;
1841#elif HAVE_TECHNAXX
1842        setRouter("TECHNAXX Router-150 Wifi-N");
1843        return ROUTER_BOARD_TECHNAXX;
1844#elif HAVE_RT10N
1845        setRouter("Asus RT-N10+");
1846        return ROUTER_ASUS_RTN10PLUS;
1847#elif HAVE_DIR600
1848#ifdef HAVE_DIR300
1849        setRouter("Dlink-DIR300 rev b");
1850#else
1851        setRouter("Dlink-DIR600 rev b");
1852#endif
1853        return ROUTER_BOARD_DIR600B;
1854#elif HAVE_RT13NB1
1855        setRouter("Asus RT-N13U B1");
1856        return ROUTER_BOARD_WHRG300N;
1857#elif HAVE_ASUSRTN13U
1858        setRouter("Asus RT-N13U");
1859        return ROUTER_BOARD_WHRG300N;
1860#elif HAVE_E1700
1861        setRouter("Linksys E1700 / N300");
1862        return ROUTER_BOARD_E1700;
1863#elif HAVE_DIR860
1864        setRouter("Dlink DIR-860L B1");
1865        return ROUTER_DIR860LB1;
1866#elif HAVE_DIR810L
1867        void *getUEnv(char *name);
1868
1869        char *hw = getUEnv("HW_BOARD_REV");
1870        if (hw) {
1871                if (!strcmp(hw, "B1"))
1872                        setRouter("Dlink DIR-810L B1");
1873                else if (!strcmp(hw, "A1"))
1874                        setRouter("Dlink DIR-810L A1");
1875                else if (!strcmp(hw, "C1"))
1876                        setRouter("Dlink DIR-810L C1");
1877                else
1878                        setRouter("Dlink DIR-810L XX");
1879
1880        } else
1881                setRouter("Dlink DIR-810L");
1882        return ROUTER_DIR810L;
1883#elif HAVE_WHR1166D
1884        setRouter("Buffalo WHR-1166D");
1885        return ROUTER_WHR300HP2;
1886#elif HAVE_WHR300HP2
1887        FILE *fp = fopen("/sys/bus/pci/devices/0000:01:00.0/device", "rb");
1888        if (fp) {
1889                fclose(fp);
1890                setRouter("Buffalo WHR-600D");
1891                return ROUTER_WHR300HP2;
1892        }
1893        setRouter("Buffalo WHR-300HP2");
1894        return ROUTER_WHR300HP2;
1895#elif HAVE_F5D8235
1896        setRouter("Belkin F5D8235-4 v2");
1897        return ROUTER_BOARD_F5D8235;
1898#elif HAVE_HAMEA15
1899        setRouter("Hame A-15");
1900        return ROUTER_BOARD_HAMEA15;
1901#elif HAVE_WCRGN
1902        setRouter("Buffalo WCR-GN");
1903        return ROUTER_BOARD_WCRGN;
1904#elif HAVE_WHRG300N
1905        setRouter("Buffalo WHR-G300N");
1906        return ROUTER_BOARD_WHRG300N;
1907#elif HAVE_WR5422
1908        setRouter("Repotec RP-WR5422");
1909        return ROUTER_BOARD_WR5422;
1910#else
1911        setRouter("Generic RT2880");
1912        return ROUTER_BOARD_RT2880;
1913#endif
1914#elif HAVE_X86
1915#ifdef HAVE_CORENET
1916        setRouter("CORENET X86i");
1917        return ROUTER_BOARD_X86;
1918#else
1919        setRouter("Generic X86");
1920        return ROUTER_BOARD_X86;
1921#endif
1922#elif HAVE_XSCALE
1923        setRouter("NewMedia Dual A/B/G");
1924        return ROUTER_BOARD_XSCALE;
1925#elif HAVE_MAGICBOX
1926        setRouter("OpenRB PowerPC Board");
1927        return ROUTER_BOARD_MAGICBOX;
1928#elif HAVE_UNIWIP
1929        setRouter("Octagon Systems UNiWiP");
1930        return ROUTER_BOARD_UNIWIP;
1931#elif HAVE_WDR4900
1932        setRouter("TP-Link WDR4900 V1");
1933        return ROUTER_BOARD_WDR4900;
1934#elif HAVE_RB1000
1935        setRouter("Mikrotik RB1000");
1936        return ROUTER_BOARD_RB600;
1937#elif HAVE_RB800
1938        setRouter("Mikrotik RB800");
1939        return ROUTER_BOARD_RB600;
1940#elif HAVE_RB600
1941        setRouter("Mikrotik RB600");
1942        return ROUTER_BOARD_RB600;
1943#elif HAVE_GWMF54G2
1944        setRouter("Planex GW-MF54G2");
1945        char mac[32];
1946        getBoardMAC(mac);
1947        if (!strncmp(mac, "00:19:3B", 8) || !strncmp(mac, "00:02:6F", 8)
1948            || !strncmp(mac, "00:15:6D", 8)) {
1949                fprintf(stderr, "unsupported board\n");
1950                sys_reboot();
1951        }
1952        return ROUTER_BOARD_FONERA;
1953#elif HAVE_WRT54GV7
1954        setRouter("Linksys WRT54G v7");
1955        return ROUTER_BOARD_FONERA;
1956#elif HAVE_WRK54G
1957        setRouter("Linksys WRK54G v3");
1958        return ROUTER_BOARD_FONERA;
1959#elif HAVE_WGT624
1960        setRouter("Netgear WGT624 v4");
1961        return ROUTER_BOARD_FONERA;
1962#elif HAVE_WPE53G
1963        setRouter("Compex WPE53G");
1964        return ROUTER_BOARD_FONERA;
1965#elif HAVE_NP25G
1966        setRouter("Compex NP25G");
1967        return ROUTER_BOARD_FONERA;
1968#elif HAVE_MR3202A
1969        setRouter("MR3202A");
1970        return ROUTER_BOARD_FONERA;
1971#elif HAVE_DLM101
1972        setRouter("Doodle Labs DLM-101");
1973        return ROUTER_BOARD_FONERA;
1974#elif HAVE_AR430W
1975        setRouter("Airlink-101 AR430W");
1976        return ROUTER_BOARD_FONERA;
1977#elif HAVE_DIR400
1978        setRouter("D-Link DIR-400");
1979        return ROUTER_BOARD_FONERA2200;
1980#elif HAVE_WRT54G2
1981        setRouter("Linksys WRT54G2 v1.1");
1982        return ROUTER_BOARD_FONERA;
1983#elif HAVE_RTG32
1984        setRouter("Asus RT-G32");
1985        return ROUTER_BOARD_FONERA;
1986#elif HAVE_DIR300
1987        setRouter("D-Link DIR-300");
1988        return ROUTER_BOARD_FONERA;
1989#elif HAVE_CNC
1990        setRouter("WiFi4You Outdoor AP");
1991        return ROUTER_BOARD_FONERA;
1992#elif defined(HAVE_CORENET) && defined(HAVE_NS2)
1993        setRouter("CORENET XNS2");
1994        return ROUTER_BOARD_LS2;
1995#elif defined(HAVE_CORENET) && defined(HAVE_LC2)
1996        setRouter("CORENET XLO2");
1997        return ROUTER_BOARD_LS2;
1998#elif defined(HAVE_CORENET) && defined(HAVE_EOC2610)
1999        setRouter("CORENET XC61");
2000        return ROUTER_BOARD_FONERA;
2001#elif defined(HAVE_CORENET) && defined(HAVE_EOC1650)
2002        setRouter("CORENET XC65");
2003        return ROUTER_BOARD_FONERA;
2004#elif defined(HAVE_CORENET) && defined(HAVE_BS2)
2005        setRouter("CORENET XBU2");
2006        return ROUTER_BOARD_LS2;
2007#elif defined(HAVE_CORENET) && defined(HAVE_BS2HP)
2008        setRouter("CORENET MBU2i");
2009        return ROUTER_BOARD_LS2;
2010#elif HAVE_WBD500
2011        setRouter("Wiligear WBD-500");
2012        return ROUTER_BOARD_FONERA;
2013#elif HAVE_EOC1650
2014        setRouter("Senao EOC-1650");
2015        return ROUTER_BOARD_FONERA;
2016#elif HAVE_EOC2611
2017        setRouter("Senao EOC-2611");
2018        return ROUTER_BOARD_FONERA;
2019#elif HAVE_EOC2610
2020#ifdef HAVE_TRIMAX
2021        setRouter("M2M-1200");
2022#else
2023        setRouter("Senao EOC-2610");
2024#endif
2025        return ROUTER_BOARD_FONERA;
2026#elif HAVE_ECB3500
2027        setRouter("Senao ECB-3500");
2028        return ROUTER_BOARD_FONERA;
2029#elif HAVE_EAP3660
2030        setRouter("Senao EAP-3660");
2031        return ROUTER_BOARD_FONERA;
2032#elif HAVE_MR3201A
2033        setRouter("Accton MR3201A");
2034        return ROUTER_BOARD_FONERA;
2035#elif HAVE_FONERA
2036        struct mii_ioctl_data *data;
2037        struct ifreq iwr;
2038        char mac[32];
2039        getBoardMAC(mac);
2040        if (!strncmp(mac, "00:19:3B", 8) || !strncmp(mac, "00:02:6F", 8)
2041            || !strncmp(mac, "00:15:6D", 8) || !strncmp(mac, "00:C0:CA", 8)) {
2042                fprintf(stderr, "unsupported board\n");
2043                sys_reboot();
2044        }
2045        int s = socket(AF_INET, SOCK_DGRAM, 0);
2046
2047        if (s < 0) {
2048                fprintf(stderr, "socket(SOCK_DRAGM)\n");
2049                setRouter("Fonera 2100/2200");
2050                return ROUTER_BOARD_FONERA;
2051        }
2052        (void)strncpy(iwr.ifr_name, "eth0", sizeof("eth0"));
2053        data = (struct mii_ioctl_data *)&iwr.ifr_data;
2054        data->phy_id = 0x10;
2055        data->reg_num = 0x2;
2056        ioctl(s, SIOCGMIIREG, &iwr);
2057        data->phy_id = 0x10;
2058        data->reg_num = 0x2;
2059        ioctl(s, SIOCGMIIREG, &iwr);
2060        if (data->val_out == 0x0141) {
2061                data->phy_id = 0x10;
2062                data->reg_num = 0x3;
2063                ioctl(s, SIOCGMIIREG, &iwr);
2064                close(s);
2065                if ((data->val_out & 0xfc00) != 0x0c00) // marvell phy
2066                {
2067                        setRouter("Fonera 2100/2200");
2068                        return ROUTER_BOARD_FONERA;
2069                } else {
2070                        setRouter("Fonera 2201");
2071                        return ROUTER_BOARD_FONERA2200;
2072                }
2073        } else {
2074                setRouter("Fonera 2100/2200");
2075                return ROUTER_BOARD_FONERA;
2076        }
2077#elif HAVE_WRT1900AC
2078        FILE *fp = fopen("/sys/firmware/devicetree/base/model", "rb");
2079        if (!fp) {
2080                fprintf(stderr, "error opening device tree\n");
2081                setRouter("Linksys WRT1900AC");
2082                return ROUTER_WRT_1900AC;
2083        }
2084        char vendorstr[32];
2085        char modelstr[32];
2086        fscanf(fp, "%s %s", &vendorstr[0], &modelstr[0]);
2087        fclose(fp);
2088        if (!strcmp(modelstr, "WRT1200AC")) {
2089                setRouter("Linksys WRT1200AC");
2090                return ROUTER_WRT_1200AC;
2091        }
2092        if (!strcmp(modelstr, "WRT1900ACv2")) {
2093                setRouter("Linksys WRT1900ACv2");
2094                return ROUTER_WRT_1900ACV2;     // similar
2095        }
2096        if (!strcmp(modelstr, "WRT1900AC")) {
2097                setRouter("Linksys WRT1900AC");
2098                return ROUTER_WRT_1900AC;       // similar
2099        }
2100
2101        if (!strcmp(modelstr, "WRT1900ACS")) {
2102                setRouter("Linksys WRT1900ACS");
2103                return ROUTER_WRT_1900ACS;      // similar
2104        }
2105        if (!strcmp(modelstr, "WRT3200ACM")) {
2106                setRouter("Linksys WRT3200ACM");
2107                return ROUTER_WRT_1900ACS;      // similar
2108        }
2109#elif HAVE_R9000
2110        setRouter("Netgear Nighthawk X10");
2111        return ROUTER_NETGEAR_R9000;
2112#elif HAVE_IPQ806X
2113        FILE *fp = fopen("/sys/firmware/devicetree/base/model", "rb");
2114        if (!fp) {
2115                fprintf(stderr, "error opening device tree\n");
2116                setRouter("Netgear R7500");
2117                return ROUTER_NETGEAR_R7500;
2118        }
2119        char vendorstr[32];
2120        char modelstr[32];
2121        fscanf(fp, "%s %s", &vendorstr[0], &modelstr[0]);
2122        fclose(fp);
2123        if (!strcmp(modelstr, "R7800")) {
2124                setRouter("Netgear R7800");
2125                return ROUTER_NETGEAR_R7800;
2126        }
2127
2128        if (!strcmp(modelstr, "R7500v2")) {
2129                setRouter("Netgear R7500v2");
2130                return ROUTER_NETGEAR_R7500V2;
2131        }
2132
2133        if (!strcmp(modelstr, "R7500")) {
2134                setRouter("Netgear R7500");
2135                return ROUTER_NETGEAR_R7500;
2136        }
2137
2138        if (!strcmp(modelstr, "EA8500")) {
2139                setRouter("Linksys EA8500");
2140                return ROUTER_LINKSYS_EA8500;
2141        }
2142
2143        if (!strcmp(modelstr, "TEW-827")) {
2144                setRouter("Trendnet TEW-827");
2145                return ROUTER_TRENDNET_TEW827;
2146        }
2147
2148        if (!strcmp(modelstr, "G10")) {
2149                setRouter("ASRock G10");
2150                return ROUTER_ASROCK_G10;
2151        }
2152#elif HAVE_MERAKI
2153        setRouter("Meraki Mini");
2154        return ROUTER_BOARD_MERAKI;
2155#elif HAVE_BWRG1000
2156        setRouter("Bountiful BWRG-1000");
2157        return ROUTER_BOARD_LS2;
2158#elif HAVE_WNR2200
2159        setRouter("Netgear WNR2200");
2160        nvram_default_get("ath0_rxantenna", "3");
2161        nvram_default_get("ath0_txantenna", "3");
2162        return ROUTER_BOARD_WHRHPGN;
2163#elif HAVE_WNR2000
2164        setRouter("Netgear WNR2000v3");
2165        nvram_default_get("ath0_rxantenna", "3");
2166        nvram_default_get("ath0_txantenna", "3");
2167        return ROUTER_BOARD_WHRHPGN;
2168#elif HAVE_WLAEAG300N
2169#ifdef HAVE_BUFFALO
2170        setRouter("WLAE-AG300N");
2171#else
2172        setRouter("Buffalo WLAE-AG300N");
2173#endif
2174        nvram_default_get("ath0_rxantenna", "3");
2175        nvram_default_get("ath0_txantenna", "3");
2176        return ROUTER_BOARD_WHRHPGN;
2177#elif HAVE_CARAMBOLA
2178#ifdef HAVE_ERC
2179        setRouter("ERC ServiceGate");
2180#else
2181        setRouter("8Devices Carambola 2");
2182#endif
2183        nvram_default_get("ath0_rxantenna", "1");
2184        nvram_default_get("ath0_txantenna", "1");
2185        return ROUTER_BOARD_WHRHPGN;
2186#elif HAVE_HORNET
2187        setRouter("Atheros Hornet");
2188        nvram_default_get("ath0_rxantenna", "1");
2189        nvram_default_get("ath0_txantenna", "1");
2190        return ROUTER_BOARD_WHRHPGN;
2191#elif HAVE_RB2011
2192        setRouter("Mikrotik RB2011");
2193        nvram_default_get("ath0_rxantenna", "3");
2194        nvram_default_get("ath0_txantenna", "3");
2195        nvram_default_get("ath1_rxantenna", "3");
2196        nvram_default_get("ath1_txantenna", "3");
2197        return ROUTER_BOARD_WHRHPGN;
2198#elif HAVE_WDR2543
2199        setRouter("TPLINK TL-WR2543");
2200        nvram_default_get("ath0_rxantenna", "7");
2201        nvram_default_get("ath0_txantenna", "7");
2202        return ROUTER_BOARD_WHRHPGN;
2203#elif HAVE_WDR3500
2204        setRouter("TPLINK TL-WDR3500 v1");
2205        nvram_default_get("ath0_rxantenna", "3");
2206        nvram_default_get("ath0_txantenna", "3");
2207        nvram_default_get("ath1_rxantenna", "3");
2208        nvram_default_get("ath1_txantenna", "3");
2209        return ROUTER_BOARD_WHRHPGN;
2210#elif HAVE_WDR3600
2211        setRouter("TPLINK TL-WDR3600 v1");
2212        nvram_default_get("ath0_rxantenna", "3");
2213        nvram_default_get("ath0_txantenna", "3");
2214        nvram_default_get("ath1_rxantenna", "3");
2215        nvram_default_get("ath1_txantenna", "3");
2216        return ROUTER_BOARD_WHRHPGN;
2217#elif HAVE_WDR4300
2218        setRouter("TPLINK TL-WDR4300 v1");
2219        nvram_default_get("ath0_rxantenna", "3");
2220        nvram_default_get("ath0_txantenna", "3");
2221        nvram_default_get("ath1_rxantenna", "7");
2222        nvram_default_get("ath1_txantenna", "7");
2223        return ROUTER_BOARD_WHRHPGN;
2224#elif HAVE_DIR835A1
2225        setRouter("Dlink DIR835-A1");
2226        nvram_default_get("ath0_rxantenna", "3");
2227        nvram_default_get("ath0_txantenna", "3");
2228        nvram_default_get("ath1_rxantenna", "7");
2229        nvram_default_get("ath1_txantenna", "7");
2230        return ROUTER_BOARD_WHRHPGN;
2231#elif HAVE_WNDR4300
2232        setRouter("Netgear WNDR4300");
2233        nvram_default_get("ath0_rxantenna", "3");
2234        nvram_default_get("ath0_txantenna", "3");
2235        nvram_default_get("ath1_rxantenna", "7");
2236        nvram_default_get("ath1_txantenna", "7");
2237        return ROUTER_BOARD_WHRHPGN;
2238#elif HAVE_WNDR3700V4
2239        setRouter("Netgear WNDR3700 V4");
2240        nvram_default_get("ath0_rxantenna", "3");
2241        nvram_default_get("ath0_txantenna", "3");
2242        nvram_default_get("ath1_rxantenna", "3");
2243        nvram_default_get("ath1_txantenna", "3");
2244        return ROUTER_BOARD_WHRHPGN;
2245#elif HAVE_TEW824
2246        setRouter("Trendnet TEW824DRU");
2247        nvram_default_get("ath0_rxantenna", "3");
2248        nvram_default_get("ath0_txantenna", "3");
2249        nvram_default_get("ath1_rxantenna", "3");
2250        nvram_default_get("ath1_txantenna", "3");
2251        return ROUTER_BOARD_WHRHPGN;
2252#elif HAVE_DIR866
2253        setRouter("Dlink DIR866-A1");
2254        nvram_default_get("ath0_rxantenna", "3");
2255        nvram_default_get("ath0_txantenna", "3");
2256        nvram_default_get("ath1_rxantenna", "3");
2257        nvram_default_get("ath1_txantenna", "3");
2258        return ROUTER_BOARD_WHRHPGN;
2259#elif HAVE_DAP2660
2260        setRouter("Dlink DAP2660");
2261        nvram_default_get("ath0_rxantenna", "3");
2262        nvram_default_get("ath0_txantenna", "3");
2263        nvram_default_get("ath1_rxantenna", "3");
2264        nvram_default_get("ath1_txantenna", "3");
2265        return ROUTER_BOARD_WHRHPGN;
2266#elif HAVE_DAP2330
2267        setRouter("Dlink DAP2330");
2268        nvram_default_get("ath0_rxantenna", "3");
2269        nvram_default_get("ath0_txantenna", "3");
2270        return ROUTER_BOARD_WHRHPGN;
2271#elif HAVE_DAP3662
2272        setRouter("Dlink DAP3662");
2273        nvram_default_get("ath0_rxantenna", "3");
2274        nvram_default_get("ath0_txantenna", "3");
2275        nvram_default_get("ath1_rxantenna", "3");
2276        nvram_default_get("ath1_txantenna", "3");
2277        return ROUTER_BOARD_WHRHPGN;
2278#elif HAVE_DIR862
2279        setRouter("Dlink DIR862-A1");
2280        nvram_default_get("ath0_rxantenna", "7");
2281        nvram_default_get("ath0_txantenna", "7");
2282        nvram_default_get("ath1_rxantenna", "7");
2283        nvram_default_get("ath1_txantenna", "7");
2284        return ROUTER_BOARD_WHRHPGN;
2285#elif HAVE_WILLY
2286        setRouter("Wallystech DR342-NAS");
2287        nvram_default_get("ath0_rxantenna", "3");
2288        nvram_default_get("ath0_txantenna", "3");
2289        return ROUTER_BOARD_WHRHPGN;
2290#elif HAVE_MMS344
2291        setRouter("Compex MMS344");
2292        nvram_default_get("ath0_rxantenna", "3");
2293        nvram_default_get("ath0_txantenna", "3");
2294        nvram_default_get("ath1_rxantenna", "3");
2295        nvram_default_get("ath1_txantenna", "3");
2296        return ROUTER_BOARD_WHRHPGN;
2297#elif HAVE_WDR4900V2
2298        setRouter("TPLINK WDR4900 v2");
2299        nvram_default_get("ath0_rxantenna", "7");
2300        nvram_default_get("ath0_txantenna", "7");
2301        nvram_default_get("ath1_rxantenna", "7");
2302        nvram_default_get("ath1_txantenna", "7");
2303        return ROUTER_BOARD_WHRHPGN;
2304#elif HAVE_ARCHERC5
2305        setRouter("TPLINK ARCHER-C5 v1");
2306        nvram_default_get("ath0_rxantenna", "7");
2307        nvram_default_get("ath0_txantenna", "7");
2308        nvram_default_get("ath1_rxantenna", "7");
2309        nvram_default_get("ath1_txantenna", "7");
2310        return ROUTER_BOARD_WHRHPGN;
2311#elif HAVE_ARCHERC7
2312        setRouter("TPLINK ARCHER-C7 v2");
2313        nvram_default_get("ath0_rxantenna", "7");
2314        nvram_default_get("ath0_txantenna", "7");
2315        nvram_default_get("ath1_rxantenna", "7");
2316        nvram_default_get("ath1_txantenna", "7");
2317        return ROUTER_BOARD_WHRHPGN;
2318#elif HAVE_WR1043V3
2319        setRouter("TPLINK WR1043ND V3");
2320        nvram_default_get("ath0_rxantenna", "7");
2321        nvram_default_get("ath0_txantenna", "7");
2322        return ROUTER_BOARD_WHRHPGN;
2323#elif HAVE_WR1043V2
2324        setRouter("TPLINK WR1043ND V2");
2325        nvram_default_get("ath0_rxantenna", "7");
2326        nvram_default_get("ath0_txantenna", "7");
2327        return ROUTER_BOARD_WHRHPGN;
2328#elif HAVE_WZR450HP2
2329#ifdef HAVE_BUFFALO
2330        setRouter("WZR-450HP2");
2331#else
2332        setRouter("Buffalo WZR-450HP2");
2333#endif
2334        nvram_default_get("ath0_rxantenna", "7");
2335        nvram_default_get("ath0_txantenna", "7");
2336        return ROUTER_BOARD_WHRHPGN;
2337#elif HAVE_DHP1565
2338        setRouter("Dlink DHP1565-A1");
2339        nvram_default_get("ath0_rxantenna", "3");
2340        nvram_default_get("ath0_txantenna", "3");
2341        return ROUTER_BOARD_WHRHPGN;
2342#elif HAVE_WR615N
2343        setRouter("Comfast WR615N");
2344        nvram_default_get("ath0_rxantenna", "3");
2345        nvram_default_get("ath0_txantenna", "3");
2346        return ROUTER_BOARD_WHRHPGN;
2347#elif HAVE_E325N
2348        setRouter("Comfast E325N");
2349        nvram_default_get("ath0_rxantenna", "3");
2350        nvram_default_get("ath0_txantenna", "3");
2351        return ROUTER_BOARD_WHRHPGN;
2352#elif HAVE_E355AC
2353        setRouter("Comfast E355AC");
2354        nvram_default_get("ath0_rxantenna", "3");
2355        nvram_default_get("ath0_txantenna", "3");
2356        return ROUTER_BOARD_WHRHPGN;
2357#elif HAVE_XD3200
2358        setRouter("Yuncore XD3200");
2359        nvram_default_get("ath0_rxantenna", "3");
2360        nvram_default_get("ath0_txantenna", "3");
2361        nvram_default_get("ath1_rxantenna", "3");
2362        nvram_default_get("ath1_txantenna", "3");
2363        return ROUTER_BOARD_WHRHPGN;
2364#elif HAVE_E380AC
2365        setRouter("Comfast E380AC");
2366        nvram_default_get("ath0_rxantenna", "7");
2367        nvram_default_get("ath0_txantenna", "7");
2368        nvram_default_get("ath1_rxantenna", "7");
2369        nvram_default_get("ath1_txantenna", "7");
2370        return ROUTER_BOARD_WHRHPGN;
2371#elif HAVE_AP120C
2372        setRouter("Alfa AP120C");
2373        nvram_default_get("ath0_rxantenna", "3");
2374        nvram_default_get("ath0_txantenna", "3");
2375        nvram_default_get("ath1_rxantenna", "3");
2376        nvram_default_get("ath1_txantenna", "3");
2377        return ROUTER_BOARD_WHRHPGN;
2378#elif HAVE_WR650AC
2379        setRouter("Comfast WR650AC");
2380        nvram_default_get("ath0_rxantenna", "7");
2381        nvram_default_get("ath0_txantenna", "7");
2382        nvram_default_get("ath1_rxantenna", "7");
2383        nvram_default_get("ath1_txantenna", "7");
2384        return ROUTER_BOARD_WHRHPGN;
2385#elif HAVE_DIR869
2386        setRouter("Dlink DIR869");
2387        nvram_default_get("ath0_rxantenna", "7");
2388        nvram_default_get("ath0_txantenna", "7");
2389        return ROUTER_BOARD_WHRHPGN;
2390#elif HAVE_DIR859
2391        setRouter("Dlink DIR859");
2392        nvram_default_get("ath0_rxantenna", "7");
2393        nvram_default_get("ath0_txantenna", "7");
2394        return ROUTER_BOARD_WHRHPGN;
2395#elif HAVE_JWAP606
2396        setRouter("JJPlus JWAP606");
2397        nvram_default_get("ath0_rxantenna", "3");
2398        nvram_default_get("ath0_txantenna", "3");
2399        nvram_default_get("ath1_rxantenna", "3");
2400        nvram_default_get("ath1_txantenna", "3");
2401        return ROUTER_BOARD_WHRHPGN;
2402#elif HAVE_DIR825C1
2403        setRouter("Dlink DIR825-C1");
2404        nvram_default_get("ath0_rxantenna", "3");
2405        nvram_default_get("ath0_txantenna", "3");
2406        nvram_default_get("ath1_rxantenna", "3");
2407        nvram_default_get("ath1_txantenna", "3");
2408        return ROUTER_BOARD_WHRHPGN;
2409#elif HAVE_WASP
2410        setRouter("Atheros Wasp");
2411        nvram_default_get("ath0_rxantenna", "3");
2412        nvram_default_get("ath0_txantenna", "3");
2413        nvram_default_get("ath1_rxantenna", "3");
2414        nvram_default_get("ath1_txantenna", "3");
2415        return ROUTER_BOARD_WHRHPGN;
2416#elif HAVE_WHRHPG300N
2417#ifdef HAVE_BUFFALO
2418#ifdef HAVE_WHR300HP
2419        setRouter("WHR-300HP");
2420#else
2421        setRouter("WHR-HP-G300N");
2422#endif
2423#else
2424        setRouter("Buffalo WHR-HP-G300N");
2425#endif
2426        nvram_default_get("ath0_rxantenna", "3");
2427        nvram_default_get("ath0_txantenna", "3");
2428        return ROUTER_BOARD_WHRHPGN;
2429#elif HAVE_WHRG300NV2
2430#ifdef HAVE_BUFFALO
2431        setRouter("WHR-G300N");
2432#else
2433        setRouter("Buffalo WHR-G300N");
2434#endif
2435        nvram_default_get("ath0_rxantenna", "3");
2436        nvram_default_get("ath0_txantenna", "3");
2437        return ROUTER_BOARD_WHRHPGN;
2438#elif HAVE_WHRHPGN
2439#ifdef HAVE_BUFFALO
2440        setRouter("WHR-HP-GN");
2441#else
2442        setRouter("Buffalo WHR-HP-GN");
2443#endif
2444        nvram_default_get("ath0_rxantenna", "1");
2445        nvram_default_get("ath0_txantenna", "1");
2446        return ROUTER_BOARD_WHRHPGN;
2447#elif HAVE_JJAP93
2448        setRouter("JJPLUS AP93");
2449        nvram_default_get("ath0_rxantenna", "1");
2450        nvram_default_get("ath0_txantenna", "1");
2451        return ROUTER_BOARD_PB42;
2452#elif HAVE_JJAP005
2453        setRouter("JJPLUS AP005");
2454        nvram_default_get("ath0_rxantenna", "1");
2455        nvram_default_get("ath0_txantenna", "1");
2456        return ROUTER_BOARD_PB42;
2457#elif HAVE_JJAP501
2458        setRouter("JJPLUS AP501");
2459        nvram_default_get("ath0_rxantenna", "3");
2460        nvram_default_get("ath0_txantenna", "3");
2461        return ROUTER_BOARD_PB42;
2462#elif HAVE_AC722
2463        setRouter("ACCTON AC722");
2464        nvram_default_get("ath0_rxantenna", "3");
2465        nvram_default_get("ath0_txantenna", "3");
2466        return ROUTER_BOARD_PB42;
2467#elif HAVE_AC622
2468        setRouter("ACCTON AC622");
2469        nvram_default_get("ath0_rxantenna", "3");
2470        nvram_default_get("ath0_txantenna", "3");
2471        return ROUTER_BOARD_PB42;
2472#elif HAVE_WPE72
2473        setRouter("Compex WPE72");
2474        nvram_default_get("ath0_rxantenna", "1");
2475        nvram_default_get("ath0_txantenna", "1");
2476        return ROUTER_BOARD_NS5M;
2477#elif HAVE_UBNTTI
2478        return ROUTER_BOARD_TI;
2479#elif HAVE_DAP3310
2480        setRouter("DLink DAP3310");
2481        return ROUTER_BOARD_NS5M;
2482#elif HAVE_DAP3410
2483        setRouter("DLink DAP3410");
2484        return ROUTER_BOARD_NS5M;
2485#elif HAVE_UBNTM
2486        typedef struct UBNTDEV {
2487                char *devicename;       // device name
2488                unsigned short devid;   // pci subdevice id
2489                unsigned char rxchain;  // rx chainmask
2490                unsigned char txchain;  // tx chainmask
2491                unsigned char rxchain5; // rx chainmask 5 ghz
2492                unsigned char txchain5; // tx chainmask 5 ghz
2493                int dddev;      // dd-wrt device id
2494                int offset;     // frequency offset
2495                int poffset;
2496        };
2497        /* these values are guessed and need to be validated */
2498#define M900 (- (2427 - 907))
2499#define M365 (- (5540 - 3650))
2500#define M35 (- (5540 - 3540))
2501#define M10 (- (5540 - 10322))
2502        struct UBNTDEV dev[] = {
2503
2504                {"NanoBeam M2 XW", 0xe2c2, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2505                {"NanoBeam M5 XW", 0xe3e5, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2506                {"NanoBeam M5 XW", 0xe4e5, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2507                {"NanoBeam M5 XW", 0xe815, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2508                {"NanoBeam M5 XW", 0xe825, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2509
2510                {"NanoStation M2", 0xe002, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2511                {"NanoStation M2", 0xe012, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2512                {"NanoStation M5", 0xe005, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},       //
2513                {"NanoStation M6", 0xe006, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},       //
2514                {"NanoStation M5", 0xe805, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},       //
2515                {"NanoStation M5 XW", 0xe855, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},    //
2516                {"NanoStation M3", 0xe035, 3, 3, 0, 0, ROUTER_BOARD_NS5M, M35, 10},     //
2517                {"NanoStation M365", 0xe003, 3, 3, 0, 0, ROUTER_BOARD_NS5M, M365, 10},  //
2518                {"NanoStation M900", 0xe2b9, 3, 3, 0, 0, ROUTER_BOARD_NS5M, M900, 10},  //
2519//              {"NanoStation M900 GPS", 0xe0b9, 3, 3, ROUTER_BOARD_NS5M, M900},       //
2520                {"Rocket M2", 0xe102, 3, 3, 0, 0, ROUTER_BOARD_R2M, 0, 10},     //
2521                {"Rocket M2", 0xe112, 3, 3, 0, 0, ROUTER_BOARD_R2M, 0, 10},     //
2522                {"Rocket M2", 0xe1b2, 3, 3, 0, 0, ROUTER_BOARD_R2M, 0, 10},     //
2523                {"Rocket M2", 0xe1c2, 3, 3, 0, 0, ROUTER_BOARD_R2M, 0, 10},     //
2524                {"Rocket M2 Titanium XW", 0xe1d2, 3, 3, 0, 0, ROUTER_BOARD_TI, 0, 10},  // Titanium
2525                {"Rocket M5 Titanium XW", 0xe4d5, 3, 3, 0, 0, ROUTER_BOARD_TI, 0, 10},  // Titanium
2526                {"Rocket M5", 0xe105, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2527                {"Rocket M5", 0xe1b5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2528                {"Rocket M5 XW", 0xe6b5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},  //
2529                {"Rocket M5", 0xe8b5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2530                {"Rocket M5", 0xe1c5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2531                {"Rocket M5 Titanium XW", 0xe1d5, 3, 3, 0, 0, ROUTER_BOARD_TI, 0, 10},  // Titanium
2532                {"Rocket M6", 0xe1b6, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2533                {"Rocket M3", 0xe1c3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M35, 10},   //
2534                {"Rocket M3", 0xe1e3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M35, 10},   //
2535                {"Rocket M5 X3 XW", 0xe3b5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},       //
2536                {"Rocket M365", 0xe1b3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M365, 10},        //
2537                {"Rocket M365", 0xe1d3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M365, 10},        //
2538                {"Rocket M900", 0xe1b9, 3, 3, 0, 0, ROUTER_BOARD_R2M, M900, 10},        //
2539                {"Rocket M900", 0xe1d9, 3, 3, 0, 0, ROUTER_BOARD_R2M, M900, 10},        //
2540                {"Airbeam 5", 0xe1e5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2541                {"Bullet M2", 0xe202, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},    //
2542                {"Bullet M5", 0xe205, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},    //
2543                {"Bullet M2 Titanium", 0xe2d2, 3, 3, 0, 0, ROUTER_BOARD_TI, 0, 10},     // Titanium
2544                {"Bullet M5 Titanium", 0xe2d5, 3, 3, 0, 0, ROUTER_BOARD_TI, 0, 10},     // Titanium
2545                {"Airgrid M2", 0xe212, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10},   //
2546                {"Airgrid M2", 0xe242, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10},   //
2547                {"Airgrid M2HP", 0xe252, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10}, //
2548                {"Airgrid M5", 0xe215, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},   //
2549                {"Airgrid M5", 0xe245, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},   //
2550                {"Airgrid M5", 0xe255, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},   //
2551                {"Airgrid M5 XW", 0xe835, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},        //
2552                {"AirRouter", 0xe4a2, 1, 1, 0, 0, ROUTER_BOARD_AIRROUTER, 0, 10},       //
2553                {"AirRouter", 0xe4b2, 1, 1, 0, 0, ROUTER_BOARD_AIRROUTER, 0, 10},       //
2554                {"Pico M2", 0xe302, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10},      //
2555                {"Pico M5", 0xe305, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},      //
2556                {"Airwire", 0xe405, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},      //
2557                {"Airwire", 0xe4a5, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},      //
2558                {"Loco M5", 0xe0a5, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},      //
2559                {"Loco M5", 0xe8a5, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},      //
2560                {"Loco M5 XW", 0xe845, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},   //
2561                {"Loco M2", 0xe0a2, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},      //
2562//              {"Loco M2", 0xe8a2, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0},   //
2563                {"Loco M900", 0xe009, 3, 3, 0, 0, ROUTER_BOARD_NS5M, M900, 10}, //
2564                {"NanoStation M900 Sector", 0xe0b9, 3, 3, 0, 0, ROUTER_BOARD_NS5M, M900, 10},   //
2565                {"LiteStation M25", 0xe115, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},      //
2566                {"LiteStation M5", 0xe2a5, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},       //
2567                {"PowerAP N", 0xe402, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},    //
2568                {"Simple AP", 0xe4a2, 3, 3, 0, 0, ROUTER_BOARD_R2M, 0, 10},     //
2569                {"PowerBridge M3", 0xe2a3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M35, 10},      //
2570                {"PowerBridge M5", 0xe1a5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},        //
2571                {"PowerBridge M10", 0xe110, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},       //
2572                {"PowerBridge M5 X3", 0xe3a5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2573                {"PowerBridge M365", 0xe1a3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M365, 10},   //
2574                {"Rocket M10", 0xe110, 3, 3, 0, 0, ROUTER_BOARD_R5M, M10, 10},  //
2575                {"NanoBridge M3", 0xe243, 3, 3, 0, 0, ROUTER_BOARD_BS5M, M35, 10},      //
2576                {"NanoBridge M365", 0xe233, 3, 3, 0, 0, ROUTER_BOARD_BS5M, M365, 10},   //
2577                {"NanoBridge M900", 0xe239, 3, 3, 0, 0, ROUTER_BOARD_BS5M, M900, 10},   //
2578                {"NanoBridge M5", 0xe235, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},        //
2579                {"NanoBridge M5", 0xe2b5, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},        //
2580                {"NanoBridge M5", 0xe2e5, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},        //
2581                {"NanoBridge M2", 0xe232, 3, 3, 0, 0, ROUTER_BOARD_BS2M, 0, 10},        //
2582                {"NanoBridge M2", 0xe2b2, 3, 3, 0, 0, ROUTER_BOARD_BS2M, 0, 10},        //
2583                {"PicoStation M2", 0xe302, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10},       //
2584                {"PicoStation M5", 0xe305, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10},       //
2585                {"3G Station", 0xe6a2, 3, 3, 0, 0, ROUTER_BOARD_BS2M, 0, 10},   //
2586                {"3G Station Professional", 0xe6b2, 3, 3, 0, 0, ROUTER_BOARD_BS2M, 0, 10},      //
2587                {"3G Station Outdoor", 0xe6c2, 3, 3, 0, 0, ROUTER_BOARD_BS2M, 0, 10},   //
2588                {"WispStation M5", 0xe345, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},       //
2589                {"UniFi UAP", 0xe502, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},   //
2590                {"UniFi UAP-PRO", 0xe507, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},       //
2591                {"UniFi UAP-LR", 0xe512, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},        //
2592                {"UniFi UAP-Mini", 0xe522, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},      //
2593                {"UniFi UAP-Outdoor", 0xe532, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},   //
2594                {"UniFi UAP-Outdoor 5G", 0xe515, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},        //
2595                {"UniFi UAP-AC", 0xe902, 7, 7, 7, 7, ROUTER_BOARD_UNIFI, 0, 10},        //
2596                {"UniFi UAP-Outdoor+", 0xe562, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},  //
2597                {"UniFi UAP-AC v2", 0xe912, 7, 7, 7, 7, ROUTER_BOARD_UNIFI, 0, 10},     //
2598                {"UniFi UAP v2", 0xe572, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},        //
2599                {"UniFi UAP-LR v2", 0xe582, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},     //
2600                {"UniFi UAP-AC-Lite", 0xe517, 3, 3, 3, 3, ROUTER_UBNT_UAPAC, 0, 10},    //
2601                {"UniFi UAP-AC-LR", 0xe527, 7, 7, 3, 3, ROUTER_UBNT_UAPAC, 0, 10},      //
2602                {"UniFi UAP-AC-Pro-Gen2", 0xe537, 7, 7, 7, 7, ROUTER_UBNT_UAPAC, 0, 10},        //
2603                {"UniFi UAP-AC-EDU", 0xe547, 7, 7, 7, 7, ROUTER_UBNT_UAPAC, 0, 10},     //
2604                {"UniFi UAP-AC-MESH", 0xe557, 7, 7, 3, 3, ROUTER_UBNT_UAPAC, 0, 10},    //
2605                {"UniFi UAP-AC-MESH-PRO", 0xe567, 7, 7, 7, 7, ROUTER_UBNT_UAPAC, 0, 10},        //
2606                {"UniFi UAP-AC-InWall", 0xe587, 7, 7, 7, 7, ROUTER_UBNT_UAPAC, 0, 10},  //
2607                {"UniFi UAP-AC-InWall", 0xe592, 3, 3, 0, 0, ROUTER_UBNT_UAPAC, 0, 10},  //
2608                {"UniFi UAP-AC-HD", 0xe535, 3, 3, 0, 0, ROUTER_UBNT_UAPAC, 0, 10},      //
2609                {NULL, 0, 0, 0, 0, 0, 0},       //
2610        };
2611
2612#undef M35
2613#undef M365
2614#undef M900
2615#undef M10
2616
2617#if 0
2618        FILE *fp = fopen("/sys/bus/pci/devices/0000:00:00.0/subsystem_device", "rb");
2619        if (fp == NULL)
2620                return ROUTER_BOARD_PB42;
2621        int device;
2622        fscanf(fp, "0x%04X", &device);
2623        fclose(fp);
2624#else
2625        FILE *fp = fopen("/dev/mtdblock5", "rb");       //open board config
2626        int device = 0;
2627        if (fp) {
2628                fseek(fp, 0x1006, SEEK_SET);
2629                unsigned short cal[132];
2630                fread(&cal[0], 1, 256, fp);
2631                int calcnt = 0;
2632                while (((cal[calcnt] & 0xffff) != 0xffff) && calcnt < 128) {
2633                        unsigned short reg = cal[calcnt++] & 0xffff;
2634                        if (reg == 0x602c || reg == 0x502c) {
2635                                calcnt++;
2636                                device = cal[calcnt++] & 0xffff;
2637                                break;
2638                        } else {
2639                                calcnt += 2;
2640                        }
2641                }
2642                if (device == 0) {
2643                        fseek(fp, 12, SEEK_SET);
2644                        unsigned short devid;
2645                        fread(&devid, 2, 1, fp);
2646                        device = devid;
2647                }
2648
2649                fclose(fp);
2650        }
2651#endif
2652        int devcnt = 0;
2653        while (dev[devcnt].devicename != NULL) {
2654                if (dev[devcnt].devid == device) {
2655                        char rxchain[16];
2656                        char txchain[16];
2657                        sprintf(rxchain, "%d", dev[devcnt].rxchain);
2658                        sprintf(txchain, "%d", dev[devcnt].txchain);
2659                        nvram_default_get("ath0_rxantenna", rxchain);
2660                        nvram_default_get("ath0_txantenna", txchain);
2661                        if (dev[devcnt].rxchain5) {
2662                                sprintf(rxchain, "%d", dev[devcnt].rxchain5);
2663                                sprintf(txchain, "%d", dev[devcnt].txchain5);
2664                                nvram_default_get("ath1_rxantenna", rxchain);
2665                                nvram_default_get("ath1_txantenna", txchain);
2666
2667                        }
2668                        if (dev[devcnt].offset) {
2669                                char foff[32];
2670                                sprintf(foff, "%d", dev[devcnt].offset);
2671                                nvram_set("ath0_offset", foff);
2672                        }
2673                        if (dev[devcnt].poffset) {
2674                                char poff[32];
2675                                sprintf(poff, "%d", dev[devcnt].poffset);
2676                                nvram_set("ath0_poweroffset", poff);
2677                        }
2678                        static char devicename[64];
2679                        sprintf(devicename, "Ubiquiti %s", dev[devcnt].devicename);
2680                        setRouter(devicename);
2681                        return dev[devcnt].dddev;
2682                }
2683                devcnt++;
2684        }
2685        setRouter("Ubiquiti Unknown Model");
2686        return ROUTER_BOARD_PB42;
2687#elif HAVE_NS2
2688        setRouter("Ubiquiti NanoStation 2");
2689        return ROUTER_BOARD_LS2;
2690#elif HAVE_EOC5510
2691        setRouter("Senao EOC-5510");
2692        return ROUTER_BOARD_LS2;
2693#elif HAVE_EOC5611
2694        setRouter("Senao EOC-5611");
2695        return ROUTER_BOARD_LS2;
2696#elif HAVE_EOC5610
2697        setRouter("Senao EOC-5610");
2698        return ROUTER_BOARD_LS2;
2699#elif HAVE_NS5
2700        setRouter("Ubiquiti NanoStation 5");
2701        return ROUTER_BOARD_LS2;
2702#elif HAVE_SOLO51
2703        setRouter("Alfa SoLo48-N");
2704        return ROUTER_BOARD_LS2;
2705#elif HAVE_NS3
2706        setRouter("Ubiquiti NanoStation 3");
2707        return ROUTER_BOARD_LS2;
2708#elif HAVE_BS5
2709        setRouter("Ubiquiti Bullet 5");
2710        return ROUTER_BOARD_LS2;
2711#elif HAVE_BS2
2712        setRouter("Ubiquiti Bullet 2");
2713        return ROUTER_BOARD_LS2;
2714#elif HAVE_PICO2
2715        setRouter("Ubiquiti PicoStation 2");
2716        return ROUTER_BOARD_LS2;
2717#elif HAVE_PICO2HP
2718        setRouter("Ubiquiti PicoStation 2 HP");
2719        return ROUTER_BOARD_LS2;
2720#elif HAVE_PICO5
2721        setRouter("Ubiquiti PicoStation 5");
2722        return ROUTER_BOARD_LS2;
2723#elif HAVE_MS2
2724        setRouter("Ubiquiti MiniStation");
2725        return ROUTER_BOARD_LS2;
2726#elif HAVE_BS2HP
2727        setRouter("Ubiquiti Bullet 2 HP");
2728        return ROUTER_BOARD_LS2;
2729#elif HAVE_LC2
2730        setRouter("Ubiquiti NanoStation 2 Loco");
2731        return ROUTER_BOARD_LS2;
2732#elif HAVE_LC5
2733        setRouter("Ubiquiti NanoStation 5 Loco");
2734        return ROUTER_BOARD_LS2;
2735#elif HAVE_PS2
2736        setRouter("Ubiquiti PowerStation 2");
2737        return ROUTER_BOARD_LS2;
2738#elif HAVE_PS5
2739        setRouter("Ubiquiti PowerStation 5");
2740        return ROUTER_BOARD_LS2;
2741#elif HAVE_LS2
2742        setRouter("Ubiquiti LiteStation 2");
2743        return ROUTER_BOARD_LS2;
2744#elif HAVE_LS5
2745        setRouter("Ubiquiti LiteStation 5");
2746        return ROUTER_BOARD_LS2;
2747#elif HAVE_WHRAG108
2748        setRouter("Buffalo WHR-HP-AG108");
2749        return ROUTER_BOARD_WHRAG108;
2750#elif HAVE_PB42
2751        setRouter("Atheros PB42");
2752        return ROUTER_BOARD_PB42;
2753#elif HAVE_RSPRO
2754        setRouter("Ubiquiti RouterStation Pro");
2755        return ROUTER_BOARD_PB42;
2756#elif HAVE_RS
2757#ifdef HAVE_DDLINK
2758        setRouter("ddlink1x1");
2759#else
2760        setRouter("Ubiquiti RouterStation");
2761#endif
2762        return ROUTER_BOARD_PB42;
2763#elif HAVE_E2100
2764        setRouter("Linksys E2100L");
2765        return ROUTER_BOARD_PB42;
2766#elif HAVE_WRT160NL
2767        setRouter("Linksys WRT160NL");
2768        return ROUTER_BOARD_PB42;
2769#elif HAVE_TG2521
2770        setRouter("ZCom TG-2521");
2771        return ROUTER_BOARD_PB42;
2772#elif HAVE_WZRG300NH2
2773        nvram_default_get("ath0_rxantenna", "3");
2774        nvram_default_get("ath0_txantenna", "3");
2775#ifdef HAVE_BUFFALO
2776#ifdef HAVE_WZR300HP
2777        setRouter("WZR-300HP");
2778#else
2779        setRouter("WZR-HP-G300NH2");
2780#endif
2781#else
2782        setRouter("Buffalo WZR-HP-G300NH2");
2783#endif
2784        return ROUTER_BOARD_PB42;
2785#elif HAVE_WZRG450
2786        nvram_default_get("ath0_rxantenna", "7");
2787        nvram_default_get("ath0_txantenna", "7");
2788
2789        void *getUEnv(char *name);
2790
2791        char *model = getUEnv("product");
2792
2793#ifdef HAVE_BUFFALO
2794        if (!strcmp(model, "BHR-4GRV"))
2795                setRouter("BHR-4GRV");
2796        else
2797                setRouter("WZR-HP-G450H");
2798#else
2799        if (!strcmp(model, "BHR-4GRV"))
2800                setRouter("Buffalo BHR-4GRV");
2801        else
2802                setRouter("Buffalo WZR-HP-G450H");
2803#endif
2804        return ROUTER_BOARD_PB42;
2805#elif HAVE_WZRG300NH
2806#ifdef HAVE_BUFFALO
2807        setRouter("WZR-HP-G300NH");
2808#else
2809        setRouter("Buffalo WZR-HP-G300NH");
2810#endif
2811        nvram_default_get("ath0_rxantenna", "7");
2812        nvram_default_get("ath0_txantenna", "7");
2813        return ROUTER_BOARD_PB42;
2814#elif HAVE_WZRHPAG300NH
2815#if defined(HAVE_BUFFALO) || defined(HAVE_IDEXX)
2816#ifdef HAVE_WZR600DHP
2817        setRouter("WZR-600DHP");
2818#else
2819        setRouter("WZR-HP-AG300H");
2820#endif
2821#else
2822        setRouter("Buffalo WZR-HP-AG300H");
2823#endif
2824        return ROUTER_BOARD_PB42;
2825#elif HAVE_DIR632
2826        nvram_default_get("ath0_rxantenna", "3");
2827        nvram_default_get("ath0_txantenna", "3");
2828        setRouter("Dlink-DIR-632A");
2829        return ROUTER_BOARD_PB42;
2830#elif HAVE_WNDR3700V2
2831        nvram_default_get("ath0_rxantenna", "3");
2832        nvram_default_get("ath0_txantenna", "3");
2833        nvram_default_get("ath1_rxantenna", "3");
2834        nvram_default_get("ath1_txantenna", "3");
2835        setRouter("Netgear WNDR3700 v2/WNDR37AV v2/WNDR3800/WNDR38AV");
2836        return ROUTER_BOARD_PB42;
2837#elif HAVE_WNDR3700
2838        nvram_default_get("ath0_rxantenna", "3");
2839        nvram_default_get("ath0_txantenna", "3");
2840        nvram_default_get("ath1_rxantenna", "3");
2841        nvram_default_get("ath1_txantenna", "3");
2842        setRouter("Netgear WNDR3700");
2843        return ROUTER_BOARD_PB42;
2844#elif HAVE_DIR825
2845        nvram_default_get("ath0_rxantenna", "3");
2846        nvram_default_get("ath0_txantenna", "3");
2847        nvram_default_get("ath1_rxantenna", "3");
2848        nvram_default_get("ath1_txantenna", "3");
2849        setRouter("Dlink DIR-825");
2850        return ROUTER_BOARD_PB42;
2851#elif HAVE_TEW673GRU
2852        nvram_default_get("ath0_rxantenna", "3");
2853        nvram_default_get("ath0_txantenna", "3");
2854        nvram_default_get("ath1_rxantenna", "3");
2855        nvram_default_get("ath1_txantenna", "3");
2856        setRouter("Trendnet TEW-673GRU");
2857        return ROUTER_BOARD_PB42;
2858#elif HAVE_WRT400
2859        nvram_default_get("ath0_rxantenna", "3");
2860        nvram_default_get("ath0_txantenna", "3");
2861        nvram_default_get("ath1_rxantenna", "3");
2862        nvram_default_get("ath1_txantenna", "3");
2863        setRouter("Linksys WRT400N");
2864        return ROUTER_BOARD_PB42;
2865#elif HAVE_DIR615C1
2866        setRouter("D-Link DIR-615-C1");
2867        return ROUTER_BOARD_PB42;
2868#elif HAVE_DIR601A1
2869        nvram_default_get("ath0_rxantenna", "1");
2870        nvram_default_get("ath0_txantenna", "1");
2871        setRouter("D-Link DIR-601-A1");
2872        return ROUTER_BOARD_PB42;
2873#elif HAVE_WR842V2
2874        nvram_default_get("ath0_rxantenna", "3");
2875        nvram_default_get("ath0_txantenna", "3");
2876        setRouter("TP-Link TL-WR842ND v2");
2877        return ROUTER_BOARD_PB42;
2878#elif HAVE_DAP3320
2879        nvram_default_get("ath0_rxantenna", "3");
2880        nvram_default_get("ath0_txantenna", "3");
2881        setRouter("Dlink DAP-3320");
2882        return ROUTER_BOARD_PB42;
2883#elif HAVE_DAP2230
2884        nvram_default_get("ath0_rxantenna", "3");
2885        nvram_default_get("ath0_txantenna", "3");
2886        setRouter("Dlink DAP-2230");
2887        return ROUTER_BOARD_PB42;
2888#elif HAVE_WR941V6
2889        nvram_default_get("ath0_rxantenna", "3");
2890        nvram_default_get("ath0_txantenna", "3");
2891        setRouter("TP-Link TL-WR941ND v6");
2892        return ROUTER_BOARD_PB42;
2893#elif HAVE_WR841V12
2894        nvram_default_get("ath0_rxantenna", "3");
2895        nvram_default_get("ath0_txantenna", "3");
2896        setRouter("TP-Link TL-WR841ND v12");
2897        return ROUTER_BOARD_PB42;
2898#elif HAVE_WR841V11
2899        nvram_default_get("ath0_rxantenna", "3");
2900        nvram_default_get("ath0_txantenna", "3");
2901        setRouter("TP-Link TL-WR841ND v11");
2902        return ROUTER_BOARD_PB42;
2903#elif HAVE_WR841V10
2904        nvram_default_get("ath0_rxantenna", "3");
2905        nvram_default_get("ath0_txantenna", "3");
2906        setRouter("TP-Link TL-WR841ND v10");
2907        return ROUTER_BOARD_PB42;
2908#elif HAVE_WR841V9
2909        nvram_default_get("ath0_rxantenna", "3");
2910        nvram_default_get("ath0_txantenna", "3");
2911        setRouter("TP-Link TL-WR841ND v9");
2912        return ROUTER_BOARD_PB42;
2913#elif HAVE_WA901V3
2914        nvram_default_get("ath0_rxantenna", "3");
2915        nvram_default_get("ath0_txantenna", "3");
2916        setRouter("TP-Link TL-WA901ND v3");
2917        return ROUTER_BOARD_PB42;
2918#elif HAVE_WR841V8
2919        nvram_default_get("ath0_rxantenna", "3");
2920        nvram_default_get("ath0_txantenna", "3");
2921        setRouter("TP-Link TL-WR841ND v8");
2922        return ROUTER_BOARD_PB42;
2923#elif HAVE_DIR615I
2924        nvram_default_get("ath0_rxantenna", "3");
2925        nvram_default_get("ath0_txantenna", "3");
2926        setRouter("D-Link DIR-615-I1");
2927        return ROUTER_BOARD_PB42;
2928#elif HAVE_DIR615E1
2929        nvram_default_get("ath0_rxantenna", "3");
2930        nvram_default_get("ath0_txantenna", "3");
2931        setRouter("D-Link DIR-615-E1");
2932        return ROUTER_BOARD_PB42;
2933#elif HAVE_DIR615E
2934        nvram_default_get("ath0_rxantenna", "3");
2935        nvram_default_get("ath0_txantenna", "3");
2936        setRouter("D-Link DIR-615-E3/E4");
2937        return ROUTER_BOARD_PB42;
2938#elif HAVE_TEW652BRP
2939        setRouter("Trendnet TEW-652BRP");
2940        return ROUTER_BOARD_PB42;
2941#elif HAVE_TEW632BRP
2942        setRouter("Trendnet TEW-632BRP");
2943        return ROUTER_BOARD_PB42;
2944#elif HAVE_WR841v3
2945        setRouter("TP-Link TL-WR841ND v3");
2946        return ROUTER_BOARD_PB42;
2947#elif HAVE_WA901
2948        setRouter("TP-Link TL-WA901ND v2");
2949        return ROUTER_BOARD_PB42;
2950#elif HAVE_WR941
2951        setRouter("TP-Link TL-WR941ND v2/v3");
2952        return ROUTER_BOARD_PB42;
2953#elif HAVE_WR841v5
2954        nvram_default_get("ath0_rxantenna", "3");
2955        nvram_default_get("ath0_txantenna", "3");
2956        setRouter("TP-Link TL-WR841ND v5");
2957        return ROUTER_BOARD_PB42;
2958#elif HAVE_WR840v1
2959        nvram_default_get("ath0_rxantenna", "3");
2960        nvram_default_get("ath0_txantenna", "3");
2961        setRouter("TP-Link TL-WR840N v1");
2962        return ROUTER_BOARD_PB42;
2963#elif HAVE_MR3220
2964        nvram_default_get("ath0_rxantenna", "1");
2965        nvram_default_get("ath0_txantenna", "1");
2966        setRouter("TP-Link TL-MR3220");
2967        return ROUTER_BOARD_PB42;
2968#elif HAVE_MR3420
2969        nvram_default_get("ath0_rxantenna", "3");
2970        nvram_default_get("ath0_txantenna", "3");
2971        setRouter("TP-Link TL-MR3420");
2972        return ROUTER_BOARD_PB42;
2973#elif HAVE_WR841v7
2974        nvram_default_get("ath0_rxantenna", "3");
2975        nvram_default_get("ath0_txantenna", "3");
2976        setRouter("TP-Link TL-WR841ND v7");
2977        return ROUTER_BOARD_PB42;
2978#elif HAVE_WR842
2979        nvram_default_get("ath0_rxantenna", "3");
2980        nvram_default_get("ath0_txantenna", "3");
2981        setRouter("TP-Link TL-WR842ND v1");
2982        return ROUTER_BOARD_PB42;
2983#elif HAVE_WR740v1
2984        nvram_default_get("ath0_rxantenna", "1");
2985        nvram_default_get("ath0_txantenna", "1");
2986        setRouter("TP-Link TL-WR740N");
2987        return ROUTER_BOARD_PB42;
2988#elif HAVE_WA801v1
2989        nvram_default_get("ath0_rxantenna", "3");
2990        nvram_default_get("ath0_txantenna", "3");
2991        setRouter("TP-Link TL-WA801ND v1");
2992        return ROUTER_BOARD_PB42;
2993#elif HAVE_WA901v1
2994        nvram_default_get("ath0_rxantenna", "3");
2995        nvram_default_get("ath0_txantenna", "3");
2996        setRouter("TP-Link TL-WA901ND v1");
2997        return ROUTER_BOARD_PB42;
2998#elif HAVE_WR941v4
2999        setRouter("TP-Link TL-WR941ND v4");
3000        return ROUTER_BOARD_PB42;
3001#elif HAVE_WR743
3002        nvram_default_get("ath0_rxantenna", "1");
3003        nvram_default_get("ath0_txantenna", "1");
3004        setRouter("TP-Link TL-WR743ND v1");
3005        return ROUTER_BOARD_PB42;
3006#elif HAVE_MR3020
3007        nvram_default_get("ath0_rxantenna", "1");
3008        nvram_default_get("ath0_txantenna", "1");
3009        setRouter("TP-Link TL-MR3020");
3010        return ROUTER_BOARD_PB42;
3011#elif HAVE_GL150
3012        nvram_default_get("ath0_rxantenna", "1");
3013        nvram_default_get("ath0_txantenna", "1");
3014        setRouter("GL.iNet-AR150");
3015        return ROUTER_BOARD_PB42;
3016#elif HAVE_WR71021
3017        nvram_default_get("ath0_rxantenna", "1");
3018        nvram_default_get("ath0_txantenna", "1");
3019        setRouter("TP-Link TL-WR710N v2.1");
3020        return ROUTER_BOARD_PB42;
3021#elif HAVE_WR710V1
3022        nvram_default_get("ath0_rxantenna", "1");
3023        nvram_default_get("ath0_txantenna", "1");
3024        setRouter("TP-Link TL-WR710N v1");
3025        return ROUTER_BOARD_PB42;
3026#elif HAVE_WR710
3027        nvram_default_get("ath0_rxantenna", "1");
3028        nvram_default_get("ath0_txantenna", "1");
3029        setRouter("TP-Link TL-WR710N v2");
3030        return ROUTER_BOARD_PB42;
3031#elif HAVE_WA701V2
3032        nvram_default_get("ath0_rxantenna", "1");
3033        nvram_default_get("ath0_txantenna", "1");
3034        setRouter("TP-Link TL-WA701ND v2");
3035        return ROUTER_BOARD_PB42;
3036#elif HAVE_WR703
3037        nvram_default_get("ath0_rxantenna", "1");
3038        nvram_default_get("ath0_txantenna", "1");
3039        setRouter("TP-Link TL-WR703N v1");
3040        return ROUTER_BOARD_PB42;
3041#elif HAVE_WR740V4
3042        nvram_default_get("ath0_rxantenna", "1");
3043        nvram_default_get("ath0_txantenna", "1");
3044        setRouter("TP-Link TL-WR740N v4");
3045        return ROUTER_BOARD_PB42;
3046#elif HAVE_WR743V2
3047        nvram_default_get("ath0_rxantenna", "1");
3048        nvram_default_get("ath0_txantenna", "1");
3049        setRouter("TP-Link TL-WR743ND v2");
3050        return ROUTER_BOARD_PB42;
3051#elif HAVE_WR741V4
3052        nvram_default_get("ath0_rxantenna", "1");
3053        nvram_default_get("ath0_txantenna", "1");
3054        setRouter("TP-Link TL-WR741ND v4");
3055        return ROUTER_BOARD_PB42;
3056#elif HAVE_WA7510
3057        nvram_default_get("ath0_rxantenna", "1");
3058        nvram_default_get("ath0_txantenna", "1");
3059        setRouter("TP-Link TL-WA7510N v1");
3060        return ROUTER_BOARD_PB42;
3061#elif HAVE_WR741
3062        nvram_default_get("ath0_rxantenna", "1");
3063        nvram_default_get("ath0_txantenna", "1");
3064        setRouter("TP-Link TL-WR741ND v1");
3065        return ROUTER_BOARD_PB42;
3066#elif HAVE_WR1043
3067        nvram_default_get("ath0_rxantenna", "7");
3068        nvram_default_get("ath0_txantenna", "7");
3069        setRouter("TP-Link TL-WR1043ND");
3070        return ROUTER_BOARD_PB42;
3071#elif HAVE_AP83
3072        setRouter("Atheros AP83");
3073        return ROUTER_BOARD_PB42;
3074#elif HAVE_WP546
3075        setRouter("Compex WP546");
3076        return ROUTER_BOARD_PB42;
3077#elif HAVE_WP543
3078        setRouter("Compex WP543");
3079        return ROUTER_BOARD_PB42;
3080#elif HAVE_JA76PF
3081        setRouter("JJPLUS JA76PF");
3082        return ROUTER_BOARD_PB42;
3083#elif HAVE_JWAP003
3084        setRouter("JJPLUS JWAP003");
3085        return ROUTER_BOARD_PB42;
3086#elif HAVE_ALFAAP94
3087        setRouter("Alfa AP94 Board");
3088        return ROUTER_BOARD_PB42;
3089#elif HAVE_LSX
3090        setRouter("Ubiquiti LiteStation-SR71");
3091        return ROUTER_BOARD_PB42;
3092#elif HAVE_WMBR_G300NH
3093        setRouter("Buffalo WBMR-HP-G300H");
3094        nvram_default_get("ath0_rxantenna", "3");
3095        nvram_default_get("ath0_txantenna", "3");
3096        return ROUTER_BOARD_DANUBE;
3097#elif HAVE_VF802
3098        setRouter("Vodafone Easybox 802");
3099        return ROUTER_BOARD_DANUBE;
3100#elif HAVE_VF803
3101        setRouter("Vodafone Easybox 803");
3102        return ROUTER_BOARD_DANUBE;
3103#elif HAVE_SX763
3104        setRouter("Gigaset SX763");
3105        return ROUTER_BOARD_DANUBE;
3106#elif HAVE_DANUBE
3107        setRouter("Infineon Danube");
3108        return ROUTER_BOARD_DANUBE;
3109#elif HAVE_WBD222
3110        setRouter("Wiligear WBD-222");
3111        return ROUTER_BOARD_STORM;
3112#elif HAVE_STORM
3113        setRouter("Wiligear WBD-111");
3114        return ROUTER_BOARD_STORM;
3115#elif HAVE_OPENRISC
3116        setRouter("Alekto OpenRisc");
3117        return ROUTER_BOARD_OPENRISC;
3118#elif HAVE_TW6600
3119        setRouter("AW-6660");
3120        return ROUTER_BOARD_TW6600;
3121#elif HAVE_ALPHA
3122        setRouter("Alfa Networks AP48");
3123        return ROUTER_BOARD_CA8;
3124#elif HAVE_USR5453
3125        setRouter("US Robotics USR5453");
3126        return ROUTER_BOARD_CA8;
3127#elif HAVE_RDAT81
3128        setRouter("Wistron RDAT-81");
3129        return ROUTER_BOARD_RDAT81;
3130#elif HAVE_RCAA01
3131        setRouter("Airlive WLA-9000AP");
3132        return ROUTER_BOARD_RCAA01;
3133#elif HAVE_CA8PRO
3134        setRouter("Wistron CA8-4 PRO");
3135        return ROUTER_BOARD_CA8PRO;
3136#elif HAVE_CA8
3137#ifdef HAVE_WHA5500CPE
3138        setRouter("Airlive WHA-5500CPE");
3139#elif HAVE_AIRMAX5
3140        setRouter("Airlive AirMax 5");
3141#else
3142        setRouter("Airlive WLA-5000AP");
3143#endif
3144        return ROUTER_BOARD_CA8;
3145#else
3146
3147        unsigned long boardnum = strtoul(nvram_safe_get("boardnum"), NULL, 0);
3148        unsigned long melco_id = strtoul(nvram_safe_get("melco_id"), NULL, 0);
3149
3150        if (boardnum == 42 && nvram_match("boardtype", "bcm94710ap")) {
3151                setRouter("Buffalo WBR-G54 / WLA-G54");
3152                return ROUTER_BUFFALO_WBR54G;
3153        }
3154#ifndef HAVE_BUFFALO
3155        if (nvram_match("boardnum", "mn700") && nvram_match("boardtype", "bcm94710ap")) {
3156                setRouter("Microsoft MN-700");
3157                return ROUTER_MICROSOFT_MN700;
3158        }
3159
3160        if (nvram_match("boardnum", "asusX") && nvram_match("boardtype", "bcm94710dev")) {
3161                setRouter("Asus WL-300g / WL-500g");
3162                return ROUTER_ASUS_WL500G;
3163        }
3164
3165        if (boardnum == 44 && nvram_match("boardtype", "bcm94710ap")) {
3166                setRouter("Dell TrueMobile 2300");
3167                return ROUTER_DELL_TRUEMOBILE_2300;
3168        }
3169#endif
3170
3171        if (boardnum == 100 && nvram_match("boardtype", "bcm94710dev")) {
3172                setRouter("Buffalo WLA-G54C");
3173                return ROUTER_BUFFALO_WLAG54C;
3174        }
3175#ifndef HAVE_BUFFALO
3176        if (boardnum == 45 && nvram_match("boardtype", "bcm95365r")) {
3177                setRouter("Asus WL-500g Deluxe");
3178                return ROUTER_ASUS_WL500GD;
3179        }
3180
3181        if (boardnum == 45 && nvram_match("boardtype", "0x0472")
3182            && nvram_match("boardrev", "0x23") && nvram_matchi("parkid", 1)) {
3183                setRouter("Asus WL-500W");
3184                return ROUTER_ASUS_WL500W;
3185        }
3186
3187        if (boardnum == 45 && nvram_match("boardtype", "0x467")) {
3188                char *hwver0 = nvram_safe_get("hardware_version");
3189
3190                if (startswith(hwver0, "WL320G")) {
3191                        setRouter("Asus WL-320gE/gP");
3192                        return ROUTER_ASUS_WL550GE;
3193                } else {
3194                        setRouter("Asus WL-550gE");
3195                        return ROUTER_ASUS_WL550GE;
3196                }
3197        }
3198#ifdef HAVE_BCMMODERN
3199        if (boardnum == 45 && nvram_match("boardtype", "0x04EC")
3200            && nvram_match("boardrev", "0x1402")) {
3201                setRouter("Asus RT-N10");
3202                return ROUTER_ASUS_RTN10;
3203        }
3204
3205        if (boardnum == 45 && nvram_match("boardtype", "0x0550")
3206            && nvram_match("boardrev", "0x1102")) {
3207                setRouter("Asus RT-N10U");
3208                return ROUTER_ASUS_RTN10U;
3209        }
3210
3211        if (boardnum == 45 && nvram_match("boardtype", "0x058e")
3212            && nvram_match("boardrev", "0x1153")) {
3213                setRouter("Asus RT-N10+ rev D1");
3214                return ROUTER_ASUS_RTN10PLUSD1;
3215        }
3216
3217        if (boardnum == 45 && nvram_match("boardtype", "0x0550")
3218            && nvram_match("boardrev", "0x1442")) {
3219                setRouter("Asus RT-N53");
3220                return ROUTER_ASUS_RTN53;
3221        }
3222
3223        if (nvram_match("boardtype", "0xF5B2")
3224            && nvram_match("boardrev", "0x1100")
3225            && !nvram_matchi("pci/2/1/sb20in80and160hr5ghpo", 0)) {
3226                setRouter("Asus RT-N66U");
3227                return ROUTER_ASUS_RTN66;
3228        }
3229
3230        if (nvram_matchi("boardnum", 1) && nvram_match("boardtype", "0x054d")
3231            && nvram_match("boardrev", "0x1109")) {
3232                setRouter("NetCore NW715P");
3233                return ROUTER_NETCORE_NW715P;
3234        }
3235
3236        if (boardnum == 45 && nvram_match("boardtype", "0x04CD")
3237            && nvram_match("boardrev", "0x1201")) {
3238                setRouter("Asus RT-N12");
3239                return ROUTER_ASUS_RTN12;
3240        }
3241
3242        if (boardnum == 45 && nvram_match("boardtype", "0x054D")
3243            && nvram_match("boardrev", "0x1101")) {
3244                char *hwrev = nvram_safe_get("hardware_version");
3245                if (!strncmp(hwrev, "RTN12C1", 7))
3246                        setRouter("Asus RT-N12C1");
3247                else
3248                        setRouter("Asus RT-N12B");
3249                return ROUTER_ASUS_RTN12B;
3250        }
3251
3252        if (boardnum == 45 && nvram_match("boardtype", "0x04cf")
3253            && nvram_match("boardrev", "0x1218")) {
3254                setRouter("Asus RT-N16");
3255                return ROUTER_ASUS_RTN16;
3256        }
3257
3258        if (nvram_match("boardtype", "0xa4cf")
3259            && nvram_match("boardrev", "0x1100")) {
3260                setRouter("Belkin F5D8235-4 v3");
3261                return ROUTER_BELKIN_F5D8235V3;
3262        }
3263
3264        if (nvram_match("boardtype", "0xd4cf")
3265            && nvram_match("boardrev", "0x1204")) {
3266                setRouter("Belkin F7D4301 / F7D8301 v1");
3267                return ROUTER_BELKIN_F7D4301;
3268        }
3269
3270        if (nvram_match("boardtype", "0xa4cf")
3271            && nvram_match("boardrev", "0x1102")) {
3272                FILE *mtd1 = fopen("/dev/mtdblock/1", "rb");
3273                unsigned int trxhd;
3274                if (mtd1) {
3275                        fread(&trxhd, 4, 1, mtd1);
3276                        fclose(mtd1);
3277                        if (trxhd == TRX_MAGIC_F7D3301) {
3278                                setRouter("Belkin F7D3301 / F7D7301 v1");
3279                                return ROUTER_BELKIN_F7D3301;
3280                        }
3281                        if (trxhd == TRX_MAGIC_F7D3302) {
3282                                setRouter("Belkin F7D3302 / F7D7302 v1");
3283                                return ROUTER_BELKIN_F7D3302;
3284                        }
3285                }
3286                setRouter("Belkin F7D4302 / F7D8302 v1");
3287                return ROUTER_BELKIN_F7D4302;
3288        }
3289#endif
3290
3291#endif
3292        if (nvram_match("boardnum", "00") && nvram_match("boardtype", "0x0101")
3293            && nvram_match("boardrev", "0x10")) {
3294                setRouter("Buffalo WBR2-G54 / WBR2-G54S");
3295                return ROUTER_BUFFALO_WBR2G54S;
3296        }
3297
3298        if (boardnum == 2 && nvram_match("boardtype", "0x0101")
3299            && nvram_match("boardrev", "0x10")) {
3300                setRouter("Buffalo WLA2-G54C / WLI3-TX1-G54");
3301                return ROUTER_BUFFALO_WLA2G54C;
3302        }
3303        if (boardnum == 0 && melco_id == 29090 && nvram_match("boardrev", "0x10")) {
3304                setRouter("Buffalo WLAH-G54");
3305                return ROUTER_BUFFALO_WLAH_G54;
3306
3307        }
3308        if (boardnum == 0 && melco_id == 31070 && nvram_match("boardflags", "0x2288")
3309            && nvram_match("boardrev", "0x10")) {
3310                setRouter("Buffalo WAPM-HP-AM54G54");
3311                return ROUTER_BUFFALO_WAPM_HP_AM54G54;
3312        }
3313
3314        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x11")
3315            && nvram_match("boardtype", "0x048e") && melco_id == 32093) {
3316                setRouter("Buffalo WHR-G125");
3317                return ROUTER_BUFFALO_WHRG54S;
3318        }
3319
3320        if (nvram_match("boardnum", "0x5347") && nvram_match("boardrev", "0x11")
3321            && nvram_match("boardtype", "0x048e")) {
3322                setRouter("Huawei B970b");
3323                return ROUTER_HUAWEI_B970B;
3324        }
3325
3326        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x10")
3327            && nvram_match("boardtype", "0x048e") && melco_id == 32139) {
3328                setRouter("Buffalo WCA-G");
3329                return ROUTER_BUFFALO_WCAG;     //vlan1 is lan, vlan0 is unused, implementation not done. will me made after return to germany
3330        }
3331
3332        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x11")
3333            && nvram_match("boardtype", "0x048e") && melco_id == 32064) {
3334                setRouter("Buffalo WHR-HP-G125");
3335                return ROUTER_BUFFALO_WHRG54S;
3336        }
3337
3338        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x13")
3339            && nvram_match("boardtype", "0x467")) {
3340                if (nvram_match("boardflags", "0x1658")
3341                    || nvram_match("boardflags", "0x2658")
3342                    || nvram_match("boardflags", "0x3658")) {
3343                        setRouter("Buffalo WLI-TX4-G54HP");
3344                        return ROUTER_BUFFALO_WLI_TX4_G54HP;
3345                }
3346                if (!nvram_matchi("buffalo_hp", 1)
3347                    && nvram_match("boardflags", "0x2758")) {
3348                        setRouter("Buffalo WHR-G54S");
3349                        return ROUTER_BUFFALO_WHRG54S;
3350                }
3351                if (nvram_matchi("buffalo_hp", 1)
3352                    || nvram_match("boardflags", "0x1758")) {
3353#ifndef HAVE_BUFFALO
3354                        setRouter("Buffalo WHR-HP-G54");
3355#else
3356#ifdef BUFFALO_JP
3357                        setRouter("Buffalo AS-A100");
3358#else
3359                        setRouter("Buffalo WHR-HP-G54DD");
3360#endif
3361#endif
3362                        return ROUTER_BUFFALO_WHRG54S;
3363                }
3364        }
3365
3366        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x10")
3367            && nvram_match("boardtype", "0x470")) {
3368                setRouter("Buffalo WHR-AM54G54");
3369                return ROUTER_BUFFALO_WHRAM54G54;
3370        }
3371
3372        if (boardnum == 42 && nvram_match("boardtype", "0x042f")) {
3373
3374                if (nvram_match("product_name", "WZR-RS-G54")
3375                    || melco_id == 30083) {
3376                        setRouter("Buffalo WZR-RS-G54");
3377                        return ROUTER_BUFFALO_WZRRSG54;
3378                }
3379                if (nvram_match("product_name", "WZR-HP-G54")
3380                    || melco_id == 30026) {
3381                        setRouter("Buffalo WZR-HP-G54");
3382                        return ROUTER_BUFFALO_WZRRSG54;
3383                }
3384                if (nvram_match("product_name", "WZR-G54") || melco_id == 30061) {
3385                        setRouter("Buffalo WZR-G54");
3386                        return ROUTER_BUFFALO_WZRRSG54;
3387                }
3388                if (nvram_match("melco_id", "290441dd")) {
3389                        setRouter("Buffalo WHR2-A54G54");
3390                        return ROUTER_BUFFALO_WZRRSG54;
3391                }
3392                if (nvram_match("product_name", "WHR3-AG54")
3393                    || nvram_match("product_name", "WHR3-B11")
3394                    || melco_id == 29130) {
3395                        setRouter("Buffalo WHR3-AG54");
3396                        return ROUTER_BUFFALO_WZRRSG54;
3397                }
3398                if (nvram_match("product_name", "WVR-G54-NF")
3399                    || melco_id == 28100) {
3400                        setRouter("Buffalo WVR-G54-NF");
3401                        return ROUTER_BUFFALO_WZRRSG54;
3402                }
3403                if (nvram_match("product_name", "WZR-G108") || melco_id == 31095 || melco_id == 30153) {
3404                        setRouter("Buffalo WZR-G108");
3405                        return ROUTER_BRCM4702_GENERIC;
3406                }
3407                if (melco_id > 0)       // e.g. 29115
3408                {
3409                        setRouter("Buffalo WZR series");
3410                        return ROUTER_BUFFALO_WZRRSG54;
3411                }
3412        }
3413#ifndef HAVE_BUFFALO
3414        if (boardnum == 42 && nvram_match("boardtype", "0x042f")
3415            && nvram_match("boardrev", "0x10"))
3416                // nvram_match ("boardflags","0x0018"))
3417        {
3418                setRouter("Linksys WRTSL54GS");
3419                return ROUTER_WRTSL54GS;
3420        }
3421
3422        if (boardnum == 42 && nvram_match("boardtype", "0x0101")
3423            && nvram_match("boardrev", "0x10")
3424            && nvram_match("boot_ver", "v3.6")) {
3425                setRouter("Linksys WRT54G3G");
3426                return ROUTER_WRT54G3G;
3427        }
3428
3429        if (nvram_match("boardtype", "0x042f")
3430            && nvram_match("boardrev", "0x10")) {
3431                char *hwver = nvram_safe_get("hardware_version");
3432
3433                if (boardnum == 45 || startswith(hwver, "WL500gp")
3434                    || startswith(hwver, "WL500gH")) {
3435                        setRouter("Asus WL-500g Premium");
3436                        return ROUTER_ASUS_WL500G_PRE;
3437                }
3438                if (boardnum == 44 || startswith(hwver, "WL700g")) {
3439                        setRouter("Asus WL-700gE");
3440                        return ROUTER_ASUS_WL700GE;
3441                }
3442        }
3443
3444        char *et0 = nvram_safe_get("et0macaddr");
3445
3446        if (boardnum == 100 && nvram_match("boardtype", "bcm94710r4")) {
3447                if (startswith(et0, "00:11:50")) {
3448                        setRouter("Belkin F5D7130 / F5D7330");
3449                        return ROUTER_RT210W;
3450                }
3451                if (startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
3452                        setRouter("Belkin F5D7230-4 v1000");
3453                        return ROUTER_RT210W;
3454                }
3455                if (startswith(et0, "00:01:E3") || startswith(et0, "00:01:e3") || startswith(et0, "00:90:96")) {
3456                        setRouter("Siemens SE505 v1");
3457                        return ROUTER_RT210W;
3458                } else {
3459                        setRouter("Askey RT210W generic");
3460                        return ROUTER_RT210W;
3461                }
3462        }
3463
3464        if (nvram_match("boardtype", "bcm94710r4")
3465            && nvram_match("boardnum", "")) {
3466                setRouter("Askey board RT2100W-D65)");
3467                return ROUTER_BRCM4702_GENERIC;
3468        }
3469
3470        if (boardnum == 0 && nvram_match("boardtype", "0x0100")
3471            && nvram_match("boardrev", "0x10")) {
3472                if (startswith(et0, "00:11:50") || startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
3473                        setRouter("Askey board RT2205(6)D-D56");
3474                } else {
3475                        setRouter("Belkin board F5D8230");
3476                }
3477                return ROUTER_ASKEY_RT220XD;
3478        }
3479
3480        if (nvram_match("boardtype", "0x0101")) {
3481                if (startswith(et0, "00:11:50") || startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
3482                        if (nvram_matchi("Belkin_ver", 2000)) {
3483                                setRouter("Belkin F5D7230-4 v2000");
3484                                return ROUTER_BELKIN_F5D7230_V2000;
3485                        } else {
3486                                setRouter("Belkin F5D7230-4 v1444");
3487                                return ROUTER_RT480W;
3488                        }
3489                }
3490                if (startswith(et0, "00:01:E3") || startswith(et0, "00:01:e3") || startswith(et0, "00:90:96")) {
3491                        setRouter("Siemens SE505 v2");
3492                        return ROUTER_RT480W;
3493                }
3494        }
3495        if (boardnum == 1 && nvram_match("boardtype", "0x456")
3496            && nvram_matchi("test_led_gpio", 2)) {
3497                setRouter("Belkin F5D7230-4 v3000");
3498                return ROUTER_BELKIN_F5D7230_V3000;
3499        }
3500
3501        if (nvram_match("boardtype", "0x456")
3502            && nvram_match("hw_model", "F5D7231-4")) {
3503                setRouter("Belkin F5D7231-4 v1212UK");
3504                return ROUTER_BELKIN_F5D7231;
3505        }
3506
3507        if (boardnum == 8 && nvram_match("boardtype", "0x0467"))        // fccid:
3508                // K7SF5D7231B
3509        {
3510                setRouter("Belkin F5D7231-4 v2000");
3511                return ROUTER_BELKIN_F5D7231_V2000;
3512        }
3513
3514        if (nvram_match("boardtype", "0x467")) {
3515                if (startswith(et0, "00:11:50") || startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
3516                        setRouter("Belkin F5D7231-4 v2000");
3517                        return ROUTER_BELKIN_F5D7231;
3518                }
3519        }
3520#endif
3521        if (boardnum == 2 && nvram_match("boardtype", "bcm94710dev") && melco_id == 29016)      // Buffalo
3522                // WLI2-TX1-G54)
3523        {
3524                setRouter("Buffalo WLI2-TX1-G54");
3525                return ROUTER_BUFFALO_WLI2_TX1_G54;
3526        }
3527#ifndef HAVE_BUFFALO
3528
3529        char *gemtek = nvram_safe_get("GemtekPmonVer");
3530        unsigned long gemteknum = strtoul(gemtek, NULL, 0);
3531
3532        if (boardnum == 2 && (gemteknum == 10 || gemteknum == 11) &&
3533            (startswith(et0, "00:0C:E5") ||
3534             startswith(et0, "00:0c:e5") || startswith(et0, "00:11:22") || startswith(et0, "00:0C:10") || startswith(et0, "00:0c:10") || startswith(et0, "00:0C:11") || startswith(et0, "00:0c:11"))) {
3535                setRouter("Motorola WE800G v1");
3536                return ROUTER_MOTOROLA_WE800G;
3537        }
3538
3539        if (boardnum == 2 && (startswith(gemtek, "RC") || gemteknum == 1 || gemteknum == 10)) {
3540                setRouter("Linksys WAP54G v1.x");
3541                return ROUTER_WAP54G_V1;
3542        }
3543
3544        if (boardnum == 2 && gemteknum == 1) {
3545                setRouter("Sitecom WL-105(b)");
3546                return ROUTER_SITECOM_WL105B;
3547        }
3548
3549        if (boardnum == 2 && gemteknum == 7 && nvram_match("boardtype", "bcm94710dev")) {
3550                setRouter("Sitecom WL-111");
3551                return ROUTER_SITECOM_WL111;
3552        }
3553
3554        if (gemteknum == 9)     // Must be Motorola wr850g v1 or we800g v1 or
3555                // Linksys wrt55ag v1
3556        {
3557                if (startswith(et0, "00:0C:E5") ||
3558                    startswith(et0, "00:0c:e5") ||
3559                    startswith(et0, "00:0C:10") ||
3560                    startswith(et0, "00:0c:10") || startswith(et0, "00:0C:11") || startswith(et0, "00:0c:11") || startswith(et0, "00:11:22") || startswith(et0, "00:0C:90") || startswith(et0, "00:0c:90")) {
3561                        if (!strlen(nvram_safe_get("phyid_num"))) {
3562                                insmod("switch-core");  // get phy type
3563                                insmod("switch-robo");
3564                                rmmod("switch-robo");
3565                                rmmod("switch-core");
3566                                nvram_seti("boardnum", 2);
3567                                nvram_set("boardtype", "bcm94710dev");
3568                        }
3569                        if (nvram_match("phyid_num", "0x00000000")) {
3570                                setRouter("Motorola WE800G v1");
3571                                return ROUTER_MOTOROLA_WE800G;
3572                        } else  // phyid_num == 0xffffffff
3573                        {
3574                                setRouter("Motorola WR850G v1");
3575                                return ROUTER_MOTOROLA_V1;
3576                        }
3577                } else {
3578                        setRouter("Linksys WRT55AG v1");
3579                        return ROUTER_LINKSYS_WRT55AG;
3580                }
3581        }
3582#endif
3583        if (boardnum == 0 && nvram_match("boardtype", "0x478")
3584            && nvram_matchi("cardbus", 0) && nvram_match("boardrev", "0x10")
3585            && nvram_match("boardflags", "0x110") && melco_id == 32027) {
3586                setRouter("Buffalo WZR-G144NH");
3587                return ROUTER_BUFFALO_WZRG144NH;
3588        }
3589
3590        if (boardnum == 20060330 && nvram_match("boardtype", "0x0472")) {
3591                setRouter("Buffalo WZR-G300N");
3592                return ROUTER_BUFFALO_WZRG300N;
3593        }
3594#ifndef HAVE_BUFFALO
3595
3596        if (boardnum == 8 && nvram_match("boardtype", "0x0472")
3597            && nvram_matchi("cardbus", 1)) {
3598                setRouter("Netgear WNR834B");
3599                return ROUTER_NETGEAR_WNR834B;
3600        }
3601
3602        if (boardnum == 1 && nvram_match("boardtype", "0x0472")
3603            && nvram_match("boardrev", "0x23")) {
3604                if (nvram_matchi("cardbus", 1)) {
3605                        setRouter("Netgear WNR834B v2");
3606                        return ROUTER_NETGEAR_WNR834BV2;
3607                } else {
3608                        setRouter("Netgear WNDR3300");
3609                        return ROUTER_NETGEAR_WNDR3300;
3610                }
3611        }
3612
3613        if (boardnum == 42)     // Get Linksys N models
3614        {
3615                if (nvram_match("boot_hw_model", "WRT300N")
3616                    && nvram_match("boot_hw_ver", "1.1")) {
3617                        setRouter("Linksys WRT300N v1.1");
3618                        return ROUTER_WRT300NV11;
3619                } else if (nvram_match("boot_hw_model", "WRT150N")
3620                           && nvram_matchi("boot_hw_ver", 1)) {
3621                        setRouter("Linksys WRT150N v1");
3622                        return ROUTER_WRT150N;
3623                } else if (nvram_match("boot_hw_model", "WRT150N")
3624                           && nvram_match("boot_hw_ver", "1.1")) {
3625                        setRouter("Linksys WRT150N v1.1");
3626                        return ROUTER_WRT150N;
3627                } else if (nvram_match("boot_hw_model", "WRT150N")
3628                           && nvram_match("boot_hw_ver", "1.2")) {
3629                        setRouter("Linksys WRT150N v1.2");
3630                        return ROUTER_WRT150N;
3631                } else if (nvram_match("boot_hw_model", "WRT160N")
3632                           && nvram_match("boot_hw_ver", "1.0")) {
3633                        setRouter("Linksys WRT160N");
3634                        return ROUTER_WRT160N;
3635                } else if (nvram_match("boot_hw_model", "WRT160N")
3636                           && nvram_match("boot_hw_ver", "3.0")) {
3637                        setRouter("Linksys WRT160N v3");
3638                        return ROUTER_WRT160NV3;
3639                } else if (nvram_match("boot_hw_model", "M10")
3640                           && nvram_match("boot_hw_ver", "1.0")) {
3641                        setRouter("Cisco Valet M10 v1");        // renamed wrt160nv3
3642                        return ROUTER_WRT160NV3;
3643                } else if (nvram_match("boot_hw_model", "E100")
3644                           && nvram_match("boot_hw_ver", "1.0")) {
3645                        setRouter("Linksys E1000 v1");  // renamed wrt160nv3
3646                        return ROUTER_WRT160NV3;
3647                } else if (nvram_match("boot_hw_model", "E800")
3648                           && nvram_match("boot_hw_ver", "1.0")) {
3649                        setRouter("Linksys E800");
3650                        return ROUTER_LINKSYS_E800;
3651                } else if (nvram_match("boot_hw_model", "E900")
3652                           && nvram_match("boot_hw_ver", "1.0")) {
3653                        setRouter("Linksys E900");
3654                        return ROUTER_LINKSYS_E900;
3655                } else if (nvram_match("boot_hw_model", "E1000")
3656                           && nvram_match("boot_hw_ver", "2.0")) {
3657                        setRouter("Linksys E1000 v2");
3658                        return ROUTER_LINKSYS_E1000V2;
3659                } else if (nvram_match("boot_hw_model", "E1000")
3660                           && nvram_match("boot_hw_ver", "2.1")) {
3661                        setRouter("Linksys E1000 v2.1");
3662                        return ROUTER_LINKSYS_E1000V2;
3663                } else if (nvram_match("boot_hw_model", "E1200")
3664                           && nvram_match("boot_hw_ver", "1.0")) {
3665                        setRouter("Linksys E1200 v1");
3666                        return ROUTER_LINKSYS_E1500;
3667                } else if (nvram_match("boot_hw_model", "E1200")
3668                           && nvram_match("boot_hw_ver", "2.0")) {
3669                        setRouter("Linksys E1200 v2");
3670                        return ROUTER_LINKSYS_E900;
3671                } else if (nvram_match("boot_hw_model", "E1500")
3672                           && nvram_match("boot_hw_ver", "1.0")) {
3673                        setRouter("Linksys E1500");
3674                        return ROUTER_LINKSYS_E1500;
3675                } else if (nvram_match("boot_hw_model", "E1550")
3676                           && nvram_match("boot_hw_ver", "1.0")) {
3677                        setRouter("Linksys E1550");
3678                        return ROUTER_LINKSYS_E1550;
3679                } else if (nvram_match("boot_hw_model", "WRT310N")
3680                           && nvram_match("boot_hw_ver", "1.0")) {
3681                        setRouter("Linksys WRT310N");
3682                        return ROUTER_WRT310N;
3683                } else if (nvram_match("boot_hw_model", "WRT310N")
3684                           && nvram_match("boot_hw_ver", "2.0")) {
3685                        setRouter("Linksys WRT310N v2");
3686                        return ROUTER_WRT310NV2;
3687                } else if (nvram_match("boot_hw_model", "M20")
3688                           && nvram_match("boot_hw_ver", "1.0")) {
3689                        setRouter("Cisco Valet Plus M20");      // ranamed wrt310nv2
3690                        return ROUTER_WRT310NV2;
3691                } else if (nvram_match("boot_hw_model", "E2500")
3692                           && nvram_match("boot_hw_ver", "1.0")) {
3693                        setRouter("Linksys E2500");
3694                        return ROUTER_LINKSYS_E2500;
3695                } else if (nvram_match("boot_hw_model", "E3200")
3696                           && nvram_match("boot_hw_ver", "1.0")) {
3697                        setRouter("Linksys E3200");
3698                        return ROUTER_LINKSYS_E3200;
3699                } else if (nvram_match("boot_hw_model", "E4200")
3700                           && nvram_match("boot_hw_ver", "1.0")) {
3701                        setRouter("Linksys E4200");
3702                        return ROUTER_LINKSYS_E4200;
3703                }
3704        }
3705
3706        if (boardnum == 42 && nvram_match("boardtype", "0x0472")
3707            && nvram_matchi("cardbus", 1)) {
3708                setRouter("Linksys WRT300N v1");
3709                return ROUTER_WRT300N;
3710        }
3711
3712        if (boardnum == 42 && nvram_match("boardtype", "0x478") && nvram_matchi("cardbus", 1)) {
3713                setRouter("Linksys WRT350N");
3714                return ROUTER_WRT350N;
3715        }
3716
3717        if (nvram_matchi("boardnum", 20070615) && nvram_match("boardtype", "0x478") && nvram_matchi("cardbus", 0)) {
3718                if (nvram_match("switch_type", "BCM5395")) {
3719                        setRouter("Linksys WRT600N v1.1");
3720                        return ROUTER_WRT600N;
3721                } else {
3722                        setRouter("Linksys WRT600N");
3723                        return ROUTER_WRT600N;
3724                }
3725        }
3726
3727        if (nvram_match("boardtype", "0x478")
3728            && nvram_match("boot_hw_model", "WRT610N")) {
3729                setRouter("Linksys WRT610N");
3730                return ROUTER_WRT610N;
3731        }
3732#ifdef HAVE_BCMMODERN
3733        if (nvram_match("boardtype", "0x04cf")
3734            && nvram_match("boot_hw_model", "WRT610N")) {
3735                setRouter("Linksys WRT610N v2");
3736                return ROUTER_WRT610NV2;
3737        }
3738
3739        if (nvram_match("boardtype", "0x04cf")
3740            && nvram_match("boot_hw_model", "E300")) {
3741                setRouter("Linksys E3000");     // renamed wrt610nv2
3742                return ROUTER_WRT610NV2;
3743        }
3744
3745        if (boardnum == 1 && nvram_match("boardtype", "0x052b")
3746            && nvram_match("boardrev", "0x1204")) {
3747                setRouter("Linksys EA2700");    // renamed wrt610nv2
3748                return ROUTER_LINKSYS_EA2700;
3749        }
3750#endif
3751
3752        if (boardnum == 42 && nvram_match("boardtype", "bcm94710dev")) {
3753                setRouter("Linksys WRT54G v1.x");
3754                return ROUTER_WRT54G1X;
3755        }
3756
3757        if ((boardnum == 1 || boardnum == 0)
3758            && nvram_match("boardtype", "0x0446")) {
3759                setRouter("U.S.Robotics USR5430");
3760                return ROUTER_USR_5430;
3761        }
3762
3763        if (boardnum == 1 && nvram_match("boardtype", "0x456")
3764            && nvram_matchi("test_led_gpio", 0)) {
3765                setRouter("Netgear WG602 v3");
3766                return ROUTER_NETGEAR_WG602_V3;
3767        }
3768
3769        if (boardnum == 10496 && nvram_match("boardtype", "0x456")) {
3770                setRouter("U.S.Robotics USR5461");
3771                return ROUTER_USR_5461;
3772        }
3773
3774        if (boardnum == 10500 && nvram_match("boardtype", "0x456")) {
3775                setRouter("U.S.Robotics USR5432");
3776                return ROUTER_USR_5461; // should work in the same way
3777        }
3778
3779        if (boardnum == 10506 && nvram_match("boardtype", "0x456")) {
3780                setRouter("U.S.Robotics USR5451");
3781                return ROUTER_USR_5461; // should work in the same way
3782        }
3783
3784        if (boardnum == 10512 && nvram_match("boardtype", "0x456")) {
3785                setRouter("U.S.Robotics USR5441");
3786                return ROUTER_USR_5461; // should work in the same way
3787        }
3788
3789        if ((boardnum == 35324 || boardnum == 38256)
3790            && nvram_match("boardtype", "0x048e")) {
3791                setRouter("U.S.Robotics USR5465");
3792                return ROUTER_USR_5465;
3793        }
3794
3795        if (boardnum == 35334 && nvram_match("boardtype", "0x048e")) {
3796                setRouter("U.S.Robotics USR5455");
3797                return ROUTER_USR_5465; // should work in the same way
3798        }
3799
3800        if (boardnum == 1024 && nvram_match("boardtype", "0x0446")) {
3801                char *cfe = nvram_safe_get("cfe_version");
3802
3803                if (strstr(cfe, "WRE54G")) {
3804                        setRouter("Linksys WRE54G v1");
3805                        return ROUTER_WAP54G_V2;
3806                } else if (strstr(cfe, "iewsonic")) {
3807                        setRouter("Viewsonic WAPBR-100");
3808                        return ROUTER_VIEWSONIC_WAPBR_100;
3809                } else {
3810                        setRouter("Linksys WAP54G v2");
3811                        return ROUTER_WAP54G_V2;
3812                }
3813        }
3814
3815        if (nvram_invmatch("CFEver", "")) {
3816                char *cfe = nvram_safe_get("CFEver");
3817
3818                if (!strncmp(cfe, "MotoWR", 6)) {
3819                        setRouter("Motorola WR850G v2/v3");
3820                        return ROUTER_MOTOROLA;
3821                }
3822        }
3823
3824        if (boardnum == 44 && (nvram_match("boardtype", "0x0101")
3825                               || nvram_match("boardtype", "0x0101\r"))) {
3826                char *cfe = nvram_safe_get("CFEver");
3827
3828                if (!strncmp(cfe, "GW_WR110G", 9)) {
3829                        setRouter("Sparklan WX-6615GT");
3830                        return ROUTER_DELL_TRUEMOBILE_2300_V2;
3831                } else {
3832                        setRouter("Dell TrueMobile 2300 v2");
3833                        return ROUTER_DELL_TRUEMOBILE_2300_V2;
3834                }
3835        }
3836#endif
3837        if (nvram_match("boardtype", "bcm94710ap")) {
3838                setRouter("Buffalo WBR-B11");
3839                return ROUTER_BUFFALO_WBR54G;
3840        }
3841
3842        if (nvram_match("productid", "RT-AC66U")) {
3843                setRouter("Asus RT-AC66U");
3844                return ROUTER_ASUS_AC66U;
3845        }
3846
3847        if (nvram_match("boardtype", "0xF5B2")
3848            && nvram_match("boardrev", "0x1100")
3849            && nvram_matchi("pci/2/1/sb20in80and160hr5ghpo", 0)) {
3850                setRouter("Asus RT-AC66U");
3851                return ROUTER_ASUS_AC66U;
3852        }
3853
3854        if (nvram_match("boardnum", "${serno}") && nvram_match("boardtype", "0xC617") && nvram_match("boardrev", "0x1103")) {
3855                setRouter("Linksys EA6500");
3856                return ROUTER_LINKSYS_EA6500;
3857        }
3858
3859        if (nvram_match("boardtype", "0x0617") && nvram_match("boardrev", "0x1103")) {
3860                setRouter("Ubiquiti UnifiAP AC");
3861#ifdef HAVE_REGISTER
3862                return ROUTER_UBNT_UNIFIAC;
3863#else
3864                sys_reboot();
3865                exit(-1);
3866#endif
3867        }
3868
3869        if (boardnum == 24 && nvram_match("boardtype", "0x0617")
3870            && nvram_match("boardrev", "0x1102")
3871            && nvram_match("gpio7", "usbport1")) {
3872                setRouter("Dlink-DIR865L");
3873                return ROUTER_DLINK_DIR865;
3874        }
3875
3876        if (boardnum == 00 && nvram_match("boardtype", "0xf52e")
3877            && nvram_match("boardrev", "0x1204")) {
3878                if (nvram_match("product", "WLI-H4-D1300")) {
3879#ifdef HAVE_BUFFALO
3880                        setRouter("WLI-H4-D1300");
3881#else
3882                        setRouter("Buffalo WLI-H4-D1300");
3883#endif
3884                } else {
3885#ifdef HAVE_BUFFALO
3886                        setRouter("WZR-D1800H");
3887#else
3888                        setRouter("Buffalo WZR-D1800H");
3889#endif
3890                }
3891                return ROUTER_D1800H;
3892        }
3893#ifndef HAVE_BUFFALO
3894        if (boardnum == 0 && nvram_match("boardtype", "0x048e") &&      // cfe sets boardnum="", strtoul -> 0
3895            nvram_match("boardrev", "0x35")) {
3896                setRouter("D-Link DIR-320");
3897                // apply some fixes
3898                if (nvram_get("vlan2ports") != NULL) {
3899                        nvram_unset("vlan2ports");
3900                        nvram_unset("vlan2hwname");
3901                }
3902                return ROUTER_DLINK_DIR320;
3903        }
3904        if (nvram_match("model_name", "DIR-330") && nvram_match("boardrev", "0x10")) {
3905                setRouter("D-Link DIR-330");
3906                nvram_set("wan_ifnames", "eth0");       // quirk
3907                nvram_set("wan_ifname", "eth0");
3908                if (nvram_match("et0macaddr", "00:90:4c:4e:00:0c")) {
3909                        FILE *in = fopen("/dev/mtdblock/1", "rb");
3910
3911                        fseek(in, 0x7a0022, SEEK_SET);
3912                        char mac[32];
3913
3914                        fread(mac, 32, 1, in);
3915                        fclose(in);
3916                        mac[17] = 0;
3917                        if (sv_valid_hwaddr(mac)) {
3918                                nvram_set("et0macaddr", mac);
3919                                fprintf(stderr, "restore D-Link MAC\n");
3920                                nvram_commit();
3921                                sys_reboot();
3922                        }
3923                }
3924                /*
3925                 * if (nvram_get("vlan2ports")!=NULL) { nvram_unset("vlan2ports");
3926                 * nvram_unset("vlan2hwname"); }
3927                 */
3928                return ROUTER_DLINK_DIR330;
3929        }
3930        if (boardnum == 42 && nvram_match("boardtype", "0x048e")
3931            && nvram_match("boardrev", "0x10")) {
3932                if (nvram_match("boardflags", "0x20750")) {
3933                        setRouter("Linksys WRT54G2 / GS2");     // router is wrt54g2v1/v1.3/gs2v1
3934                } else {
3935                        setRouter("Linksys WRT54Gv8 / GSv7");
3936                }
3937                return ROUTER_WRT54G_V8;
3938        }
3939
3940        if (boardnum == 8 && nvram_match("boardtype", "0x048e")
3941            && nvram_match("boardrev", "0x11")) {
3942                setRouter("ALLNET EUROWRT 54"); //ALLNET01
3943                return ROUTER_ALLNET01;
3944        }
3945
3946        if (boardnum == 01 && nvram_match("boardtype", "0x048e")
3947            && nvram_match("boardrev", "0x11")
3948            && (nvram_match("boardflags", "0x650")
3949                || nvram_match("boardflags", "0x0458"))) {
3950                setRouter("Netgear WG602 v4");
3951                return ROUTER_NETGEAR_WG602_V4;
3952        }
3953
3954        if (boardnum == 1 && nvram_match("boardtype", "0x048e")
3955            && nvram_match("boardrev", "0x35")
3956            && nvram_match("parefldovoltage", "0x28")) {
3957                setRouter("NetCore NW618 / Rosewill RNX-GX4");
3958                return ROUTER_NETCORE_NW618;
3959        }
3960
3961        if (boardnum == 42 && nvram_match("boardtype", "0x048E")
3962            && nvram_match("boardrev", "0x10")) {
3963                setRouter("Linksys WRH54G");
3964                return ROUTER_LINKSYS_WRH54G;
3965        }
3966
3967        if (nvram_match("boardnum", "00") && nvram_match("boardtype", "0x048E")
3968            && nvram_match("boardrev", "0x10")) {
3969                setRouter("Linksys WRT54G v8.1");
3970                return ROUTER_WRT54G_V81;
3971        }
3972
3973        if (boardnum == 45 && nvram_match("boardtype", "0x456")) {
3974                setRouter("Asus WL-520G");
3975                return ROUTER_ASUS_WL520G;
3976        }
3977
3978        if (nvram_match("boardtype", "0x48E")
3979            && nvram_match("boardrev", "0x10")) {
3980                char *hwver = nvram_safe_get("hardware_version");
3981
3982                if (boardnum == 45 && startswith(hwver, "WL500GPV2")) {
3983                        setRouter("Asus WL-500G Premium v2");
3984                        return ROUTER_ASUS_WL500G_PRE_V2;
3985                } else if (boardnum == 45 && startswith(hwver, "WL330GE")) {
3986                        setRouter("Asus WL-330GE");
3987                        return ROUTER_ASUS_330GE;
3988                } else if (boardnum == 45 || startswith(hwver, "WL500GU")
3989                           || startswith(hwver, "WL500GC")) {
3990                        setRouter("Asus WL-520GU/GC");
3991                        return ROUTER_ASUS_WL520GUGC;
3992                }
3993        }
3994
3995        if ((boardnum == 83258 || boardnum == 1 || boardnum == 0123)    //or 01 or 001 or 0x01
3996            && (nvram_match("boardtype", "0x048e") || nvram_match("boardtype", "0x48E")) && (nvram_match("boardrev", "0x11") || nvram_match("boardrev", "0x10")) && (nvram_match("boardflags", "0x750") || nvram_match("boardflags", "0x0750")) && nvram_match("sdram_init", "0x000A")) //16 MB ram
3997        {
3998                setRouter("Netgear WGR614v8/L/WW");
3999                return ROUTER_NETGEAR_WGR614L;
4000        }
4001
4002        if (boardnum == 3805 && nvram_match("boardtype", "0x48E")
4003            && nvram_match("boardrev", "0x10")) {
4004                setRouter("Netgear WGR614v9");
4005                return ROUTER_NETGEAR_WGR614V9;
4006        }
4007
4008        if (boardnum == 56 && nvram_match("boardtype", "0x456")
4009            && nvram_match("boardrev", "0x10")) {
4010                setRouter("Linksys WTR54GS");
4011                return ROUTER_LINKSYS_WTR54GS;
4012        }
4013
4014        if (nvram_match("boardnum", "WAP54GV3_8M_0614")
4015            && (nvram_match("boardtype", "0x0467")
4016                || nvram_match("boardtype", "0x467"))
4017            && nvram_matchi("WAPver", 3)) {
4018                setRouter("Linksys WAP54G v3.x");
4019                return ROUTER_WAP54G_V3;
4020        }
4021#ifdef HAVE_BCMMODERN
4022        if (boardnum == 1 && nvram_match("boardtype", "0xE4CD")
4023            && nvram_match("boardrev", "0x1700")) {
4024                setRouter("Netgear WNR2000 v2");
4025                return ROUTER_NETGEAR_WNR2000V2;
4026        }
4027
4028        if ((boardnum == 1 || boardnum == 3500)
4029            && nvram_match("boardtype", "0x04CF")
4030            && (nvram_match("boardrev", "0x1213")
4031                || nvram_matchi("boardrev", 02))) {
4032                setRouter("Netgear WNR3500 v2/U/L v1");
4033                return ROUTER_NETGEAR_WNR3500L;
4034        }
4035
4036        if (nvram_match("boardnum", "3500L") && nvram_match("boardtype", "0x052b")) {
4037                setRouter("Netgear WNR3500L v2");
4038                return ROUTER_NETGEAR_WNR3500LV2;
4039        }
4040
4041        if (nvram_match("boardnum", "01") && nvram_match("boardtype", "0xb4cf")
4042            && nvram_match("boardrev", "0x1100")) {
4043                setRouter("Netgear WNDR3400");
4044                return ROUTER_NETGEAR_WNDR3400;
4045        }
4046
4047        if (nvram_match("boardnum", "01") && nvram_match("boardtype", "0xF52C")
4048            && nvram_match("boardrev", "0x1101")) {
4049
4050                int mtd = getMTD("board_data");
4051                char devname[32];
4052                sprintf(devname, "/dev/mtdblock/%d", mtd);
4053                FILE *model = fopen(devname, "rb");
4054                if (model) {
4055#define WNDR3700V3 "U12H194T00_NETGEAR"
4056                        char modelstr[32];
4057                        fread(modelstr, 1, strlen(WNDR3700V3), model);
4058                        if (!strncmp(modelstr, WNDR3700V3, strlen(WNDR3700V3))) {
4059                                fclose(model);
4060                                setRouter("Netgear WNDR3700v3");
4061                                return ROUTER_NETGEAR_WNDR4000;
4062                        }
4063                        fclose(model);
4064                }
4065                setRouter("Netgear WNDR4000");
4066                return ROUTER_NETGEAR_WNDR4000;
4067        }
4068
4069        if (nvram_matchi("boardnum", 4536)
4070            && nvram_match("boardtype", "0xf52e")
4071            && nvram_match("boardrev", "0x1102")) {
4072                int mtd = getMTD("board_data");
4073                char devname[32];
4074                sprintf(devname, "/dev/mtdblock/%d", mtd);
4075                FILE *model = fopen(devname, "rb");
4076                if (model) {
4077#define R6300 "U12H218T00_NETGEAR"
4078#define WNDR4500V2 "U12H224T00_NETGEAR"
4079                        char modelstr[32];
4080                        fread(modelstr, 1, strlen(R6300), model);
4081                        if (!strncmp(modelstr, R6300, strlen(R6300))) {
4082                                fclose(model);
4083                                setRouter("Netgear R6300");
4084                                return ROUTER_NETGEAR_R6300;
4085                        }
4086                        fread(modelstr, 1, strlen(R6300), model);
4087                        if (!strncmp(modelstr, WNDR4500V2, strlen(WNDR4500V2))) {
4088                                fclose(model);
4089                                setRouter("Netgear WNDR4500V2");
4090                                return ROUTER_NETGEAR_WNDR4500V2;
4091                        }
4092                        fclose(model);
4093                }
4094                setRouter("Netgear WNDR4500");
4095                return ROUTER_NETGEAR_WNDR4500;
4096        }
4097
4098        if (nvram_matchi("boardnum", 679) && nvram_match("boardtype", "0x0646")
4099            && nvram_match("boardrev", "0x1110")) {
4100                setRouter("Netgear R6250");
4101                return ROUTER_NETGEAR_R6250;
4102        }
4103
4104        if ((boardnum == 42 || boardnum == 66)
4105            && nvram_match("boardtype", "0x04EF")
4106            && (nvram_match("boardrev", "0x1304")
4107                || nvram_match("boardrev", "0x1305"))) {
4108                setRouter("Linksys WRT320N");
4109                return ROUTER_WRT320N;
4110        }
4111
4112        if (boardnum == 42 && nvram_match("boardtype", "0x04EF")
4113            && nvram_match("boardrev", "0x1307")) {
4114                setRouter("Linksys E2000");     // renamed (and fixed reset button) wrt320n
4115                return ROUTER_WRT320N;
4116        }
4117#endif
4118
4119        if (boardnum == 94703 && nvram_match("boardtype", "0x04c0")
4120            && nvram_match("boardrev", "0x1100")) {
4121                setRouter("Dynex DX-NRUTER");
4122                return ROUTER_DYNEX_DX_NRUTER;
4123        }
4124
4125        setRouter("Linksys WRT54G/GL/GS");
4126        return ROUTER_WRT54G;
4127#else
4128        eval("event", "3", "1", "15");
4129        return 0;
4130#endif
4131#endif
4132#endif
4133}
4134
4135static int router_type = -1;
4136int getRouterBrand()
4137{
4138        if (router_type == -1)
4139                router_type = internal_getRouterBrand();
4140        return router_type;
4141}
4142
4143int get_ppp_pid(char *file)
4144{
4145        char buf[80];
4146        int pid = -1;
4147
4148        if (file_to_buf(file, buf, sizeof(buf))) {
4149                char tmp[80], tmp1[80];
4150
4151                snprintf(tmp, sizeof(tmp), "/var/run/%s.pid", buf);
4152                file_to_buf(tmp, tmp1, sizeof(tmp1));
4153                pid = atoi(tmp1);
4154        }
4155        return pid;
4156}
4157
4158int check_wan_link(int num)
4159{
4160        int wan_link = 0;
4161
4162        if ((nvram_match("wan_proto", "pptp")
4163#ifdef HAVE_L2TP
4164             || nvram_match("wan_proto", "l2tp")
4165#endif
4166#ifdef HAVE_PPPOE
4167             || nvram_match("wan_proto", "pppoe")
4168#endif
4169#ifdef HAVE_PPPOEDUAL
4170             || nvram_match("wan_proto", "pppoe_dual")
4171#endif
4172#ifdef HAVE_PPPOA
4173             || nvram_match("wan_proto", "pppoa")
4174#endif
4175#ifdef HAVE_3G
4176             || (nvram_match("wan_proto", "3g") && !nvram_match("3gdata", "hso")
4177                 && !nvram_match("3gdata", "qmi"))
4178#endif
4179             || nvram_match("wan_proto", "heartbeat"))
4180            ) {
4181                FILE *fp;
4182                char filename[80];
4183                char *name;
4184
4185                if (num == 0)
4186                        strcpy(filename, "/tmp/ppp/link");
4187                if ((fp = fopen(filename, "r"))) {
4188                        int pid = -1;
4189
4190                        fclose(fp);
4191                        if (nvram_match("wan_proto", "heartbeat")) {
4192                                char buf[20];
4193
4194                                file_to_buf("/tmp/ppp/link", buf, sizeof(buf));
4195                                pid = atoi(buf);
4196                        } else
4197                                pid = get_ppp_pid(filename);
4198
4199                        name = find_name_by_proc(pid);
4200                        if (!strncmp(name, "pppoecd", 7) ||     // for PPPoE
4201                            !strncmp(name, "pppd", 4) ||        // for PPTP
4202                            !strncmp(name, "bpalogin", 8))      // for HeartBeat
4203                                wan_link = 1;   // connect
4204                        else {
4205                                printf("The %s had been died, remove %s\n", nvram_safe_get("wan_proto"), filename);
4206                                wan_link = 0;   // For some reason, the pppoed had been died,
4207                                // by link file still exist.
4208                                unlink(filename);
4209                        }
4210                }
4211        }
4212#if defined(HAVE_LIBQMI) || defined(HAVE_UQMI)
4213        else if (nvram_match("wan_proto", "3g") && nvram_match("3gdata", "qmi")) {
4214                FILE *fp = fopen("/tmp/qmistatus", "rb");
4215                int value = 0;
4216                if (fp) {
4217                        fscanf(fp, "%d", &value);
4218                        fclose(fp);
4219                }
4220#ifdef HAVE_UQMI
4221                if (value)
4222                        return 1;
4223                return 0;
4224#else
4225                if (value)
4226                        return 0;
4227                return 1;
4228#endif
4229        }
4230#endif
4231        else
4232#ifdef HAVE_IPETH
4233        if (nvram_match("wan_proto", "iphone")) {
4234                FILE *fp;
4235                if ((fp = fopen("/proc/net/dev", "r"))) {
4236                        char line[256];
4237                        while (fgets(line, sizeof(line), fp) != NULL) {
4238                                if (strstr(line, "iph0")) {
4239                                        int sock;
4240                                        struct ifreq ifr;
4241                                        if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
4242                                                break;
4243                                        memset(&ifr, 0, sizeof(struct ifreq));
4244                                        snprintf(ifr.ifr_name, IFNAMSIZ, "iph0");
4245                                        ioctl(sock, SIOCGIFFLAGS, &ifr);
4246                                        if ((ifr.ifr_flags & (IFF_RUNNING | IFF_UP))
4247                                            == (IFF_RUNNING | IFF_UP))
4248                                                wan_link = 1;
4249                                        close(sock);
4250                                        break;
4251                                }
4252                        }
4253                        fclose(fp);
4254                        if (nvram_match("wan_ipaddr", "0.0.0.0")
4255                            || nvram_match("wan_ipaddr", ""))
4256                                wan_link = 0;
4257
4258                }
4259        } else
4260#endif
4261        {
4262                if (nvram_invmatch("wan_ipaddr", "0.0.0.0"))
4263                        wan_link = 1;
4264        }
4265
4266        return wan_link;
4267}
4268
4269#ifdef HAVE_WZR450HP2
4270struct ENV_EXTDATA {
4271        unsigned char wanmac[6];        // 0x0
4272        unsigned char lanmac[6];        // 0x6
4273        unsigned char wpspin[8];        // 0xc
4274        unsigned char passphrase[25];   // 0x14, length is max <=24 followed by 0 termination
4275        unsigned char authmode[3];
4276        unsigned char crypto[3];
4277        unsigned char authmode_ex[4];
4278        unsigned char region[2];
4279        unsigned char productid[16];
4280        unsigned char bootversion[8];
4281        unsigned char hwversion;
4282        unsigned char customid;
4283        unsigned char melcoid[11];
4284        unsigned char builddate[28];
4285        unsigned char inspection;
4286};
4287
4288static char *getUEnvExt(char *name)
4289{
4290        struct ENV_EXTDATA data;
4291        FILE *fp = fopen("/dev/mtdblock5", "rb");       // board data
4292        if (!fp)
4293                return NULL;
4294
4295        fread(&data, 1, sizeof(data), fp);
4296        fclose(fp);
4297        if (!strcmp(name, "DEF-p_wireless_ath0_11bg-authmode_ex")) {
4298                if (!memcmp(data.authmode_ex, "WPA2", 4))
4299                        return "wpa2-psk";
4300                if (!memcmp(data.authmode_ex, "WPA", 3))
4301                        return "wpa-psk";
4302        }
4303        if (!strcmp(name, "DEF-p_wireless_ath0_11bg-authmode")) {
4304                if (!memcmp(data.authmode_ex, "WPA2", 4) && !memcmp(data.authmode, "PSK", 3))
4305                        return "psk2";
4306                if (!memcmp(data.authmode_ex, "WPA", 3) && !memcmp(data.authmode, "PSK", 3))
4307                        return "psk";
4308        }
4309        if (!strcmp(name, "DEF-p_wireless_ath0_11bg-wpapsk")) {
4310                static char passphrase[25];
4311                strncpy(passphrase, (char *)&data.passphrase[1], (data.passphrase[0] & 0xff));
4312                return passphrase;
4313        }
4314        if (!strcmp(name, "DEF-p_wireless_ath0_11bg-crypto")) {
4315                if (!memcmp(data.crypto, "AES", 3))
4316                        return "aes";
4317        }
4318        if (!strcmp(name, "region")) {
4319                static char region[3];
4320                region[2] = 0;
4321                memcpy(region, data.region, 2);
4322                return region;
4323        }
4324        if (!strcmp(name, "pincode")) {
4325                static char pincode[9];
4326                memcpy(pincode, data.wpspin, 8);
4327                pincode[8] = 0;
4328                return pincode;
4329        }
4330
4331        return NULL;
4332}
4333
4334#endif
4335
4336#if defined(HAVE_BUFFALO) || defined(HAVE_BUFFALO_BL_DEFAULTS) || defined(HAVE_WMBR_G300NH) || defined(HAVE_WZRG450) || defined(HAVE_DIR810L) || defined(HAVE_MVEBU) || defined(HAVE_IPQ806X) || defined(HAVE_ALPINE)
4337void *getUEnv(char *name)
4338{
4339
4340#ifdef HAVE_WZRG300NH
4341#define UOFFSET 0x40000
4342#elif HAVE_WZR450HP2
4343#define UOFFSET 0x40000
4344#elif HAVE_WZRHPAG300NH
4345#define UOFFSET 0x40000
4346#elif HAVE_WZRG450
4347#define UOFFSET 0x40000
4348#elif HAVE_WMBR_G300NH
4349#define UOFFSET 0x0
4350#elif HAVE_DIR810L
4351#define UOFFSET 0x0
4352#elif HAVE_MVEBU
4353#define UOFFSET 0x0
4354#elif HAVE_IPQ806X
4355#define UOFFSET 0x0
4356#else
4357#define UOFFSET 0x3E000
4358#endif
4359//      static char res[64];
4360        static char res[256];
4361        memset(res, 0, sizeof(res));
4362        //fprintf(stderr,"[u-boot env]%s\n",name);
4363#if defined(HAVE_WMBR_G300NH) || defined(HAVE_DIR810L)
4364        FILE *fp = fopen("/dev/mtdblock/1", "rb");
4365#elif HAVE_MVEBU
4366        FILE *fp = fopen("/dev/mtdblock/1", "rb");
4367#elif HAVE_IPQ806X
4368        int brand = getRouterBrand();
4369        FILE *fp;
4370        if (brand == ROUTER_LINKSYS_EA8500) {
4371                fp = fopen("/dev/mtdblock/10", "rb");
4372        } else {
4373                fp = fopen("/dev/mtdblock/3", "rb");
4374        }
4375#else
4376        FILE *fp = fopen("/dev/mtdblock/0", "rb");
4377#endif
4378        char newname[64];
4379        snprintf(newname, 64, "%s=", name);
4380        fseek(fp, UOFFSET, SEEK_SET);
4381        char *mem = safe_malloc(0x2000);
4382        fread(mem, 0x2000, 1, fp);
4383        fclose(fp);
4384        int s = (0x2000 - 1) - strlen(newname);
4385        int i;
4386        int l = strlen(newname);
4387        for (i = 0; i < s; i++) {
4388                if (!strncmp(mem + i, newname, l)) {
4389                        strncpy(res, mem + i + l, sizeof(res) - 1);
4390                        free(mem);
4391                        return res;
4392                }
4393        }
4394        free(mem);
4395#ifdef HAVE_WZR450HP2
4396        char *result = getUEnvExt(name);
4397        if (result)
4398                return result;
4399#endif
4400        return NULL;
4401}
4402#endif
4403
4404char *get_wan_ipaddr(void)
4405{
4406        char *wan_ipaddr;
4407        char *wan_proto = nvram_safe_get("wan_proto");
4408        int wan_link = check_wan_link(0);
4409
4410        if (!strcmp(wan_proto, "pptp")) {
4411                wan_ipaddr = wan_link ? nvram_safe_get("pptp_get_ip") : nvram_safe_get("wan_ipaddr");
4412        } else if (!strcmp(wan_proto, "pppoe")
4413#ifdef HAVE_PPPOATM
4414                   || !strcmp(wan_proto, "pppoa")
4415#endif
4416#ifdef HAVE_PPPOEDUAL
4417                   || !strcmp(wan_proto, "pppoe_dual")
4418#endif
4419#ifdef HAVE_3G
4420                   || !strcmp(wan_proto, "3g")
4421#endif
4422            ) {
4423                wan_ipaddr = wan_link ? nvram_safe_get("wan_ipaddr") : "0.0.0.0";
4424#ifdef HAVE_L2TP
4425        } else if (!strcmp(wan_proto, "l2tp")) {
4426                wan_ipaddr = wan_link ? nvram_safe_get("l2tp_get_ip") : nvram_safe_get("wan_ipaddr");
4427#endif
4428        } else {
4429                wan_ipaddr = nvram_safe_get("wan_ipaddr");
4430        }
4431
4432        if (strlen(wan_ipaddr) == 0)
4433                wan_ipaddr = "0.0.0.0";
4434
4435        return wan_ipaddr;
4436}
4437
4438/*
4439 * Find process name by pid from /proc directory
4440 */
4441char *find_name_by_proc(int pid)
4442{
4443        FILE *fp;
4444        char line[254];
4445        char filename[80];
4446        static char name[80];
4447
4448        snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
4449
4450        if ((fp = fopen(filename, "r"))) {
4451                fgets(line, sizeof(line), fp);
4452                /*
4453                 * Buffer should contain a string like "Name: binary_name"
4454                 */
4455                sscanf(line, "%*s %s", name);
4456                fclose(fp);
4457                return name;
4458        }
4459
4460        return "";
4461}
4462
4463int diag_led_4702(int type, int act)
4464{
4465
4466#if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_LAGUNA) || defined(HAVE_MAGICBOX) || defined(HAVE_RB600) || defined(HAVE_FONERA) || defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_WHRAG108) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_FONERA) || defined(HAVE_LSX) || defined(HAVE_DANUBE) || defined(HAVE_STORM) || defined(HAVE_ADM5120) || defined(HAVE_RT2880) || defined(HAVE_OPENRISC)
4467        return 0;
4468#else
4469        if (act == START_LED) {
4470                switch (type) {
4471                case DMZ:
4472                        writeprocsys("diag", "1");
4473                        break;
4474                }
4475        } else {
4476                switch (type) {
4477                case DMZ:
4478                        writeprocsys("diag", "0");
4479                        break;
4480                }
4481        }
4482        return 0;
4483#endif
4484}
4485
4486int C_led_4702(int i)
4487{
4488#if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE)  || defined(HAVE_LAGUNA) || defined(HAVE_MAGICBOX) || defined(HAVE_RB600) || defined(HAVE_FONERA) || defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_WHRAG108) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_LSX) || defined(HAVE_DANUBE) || defined(HAVE_STORM) || defined(HAVE_ADM5120) || defined(HAVE_RT2880) || defined(HAVE_OPENRISC)
4489        return 0;
4490#else
4491        FILE *fp;
4492        char string[10];
4493        int flg;
4494
4495        memset(string, 0, 10);
4496        /*
4497         * get diag before set
4498         */
4499        if ((fp = fopen("/proc/sys/diag", "r"))) {
4500                fgets(string, sizeof(string), fp);
4501                fclose(fp);
4502        } else
4503                perror("/proc/sys/diag");
4504
4505        if (i)
4506                flg = atoi(string) | 0x10;
4507        else
4508                flg = atoi(string) & 0xef;
4509
4510        memset(string, 0, 10);
4511        sprintf(string, "%d", flg);
4512        writeprocsys("diag", string);
4513
4514        return 0;
4515#endif
4516}
4517
4518unsigned int read_gpio(char *device)
4519{
4520        FILE *fp;
4521        unsigned int val;
4522
4523        if ((fp = fopen(device, "r"))) {
4524                fread(&val, 4, 1, fp);
4525                fclose(fp);
4526                // fprintf(stderr, "----- gpio %s = [%X]\n",device,val);
4527                return val;
4528        } else {
4529                perror(device);
4530                return 0;
4531        }
4532}
4533
4534unsigned int write_gpio(char *device, unsigned int val)
4535{
4536        FILE *fp;
4537
4538        if ((fp = fopen(device, "w"))) {
4539                fwrite(&val, 4, 1, fp);
4540                fclose(fp);
4541                // fprintf(stderr, "----- set gpio %s = [%X]\n",device,val);
4542                return 1;
4543        } else {
4544                perror(device);
4545                return 0;
4546        }
4547}
4548
4549int diag_led_4704(int type, int act)
4550{
4551#if defined(HAVE_IPQ806X) || defined(HAVE_MVEBU) || defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_LAGUNA) || defined(HAVE_MAGICBOX) || defined(HAVE_RB600) || defined(HAVE_FONERA) || defined(HAVE_MERAKI)|| defined(HAVE_LS2) || defined(HAVE_WHRAG108) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_LSX) || defined(HAVE_DANUBE) || defined(HAVE_STORM) || defined(HAVE_ADM5120) || defined(HAVE_RT2880) || defined(HAVE_OPENRISC) || defined(HAVE_ALPINE)
4552        return 0;
4553#else
4554        unsigned int control, in, outen, out;
4555
4556#ifdef BCM94712AGR
4557        /*
4558         * The router will crash, if we load the code into broadcom demo board.
4559         */
4560        return 1;
4561#endif
4562        static char hw_error = 0;
4563        // int brand;
4564        control = read_gpio("/dev/gpio/control");
4565        in = read_gpio("/dev/gpio/in");
4566        out = read_gpio("/dev/gpio/out");
4567        outen = read_gpio("/dev/gpio/outen");
4568
4569        write_gpio("/dev/gpio/outen", (outen & 0x7c) | 0x83);
4570        switch (type) {
4571        case DIAG:              // GPIO 1
4572                if (hw_error) {
4573                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x00);
4574                        return 1;
4575                }
4576
4577                if (act == STOP_LED) {  // stop blinking
4578                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x83);
4579                        // cprintf("tallest:=====( DIAG STOP_LED !!)=====\n");
4580                } else if (act == START_LED) {  // start blinking
4581                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x81);
4582                        // cprintf("tallest:=====( DIAG START_LED !!)=====\n");
4583                } else if (act == MALFUNCTION_LED) {    // start blinking
4584                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x00);
4585                        hw_error = 1;
4586                        // cprintf("tallest:=====( DIAG MALFUNCTION_LED !!)=====\n");
4587                }
4588                break;
4589
4590        }
4591        return 1;
4592#endif
4593}
4594
4595int diag_led_4712(int type, int act)
4596{
4597
4598#if defined(HAVE_IPQ806X) || defined(HAVE_MVEBU) || defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_LAGUNA) || defined(HAVE_MAGICBOX) || defined(HAVE_RB600) || defined(HAVE_FONERA)|| defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_WHRAG108) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_LSX) || defined(HAVE_DANUBE) || defined(HAVE_STORM) || defined(HAVE_ADM5120) || defined(HAVE_RT2880) || defined(HAVE_OPENRISC) | defined(HAVE_ALPINE)
4599        return 0;
4600#else
4601        unsigned int control, in, outen, out, ctr_mask, out_mask;
4602
4603#ifdef BCM94712AGR
4604        /*
4605         * The router will crash, if we load the code into broadcom demo board.
4606         */
4607        return 1;
4608#endif
4609        control = read_gpio("/dev/gpio/control");
4610        in = read_gpio("/dev/gpio/in");
4611        out = read_gpio("/dev/gpio/out");
4612        outen = read_gpio("/dev/gpio/outen");
4613
4614        ctr_mask = ~(1 << type);
4615        out_mask = (1 << type);
4616
4617        write_gpio("/dev/gpio/control", control & ctr_mask);
4618        write_gpio("/dev/gpio/outen", outen | out_mask);
4619
4620        if (act == STOP_LED) {  // stop blinking
4621                // cprintf("%s: Stop GPIO %d\n", __FUNCTION__, type);
4622                write_gpio("/dev/gpio/out", out | out_mask);
4623        } else if (act == START_LED) {  // start blinking
4624                // cprintf("%s: Start GPIO %d\n", __FUNCTION__, type);
4625                write_gpio("/dev/gpio/out", out & ctr_mask);
4626        }
4627
4628        return 1;
4629#endif
4630}
4631
4632int C_led_4712(int i)
4633{
4634        if (i == 1)
4635                return diag_led(DIAG, START_LED);
4636        else
4637                return diag_led(DIAG, STOP_LED);
4638}
4639
4640int C_led(int i)
4641{
4642        int brand = getRouterBrand();
4643
4644        if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
4645                return C_led_4702(i);
4646        else if (brand == ROUTER_WRT54G)
4647                return C_led_4712(i);
4648        else
4649                return 0;
4650}
4651
4652int diag_led(int type, int act)
4653{
4654        int brand = getRouterBrand();
4655
4656        if (brand == ROUTER_WRT54G || brand == ROUTER_WRT54G3G || brand == ROUTER_WRT300NV11)
4657                return diag_led_4712(type, act);
4658        else if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
4659                return diag_led_4702(type, act);
4660        else if ((brand == ROUTER_WRTSL54GS || brand == ROUTER_WRT310N || brand == ROUTER_WRT350N || brand == ROUTER_BUFFALO_WZRG144NH) && type == DIAG)
4661                return diag_led_4704(type, act);
4662        else {
4663                if (type == DMZ) {
4664                        if (act == START_LED)
4665                                return led_control(LED_DMZ, LED_ON);
4666                        if (act == STOP_LED)
4667                                return led_control(LED_DMZ, LED_OFF);
4668                        return 1;
4669                }
4670        }
4671        return 0;
4672}
4673
4674#ifdef HAVE_MADWIFI
4675static char *stalist[] = {
4676        "ath0", "ath1", "ath2", "ath3", "ath4", "ath5", "ath6", "ath8", "ath9"
4677};
4678
4679char *getWifi(char *ifname)
4680{
4681#ifdef HAVE_MVEBU
4682        if (!strncmp(ifname, "ath0", 4))
4683                return "wlan0";
4684        if (!strncmp(ifname, "ath1", 4))
4685                return "wlan1";
4686        if (!strncmp(ifname, "ath2", 4))
4687                return "wlan2";
4688        if (!strncmp(ifname, "ath3", 4))
4689                return "wlan3";
4690        return NULL;
4691#else
4692        if (!strncmp(ifname, "ath0", 4))
4693                return "wifi0";
4694        if (!strncmp(ifname, "ath1", 4))
4695                return "wifi1";
4696        if (!strncmp(ifname, "ath2", 4))
4697                return "wifi2";
4698        if (!strncmp(ifname, "ath3", 4))
4699                return "wifi3";
4700        return NULL;
4701#endif
4702}
4703
4704char *getWDSSTA(void)
4705{
4706
4707        int c = getdevicecount();
4708        int i;
4709
4710        for (i = 0; i < c; i++) {
4711                char mode[32];
4712                char netmode[32];
4713
4714                sprintf(mode, "ath%d_mode", i);
4715                sprintf(netmode, "ath%d_net_mode", i);
4716                if (nvram_match(mode, "wdssta")
4717                    && !nvram_match(netmode, "disabled")) {
4718                        return stalist[i];
4719                }
4720
4721        }
4722        return NULL;
4723}
4724
4725char *getSTA(void)
4726{
4727
4728#ifdef HAVE_WAVESAT
4729        if (nvram_match("ofdm_mode", "sta"))
4730                return "ofdm";
4731#endif
4732        int c = getdevicecount();
4733        int i;
4734
4735        for (i = 0; i < c; i++) {
4736                if (nvram_nmatch("sta", "ath%d_mode", i)
4737                    && !nvram_nmatch("disabled", "ath%d_net_mode", i)) {
4738                        return stalist[i];
4739                }
4740
4741        }
4742        return NULL;
4743}
4744
4745char *getWET(void)
4746{
4747#ifdef HAVE_WAVESAT
4748        if (nvram_match("ofdm_mode", "bridge"))
4749                return "ofdm";
4750#endif
4751        int c = getdevicecount();
4752        int i;
4753
4754        for (i = 0; i < c; i++) {
4755                if (nvram_nmatch("wet", "ath%d_mode", i)
4756                    && !nvram_nmatch("disabled", "ath%d_net_mode", i)) {
4757                        return stalist[i];
4758                }
4759
4760        }
4761        return NULL;
4762}
4763
4764#elif defined(HAVE_RT2880) || defined(HAVE_RT61)
4765
4766char *getSTA()
4767{
4768        int c = get_wl_instances();
4769        int i;
4770
4771        for (i = 0; i < c; i++) {
4772                if (nvram_nmatch("sta", "wl%d_mode", i)) {
4773                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i)) {
4774                                if (i == 0)
4775                                        return "ra0";
4776                                else
4777                                        return "ba0";
4778                        }
4779                }
4780
4781                if (nvram_nmatch("apsta", "wl%d_mode", i)) {
4782                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i)) {
4783                                if (i == 0)
4784                                        return "apcli0";
4785                                else
4786                                        return "apcli1";
4787                        }
4788                }
4789
4790        }
4791        return NULL;
4792}
4793
4794char *getWET()
4795{
4796        int c = get_wl_instances();
4797        int i;
4798
4799        for (i = 0; i < c; i++) {
4800                if (!nvram_nmatch("disabled", "wl%d_net_mode", i)
4801                    && nvram_nmatch("wet", "wl%d_mode", i))
4802                        if (i == 0)
4803                                return "ra0";
4804                        else
4805                                return "ba0";
4806
4807                if (!nvram_nmatch("disabled", "wl%d_net_mode", i)
4808                    && nvram_nmatch("apstawet", "wl%d_mode", i))
4809                        if (i == 0)
4810                                return "apcli0";
4811                        else
4812                                return "apcli1";
4813
4814        }
4815        return NULL;
4816}
4817
4818#else
4819char *getSTA()
4820{
4821        int c = get_wl_instances();
4822        int i;
4823
4824        for (i = 0; i < c; i++) {
4825                if (nvram_nmatch("sta", "wl%d_mode", i)
4826                    || nvram_nmatch("apsta", "wl%d_mode", i)) {
4827                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
4828                                return get_wl_instance_name(i);
4829                        // else
4830                        // return nvram_nget ("wl%d_ifname", i);
4831                }
4832
4833        }
4834        return NULL;
4835}
4836
4837char *getWET()
4838{
4839        int c = get_wl_instances();
4840        int i;
4841
4842        for (i = 0; i < c; i++) {
4843                if (nvram_nmatch("wet", "wl%d_mode", i)
4844                    || nvram_nmatch("apstawet", "wl%d_mode", i)) {
4845                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
4846                                return get_wl_instance_name(i);
4847                        // else
4848                        // return nvram_nget ("wl%d_ifname", i);
4849
4850                }
4851
4852        }
4853        return NULL;
4854}
4855
4856#endif
4857// note - broadcast addr returned in ipaddr
4858void get_broadcast(char *ipaddr, char *netmask)
4859{
4860        int ip2[4], mask2[4];
4861        unsigned char ip[4], mask[4];
4862
4863        if (!ipaddr || !netmask)
4864                return;
4865
4866        sscanf(ipaddr, "%d.%d.%d.%d", &ip2[0], &ip2[1], &ip2[2], &ip2[3]);
4867        sscanf(netmask, "%d.%d.%d.%d", &mask2[0], &mask2[1], &mask2[2], &mask2[3]);
4868        int i = 0;
4869
4870        for (i = 0; i < 4; i++) {
4871                ip[i] = ip2[i];
4872                mask[i] = mask2[i];
4873                // ip[i] = (ip[i] & mask[i]) | !mask[i];
4874                ip[i] = (ip[i] & mask[i]) | (0xff & ~mask[i]);
4875        }
4876
4877        sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
4878#ifdef WDS_DEBUG
4879        fprintf(fp, "get_broadcast return %s\n", value);
4880#endif
4881
4882}
4883
4884char *get_wan_face(void)
4885{
4886        static char localwanface[IFNAMSIZ];
4887        if (nvram_match("wan_proto", "disabled"))
4888                return "br0";
4889
4890        /*
4891         * if (nvram_match ("pptpd_client_enable", "1")) { strncpy (localwanface,
4892         * "ppp0", IFNAMSIZ); return localwanface; }
4893         */
4894        if (nvram_match("wan_proto", "pptp")
4895#ifdef HAVE_L2TP
4896            || nvram_match("wan_proto", "l2tp")
4897#endif
4898#ifdef HAVE_PPPOATM
4899            || nvram_match("wan_proto", "pppoa")
4900#endif
4901#ifdef HAVE_PPPOEDUAL
4902            || nvram_match("wan_proto", "pppoe_dual")
4903#endif
4904            || nvram_match("wan_proto", "pppoe")) {
4905                if (nvram_match("pppd_pppifname", ""))
4906                        strncpy(localwanface, "ppp0", IFNAMSIZ);
4907                else
4908                        strncpy(localwanface, nvram_safe_get("pppd_pppifname"), IFNAMSIZ);
4909        }
4910#ifdef HAVE_3G
4911        else if (nvram_match("wan_proto", "3g")) {
4912                if (nvram_match("3gdata", "qmi")) {
4913                        strncpy(localwanface, "wwan0", IFNAMSIZ);
4914                } else {
4915                        if (nvram_match("pppd_pppifname", ""))
4916                                strncpy(localwanface, "ppp0", IFNAMSIZ);
4917                        else
4918                                strncpy(localwanface, nvram_safe_get("pppd_pppifname"), IFNAMSIZ);
4919                }
4920
4921        }
4922#endif
4923#ifndef HAVE_MADWIFI
4924        else if (getSTA()) {
4925                strcpy(localwanface, getSTA());
4926        }
4927#else
4928        else if (getSTA()) {
4929                if (nvram_matchi("wifi_bonding", 1))
4930                        strcpy(localwanface, "bond0");
4931                else
4932                        strcpy(localwanface, getSTA());
4933        }
4934#endif
4935#ifdef HAVE_IPETH
4936        else if (nvram_match("wan_proto", "iphone")) {
4937                strncpy(localwanface, "iph0", IFNAMSIZ);
4938        }
4939#endif
4940        else
4941                strncpy(localwanface, nvram_safe_get("wan_ifname"), IFNAMSIZ);
4942
4943        return localwanface;
4944}
4945
4946int wanChanged(void)
4947{
4948        FILE *fp = fopen("/tmp/.wanchange", "rb");
4949        if (fp) {
4950                fclose(fp);
4951                unlink("/tmp/.wanchange");
4952                return 1;
4953        }
4954        return 0;
4955}
4956
4957void notifywanChange(void)
4958{
4959        FILE *fp = fopen("/tmp/.wanchange", "wb");
4960        if (fp) {
4961                fputs("change", fp);
4962                fclose(fp);
4963        }
4964}
4965
4966static int _pidof(const char *name, pid_t ** pids)
4967{
4968        const char *p;
4969        char *e;
4970        DIR *dir;
4971        struct dirent *de;
4972        pid_t i;
4973        int count;
4974        char buf[256];
4975
4976        count = 0;
4977        *pids = NULL;
4978        if ((p = strchr(name, '/')) != NULL)
4979                name = p + 1;
4980        if ((dir = opendir("/proc")) != NULL) {
4981                while ((de = readdir(dir)) != NULL) {
4982                        i = strtol(de->d_name, &e, 10);
4983                        if (*e != 0)
4984                                continue;
4985                        if (strcmp(name, psname(i, buf, sizeof(buf))) == 0) {
4986                                if ((*pids = realloc(*pids, sizeof(pid_t) * (count + 1))) == NULL) {
4987                                        return -1;
4988                                }
4989                                (*pids)[count++] = i;
4990                        }
4991                }
4992        }
4993        closedir(dir);
4994        return count;
4995}
4996
4997int pidof(const char *name)
4998{
4999        pid_t *pids;
5000        pid_t p;
5001        if (!name)
5002                return -1;
5003        if (_pidof(name, &pids) > 0) {
5004                p = *pids;
5005                free(pids);
5006                return p;
5007        }
5008        return -1;
5009}
5010
5011int killall(const char *name, int sig)
5012{
5013        pid_t *pids;
5014        int i;
5015        int r;
5016
5017        if ((i = _pidof(name, &pids)) > 0) {
5018                r = 0;
5019                do {
5020                        r |= kill(pids[--i], sig);
5021                }
5022                while (i > 0);
5023                free(pids);
5024                return r;
5025        }
5026        return -2;
5027}
5028
5029void set_ip_forward(char c)
5030{
5031        char ch[8];
5032        sprintf(ch, "%c", c);
5033        writeprocsysnet("ipv4/ip_forward", ch);
5034}
5035
5036int ifexists(const char *ifname)
5037{
5038        return getifcount(ifname) > 0 ? 1 : 0;
5039}
5040
5041int getdevicecount(void)
5042{
5043        int count = 0;
5044#ifdef HAVE_ATH9K
5045        count += getath9kdevicecount();
5046#endif
5047        count += getifcount("wifi");
5048
5049        return count;
5050}
5051
5052int getifcount(const char *ifprefix)
5053{
5054        /*
5055         * char devcall[128];
5056         *
5057         * sprintf (devcall, "cat /proc/net/dev|grep \"%s\"|wc -l", ifprefix);
5058         * FILE *in = popen (devcall, "rb"); if (in == NULL) return 0; int count;
5059         * fscanf (in, "%d", &count); pclose (in); return count;
5060         */
5061        char *iflist = calloc(256, 1);
5062
5063        int c = getIfList(iflist, ifprefix);
5064
5065        free(iflist);
5066        return c;
5067}
5068
5069static void skipline(FILE * in)
5070{
5071        while (1) {
5072                int c = getc(in);
5073
5074                if (c == EOF)
5075                        return;
5076                if (c == 0x0)
5077                        return;
5078                if (c == 0xa)
5079                        return;
5080        }
5081}
5082
5083/*
5084 * strips trailing char(s) c from string
5085 */
5086void strtrim_right(char *p, int c)
5087{
5088        char *end;
5089        int len;
5090
5091        len = strlen(p);
5092        while (*p && len) {
5093                end = p + len - 1;
5094                if (c == *end)
5095                        *end = 0;
5096                else
5097                        break;
5098                len = strlen(p);
5099        }
5100        return;
5101}
5102
5103static int gstrcmp(char *str1, char *str2)
5104{
5105        int l1 = strlen(str1);
5106        int l2 = strlen(str2);
5107        int maxlen = l1 > l2 ? l2 : l1;
5108        int i;
5109        for (i = 0; i < maxlen; i++) {
5110                if (str1[i] > str2[i])
5111                        return 1;
5112                if (str1[i] < str2[i])
5113                        return -1;
5114        }
5115        return 0;
5116}
5117
5118int getIfList(char *buffer, const char *ifprefix)
5119{
5120        return getIfListB(buffer, ifprefix, 0);
5121}
5122
5123// returns a physical interfacelist filtered by ifprefix. if ifprefix is
5124// NULL, all valid interfaces will be returned
5125int getIfListB(char *buffer, const char *ifprefix, int bridgesonly)
5126{
5127        FILE *in = fopen("/proc/net/dev", "rb");
5128        char ifname[32];
5129
5130        // skip the first 2 lines
5131        skipline(in);
5132        skipline(in);
5133        int ifcount = 0;
5134        int count = 0;
5135        char **sort = NULL;
5136        while (1) {
5137                int c = getc(in);
5138
5139                if (c == 0 || c == EOF) {
5140                        fclose(in);
5141                        goto sort;
5142                }
5143                if (c == 0x20)
5144                        continue;
5145                if (c == ':' || ifcount == 30) {
5146                        ifname[ifcount++] = 0;
5147                        int skip = 0;
5148                        if (bridgesonly && !isbridge(ifname))
5149                                skip = 1;
5150                        if (ifprefix) {
5151                                if (strncmp(ifname, ifprefix, strlen(ifprefix))) {
5152                                        skip = 1;
5153                                }
5154                        } else {
5155                                if (!strncmp(ifname, "wifi", 4))
5156                                        skip = 1;
5157                                if (!strncmp(ifname, "wlan", 4))
5158                                        skip = 1;
5159                                if (!strncmp(ifname, "ifb", 3))
5160                                        skip = 1;
5161                                if (!strncmp(ifname, "imq", 3))
5162                                        skip = 1;
5163                                if (!strncmp(ifname, "etherip", 7))
5164                                        skip = 1;
5165                                if (!strncmp(ifname, "lo", 2))
5166                                        skip = 1;
5167                                if (!strncmp(ifname, "teql", 4))
5168                                        skip = 1;
5169                                if (!strncmp(ifname, "gre", 3))
5170                                        skip = 1;
5171                                if (!strncmp(ifname, "ppp", 3))
5172                                        skip = 1;
5173                                if (!strncmp(ifname, "tun", 3))
5174                                        skip = 1;
5175                                if (!strncmp(ifname, "tap", 3))
5176                                        skip = 1;
5177                        }
5178                        if (!skip) {
5179                                if (!sort) {
5180                                        sort = malloc(sizeof(char *));
5181                                } else {
5182                                        sort = realloc(sort, sizeof(char *) * (count + 1));
5183                                }
5184                                sort[count] = malloc(strlen(ifname) + 1);
5185                                strcpy(sort[count], ifname);
5186                                count++;
5187                        }
5188                        skip = 0;
5189                        ifcount = 0;
5190                        memset(ifname, 0, 32);
5191                        skipline(in);
5192                        continue;
5193                }
5194                if (ifcount < 30)
5195                        ifname[ifcount++] = c;
5196        }
5197      sort:;
5198        int i;
5199        int a;
5200        for (a = 0; a < count; a++) {
5201                for (i = 0; i < count - 1; i++) {
5202                        if (gstrcmp(sort[i], sort[i + 1]) > 0) {
5203                                char *temp = sort[i + 1];
5204                                sort[i + 1] = sort[i];
5205                                sort[i] = temp;
5206                        }
5207                }
5208        }
5209        for (i = 0; i < count; i++) {
5210                strcat(buffer, sort[i]);
5211                strcat(buffer, " ");
5212                free(sort[i]);
5213        }
5214        if (sort)
5215                free(sort);
5216        if (count)
5217                buffer[strlen(buffer) - 1] = 0; // fixup last space
5218        return count;
5219}
5220
5221/*
5222 * Example: legal_hwaddr("00:11:22:33:44:aB"); return true;
5223 * legal_hwaddr("00:11:22:33:44:5"); return false;
5224 * legal_hwaddr("00:11:22:33:44:HH"); return false;
5225 */
5226int sv_valid_hwaddr(char *value)
5227{
5228        unsigned int hwaddr[6];
5229        int tag = TRUE;
5230        int i, count;
5231
5232        /*
5233         * Check for bad, multicast, broadcast, or null address
5234         */
5235        for (i = 0, count = 0; *(value + i); i++) {
5236                if (*(value + i) == ':') {
5237                        if ((i + 1) % 3 != 0) {
5238                                tag = FALSE;
5239                                break;
5240                        }
5241                        count++;
5242                } else if (ishexit(*(value + i)))       /* one of 0 1 2 3 4 5 6 7 8 9
5243                                                         * a b c d e f A B C D E F */
5244                        continue;
5245                else {
5246                        tag = FALSE;
5247                        break;
5248                }
5249        }
5250
5251        if (!tag || i != 17 || count != 5)      /* must have 17's characters and 5's
5252                                                 * ':' */
5253                tag = FALSE;
5254        else if (sscanf(value, "%x:%x:%x:%x:%x:%x", &hwaddr[0], &hwaddr[1], &hwaddr[2], &hwaddr[3], &hwaddr[4], &hwaddr[5]) != 6) {
5255                tag = FALSE;
5256        } else
5257                tag = TRUE;
5258#ifdef WDS_DEBUG
5259        if (tag == FALSE)
5260                fprintf(fp, "failed valid_hwaddr\n");
5261#endif
5262
5263        return tag;
5264}
5265
5266char *cpustring(void)
5267{
5268        static char buf[256];
5269#ifdef HAVE_MVEBU
5270        if (getRouterBrand() == ROUTER_WRT_1900AC) {
5271                strcpy(buf, "Marvel Armada 370/XP");
5272        } else {
5273                if (nvram_match("DD_BOARD", "Linksys WRT3200ACM"))
5274                        strcpy(buf, "Marvel Armada 395");
5275                else
5276                        strcpy(buf, "Marvel Armada 385");
5277        }
5278        return buf;
5279#elif HAVE_ALPINE
5280        strcpy(buf, "Annapurna Labs Alpine");
5281        return buf;
5282#elif HAVE_IPQ806X
5283        strcpy(buf, "QCA IPQ806X");
5284        return buf;
5285#elif HAVE_UNIWIP
5286        strcpy(buf, "FreeScale MPC8314");
5287        return buf;
5288#elif HAVE_WDR4900
5289        strcpy(buf, "FreeScale P1014");
5290        return buf;
5291#elif HAVE_RB600
5292        strcpy(buf, "FreeScale MPC8343");
5293        return buf;
5294#elif HAVE_VENTANA
5295        strcpy(buf, "FreeScale i.MX6 Quad/DualLite");
5296        return buf;
5297#elif HAVE_NORTHSTAR
5298        FILE *fp = fopen("/proc/bcm_chipinfo", "rb");
5299        if (!fp) {
5300                strcpy(buf, "Broadcom BCM470X");
5301                return buf;
5302        }
5303        int chipid;
5304        int chiprevision;
5305        int packageoption;
5306        fscanf(fp, "%*s %X\n", &chipid);
5307        fscanf(fp, "%*s %X\n", &chiprevision);
5308        fscanf(fp, "%*s %X\n", &packageoption);
5309        fclose(fp);
5310        if (chipid == 53030 || chipid == 53010 || chipid == 53011 || chipid == 53012 || chipid == 53018 || chipid == 53019) {   // 53030
5311                if (packageoption == 0)
5312                        strcpy(buf, "Broadcom BCM4709");
5313                if (packageoption == 1)
5314                        strcpy(buf, "Broadcom BCM4707");
5315                if (packageoption == 2)
5316                        strcpy(buf, "Broadcom BCM4708");
5317        } else if (chipid == 53573) {
5318                strcpy(buf, "Broadcom BCM47189");
5319        } else
5320                strcpy(buf, "Broadcom BCM470X");
5321
5322        return buf;
5323#else
5324        FILE *fcpu = fopen("/proc/cpuinfo", "r");
5325
5326        if (fcpu == NULL) {
5327                return NULL;
5328        }
5329        int i;
5330
5331#ifdef HAVE_MAGICBOX
5332        int cnt = 0;
5333#endif
5334#ifdef HAVE_X86
5335        int cnt = 0;
5336#endif
5337        for (i = 0; i < 256; i++) {
5338                int c = getc(fcpu);
5339
5340                if (c == EOF) {
5341                        fclose(fcpu);
5342                        return NULL;
5343                }
5344                if (c == ':')
5345#ifdef HAVE_MAGICBOX
5346                        cnt++;
5347                if (cnt == 2)
5348                        break;
5349#elif HAVE_X86
5350                        cnt++;
5351                if (cnt == 5)
5352                        break;
5353#else
5354                        break;
5355#endif
5356        }
5357        getc(fcpu);
5358        for (i = 0; i < 256; i++) {
5359                int c = getc(fcpu);
5360
5361                if (c == EOF) {
5362                        fclose(fcpu);
5363                        return NULL;
5364                }
5365                if (c == 0xa || c == 0xd)
5366                        break;
5367                buf[i] = c;
5368        }
5369        buf[i] = 0;
5370        fclose(fcpu);
5371        return buf;
5372#endif
5373}
5374
5375#if defined(HAVE_MADWIFI_MIMO) || defined(HAVE_ATH9K)
5376
5377int isap8x(void)
5378{
5379#define CPUSTR "Atheros AR91"
5380        char *str = cpustring();
5381        if (str && !strncmp(str, CPUSTR, 12))
5382                return 1;
5383        else
5384                return 0;
5385#undef CPUSTR
5386
5387}
5388
5389#endif
5390
5391int led_control(int type, int act)
5392/*
5393 * type: LED_POWER, LED_DIAG, LED_DMZ, LED_CONNECTED, LED_BRIDGE, LED_VPN,
5394 * LED_SES, LED_SES2, LED_WLAN0, LED_WLAN1, LED_WLAN2, LED_SEC0, LED_SEC1, USB_POWER, USB_POWER1
5395 * act: LED_ON, LED_OFF, LED_FLASH
5396 * 1st hex number: 1 = inverted, 0 = normal
5397 */
5398{
5399#if (defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_MAGICBOX)  || (defined(HAVE_RB600) && !defined(HAVE_WDR4900)) || defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_LS5))  && (!defined(HAVE_DIR300) && !defined(HAVE_WRT54G2) && !defined(HAVE_RTG32) && !defined(HAVE_DIR400) && !defined(HAVE_BWRG1000))
5400        return 0;
5401#else
5402        int use_gpio = 0x0ff;
5403        int gpio_value;
5404        int enable;
5405        int disable;
5406
5407        int power_gpio = 0x0ff;
5408        int beeper_gpio = 0x0ff;
5409        int diag_gpio = 0x0ff;
5410        int diag_gpio_disabled = 0x0ff;
5411        int dmz_gpio = 0x0ff;
5412        int connected_gpio = 0x0ff;
5413        int disconnected_gpio = 0x0ff;
5414        int bridge_gpio = 0x0ff;
5415        int vpn_gpio = 0x0ff;
5416        int ses_gpio = 0x0ff;   // use for SES1 (Linksys), AOSS (Buffalo)
5417        int ses2_gpio = 0x0ff;
5418        int wlan_gpio = 0x0ff;  // wlan button led R7000
5419        int wlan0_gpio = 0x0ff; // use this only if wlan led is not controlled by hardware!
5420        int wlan1_gpio = 0x0ff;
5421        int wlan2_gpio = 0x0ff;
5422        int usb_gpio = 0x0ff;
5423        int usb_gpio1 = 0x0ff;
5424        int sec0_gpio = 0x0ff;  // security leds, wrt600n
5425        int sec1_gpio = 0x0ff;
5426        int usb_power = 0x0ff;
5427        int usb_power1 = 0x0ff;
5428        int v1func = 0;
5429        int connblue = nvram_matchi("connblue", 1) ? 1 : 0;
5430
5431        switch (getRouterBrand())       // gpio definitions here: 0xYZ,
5432                // Y=0:normal, Y=1:inverted, Z:gpio
5433                // number (f=disabled)
5434        {
5435#ifndef HAVE_BUFFALO
5436        case ROUTER_BOARD_TECHNAXX3G:
5437                usb_gpio = 0x109;
5438                diag_gpio = 0x10c;
5439                connected_gpio = 0x10b;
5440                ses_gpio = 0x10c;
5441                break;
5442#ifdef HAVE_WPE72
5443        case ROUTER_BOARD_NS5M:
5444                diag_gpio = 0x10d;
5445                break;
5446#endif
5447        case ROUTER_BOARD_UNIFI:
5448                ses_gpio = 0x001;
5449                sec0_gpio = 0x001;
5450                break;
5451        case ROUTER_UBNT_UAPAC:
5452                ses_gpio = 0x007;
5453                sec0_gpio = 0x007;
5454                break;
5455        case ROUTER_BOARD_AIRROUTER:
5456                power_gpio = 0x10b;
5457                diag_gpio = 0x00b;
5458                connected_gpio = 0x100;
5459                break;
5460        case ROUTER_BOARD_DANUBE:
5461#ifdef HAVE_WMBR_G300NH
5462                diag_gpio = 0x105;
5463                ses_gpio = 0x10e;
5464                sec0_gpio = 0x10e;
5465                connected_gpio = 0x111;
5466                disconnected_gpio = 0x112;
5467                power_gpio = 0x101;
5468#endif
5469#ifdef HAVE_SX763
5470//              diag_gpio = 0x105;
5471//              ses_gpio = 0x10e;
5472//              sec0_gpio = 0x10e;
5473                connected_gpio = 0x1de;
5474//              disconnected_gpio = 0x112;
5475//              power_gpio = 0x101;
5476#endif
5477                break;
5478#ifdef HAVE_UNIWIP
5479        case ROUTER_BOARD_UNIWIP:
5480                break;
5481#endif
5482#ifdef HAVE_WDR4900
5483        case ROUTER_BOARD_WDR4900:
5484                diag_gpio = 0x000;
5485                usb_gpio = 0x001;
5486                usb_gpio1 = 0x002;
5487                usb_power = 0x103;
5488                break;
5489#endif
5490#ifdef HAVE_WRT1900AC
5491        case ROUTER_WRT_1200AC:
5492        case ROUTER_WRT_1900ACS:
5493        case ROUTER_WRT_1900ACV2:
5494                usb_power = 0x032;
5495        case ROUTER_WRT_1900AC:
5496                power_gpio = 0x000;
5497                diag_gpio = 0x100;
5498                connected_gpio = 0x006;
5499                disconnected_gpio = 0x007;
5500                usb_gpio = 0x004;
5501                usb_gpio1 = 0x005;
5502                ses_gpio = 0x009;
5503                break;
5504#endif
5505        case ROUTER_BOARD_PB42:
5506#ifdef HAVE_WA901
5507                diag_gpio = 0x102;
5508                ses_gpio = 0x004;
5509//              usb_gpio = 0x101;
5510#elif  HAVE_WR941
5511                diag_gpio = 0x102;
5512                ses_gpio = 0x005;
5513//              usb_gpio = 0x101;
5514#endif
5515#ifdef HAVE_MR3020
5516                connected_gpio = 0x11b;
5517                diag_gpio = 0x11a;
5518                usb_power = 0x008;
5519#elif HAVE_GL150
5520//              power_gpio = 0x11b;
5521//              diag_gpio = 0x01b;
5522//              usb_power = 0x008;
5523#elif HAVE_WR710
5524                power_gpio = 0x11b;
5525                diag_gpio = 0x01b;
5526#elif HAVE_WA701V2
5527                diag_gpio = 0x11b;
5528                ses_gpio = 0x001;
5529                sec0_gpio = 0x001;
5530#elif HAVE_WR703
5531                diag_gpio = 0x11b;
5532                ses_gpio = 0x001;
5533                sec0_gpio = 0x001;
5534                usb_power = 0x008;
5535#elif HAVE_WR842
5536                diag_gpio = 0x101;
5537                ses_gpio = 0x000;
5538                usb_power = 0x006;
5539
5540#elif HAVE_WR741V4
5541                diag_gpio = 0x11b;
5542                ses_gpio = 0x001;
5543                sec0_gpio = 0x001;
5544
5545#elif HAVE_MR3420
5546                diag_gpio = 0x101;
5547                connected_gpio = 0x108;
5548                usb_power = 0x006;
5549#elif HAVE_WR741
5550                diag_gpio = 0x101;
5551                ses_gpio = 0x000;
5552//              usb_gpio = 0x101;
5553#endif
5554#ifdef HAVE_WR1043
5555                diag_gpio = 0x102;
5556                ses_gpio = 0x005;
5557//              usb_gpio = 0x101;
5558#endif
5559#ifdef HAVE_WRT160NL
5560                power_gpio = 0x10e;
5561                connected_gpio = 0x109;
5562                ses_gpio = 0x108;
5563#endif
5564#ifdef HAVE_TG2521
5565                ses_gpio = 0x103;
5566                diag_gpio = 0x103;
5567                usb_power = 0x105;
5568#endif
5569#ifdef HAVE_TEW632BRP
5570                diag_gpio = 0x101;
5571                ses_gpio = 0x103;
5572#endif
5573#ifdef HAVE_WP543
5574                diag_gpio = 0x107;
5575                connected_gpio = 0x106;
5576#endif
5577#ifdef HAVE_WP546
5578                beeper_gpio = 0x001;
5579                diag_gpio = 0x107;
5580                connected_gpio = 0x106;
5581#endif
5582#ifdef HAVE_DIR825
5583                power_gpio = 0x102;
5584                diag_gpio = 0x101;
5585                connected_gpio = 0x10b;
5586                disconnected_gpio = 0x106;
5587                ses_gpio = 0x104;
5588                usb_gpio = 0x100;
5589//              wlan0_gpio = 0x0ff; //correct states missing
5590#endif
5591#ifdef HAVE_WNDR3700
5592                power_gpio = 0x102;
5593                diag_gpio = 0x101;
5594                connected_gpio = 0x106;
5595                ses_gpio = 0x104;
5596#endif
5597#ifdef HAVE_WZRG300NH
5598                diag_gpio = 0x101;
5599                connected_gpio = 0x112;
5600                ses_gpio = 0x111;
5601                sec0_gpio = 0x111;
5602#endif
5603#ifdef HAVE_DIR632
5604                power_gpio = 0x001;
5605                diag_gpio = 0x100;
5606                connected_gpio = 0x111;
5607                usb_gpio = 0x10b;
5608#endif
5609#ifdef HAVE_WZRG450
5610                diag_gpio = 0x10e;
5611                ses_gpio = 0x10d;
5612                sec0_gpio = 0x10d;
5613                usb_power = 0x010;
5614                connected_gpio = 0x12e; // card 1, gpio 14
5615#endif
5616#ifdef HAVE_WZRG300NH2
5617                diag_gpio = 0x110;
5618                ses_gpio = 0x126;       // card 1, gpio 6
5619                sec0_gpio = 0x126;
5620                usb_power = 0x00d;
5621                connected_gpio = 0x127; // card 1, gpio 7
5622#endif
5623#ifdef HAVE_WZRHPAG300NH
5624                diag_gpio = 0x101;
5625                connected_gpio = 0x133; // card 2 gpio 3
5626                sec0_gpio = 0x125;
5627                sec1_gpio = 0x131;
5628                ses_gpio = 0x125;       // card 1 gpio 5
5629                ses2_gpio = 0x131;      // card 2 gpio 5
5630                usb_power = 0x002;
5631#endif
5632#ifdef HAVE_DIR615C1
5633                power_gpio = 0x104;
5634                wlan0_gpio = 0x10f;
5635#endif
5636#ifdef HAVE_DIR615E
5637                power_gpio = 0x006;
5638                diag_gpio = 0x001;
5639                connected_gpio = 0x111;
5640                disconnected_gpio = 0x007;
5641                ses_gpio = 0x100;
5642#endif
5643#ifdef HAVE_DAP2230
5644                diag_gpio = 0x00b;
5645                power_gpio = 0x10b;
5646#elif HAVE_WR941V6
5647                disconnected_gpio = 0x00f;
5648                power_gpio = 0x112;
5649                diag_gpio = 0x012;
5650
5651#elif HAVE_WR841V12
5652                power_gpio = 0x101;
5653                diag_gpio = 0x001;
5654                ses_gpio = 0x103;
5655                sec0_gpio = 0x103;
5656                connected_gpio = 0x102;
5657#elif HAVE_WR841V11
5658                power_gpio = 0x101;
5659                diag_gpio = 0x001;
5660                ses_gpio = 0x103;
5661                sec0_gpio = 0x103;
5662                connected_gpio = 0x102;
5663#elif HAVE_WR841V9
5664                diag_gpio = 0x103;
5665#elif HAVE_WR842V2
5666                connected_gpio = 0x10e;
5667                usb_power = 0x204;
5668                usb_gpio = 0x10f;
5669#elif HAVE_WR841V8
5670                diag_gpio = 0x10f;
5671                connected_gpio = 0x10e;
5672#elif HAVE_DIR615I
5673                power_gpio = 0x00e;
5674                diag_gpio = 0x10f;
5675                connected_gpio = 0x10c;
5676                disconnected_gpio = 0x016;
5677#endif
5678#ifdef HAVE_WRT400
5679                power_gpio = 0x001;
5680                diag_gpio = 0x105;
5681                ses_gpio = 0x104;
5682                connected_gpio = 0x007;
5683#endif
5684#ifdef HAVE_ALFAAP94
5685                power_gpio = 0x005;
5686#endif
5687                break;
5688        case ROUTER_ALLNET01:
5689                connected_gpio = 0x100;
5690                break;
5691        case ROUTER_BOARD_WP54G:
5692                diag_gpio = 0x102;
5693                connected_gpio = 0x107;
5694                break;
5695        case ROUTER_BOARD_NP28G:
5696                diag_gpio = 0x102;
5697                connected_gpio = 0x106;
5698                break;
5699        case ROUTER_BOARD_GATEWORX_GW2369:
5700                connected_gpio = 0x102;
5701                break;
5702        case ROUTER_BOARD_GW2388:
5703        case ROUTER_BOARD_GW2380:
5704#ifdef HAVE_VENTANA
5705                power_gpio = 0x166;
5706                diag_gpio = 0x06F;
5707                connected_gpio = 0x066;
5708                disconnected_gpio = 0x067;
5709#else
5710                connected_gpio = 0x110; // 16 is mapped to front led
5711#endif
5712                break;
5713        case ROUTER_BOARD_GATEWORX:
5714#ifdef HAVE_WG302V1
5715                diag_gpio = 0x104;
5716                wlan0_gpio = 0x105;
5717#elif HAVE_WG302
5718                diag_gpio = 0x102;
5719                wlan0_gpio = 0x104;
5720#else
5721                if (nvram_match("DD_BOARD", "Gateworks Cambria GW2350")
5722                    || nvram_match("DD_BOARD2", "Gateworks Cambria GW2350"))
5723                        connected_gpio = 0x105;
5724                else if (nvram_match("DD_BOARD", "Gateworks Cambria GW2358-4")
5725                         || nvram_match("DD_BOARD2", "Gateworks Cambria GW2358-4"))
5726                        connected_gpio = 0x118;
5727                else
5728                        connected_gpio = 0x003;
5729#endif
5730                break;
5731        case ROUTER_BOARD_GATEWORX_SWAP:
5732                connected_gpio = 0x004;
5733                break;
5734        case ROUTER_BOARD_STORM:
5735                connected_gpio = 0x005;
5736                diag_gpio = 0x003;
5737                break;
5738        case ROUTER_LINKSYS_WRH54G:
5739                diag_gpio = 0x101;      // power led blink / off to indicate factory
5740                // defaults
5741                break;
5742        case ROUTER_WRT54G:
5743        case ROUTER_WRT54G_V8:
5744                power_gpio = 0x001;
5745                dmz_gpio = 0x107;
5746                connected_gpio = 0x103; // ses orange
5747                ses_gpio = 0x102;       // ses white
5748                ses2_gpio = 0x103;      // ses orange
5749                break;
5750        case ROUTER_WRT54G_V81:
5751                power_gpio = 0x101;
5752                dmz_gpio = 0x102;
5753                connected_gpio = 0x104; // ses orange
5754                ses_gpio = 0x103;       // ses white
5755                ses2_gpio = 0x104;      // ses orange
5756                break;
5757        case ROUTER_WRT54G1X:
5758                connected_gpio = 0x103;
5759                v1func = 1;
5760                break;
5761        case ROUTER_WRT350N:
5762                connected_gpio = 0x103;
5763                power_gpio = 0x001;
5764                ses2_gpio = 0x103;      // ses orange
5765                sec0_gpio = 0x109;
5766                usb_gpio = 0x10b;
5767                break;
5768        case ROUTER_WRT600N:
5769                power_gpio = 0x102;
5770                diag_gpio = 0x002;
5771                usb_gpio = 0x103;
5772                sec0_gpio = 0x109;
5773                sec1_gpio = 0x10b;
5774                break;
5775        case ROUTER_LINKSYS_WRT55AG:
5776                connected_gpio = 0x103;
5777                break;
5778        case ROUTER_DLINK_DIR330:
5779                diag_gpio = 0x106;
5780                connected_gpio = 0x100;
5781                usb_gpio = 0x104;
5782                break;
5783        case ROUTER_ASUS_RTN10PLUS:
5784//              diag_gpio = 0x10d;
5785//              connected_gpio = 0x108;
5786//              power_gpio = 0x109;
5787                break;
5788        case ROUTER_BOARD_DIR600B:
5789                diag_gpio = 0x10d;
5790                connected_gpio = 0x108;
5791                power_gpio = 0x109;
5792                break;
5793        case ROUTER_BOARD_DIR615D:
5794#ifdef HAVE_DIR615H
5795                diag_gpio = 0x007;
5796                connected_gpio = 0x10d;
5797                disconnected_gpio = 0x10c;
5798                ses_gpio = 0x10e;
5799                power_gpio = 0x009;
5800#else
5801                diag_gpio = 0x108;
5802                connected_gpio = 0x10c;
5803                disconnected_gpio = 0x10e;
5804                ses_gpio = 0x10b;
5805                power_gpio = 0x109;
5806#endif
5807                break;
5808        case ROUTER_BOARD_W502U:
5809                connected_gpio = 0x10d;
5810                break;
5811        case ROUTER_BOARD_OPENRISC:
5812#ifndef HAVE_ERC
5813// ERC: diag button is used different / wlan button is handled by a script
5814                diag_gpio = 0x003;
5815                ses_gpio = 0x005;
5816#endif
5817                break;
5818        case ROUTER_BOARD_WR5422:
5819                ses_gpio = 0x10d;
5820                break;
5821        case ROUTER_BOARD_F5D8235:
5822                usb_gpio = 0x117;
5823                diag_gpio = 0x109;
5824                disconnected_gpio = 0x106;
5825                connected_gpio = 0x105;
5826                ses_gpio = 0x10c;
5827                break;
5828#else
5829        case ROUTER_BOARD_DANUBE:
5830#ifdef HAVE_WMBR_G300NH
5831                diag_gpio = 0x105;
5832                ses_gpio = 0x10e;
5833                sec0_gpio = 0x10e;
5834                connected_gpio = 0x111;
5835                disconnected_gpio = 0x112;
5836                power_gpio = 0x101;
5837#endif
5838                break;
5839        case ROUTER_BOARD_PB42:
5840#ifdef HAVE_WZRG300NH
5841                diag_gpio = 0x101;
5842                connected_gpio = 0x112;
5843                ses_gpio = 0x111;
5844                sec0_gpio = 0x111;
5845#endif
5846#ifdef HAVE_WZRHPAG300NH
5847                diag_gpio = 0x101;
5848                connected_gpio = 0x133;
5849                ses_gpio = 0x125;
5850                ses2_gpio = 0x131;
5851                sec0_gpio = 0x125;
5852                sec1_gpio = 0x131;
5853                usb_power = 0x002;
5854#endif
5855#ifdef HAVE_WZRG450
5856                diag_gpio = 0x10e;
5857                ses_gpio = 0x10d;
5858                sec0_gpio = 0x10d;
5859                usb_power = 0x010;
5860                connected_gpio = 0x12e; // card 1, gpio 14
5861#endif
5862#ifdef HAVE_WZRG300NH2
5863                diag_gpio = 0x110;
5864                ses_gpio = 0x126;
5865                sec0_gpio = 0x126;
5866                usb_power = 0x00d;
5867                connected_gpio = 0x127;
5868#endif
5869                break;
5870#endif
5871        case ROUTER_BOARD_HAMEA15:
5872                diag_gpio = 0x111;
5873                connected_gpio = 0x114;
5874//              ses_gpio = 0x10e;
5875                break;
5876        case ROUTER_BOARD_WCRGN:
5877                diag_gpio = 0x107;
5878                connected_gpio = 0x10b;
5879//              ses_gpio = 0x10e;
5880                break;
5881        case ROUTER_DIR860LB1:
5882                power_gpio = 0x10f;
5883                diag_gpio = 0x10d;
5884                diag_gpio_disabled = 0x10f;
5885                disconnected_gpio = 0x10e;
5886                connected_gpio = 0x110;
5887                break;
5888        case ROUTER_DIR810L:
5889                power_gpio = 0x009;
5890                diag_gpio = 0x00d;
5891                diag_gpio_disabled = 0x009;
5892                connected_gpio = 0x128;
5893                disconnected_gpio = 0x00c;
5894                break;
5895        case ROUTER_WHR300HP2:
5896                power_gpio = 0x109;
5897                diag_gpio = 0x107;
5898                diag_gpio_disabled = 0x109;
5899                wlan0_gpio = 0x108;
5900                sec0_gpio = 0x10a;
5901                ses_gpio = 0x10a;
5902                connected_gpio = 0x139;
5903                disconnected_gpio = 0x13b;
5904                break;
5905        case ROUTER_BOARD_WHRG300N:
5906                diag_gpio = 0x107;
5907                connected_gpio = 0x109;
5908                ses_gpio = 0x10e;
5909                break;
5910#ifdef HAVE_WNR2200
5911        case ROUTER_BOARD_WHRHPGN:
5912                power_gpio = 0x122;
5913                diag_gpio = 0x121;
5914                connected_gpio = 0x107;
5915                usb_power = 0x024;      // enable usb port
5916                ses_gpio = 0x105;       //correct state missing
5917                usb_gpio = 0x108;
5918//              sec0_gpio = 0x104;
5919                break;
5920#elif HAVE_WNR2000
5921        case ROUTER_BOARD_WHRHPGN:
5922                power_gpio = 0x123;
5923                diag_gpio = 0x122;
5924                connected_gpio = 0x100;
5925//              ses_gpio = 0x104;
5926//              sec0_gpio = 0x104;
5927                break;
5928#elif HAVE_WLAEAG300N
5929        case ROUTER_BOARD_WHRHPGN:
5930                power_gpio = 0x110;
5931                diag_gpio = 0x111;
5932                connected_gpio = 0x106;
5933                ses_gpio = 0x10e;
5934                sec0_gpio = 0x10e;
5935                break;
5936#elif HAVE_CARAMBOLA
5937#ifdef HAVE_ERC
5938        case ROUTER_BOARD_WHRHPGN:
5939                vpn_gpio = 0x11B;
5940                wlan0_gpio = 0x000;
5941                break;
5942#else
5943        case ROUTER_BOARD_WHRHPGN:
5944//              usb_power = 0x01a;
5945//              usb_gpio = 0x001;
5946//              ses_gpio = 0x11b;
5947                break;
5948#endif
5949#elif HAVE_HORNET
5950        case ROUTER_BOARD_WHRHPGN:
5951                usb_power = 0x01a;
5952                usb_gpio = 0x001;
5953                ses_gpio = 0x11b;
5954                break;
5955#elif HAVE_RB2011
5956        case ROUTER_BOARD_WHRHPGN:
5957//              diag_gpio = 0x10f;
5958//              connected_gpio = 0x112;
5959//              disconnected_gpio = 0x113;
5960//              power_gpio = 0x10e;
5961//              usb_power = 0x01a;
5962//              usb_gpio = 0x10b;
5963//              ses_gpio = 0x11b;
5964                break;
5965#elif HAVE_WDR3500
5966        case ROUTER_BOARD_WHRHPGN:
5967                usb_gpio = 0x10b;
5968                usb_power = 0x00f;
5969                diag_gpio = 0x10e;
5970                connected_gpio = 0x10f;
5971                break;
5972#elif HAVE_WDR4300
5973        case ROUTER_BOARD_WHRHPGN:
5974                usb_gpio = 0x10b;
5975                usb_gpio1 = 0x10c;
5976                usb_power = 0x015;
5977                usb_power1 = 0x016;
5978                diag_gpio = 0x10e;
5979                connected_gpio = 0x10f;
5980                break;
5981#elif HAVE_WNDR3700V4
5982        case ROUTER_BOARD_WHRHPGN:
5983                diag_gpio = 0x102;
5984                power_gpio = 0x100;
5985                connected_gpio = 0x101;
5986                disconnected_gpio = 0x103;
5987                usb_power = 0x020;
5988                usb_gpio = 0x10d;
5989                ses_gpio = 0x110;
5990                break;
5991#elif HAVE_DAP3662
5992        case ROUTER_BOARD_WHRHPGN:
5993                diag_gpio = 0x10e;      // red
5994                diag_gpio_disabled = 0x117;     //
5995                power_gpio = 0x117;     // green
5996                break;
5997#elif HAVE_DIR862
5998        case ROUTER_BOARD_WHRHPGN:
5999                diag_gpio = 0x10e;      // orange
6000                diag_gpio_disabled = 0x113;     //
6001                power_gpio = 0x113;     // green
6002                connected_gpio = 0x116; // green
6003                disconnected_gpio = 0x117;      // orange
6004                break;
6005#elif HAVE_MMS344
6006        case ROUTER_BOARD_WHRHPGN:
6007                diag_gpio = 0x10e;
6008                break;
6009#elif HAVE_ARCHERC7
6010        case ROUTER_BOARD_WHRHPGN:
6011                diag_gpio = 0x10e;
6012                ses_gpio = 0x10f;
6013                sec0_gpio = 0x10f;
6014
6015                usb_power = 0x016;
6016                usb_gpio = 0x112;
6017
6018                usb_power1 = 0x015;
6019                usb_gpio1 = 0x113;
6020
6021                usb_gpio = 0x10f;
6022                break;
6023#elif HAVE_WR1043V2
6024        case ROUTER_BOARD_WHRHPGN:
6025                diag_gpio = 0x113;
6026//              connected_gpio = 0x112;
6027//              disconnected_gpio = 0x113;
6028//              power_gpio = 0x10e;
6029                usb_power = 0x015;
6030                usb_gpio = 0x10f;
6031                ses_gpio = 0x112;
6032                sec0_gpio = 0x112;
6033                break;
6034#elif HAVE_WZR450HP2
6035        case ROUTER_BOARD_WHRHPGN:
6036                diag_gpio = 0x114;
6037//              connected_gpio = 0x112;
6038//              disconnected_gpio = 0x113;
6039//              power_gpio = 0x10e;
6040//              usb_power = 0x01a;
6041//              usb_gpio = 0x10b;
6042
6043                connected_gpio = 0x10d;
6044                power_gpio = 0x113;
6045                ses_gpio = 0x103;
6046                sec0_gpio = 0x103;
6047                break;
6048#elif HAVE_DHP1565
6049        case ROUTER_BOARD_WHRHPGN:
6050                diag_gpio = 0x10e;
6051                diag_gpio_disabled = 0x116;
6052                connected_gpio = 0x112;
6053                disconnected_gpio = 0x113;
6054                power_gpio = 0x116;
6055                usb_gpio = 0x10b;
6056                ses_gpio = 0x10f;
6057                break;
6058#elif HAVE_E325N
6059        case ROUTER_BOARD_WHRHPGN:
6060                connected_gpio = 0x003;
6061                disconnected_gpio = 0x002;
6062                break;
6063#elif HAVE_XD3200
6064        case ROUTER_BOARD_WHRHPGN:
6065                break;
6066#elif HAVE_E380AC
6067        case ROUTER_BOARD_WHRHPGN:
6068                diag_gpio = 0x003;
6069                break;
6070#elif HAVE_WR615N
6071        case ROUTER_BOARD_WHRHPGN:
6072                diag_gpio = 0x101;
6073                connected_gpio = 0x102;
6074                disconnected_gpio = 0x103;
6075                ses_gpio = 0x10c;
6076                sec0_gpio = 0x10c;
6077                break;
6078#elif HAVE_E355AC
6079        case ROUTER_BOARD_WHRHPGN:
6080                diag_gpio = 0x002;
6081                break;
6082#elif HAVE_WR650AC
6083        case ROUTER_BOARD_WHRHPGN:
6084                ses_gpio = 0x114;
6085                sec0_gpio = 0x114;
6086                connected_gpio = 0x104;
6087                diag_gpio = 0x004;
6088                break;
6089#elif HAVE_DIR869
6090        case ROUTER_BOARD_WHRHPGN:
6091                disconnected_gpio = 0x10f;
6092                connected_gpio = 0x110;
6093                diag_gpio = 0x00f;
6094                break;
6095#elif HAVE_DIR859
6096        case ROUTER_BOARD_WHRHPGN:
6097                power_gpio = 0x10f;
6098                connected_gpio = 0x110;
6099                diag_gpio = 0x00f;
6100                break;
6101#elif HAVE_JWAP606
6102        case ROUTER_BOARD_WHRHPGN:
6103                diag_gpio = 0x10b;
6104                connected_gpio = 0x10d;
6105                disconnected_gpio = 0x10d;
6106                power_gpio = 0x10b;
6107//              usb_power = 0x01a;
6108//              usb_gpio = 0x10b;
6109//              ses_gpio = 0x11b;
6110                break;
6111#elif HAVE_DIR825C1
6112        case ROUTER_BOARD_WHRHPGN:
6113                diag_gpio = 0x10f;
6114                connected_gpio = 0x112;
6115                disconnected_gpio = 0x113;
6116                power_gpio = 0x10e;
6117//              usb_power = 0x01a;
6118                usb_gpio = 0x10b;
6119//              ses_gpio = 0x11b;
6120                break;
6121#elif HAVE_WDR2543
6122        case ROUTER_BOARD_WHRHPGN:
6123                diag_gpio = 0x100;
6124                usb_gpio = 0x108;
6125                break;
6126#elif HAVE_WASP
6127        case ROUTER_BOARD_WHRHPGN:
6128//              usb_power = 0x01a;
6129//              usb_gpio = 0x001;
6130//              ses_gpio = 0x11b;
6131                break;
6132#else
6133        case ROUTER_BOARD_WHRHPGN:
6134                diag_gpio = 0x101;
6135                connected_gpio = 0x106;
6136                ses_gpio = 0x100;
6137                sec0_gpio = 0x100;
6138                break;
6139#endif
6140        case ROUTER_BUFFALO_WBR54G:
6141                diag_gpio = 0x107;
6142                break;
6143        case ROUTER_BUFFALO_WBR2G54S:
6144                diag_gpio = 0x001;
6145                ses_gpio = 0x006;
6146                break;
6147        case ROUTER_BUFFALO_WLA2G54C:
6148                diag_gpio = 0x104;
6149                ses_gpio = 0x103;
6150                break;
6151        case ROUTER_BUFFALO_WLAH_G54:
6152                diag_gpio = 0x107;
6153                ses_gpio = 0x106;
6154                break;
6155        case ROUTER_BUFFALO_WAPM_HP_AM54G54:
6156                diag_gpio = 0x107;
6157                ses_gpio = 0x101;
6158                break;
6159        case ROUTER_BOARD_WHRAG108:
6160                diag_gpio = 0x107;
6161                bridge_gpio = 0x104;
6162                ses_gpio = 0x100;
6163                break;
6164        case ROUTER_BUFFALO_WHRG54S:
6165        case ROUTER_BUFFALO_WLI_TX4_G54HP:
6166                diag_gpio = 0x107;
6167                if (nvram_match("DD_BOARD", "Buffalo WHR-G125")) {
6168                        connected_gpio = 0x101;
6169                        sec0_gpio = 0x106;
6170                } else {
6171                        bridge_gpio = 0x101;
6172                        ses_gpio = 0x106;
6173                }
6174                break;
6175        case ROUTER_UBNT_UNIFIAC:
6176                power_gpio = 0x00e;
6177                diag_gpio = 0x00f;
6178                break;
6179        case ROUTER_D1800H:
6180                usb_gpio = 0x101;
6181                usb_power = 0x007;
6182                power_gpio = 0x002;
6183                diag_gpio = 0x00d;
6184                diag_gpio_disabled = 0x002;
6185                connected_gpio = 0x10f;
6186                disconnected_gpio = 0x10e;
6187                break;
6188        case ROUTER_BUFFALO_WZRRSG54:
6189                diag_gpio = 0x107;
6190                vpn_gpio = 0x101;
6191                ses_gpio = 0x106;
6192                break;
6193        case ROUTER_BUFFALO_WZRG300N:
6194                diag_gpio = 0x107;
6195                bridge_gpio = 0x101;
6196                break;
6197        case ROUTER_BUFFALO_WZRG144NH:
6198                diag_gpio = 0x103;
6199                bridge_gpio = 0x101;
6200                ses_gpio = 0x102;
6201                break;
6202        case ROUTER_BUFFALO_WZR900DHP:
6203        case ROUTER_BUFFALO_WZR600DHP2:
6204//              usb_power = 0x009;      // USB 2.0 ehci port
6205                usb_power1 = 0x10a;     // USB 3.0 xhci port
6206//              wlan0_gpio = 0x028; // wireless orange
6207//              wlan1_gpio = 0x029; // wireless blue
6208                connected_gpio = 0x02a; // connected blue
6209                sec0_gpio = 0x02b;
6210                sec1_gpio = 0x02c;
6211                // 0x2b strange led orange
6212                // 0x2c strange led blue
6213                power_gpio = 0x02e;
6214                diag_gpio = 0x02d;
6215                diag_gpio_disabled = 0x02e;
6216                usb_gpio = 0x02f;
6217                break;
6218
6219        case ROUTER_BUFFALO_WXR1900DHP:
6220                usb_power = 0x00d;      // USB 2.0 ehci port
6221                usb_power1 = 0x00e;     // USB 3.0 xhci port
6222//              wlan0_gpio = 0x028; // wireless orange
6223//              wlan1_gpio = 0x029; // wireless blue
6224                connected_gpio = 0x009; // connected blue
6225                disconnected_gpio = 0x00a;      // connected blue
6226                sec0_gpio = 0x00b;
6227                sec1_gpio = 0x00b;
6228                // 0x2b strange led orange
6229                // 0x2c strange led blue
6230                power_gpio = 0x006;
6231                diag_gpio = 0x005;
6232                diag_gpio_disabled = 0x006;
6233                break;
6234
6235        case ROUTER_BUFFALO_WZR1750:
6236                usb_power = 0x009;      // USB 2.0 ehci port
6237                usb_power1 = 0x10a;     // USB 3.0 xhci port
6238//              wlan0_gpio = 0x028; // wireless orange
6239//              wlan1_gpio = 0x029; // wireless blue
6240                connected_gpio = 0x02a; // connected blue
6241                sec0_gpio = 0x02b;
6242                sec1_gpio = 0x02c;
6243                // 0x2b strange led orange
6244                // 0x2c strange led blue
6245                power_gpio = 0x02d;
6246                diag_gpio = 0x02e;
6247                diag_gpio_disabled = 0x02d;
6248                usb_gpio = 0x02f;
6249                break;
6250#ifndef HAVE_BUFFALO
6251#ifdef HAVE_DIR300
6252        case ROUTER_BOARD_FONERA:
6253                diag_gpio = 0x003;
6254                bridge_gpio = 0x004;
6255                ses_gpio = 0x001;
6256                break;
6257#endif
6258#ifdef HAVE_WRT54G2
6259        case ROUTER_BOARD_FONERA:
6260                bridge_gpio = 0x004;
6261                ses_gpio = 0x104;
6262                diag_gpio = 0x103;
6263                break;
6264#endif
6265#ifdef HAVE_RTG32
6266        case ROUTER_BOARD_FONERA:
6267                break;
6268#endif
6269#ifdef HAVE_BWRG1000
6270        case ROUTER_BOARD_LS2:
6271                diag_gpio = 0x007;
6272                break;
6273#endif
6274#ifdef HAVE_DIR400
6275        case ROUTER_BOARD_FONERA2200:
6276                diag_gpio = 0x003;
6277                bridge_gpio = 0x004;
6278                ses_gpio = 0x001;
6279                break;
6280#endif
6281#ifdef HAVE_WRK54G
6282        case ROUTER_BOARD_FONERA:
6283                diag_gpio = 0x107;
6284                dmz_gpio = 0x005;
6285                break;
6286#endif
6287        case ROUTER_BOARD_TW6600:
6288                diag_gpio = 0x107;
6289                bridge_gpio = 0x104;
6290                ses_gpio = 0x100;
6291                break;
6292        case ROUTER_MOTOROLA:
6293                power_gpio = 0x001;
6294                diag_gpio = 0x101;      // power led blink / off to indicate factory
6295                // defaults
6296                break;
6297        case ROUTER_RT210W:
6298                power_gpio = 0x105;
6299                diag_gpio = 0x005;      // power led blink / off to indicate factory
6300                // defaults
6301                connected_gpio = 0x100;
6302                wlan0_gpio = 0x103;
6303                break;
6304        case ROUTER_RT480W:
6305        case ROUTER_BELKIN_F5D7230_V2000:
6306        case ROUTER_BELKIN_F5D7231:
6307                power_gpio = 0x105;
6308                diag_gpio = 0x005;      // power led blink / off to indicate factory
6309                // defaults
6310                connected_gpio = 0x100;
6311                break;
6312        case ROUTER_MICROSOFT_MN700:
6313                power_gpio = 0x006;
6314                diag_gpio = 0x106;      // power led blink / off to indicate factory
6315                // defaults
6316                break;
6317        case ROUTER_ASUS_WL500GD:
6318        case ROUTER_ASUS_WL520GUGC:
6319                diag_gpio = 0x000;      // power led blink / off to indicate factory
6320                // defaults
6321                break;
6322        case ROUTER_ASUS_WL500G_PRE:
6323        case ROUTER_ASUS_WL700GE:
6324                power_gpio = 0x101;
6325                diag_gpio = 0x001;      // power led blink / off to indicate factory
6326                // defaults
6327                break;
6328        case ROUTER_ASUS_WL550GE:
6329                power_gpio = 0x102;
6330                diag_gpio = 0x002;      // power led blink / off to indicate factory
6331                // defaults
6332                break;
6333        case ROUTER_WRT54G3G:
6334        case ROUTER_WRTSL54GS:
6335                power_gpio = 0x001;
6336                dmz_gpio = 0x100;
6337                connected_gpio = 0x107; // ses orange
6338                ses_gpio = 0x105;       // ses white
6339                ses2_gpio = 0x107;      // ses orange
6340                break;
6341        case ROUTER_MOTOROLA_WE800G:
6342        case ROUTER_MOTOROLA_V1:
6343                diag_gpio = 0x103;
6344                wlan0_gpio = 0x101;
6345                bridge_gpio = 0x105;
6346                break;
6347        case ROUTER_DELL_TRUEMOBILE_2300:
6348        case ROUTER_DELL_TRUEMOBILE_2300_V2:
6349                power_gpio = 0x107;
6350                diag_gpio = 0x007;      // power led blink / off to indicate factory
6351                // defaults
6352                wlan0_gpio = 0x106;
6353                break;
6354        case ROUTER_NETGEAR_WNR834B:
6355                power_gpio = 0x104;
6356                diag_gpio = 0x105;
6357                wlan0_gpio = 0x106;
6358                break;
6359        case ROUTER_SITECOM_WL105B:
6360                power_gpio = 0x003;
6361                diag_gpio = 0x103;      // power led blink / off to indicate factory
6362                // defaults
6363                wlan0_gpio = 0x104;
6364                break;
6365        case ROUTER_WRT300N:
6366                power_gpio = 0x001;
6367                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6368                break;
6369        case ROUTER_WRT150N:
6370                power_gpio = 0x001;
6371                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6372                sec0_gpio = 0x105;
6373                break;
6374        case ROUTER_WRT300NV11:
6375                ses_gpio = 0x105;
6376                sec0_gpio = 0x103;
6377                // diag_gpio = 0x11; //power led blink / off to indicate fac.def.
6378                break;
6379        case ROUTER_WRT310N:
6380                connected_gpio = 0x103; //ses orange
6381                power_gpio = 0x001;
6382                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6383                ses_gpio = 0x109;       // ses blue
6384                break;
6385        case ROUTER_WRT310NV2:
6386                connected_gpio = 0x102; // ses orange
6387                power_gpio = 0x001;
6388                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6389                ses_gpio = 0x104;       // ses blue
6390                break;
6391        case ROUTER_WRT160N:
6392                power_gpio = 0x001;
6393                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6394                connected_gpio = 0x103; // ses orange
6395                ses_gpio = 0x105;       // ses blue
6396                break;
6397        case ROUTER_WRT160NV3:
6398                power_gpio = 0x001;
6399                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6400                connected_gpio = 0x102; // ses orange
6401                ses_gpio = 0x104;       // ses blue
6402                break;
6403        case ROUTER_LINKSYS_E800:
6404        case ROUTER_LINKSYS_E900:
6405        case ROUTER_LINKSYS_E1500:
6406        case ROUTER_LINKSYS_E1550:
6407                power_gpio = 0x106;
6408                diag_gpio = 0x006;      // power led blink / off to indicate fac.def.
6409                ses_gpio = 0x108;       // ses blue
6410                break;
6411        case ROUTER_LINKSYS_E1000V2:
6412                power_gpio = 0x106;
6413                diag_gpio = 0x006;      // power led blink / off to indicate fac.def.
6414                connected_gpio = 0x007; // ses orange
6415                ses_gpio = 0x008;       // ses blue
6416                break;
6417        case ROUTER_LINKSYS_E2500:
6418                power_gpio = 0x106;
6419                diag_gpio = 0x006;      // power led blink / off to indicate fac.def.
6420                break;
6421        case ROUTER_LINKSYS_E3200:
6422                power_gpio = 0x103;
6423                diag_gpio = 0x003;      // power led blink / off to indicate fac.def.
6424                break;
6425        case ROUTER_LINKSYS_E4200:
6426                power_gpio = 0x105;     // white LED1
6427                diag_gpio = 0x103;      // power led blink / off to indicate fac.def.
6428//              connected_gpio = 0x103; // white LED2
6429                break;
6430        case ROUTER_LINKSYS_EA6500:
6431                diag_gpio = 0x101;      // white led blink / off to indicate fac.def.
6432                break;
6433        case ROUTER_LINKSYS_EA6500V2:
6434        case ROUTER_LINKSYS_EA6700:
6435        case ROUTER_LINKSYS_EA6400:
6436        case ROUTER_LINKSYS_EA6350:
6437        case ROUTER_LINKSYS_EA6900:
6438                usb_power = 0x009;      //usb power on/off
6439                usb_power1 = 0x00a;     //usb power on/off
6440                diag_gpio = 0x106;      // white led blink / off to indicate fac.def.
6441                connected_gpio = 0x008;
6442                break;
6443        case ROUTER_LINKSYS_EA8500:
6444                power_gpio = 0x100;     // power led
6445                diag_gpio = 0x000;      // power led orange     
6446                wlan0_gpio = 0x001;     // radio 0 
6447                ses_gpio = 0x102;       // wps led
6448                break;
6449        case ROUTER_ASUS_WL500G:
6450                power_gpio = 0x100;
6451                diag_gpio = 0x000;      // power led blink /off to indicate factory
6452                // defaults
6453                break;
6454        case ROUTER_ASUS_WL500W:
6455                power_gpio = 0x105;
6456                diag_gpio = 0x005;      // power led blink /off to indicate factory
6457                // defaults
6458                break;
6459        case ROUTER_LINKSYS_WTR54GS:
6460                diag_gpio = 0x001;
6461                break;
6462        case ROUTER_WAP54G_V1:
6463                diag_gpio = 0x103;
6464                wlan0_gpio = 0x104;     // LINK led
6465                break;
6466        case ROUTER_WAP54G_V3:
6467                ses_gpio = 0x10c;
6468                connected_gpio = 0x006;
6469                break;
6470        case ROUTER_NETGEAR_WNR834BV2:
6471                power_gpio = 0x002;
6472                diag_gpio = 0x003;      // power led amber
6473                connected_gpio = 0x007; // WAN led green
6474                break;
6475        case ROUTER_NETGEAR_WNDR3300:
6476                power_gpio = 0x005;
6477                diag_gpio = 0x105;      // power led blink /off to indicate factory defaults
6478                connected_gpio = 0x007; // WAN led green
6479                break;
6480        case ROUTER_ASKEY_RT220XD:
6481                wlan0_gpio = 0x100;
6482                dmz_gpio = 0x101;       // not soldered
6483                break;
6484        case ROUTER_WRT610N:
6485                power_gpio = 0x001;
6486                diag_gpio = 0x101;      // power led blink /off to indicate factory defaults
6487                connected_gpio = 0x103; // ses amber
6488                ses_gpio = 0x109;       // ses blue
6489                usb_gpio = 0x100;
6490                break;
6491        case ROUTER_WRT610NV2:
6492                power_gpio = 0x005;
6493                diag_gpio = 0x105;      // power led blink
6494                connected_gpio = 0x100; // ses amber
6495                ses_gpio = 0x103;       // ses blue
6496                usb_gpio = 0x007;
6497                break;
6498        case ROUTER_USR_5461:
6499                usb_gpio = 0x001;
6500                break;
6501        case ROUTER_USR_5465:
6502                //usb_gpio = 0x002; //or 0x001 ??
6503                break;
6504        case ROUTER_NETGEAR_WGR614L:
6505        case ROUTER_NETGEAR_WGR614V9:
6506                // power_gpio = 0x107;       // don't use - resets router
6507                diag_gpio = 0x006;
6508                connected_gpio = 0x104;
6509                break;
6510        case ROUTER_NETGEAR_WG602_V4:
6511                power_gpio = 0x101;     // trick: make lan led green for 100Mbps
6512                break;
6513        case ROUTER_BELKIN_F5D7231_V2000:
6514                connected_gpio = 0x104;
6515                diag_gpio = 0x001;      // power led blink /off to indicate factory defaults
6516                break;
6517        case ROUTER_NETGEAR_WNR3500L:
6518        case ROUTER_NETGEAR_WNR3500LV2:
6519                power_gpio = 0x003;     // power led green
6520                diag_gpio = 0x007;      // power led amber
6521                ses_gpio = 0x001;       // WPS led green
6522                connected_gpio = 0x002; // wan led green
6523                wlan1_gpio = 0x000;     // radio 1 blue led
6524                usb_gpio = 0x014;       // usb power
6525                break;
6526        case ROUTER_NETGEAR_WNDR3400:
6527                power_gpio = 0x003;     //power led green
6528                diag_gpio = 0x007;      // power led amber
6529                connected_gpio = 0x001; //wan led green
6530                usb_gpio = 0x102;       //usb led green
6531                wlan1_gpio = 0x000;     // radio 1 led blue
6532                break;
6533        case ROUTER_NETGEAR_WNDR4000:
6534                power_gpio = 0x000;     //power led green
6535                diag_gpio = 0x001;      // power led amber
6536                connected_gpio = 0x002; //wan led green
6537                wlan0_gpio = 0x003;     //radio 0 led green
6538                wlan1_gpio = 0x004;     // radio 1 led blue
6539                usb_gpio = 0x005;       //usb led green
6540                ses_gpio = 0x106;       // WPS led green - inverse
6541                ses2_gpio = 0x107;      // WLAN led green - inverse
6542                break;
6543        case ROUTER_DLINK_DIR860:
6544                usb_power = 0x00a;
6545                connected_gpio = 0x104;
6546                disconnected_gpio = 0x103;
6547                power_gpio = 0x101;
6548                diag_gpio = 0x100;
6549                diag_gpio_disabled = 0x101;
6550                break;
6551        case ROUTER_DLINK_DIR868:
6552        case ROUTER_DLINK_DIR868C:
6553                usb_power = 0x00a;
6554                connected_gpio = 0x103;
6555                disconnected_gpio = 0x101;
6556                power_gpio = 0x102;
6557                diag_gpio = 0x100;
6558                break;
6559
6560        case ROUTER_DLINK_DIR880:
6561                connected_gpio = 0x103;
6562                disconnected_gpio = 0x101;
6563                power_gpio = 0x102;
6564                diag_gpio = 0x100;
6565                diag_gpio_disabled = 0x102;
6566                usb_gpio = 0x108;
6567                usb_gpio1 = 0x10f;
6568//              wlan0_gpio = 0x10d;
6569//              wlan1_gpio = 0x10e;
6570                usb_power = 0x009;
6571                usb_power1 = 0x00a;
6572                break;
6573        case ROUTER_DLINK_DIR885:
6574                usb_power = 0x012;
6575                usb_gpio = 0x108;
6576                power_gpio = 0x100;
6577                diag_gpio = 0x102;
6578                diag_gpio_disabled = 0x100;
6579                disconnected_gpio = 0x103;
6580                connected_gpio = 0x101;
6581                wlan0_gpio = 0x10d;
6582                wlan1_gpio = 0x10e;
6583                break;
6584        case ROUTER_DLINK_DIR895:
6585                usb_power = 0x015;
6586                usb_power1 = 0x012;
6587                usb_gpio = 0x108;
6588                usb_gpio1 = 0x10f;
6589                power_gpio = 0x100;
6590                diag_gpio = 0x102;
6591                diag_gpio_disabled = 0x100;
6592                disconnected_gpio = 0x103;
6593                connected_gpio = 0x101;
6594                wlan0_gpio = 0x10d;
6595                wlan1_gpio = 0x10e;
6596                break;
6597        case ROUTER_DLINK_DIR890:
6598                usb_power = 0x015;
6599                usb_power1 = 0x012;
6600                usb_gpio = 0x108;
6601                usb_gpio1 = 0x10f;
6602                connected_gpio = 0x101;
6603                disconnected_gpio = 0x103;
6604                power_gpio = 0x102;
6605                diag_gpio = 0x002;
6606                break;
6607        case ROUTER_TRENDNET_TEW828:
6608                usb_gpio = 0x104;
6609                power_gpio = 0x106;
6610                diag_gpio = 0x006;
6611                break;
6612        case ROUTER_TRENDNET_TEW812:
6613                // gpio !1 = 2.4 ghz led
6614                // gpio !2 = 5 ghz led
6615                // gpio !3 = power somthing
6616                // gpio !8 = usb led
6617                //
6618                usb_gpio = 0x108;
6619                diag_gpio = 0x103;
6620                wlan0_gpio = 0x101;
6621                wlan1_gpio = 0x102;
6622                break;
6623        case ROUTER_ASUS_RTN18U:
6624                power_gpio = 0x100;
6625//              usb_power = 0x00d;      //usb power on/off
6626                if (nvram_match("bl_version", "3.0.0.7")) {
6627                        usb_gpio = 0x10e;
6628                        connected_gpio = 0x103;
6629                        disconnected_gpio = 0x106;
6630                } else if (nvram_match("bl_version", "1.0.0.0")) {
6631                        usb_gpio = 0x103;
6632                        connected_gpio = 0x106;
6633                        disconnected_gpio = 0x109;
6634                } else {
6635                        usb_gpio = 0x103;
6636                        usb_gpio1 = 0x10e;
6637                        connected_gpio = 0x106;
6638                        disconnected_gpio = 0x109;
6639                }
6640                break;
6641        case ROUTER_TPLINK_ARCHERC9:
6642                ses_gpio = 0x002;
6643                usb_gpio = 0x006;
6644                usb_gpio1 = 0x007;
6645                disconnected_gpio = 0x00f;
6646                connected_gpio = 0x00e;
6647                power_gpio = 0x112;
6648                diag_gpio = 0x012;
6649                usb_power = 0x00c;      // usb 3
6650                usb_power1 = 0x00d;     // usb 2
6651                break;
6652        case ROUTER_TPLINK_ARCHERC3150:
6653                ses_gpio = 0x002;
6654//              usb_gpio = 0x006;
6655//              usb_gpio1 = 0x007;
6656//              disconnected_gpio = 0x00f;
6657//              connected_gpio = 0x00e;
6658//              power_gpio = 0x112;
6659//              diag_gpio = 0x012;
6660                usb_power = 0x00c;      // usb 3
6661                usb_power1 = 0x00d;     // usb 2
6662                break;
6663        case ROUTER_ASUS_AC67U:
6664        case ROUTER_ASUS_AC56U:
6665                wlan1_gpio = 0x106;
6666                power_gpio = 0x103;
6667                usb_power = 0x009;      //usb power on/off
6668                usb_power1 = 0x00a;     //usb power on/off
6669                usb_gpio = 0x10e;
6670                usb_gpio1 = 0x100;
6671                diag_gpio = 0x003;
6672                connected_gpio = 0x101;
6673                disconnected_gpio = 0x102;
6674                break;
6675        case ROUTER_ASUS_AC3200:
6676                usb_power = 0x009;
6677                power_gpio = 0x103;
6678                connected_gpio = 0x105;
6679                diag_gpio = 0x003;
6680                // wps gpio = 14
6681                break;
6682        case ROUTER_ASUS_AC1200:
6683                usb_power = 0x10a;
6684                diag_gpio = 0x00a;
6685                diag_gpio_disabled = 0x10a;
6686                usb_gpio = 0x10f;
6687                break;
6688        case ROUTER_ASUS_AC88U:
6689        case ROUTER_ASUS_AC3100:
6690        case ROUTER_ASUS_AC5300:
6691                usb_power = 0x009;
6692                usb_gpio = 0x110;
6693                usb_gpio1 = 0x111;
6694                power_gpio = 0x103;
6695                diag_gpio = 0x003;
6696                connected_gpio = 0x005;
6697                disconnected_gpio = 0x115;
6698                ses_gpio = 0x113;
6699                // komisches symbol gpio 21
6700                // quantenna reset 8 inv (off / on to reset)   
6701                break;
6702        case ROUTER_ASUS_AC87U:
6703                usb_power = 0x009;
6704                power_gpio = 0x103;
6705                connected_gpio = 0x105;
6706                ses_gpio = 0x101;
6707                // quantenna reset 8 inv (off / on to reset)   
6708                break;
6709        case ROUTER_NETGEAR_EX6200:
6710                //power_gpio = 0x109;   // connected red
6711                diag_gpio = 0x101;      // Netgear logo
6712                connected_gpio = 0x108; // connected green
6713                wlan1_gpio = 0x10b;     // radio led red 2.4G
6714                wlan0_gpio = 0x10d;     // radio led red 5G
6715                usb_gpio = 0x105;       // usb led
6716                //usb_power = 0x000;    // usb enable
6717                break;
6718        case ROUTER_NETGEAR_AC1450:
6719                power_gpio = 0x102;     // power led green
6720                //diag_gpio = 0x103;    // power led orange
6721                diag_gpio = 0x101;      // Netgear logo
6722                connected_gpio = 0x10a; // wan led green - hw controlled
6723                wlan0_gpio = 0x10b;     // radio led blue
6724                usb_gpio = 0x108;       // usb led
6725                //usb_power = 0x000;    // usb enable
6726                break;
6727        case ROUTER_NETGEAR_R6250:
6728                power_gpio = 0x102;     // power led green
6729                //diag_gpio = 0x103;    // power led orange
6730                diag_gpio = 0x001;      // Netgear logo
6731                //emblem0_gpio = 0x001; // NETGEAR Emblem       
6732                //connected_gpio = 0x10f;       // wan led green
6733                wlan0_gpio = 0x10b;     // radio led blue
6734                usb_gpio = 0x108;       // usb led green
6735                //usb_power = 0x000;    // usb enable
6736                break;
6737        case ROUTER_NETGEAR_R6300:
6738                usb_gpio = 0x108;       //usb led
6739                usb_power = 0x000;      //usb power on/off
6740                connected_gpio = 0x10f; //green led
6741                power_gpio = 0x102;     //power orange led
6742                diag_gpio = 0x103;      //power led orange
6743                //diag_gpio_disabled=0x009;//netgear logo led r
6744                //emblem0_gpio = 0x101;   // NETGEAR Emblem l     
6745                //emblem1_gpio = 0x109;   // NETGEAR Emblem r
6746                wlan0_gpio = 0x10b;     // radio led blue
6747                break;
6748        case ROUTER_NETGEAR_R6300V2:
6749                power_gpio = 0x102;     // power led green
6750                //diag_gpio = 0x103;    // power led orange
6751                diag_gpio = 0x101;      // Netgear logo
6752                connected_gpio = 0x10a; // wan led green - hw controlled
6753                wlan0_gpio = 0x10b;     // radio led blue
6754                usb_gpio = 0x108;       // usb led
6755                //usb_power = 0x000;    // usb enable
6756                break;
6757        case ROUTER_NETGEAR_R6400:
6758                power_gpio = 0x101;     //
6759                connected_gpio = 0x107; //
6760                usb_power = 0x000;      //
6761                diag_gpio = 0x102;      //
6762                wlan0_gpio = 0x109;     // radio 0
6763                wlan1_gpio = 0x108;     // radio 1
6764                ses_gpio = 0x10a;       // wps led
6765                wlan_gpio = 0x10b;      // wifi button led
6766                usb_gpio = 0x10c;       // usb1
6767                usb_gpio1 = 0x10d;      // usb2
6768                break;
6769        case ROUTER_NETGEAR_R7000:
6770                power_gpio = 0x102;     // power led
6771                diag_gpio = 0x103;      // power led orange     
6772                connected_gpio = 0x109; // wan led
6773                usb_power = 0x000;      // usb enable
6774                wlan0_gpio = 0x10d;     // radio 0
6775                wlan1_gpio = 0x10c;     // radio 1
6776                ses_gpio = 0x10e;       // wps led
6777                //wlan_gpio = 0x10f;    // wifi button led
6778                usb_gpio = 0x111;       //usb1
6779                usb_gpio1 = 0x112;      //usb2
6780                break;
6781        case ROUTER_NETGEAR_R7500V2:
6782        case ROUTER_NETGEAR_R7500:
6783                power_gpio = 0x000;     // power led
6784                diag_gpio = 0x00a;      // power led orange     
6785                diag_gpio_disabled = 0x000;     // power led orange     
6786                connected_gpio = 0x007; // wan led
6787                usb_power = 0x010;      // usb enable
6788                usb_power1 = 0x00f;     // usb enable
6789                wlan0_gpio = 0x001;     // radio 0
6790                wlan1_gpio = 0x102;     // radio 1
6791                ses_gpio = 0x109;       // wps led
6792                wlan_gpio = 0x108;      // wifi button led
6793                usb_gpio = 0x004;       //usb1
6794                usb_gpio1 = 0x005;      //usb2
6795                break;
6796        case ROUTER_NETGEAR_R7800:
6797                power_gpio = 0x000;     // power led
6798                diag_gpio = 0x00a;      // power led orange     
6799                diag_gpio_disabled = 0x000;     // power led orange     
6800                connected_gpio = 0x007; // wan led
6801                usb_power = 0x010;      // usb enable
6802                usb_power1 = 0x00f;
6803                wlan0_gpio = 0x009;     // radio 5G
6804                wlan1_gpio = 0x008;     // radio 2G
6805                //ses_gpio = 0x109;     // wps button led used for 2G
6806                //wlan_gpio = 0x008;    // wifi button led used for 5G
6807                usb_gpio = 0x004;       //usb1
6808                usb_gpio1 = 0x005;      //usb2
6809                break;
6810        case ROUTER_ASROCK_G10:
6811                diag_gpio = 0x009;      // power led orange     
6812                connected_gpio = 0x008; // wan led
6813                disconnected_gpio = 0x007;      // wan led
6814                break;
6815        case ROUTER_NETGEAR_R9000:
6816
6817                power_gpio = 0x016;     // power led
6818                diag_gpio = 0x116;      // power led orange     
6819                diag_gpio_disabled = 0x016;     // power led orange     
6820                connected_gpio = 0x017; // wan led
6821//      usb_power = 0x010;      // usb enable
6822//      usb_power1 = 0x00f;
6823                ses_gpio = 0x127;       // wps button led used for 2G
6824                usb_gpio = 0x024;       //usb1
6825                usb_gpio1 = 0x025;      //usb2
6826                break;
6827        case ROUTER_TRENDNET_TEW827:
6828                power_gpio = 0x135;     // power led
6829                usb_gpio = 0x107;       // usb led
6830                break;
6831        case ROUTER_NETGEAR_R8000:
6832                power_gpio = 0x102;     // power led
6833                diag_gpio = 0x103;      // power led orange     
6834                connected_gpio = 0x109; // wan led green
6835                usb_power = 0x000;      // usb enable
6836                wlan0_gpio = 0x10d;     // radio 2G
6837                wlan1_gpio = 0x10c;     // radio 5G-1
6838                wlan2_gpio = 0x110;     // radio 5G-2
6839                ses_gpio = 0x10e;       // wps led
6840                wlan_gpio = 0x10f;      // wifi button led
6841                usb_gpio = 0x111;       //usb1
6842                usb_gpio1 = 0x112;      //usb2
6843                break;
6844        case ROUTER_NETGEAR_R8500:
6845                power_gpio = 0x102;     // power led
6846                diag_gpio = 0x10f;      //     
6847                connected_gpio = 0x109; // wan led white 1Gb amber 100Mb
6848                usb_power = 0x000;      // usb enable
6849                wlan0_gpio = 0x10b;     // radio 5G-1
6850                wlan1_gpio = 0x10d;     // radio 2G
6851                wlan2_gpio = 0x10c;     // radio 5G-2
6852                ses_gpio = 0x10e;       // wps led
6853                wlan_gpio = 0x014;      // wifi button led
6854                usb_gpio = 0x111;       //usb1
6855                usb_gpio1 = 0x112;      //usb2
6856                break;
6857        case ROUTER_NETGEAR_WNDR4500:
6858        case ROUTER_NETGEAR_WNDR4500V2:
6859                power_gpio = 0x102;     //power led green
6860                diag_gpio = 0x103;      // power led amber
6861                connected_gpio = 0x10f; //wan led green
6862                wlan0_gpio = 0x109;     //radio 0 led green
6863                wlan1_gpio = 0x10b;     // radio 1 led blue
6864                usb_gpio = 0x108;       //usb led green
6865                usb_gpio1 = 0x10e;      //usb1 led green
6866                break;
6867        case ROUTER_ASUS_RTN66:
6868        case ROUTER_ASUS_AC66U:
6869                power_gpio = 0x10c;
6870                diag_gpio = 0x00c;
6871                usb_gpio = 0x10f;
6872                break;
6873        case ROUTER_NETGEAR_WNR2000V2:
6874
6875                //power_gpio = ??;
6876                diag_gpio = 0x002;
6877                ses_gpio = 0x007;       //WPS led
6878                connected_gpio = 0x006;
6879                break;
6880        case ROUTER_WRT320N:
6881                power_gpio = 0x002;     //power/diag (disabled=blink)
6882                ses_gpio = 0x103;       // ses blue
6883                connected_gpio = 0x104; //ses orange
6884                break;
6885        case ROUTER_ASUS_RTN12:
6886                power_gpio = 0x102;
6887                diag_gpio = 0x002;      // power blink
6888                break;
6889        case ROUTER_BOARD_NEPTUNE:
6890//              usb_gpio = 0x108;
6891                // 0x10c //unknown gpio label, use as diag
6892#ifdef HAVE_RUT500
6893                diag_gpio = 0x10e;
6894#else
6895                diag_gpio = 0x10c;
6896#endif
6897                break;
6898        case ROUTER_ASUS_RTN10U:
6899                ses_gpio = 0x007;
6900                usb_gpio = 0x008;
6901                break;
6902        case ROUTER_ASUS_RTN12B:
6903                connected_gpio = 0x105;
6904                break;
6905        case ROUTER_ASUS_RTN10PLUSD1:
6906                ses_gpio = 0x007;
6907                power_gpio = 0x106;
6908                diag_gpio = 0x006;
6909                break;
6910        case ROUTER_ASUS_RTN10:
6911        case ROUTER_ASUS_RTN16:
6912        case ROUTER_NETCORE_NW618:
6913                power_gpio = 0x101;
6914                diag_gpio = 0x001;      // power blink
6915                break;
6916        case ROUTER_BELKIN_F7D3301:
6917        case ROUTER_BELKIN_F7D3302:
6918        case ROUTER_BELKIN_F7D4301:
6919        case ROUTER_BELKIN_F7D4302:
6920                power_gpio = 0x10a;     // green
6921                diag_gpio = 0x10b;      // red
6922                ses_gpio = 0x10d;       // wps orange
6923                break;
6924        case ROUTER_DYNEX_DX_NRUTER:
6925                power_gpio = 0x001;
6926                diag_gpio = 0x101;      // power blink
6927                connected_gpio = 0x100;
6928                sec0_gpio = 0x103;
6929                break;
6930#endif
6931        }
6932
6933        if (type == LED_DIAG && v1func == 1) {
6934                if (act == LED_ON)
6935                        C_led(1);
6936                else
6937                        C_led(0);
6938        }
6939
6940        switch (type) {
6941        case LED_POWER:
6942                use_gpio = power_gpio;
6943                break;
6944        case BEEPER:
6945                use_gpio = beeper_gpio;
6946                break;
6947        case USB_POWER:
6948                use_gpio = usb_power;
6949                break;
6950        case USB_POWER1:
6951                use_gpio = usb_power1;
6952                break;
6953        case LED_DIAG:
6954                if (act == LED_ON)
6955                        led_control(LED_DIAG_DISABLED, LED_OFF);
6956                else
6957                        led_control(LED_DIAG_DISABLED, LED_ON);
6958                use_gpio = diag_gpio;
6959                break;
6960        case LED_DIAG_DISABLED:
6961                use_gpio = diag_gpio_disabled;
6962                break;
6963        case LED_DMZ:
6964                use_gpio = dmz_gpio;
6965                break;
6966        case LED_CONNECTED:
6967                if (act == LED_ON)
6968                        led_control(LED_DISCONNECTED, LED_OFF);
6969                else
6970                        led_control(LED_DISCONNECTED, LED_ON);
6971                use_gpio = connblue ? ses_gpio : connected_gpio;
6972                break;
6973        case LED_DISCONNECTED:
6974                use_gpio = disconnected_gpio;
6975                break;
6976        case LED_BRIDGE:
6977                use_gpio = bridge_gpio;
6978                break;
6979        case LED_VPN:
6980                use_gpio = vpn_gpio;
6981                break;
6982        case LED_SES:
6983                use_gpio = connblue ? connected_gpio : ses_gpio;
6984                break;
6985        case LED_SES2:
6986                use_gpio = ses2_gpio;
6987                break;
6988        case LED_WLAN:
6989                use_gpio = wlan_gpio;
6990                break;
6991        case LED_WLAN0:
6992                use_gpio = wlan0_gpio;
6993                break;
6994        case LED_WLAN1:
6995                use_gpio = wlan1_gpio;
6996                break;
6997        case LED_WLAN2:
6998                use_gpio = wlan2_gpio;
6999                break;
7000        case LED_USB:
7001                use_gpio = usb_gpio;
7002                break;
7003        case LED_USB1:
7004                use_gpio = usb_gpio1;
7005                break;
7006        case LED_SEC0:
7007                use_gpio = sec0_gpio;
7008                break;
7009        case LED_SEC1:
7010                use_gpio = sec1_gpio;
7011                break;
7012        }
7013
7014        if ((use_gpio & 0x0ff) != 0x0ff) {
7015                gpio_value = use_gpio & 0x0ff;
7016                enable = (use_gpio & 0x100) == 0 ? 1 : 0;
7017                disable = (use_gpio & 0x100) == 0 ? 0 : 1;
7018                int setin = (use_gpio & 0x200) == 0 ? 0 : 1;
7019                switch (act) {
7020                case LED_ON:
7021                        set_gpio(gpio_value, enable);
7022                        if (setin)
7023                                get_gpio(gpio_value);
7024                        break;
7025                case LED_OFF:
7026                        set_gpio(gpio_value, disable);
7027                        break;
7028                case LED_FLASH: // will lit the led for 1 sec.
7029                        set_gpio(gpio_value, enable);
7030                        sleep(1);
7031                        set_gpio(gpio_value, disable);
7032                        break;
7033                }
7034        }
7035        return 1;
7036
7037#endif
7038}
7039
7040int file_to_buf(char *path, char *buf, int len)
7041{
7042        FILE *fp;
7043
7044        memset(buf, 0, len);
7045
7046        if ((fp = fopen(path, "r"))) {
7047                fgets(buf, len, fp);
7048                fclose(fp);
7049                return 1;
7050        }
7051
7052        return 0;
7053}
7054
7055int ishexit(char c)
7056{
7057
7058        if (strchr("01234567890abcdefABCDEF", c) != (char *)0)
7059                return 1;
7060
7061        return 0;
7062}
7063
7064int getMTD(char *name)
7065{
7066        char buf[32];
7067        int device = -1;
7068        char dev[32];
7069        char size[32];
7070        char esize[32];
7071        char n[32];
7072        sprintf(buf, "\"%s\"", name);
7073        FILE *fp = fopen("/proc/mtd", "rb");
7074        if (!fp)
7075                return -1;
7076        while (!feof(fp) && fscanf(fp, "%s %s %s %s", dev, size, esize, n) == 4) {
7077                if (!strcmp(n, buf)) {
7078                        if (dev[4] == ':') {
7079                                device = dev[3] - '0';
7080                        } else {
7081                                device = 10 + (dev[4] - '0');
7082                        }
7083
7084                        break;
7085                }
7086        }
7087        fclose(fp);
7088        return device;
7089}
7090
7091int insmod(char *module)
7092{
7093        static char word[256];
7094        char *next, *wordlist;
7095        int ret = 0;
7096        wordlist = module;
7097        foreach(word, wordlist, next) {
7098                ret |= _evalpid((char *[]) {
7099                                "insmod", word, NULL}, ">/dev/null", 0, NULL);
7100        }
7101        return ret;
7102}
7103
7104void rmmod(char *module)
7105{
7106        static char word[256];
7107        char *next, *wordlist;
7108        wordlist = module;
7109        foreach(word, wordlist, next) {
7110                _evalpid((char *[]) {
7111                         "rmmod", word, NULL}, ">/dev/null", 0, NULL);
7112        }
7113}
7114
7115#include "revision.h"
7116
7117char *getSoftwareRevision(void)
7118{
7119        return "" SVN_REVISION "";
7120}
7121
7122#ifdef HAVE_OLED
7123void initlcd()
7124{
7125
7126}
7127
7128void lcdmessage(char *message)
7129{
7130        eval("oled-print", "DD-WRT v24 sp2", "build:" SVN_REVISION, "3G/UMTS Router", message);
7131}
7132
7133void lcdmessaged(char *dual, char *message)
7134{
7135
7136}
7137
7138#endif
7139
7140#if 0
7141
7142static int fd;
7143
7144void SetEnvironment()
7145{
7146        system("stty ispeed 2400 < /dev/tts/1");
7147        system("stty raw < /dev/tts/1");
7148}
7149
7150int Cmd = 254;                  /* EZIO Command */
7151int cls = 1;                    /* Clear screen */
7152void Cls()
7153{
7154        write(fd, &Cmd, 1);
7155        write(fd, &cls, 1);
7156}
7157
7158int init = 0x28;
7159void Init()
7160{
7161        write(fd, &Cmd, 1);
7162        write(fd, &init, 1);
7163}
7164
7165int stopsend = 0x37;
7166void StopSend()
7167{
7168        write(fd, &Cmd, 1);
7169        write(fd, &init, 1);
7170}
7171
7172int home = 2;                   /* Home cursor */
7173void Home()
7174{
7175        write(fd, &Cmd, 1);
7176        write(fd, &home, 1);
7177}
7178
7179int readkey = 6;                /* Read key */
7180void ReadKey()
7181{
7182        write(fd, &Cmd, 1);
7183        write(fd, &readkey, 1);
7184}
7185
7186int blank = 8;                  /* Blank display */
7187void Blank()
7188{
7189        write(fd, &Cmd, 1);
7190        write(fd, &blank, 1);
7191}
7192
7193int hide = 12;                  /* Hide cursor & display blanked characters */
7194void Hide()
7195{
7196        write(fd, &Cmd, 1);
7197        write(fd, &hide, 1);
7198}
7199
7200int turn = 13;                  /* Turn On (blinking block cursor) */
7201void TurnOn()
7202{
7203        write(fd, &Cmd, 1);
7204        write(fd, &turn, 1);
7205}
7206
7207int show = 14;                  /* Show underline cursor */
7208void Show()
7209{
7210        write(fd, &Cmd, 1);
7211        write(fd, &show, 1);
7212}
7213
7214int movel = 16;                 /* Move cursor 1 character left */
7215void MoveL()
7216{
7217        write(fd, &Cmd, 1);
7218        write(fd, &movel, 1);
7219}
7220
7221int mover = 20;                 /* Move cursor 1 character right */
7222void MoveR()
7223{
7224        write(fd, &Cmd, 1);
7225        write(fd, &mover, 1);
7226}
7227
7228int scl = 24;                   /* Scroll cursor 1 character left */
7229void ScrollL()
7230{
7231        write(fd, &Cmd, 1);
7232        write(fd, &scl, 1);
7233}
7234
7235int scr = 28;                   /* Scroll cursor 1 character right */
7236void ScrollR()
7237{
7238        write(fd, &Cmd, 1);
7239        write(fd, &scr, 1);
7240}
7241
7242int setdis = 64;                /* Command */
7243void SetDis()
7244{
7245        write(fd, &Cmd, 1);
7246        write(fd, &setdis, 1);
7247
7248}
7249
7250int a, b;
7251void ShowMessage(char *str1, char *str2)
7252{
7253        char nul[] = "                                       ";
7254
7255        a = strlen(str1);
7256        b = 40 - a;
7257        write(fd, str1, a);
7258        write(fd, nul, b);
7259        write(fd, str2, strlen(str2));
7260}
7261
7262void initlcd()
7263{
7264
7265        fd = open("/dev/tts/1", O_RDWR);
7266
7267                                  /** Open Serial port (COM2) */
7268        if (fd > 0) {
7269                close(fd);
7270                SetEnvironment();       /* Set RAW mode */
7271                fd = open("/dev/tts/1", O_RDWR);
7272                Init();         /* Initialize EZIO twice */
7273                Init();
7274
7275                Cls();          /* Clear screen */
7276        }
7277        close(fd);
7278}
7279
7280void lcdmessage(char *message)
7281{
7282
7283        fd = open("/dev/tts/1", O_RDWR);
7284                                   /** Open Serial port (COM2) */
7285
7286        if (fd > 0) {
7287                Init();         /* Initialize EZIO twice */
7288                Init();
7289                SetDis();
7290                Cls();
7291                Home();
7292                ShowMessage("State", message);
7293                close(fd);
7294        }
7295}
7296
7297void lcdmessaged(char *dual, char *message)
7298{
7299
7300        fd = open("/dev/tts/1", O_RDWR);
7301
7302                                  /** Open Serial port (COM2) */
7303
7304        if (fd > 0) {
7305                Init();         /* Initialize EZIO twice */
7306                Init();
7307                SetDis();
7308                Cls();          /* Clear screen */
7309                Home();
7310                ShowMessage(dual, message);
7311                close(fd);
7312        }
7313}
7314
7315#endif
7316static int i64c(int i)
7317{
7318        i &= 0x3f;
7319        if (i == 0)
7320                return '.';
7321        if (i == 1)
7322                return '/';
7323        if (i < 12)
7324                return ('0' - 2 + i);
7325        if (i < 38)
7326                return ('A' - 12 + i);
7327        return ('a' - 38 + i);
7328}
7329
7330int crypt_make_salt(char *p, int cnt, int x)
7331{
7332        x += getpid() + time(NULL);
7333        do {
7334                /*
7335                 * x = (x*1664525 + 1013904223) % 2^32 generator is lame (low-order
7336                 * bit is not "random", etc...), but for our purposes it is good
7337                 * enough
7338                 */
7339                x = x * 1664525 + 1013904223;
7340                /*
7341                 * BTW, Park and Miller's "minimal standard generator" is x = x*16807
7342                 * % ((2^31)-1) It has no problem with visibly alternating lowest bit
7343                 * but is also weak in cryptographic sense + needs div, which needs
7344                 * more code (and slower) on many CPUs
7345                 */
7346                *p++ = i64c(x >> 16);
7347                *p++ = i64c(x >> 22);
7348        }
7349        while (--cnt);
7350        *p = '\0';
7351        return x;
7352}
7353
7354#include <crypt.h>
7355
7356char *zencrypt(char *passwd, char *passout)
7357{
7358        char salt[sizeof("$N$XXXXXXXX")];       /* "$N$XXXXXXXX" or "XX" */
7359
7360        strcpy(salt, "$1$");
7361        crypt_make_salt(salt + 3, 4, 0);
7362        strcpy(passout, crypt((char *)passwd, (char *)salt));
7363        return passout;
7364}
7365
7366int has_gateway(void)
7367{
7368        if (nvram_match("wk_mode", "gateway"))
7369                return 1;
7370        if (nvram_match("wk_mode", "olsr") && nvram_matchi("olsrd_gateway", 1))
7371                return 1;
7372        return 0;
7373}
7374
7375struct wifidevices {
7376        char *name;
7377        int vendor;
7378        int device;
7379};
7380
7381static struct wifidevices wdevices[] = {
7382        {"AR5210 802.11a", 0x168c, 0x0007},
7383        {"AR5210 802.11a", 0x168c, 0x0207},
7384        {"AR5211 802.11a", 0x168c, 0x0011},
7385        {"AR5211 802.11ab", 0x168c, 0x0012},
7386        {"AR5212", 0x168c, 0x0013},
7387        {"AR5212", 0x168c, 0x1014},
7388        {"AR2413", 0x168c, 0x001a},
7389        {"AR5413", 0x168c, 0x001b},
7390        {"AR542x", 0x168c, 0x001c},
7391        {"AR2417", 0x168c, 0x001d},
7392        {"AR5513", 0x168c, 0x0020},
7393        {"AR5416 802.11n", 0x168c, 0x0023},
7394        {"AR5418 802.11n", 0x168c, 0x0024},
7395        {"AR9160 802.11n", 0x168c, 0x0027},
7396        {"AR922X 802.11n", 0x168c, 0x0029},
7397        {"AR928X 802.11n", 0x168c, 0x002a},
7398        {"AR9285 802.11n", 0x168c, 0x002b},
7399        {"AR2427 802.11n", 0x168c, 0x002c},
7400        {"AR9227 802.11n", 0x168c, 0x002d},
7401        {"AR9287 802.11n", 0x168c, 0x002e},
7402        {"AR93xx 802.11n", 0x168c, 0x0030},
7403        {"AR9485 802.11n", 0x168c, 0x0032},
7404        {"AR958x 802.11n", 0x168c, 0x0033},
7405        {"AR9462 802.11n", 0x168c, 0x0034},
7406        {"QCA9565 802.11n", 0x168c, 0x0036},
7407        {"AR9485 802.11n", 0x168c, 0x0037},
7408        {"AR5002X", 0x168c, 0x9013},
7409        {"AR5006X", 0x168c, 0xff19},
7410        {"AR2425", 0x168c, 0xff1b},
7411        {"AR5008", 0x168c, 0xff1c},
7412        {"AR922x 802.11n", 0x168c, 0xff1d},
7413        {"QCA988x 802.11ac", 0x168c, 0x003c},
7414        {"QCA6174 802.11ac", 0x168c, 0x003e},
7415        {"QCA9980 802.11ac", 0x168c, 0x0040},
7416        {"QCA6174 802.11ac", 0x168c, 0x0041},
7417        {"QCA9377 802.11ac", 0x168c, 0x0042},
7418        {"QCA9984 802.11ac", 0x168c, 0x0046},
7419        {"QCA9887 802.11ac", 0x168c, 0x0050},
7420        {"QCA9888 802.11ac", 0x168c, 0x0056},
7421        {"88W8964 802.11ac", 0x11ab, 0x2b40},
7422        {"88W8864 802.11ac", 0x11ab, 0x2a55},
7423        {"88W8897 802.11ac", 0x11ab, 0x2b38},
7424        {"WIL6210 802.11ad", 0x1ae9, 0x0310},
7425
7426};
7427
7428char *getWifiDeviceName(char *prefix)
7429{
7430        char *globstring;
7431        int devnum;
7432        int device = 0, vendor = 0;
7433        int devcount;
7434        FILE *fp;
7435        sscanf(prefix, "ath%d", &devcount);
7436        asprintf(&globstring, "/proc/sys/dev/wifi%d/dev_vendor", devcount);
7437        fp = fopen(globstring, "rb");
7438        if (fp) {
7439                fscanf(fp, "%d", &vendor);
7440                fclose(fp);
7441        }
7442        free(globstring);
7443        asprintf(&globstring, "/proc/sys/dev/wifi%d/dev_device", devcount);
7444        fp = fopen(globstring, "rb");
7445        if (fp) {
7446                fscanf(fp, "%d", &device);
7447                fclose(fp);
7448        }
7449        free(globstring);
7450#ifdef HAVE_ATH9K
7451        if (!vendor || !device) {
7452                devnum = get_ath9k_phy_ifname(prefix);
7453                if (devnum == -1)
7454                        return NULL;
7455                asprintf(&globstring, "/sys/class/ieee80211/phy%d/device/vendor", devnum);
7456                fp = fopen(globstring, "rb");
7457                if (fp) {
7458                        fscanf(fp, "0x%x", &vendor);
7459                        fclose(fp);
7460                }
7461                free(globstring);
7462                asprintf(&globstring, "/sys/class/ieee80211/phy%d/device/device", devnum);
7463                fp = fopen(globstring, "rb");
7464                if (fp) {
7465                        fscanf(fp, "0x%x", &device);
7466                        fclose(fp);
7467                }
7468                free(globstring);
7469        }
7470#endif
7471        if (!vendor || !device) {
7472                return NULL;
7473        }
7474        int i;
7475        for (i = 0; i < sizeof(wdevices) / sizeof(wdevices[0]); i++) {
7476                if (wdevices[i].vendor == vendor && wdevices[i].device == device)
7477                        return wdevices[i].name;
7478        }
7479        return NULL;
7480
7481}
7482
7483#ifdef HAVE_ATH9K
7484int getath9kdevicecount(void)
7485{
7486        glob_t globbuf;
7487        int globresult;
7488        int count = 0;
7489#ifndef HAVE_MADWIFI_MIMO
7490        if (1) {
7491#else
7492        if (nvram_match("mimo_driver", "ath9k")) {
7493#endif
7494                globresult = glob("/sys/class/ieee80211/phy*", GLOB_NOSORT, NULL, &globbuf);
7495                if (globresult == 0)
7496                        count = (int)globbuf.gl_pathc;
7497                globfree(&globbuf);
7498        }
7499#if (defined(HAVE_MMS344) || defined(HAVE_ARCHERC7)) && !defined(HAVE_DAP2330) && !defined(HAVE_WILLY)
7500        return 2;
7501#else
7502        return (count);
7503#endif
7504}
7505
7506int get_ath9k_phy_idx(int idx)
7507{
7508        // fprintf(stderr,"channel number %d of %d\n", i,achans.ic_nchans);
7509#ifdef HAVE_MVEBU
7510        return idx;
7511#else
7512        return idx - getifcount("wifi");
7513#endif
7514}
7515
7516int get_ath9k_phy_ifname(const char *ifname)
7517{
7518        int devnum;
7519        if (is_wil6210(ifname))
7520                return 2;
7521        if (strncmp(ifname, "ath", 3))
7522                return -1;
7523        if (!sscanf(ifname, "ath%d", &devnum))
7524                return -1;
7525        // fprintf(stderr,"channel number %d of %d\n", i,achans.ic_nchans);
7526        return get_ath9k_phy_idx(devnum);
7527}
7528
7529int is_ath9k(const char *prefix)
7530{
7531#ifdef HAVE_MVEBU
7532        return 1;
7533#endif
7534        glob_t globbuf;
7535        int count = 0;
7536        char *globstring;
7537        int globresult;
7538        int devnum;
7539        // get legacy interface count
7540#ifdef HAVE_MADWIFI_MIMO
7541        if (!nvram_match("mimo_driver", "ath9k"))
7542                return (0);
7543#endif
7544        // correct index if there are legacy cards arround
7545        devnum = get_ath9k_phy_ifname(prefix);
7546        if (devnum == -1)
7547                return 0;
7548        asprintf(&globstring, "/sys/class/ieee80211/phy%d", devnum);
7549        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
7550        free(globstring);
7551        if (globresult == 0)
7552                count = (int)globbuf.gl_pathc;
7553        globfree(&globbuf);
7554        return (count);
7555}
7556
7557int has_spectralscanning(const char *prefix)
7558{
7559#ifdef HAVE_MVEBU
7560        return 0;
7561#endif
7562        glob_t globbuf;
7563        int count = 0;
7564        char *globstring;
7565        int globresult;
7566        int devnum;
7567        // get legacy interface count
7568#ifdef HAVE_MADWIFI_MIMO
7569        if (!nvram_match("mimo_driver", "ath9k"))
7570                return (0);
7571#endif
7572        // correct index if there are legacy cards arround
7573        devnum = get_ath9k_phy_ifname(prefix);
7574        if (devnum == -1)
7575                return 0;
7576#ifdef HAVE_ATH10K
7577        if (is_ath10k(prefix))
7578                asprintf(&globstring, "/sys/kernel/debug/ieee80211/phy%d/ath10k/spectral_count", devnum);
7579        else
7580#endif
7581                asprintf(&globstring, "/sys/kernel/debug/ieee80211/phy%d/ath9k/spectral_count", devnum);
7582        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
7583        free(globstring);
7584        if (globresult == 0)
7585                count = (int)globbuf.gl_pathc;
7586        globfree(&globbuf);
7587        return (count);
7588}
7589#endif
7590
7591static int devicecountbydriver(const char *prefix, char *drivername)
7592{
7593        glob_t globbuf;
7594        int count = 0;
7595        char *globstring;
7596        int globresult;
7597        int devnum;
7598        // correct index if there are legacy cards arround... should not...
7599        devnum = get_ath9k_phy_ifname(prefix);
7600        if (devnum == -1)
7601                return 0;
7602        asprintf(&globstring, "/sys/class/ieee80211/phy%d/device/driver/module/drivers/pci:%s", devnum, drivername);
7603        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
7604        free(globstring);
7605        if (globresult == 0)
7606                count = (int)globbuf.gl_pathc;
7607        globfree(&globbuf);
7608        return (count);
7609
7610}
7611
7612#ifdef HAVE_ATH5K
7613int is_ath5k(const char *prefix)
7614{
7615        return devicecountbydriver(prefix, "ath5k");
7616}
7617#endif
7618#ifdef HAVE_MVEBU
7619int is_mvebu(const char *prefix)
7620{
7621        return devicecountbydriver(prefix, "mwlwifi");
7622}
7623#endif
7624#ifdef HAVE_ATH10K
7625int is_ath10k(const char *prefix)
7626{
7627        // get legacy interface count
7628#ifdef HAVE_MADWIFI_MIMO
7629        if (!nvram_match("mimo_driver", "ath9k"))
7630                return (0);
7631#endif
7632        return devicecountbydriver(prefix, "ath10k_pci");
7633}
7634
7635#endif
7636#ifdef HAVE_WIL6210
7637int is_wil6210(const char *prefix)
7638{
7639        if (!strcmp(prefix, "giwifi"))
7640                return 1;
7641        if (!strcmp(prefix, "ath2"))
7642                return 1;
7643        return 0;
7644        // get legacy interface count
7645//      return devicecountbydriver(prefix, "wil6210");
7646}
7647
7648#endif
7649
7650static int HTtoVHTindex(int mcs)
7651{
7652        if (mcs < 8)
7653                return mcs;
7654        if (mcs < 16)
7655                return mcs + 2;
7656        if (mcs < 24)
7657                return mcs + 4;
7658        return mcs + 6;
7659}
7660
7661int VHTTxRate(unsigned int mcs, unsigned int vhtmcs, unsigned int sgi, unsigned int bw)
7662{
7663        static int vHTTxRate20_800[40] = {
7664                6500, 13000, 19500, 26000, 39000, 52000, 58500, 65000, 78000, 78000,    // MCS 0 -8
7665                13000, 26000, 39000, 52000, 78000, 104000, 117000, 130000, 156000, 156000,      // MCS 8 - 15
7666                19500, 39000, 58500, 78000, 117000, 156000, 175500, 195000, 234000, 260000,     // MCS 16 - 23
7667                26000, 52000, 78000, 104000, 156000, 208000, 234000, 260000, 312000, 312000     // MCS 24 - 31
7668        };
7669        static int vHTTxRate20_400[40] = {
7670                7200, 14400, 21700, 28900, 43300, 57800, 65000, 72200, 86700, 86700,    //
7671                14444, 28889, 43333, 57778, 86667, 115556, 130000, 144444, 173300, 173300,      //
7672                21700, 43300, 65000, 86700, 130000, 173300, 195000, 216700, 260000, 288900,     //
7673                28900, 57800, 86700, 115600, 173300, 231100, 260000, 288900, 346700, 0  //
7674        };
7675        static int vHTTxRate40_800[40] = {
7676                13500, 27000, 40500, 54000, 81000, 108000, 121500, 135000, 162000, 180000,      //
7677                27000, 54000, 81000, 108000, 162000, 216000, 243000, 270000, 324000, 360000,    //
7678                40500, 81000, 121500, 162000, 243000, 324000, 364500, 405000, 486000, 540000,   //
7679                54000, 108000, 162000, 216000, 324000, 432000, 486000, 540000, 648000, 720000   //
7680        };
7681        static int vHTTxRate40_400[40] = {
7682                15000, 30000, 45000, 60000, 90000, 120000, 135000, 150000, 180000, 200000,      //
7683                30000, 60000, 90000, 120000, 180000, 240000, 270000, 300000, 360000, 400000,    //
7684                45000, 90000, 135000, 180000, 270000, 360000, 405000, 450000, 540000, 600000,   //
7685                60000, 120000, 180000, 240000, 360000, 480000, 540000, 600000, 720000, 800000   //
7686        };
7687        static int vHTTxRate80_800[40] = {
7688                29300, 58500, 87800, 117000, 175500, 234000, 263300, 292500, 351000, 390000,    //
7689                58500, 117000, 175500, 234000, 351000, 468000, 526500, 585000, 702000, 780000,
7690                87800, 175500, 263300, 351000, 526500, 702000, 0, 877500, 1053000, 1170000,     //
7691                117000, 234000, 351000, 468000, 702000, 936000, 1053000, 1170000, 1404000, 1560000
7692        };
7693        static int vHTTxRate80_400[40] = {
7694                32500, 65000, 97500, 130000, 195000, 260000, 292500, 325000, 390000, 433300,    //
7695                65000, 130000, 195000, 260000, 390000, 520000, 585000, 650000, 780000, 866700,  //
7696                97500, 195000, 292500, 390000, 585000, 780000, 0, 975000, 1170000, 1300000,     //
7697                130000, 260000, 390000, 520000, 780000, 1040000, 1170000, 1300000, 1560000, 1733300
7698        };
7699        static int vHTTxRate160_800[40] = {
7700                58500, 117000, 175500, 234000, 351000, 468000, 526500, 585000, 702000, 780000,
7701                117000, 234000, 351000, 468000, 702000, 936000, 1053000, 1170000, 1404000, 1560000,
7702                175500, 351000, 526500, 702000, 1053000, 1404000, 1579500, 1755000, 2106000, 2106000,
7703                234000, 468000, 702000, 936000, 1404000, 1872000, 2106000, 2340000, 2808000, 3120000,
7704
7705        };
7706        static int vHTTxRate160_400[40] = {
7707                65000, 130000, 195000, 260000, 390000, 520000, 585000, 650000, 780000, 866700,  //
7708                130000, 260000, 390000, 520000, 780000, 1040000, 1170000, 1300000, 1560000, 1733300,
7709                195000, 390000, 585000, 780000, 1170000, 1560000, 1755000, 1950000, 2340000, 2340000,
7710                260000, 520000, 780000, 1040000, 1560000, 2080000, 2340000, 2600000, 3120000, 3466700,
7711        };
7712
7713        int *table = vHTTxRate20_400;
7714//      fprintf(stderr, "sgi %d mcs %d vhtmcs %d\n", sgi, mcs, vhtmcs);
7715        if (sgi) {
7716                switch (bw) {
7717                case 20:
7718                        table = vHTTxRate20_400;
7719                        break;
7720                case 40:
7721                        table = vHTTxRate40_400;
7722                        break;
7723                case 80:
7724                        table = vHTTxRate80_400;
7725                        break;
7726                case 160:
7727                        table = vHTTxRate160_400;
7728                        break;
7729                }
7730        } else {
7731
7732                switch (bw) {
7733                case 20:
7734                        table = vHTTxRate20_800;
7735                        break;
7736                case 40:
7737                        table = vHTTxRate40_800;
7738                        break;
7739                case 80:
7740                        table = vHTTxRate80_800;
7741                        break;
7742                case 160:
7743                        table = vHTTxRate160_800;
7744                        break;
7745                }
7746        }
7747        if (vhtmcs == -1) {
7748                vhtmcs = HTtoVHTindex(mcs);
7749        }
7750
7751        return table[vhtmcs];
7752}
7753
7754int writeproc(char *path, char *value)
7755{
7756        int fd;
7757        fd = open(path, O_WRONLY);
7758        if (fd == -1) {
7759                fprintf(stderr, "cannot open %s\n", path);
7760                return -1;
7761        }
7762        write(fd, value, strlen(value));
7763        close(fd);
7764        return 0;
7765}
7766
7767int writeprocsysnet(char *path, char *value)
7768{
7769        char syspath[64];
7770        snprintf(syspath, 64, "/proc/sys/net/%s", path);
7771        return writeproc(syspath, value);
7772}
7773
7774int writeprocsys(char *path, char *value)
7775{
7776        char syspath[64];
7777        snprintf(syspath, 64, "/proc/sys/%s", path);
7778        return writeproc(syspath, value);
7779}
7780
7781int writevaproc(char *value, char *fmt, ...)
7782{
7783        char varbuf[256];
7784        va_list args;
7785
7786        va_start(args, (char *)fmt);
7787        vsnprintf(varbuf, sizeof(varbuf), fmt, args);
7788        va_end(args);
7789        return writeproc(varbuf, value);
7790}
7791
7792void set_smp_affinity(int irq, int cpu)
7793{
7794        char s_cpu[32];
7795        snprintf(s_cpu, sizeof(s_cpu), "%d", cpu);
7796        writevaproc(s_cpu, "/proc/irq/%d/smp_affinity", irq);
7797}
7798
7799/* gartarp */
7800
7801struct arph {
7802        uint16_t hw_type;
7803
7804#define ARPHDR_ETHER    1
7805
7806        uint16_t proto_type;
7807
7808        char ha_len;
7809        char pa_len;
7810
7811#define ARPOP_BROADCAST 1
7812#define ARPOP_REPLY     2
7813        uint16_t opcode;
7814        char source_add[ETH_ALEN];
7815        char source_ip[IP_ALEN];
7816        char dest_add[ETH_ALEN];
7817        char dest_ip[IP_ALEN];
7818
7819} __attribute__((packed));
7820
7821#define ARP_HLEN        sizeof(struct arph) + ETH_HLEN
7822#define BCAST           "\xff\xff\xff\xff\xff\xff"
7823
7824static inline int get_iface_attr(int sk, char *iface, char *hw, char *paddr)
7825{
7826        int ret;
7827        struct ifreq ifr;
7828
7829        strcpy(ifr.ifr_name, iface);
7830
7831        ret = ioctl(sk, SIOCGIFHWADDR, &ifr);
7832        if (unlikely(ret == -1)) {
7833                perror("ioctl SIOCGIFHWADDR");
7834                return ret;
7835        }
7836        memcpy(hw, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
7837
7838        ret = ioctl(sk, SIOCGIFADDR, &ifr);
7839        if (unlikely(ret == -1)) {
7840                perror("ioctl SIOCGIFADDR");
7841                return ret;
7842        }
7843        memcpy(paddr, ifr.ifr_addr.sa_data + 2, IP_ALEN);
7844
7845        return ret;
7846}
7847
7848static inline void setup_eth(struct ether_header *eth, char *hw_addr)
7849{
7850        memcpy(eth->ether_shost, hw_addr, ETH_ALEN);
7851        memcpy(eth->ether_dhost, BCAST, ETH_ALEN);
7852        eth->ether_type = htons(ETH_P_ARP);
7853}
7854
7855static inline void setup_garp(struct arph *arp, char *hw_addr, char *paddr)
7856{
7857        arp->hw_type = htons(ARPHDR_ETHER);
7858        arp->proto_type = htons(ETH_P_IP);
7859        arp->ha_len = ETH_ALEN;
7860        arp->pa_len = IP_ALEN;
7861
7862        memcpy(arp->source_add, hw_addr, ETH_ALEN);
7863        memcpy(arp->source_ip, paddr, IP_ALEN);
7864}
7865
7866static inline void setup_garp_broadcast(struct arph *arp, char *paddr)
7867{
7868        arp->opcode = htons(ARPOP_BROADCAST);
7869
7870        memset(arp->dest_add, 0, ETH_ALEN);
7871        memcpy(arp->dest_ip, paddr, IP_ALEN);
7872}
7873
7874static inline void setup_garp_reply(struct arph *arp, char *hw_addr, char *paddr)
7875{
7876        arp->opcode = htons(ARPOP_REPLY);
7877
7878        memcpy(arp->dest_add, hw_addr, ETH_ALEN);
7879        memcpy(arp->dest_ip, paddr, IP_ALEN);
7880}
7881
7882/*
7883 * send_garp
7884 *
7885 * - sends 20 gartuitous arps
7886 * in a 200 millisec interval.
7887 * One as braadcast and one as reply.
7888 *
7889 *
7890 * parameter iface: sending interface name
7891 *
7892 * returns false on failure
7893 *         true on success
7894 */
7895static int send_garp(char *iface)
7896{
7897        char pkt[ARP_HLEN];
7898        char iface_hw[ETH_ALEN];
7899        char iface_paddr[IP_ALEN];
7900        struct sockaddr_ll link;
7901        struct ether_header *eth;
7902        struct arph *arp;
7903        int rc;
7904        int sk;
7905        int n_garps = 10;
7906
7907        eth = (struct ether_header *)pkt;
7908        arp = (struct arph *)(pkt + ETH_HLEN);
7909
7910        sk = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
7911        if (unlikely(sk == -1)) {
7912                perror("socket");
7913                return sk;
7914        }
7915
7916        rc = get_iface_attr(sk, iface, iface_hw, iface_paddr);
7917        if (unlikely(rc == -1))
7918                goto out;
7919
7920        /* set link layer information for driver */
7921        memset(&link, 0, sizeof(link));
7922        link.sll_family = AF_PACKET;
7923        link.sll_ifindex = if_nametoindex(iface);
7924
7925        setup_eth(eth, iface_hw);
7926        setup_garp(arp, iface_hw, iface_paddr);
7927
7928        while (n_garps--) {
7929                setup_garp_broadcast(arp, iface_paddr);
7930                rc = sendto(sk, pkt, ARP_HLEN, 0, (struct sockaddr *)&link, sizeof(struct sockaddr_ll)
7931                    );
7932                if (unlikely(rc == -1)) {
7933                        perror("sendto");
7934                        goto out;
7935                }
7936
7937                setup_garp_reply(arp, iface_hw, iface_paddr);
7938                rc = sendto(sk, pkt, ARP_HLEN, 0, (struct sockaddr *)&link, sizeof(struct sockaddr_ll)
7939                    );
7940                if (unlikely(rc == -1)) {
7941                        perror("sendto");
7942                        goto out;
7943                }
7944                usleep(200000);
7945        }
7946
7947out:
7948        close(sk);
7949        return rc;
7950}
7951
7952int gratarp_main(char *iface)
7953{
7954        if (iface) {
7955                usleep(500000);
7956                send_garp(iface);
7957        }
7958
7959        return 0;
7960}
7961
7962/* NF Mark/Mask
7963 *
7964 * since multiple services needs a NF packet mark,
7965 * we need to use masks to split the 32bit value into several pieces
7966 *
7967 *                                             31       23       15       7      0
7968 * port_forwards         1 bit(s) offset 31  > 10000000 00000000 00000000 00000000
7969 * hotspot                               8 bit(s) offset 23  > 01111111 10000000 00000000 00000000
7970 * quality of service   13 bit(s) offset 10  > 00000000 01111111 11111100 00000000
7971 *
7972 * the remaining 11 bits are currently not in use
7973 */
7974
7975struct NF_MASKS {
7976        char *service_name;     // name of the service
7977        int bits_used;          // bits used by this service
7978        int bit_offset;         // position of the fist bit
7979};
7980
7981static struct NF_MASKS service_masks[] = {
7982        {"FORWARD", 1, 31},
7983        {"HOTSPOT", 8, 23},
7984        {"QOS", 13, 10},
7985};
7986
7987char *get_NFServiceMark(char *service, uint32 mark)
7988{
7989        static char buffer[24];
7990        memset(&buffer, 0, sizeof(buffer));
7991
7992#if defined(ARCH_broadcom) && !defined(HAVE_BCMMODERN)
7993// no mask support possible in kernel 2.4
7994        sprintf(buffer, "0x%x", mark);
7995        return buffer;
7996#else
7997        int x, offset, bitpos;
7998        uint32 nfmark = 0, nfmask = 0;
7999
8000        for (x = 0; x < sizeof(service_masks) / sizeof(struct NF_MASKS); x++) {
8001                if (strcmp(service, service_masks[x].service_name) == 0) {
8002                        if (mark >= (1 << service_masks[x].bits_used))
8003                                return "0xffffffff/0xffffffff";
8004
8005                        offset = service_masks[x].bit_offset;
8006                        bitpos = offset + service_masks[x].bits_used - 1;
8007
8008                        nfmark = (mark << offset);
8009
8010                        for (; bitpos >= offset; bitpos--)
8011                                nfmask |= (1 << bitpos);
8012
8013                        sprintf(buffer, "0x%x/0x%x", nfmark, nfmask);
8014                        return buffer;
8015                }
8016        }
8017        return "0xffffffff/0xffffffff";
8018#endif
8019}
8020
8021char *qos_nfmark(uint32 x)
8022{
8023        return get_NFServiceMark("QOS", x);
8024}
8025
8026void getPortMapping(int *vlanmap)
8027{
8028        if (nvram_match("vlan1ports", "0 5")) {
8029                vlanmap[0] = 0;
8030                vlanmap[5] = 5;
8031                if (nvram_match("vlan0ports", "4 3 2 1 5*")) {
8032                        vlanmap[1] = 4;
8033                        vlanmap[2] = 3;
8034                        vlanmap[3] = 2;
8035                        vlanmap[4] = 1;
8036                } else if (nvram_match("vlan0ports", "4 1 2 3 5*")) {
8037                        vlanmap[1] = 4;
8038                        vlanmap[2] = 1;
8039                        vlanmap[3] = 2;
8040                        vlanmap[4] = 3;
8041                } else          // nvram_match ("vlan0ports", "1 2 3 4 5*")
8042                        // nothing to do
8043                {
8044                }
8045        } else if (nvram_match("vlan2ports", "0 5u")) {
8046                vlanmap[0] = 0;
8047                vlanmap[5] = 5;
8048                if (nvram_match("vlan1ports", "4 3 2 1 5*")) {
8049                        vlanmap[1] = 4;
8050                        vlanmap[2] = 3;
8051                        vlanmap[3] = 2;
8052                        vlanmap[4] = 1;
8053                } else if (nvram_match("vlan1ports", "4 1 2 3 5*")) {
8054                        vlanmap[1] = 4;
8055                        vlanmap[2] = 1;
8056                        vlanmap[3] = 2;
8057                        vlanmap[4] = 3;
8058                }
8059                if (nvram_match("vlan1ports", "4 3 2 1 5*") && nvram_matchi("boardnum", 32)) {  //R7000
8060                        vlanmap[1] = 1;
8061                        vlanmap[2] = 2;
8062                        vlanmap[3] = 3;
8063                        vlanmap[4] = 4;
8064                }
8065        } else if (nvram_match("vlan1ports", "4 5")) {
8066                vlanmap[0] = 4;
8067                vlanmap[5] = 5;
8068                if (nvram_match("vlan0ports", "0 1 2 3 5*")) {
8069                        vlanmap[1] = 0;
8070                        vlanmap[2] = 1;
8071                        vlanmap[3] = 2;
8072                        vlanmap[4] = 3;
8073                } else          // nvram_match ("vlan0ports", "3 2 1 0 5*")
8074                {
8075                        vlanmap[1] = 3;
8076                        vlanmap[2] = 2;
8077                        vlanmap[3] = 1;
8078                        vlanmap[4] = 0;
8079                }
8080        } else if (nvram_match("vlan1ports", "1 5")) {  // Linksys WTR54GS
8081                vlanmap[5] = 5;
8082                vlanmap[0] = 1;
8083                vlanmap[1] = 0;
8084        } else if (nvram_match("vlan2ports", "0 8") || nvram_match("vlan2ports", "0 8u") || nvram_match("vlan2ports", "0 8t") || nvram_match("vlan2ports", "0 8*")) {
8085                vlanmap[0] = 0;
8086                vlanmap[5] = 8;
8087                if (nvram_match("vlan1ports", "4 3 2 1 8*")) {
8088                        vlanmap[1] = 4;
8089                        vlanmap[2] = 3;
8090                        vlanmap[3] = 2;
8091                        vlanmap[4] = 1;
8092                }
8093        } else if (nvram_match("vlan2ports", "4 8") || nvram_match("vlan2ports", "4 8u")) {
8094                vlanmap[0] = 4;
8095                vlanmap[5] = 8;
8096                if (nvram_match("vlan1ports", "0 1 2 3 8*")) {
8097                        vlanmap[1] = 0;
8098                        vlanmap[2] = 1;
8099                        vlanmap[3] = 2;
8100                        vlanmap[4] = 3;
8101                } else          // "3 2 1 0 8*"
8102                {
8103                        vlanmap[1] = 3;
8104                        vlanmap[2] = 2;
8105                        vlanmap[3] = 1;
8106                        vlanmap[4] = 0;
8107                }
8108                if (nvram_match("vlan1ports", "0 1 2 3 8*") && nvram_matchi("boardnum", 4536)) {        // WNDR4500/WNDR4500V2/R6300V1
8109                        vlanmap[1] = 3;
8110                        vlanmap[2] = 2;
8111                        vlanmap[3] = 1;
8112                        vlanmap[4] = 0;
8113                }
8114                if (nvram_match("vlan1ports", "3 2 1 0 5 7 8*") && nvram_matchi("boardnum", 32)) {
8115                        vlanmap[1] = 0;
8116                        vlanmap[2] = 1;
8117                        vlanmap[3] = 2;
8118                        vlanmap[4] = 3;
8119                }
8120        } else if (nvram_match("vlan1ports", "4 8")) {
8121                vlanmap[0] = 4;
8122                vlanmap[5] = 8;
8123                if (nvram_match("vlan2ports", "0 1 2 3 8*")) {
8124                        vlanmap[1] = 0;
8125                        vlanmap[2] = 1;
8126                        vlanmap[3] = 2;
8127                        vlanmap[4] = 3;
8128                }
8129        } else if (nvram_match("vlan2ports", "4 5") || nvram_match("vlan2ports", "4 5u")) {
8130                vlanmap[0] = 4;
8131                vlanmap[5] = 5;
8132                if (nvram_match("vlan1ports", "0 1 2 3 5*")) {
8133                        vlanmap[1] = 0;
8134                        vlanmap[2] = 1;
8135                        vlanmap[3] = 2;
8136                        vlanmap[4] = 3;
8137                } else {        // nvram_match ("vlan1ports", "3 2 1 0 5*")
8138                        vlanmap[1] = 3;
8139                        vlanmap[2] = 2;
8140                        vlanmap[3] = 1;
8141                        vlanmap[4] = 0;
8142                }
8143                if (nvram_match("vlan1ports", "0 1 2 3 5*") && nvram_matchi("boardnum", 679)) { //R6300V2
8144                        vlanmap[1] = 3;
8145                        vlanmap[2] = 2;
8146                        vlanmap[3] = 1;
8147                        vlanmap[4] = 0;
8148                }
8149
8150        } else if (nvram_match("vlan2ports", "0 5u")) {
8151                vlanmap[0] = 0;
8152                vlanmap[5] = 5;
8153
8154                vlanmap[1] = 1;
8155                vlanmap[2] = 2;
8156                vlanmap[3] = 3;
8157                vlanmap[4] = 4;
8158        }
8159
8160}
8161
8162u_int64_t freediskSpace(char *path)
8163{
8164        struct statfs sizefs;
8165
8166        if ((statfs(path, &sizefs) != 0) || (sizefs.f_type == 0x73717368)) {
8167                memset(&sizefs, 0, sizeof(sizefs));
8168        }
8169
8170        return (u_int64_t)sizefs.f_bsize * (u_int64_t)sizefs.f_bfree;
8171}
8172
8173void getSystemMac(char *newmac)
8174{
8175        int brand = getRouterBrand();
8176        switch (brand) {
8177        case ROUTER_ASUS_AC87U:
8178        case ROUTER_ASUS_AC88U:
8179        case ROUTER_ASUS_AC5300:
8180                strcpy(newmac, nvram_safe_get("et1macaddr"));
8181                break;
8182        case ROUTER_NETGEAR_R8000:
8183        case ROUTER_NETGEAR_R8500:
8184        case ROUTER_TRENDNET_TEW828:
8185        case ROUTER_ASUS_AC3100:
8186                strcpy(newmac, nvram_safe_get("et2macaddr"));
8187                break;
8188        case ROUTER_DLINK_DIR885:
8189                if (nvram_get("et0macaddr"))
8190                        strcpy(newmac, nvram_safe_get("et0macaddr"));
8191                else
8192                        strcpy(newmac, nvram_safe_get("et2macaddr"));
8193                break;
8194        default:
8195                strcpy(newmac, nvram_safe_get("et0macaddr"));
8196                break;
8197        }
8198
8199}
8200
8201void strcpyto(char *dest, char *src, char c)
8202{
8203        int cnt = 0;
8204        int len = strlen(src);
8205        while (cnt < len && src[cnt] != c) {
8206                dest[cnt] = src[cnt];
8207                cnt++;
8208        }
8209        dest[cnt] = '\0';
8210}
8211
8212char *chomp(char *s)
8213{
8214        char *c = (s) + strlen((s)) - 1;
8215        while ((c > (s)) && (*c == '\n' || *c == '\r' || *c == ' '))
8216                *c-- = '\0';
8217        return s;
8218}
8219
8220char *foreach_first(char *foreachwordlist, char *word)
8221{
8222        char *next = &foreachwordlist[strspn(foreachwordlist, " ")];
8223        strcpyto(word, next, ' ');
8224        next = strchr(next, ' ');
8225        return next;
8226}
8227
8228char *foreach_last(char *next, char *word)
8229{
8230        next = next ? &next[strspn(next, " ")] : "";
8231        strcpyto(word, next, ' ');
8232        next = strchr(next, ' ');
8233        return next;
8234}
8235
8236#define MAX_BRIDGES     1024
8237
8238#include <linux/if_bridge.h>
8239int isbridge(char *name)
8240{
8241        int i, num;
8242        char ifname[IFNAMSIZ];
8243        int ifindices[MAX_BRIDGES];
8244        int br_socket_fd = -1;
8245        unsigned long args[3] = { BRCTL_GET_BRIDGES,
8246                (unsigned long)ifindices, MAX_BRIDGES
8247        };
8248
8249        if ((br_socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
8250                return 0;
8251
8252        num = ioctl(br_socket_fd, SIOCGIFBR, args);
8253        close(br_socket_fd);
8254        if (num < 0) {
8255                return 0;
8256        }
8257
8258        for (i = 0; i < num; i++) {
8259                if (!if_indextoname(ifindices[i], ifname)) {
8260                        return 0;
8261                }
8262
8263                if (!strcmp(ifname, name))
8264                        return 1;
8265        }
8266        return 0;
8267
8268}
8269
8270#if 0
8271int isbridge(char *name)
8272{
8273        char path[64];
8274        struct stat st;
8275        memset(&st, 0, sizeof(struct stat));
8276        sprintf(path, "/sys/class/net/%s/bridge", name);
8277        return (stat(path, &st) == 0) && (S_ISDIR(st.st_mode));
8278
8279}
8280#endif
8281
8282#if defined(HAVE_X86) || defined(HAVE_RB600) || defined(HAVE_EROUTER) && !defined(HAVE_WDR4900)
8283char *getdisc(void)             // works only for squashfs
8284{
8285        int i;
8286        static char ret[8];
8287        char *disks[] = { "sda2", "sdb2", "sdc2", "sdd2", "sde2", "sdf2", "sdg2", "sdh2",
8288                "sdi2", "mmcblk0p2"
8289        };
8290        for (i = 0; i < 10; i++) {
8291                char dev[64];
8292
8293                sprintf(dev, "/dev/%s", disks[i]);
8294                FILE *in = fopen(dev, "rb");
8295
8296                if (in == NULL)
8297                        continue;       // no second partition or disc does not
8298                // exist, skipping
8299                char buf[4];
8300
8301                fread(buf, 4, 1, in);
8302                if ((buf[0] == 't' && buf[1] == 'q' && buf[2] == 's' && buf[3] == 'h')
8303                    || (buf[0] == 'h' && buf[1] == 's' && buf[2] == 'q' && buf[3] == 't')
8304                    || (buf[0] == 'h' && buf[1] == 's' && buf[2] == 'q' && buf[3] == 's')) {
8305                        fclose(in);
8306                        // filesystem detected
8307                        memset(ret, 0, 8);
8308                        if (strlen(disks[i]) == 4)
8309                                strncpy(ret, disks[i], 3);
8310                        else
8311                                strncpy(ret, disks[i], 7);
8312                        return ret;
8313                }
8314                fclose(in);
8315        }
8316        return NULL;
8317}
8318#endif
Note: See TracBrowser for help on using the repository browser.