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

Last change on this file since 32589 was 32589, checked in by brainslayer, 3 weeks ago

format code

File size: 234.1 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                bzero(&ifr, 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        bzero(&tcfmark, sizeof(tcfmark));
591        bzero(&nfmark, 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        FILE *fp = fopen("/dev/mtdblock3", "rb");
1865        if (fp) {
1866                fseek(fp, 64, SEEK_SET);
1867                char sign[32];
1868                fread(&sign, 32, 1, fp);
1869                fclose(fp);
1870                if (!memcmp(sign, "DIR-882", 7)) {
1871                        setRouter("Dlink DIR-882 A1");
1872                        return ROUTER_DIR882;
1873                }
1874                if (!memcmp(sign, "DIR-878", 7)) {
1875                        setRouter("Dlink DIR-878 A1");
1876                        return ROUTER_DIR882;
1877                }
1878        }
1879        setRouter("Dlink DIR-860L B1");
1880        return ROUTER_DIR860LB1;
1881#elif HAVE_DIR810L
1882        void *getUEnv(char *name);
1883
1884        char *hw = getUEnv("HW_BOARD_REV");
1885        if (hw) {
1886                if (!strcmp(hw, "B1"))
1887                        setRouter("Dlink DIR-810L B1");
1888                else if (!strcmp(hw, "A1"))
1889                        setRouter("Dlink DIR-810L A1");
1890                else if (!strcmp(hw, "C1"))
1891                        setRouter("Dlink DIR-810L C1");
1892                else
1893                        setRouter("Dlink DIR-810L XX");
1894
1895        } else
1896                setRouter("Dlink DIR-810L");
1897        return ROUTER_DIR810L;
1898#elif HAVE_WHR1166D
1899        setRouter("Buffalo WHR-1166D");
1900        return ROUTER_WHR300HP2;
1901#elif HAVE_WHR300HP2
1902        FILE *fp = fopen("/sys/bus/pci/devices/0000:01:00.0/device", "rb");
1903        if (fp) {
1904                fclose(fp);
1905                setRouter("Buffalo WHR-600D");
1906                return ROUTER_WHR300HP2;
1907        }
1908        setRouter("Buffalo WHR-300HP2");
1909        return ROUTER_WHR300HP2;
1910#elif HAVE_F5D8235
1911        setRouter("Belkin F5D8235-4 v2");
1912        return ROUTER_BOARD_F5D8235;
1913#elif HAVE_HAMEA15
1914        setRouter("Hame A-15");
1915        return ROUTER_BOARD_HAMEA15;
1916#elif HAVE_WCRGN
1917        setRouter("Buffalo WCR-GN");
1918        return ROUTER_BOARD_WCRGN;
1919#elif HAVE_WHRG300N
1920        setRouter("Buffalo WHR-G300N");
1921        return ROUTER_BOARD_WHRG300N;
1922#elif HAVE_WR5422
1923        setRouter("Repotec RP-WR5422");
1924        return ROUTER_BOARD_WR5422;
1925#else
1926        setRouter("Generic RT2880");
1927        return ROUTER_BOARD_RT2880;
1928#endif
1929#elif HAVE_X86
1930#ifdef HAVE_CORENET
1931        setRouter("CORENET X86i");
1932        return ROUTER_BOARD_X86;
1933#else
1934        setRouter("Generic X86");
1935        return ROUTER_BOARD_X86;
1936#endif
1937#elif HAVE_XSCALE
1938        setRouter("NewMedia Dual A/B/G");
1939        return ROUTER_BOARD_XSCALE;
1940#elif HAVE_MAGICBOX
1941        setRouter("OpenRB PowerPC Board");
1942        return ROUTER_BOARD_MAGICBOX;
1943#elif HAVE_UNIWIP
1944        setRouter("Octagon Systems UNiWiP");
1945        return ROUTER_BOARD_UNIWIP;
1946#elif HAVE_WDR4900
1947        setRouter("TP-Link WDR4900 V1");
1948        return ROUTER_BOARD_WDR4900;
1949#elif HAVE_RB1000
1950        setRouter("Mikrotik RB1000");
1951        return ROUTER_BOARD_RB600;
1952#elif HAVE_RB800
1953        setRouter("Mikrotik RB800");
1954        return ROUTER_BOARD_RB600;
1955#elif HAVE_RB600
1956        setRouter("Mikrotik RB600");
1957        return ROUTER_BOARD_RB600;
1958#elif HAVE_GWMF54G2
1959        setRouter("Planex GW-MF54G2");
1960        char mac[32];
1961        getBoardMAC(mac);
1962        if (!strncmp(mac, "00:19:3B", 8) || !strncmp(mac, "00:02:6F", 8)
1963            || !strncmp(mac, "00:15:6D", 8)) {
1964                fprintf(stderr, "unsupported board\n");
1965                sys_reboot();
1966        }
1967        return ROUTER_BOARD_FONERA;
1968#elif HAVE_WRT54GV7
1969        setRouter("Linksys WRT54G v7");
1970        return ROUTER_BOARD_FONERA;
1971#elif HAVE_WRK54G
1972        setRouter("Linksys WRK54G v3");
1973        return ROUTER_BOARD_FONERA;
1974#elif HAVE_WGT624
1975        setRouter("Netgear WGT624 v4");
1976        return ROUTER_BOARD_FONERA;
1977#elif HAVE_WPE53G
1978        setRouter("Compex WPE53G");
1979        return ROUTER_BOARD_FONERA;
1980#elif HAVE_NP25G
1981        setRouter("Compex NP25G");
1982        return ROUTER_BOARD_FONERA;
1983#elif HAVE_MR3202A
1984        setRouter("MR3202A");
1985        return ROUTER_BOARD_FONERA;
1986#elif HAVE_DLM101
1987        setRouter("Doodle Labs DLM-101");
1988        return ROUTER_BOARD_FONERA;
1989#elif HAVE_AR430W
1990        setRouter("Airlink-101 AR430W");
1991        return ROUTER_BOARD_FONERA;
1992#elif HAVE_DIR400
1993        setRouter("D-Link DIR-400");
1994        return ROUTER_BOARD_FONERA2200;
1995#elif HAVE_WRT54G2
1996        setRouter("Linksys WRT54G2 v1.1");
1997        return ROUTER_BOARD_FONERA;
1998#elif HAVE_RTG32
1999        setRouter("Asus RT-G32");
2000        return ROUTER_BOARD_FONERA;
2001#elif HAVE_DIR300
2002        setRouter("D-Link DIR-300");
2003        return ROUTER_BOARD_FONERA;
2004#elif HAVE_CNC
2005        setRouter("WiFi4You Outdoor AP");
2006        return ROUTER_BOARD_FONERA;
2007#elif defined(HAVE_CORENET) && defined(HAVE_NS2)
2008        setRouter("CORENET XNS2");
2009        return ROUTER_BOARD_LS2;
2010#elif defined(HAVE_CORENET) && defined(HAVE_LC2)
2011        setRouter("CORENET XLO2");
2012        return ROUTER_BOARD_LS2;
2013#elif defined(HAVE_CORENET) && defined(HAVE_EOC2610)
2014        setRouter("CORENET XC61");
2015        return ROUTER_BOARD_FONERA;
2016#elif defined(HAVE_CORENET) && defined(HAVE_EOC1650)
2017        setRouter("CORENET XC65");
2018        return ROUTER_BOARD_FONERA;
2019#elif defined(HAVE_CORENET) && defined(HAVE_BS2)
2020        setRouter("CORENET XBU2");
2021        return ROUTER_BOARD_LS2;
2022#elif defined(HAVE_CORENET) && defined(HAVE_BS2HP)
2023        setRouter("CORENET MBU2i");
2024        return ROUTER_BOARD_LS2;
2025#elif HAVE_WBD500
2026        setRouter("Wiligear WBD-500");
2027        return ROUTER_BOARD_FONERA;
2028#elif HAVE_EOC1650
2029        setRouter("Senao EOC-1650");
2030        return ROUTER_BOARD_FONERA;
2031#elif HAVE_EOC2611
2032        setRouter("Senao EOC-2611");
2033        return ROUTER_BOARD_FONERA;
2034#elif HAVE_EOC2610
2035#ifdef HAVE_TRIMAX
2036        setRouter("M2M-1200");
2037#else
2038        setRouter("Senao EOC-2610");
2039#endif
2040        return ROUTER_BOARD_FONERA;
2041#elif HAVE_ECB3500
2042        setRouter("Senao ECB-3500");
2043        return ROUTER_BOARD_FONERA;
2044#elif HAVE_EAP3660
2045        setRouter("Senao EAP-3660");
2046        return ROUTER_BOARD_FONERA;
2047#elif HAVE_MR3201A
2048        setRouter("Accton MR3201A");
2049        return ROUTER_BOARD_FONERA;
2050#elif HAVE_FONERA
2051        struct mii_ioctl_data *data;
2052        struct ifreq iwr;
2053        char mac[32];
2054        getBoardMAC(mac);
2055        if (!strncmp(mac, "00:19:3B", 8) || !strncmp(mac, "00:02:6F", 8)
2056            || !strncmp(mac, "00:15:6D", 8) || !strncmp(mac, "00:C0:CA", 8)) {
2057                fprintf(stderr, "unsupported board\n");
2058                sys_reboot();
2059        }
2060        int s = socket(AF_INET, SOCK_DGRAM, 0);
2061
2062        if (s < 0) {
2063                fprintf(stderr, "socket(SOCK_DRAGM)\n");
2064                setRouter("Fonera 2100/2200");
2065                return ROUTER_BOARD_FONERA;
2066        }
2067        (void)strncpy(iwr.ifr_name, "eth0", sizeof("eth0"));
2068        data = (struct mii_ioctl_data *)&iwr.ifr_data;
2069        data->phy_id = 0x10;
2070        data->reg_num = 0x2;
2071        ioctl(s, SIOCGMIIREG, &iwr);
2072        data->phy_id = 0x10;
2073        data->reg_num = 0x2;
2074        ioctl(s, SIOCGMIIREG, &iwr);
2075        if (data->val_out == 0x0141) {
2076                data->phy_id = 0x10;
2077                data->reg_num = 0x3;
2078                ioctl(s, SIOCGMIIREG, &iwr);
2079                close(s);
2080                if ((data->val_out & 0xfc00) != 0x0c00) // marvell phy
2081                {
2082                        setRouter("Fonera 2100/2200");
2083                        return ROUTER_BOARD_FONERA;
2084                } else {
2085                        setRouter("Fonera 2201");
2086                        return ROUTER_BOARD_FONERA2200;
2087                }
2088        } else {
2089                setRouter("Fonera 2100/2200");
2090                return ROUTER_BOARD_FONERA;
2091        }
2092#elif HAVE_WRT1900AC
2093        FILE *fp = fopen("/sys/firmware/devicetree/base/model", "rb");
2094        if (!fp) {
2095                fprintf(stderr, "error opening device tree\n");
2096                setRouter("Linksys WRT1900AC");
2097                return ROUTER_WRT_1900AC;
2098        }
2099        char vendorstr[32];
2100        char modelstr[32];
2101        fscanf(fp, "%s %s", &vendorstr[0], &modelstr[0]);
2102        fclose(fp);
2103        if (!strcmp(modelstr, "WRT1200AC")) {
2104                setRouter("Linksys WRT1200AC");
2105                return ROUTER_WRT_1200AC;
2106        }
2107        if (!strcmp(modelstr, "WRT1900ACv2")) {
2108                setRouter("Linksys WRT1900ACv2");
2109                return ROUTER_WRT_1900ACV2;     // similar
2110        }
2111        if (!strcmp(modelstr, "WRT1900AC")) {
2112                setRouter("Linksys WRT1900AC");
2113                return ROUTER_WRT_1900AC;       // similar
2114        }
2115
2116        if (!strcmp(modelstr, "WRT1900ACS")) {
2117                setRouter("Linksys WRT1900ACS");
2118                return ROUTER_WRT_1900ACS;      // similar
2119        }
2120        if (!strcmp(modelstr, "WRT3200ACM")) {
2121                setRouter("Linksys WRT3200ACM");
2122                return ROUTER_WRT_3200ACM;
2123        }
2124        setRouter("Linksys WRTXXXXACM");
2125        return ROUTER_WRT_3200ACM;
2126#elif HAVE_R9000
2127        setRouter("Netgear Nighthawk X10");
2128        return ROUTER_NETGEAR_R9000;
2129#elif HAVE_IPQ806X
2130        FILE *fp = fopen("/sys/firmware/devicetree/base/model", "rb");
2131        if (!fp) {
2132                fprintf(stderr, "error opening device tree\n");
2133                setRouter("Netgear R7500");
2134                return ROUTER_NETGEAR_R7500;
2135        }
2136        char vendorstr[32];
2137        char modelstr[32];
2138        fscanf(fp, "%s %s", &vendorstr[0], &modelstr[0]);
2139        fclose(fp);
2140        if (!strcmp(modelstr, "R7800")) {
2141                setRouter("Netgear R7800");
2142                return ROUTER_NETGEAR_R7800;
2143        }
2144
2145        if (!strcmp(modelstr, "R7500v2")) {
2146                setRouter("Netgear R7500v2");
2147                return ROUTER_NETGEAR_R7500V2;
2148        }
2149
2150        if (!strcmp(modelstr, "R7500")) {
2151                setRouter("Netgear R7500");
2152                return ROUTER_NETGEAR_R7500;
2153        }
2154
2155        if (!strcmp(modelstr, "EA8500")) {
2156                setRouter("Linksys EA8500");
2157                return ROUTER_LINKSYS_EA8500;
2158        }
2159
2160        if (!strcmp(modelstr, "TEW-827")) {
2161                setRouter("Trendnet TEW-827");
2162                return ROUTER_TRENDNET_TEW827;
2163        }
2164
2165        if (!strcmp(modelstr, "G10")) {
2166                setRouter("ASRock G10");
2167                return ROUTER_ASROCK_G10;
2168        }
2169#elif HAVE_MERAKI
2170        setRouter("Meraki Mini");
2171        return ROUTER_BOARD_MERAKI;
2172#elif HAVE_BWRG1000
2173        setRouter("Bountiful BWRG-1000");
2174        return ROUTER_BOARD_LS2;
2175#elif HAVE_WNR2200
2176        setRouter("Netgear WNR2200");
2177        nvram_default_get("ath0_rxantenna", "3");
2178        nvram_default_get("ath0_txantenna", "3");
2179        return ROUTER_BOARD_WHRHPGN;
2180#elif HAVE_WNR2000
2181        setRouter("Netgear WNR2000v3");
2182        nvram_default_get("ath0_rxantenna", "3");
2183        nvram_default_get("ath0_txantenna", "3");
2184        return ROUTER_BOARD_WHRHPGN;
2185#elif HAVE_WLAEAG300N
2186#ifdef HAVE_BUFFALO
2187        setRouter("WLAE-AG300N");
2188#else
2189        setRouter("Buffalo WLAE-AG300N");
2190#endif
2191        nvram_default_get("ath0_rxantenna", "3");
2192        nvram_default_get("ath0_txantenna", "3");
2193        return ROUTER_BOARD_WHRHPGN;
2194#elif HAVE_CARAMBOLA
2195#ifdef HAVE_ERC
2196        setRouter("ERC ServiceGate");
2197#else
2198        setRouter("8Devices Carambola 2");
2199#endif
2200        nvram_default_get("ath0_rxantenna", "1");
2201        nvram_default_get("ath0_txantenna", "1");
2202        return ROUTER_BOARD_WHRHPGN;
2203#elif HAVE_HORNET
2204        setRouter("Atheros Hornet");
2205        nvram_default_get("ath0_rxantenna", "1");
2206        nvram_default_get("ath0_txantenna", "1");
2207        return ROUTER_BOARD_WHRHPGN;
2208#elif HAVE_RB2011
2209        setRouter("Mikrotik RB2011");
2210        nvram_default_get("ath0_rxantenna", "3");
2211        nvram_default_get("ath0_txantenna", "3");
2212        nvram_default_get("ath1_rxantenna", "3");
2213        nvram_default_get("ath1_txantenna", "3");
2214        return ROUTER_BOARD_WHRHPGN;
2215#elif HAVE_WDR2543
2216        setRouter("TPLINK TL-WR2543");
2217        nvram_default_get("ath0_rxantenna", "7");
2218        nvram_default_get("ath0_txantenna", "7");
2219        return ROUTER_BOARD_WHRHPGN;
2220#elif HAVE_WDR3500
2221        setRouter("TPLINK TL-WDR3500 v1");
2222        nvram_default_get("ath0_rxantenna", "3");
2223        nvram_default_get("ath0_txantenna", "3");
2224        nvram_default_get("ath1_rxantenna", "3");
2225        nvram_default_get("ath1_txantenna", "3");
2226        return ROUTER_BOARD_WHRHPGN;
2227#elif HAVE_WDR3600
2228        setRouter("TPLINK TL-WDR3600 v1");
2229        nvram_default_get("ath0_rxantenna", "3");
2230        nvram_default_get("ath0_txantenna", "3");
2231        nvram_default_get("ath1_rxantenna", "3");
2232        nvram_default_get("ath1_txantenna", "3");
2233        return ROUTER_BOARD_WHRHPGN;
2234#elif HAVE_WDR4300
2235        setRouter("TPLINK TL-WDR4300 v1");
2236        nvram_default_get("ath0_rxantenna", "3");
2237        nvram_default_get("ath0_txantenna", "3");
2238        nvram_default_get("ath1_rxantenna", "7");
2239        nvram_default_get("ath1_txantenna", "7");
2240        return ROUTER_BOARD_WHRHPGN;
2241#elif HAVE_DIR835A1
2242        setRouter("Dlink DIR835-A1");
2243        nvram_default_get("ath0_rxantenna", "3");
2244        nvram_default_get("ath0_txantenna", "3");
2245        nvram_default_get("ath1_rxantenna", "7");
2246        nvram_default_get("ath1_txantenna", "7");
2247        return ROUTER_BOARD_WHRHPGN;
2248#elif HAVE_WNDR4300
2249        setRouter("Netgear WNDR4300");
2250        nvram_default_get("ath0_rxantenna", "3");
2251        nvram_default_get("ath0_txantenna", "3");
2252        nvram_default_get("ath1_rxantenna", "7");
2253        nvram_default_get("ath1_txantenna", "7");
2254        return ROUTER_BOARD_WHRHPGN;
2255#elif HAVE_WNDR3700V4
2256        setRouter("Netgear WNDR3700 V4");
2257        nvram_default_get("ath0_rxantenna", "3");
2258        nvram_default_get("ath0_txantenna", "3");
2259        nvram_default_get("ath1_rxantenna", "3");
2260        nvram_default_get("ath1_txantenna", "3");
2261        return ROUTER_BOARD_WHRHPGN;
2262#elif HAVE_TEW824
2263        setRouter("Trendnet TEW824DRU");
2264        nvram_default_get("ath0_rxantenna", "3");
2265        nvram_default_get("ath0_txantenna", "3");
2266        nvram_default_get("ath1_rxantenna", "3");
2267        nvram_default_get("ath1_txantenna", "3");
2268        return ROUTER_BOARD_WHRHPGN;
2269#elif HAVE_DIR866
2270        setRouter("Dlink DIR866-A1");
2271        nvram_default_get("ath0_rxantenna", "3");
2272        nvram_default_get("ath0_txantenna", "3");
2273        nvram_default_get("ath1_rxantenna", "3");
2274        nvram_default_get("ath1_txantenna", "3");
2275        return ROUTER_BOARD_WHRHPGN;
2276#elif HAVE_DAP2660
2277        setRouter("Dlink DAP2660");
2278        nvram_default_get("ath0_rxantenna", "3");
2279        nvram_default_get("ath0_txantenna", "3");
2280        nvram_default_get("ath1_rxantenna", "3");
2281        nvram_default_get("ath1_txantenna", "3");
2282        return ROUTER_BOARD_WHRHPGN;
2283#elif HAVE_DAP2330
2284        setRouter("Dlink DAP2330");
2285        nvram_default_get("ath0_rxantenna", "3");
2286        nvram_default_get("ath0_txantenna", "3");
2287        return ROUTER_BOARD_WHRHPGN;
2288#elif HAVE_DAP3662
2289        setRouter("Dlink DAP3662");
2290        nvram_default_get("ath0_rxantenna", "3");
2291        nvram_default_get("ath0_txantenna", "3");
2292        nvram_default_get("ath1_rxantenna", "3");
2293        nvram_default_get("ath1_txantenna", "3");
2294        return ROUTER_BOARD_WHRHPGN;
2295#elif HAVE_DIR862
2296        setRouter("Dlink DIR862-A1");
2297        nvram_default_get("ath0_rxantenna", "7");
2298        nvram_default_get("ath0_txantenna", "7");
2299        nvram_default_get("ath1_rxantenna", "7");
2300        nvram_default_get("ath1_txantenna", "7");
2301        return ROUTER_BOARD_WHRHPGN;
2302#elif HAVE_WILLY
2303        setRouter("Wallystech DR342-NAS");
2304        nvram_default_get("ath0_rxantenna", "3");
2305        nvram_default_get("ath0_txantenna", "3");
2306        return ROUTER_BOARD_WHRHPGN;
2307#elif HAVE_MMS344
2308        setRouter("Compex MMS344");
2309        nvram_default_get("ath0_rxantenna", "3");
2310        nvram_default_get("ath0_txantenna", "3");
2311        nvram_default_get("ath1_rxantenna", "3");
2312        nvram_default_get("ath1_txantenna", "3");
2313        return ROUTER_BOARD_WHRHPGN;
2314#elif HAVE_WDR4900V2
2315        setRouter("TPLINK WDR4900 v2");
2316        nvram_default_get("ath0_rxantenna", "7");
2317        nvram_default_get("ath0_txantenna", "7");
2318        nvram_default_get("ath1_rxantenna", "7");
2319        nvram_default_get("ath1_txantenna", "7");
2320        return ROUTER_BOARD_WHRHPGN;
2321#elif HAVE_ARCHERC5
2322        setRouter("TPLINK ARCHER-C5 v1");
2323        nvram_default_get("ath0_rxantenna", "7");
2324        nvram_default_get("ath0_txantenna", "7");
2325        nvram_default_get("ath1_rxantenna", "7");
2326        nvram_default_get("ath1_txantenna", "7");
2327        return ROUTER_BOARD_WHRHPGN;
2328#elif HAVE_ARCHERC7
2329        setRouter("TPLINK ARCHER-C7 v2");
2330        nvram_default_get("ath0_rxantenna", "7");
2331        nvram_default_get("ath0_txantenna", "7");
2332        nvram_default_get("ath1_rxantenna", "7");
2333        nvram_default_get("ath1_txantenna", "7");
2334        return ROUTER_BOARD_WHRHPGN;
2335#elif HAVE_WR1043V3
2336        setRouter("TPLINK WR1043ND V3");
2337        nvram_default_get("ath0_rxantenna", "7");
2338        nvram_default_get("ath0_txantenna", "7");
2339        return ROUTER_BOARD_WHRHPGN;
2340#elif HAVE_WR1043V2
2341        setRouter("TPLINK WR1043ND V2");
2342        nvram_default_get("ath0_rxantenna", "7");
2343        nvram_default_get("ath0_txantenna", "7");
2344        return ROUTER_BOARD_WHRHPGN;
2345#elif HAVE_WZR450HP2
2346#ifdef HAVE_BUFFALO
2347        setRouter("WZR-450HP2");
2348#else
2349        setRouter("Buffalo WZR-450HP2");
2350#endif
2351        nvram_default_get("ath0_rxantenna", "7");
2352        nvram_default_get("ath0_txantenna", "7");
2353        return ROUTER_BOARD_WHRHPGN;
2354#elif HAVE_DHP1565
2355        setRouter("Dlink DHP1565-A1");
2356        nvram_default_get("ath0_rxantenna", "3");
2357        nvram_default_get("ath0_txantenna", "3");
2358        return ROUTER_BOARD_WHRHPGN;
2359#elif HAVE_WR615N
2360        setRouter("Comfast WR615N");
2361        nvram_default_get("ath0_rxantenna", "3");
2362        nvram_default_get("ath0_txantenna", "3");
2363        return ROUTER_BOARD_WHRHPGN;
2364#elif HAVE_E325N
2365        setRouter("Comfast E325N");
2366        nvram_default_get("ath0_rxantenna", "3");
2367        nvram_default_get("ath0_txantenna", "3");
2368        return ROUTER_BOARD_WHRHPGN;
2369#elif HAVE_E355AC
2370        setRouter("Comfast E355AC");
2371        nvram_default_get("ath0_rxantenna", "3");
2372        nvram_default_get("ath0_txantenna", "3");
2373        return ROUTER_BOARD_WHRHPGN;
2374#elif HAVE_XD3200
2375        setRouter("Yuncore XD3200");
2376        nvram_default_get("ath0_rxantenna", "3");
2377        nvram_default_get("ath0_txantenna", "3");
2378        nvram_default_get("ath1_rxantenna", "3");
2379        nvram_default_get("ath1_txantenna", "3");
2380        return ROUTER_BOARD_WHRHPGN;
2381#elif HAVE_E380AC
2382        setRouter("Comfast E380AC");
2383        nvram_default_get("ath0_rxantenna", "7");
2384        nvram_default_get("ath0_txantenna", "7");
2385        nvram_default_get("ath1_rxantenna", "7");
2386        nvram_default_get("ath1_txantenna", "7");
2387        return ROUTER_BOARD_WHRHPGN;
2388#elif HAVE_AP120C
2389        setRouter("Alfa AP120C");
2390        nvram_default_get("ath0_rxantenna", "3");
2391        nvram_default_get("ath0_txantenna", "3");
2392        nvram_default_get("ath1_rxantenna", "3");
2393        nvram_default_get("ath1_txantenna", "3");
2394        return ROUTER_BOARD_WHRHPGN;
2395#elif HAVE_WR650AC
2396        setRouter("Comfast WR650AC");
2397        nvram_default_get("ath0_rxantenna", "7");
2398        nvram_default_get("ath0_txantenna", "7");
2399        nvram_default_get("ath1_rxantenna", "7");
2400        nvram_default_get("ath1_txantenna", "7");
2401        return ROUTER_BOARD_WHRHPGN;
2402#elif HAVE_DIR869
2403        setRouter("Dlink DIR869");
2404        nvram_default_get("ath0_rxantenna", "7");
2405        nvram_default_get("ath0_txantenna", "7");
2406        return ROUTER_BOARD_WHRHPGN;
2407#elif HAVE_DIR859
2408        setRouter("Dlink DIR859");
2409        nvram_default_get("ath0_rxantenna", "7");
2410        nvram_default_get("ath0_txantenna", "7");
2411        return ROUTER_BOARD_WHRHPGN;
2412#elif HAVE_JWAP606
2413        setRouter("JJPlus JWAP606");
2414        nvram_default_get("ath0_rxantenna", "3");
2415        nvram_default_get("ath0_txantenna", "3");
2416        nvram_default_get("ath1_rxantenna", "3");
2417        nvram_default_get("ath1_txantenna", "3");
2418        return ROUTER_BOARD_WHRHPGN;
2419#elif HAVE_DIR825C1
2420        setRouter("Dlink DIR825-C1");
2421        nvram_default_get("ath0_rxantenna", "3");
2422        nvram_default_get("ath0_txantenna", "3");
2423        nvram_default_get("ath1_rxantenna", "3");
2424        nvram_default_get("ath1_txantenna", "3");
2425        return ROUTER_BOARD_WHRHPGN;
2426#elif HAVE_WASP
2427        setRouter("Atheros Wasp");
2428        nvram_default_get("ath0_rxantenna", "3");
2429        nvram_default_get("ath0_txantenna", "3");
2430        nvram_default_get("ath1_rxantenna", "3");
2431        nvram_default_get("ath1_txantenna", "3");
2432        return ROUTER_BOARD_WHRHPGN;
2433#elif HAVE_WHRHPG300N
2434#ifdef HAVE_BUFFALO
2435#ifdef HAVE_WHR300HP
2436        setRouter("WHR-300HP");
2437#else
2438        setRouter("WHR-HP-G300N");
2439#endif
2440#else
2441        setRouter("Buffalo WHR-HP-G300N");
2442#endif
2443        nvram_default_get("ath0_rxantenna", "3");
2444        nvram_default_get("ath0_txantenna", "3");
2445        return ROUTER_BOARD_WHRHPGN;
2446#elif HAVE_WHRG300NV2
2447#ifdef HAVE_BUFFALO
2448        setRouter("WHR-G300N");
2449#else
2450        setRouter("Buffalo WHR-G300N");
2451#endif
2452        nvram_default_get("ath0_rxantenna", "3");
2453        nvram_default_get("ath0_txantenna", "3");
2454        return ROUTER_BOARD_WHRHPGN;
2455#elif HAVE_WHRHPGN
2456#ifdef HAVE_BUFFALO
2457        setRouter("WHR-HP-GN");
2458#else
2459        setRouter("Buffalo WHR-HP-GN");
2460#endif
2461        nvram_default_get("ath0_rxantenna", "1");
2462        nvram_default_get("ath0_txantenna", "1");
2463        return ROUTER_BOARD_WHRHPGN;
2464#elif HAVE_JJAP93
2465        setRouter("JJPLUS AP93");
2466        nvram_default_get("ath0_rxantenna", "1");
2467        nvram_default_get("ath0_txantenna", "1");
2468        return ROUTER_BOARD_PB42;
2469#elif HAVE_JJAP005
2470        setRouter("JJPLUS AP005");
2471        nvram_default_get("ath0_rxantenna", "1");
2472        nvram_default_get("ath0_txantenna", "1");
2473        return ROUTER_BOARD_PB42;
2474#elif HAVE_JJAP501
2475        setRouter("JJPLUS AP501");
2476        nvram_default_get("ath0_rxantenna", "3");
2477        nvram_default_get("ath0_txantenna", "3");
2478        return ROUTER_BOARD_PB42;
2479#elif HAVE_AC722
2480        setRouter("ACCTON AC722");
2481        nvram_default_get("ath0_rxantenna", "3");
2482        nvram_default_get("ath0_txantenna", "3");
2483        return ROUTER_BOARD_PB42;
2484#elif HAVE_AC622
2485        setRouter("ACCTON AC622");
2486        nvram_default_get("ath0_rxantenna", "3");
2487        nvram_default_get("ath0_txantenna", "3");
2488        return ROUTER_BOARD_PB42;
2489#elif HAVE_WPE72
2490        setRouter("Compex WPE72");
2491        nvram_default_get("ath0_rxantenna", "1");
2492        nvram_default_get("ath0_txantenna", "1");
2493        return ROUTER_BOARD_NS5M;
2494#elif HAVE_UBNTTI
2495        return ROUTER_BOARD_TI;
2496#elif HAVE_DAP3310
2497        setRouter("DLink DAP3310");
2498        return ROUTER_BOARD_NS5M;
2499#elif HAVE_DAP3410
2500        setRouter("DLink DAP3410");
2501        return ROUTER_BOARD_NS5M;
2502#elif HAVE_UBNTM
2503        typedef struct UBNTDEV {
2504                char *devicename;       // device name
2505                unsigned short devid;   // pci subdevice id
2506                unsigned char rxchain;  // rx chainmask
2507                unsigned char txchain;  // tx chainmask
2508                unsigned char rxchain5; // rx chainmask 5 ghz
2509                unsigned char txchain5; // tx chainmask 5 ghz
2510                int dddev;      // dd-wrt device id
2511                int offset;     // frequency offset
2512                int poffset;
2513        };
2514        /* these values are guessed and need to be validated */
2515#define M900 (- (2427 - 907))
2516#define M365 (- (5540 - 3650))
2517#define M35 (- (5540 - 3540))
2518#define M10 (- (5540 - 10322))
2519        struct UBNTDEV dev[] = {
2520
2521                {"NanoBeam M2 XW", 0xe2c2, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2522                {"NanoBeam M5 XW", 0xe3e5, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2523                {"NanoBeam M5 XW", 0xe4e5, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2524                {"NanoBeam M5 XW", 0xe815, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2525                {"NanoBeam M5 XW", 0xe825, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2526
2527                {"NanoStation M2", 0xe002, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2528                {"NanoStation M2", 0xe012, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},       //
2529                {"NanoStation M5", 0xe005, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},       //
2530                {"NanoStation M6", 0xe006, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},       //
2531                {"NanoStation M5", 0xe805, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},       //
2532                {"NanoStation M5 XW", 0xe855, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},    //
2533                {"NanoStation M3", 0xe035, 3, 3, 0, 0, ROUTER_BOARD_NS5M, M35, 10},     //
2534                {"NanoStation M365", 0xe003, 3, 3, 0, 0, ROUTER_BOARD_NS5M, M365, 10},  //
2535                {"NanoStation M900", 0xe2b9, 3, 3, 0, 0, ROUTER_BOARD_NS5M, M900, 10},  //
2536//              {"NanoStation M900 GPS", 0xe0b9, 3, 3, ROUTER_BOARD_NS5M, M900},       //
2537                {"Rocket M2", 0xe102, 3, 3, 0, 0, ROUTER_BOARD_R2M, 0, 10},     //
2538                {"Rocket M2", 0xe112, 3, 3, 0, 0, ROUTER_BOARD_R2M, 0, 10},     //
2539                {"Rocket M2", 0xe1b2, 3, 3, 0, 0, ROUTER_BOARD_R2M, 0, 10},     //
2540                {"Rocket M2", 0xe1c2, 3, 3, 0, 0, ROUTER_BOARD_R2M, 0, 10},     //
2541                {"Rocket M2 Titanium XW", 0xe1d2, 3, 3, 0, 0, ROUTER_BOARD_TI, 0, 10},  // Titanium
2542                {"Rocket M5 Titanium XW", 0xe4d5, 3, 3, 0, 0, ROUTER_BOARD_TI, 0, 10},  // Titanium
2543                {"Rocket M5", 0xe105, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2544                {"Rocket M5", 0xe1b5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2545                {"Rocket M5 XW", 0xe6b5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},  //
2546                {"Rocket M5", 0xe8b5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2547                {"Rocket M5", 0xe1c5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2548                {"Rocket M5 Titanium XW", 0xe1d5, 3, 3, 0, 0, ROUTER_BOARD_TI, 0, 10},  // Titanium
2549                {"Rocket M6", 0xe1b6, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2550                {"Rocket M3", 0xe1c3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M35, 10},   //
2551                {"Rocket M3", 0xe1e3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M35, 10},   //
2552                {"Rocket M5 X3 XW", 0xe3b5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},       //
2553                {"Rocket M365", 0xe1b3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M365, 10},        //
2554                {"Rocket M365", 0xe1d3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M365, 10},        //
2555                {"Rocket M900", 0xe1b9, 3, 3, 0, 0, ROUTER_BOARD_R2M, M900, 10},        //
2556                {"Rocket M900", 0xe1d9, 3, 3, 0, 0, ROUTER_BOARD_R2M, M900, 10},        //
2557                {"Airbeam 5", 0xe1e5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2558                {"Bullet M2", 0xe202, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},    //
2559                {"Bullet M5", 0xe205, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},    //
2560                {"Bullet M2 Titanium", 0xe2d2, 3, 3, 0, 0, ROUTER_BOARD_TI, 0, 10},     // Titanium
2561                {"Bullet M5 Titanium", 0xe2d5, 3, 3, 0, 0, ROUTER_BOARD_TI, 0, 10},     // Titanium
2562                {"Airgrid M2", 0xe212, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10},   //
2563                {"Airgrid M2", 0xe242, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10},   //
2564                {"Airgrid M2HP", 0xe252, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10}, //
2565                {"Airgrid M5", 0xe215, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},   //
2566                {"Airgrid M5", 0xe245, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},   //
2567                {"Airgrid M5", 0xe255, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},   //
2568                {"Airgrid M5 XW", 0xe835, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},        //
2569                {"AirRouter", 0xe4a2, 1, 1, 0, 0, ROUTER_BOARD_AIRROUTER, 0, 10},       //
2570                {"AirRouter", 0xe4b2, 1, 1, 0, 0, ROUTER_BOARD_AIRROUTER, 0, 10},       //
2571                {"Pico M2", 0xe302, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10},      //
2572                {"Pico M5", 0xe305, 1, 1, 0, 0, ROUTER_BOARD_BS5M, 0, 10},      //
2573                {"Airwire", 0xe405, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},      //
2574                {"Airwire", 0xe4a5, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},      //
2575                {"Loco M5", 0xe0a5, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},      //
2576                {"Loco M5", 0xe8a5, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},      //
2577                {"Loco M5 XW", 0xe845, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},   //
2578                {"Loco M2", 0xe0a2, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},      //
2579//              {"Loco M2", 0xe8a2, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0},   //
2580                {"Loco M900", 0xe009, 3, 3, 0, 0, ROUTER_BOARD_NS5M, M900, 10}, //
2581                {"NanoStation M900 Sector", 0xe0b9, 3, 3, 0, 0, ROUTER_BOARD_NS5M, M900, 10},   //
2582                {"LiteStation M25", 0xe115, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},      //
2583                {"LiteStation M5", 0xe2a5, 3, 3, 0, 0, ROUTER_BOARD_NS5M, 0, 10},       //
2584                {"PowerAP N", 0xe402, 3, 3, 0, 0, ROUTER_BOARD_NS2M, 0, 10},    //
2585                {"Simple AP", 0xe4a2, 3, 3, 0, 0, ROUTER_BOARD_R2M, 0, 10},     //
2586                {"PowerBridge M3", 0xe2a3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M35, 10},      //
2587                {"PowerBridge M5", 0xe1a5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},        //
2588                {"PowerBridge M10", 0xe110, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},       //
2589                {"PowerBridge M5 X3", 0xe3a5, 3, 3, 0, 0, ROUTER_BOARD_R5M, 0, 10},     //
2590                {"PowerBridge M365", 0xe1a3, 3, 3, 0, 0, ROUTER_BOARD_R5M, M365, 10},   //
2591                {"Rocket M10", 0xe110, 3, 3, 0, 0, ROUTER_BOARD_R5M, M10, 10},  //
2592                {"NanoBridge M3", 0xe243, 3, 3, 0, 0, ROUTER_BOARD_BS5M, M35, 10},      //
2593                {"NanoBridge M365", 0xe233, 3, 3, 0, 0, ROUTER_BOARD_BS5M, M365, 10},   //
2594                {"NanoBridge M900", 0xe239, 3, 3, 0, 0, ROUTER_BOARD_BS5M, M900, 10},   //
2595                {"NanoBridge M5", 0xe235, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},        //
2596                {"NanoBridge M5", 0xe2b5, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},        //
2597                {"NanoBridge M5", 0xe2e5, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},        //
2598                {"NanoBridge M2", 0xe232, 3, 3, 0, 0, ROUTER_BOARD_BS2M, 0, 10},        //
2599                {"NanoBridge M2", 0xe2b2, 3, 3, 0, 0, ROUTER_BOARD_BS2M, 0, 10},        //
2600                {"PicoStation M2", 0xe302, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10},       //
2601                {"PicoStation M5", 0xe305, 1, 1, 0, 0, ROUTER_BOARD_BS2M, 0, 10},       //
2602                {"3G Station", 0xe6a2, 3, 3, 0, 0, ROUTER_BOARD_BS2M, 0, 10},   //
2603                {"3G Station Professional", 0xe6b2, 3, 3, 0, 0, ROUTER_BOARD_BS2M, 0, 10},      //
2604                {"3G Station Outdoor", 0xe6c2, 3, 3, 0, 0, ROUTER_BOARD_BS2M, 0, 10},   //
2605                {"WispStation M5", 0xe345, 3, 3, 0, 0, ROUTER_BOARD_BS5M, 0, 10},       //
2606                {"UniFi UAP", 0xe502, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},   //
2607                {"UniFi UAP-PRO", 0xe507, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},       //
2608                {"UniFi UAP-LR", 0xe512, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},        //
2609                {"UniFi UAP-Mini", 0xe522, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},      //
2610                {"UniFi UAP-Outdoor", 0xe532, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},   //
2611                {"UniFi UAP-Outdoor 5G", 0xe515, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},        //
2612                {"UniFi UAP-AC", 0xe902, 7, 7, 7, 7, ROUTER_BOARD_UNIFI, 0, 10},        //
2613                {"UniFi UAP-Outdoor+", 0xe562, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},  //
2614                {"UniFi UAP-AC v2", 0xe912, 7, 7, 7, 7, ROUTER_BOARD_UNIFI, 0, 10},     //
2615                {"UniFi UAP v2", 0xe572, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},        //
2616                {"UniFi UAP-LR v2", 0xe582, 3, 3, 0, 0, ROUTER_BOARD_UNIFI, 0, 10},     //
2617                {"UniFi UAP-AC-Lite", 0xe517, 3, 3, 3, 3, ROUTER_UBNT_UAPAC, 0, 10},    //
2618                {"UniFi UAP-AC-LR", 0xe527, 7, 7, 3, 3, ROUTER_UBNT_UAPAC, 0, 10},      //
2619                {"UniFi UAP-AC-Pro-Gen2", 0xe537, 7, 7, 7, 7, ROUTER_UBNT_UAPAC, 0, 10},        //
2620                {"UniFi UAP-AC-EDU", 0xe547, 7, 7, 7, 7, ROUTER_UBNT_UAPAC, 0, 10},     //
2621                {"UniFi UAP-AC-MESH", 0xe557, 7, 7, 3, 3, ROUTER_UBNT_UAPAC, 0, 10},    //
2622                {"UniFi UAP-AC-MESH-PRO", 0xe567, 7, 7, 7, 7, ROUTER_UBNT_UAPAC, 0, 10},        //
2623                {"UniFi UAP-AC-InWall", 0xe587, 7, 7, 7, 7, ROUTER_UBNT_UAPAC, 0, 10},  //
2624                {"UniFi UAP-AC-InWall", 0xe592, 3, 3, 0, 0, ROUTER_UBNT_UAPAC, 0, 10},  //
2625                {"UniFi UAP-AC-HD", 0xe535, 3, 3, 0, 0, ROUTER_UBNT_UAPAC, 0, 10},      //
2626                {NULL, 0, 0, 0, 0, 0, 0},       //
2627        };
2628
2629#undef M35
2630#undef M365
2631#undef M900
2632#undef M10
2633
2634#if 0
2635        FILE *fp = fopen("/sys/bus/pci/devices/0000:00:00.0/subsystem_device", "rb");
2636        if (fp == NULL)
2637                return ROUTER_BOARD_PB42;
2638        int device;
2639        fscanf(fp, "0x%04X", &device);
2640        fclose(fp);
2641#else
2642        FILE *fp = fopen("/dev/mtdblock5", "rb");       //open board config
2643        int device = 0;
2644        if (fp) {
2645                fseek(fp, 0x1006, SEEK_SET);
2646                unsigned short cal[132];
2647                fread(&cal[0], 1, 256, fp);
2648                int calcnt = 0;
2649                while (((cal[calcnt] & 0xffff) != 0xffff) && calcnt < 128) {
2650                        unsigned short reg = cal[calcnt++] & 0xffff;
2651                        if (reg == 0x602c || reg == 0x502c) {
2652                                calcnt++;
2653                                device = cal[calcnt++] & 0xffff;
2654                                break;
2655                        } else {
2656                                calcnt += 2;
2657                        }
2658                }
2659                if (device == 0) {
2660                        fseek(fp, 12, SEEK_SET);
2661                        unsigned short devid;
2662                        fread(&devid, 2, 1, fp);
2663                        device = devid;
2664                }
2665
2666                fclose(fp);
2667        }
2668#endif
2669        int devcnt = 0;
2670        while (dev[devcnt].devicename != NULL) {
2671                if (dev[devcnt].devid == device) {
2672                        char rxchain[16];
2673                        char txchain[16];
2674                        sprintf(rxchain, "%d", dev[devcnt].rxchain);
2675                        sprintf(txchain, "%d", dev[devcnt].txchain);
2676                        nvram_default_get("ath0_rxantenna", rxchain);
2677                        nvram_default_get("ath0_txantenna", txchain);
2678                        if (dev[devcnt].rxchain5) {
2679                                sprintf(rxchain, "%d", dev[devcnt].rxchain5);
2680                                sprintf(txchain, "%d", dev[devcnt].txchain5);
2681                                nvram_default_get("ath1_rxantenna", rxchain);
2682                                nvram_default_get("ath1_txantenna", txchain);
2683
2684                        }
2685                        if (dev[devcnt].offset) {
2686                                char foff[32];
2687                                sprintf(foff, "%d", dev[devcnt].offset);
2688                                nvram_set("ath0_offset", foff);
2689                        }
2690                        if (dev[devcnt].poffset) {
2691                                char poff[32];
2692                                sprintf(poff, "%d", dev[devcnt].poffset);
2693                                nvram_set("ath0_poweroffset", poff);
2694                        }
2695                        static char devicename[64];
2696                        sprintf(devicename, "Ubiquiti %s", dev[devcnt].devicename);
2697                        setRouter(devicename);
2698                        return dev[devcnt].dddev;
2699                }
2700                devcnt++;
2701        }
2702        setRouter("Ubiquiti Unknown Model");
2703        return ROUTER_BOARD_PB42;
2704#elif HAVE_NS2
2705        setRouter("Ubiquiti NanoStation 2");
2706        return ROUTER_BOARD_LS2;
2707#elif HAVE_EOC5510
2708        setRouter("Senao EOC-5510");
2709        return ROUTER_BOARD_LS2;
2710#elif HAVE_EOC5611
2711        setRouter("Senao EOC-5611");
2712        return ROUTER_BOARD_LS2;
2713#elif HAVE_EOC5610
2714        setRouter("Senao EOC-5610");
2715        return ROUTER_BOARD_LS2;
2716#elif HAVE_NS5
2717        setRouter("Ubiquiti NanoStation 5");
2718        return ROUTER_BOARD_LS2;
2719#elif HAVE_SOLO51
2720        setRouter("Alfa SoLo48-N");
2721        return ROUTER_BOARD_LS2;
2722#elif HAVE_NS3
2723        setRouter("Ubiquiti NanoStation 3");
2724        return ROUTER_BOARD_LS2;
2725#elif HAVE_BS5
2726        setRouter("Ubiquiti Bullet 5");
2727        return ROUTER_BOARD_LS2;
2728#elif HAVE_BS2
2729        setRouter("Ubiquiti Bullet 2");
2730        return ROUTER_BOARD_LS2;
2731#elif HAVE_PICO2
2732        setRouter("Ubiquiti PicoStation 2");
2733        return ROUTER_BOARD_LS2;
2734#elif HAVE_PICO2HP
2735        setRouter("Ubiquiti PicoStation 2 HP");
2736        return ROUTER_BOARD_LS2;
2737#elif HAVE_PICO5
2738        setRouter("Ubiquiti PicoStation 5");
2739        return ROUTER_BOARD_LS2;
2740#elif HAVE_MS2
2741        setRouter("Ubiquiti MiniStation");
2742        return ROUTER_BOARD_LS2;
2743#elif HAVE_BS2HP
2744        setRouter("Ubiquiti Bullet 2 HP");
2745        return ROUTER_BOARD_LS2;
2746#elif HAVE_LC2
2747        setRouter("Ubiquiti NanoStation 2 Loco");
2748        return ROUTER_BOARD_LS2;
2749#elif HAVE_LC5
2750        setRouter("Ubiquiti NanoStation 5 Loco");
2751        return ROUTER_BOARD_LS2;
2752#elif HAVE_PS2
2753        setRouter("Ubiquiti PowerStation 2");
2754        return ROUTER_BOARD_LS2;
2755#elif HAVE_PS5
2756        setRouter("Ubiquiti PowerStation 5");
2757        return ROUTER_BOARD_LS2;
2758#elif HAVE_LS2
2759        setRouter("Ubiquiti LiteStation 2");
2760        return ROUTER_BOARD_LS2;
2761#elif HAVE_LS5
2762        setRouter("Ubiquiti LiteStation 5");
2763        return ROUTER_BOARD_LS2;
2764#elif HAVE_WHRAG108
2765        setRouter("Buffalo WHR-HP-AG108");
2766        return ROUTER_BOARD_WHRAG108;
2767#elif HAVE_PB42
2768        setRouter("Atheros PB42");
2769        return ROUTER_BOARD_PB42;
2770#elif HAVE_RSPRO
2771        setRouter("Ubiquiti RouterStation Pro");
2772        return ROUTER_BOARD_PB42;
2773#elif HAVE_RS
2774#ifdef HAVE_DDLINK
2775        setRouter("ddlink1x1");
2776#else
2777        setRouter("Ubiquiti RouterStation");
2778#endif
2779        return ROUTER_BOARD_PB42;
2780#elif HAVE_E2100
2781        setRouter("Linksys E2100L");
2782        return ROUTER_BOARD_PB42;
2783#elif HAVE_WRT160NL
2784        setRouter("Linksys WRT160NL");
2785        return ROUTER_BOARD_PB42;
2786#elif HAVE_TG2521
2787        setRouter("ZCom TG-2521");
2788        return ROUTER_BOARD_PB42;
2789#elif HAVE_WZRG300NH2
2790        nvram_default_get("ath0_rxantenna", "3");
2791        nvram_default_get("ath0_txantenna", "3");
2792#ifdef HAVE_BUFFALO
2793#ifdef HAVE_WZR300HP
2794        setRouter("WZR-300HP");
2795#else
2796        setRouter("WZR-HP-G300NH2");
2797#endif
2798#else
2799        setRouter("Buffalo WZR-HP-G300NH2");
2800#endif
2801        return ROUTER_BOARD_PB42;
2802#elif HAVE_WZRG450
2803        nvram_default_get("ath0_rxantenna", "7");
2804        nvram_default_get("ath0_txantenna", "7");
2805
2806        void *getUEnv(char *name);
2807
2808        char *model = getUEnv("product");
2809
2810#ifdef HAVE_BUFFALO
2811        if (!strcmp(model, "BHR-4GRV"))
2812                setRouter("BHR-4GRV");
2813        else
2814                setRouter("WZR-HP-G450H");
2815#else
2816        if (!strcmp(model, "BHR-4GRV"))
2817                setRouter("Buffalo BHR-4GRV");
2818        else
2819                setRouter("Buffalo WZR-HP-G450H");
2820#endif
2821        return ROUTER_BOARD_PB42;
2822#elif HAVE_WZRG300NH
2823#ifdef HAVE_BUFFALO
2824        setRouter("WZR-HP-G300NH");
2825#else
2826        setRouter("Buffalo WZR-HP-G300NH");
2827#endif
2828        nvram_default_get("ath0_rxantenna", "7");
2829        nvram_default_get("ath0_txantenna", "7");
2830        return ROUTER_BOARD_PB42;
2831#elif HAVE_WZRHPAG300NH
2832#if defined(HAVE_BUFFALO) || defined(HAVE_IDEXX)
2833#ifdef HAVE_WZR600DHP
2834        setRouter("WZR-600DHP");
2835#else
2836        setRouter("WZR-HP-AG300H");
2837#endif
2838#else
2839        setRouter("Buffalo WZR-HP-AG300H");
2840#endif
2841        return ROUTER_BOARD_PB42;
2842#elif HAVE_DIR632
2843        nvram_default_get("ath0_rxantenna", "3");
2844        nvram_default_get("ath0_txantenna", "3");
2845        setRouter("Dlink-DIR-632A");
2846        return ROUTER_BOARD_PB42;
2847#elif HAVE_WNDR3700V2
2848        nvram_default_get("ath0_rxantenna", "3");
2849        nvram_default_get("ath0_txantenna", "3");
2850        nvram_default_get("ath1_rxantenna", "3");
2851        nvram_default_get("ath1_txantenna", "3");
2852        setRouter("Netgear WNDR3700 v2/WNDR37AV v2/WNDR3800/WNDR38AV");
2853        return ROUTER_BOARD_PB42;
2854#elif HAVE_WNDR3700
2855        nvram_default_get("ath0_rxantenna", "3");
2856        nvram_default_get("ath0_txantenna", "3");
2857        nvram_default_get("ath1_rxantenna", "3");
2858        nvram_default_get("ath1_txantenna", "3");
2859        setRouter("Netgear WNDR3700");
2860        return ROUTER_BOARD_PB42;
2861#elif HAVE_DIR825
2862        nvram_default_get("ath0_rxantenna", "3");
2863        nvram_default_get("ath0_txantenna", "3");
2864        nvram_default_get("ath1_rxantenna", "3");
2865        nvram_default_get("ath1_txantenna", "3");
2866        setRouter("Dlink DIR-825");
2867        return ROUTER_BOARD_PB42;
2868#elif HAVE_TEW673GRU
2869        nvram_default_get("ath0_rxantenna", "3");
2870        nvram_default_get("ath0_txantenna", "3");
2871        nvram_default_get("ath1_rxantenna", "3");
2872        nvram_default_get("ath1_txantenna", "3");
2873        setRouter("Trendnet TEW-673GRU");
2874        return ROUTER_BOARD_PB42;
2875#elif HAVE_WRT400
2876        nvram_default_get("ath0_rxantenna", "3");
2877        nvram_default_get("ath0_txantenna", "3");
2878        nvram_default_get("ath1_rxantenna", "3");
2879        nvram_default_get("ath1_txantenna", "3");
2880        setRouter("Linksys WRT400N");
2881        return ROUTER_BOARD_PB42;
2882#elif HAVE_DIR615C1
2883        setRouter("D-Link DIR-615-C1");
2884        return ROUTER_BOARD_PB42;
2885#elif HAVE_DIR601A1
2886        nvram_default_get("ath0_rxantenna", "1");
2887        nvram_default_get("ath0_txantenna", "1");
2888        setRouter("D-Link DIR-601-A1");
2889        return ROUTER_BOARD_PB42;
2890#elif HAVE_WR842V2
2891        nvram_default_get("ath0_rxantenna", "3");
2892        nvram_default_get("ath0_txantenna", "3");
2893        setRouter("TP-Link TL-WR842ND v2");
2894        return ROUTER_BOARD_PB42;
2895#elif HAVE_DAP3320
2896        nvram_default_get("ath0_rxantenna", "3");
2897        nvram_default_get("ath0_txantenna", "3");
2898        setRouter("Dlink DAP-3320");
2899        return ROUTER_BOARD_PB42;
2900#elif HAVE_DAP2230
2901        nvram_default_get("ath0_rxantenna", "3");
2902        nvram_default_get("ath0_txantenna", "3");
2903        setRouter("Dlink DAP-2230");
2904        return ROUTER_BOARD_PB42;
2905#elif HAVE_WR941V6
2906        nvram_default_get("ath0_rxantenna", "3");
2907        nvram_default_get("ath0_txantenna", "3");
2908        setRouter("TP-Link TL-WR941ND v6");
2909        return ROUTER_BOARD_PB42;
2910#elif HAVE_WR841V12
2911        nvram_default_get("ath0_rxantenna", "3");
2912        nvram_default_get("ath0_txantenna", "3");
2913        setRouter("TP-Link TL-WR841ND v12");
2914        return ROUTER_BOARD_PB42;
2915#elif HAVE_WR841V11
2916        nvram_default_get("ath0_rxantenna", "3");
2917        nvram_default_get("ath0_txantenna", "3");
2918        setRouter("TP-Link TL-WR841ND v11");
2919        return ROUTER_BOARD_PB42;
2920#elif HAVE_WR841V10
2921        nvram_default_get("ath0_rxantenna", "3");
2922        nvram_default_get("ath0_txantenna", "3");
2923        setRouter("TP-Link TL-WR841ND v10");
2924        return ROUTER_BOARD_PB42;
2925#elif HAVE_WR841V9
2926        nvram_default_get("ath0_rxantenna", "3");
2927        nvram_default_get("ath0_txantenna", "3");
2928        setRouter("TP-Link TL-WR841ND v9");
2929        return ROUTER_BOARD_PB42;
2930#elif HAVE_WA901V3
2931        nvram_default_get("ath0_rxantenna", "3");
2932        nvram_default_get("ath0_txantenna", "3");
2933        setRouter("TP-Link TL-WA901ND v3");
2934        return ROUTER_BOARD_PB42;
2935#elif HAVE_WR841V8
2936        nvram_default_get("ath0_rxantenna", "3");
2937        nvram_default_get("ath0_txantenna", "3");
2938        setRouter("TP-Link TL-WR841ND v8");
2939        return ROUTER_BOARD_PB42;
2940#elif HAVE_DIR615I
2941        nvram_default_get("ath0_rxantenna", "3");
2942        nvram_default_get("ath0_txantenna", "3");
2943        setRouter("D-Link DIR-615-I1");
2944        return ROUTER_BOARD_PB42;
2945#elif HAVE_DIR615E1
2946        nvram_default_get("ath0_rxantenna", "3");
2947        nvram_default_get("ath0_txantenna", "3");
2948        setRouter("D-Link DIR-615-E1");
2949        return ROUTER_BOARD_PB42;
2950#elif HAVE_DIR615E
2951        nvram_default_get("ath0_rxantenna", "3");
2952        nvram_default_get("ath0_txantenna", "3");
2953        setRouter("D-Link DIR-615-E3/E4");
2954        return ROUTER_BOARD_PB42;
2955#elif HAVE_TEW652BRP
2956        setRouter("Trendnet TEW-652BRP");
2957        return ROUTER_BOARD_PB42;
2958#elif HAVE_TEW632BRP
2959        setRouter("Trendnet TEW-632BRP");
2960        return ROUTER_BOARD_PB42;
2961#elif HAVE_WR841v3
2962        setRouter("TP-Link TL-WR841ND v3");
2963        return ROUTER_BOARD_PB42;
2964#elif HAVE_WA901
2965        setRouter("TP-Link TL-WA901ND v2");
2966        return ROUTER_BOARD_PB42;
2967#elif HAVE_WR941
2968        setRouter("TP-Link TL-WR941ND v2/v3");
2969        return ROUTER_BOARD_PB42;
2970#elif HAVE_WR841v5
2971        nvram_default_get("ath0_rxantenna", "3");
2972        nvram_default_get("ath0_txantenna", "3");
2973        setRouter("TP-Link TL-WR841ND v5");
2974        return ROUTER_BOARD_PB42;
2975#elif HAVE_WR840v1
2976        nvram_default_get("ath0_rxantenna", "3");
2977        nvram_default_get("ath0_txantenna", "3");
2978        setRouter("TP-Link TL-WR840N v1");
2979        return ROUTER_BOARD_PB42;
2980#elif HAVE_MR3220
2981        nvram_default_get("ath0_rxantenna", "1");
2982        nvram_default_get("ath0_txantenna", "1");
2983        setRouter("TP-Link TL-MR3220");
2984        return ROUTER_BOARD_PB42;
2985#elif HAVE_MR3420
2986        nvram_default_get("ath0_rxantenna", "3");
2987        nvram_default_get("ath0_txantenna", "3");
2988        setRouter("TP-Link TL-MR3420");
2989        return ROUTER_BOARD_PB42;
2990#elif HAVE_WR841v7
2991        nvram_default_get("ath0_rxantenna", "3");
2992        nvram_default_get("ath0_txantenna", "3");
2993        setRouter("TP-Link TL-WR841ND v7");
2994        return ROUTER_BOARD_PB42;
2995#elif HAVE_WR842
2996        nvram_default_get("ath0_rxantenna", "3");
2997        nvram_default_get("ath0_txantenna", "3");
2998        setRouter("TP-Link TL-WR842ND v1");
2999        return ROUTER_BOARD_PB42;
3000#elif HAVE_WR740v1
3001        nvram_default_get("ath0_rxantenna", "1");
3002        nvram_default_get("ath0_txantenna", "1");
3003        setRouter("TP-Link TL-WR740N");
3004        return ROUTER_BOARD_PB42;
3005#elif HAVE_WA801v1
3006        nvram_default_get("ath0_rxantenna", "3");
3007        nvram_default_get("ath0_txantenna", "3");
3008        setRouter("TP-Link TL-WA801ND v1");
3009        return ROUTER_BOARD_PB42;
3010#elif HAVE_WA901v1
3011        nvram_default_get("ath0_rxantenna", "3");
3012        nvram_default_get("ath0_txantenna", "3");
3013        setRouter("TP-Link TL-WA901ND v1");
3014        return ROUTER_BOARD_PB42;
3015#elif HAVE_WR941v4
3016        setRouter("TP-Link TL-WR941ND v4");
3017        return ROUTER_BOARD_PB42;
3018#elif HAVE_WR743
3019        nvram_default_get("ath0_rxantenna", "1");
3020        nvram_default_get("ath0_txantenna", "1");
3021        setRouter("TP-Link TL-WR743ND v1");
3022        return ROUTER_BOARD_PB42;
3023#elif HAVE_MR3020
3024        nvram_default_get("ath0_rxantenna", "1");
3025        nvram_default_get("ath0_txantenna", "1");
3026        setRouter("TP-Link TL-MR3020");
3027        return ROUTER_BOARD_PB42;
3028#elif HAVE_GL150
3029        nvram_default_get("ath0_rxantenna", "1");
3030        nvram_default_get("ath0_txantenna", "1");
3031        setRouter("GL.iNet-AR150");
3032        return ROUTER_BOARD_PB42;
3033#elif HAVE_WR71021
3034        nvram_default_get("ath0_rxantenna", "1");
3035        nvram_default_get("ath0_txantenna", "1");
3036        setRouter("TP-Link TL-WR710N v2.1");
3037        return ROUTER_BOARD_PB42;
3038#elif HAVE_WR710V1
3039        nvram_default_get("ath0_rxantenna", "1");
3040        nvram_default_get("ath0_txantenna", "1");
3041        setRouter("TP-Link TL-WR710N v1");
3042        return ROUTER_BOARD_PB42;
3043#elif HAVE_WR710
3044        nvram_default_get("ath0_rxantenna", "1");
3045        nvram_default_get("ath0_txantenna", "1");
3046        setRouter("TP-Link TL-WR710N v2");
3047        return ROUTER_BOARD_PB42;
3048#elif HAVE_WA701V2
3049        nvram_default_get("ath0_rxantenna", "1");
3050        nvram_default_get("ath0_txantenna", "1");
3051        setRouter("TP-Link TL-WA701ND v2");
3052        return ROUTER_BOARD_PB42;
3053#elif HAVE_WR703
3054        nvram_default_get("ath0_rxantenna", "1");
3055        nvram_default_get("ath0_txantenna", "1");
3056        setRouter("TP-Link TL-WR703N v1");
3057        return ROUTER_BOARD_PB42;
3058#elif HAVE_WR740V4
3059        nvram_default_get("ath0_rxantenna", "1");
3060        nvram_default_get("ath0_txantenna", "1");
3061        setRouter("TP-Link TL-WR740N v4");
3062        return ROUTER_BOARD_PB42;
3063#elif HAVE_WR743V2
3064        nvram_default_get("ath0_rxantenna", "1");
3065        nvram_default_get("ath0_txantenna", "1");
3066        setRouter("TP-Link TL-WR743ND v2");
3067        return ROUTER_BOARD_PB42;
3068#elif HAVE_WR741V4
3069        nvram_default_get("ath0_rxantenna", "1");
3070        nvram_default_get("ath0_txantenna", "1");
3071        setRouter("TP-Link TL-WR741ND v4");
3072        return ROUTER_BOARD_PB42;
3073#elif HAVE_WA7510
3074        nvram_default_get("ath0_rxantenna", "1");
3075        nvram_default_get("ath0_txantenna", "1");
3076        setRouter("TP-Link TL-WA7510N v1");
3077        return ROUTER_BOARD_PB42;
3078#elif HAVE_WR741
3079        nvram_default_get("ath0_rxantenna", "1");
3080        nvram_default_get("ath0_txantenna", "1");
3081        setRouter("TP-Link TL-WR741ND v1");
3082        return ROUTER_BOARD_PB42;
3083#elif HAVE_WR1043
3084        nvram_default_get("ath0_rxantenna", "7");
3085        nvram_default_get("ath0_txantenna", "7");
3086        setRouter("TP-Link TL-WR1043ND");
3087        return ROUTER_BOARD_PB42;
3088#elif HAVE_AP83
3089        setRouter("Atheros AP83");
3090        return ROUTER_BOARD_PB42;
3091#elif HAVE_WP546
3092        setRouter("Compex WP546");
3093        return ROUTER_BOARD_PB42;
3094#elif HAVE_WP543
3095        setRouter("Compex WP543");
3096        return ROUTER_BOARD_PB42;
3097#elif HAVE_JA76PF
3098        setRouter("JJPLUS JA76PF");
3099        return ROUTER_BOARD_PB42;
3100#elif HAVE_JWAP003
3101        setRouter("JJPLUS JWAP003");
3102        return ROUTER_BOARD_PB42;
3103#elif HAVE_ALFAAP94
3104        setRouter("Alfa AP94 Board");
3105        return ROUTER_BOARD_PB42;
3106#elif HAVE_LSX
3107        setRouter("Ubiquiti LiteStation-SR71");
3108        return ROUTER_BOARD_PB42;
3109#elif HAVE_WMBR_G300NH
3110        setRouter("Buffalo WBMR-HP-G300H");
3111        nvram_default_get("ath0_rxantenna", "3");
3112        nvram_default_get("ath0_txantenna", "3");
3113        return ROUTER_BOARD_DANUBE;
3114#elif HAVE_VF802
3115        setRouter("Vodafone Easybox 802");
3116        return ROUTER_BOARD_DANUBE;
3117#elif HAVE_VF803
3118        setRouter("Vodafone Easybox 803");
3119        return ROUTER_BOARD_DANUBE;
3120#elif HAVE_SX763
3121        setRouter("Gigaset SX763");
3122        return ROUTER_BOARD_DANUBE;
3123#elif HAVE_DANUBE
3124        setRouter("Infineon Danube");
3125        return ROUTER_BOARD_DANUBE;
3126#elif HAVE_WBD222
3127        setRouter("Wiligear WBD-222");
3128        return ROUTER_BOARD_STORM;
3129#elif HAVE_STORM
3130        setRouter("Wiligear WBD-111");
3131        return ROUTER_BOARD_STORM;
3132#elif HAVE_OPENRISC
3133        setRouter("Alekto OpenRisc");
3134        return ROUTER_BOARD_OPENRISC;
3135#elif HAVE_TW6600
3136        setRouter("AW-6660");
3137        return ROUTER_BOARD_TW6600;
3138#elif HAVE_ALPHA
3139        setRouter("Alfa Networks AP48");
3140        return ROUTER_BOARD_CA8;
3141#elif HAVE_USR5453
3142        setRouter("US Robotics USR5453");
3143        return ROUTER_BOARD_CA8;
3144#elif HAVE_RDAT81
3145        setRouter("Wistron RDAT-81");
3146        return ROUTER_BOARD_RDAT81;
3147#elif HAVE_RCAA01
3148        setRouter("Airlive WLA-9000AP");
3149        return ROUTER_BOARD_RCAA01;
3150#elif HAVE_CA8PRO
3151        setRouter("Wistron CA8-4 PRO");
3152        return ROUTER_BOARD_CA8PRO;
3153#elif HAVE_CA8
3154#ifdef HAVE_WHA5500CPE
3155        setRouter("Airlive WHA-5500CPE");
3156#elif HAVE_AIRMAX5
3157        setRouter("Airlive AirMax 5");
3158#else
3159        setRouter("Airlive WLA-5000AP");
3160#endif
3161        return ROUTER_BOARD_CA8;
3162#else
3163
3164        unsigned long boardnum = strtoul(nvram_safe_get("boardnum"), NULL, 0);
3165        unsigned long melco_id = strtoul(nvram_safe_get("melco_id"), NULL, 0);
3166
3167        if (boardnum == 42 && nvram_match("boardtype", "bcm94710ap")) {
3168                setRouter("Buffalo WBR-G54 / WLA-G54");
3169                return ROUTER_BUFFALO_WBR54G;
3170        }
3171#ifndef HAVE_BUFFALO
3172        if (nvram_match("boardnum", "mn700") && nvram_match("boardtype", "bcm94710ap")) {
3173                setRouter("Microsoft MN-700");
3174                return ROUTER_MICROSOFT_MN700;
3175        }
3176
3177        if (nvram_match("boardnum", "asusX") && nvram_match("boardtype", "bcm94710dev")) {
3178                setRouter("Asus WL-300g / WL-500g");
3179                return ROUTER_ASUS_WL500G;
3180        }
3181
3182        if (boardnum == 44 && nvram_match("boardtype", "bcm94710ap")) {
3183                setRouter("Dell TrueMobile 2300");
3184                return ROUTER_DELL_TRUEMOBILE_2300;
3185        }
3186#endif
3187
3188        if (boardnum == 100 && nvram_match("boardtype", "bcm94710dev")) {
3189                setRouter("Buffalo WLA-G54C");
3190                return ROUTER_BUFFALO_WLAG54C;
3191        }
3192#ifndef HAVE_BUFFALO
3193        if (boardnum == 45 && nvram_match("boardtype", "bcm95365r")) {
3194                setRouter("Asus WL-500g Deluxe");
3195                return ROUTER_ASUS_WL500GD;
3196        }
3197
3198        if (boardnum == 45 && nvram_match("boardtype", "0x0472")
3199            && nvram_match("boardrev", "0x23") && nvram_matchi("parkid", 1)) {
3200                setRouter("Asus WL-500W");
3201                return ROUTER_ASUS_WL500W;
3202        }
3203
3204        if (boardnum == 45 && nvram_match("boardtype", "0x467")) {
3205                char *hwver0 = nvram_safe_get("hardware_version");
3206
3207                if (startswith(hwver0, "WL320G")) {
3208                        setRouter("Asus WL-320gE/gP");
3209                        return ROUTER_ASUS_WL550GE;
3210                } else {
3211                        setRouter("Asus WL-550gE");
3212                        return ROUTER_ASUS_WL550GE;
3213                }
3214        }
3215#ifdef HAVE_BCMMODERN
3216        if (boardnum == 45 && nvram_match("boardtype", "0x04EC")
3217            && nvram_match("boardrev", "0x1402")) {
3218                setRouter("Asus RT-N10");
3219                return ROUTER_ASUS_RTN10;
3220        }
3221
3222        if (boardnum == 45 && nvram_match("boardtype", "0x0550")
3223            && nvram_match("boardrev", "0x1102")) {
3224                setRouter("Asus RT-N10U");
3225                return ROUTER_ASUS_RTN10U;
3226        }
3227
3228        if (boardnum == 45 && nvram_match("boardtype", "0x058e")
3229            && nvram_match("boardrev", "0x1153")) {
3230                setRouter("Asus RT-N10+ rev D1");
3231                return ROUTER_ASUS_RTN10PLUSD1;
3232        }
3233
3234        if (boardnum == 45 && nvram_match("boardtype", "0x0550")
3235            && nvram_match("boardrev", "0x1442")) {
3236                setRouter("Asus RT-N53");
3237                return ROUTER_ASUS_RTN53;
3238        }
3239
3240        if (nvram_match("boardtype", "0xF5B2")
3241            && nvram_match("boardrev", "0x1100")
3242            && !nvram_matchi("pci/2/1/sb20in80and160hr5ghpo", 0)) {
3243                setRouter("Asus RT-N66U");
3244                return ROUTER_ASUS_RTN66;
3245        }
3246
3247        if (nvram_matchi("boardnum", 1) && nvram_match("boardtype", "0x054d")
3248            && nvram_match("boardrev", "0x1109")) {
3249                setRouter("NetCore NW715P");
3250                return ROUTER_NETCORE_NW715P;
3251        }
3252
3253        if (boardnum == 45 && nvram_match("boardtype", "0x04CD")
3254            && nvram_match("boardrev", "0x1201")) {
3255                setRouter("Asus RT-N12");
3256                return ROUTER_ASUS_RTN12;
3257        }
3258
3259        if (boardnum == 45 && nvram_match("boardtype", "0x054D")
3260            && nvram_match("boardrev", "0x1101")) {
3261                char *hwrev = nvram_safe_get("hardware_version");
3262                if (!strncmp(hwrev, "RTN12C1", 7))
3263                        setRouter("Asus RT-N12C1");
3264                else
3265                        setRouter("Asus RT-N12B");
3266                return ROUTER_ASUS_RTN12B;
3267        }
3268
3269        if (boardnum == 45 && nvram_match("boardtype", "0x04cf")
3270            && nvram_match("boardrev", "0x1218")) {
3271                setRouter("Asus RT-N16");
3272                return ROUTER_ASUS_RTN16;
3273        }
3274
3275        if (nvram_match("boardtype", "0xa4cf")
3276            && nvram_match("boardrev", "0x1100")) {
3277                setRouter("Belkin F5D8235-4 v3");
3278                return ROUTER_BELKIN_F5D8235V3;
3279        }
3280
3281        if (nvram_match("boardtype", "0xd4cf")
3282            && nvram_match("boardrev", "0x1204")) {
3283                setRouter("Belkin F7D4301 / F7D8301 v1");
3284                return ROUTER_BELKIN_F7D4301;
3285        }
3286
3287        if (nvram_match("boardtype", "0xa4cf")
3288            && nvram_match("boardrev", "0x1102")) {
3289                FILE *mtd1 = fopen("/dev/mtdblock/1", "rb");
3290                unsigned int trxhd;
3291                if (mtd1) {
3292                        fread(&trxhd, 4, 1, mtd1);
3293                        fclose(mtd1);
3294                        if (trxhd == TRX_MAGIC_F7D3301) {
3295                                setRouter("Belkin F7D3301 / F7D7301 v1");
3296                                return ROUTER_BELKIN_F7D3301;
3297                        }
3298                        if (trxhd == TRX_MAGIC_F7D3302) {
3299                                setRouter("Belkin F7D3302 / F7D7302 v1");
3300                                return ROUTER_BELKIN_F7D3302;
3301                        }
3302                }
3303                setRouter("Belkin F7D4302 / F7D8302 v1");
3304                return ROUTER_BELKIN_F7D4302;
3305        }
3306#endif
3307
3308#endif
3309        if (nvram_match("boardnum", "00") && nvram_match("boardtype", "0x0101")
3310            && nvram_match("boardrev", "0x10")) {
3311                setRouter("Buffalo WBR2-G54 / WBR2-G54S");
3312                return ROUTER_BUFFALO_WBR2G54S;
3313        }
3314
3315        if (boardnum == 2 && nvram_match("boardtype", "0x0101")
3316            && nvram_match("boardrev", "0x10")) {
3317                setRouter("Buffalo WLA2-G54C / WLI3-TX1-G54");
3318                return ROUTER_BUFFALO_WLA2G54C;
3319        }
3320        if (boardnum == 0 && melco_id == 29090 && nvram_match("boardrev", "0x10")) {
3321                setRouter("Buffalo WLAH-G54");
3322                return ROUTER_BUFFALO_WLAH_G54;
3323
3324        }
3325        if (boardnum == 0 && melco_id == 31070 && nvram_match("boardflags", "0x2288")
3326            && nvram_match("boardrev", "0x10")) {
3327                setRouter("Buffalo WAPM-HP-AM54G54");
3328                return ROUTER_BUFFALO_WAPM_HP_AM54G54;
3329        }
3330
3331        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x11")
3332            && nvram_match("boardtype", "0x048e") && melco_id == 32093) {
3333                setRouter("Buffalo WHR-G125");
3334                return ROUTER_BUFFALO_WHRG54S;
3335        }
3336
3337        if (nvram_match("boardnum", "0x5347") && nvram_match("boardrev", "0x11")
3338            && nvram_match("boardtype", "0x048e")) {
3339                setRouter("Huawei B970b");
3340                return ROUTER_HUAWEI_B970B;
3341        }
3342
3343        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x10")
3344            && nvram_match("boardtype", "0x048e") && melco_id == 32139) {
3345                setRouter("Buffalo WCA-G");
3346                return ROUTER_BUFFALO_WCAG;     //vlan1 is lan, vlan0 is unused, implementation not done. will me made after return to germany
3347        }
3348
3349        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x11")
3350            && nvram_match("boardtype", "0x048e") && melco_id == 32064) {
3351                setRouter("Buffalo WHR-HP-G125");
3352                return ROUTER_BUFFALO_WHRG54S;
3353        }
3354
3355        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x13")
3356            && nvram_match("boardtype", "0x467")) {
3357                if (nvram_match("boardflags", "0x1658")
3358                    || nvram_match("boardflags", "0x2658")
3359                    || nvram_match("boardflags", "0x3658")) {
3360                        setRouter("Buffalo WLI-TX4-G54HP");
3361                        return ROUTER_BUFFALO_WLI_TX4_G54HP;
3362                }
3363                if (!nvram_matchi("buffalo_hp", 1)
3364                    && nvram_match("boardflags", "0x2758")) {
3365                        setRouter("Buffalo WHR-G54S");
3366                        return ROUTER_BUFFALO_WHRG54S;
3367                }
3368                if (nvram_matchi("buffalo_hp", 1)
3369                    || nvram_match("boardflags", "0x1758")) {
3370#ifndef HAVE_BUFFALO
3371                        setRouter("Buffalo WHR-HP-G54");
3372#else
3373#ifdef BUFFALO_JP
3374                        setRouter("Buffalo AS-A100");
3375#else
3376                        setRouter("Buffalo WHR-HP-G54DD");
3377#endif
3378#endif
3379                        return ROUTER_BUFFALO_WHRG54S;
3380                }
3381        }
3382
3383        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x10")
3384            && nvram_match("boardtype", "0x470")) {
3385                setRouter("Buffalo WHR-AM54G54");
3386                return ROUTER_BUFFALO_WHRAM54G54;
3387        }
3388
3389        if (boardnum == 42 && nvram_match("boardtype", "0x042f")) {
3390
3391                if (nvram_match("product_name", "WZR-RS-G54")
3392                    || melco_id == 30083) {
3393                        setRouter("Buffalo WZR-RS-G54");
3394                        return ROUTER_BUFFALO_WZRRSG54;
3395                }
3396                if (nvram_match("product_name", "WZR-HP-G54")
3397                    || melco_id == 30026) {
3398                        setRouter("Buffalo WZR-HP-G54");
3399                        return ROUTER_BUFFALO_WZRRSG54;
3400                }
3401                if (nvram_match("product_name", "WZR-G54") || melco_id == 30061) {
3402                        setRouter("Buffalo WZR-G54");
3403                        return ROUTER_BUFFALO_WZRRSG54;
3404                }
3405                if (nvram_match("melco_id", "290441dd")) {
3406                        setRouter("Buffalo WHR2-A54G54");
3407                        return ROUTER_BUFFALO_WZRRSG54;
3408                }
3409                if (nvram_match("product_name", "WHR3-AG54")
3410                    || nvram_match("product_name", "WHR3-B11")
3411                    || melco_id == 29130) {
3412                        setRouter("Buffalo WHR3-AG54");
3413                        return ROUTER_BUFFALO_WZRRSG54;
3414                }
3415                if (nvram_match("product_name", "WVR-G54-NF")
3416                    || melco_id == 28100) {
3417                        setRouter("Buffalo WVR-G54-NF");
3418                        return ROUTER_BUFFALO_WZRRSG54;
3419                }
3420                if (nvram_match("product_name", "WZR-G108") || melco_id == 31095 || melco_id == 30153) {
3421                        setRouter("Buffalo WZR-G108");
3422                        return ROUTER_BRCM4702_GENERIC;
3423                }
3424                if (melco_id > 0)       // e.g. 29115
3425                {
3426                        setRouter("Buffalo WZR series");
3427                        return ROUTER_BUFFALO_WZRRSG54;
3428                }
3429        }
3430#ifndef HAVE_BUFFALO
3431        if (boardnum == 42 && nvram_match("boardtype", "0x042f")
3432            && nvram_match("boardrev", "0x10"))
3433                // nvram_match ("boardflags","0x0018"))
3434        {
3435                setRouter("Linksys WRTSL54GS");
3436                return ROUTER_WRTSL54GS;
3437        }
3438
3439        if (boardnum == 42 && nvram_match("boardtype", "0x0101")
3440            && nvram_match("boardrev", "0x10")
3441            && nvram_match("boot_ver", "v3.6")) {
3442                setRouter("Linksys WRT54G3G");
3443                return ROUTER_WRT54G3G;
3444        }
3445
3446        if (nvram_match("boardtype", "0x042f")
3447            && nvram_match("boardrev", "0x10")) {
3448                char *hwver = nvram_safe_get("hardware_version");
3449
3450                if (boardnum == 45 || startswith(hwver, "WL500gp")
3451                    || startswith(hwver, "WL500gH")) {
3452                        setRouter("Asus WL-500g Premium");
3453                        return ROUTER_ASUS_WL500G_PRE;
3454                }
3455                if (boardnum == 44 || startswith(hwver, "WL700g")) {
3456                        setRouter("Asus WL-700gE");
3457                        return ROUTER_ASUS_WL700GE;
3458                }
3459        }
3460
3461        char *et0 = nvram_safe_get("et0macaddr");
3462
3463        if (boardnum == 100 && nvram_match("boardtype", "bcm94710r4")) {
3464                if (startswith(et0, "00:11:50")) {
3465                        setRouter("Belkin F5D7130 / F5D7330");
3466                        return ROUTER_RT210W;
3467                }
3468                if (startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
3469                        setRouter("Belkin F5D7230-4 v1000");
3470                        return ROUTER_RT210W;
3471                }
3472                if (startswith(et0, "00:01:E3") || startswith(et0, "00:01:e3") || startswith(et0, "00:90:96")) {
3473                        setRouter("Siemens SE505 v1");
3474                        return ROUTER_RT210W;
3475                } else {
3476                        setRouter("Askey RT210W generic");
3477                        return ROUTER_RT210W;
3478                }
3479        }
3480
3481        if (nvram_match("boardtype", "bcm94710r4")
3482            && nvram_match("boardnum", "")) {
3483                setRouter("Askey board RT2100W-D65)");
3484                return ROUTER_BRCM4702_GENERIC;
3485        }
3486
3487        if (boardnum == 0 && nvram_match("boardtype", "0x0100")
3488            && nvram_match("boardrev", "0x10")) {
3489                if (startswith(et0, "00:11:50") || startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
3490                        setRouter("Askey board RT2205(6)D-D56");
3491                } else {
3492                        setRouter("Belkin board F5D8230");
3493                }
3494                return ROUTER_ASKEY_RT220XD;
3495        }
3496
3497        if (nvram_match("boardtype", "0x0101")) {
3498                if (startswith(et0, "00:11:50") || startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
3499                        if (nvram_matchi("Belkin_ver", 2000)) {
3500                                setRouter("Belkin F5D7230-4 v2000");
3501                                return ROUTER_BELKIN_F5D7230_V2000;
3502                        } else {
3503                                setRouter("Belkin F5D7230-4 v1444");
3504                                return ROUTER_RT480W;
3505                        }
3506                }
3507                if (startswith(et0, "00:01:E3") || startswith(et0, "00:01:e3") || startswith(et0, "00:90:96")) {
3508                        setRouter("Siemens SE505 v2");
3509                        return ROUTER_RT480W;
3510                }
3511        }
3512        if (boardnum == 1 && nvram_match("boardtype", "0x456")
3513            && nvram_matchi("test_led_gpio", 2)) {
3514                setRouter("Belkin F5D7230-4 v3000");
3515                return ROUTER_BELKIN_F5D7230_V3000;
3516        }
3517
3518        if (nvram_match("boardtype", "0x456")
3519            && nvram_match("hw_model", "F5D7231-4")) {
3520                setRouter("Belkin F5D7231-4 v1212UK");
3521                return ROUTER_BELKIN_F5D7231;
3522        }
3523
3524        if (boardnum == 8 && nvram_match("boardtype", "0x0467"))        // fccid:
3525                // K7SF5D7231B
3526        {
3527                setRouter("Belkin F5D7231-4 v2000");
3528                return ROUTER_BELKIN_F5D7231_V2000;
3529        }
3530
3531        if (nvram_match("boardtype", "0x467")) {
3532                if (startswith(et0, "00:11:50") || startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
3533                        setRouter("Belkin F5D7231-4 v2000");
3534                        return ROUTER_BELKIN_F5D7231;
3535                }
3536        }
3537#endif
3538        if (boardnum == 2 && nvram_match("boardtype", "bcm94710dev") && melco_id == 29016)      // Buffalo
3539                // WLI2-TX1-G54)
3540        {
3541                setRouter("Buffalo WLI2-TX1-G54");
3542                return ROUTER_BUFFALO_WLI2_TX1_G54;
3543        }
3544#ifndef HAVE_BUFFALO
3545
3546        char *gemtek = nvram_safe_get("GemtekPmonVer");
3547        unsigned long gemteknum = strtoul(gemtek, NULL, 0);
3548
3549        if (boardnum == 2 && (gemteknum == 10 || gemteknum == 11) &&
3550            (startswith(et0, "00:0C:E5") ||
3551             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"))) {
3552                setRouter("Motorola WE800G v1");
3553                return ROUTER_MOTOROLA_WE800G;
3554        }
3555
3556        if (boardnum == 2 && (startswith(gemtek, "RC") || gemteknum == 1 || gemteknum == 10)) {
3557                setRouter("Linksys WAP54G v1.x");
3558                return ROUTER_WAP54G_V1;
3559        }
3560
3561        if (boardnum == 2 && gemteknum == 1) {
3562                setRouter("Sitecom WL-105(b)");
3563                return ROUTER_SITECOM_WL105B;
3564        }
3565
3566        if (boardnum == 2 && gemteknum == 7 && nvram_match("boardtype", "bcm94710dev")) {
3567                setRouter("Sitecom WL-111");
3568                return ROUTER_SITECOM_WL111;
3569        }
3570
3571        if (gemteknum == 9)     // Must be Motorola wr850g v1 or we800g v1 or
3572                // Linksys wrt55ag v1
3573        {
3574                if (startswith(et0, "00:0C:E5") ||
3575                    startswith(et0, "00:0c:e5") ||
3576                    startswith(et0, "00:0C:10") ||
3577                    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")) {
3578                        if (!strlen(nvram_safe_get("phyid_num"))) {
3579                                insmod("switch-core");  // get phy type
3580                                insmod("switch-robo");
3581                                rmmod("switch-robo");
3582                                rmmod("switch-core");
3583                                nvram_seti("boardnum", 2);
3584                                nvram_set("boardtype", "bcm94710dev");
3585                        }
3586                        if (nvram_match("phyid_num", "0x00000000")) {
3587                                setRouter("Motorola WE800G v1");
3588                                return ROUTER_MOTOROLA_WE800G;
3589                        } else  // phyid_num == 0xffffffff
3590                        {
3591                                setRouter("Motorola WR850G v1");
3592                                return ROUTER_MOTOROLA_V1;
3593                        }
3594                } else {
3595                        setRouter("Linksys WRT55AG v1");
3596                        return ROUTER_LINKSYS_WRT55AG;
3597                }
3598        }
3599#endif
3600        if (boardnum == 0 && nvram_match("boardtype", "0x478")
3601            && nvram_matchi("cardbus", 0) && nvram_match("boardrev", "0x10")
3602            && nvram_match("boardflags", "0x110") && melco_id == 32027) {
3603                setRouter("Buffalo WZR-G144NH");
3604                return ROUTER_BUFFALO_WZRG144NH;
3605        }
3606
3607        if (boardnum == 20060330 && nvram_match("boardtype", "0x0472")) {
3608                setRouter("Buffalo WZR-G300N");
3609                return ROUTER_BUFFALO_WZRG300N;
3610        }
3611#ifndef HAVE_BUFFALO
3612
3613        if (boardnum == 8 && nvram_match("boardtype", "0x0472")
3614            && nvram_matchi("cardbus", 1)) {
3615                setRouter("Netgear WNR834B");
3616                return ROUTER_NETGEAR_WNR834B;
3617        }
3618
3619        if (boardnum == 1 && nvram_match("boardtype", "0x0472")
3620            && nvram_match("boardrev", "0x23")) {
3621                if (nvram_matchi("cardbus", 1)) {
3622                        setRouter("Netgear WNR834B v2");
3623                        return ROUTER_NETGEAR_WNR834BV2;
3624                } else {
3625                        setRouter("Netgear WNDR3300");
3626                        return ROUTER_NETGEAR_WNDR3300;
3627                }
3628        }
3629
3630        if (boardnum == 42)     // Get Linksys N models
3631        {
3632                if (nvram_match("boot_hw_model", "WRT300N")
3633                    && nvram_match("boot_hw_ver", "1.1")) {
3634                        setRouter("Linksys WRT300N v1.1");
3635                        return ROUTER_WRT300NV11;
3636                } else if (nvram_match("boot_hw_model", "WRT150N")
3637                           && nvram_matchi("boot_hw_ver", 1)) {
3638                        setRouter("Linksys WRT150N v1");
3639                        return ROUTER_WRT150N;
3640                } else if (nvram_match("boot_hw_model", "WRT150N")
3641                           && nvram_match("boot_hw_ver", "1.1")) {
3642                        setRouter("Linksys WRT150N v1.1");
3643                        return ROUTER_WRT150N;
3644                } else if (nvram_match("boot_hw_model", "WRT150N")
3645                           && nvram_match("boot_hw_ver", "1.2")) {
3646                        setRouter("Linksys WRT150N v1.2");
3647                        return ROUTER_WRT150N;
3648                } else if (nvram_match("boot_hw_model", "WRT160N")
3649                           && nvram_match("boot_hw_ver", "1.0")) {
3650                        setRouter("Linksys WRT160N");
3651                        return ROUTER_WRT160N;
3652                } else if (nvram_match("boot_hw_model", "WRT160N")
3653                           && nvram_match("boot_hw_ver", "3.0")) {
3654                        setRouter("Linksys WRT160N v3");
3655                        return ROUTER_WRT160NV3;
3656                } else if (nvram_match("boot_hw_model", "M10")
3657                           && nvram_match("boot_hw_ver", "1.0")) {
3658                        setRouter("Cisco Valet M10 v1");        // renamed wrt160nv3
3659                        return ROUTER_WRT160NV3;
3660                } else if (nvram_match("boot_hw_model", "E100")
3661                           && nvram_match("boot_hw_ver", "1.0")) {
3662                        setRouter("Linksys E1000 v1");  // renamed wrt160nv3
3663                        return ROUTER_WRT160NV3;
3664                } else if (nvram_match("boot_hw_model", "E800")
3665                           && nvram_match("boot_hw_ver", "1.0")) {
3666                        setRouter("Linksys E800");
3667                        return ROUTER_LINKSYS_E800;
3668                } else if (nvram_match("boot_hw_model", "E900")
3669                           && nvram_match("boot_hw_ver", "1.0")) {
3670                        setRouter("Linksys E900");
3671                        return ROUTER_LINKSYS_E900;
3672                } else if (nvram_match("boot_hw_model", "E1000")
3673                           && nvram_match("boot_hw_ver", "2.0")) {
3674                        setRouter("Linksys E1000 v2");
3675                        return ROUTER_LINKSYS_E1000V2;
3676                } else if (nvram_match("boot_hw_model", "E1000")
3677                           && nvram_match("boot_hw_ver", "2.1")) {
3678                        setRouter("Linksys E1000 v2.1");
3679                        return ROUTER_LINKSYS_E1000V2;
3680                } else if (nvram_match("boot_hw_model", "E1200")
3681                           && nvram_match("boot_hw_ver", "1.0")) {
3682                        setRouter("Linksys E1200 v1");
3683                        return ROUTER_LINKSYS_E1500;
3684                } else if (nvram_match("boot_hw_model", "E1200")
3685                           && nvram_match("boot_hw_ver", "2.0")) {
3686                        setRouter("Linksys E1200 v2");
3687                        return ROUTER_LINKSYS_E900;
3688                } else if (nvram_match("boot_hw_model", "E1500")
3689                           && nvram_match("boot_hw_ver", "1.0")) {
3690                        setRouter("Linksys E1500");
3691                        return ROUTER_LINKSYS_E1500;
3692                } else if (nvram_match("boot_hw_model", "E1550")
3693                           && nvram_match("boot_hw_ver", "1.0")) {
3694                        setRouter("Linksys E1550");
3695                        return ROUTER_LINKSYS_E1550;
3696                } else if (nvram_match("boot_hw_model", "WRT310N")
3697                           && nvram_match("boot_hw_ver", "1.0")) {
3698                        setRouter("Linksys WRT310N");
3699                        return ROUTER_WRT310N;
3700                } else if (nvram_match("boot_hw_model", "WRT310N")
3701                           && nvram_match("boot_hw_ver", "2.0")) {
3702                        setRouter("Linksys WRT310N v2");
3703                        return ROUTER_WRT310NV2;
3704                } else if (nvram_match("boot_hw_model", "M20")
3705                           && nvram_match("boot_hw_ver", "1.0")) {
3706                        setRouter("Cisco Valet Plus M20");      // ranamed wrt310nv2
3707                        return ROUTER_WRT310NV2;
3708                } else if (nvram_match("boot_hw_model", "E2500")
3709                           && nvram_match("boot_hw_ver", "1.0")) {
3710                        setRouter("Linksys E2500");
3711                        return ROUTER_LINKSYS_E2500;
3712                } else if (nvram_match("boot_hw_model", "E3200")
3713                           && nvram_match("boot_hw_ver", "1.0")) {
3714                        setRouter("Linksys E3200");
3715                        return ROUTER_LINKSYS_E3200;
3716                } else if (nvram_match("boot_hw_model", "E4200")
3717                           && nvram_match("boot_hw_ver", "1.0")) {
3718                        setRouter("Linksys E4200");
3719                        return ROUTER_LINKSYS_E4200;
3720                }
3721        }
3722
3723        if (boardnum == 42 && nvram_match("boardtype", "0x0472")
3724            && nvram_matchi("cardbus", 1)) {
3725                setRouter("Linksys WRT300N v1");
3726                return ROUTER_WRT300N;
3727        }
3728
3729        if (boardnum == 42 && nvram_match("boardtype", "0x478") && nvram_matchi("cardbus", 1)) {
3730                setRouter("Linksys WRT350N");
3731                return ROUTER_WRT350N;
3732        }
3733
3734        if (nvram_matchi("boardnum", 20070615) && nvram_match("boardtype", "0x478") && nvram_matchi("cardbus", 0)) {
3735                if (nvram_match("switch_type", "BCM5395")) {
3736                        setRouter("Linksys WRT600N v1.1");
3737                        return ROUTER_WRT600N;
3738                } else {
3739                        setRouter("Linksys WRT600N");
3740                        return ROUTER_WRT600N;
3741                }
3742        }
3743
3744        if (nvram_match("boardtype", "0x478")
3745            && nvram_match("boot_hw_model", "WRT610N")) {
3746                setRouter("Linksys WRT610N");
3747                return ROUTER_WRT610N;
3748        }
3749#ifdef HAVE_BCMMODERN
3750        if (nvram_match("boardtype", "0x04cf")
3751            && nvram_match("boot_hw_model", "WRT610N")) {
3752                setRouter("Linksys WRT610N v2");
3753                return ROUTER_WRT610NV2;
3754        }
3755
3756        if (nvram_match("boardtype", "0x04cf")
3757            && nvram_match("boot_hw_model", "E300")) {
3758                setRouter("Linksys E3000");     // renamed wrt610nv2
3759                return ROUTER_WRT610NV2;
3760        }
3761
3762        if (boardnum == 1 && nvram_match("boardtype", "0x052b")
3763            && nvram_match("boardrev", "0x1204")) {
3764                setRouter("Linksys EA2700");    // renamed wrt610nv2
3765                return ROUTER_LINKSYS_EA2700;
3766        }
3767#endif
3768
3769        if (boardnum == 42 && nvram_match("boardtype", "bcm94710dev")) {
3770                setRouter("Linksys WRT54G v1.x");
3771                return ROUTER_WRT54G1X;
3772        }
3773
3774        if ((boardnum == 1 || boardnum == 0)
3775            && nvram_match("boardtype", "0x0446")) {
3776                setRouter("U.S.Robotics USR5430");
3777                return ROUTER_USR_5430;
3778        }
3779
3780        if (boardnum == 1 && nvram_match("boardtype", "0x456")
3781            && nvram_matchi("test_led_gpio", 0)) {
3782                setRouter("Netgear WG602 v3");
3783                return ROUTER_NETGEAR_WG602_V3;
3784        }
3785
3786        if (boardnum == 10496 && nvram_match("boardtype", "0x456")) {
3787                setRouter("U.S.Robotics USR5461");
3788                return ROUTER_USR_5461;
3789        }
3790
3791        if (boardnum == 10500 && nvram_match("boardtype", "0x456")) {
3792                setRouter("U.S.Robotics USR5432");
3793                return ROUTER_USR_5461; // should work in the same way
3794        }
3795
3796        if (boardnum == 10506 && nvram_match("boardtype", "0x456")) {
3797                setRouter("U.S.Robotics USR5451");
3798                return ROUTER_USR_5461; // should work in the same way
3799        }
3800
3801        if (boardnum == 10512 && nvram_match("boardtype", "0x456")) {
3802                setRouter("U.S.Robotics USR5441");
3803                return ROUTER_USR_5461; // should work in the same way
3804        }
3805
3806        if ((boardnum == 35324 || boardnum == 38256)
3807            && nvram_match("boardtype", "0x048e")) {
3808                setRouter("U.S.Robotics USR5465");
3809                return ROUTER_USR_5465;
3810        }
3811
3812        if (boardnum == 35334 && nvram_match("boardtype", "0x048e")) {
3813                setRouter("U.S.Robotics USR5455");
3814                return ROUTER_USR_5465; // should work in the same way
3815        }
3816
3817        if (boardnum == 1024 && nvram_match("boardtype", "0x0446")) {
3818                char *cfe = nvram_safe_get("cfe_version");
3819
3820                if (strstr(cfe, "WRE54G")) {
3821                        setRouter("Linksys WRE54G v1");
3822                        return ROUTER_WAP54G_V2;
3823                } else if (strstr(cfe, "iewsonic")) {
3824                        setRouter("Viewsonic WAPBR-100");
3825                        return ROUTER_VIEWSONIC_WAPBR_100;
3826                } else {
3827                        setRouter("Linksys WAP54G v2");
3828                        return ROUTER_WAP54G_V2;
3829                }
3830        }
3831
3832        if (nvram_invmatch("CFEver", "")) {
3833                char *cfe = nvram_safe_get("CFEver");
3834
3835                if (!strncmp(cfe, "MotoWR", 6)) {
3836                        setRouter("Motorola WR850G v2/v3");
3837                        return ROUTER_MOTOROLA;
3838                }
3839        }
3840
3841        if (boardnum == 44 && (nvram_match("boardtype", "0x0101")
3842                               || nvram_match("boardtype", "0x0101\r"))) {
3843                char *cfe = nvram_safe_get("CFEver");
3844
3845                if (!strncmp(cfe, "GW_WR110G", 9)) {
3846                        setRouter("Sparklan WX-6615GT");
3847                        return ROUTER_DELL_TRUEMOBILE_2300_V2;
3848                } else {
3849                        setRouter("Dell TrueMobile 2300 v2");
3850                        return ROUTER_DELL_TRUEMOBILE_2300_V2;
3851                }
3852        }
3853#endif
3854        if (nvram_match("boardtype", "bcm94710ap")) {
3855                setRouter("Buffalo WBR-B11");
3856                return ROUTER_BUFFALO_WBR54G;
3857        }
3858
3859        if (nvram_match("productid", "RT-AC66U")) {
3860                setRouter("Asus RT-AC66U");
3861                return ROUTER_ASUS_AC66U;
3862        }
3863
3864        if (nvram_match("boardtype", "0xF5B2")
3865            && nvram_match("boardrev", "0x1100")
3866            && nvram_matchi("pci/2/1/sb20in80and160hr5ghpo", 0)) {
3867                setRouter("Asus RT-AC66U");
3868                return ROUTER_ASUS_AC66U;
3869        }
3870
3871        if (nvram_match("boardnum", "${serno}") && nvram_match("boardtype", "0xC617") && nvram_match("boardrev", "0x1103")) {
3872                setRouter("Linksys EA6500");
3873                return ROUTER_LINKSYS_EA6500;
3874        }
3875
3876        if (nvram_match("boardtype", "0x0617") && nvram_match("boardrev", "0x1103")) {
3877                setRouter("Ubiquiti UnifiAP AC");
3878#ifdef HAVE_REGISTER
3879                return ROUTER_UBNT_UNIFIAC;
3880#else
3881                sys_reboot();
3882                exit(-1);
3883#endif
3884        }
3885
3886        if (boardnum == 24 && nvram_match("boardtype", "0x0617")
3887            && nvram_match("boardrev", "0x1102")
3888            && nvram_match("gpio7", "usbport1")) {
3889                setRouter("Dlink-DIR865L");
3890                return ROUTER_DLINK_DIR865;
3891        }
3892
3893        if (boardnum == 00 && nvram_match("boardtype", "0xf52e")
3894            && nvram_match("boardrev", "0x1204")) {
3895                if (nvram_match("product", "WLI-H4-D1300")) {
3896#ifdef HAVE_BUFFALO
3897                        setRouter("WLI-H4-D1300");
3898#else
3899                        setRouter("Buffalo WLI-H4-D1300");
3900#endif
3901                } else {
3902#ifdef HAVE_BUFFALO
3903                        setRouter("WZR-D1800H");
3904#else
3905                        setRouter("Buffalo WZR-D1800H");
3906#endif
3907                }
3908                return ROUTER_D1800H;
3909        }
3910#ifndef HAVE_BUFFALO
3911        if (boardnum == 0 && nvram_match("boardtype", "0x048e") &&      // cfe sets boardnum="", strtoul -> 0
3912            nvram_match("boardrev", "0x35")) {
3913                setRouter("D-Link DIR-320");
3914                // apply some fixes
3915                if (nvram_get("vlan2ports") != NULL) {
3916                        nvram_unset("vlan2ports");
3917                        nvram_unset("vlan2hwname");
3918                }
3919                return ROUTER_DLINK_DIR320;
3920        }
3921        if (nvram_match("model_name", "DIR-330") && nvram_match("boardrev", "0x10")) {
3922                setRouter("D-Link DIR-330");
3923                nvram_set("wan_ifnames", "eth0");       // quirk
3924                nvram_set("wan_ifname", "eth0");
3925                if (nvram_match("et0macaddr", "00:90:4c:4e:00:0c")) {
3926                        FILE *in = fopen("/dev/mtdblock/1", "rb");
3927
3928                        fseek(in, 0x7a0022, SEEK_SET);
3929                        char mac[32];
3930
3931                        fread(mac, 32, 1, in);
3932                        fclose(in);
3933                        mac[17] = 0;
3934                        if (sv_valid_hwaddr(mac)) {
3935                                nvram_set("et0macaddr", mac);
3936                                fprintf(stderr, "restore D-Link MAC\n");
3937                                nvram_commit();
3938                                sys_reboot();
3939                        }
3940                }
3941                /*
3942                 * if (nvram_get("vlan2ports")!=NULL) { nvram_unset("vlan2ports");
3943                 * nvram_unset("vlan2hwname"); }
3944                 */
3945                return ROUTER_DLINK_DIR330;
3946        }
3947        if (boardnum == 42 && nvram_match("boardtype", "0x048e")
3948            && nvram_match("boardrev", "0x10")) {
3949                if (nvram_match("boardflags", "0x20750")) {
3950                        setRouter("Linksys WRT54G2 / GS2");     // router is wrt54g2v1/v1.3/gs2v1
3951                } else {
3952                        setRouter("Linksys WRT54Gv8 / GSv7");
3953                }
3954                return ROUTER_WRT54G_V8;
3955        }
3956
3957        if (boardnum == 8 && nvram_match("boardtype", "0x048e")
3958            && nvram_match("boardrev", "0x11")) {
3959                setRouter("ALLNET EUROWRT 54"); //ALLNET01
3960                return ROUTER_ALLNET01;
3961        }
3962
3963        if (boardnum == 01 && nvram_match("boardtype", "0x048e")
3964            && nvram_match("boardrev", "0x11")
3965            && (nvram_match("boardflags", "0x650")
3966                || nvram_match("boardflags", "0x0458"))) {
3967                setRouter("Netgear WG602 v4");
3968                return ROUTER_NETGEAR_WG602_V4;
3969        }
3970
3971        if (boardnum == 1 && nvram_match("boardtype", "0x048e")
3972            && nvram_match("boardrev", "0x35")
3973            && nvram_match("parefldovoltage", "0x28")) {
3974                setRouter("NetCore NW618 / Rosewill RNX-GX4");
3975                return ROUTER_NETCORE_NW618;
3976        }
3977
3978        if (boardnum == 42 && nvram_match("boardtype", "0x048E")
3979            && nvram_match("boardrev", "0x10")) {
3980                setRouter("Linksys WRH54G");
3981                return ROUTER_LINKSYS_WRH54G;
3982        }
3983
3984        if (nvram_match("boardnum", "00") && nvram_match("boardtype", "0x048E")
3985            && nvram_match("boardrev", "0x10")) {
3986                setRouter("Linksys WRT54G v8.1");
3987                return ROUTER_WRT54G_V81;
3988        }
3989
3990        if (boardnum == 45 && nvram_match("boardtype", "0x456")) {
3991                setRouter("Asus WL-520G");
3992                return ROUTER_ASUS_WL520G;
3993        }
3994
3995        if (nvram_match("boardtype", "0x48E")
3996            && nvram_match("boardrev", "0x10")) {
3997                char *hwver = nvram_safe_get("hardware_version");
3998
3999                if (boardnum == 45 && startswith(hwver, "WL500GPV2")) {
4000                        setRouter("Asus WL-500G Premium v2");
4001                        return ROUTER_ASUS_WL500G_PRE_V2;
4002                } else if (boardnum == 45 && startswith(hwver, "WL330GE")) {
4003                        setRouter("Asus WL-330GE");
4004                        return ROUTER_ASUS_330GE;
4005                } else if (boardnum == 45 || startswith(hwver, "WL500GU")
4006                           || startswith(hwver, "WL500GC")) {
4007                        setRouter("Asus WL-520GU/GC");
4008                        return ROUTER_ASUS_WL520GUGC;
4009                }
4010        }
4011
4012        if ((boardnum == 83258 || boardnum == 1 || boardnum == 0123)    //or 01 or 001 or 0x01
4013            && (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
4014        {
4015                setRouter("Netgear WGR614v8/L/WW");
4016                return ROUTER_NETGEAR_WGR614L;
4017        }
4018
4019        if (boardnum == 3805 && nvram_match("boardtype", "0x48E")
4020            && nvram_match("boardrev", "0x10")) {
4021                setRouter("Netgear WGR614v9");
4022                return ROUTER_NETGEAR_WGR614V9;
4023        }
4024
4025        if (boardnum == 56 && nvram_match("boardtype", "0x456")
4026            && nvram_match("boardrev", "0x10")) {
4027                setRouter("Linksys WTR54GS");
4028                return ROUTER_LINKSYS_WTR54GS;
4029        }
4030
4031        if (nvram_match("boardnum", "WAP54GV3_8M_0614")
4032            && (nvram_match("boardtype", "0x0467")
4033                || nvram_match("boardtype", "0x467"))
4034            && nvram_matchi("WAPver", 3)) {
4035                setRouter("Linksys WAP54G v3.x");
4036                return ROUTER_WAP54G_V3;
4037        }
4038#ifdef HAVE_BCMMODERN
4039        if (boardnum == 1 && nvram_match("boardtype", "0xE4CD")
4040            && nvram_match("boardrev", "0x1700")) {
4041                setRouter("Netgear WNR2000 v2");
4042                return ROUTER_NETGEAR_WNR2000V2;
4043        }
4044
4045        if ((boardnum == 1 || boardnum == 3500)
4046            && nvram_match("boardtype", "0x04CF")
4047            && (nvram_match("boardrev", "0x1213")
4048                || nvram_matchi("boardrev", 02))) {
4049                setRouter("Netgear WNR3500 v2/U/L v1");
4050                return ROUTER_NETGEAR_WNR3500L;
4051        }
4052
4053        if (nvram_match("boardnum", "3500L") && nvram_match("boardtype", "0x052b")) {
4054                setRouter("Netgear WNR3500L v2");
4055                return ROUTER_NETGEAR_WNR3500LV2;
4056        }
4057
4058        if (nvram_match("boardnum", "01") && nvram_match("boardtype", "0xb4cf")
4059            && nvram_match("boardrev", "0x1100")) {
4060                setRouter("Netgear WNDR3400");
4061                return ROUTER_NETGEAR_WNDR3400;
4062        }
4063
4064        if (nvram_match("boardnum", "01") && nvram_match("boardtype", "0xF52C")
4065            && nvram_match("boardrev", "0x1101")) {
4066
4067                int mtd = getMTD("board_data");
4068                char devname[32];
4069                sprintf(devname, "/dev/mtdblock/%d", mtd);
4070                FILE *model = fopen(devname, "rb");
4071                if (model) {
4072#define WNDR3700V3 "U12H194T00_NETGEAR"
4073                        char modelstr[32];
4074                        fread(modelstr, 1, strlen(WNDR3700V3), model);
4075                        if (!strncmp(modelstr, WNDR3700V3, strlen(WNDR3700V3))) {
4076                                fclose(model);
4077                                setRouter("Netgear WNDR3700v3");
4078                                return ROUTER_NETGEAR_WNDR4000;
4079                        }
4080                        fclose(model);
4081                }
4082                setRouter("Netgear WNDR4000");
4083                return ROUTER_NETGEAR_WNDR4000;
4084        }
4085
4086        if (nvram_matchi("boardnum", 4536)
4087            && nvram_match("boardtype", "0xf52e")
4088            && nvram_match("boardrev", "0x1102")) {
4089                int mtd = getMTD("board_data");
4090                char devname[32];
4091                sprintf(devname, "/dev/mtdblock/%d", mtd);
4092                FILE *model = fopen(devname, "rb");
4093                if (model) {
4094#define R6300 "U12H218T00_NETGEAR"
4095#define WNDR4500V2 "U12H224T00_NETGEAR"
4096                        char modelstr[32];
4097                        fread(modelstr, 1, strlen(R6300), model);
4098                        if (!strncmp(modelstr, R6300, strlen(R6300))) {
4099                                fclose(model);
4100                                setRouter("Netgear R6300");
4101                                return ROUTER_NETGEAR_R6300;
4102                        }
4103                        fread(modelstr, 1, strlen(R6300), model);
4104                        if (!strncmp(modelstr, WNDR4500V2, strlen(WNDR4500V2))) {
4105                                fclose(model);
4106                                setRouter("Netgear WNDR4500V2");
4107                                return ROUTER_NETGEAR_WNDR4500V2;
4108                        }
4109                        fclose(model);
4110                }
4111                setRouter("Netgear WNDR4500");
4112                return ROUTER_NETGEAR_WNDR4500;
4113        }
4114
4115        if (nvram_matchi("boardnum", 679) && nvram_match("boardtype", "0x0646")
4116            && nvram_match("boardrev", "0x1110")) {
4117                setRouter("Netgear R6250");
4118                return ROUTER_NETGEAR_R6250;
4119        }
4120
4121        if ((boardnum == 42 || boardnum == 66)
4122            && nvram_match("boardtype", "0x04EF")
4123            && (nvram_match("boardrev", "0x1304")
4124                || nvram_match("boardrev", "0x1305"))) {
4125                setRouter("Linksys WRT320N");
4126                return ROUTER_WRT320N;
4127        }
4128
4129        if (boardnum == 42 && nvram_match("boardtype", "0x04EF")
4130            && nvram_match("boardrev", "0x1307")) {
4131                setRouter("Linksys E2000");     // renamed (and fixed reset button) wrt320n
4132                return ROUTER_WRT320N;
4133        }
4134#endif
4135
4136        if (boardnum == 94703 && nvram_match("boardtype", "0x04c0")
4137            && nvram_match("boardrev", "0x1100")) {
4138                setRouter("Dynex DX-NRUTER");
4139                return ROUTER_DYNEX_DX_NRUTER;
4140        }
4141
4142        setRouter("Linksys WRT54G/GL/GS");
4143        return ROUTER_WRT54G;
4144#else
4145        eval("event", "3", "1", "15");
4146        return 0;
4147#endif
4148#endif
4149#endif
4150}
4151
4152static int router_type = -1;
4153int getRouterBrand()
4154{
4155        if (router_type == -1)
4156                router_type = internal_getRouterBrand();
4157        return router_type;
4158}
4159
4160int get_ppp_pid(char *file)
4161{
4162        char buf[80];
4163        int pid = -1;
4164
4165        if (file_to_buf(file, buf, sizeof(buf))) {
4166                char tmp[80], tmp1[80];
4167
4168                snprintf(tmp, sizeof(tmp), "/var/run/%s.pid", buf);
4169                file_to_buf(tmp, tmp1, sizeof(tmp1));
4170                pid = atoi(tmp1);
4171        }
4172        return pid;
4173}
4174
4175int check_wan_link(int num)
4176{
4177        int wan_link = 0;
4178
4179        if ((nvram_match("wan_proto", "pptp")
4180#ifdef HAVE_L2TP
4181             || nvram_match("wan_proto", "l2tp")
4182#endif
4183#ifdef HAVE_PPPOE
4184             || nvram_match("wan_proto", "pppoe")
4185#endif
4186#ifdef HAVE_PPPOEDUAL
4187             || nvram_match("wan_proto", "pppoe_dual")
4188#endif
4189#ifdef HAVE_PPPOA
4190             || nvram_match("wan_proto", "pppoa")
4191#endif
4192#ifdef HAVE_3G
4193             || (nvram_match("wan_proto", "3g") && !nvram_match("3gdata", "hso")
4194                 && !nvram_match("3gdata", "qmi"))
4195#endif
4196             || nvram_match("wan_proto", "heartbeat"))
4197            ) {
4198                FILE *fp;
4199                char filename[80];
4200                char *name;
4201
4202                if (num == 0)
4203                        strcpy(filename, "/tmp/ppp/link");
4204                if ((fp = fopen(filename, "r"))) {
4205                        int pid = -1;
4206
4207                        fclose(fp);
4208                        if (nvram_match("wan_proto", "heartbeat")) {
4209                                char buf[20];
4210
4211                                file_to_buf("/tmp/ppp/link", buf, sizeof(buf));
4212                                pid = atoi(buf);
4213                        } else
4214                                pid = get_ppp_pid(filename);
4215
4216                        name = find_name_by_proc(pid);
4217                        if (!strncmp(name, "pppoecd", 7) ||     // for PPPoE
4218                            !strncmp(name, "pppd", 4) ||        // for PPTP
4219                            !strncmp(name, "bpalogin", 8))      // for HeartBeat
4220                                wan_link = 1;   // connect
4221                        else {
4222                                printf("The %s had been died, remove %s\n", nvram_safe_get("wan_proto"), filename);
4223                                wan_link = 0;   // For some reason, the pppoed had been died,
4224                                // by link file still exist.
4225                                unlink(filename);
4226                        }
4227                }
4228        }
4229#if defined(HAVE_LIBQMI) || defined(HAVE_UQMI)
4230        else if (nvram_match("wan_proto", "3g") && nvram_match("3gdata", "qmi")) {
4231                FILE *fp = fopen("/tmp/qmistatus", "rb");
4232                int value = 0;
4233                if (fp) {
4234                        fscanf(fp, "%d", &value);
4235                        fclose(fp);
4236                }
4237#ifdef HAVE_UQMI
4238                if (value)
4239                        return 1;
4240                return 0;
4241#else
4242                if (value)
4243                        return 0;
4244                return 1;
4245#endif
4246        }
4247#endif
4248        else
4249#ifdef HAVE_IPETH
4250        if (nvram_match("wan_proto", "iphone")) {
4251                FILE *fp;
4252                if ((fp = fopen("/proc/net/dev", "r"))) {
4253                        char line[256];
4254                        while (fgets(line, sizeof(line), fp) != NULL) {
4255                                if (strstr(line, "iph0")) {
4256                                        int sock;
4257                                        struct ifreq ifr;
4258                                        if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
4259                                                break;
4260                                        bzero(&ifr, sizeof(struct ifreq));
4261                                        snprintf(ifr.ifr_name, IFNAMSIZ, "iph0");
4262                                        ioctl(sock, SIOCGIFFLAGS, &ifr);
4263                                        if ((ifr.ifr_flags & (IFF_RUNNING | IFF_UP))
4264                                            == (IFF_RUNNING | IFF_UP))
4265                                                wan_link = 1;
4266                                        close(sock);
4267                                        break;
4268                                }
4269                        }
4270                        fclose(fp);
4271                        if (nvram_match("wan_ipaddr", "0.0.0.0")
4272                            || nvram_match("wan_ipaddr", ""))
4273                                wan_link = 0;
4274
4275                }
4276        } else
4277#endif
4278        {
4279                if (nvram_invmatch("wan_ipaddr", "0.0.0.0"))
4280                        wan_link = 1;
4281        }
4282
4283        return wan_link;
4284}
4285
4286#ifdef HAVE_WZR450HP2
4287struct ENV_EXTDATA {
4288        unsigned char wanmac[6];        // 0x0
4289        unsigned char lanmac[6];        // 0x6
4290        unsigned char wpspin[8];        // 0xc
4291        unsigned char passphrase[25];   // 0x14, length is max <=24 followed by 0 termination
4292        unsigned char authmode[3];
4293        unsigned char crypto[3];
4294        unsigned char authmode_ex[4];
4295        unsigned char region[2];
4296        unsigned char productid[16];
4297        unsigned char bootversion[8];
4298        unsigned char hwversion;
4299        unsigned char customid;
4300        unsigned char melcoid[11];
4301        unsigned char builddate[28];
4302        unsigned char inspection;
4303};
4304
4305static char *getUEnvExt(char *name)
4306{
4307        struct ENV_EXTDATA data;
4308        FILE *fp = fopen("/dev/mtdblock5", "rb");       // board data
4309        if (!fp)
4310                return NULL;
4311
4312        fread(&data, 1, sizeof(data), fp);
4313        fclose(fp);
4314        if (!strcmp(name, "DEF-p_wireless_ath0_11bg-authmode_ex")) {
4315                if (!memcmp(data.authmode_ex, "WPA2", 4))
4316                        return "wpa2-psk";
4317                if (!memcmp(data.authmode_ex, "WPA", 3))
4318                        return "wpa-psk";
4319        }
4320        if (!strcmp(name, "DEF-p_wireless_ath0_11bg-authmode")) {
4321                if (!memcmp(data.authmode_ex, "WPA2", 4) && !memcmp(data.authmode, "PSK", 3))
4322                        return "psk2";
4323                if (!memcmp(data.authmode_ex, "WPA", 3) && !memcmp(data.authmode, "PSK", 3))
4324                        return "psk";
4325        }
4326        if (!strcmp(name, "DEF-p_wireless_ath0_11bg-wpapsk")) {
4327                static char passphrase[25];
4328                strncpy(passphrase, (char *)&data.passphrase[1], (data.passphrase[0] & 0xff));
4329                return passphrase;
4330        }
4331        if (!strcmp(name, "DEF-p_wireless_ath0_11bg-crypto")) {
4332                if (!memcmp(data.crypto, "AES", 3))
4333                        return "aes";
4334        }
4335        if (!strcmp(name, "region")) {
4336                static char region[3];
4337                region[2] = 0;
4338                memcpy(region, data.region, 2);
4339                return region;
4340        }
4341        if (!strcmp(name, "pincode")) {
4342                static char pincode[9];
4343                memcpy(pincode, data.wpspin, 8);
4344                pincode[8] = 0;
4345                return pincode;
4346        }
4347
4348        return NULL;
4349}
4350
4351#endif
4352
4353#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)
4354void *getUEnv(char *name)
4355{
4356
4357#ifdef HAVE_WZRG300NH
4358#define UOFFSET 0x40000
4359#elif HAVE_WZR450HP2
4360#define UOFFSET 0x40000
4361#elif HAVE_WZRHPAG300NH
4362#define UOFFSET 0x40000
4363#elif HAVE_WZRG450
4364#define UOFFSET 0x40000
4365#elif HAVE_WMBR_G300NH
4366#define UOFFSET 0x0
4367#elif HAVE_DIR810L
4368#define UOFFSET 0x0
4369#elif HAVE_MVEBU
4370#define UOFFSET 0x0
4371#elif HAVE_IPQ806X
4372#define UOFFSET 0x0
4373#else
4374#define UOFFSET 0x3E000
4375#endif
4376//      static char res[64];
4377        static char res[256];
4378        bzero(res, sizeof(res));
4379        //fprintf(stderr,"[u-boot env]%s\n",name);
4380#if defined(HAVE_WMBR_G300NH) || defined(HAVE_DIR810L)
4381        FILE *fp = fopen("/dev/mtdblock/1", "rb");
4382#elif HAVE_MVEBU
4383        FILE *fp = fopen("/dev/mtdblock/1", "rb");
4384#elif HAVE_IPQ806X
4385        int brand = getRouterBrand();
4386        FILE *fp;
4387        if (brand == ROUTER_LINKSYS_EA8500) {
4388                fp = fopen("/dev/mtdblock/10", "rb");
4389        } else {
4390                fp = fopen("/dev/mtdblock/3", "rb");
4391        }
4392#else
4393        FILE *fp = fopen("/dev/mtdblock/0", "rb");
4394#endif
4395        char newname[64];
4396        snprintf(newname, 64, "%s=", name);
4397        fseek(fp, UOFFSET, SEEK_SET);
4398        char *mem = safe_malloc(0x2000);
4399        fread(mem, 0x2000, 1, fp);
4400        fclose(fp);
4401        int s = (0x2000 - 1) - strlen(newname);
4402        int i;
4403        int l = strlen(newname);
4404        for (i = 0; i < s; i++) {
4405                if (!strncmp(mem + i, newname, l)) {
4406                        strncpy(res, mem + i + l, sizeof(res) - 1);
4407                        free(mem);
4408                        return res;
4409                }
4410        }
4411        free(mem);
4412#ifdef HAVE_WZR450HP2
4413        char *result = getUEnvExt(name);
4414        if (result)
4415                return result;
4416#endif
4417        return NULL;
4418}
4419#endif
4420
4421char *get_wan_ipaddr(void)
4422{
4423        char *wan_ipaddr;
4424        char *wan_proto = nvram_safe_get("wan_proto");
4425        int wan_link = check_wan_link(0);
4426
4427        if (!strcmp(wan_proto, "pptp")) {
4428                wan_ipaddr = wan_link ? nvram_safe_get("pptp_get_ip") : nvram_safe_get("wan_ipaddr");
4429        } else if (!strcmp(wan_proto, "pppoe")
4430#ifdef HAVE_PPPOATM
4431                   || !strcmp(wan_proto, "pppoa")
4432#endif
4433#ifdef HAVE_PPPOEDUAL
4434                   || !strcmp(wan_proto, "pppoe_dual")
4435#endif
4436#ifdef HAVE_3G
4437                   || !strcmp(wan_proto, "3g")
4438#endif
4439            ) {
4440                wan_ipaddr = wan_link ? nvram_safe_get("wan_ipaddr") : "0.0.0.0";
4441#ifdef HAVE_L2TP
4442        } else if (!strcmp(wan_proto, "l2tp")) {
4443                wan_ipaddr = wan_link ? nvram_safe_get("l2tp_get_ip") : nvram_safe_get("wan_ipaddr");
4444#endif
4445        } else {
4446                wan_ipaddr = nvram_safe_get("wan_ipaddr");
4447        }
4448
4449        if (strlen(wan_ipaddr) == 0)
4450                wan_ipaddr = "0.0.0.0";
4451
4452        return wan_ipaddr;
4453}
4454
4455/*
4456 * Find process name by pid from /proc directory
4457 */
4458char *find_name_by_proc(int pid)
4459{
4460        FILE *fp;
4461        char line[254];
4462        char filename[80];
4463        static char name[80];
4464
4465        snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
4466
4467        if ((fp = fopen(filename, "r"))) {
4468                fgets(line, sizeof(line), fp);
4469                /*
4470                 * Buffer should contain a string like "Name: binary_name"
4471                 */
4472                sscanf(line, "%*s %s", name);
4473                fclose(fp);
4474                return name;
4475        }
4476
4477        return "";
4478}
4479
4480int diag_led_4702(int type, int act)
4481{
4482
4483#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)
4484        return 0;
4485#else
4486        if (act == START_LED) {
4487                switch (type) {
4488                case DMZ:
4489                        writeprocsys("diag", "1");
4490                        break;
4491                }
4492        } else {
4493                switch (type) {
4494                case DMZ:
4495                        writeprocsys("diag", "0");
4496                        break;
4497                }
4498        }
4499        return 0;
4500#endif
4501}
4502
4503int C_led_4702(int i)
4504{
4505#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)
4506        return 0;
4507#else
4508        FILE *fp;
4509        char string[10];
4510        int flg;
4511
4512        bzero(string, 10);
4513        /*
4514         * get diag before set
4515         */
4516        if ((fp = fopen("/proc/sys/diag", "r"))) {
4517                fgets(string, sizeof(string), fp);
4518                fclose(fp);
4519        } else
4520                perror("/proc/sys/diag");
4521
4522        if (i)
4523                flg = atoi(string) | 0x10;
4524        else
4525                flg = atoi(string) & 0xef;
4526
4527        bzero(string, 10);
4528        sprintf(string, "%d", flg);
4529        writeprocsys("diag", string);
4530
4531        return 0;
4532#endif
4533}
4534
4535unsigned int read_gpio(char *device)
4536{
4537        FILE *fp;
4538        unsigned int val;
4539
4540        if ((fp = fopen(device, "r"))) {
4541                fread(&val, 4, 1, fp);
4542                fclose(fp);
4543                // fprintf(stderr, "----- gpio %s = [%X]\n",device,val);
4544                return val;
4545        } else {
4546                perror(device);
4547                return 0;
4548        }
4549}
4550
4551unsigned int write_gpio(char *device, unsigned int val)
4552{
4553        FILE *fp;
4554
4555        if ((fp = fopen(device, "w"))) {
4556                fwrite(&val, 4, 1, fp);
4557                fclose(fp);
4558                // fprintf(stderr, "----- set gpio %s = [%X]\n",device,val);
4559                return 1;
4560        } else {
4561                perror(device);
4562                return 0;
4563        }
4564}
4565
4566int diag_led_4704(int type, int act)
4567{
4568#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)
4569        return 0;
4570#else
4571        unsigned int control, in, outen, out;
4572
4573#ifdef BCM94712AGR
4574        /*
4575         * The router will crash, if we load the code into broadcom demo board.
4576         */
4577        return 1;
4578#endif
4579        static char hw_error = 0;
4580        // int brand;
4581        control = read_gpio("/dev/gpio/control");
4582        in = read_gpio("/dev/gpio/in");
4583        out = read_gpio("/dev/gpio/out");
4584        outen = read_gpio("/dev/gpio/outen");
4585
4586        write_gpio("/dev/gpio/outen", (outen & 0x7c) | 0x83);
4587        switch (type) {
4588        case DIAG:              // GPIO 1
4589                if (hw_error) {
4590                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x00);
4591                        return 1;
4592                }
4593
4594                if (act == STOP_LED) {  // stop blinking
4595                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x83);
4596                        // cprintf("tallest:=====( DIAG STOP_LED !!)=====\n");
4597                } else if (act == START_LED) {  // start blinking
4598                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x81);
4599                        // cprintf("tallest:=====( DIAG START_LED !!)=====\n");
4600                } else if (act == MALFUNCTION_LED) {    // start blinking
4601                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x00);
4602                        hw_error = 1;
4603                        // cprintf("tallest:=====( DIAG MALFUNCTION_LED !!)=====\n");
4604                }
4605                break;
4606
4607        }
4608        return 1;
4609#endif
4610}
4611
4612int diag_led_4712(int type, int act)
4613{
4614
4615#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)
4616        return 0;
4617#else
4618        unsigned int control, in, outen, out, ctr_mask, out_mask;
4619
4620#ifdef BCM94712AGR
4621        /*
4622         * The router will crash, if we load the code into broadcom demo board.
4623         */
4624        return 1;
4625#endif
4626        control = read_gpio("/dev/gpio/control");
4627        in = read_gpio("/dev/gpio/in");
4628        out = read_gpio("/dev/gpio/out");
4629        outen = read_gpio("/dev/gpio/outen");
4630
4631        ctr_mask = ~(1 << type);
4632        out_mask = (1 << type);
4633
4634        write_gpio("/dev/gpio/control", control & ctr_mask);
4635        write_gpio("/dev/gpio/outen", outen | out_mask);
4636
4637        if (act == STOP_LED) {  // stop blinking
4638                // cprintf("%s: Stop GPIO %d\n", __FUNCTION__, type);
4639                write_gpio("/dev/gpio/out", out | out_mask);
4640        } else if (act == START_LED) {  // start blinking
4641                // cprintf("%s: Start GPIO %d\n", __FUNCTION__, type);
4642                write_gpio("/dev/gpio/out", out & ctr_mask);
4643        }
4644
4645        return 1;
4646#endif
4647}
4648
4649int C_led_4712(int i)
4650{
4651        if (i == 1)
4652                return diag_led(DIAG, START_LED);
4653        else
4654                return diag_led(DIAG, STOP_LED);
4655}
4656
4657int C_led(int i)
4658{
4659        int brand = getRouterBrand();
4660
4661        if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
4662                return C_led_4702(i);
4663        else if (brand == ROUTER_WRT54G)
4664                return C_led_4712(i);
4665        else
4666                return 0;
4667}
4668
4669int diag_led(int type, int act)
4670{
4671        int brand = getRouterBrand();
4672
4673        if (brand == ROUTER_WRT54G || brand == ROUTER_WRT54G3G || brand == ROUTER_WRT300NV11)
4674                return diag_led_4712(type, act);
4675        else if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
4676                return diag_led_4702(type, act);
4677        else if ((brand == ROUTER_WRTSL54GS || brand == ROUTER_WRT310N || brand == ROUTER_WRT350N || brand == ROUTER_BUFFALO_WZRG144NH) && type == DIAG)
4678                return diag_led_4704(type, act);
4679        else {
4680                if (type == DMZ) {
4681                        if (act == START_LED)
4682                                return led_control(LED_DMZ, LED_ON);
4683                        if (act == STOP_LED)
4684                                return led_control(LED_DMZ, LED_OFF);
4685                        return 1;
4686                }
4687        }
4688        return 0;
4689}
4690
4691#ifdef HAVE_MADWIFI
4692static char *stalist[] = {
4693        "ath0", "ath1", "ath2", "ath3", "ath4", "ath5", "ath6", "ath8", "ath9"
4694};
4695
4696char *getWifi(char *ifname)
4697{
4698#ifdef HAVE_MVEBU
4699        if (!strncmp(ifname, "ath0", 4))
4700                return "wlan0";
4701        if (!strncmp(ifname, "ath1", 4))
4702                return "wlan1";
4703        if (!strncmp(ifname, "ath2", 4))
4704                return "wlan2";
4705        if (!strncmp(ifname, "ath3", 4))
4706                return "wlan3";
4707        return NULL;
4708#else
4709        if (!strncmp(ifname, "ath0", 4))
4710                return "wifi0";
4711        if (!strncmp(ifname, "ath1", 4))
4712                return "wifi1";
4713        if (!strncmp(ifname, "ath2", 4))
4714                return "wifi2";
4715        if (!strncmp(ifname, "ath3", 4))
4716                return "wifi3";
4717        return NULL;
4718#endif
4719}
4720
4721char *getWDSSTA(void)
4722{
4723
4724        int c = getdevicecount();
4725        int i;
4726
4727        for (i = 0; i < c; i++) {
4728                char mode[32];
4729                char netmode[32];
4730
4731                sprintf(mode, "ath%d_mode", i);
4732                sprintf(netmode, "ath%d_net_mode", i);
4733                if (nvram_match(mode, "wdssta")
4734                    && !nvram_match(netmode, "disabled")) {
4735                        return stalist[i];
4736                }
4737
4738        }
4739        return NULL;
4740}
4741
4742char *getSTA(void)
4743{
4744
4745#ifdef HAVE_WAVESAT
4746        if (nvram_match("ofdm_mode", "sta"))
4747                return "ofdm";
4748#endif
4749        int c = getdevicecount();
4750        int i;
4751
4752        for (i = 0; i < c; i++) {
4753                if (nvram_nmatch("sta", "ath%d_mode", i)
4754                    && !nvram_nmatch("disabled", "ath%d_net_mode", i)) {
4755                        return stalist[i];
4756                }
4757
4758        }
4759        return NULL;
4760}
4761
4762char *getWET(void)
4763{
4764#ifdef HAVE_WAVESAT
4765        if (nvram_match("ofdm_mode", "bridge"))
4766                return "ofdm";
4767#endif
4768        int c = getdevicecount();
4769        int i;
4770
4771        for (i = 0; i < c; i++) {
4772                if (nvram_nmatch("wet", "ath%d_mode", i)
4773                    && !nvram_nmatch("disabled", "ath%d_net_mode", i)) {
4774                        return stalist[i];
4775                }
4776
4777        }
4778        return NULL;
4779}
4780
4781#elif defined(HAVE_RT2880) || defined(HAVE_RT61)
4782
4783char *getSTA()
4784{
4785        int c = get_wl_instances();
4786        int i;
4787
4788        for (i = 0; i < c; i++) {
4789                if (nvram_nmatch("sta", "wl%d_mode", i)) {
4790                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i)) {
4791                                if (i == 0)
4792                                        return "ra0";
4793                                else
4794                                        return "ba0";
4795                        }
4796                }
4797
4798                if (nvram_nmatch("apsta", "wl%d_mode", i)) {
4799                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i)) {
4800                                if (i == 0)
4801                                        return "apcli0";
4802                                else
4803                                        return "apcli1";
4804                        }
4805                }
4806
4807        }
4808        return NULL;
4809}
4810
4811char *getWET()
4812{
4813        int c = get_wl_instances();
4814        int i;
4815
4816        for (i = 0; i < c; i++) {
4817                if (!nvram_nmatch("disabled", "wl%d_net_mode", i)
4818                    && nvram_nmatch("wet", "wl%d_mode", i))
4819                        if (i == 0)
4820                                return "ra0";
4821                        else
4822                                return "ba0";
4823
4824                if (!nvram_nmatch("disabled", "wl%d_net_mode", i)
4825                    && nvram_nmatch("apstawet", "wl%d_mode", i))
4826                        if (i == 0)
4827                                return "apcli0";
4828                        else
4829                                return "apcli1";
4830
4831        }
4832        return NULL;
4833}
4834
4835#else
4836char *getSTA()
4837{
4838        int c = get_wl_instances();
4839        int i;
4840
4841        for (i = 0; i < c; i++) {
4842                if (nvram_nmatch("sta", "wl%d_mode", i)
4843                    || nvram_nmatch("apsta", "wl%d_mode", i)) {
4844                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
4845                                return get_wl_instance_name(i);
4846                        // else
4847                        // return nvram_nget ("wl%d_ifname", i);
4848                }
4849
4850        }
4851        return NULL;
4852}
4853
4854char *getWET()
4855{
4856        int c = get_wl_instances();
4857        int i;
4858
4859        for (i = 0; i < c; i++) {
4860                if (nvram_nmatch("wet", "wl%d_mode", i)
4861                    || nvram_nmatch("apstawet", "wl%d_mode", i)) {
4862                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
4863                                return get_wl_instance_name(i);
4864                        // else
4865                        // return nvram_nget ("wl%d_ifname", i);
4866
4867                }
4868
4869        }
4870        return NULL;
4871}
4872
4873#endif
4874// note - broadcast addr returned in ipaddr
4875void get_broadcast(char *ipaddr, char *netmask)
4876{
4877        int ip2[4], mask2[4];
4878        unsigned char ip[4], mask[4];
4879
4880        if (!ipaddr || !netmask)
4881                return;
4882
4883        sscanf(ipaddr, "%d.%d.%d.%d", &ip2[0], &ip2[1], &ip2[2], &ip2[3]);
4884        sscanf(netmask, "%d.%d.%d.%d", &mask2[0], &mask2[1], &mask2[2], &mask2[3]);
4885        int i = 0;
4886
4887        for (i = 0; i < 4; i++) {
4888                ip[i] = ip2[i];
4889                mask[i] = mask2[i];
4890                // ip[i] = (ip[i] & mask[i]) | !mask[i];
4891                ip[i] = (ip[i] & mask[i]) | (0xff & ~mask[i]);
4892        }
4893
4894        sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
4895#ifdef WDS_DEBUG
4896        fprintf(fp, "get_broadcast return %s\n", value);
4897#endif
4898
4899}
4900
4901char *get_wan_face(void)
4902{
4903        static char localwanface[IFNAMSIZ];
4904        if (nvram_match("wan_proto", "disabled"))
4905                return "br0";
4906
4907        /*
4908         * if (nvram_match ("pptpd_client_enable", "1")) { strncpy (localwanface,
4909         * "ppp0", IFNAMSIZ); return localwanface; }
4910         */
4911        if (nvram_match("wan_proto", "pptp")
4912#ifdef HAVE_L2TP
4913            || nvram_match("wan_proto", "l2tp")
4914#endif
4915#ifdef HAVE_PPPOATM
4916            || nvram_match("wan_proto", "pppoa")
4917#endif
4918#ifdef HAVE_PPPOEDUAL
4919            || nvram_match("wan_proto", "pppoe_dual")
4920#endif
4921            || nvram_match("wan_proto", "pppoe")) {
4922                if (nvram_match("pppd_pppifname", ""))
4923                        strncpy(localwanface, "ppp0", IFNAMSIZ);
4924                else
4925                        strncpy(localwanface, nvram_safe_get("pppd_pppifname"), IFNAMSIZ);
4926        }
4927#ifdef HAVE_3G
4928        else if (nvram_match("wan_proto", "3g")) {
4929                if (nvram_match("3gdata", "qmi")) {
4930                        strncpy(localwanface, "wwan0", IFNAMSIZ);
4931                } else {
4932                        if (nvram_match("pppd_pppifname", ""))
4933                                strncpy(localwanface, "ppp0", IFNAMSIZ);
4934                        else
4935                                strncpy(localwanface, nvram_safe_get("pppd_pppifname"), IFNAMSIZ);
4936                }
4937
4938        }
4939#endif
4940#ifndef HAVE_MADWIFI
4941        else if (getSTA()) {
4942                strcpy(localwanface, getSTA());
4943        }
4944#else
4945        else if (getSTA()) {
4946                if (nvram_matchi("wifi_bonding", 1))
4947                        strcpy(localwanface, "bond0");
4948                else
4949                        strcpy(localwanface, getSTA());
4950        }
4951#endif
4952#ifdef HAVE_IPETH
4953        else if (nvram_match("wan_proto", "iphone")) {
4954                strncpy(localwanface, "iph0", IFNAMSIZ);
4955        }
4956#endif
4957        else
4958                strncpy(localwanface, nvram_safe_get("wan_ifname"), IFNAMSIZ);
4959
4960        return localwanface;
4961}
4962
4963int wanChanged(void)
4964{
4965        FILE *fp = fopen("/tmp/.wanchange", "rb");
4966        if (fp) {
4967                fclose(fp);
4968                unlink("/tmp/.wanchange");
4969                return 1;
4970        }
4971        return 0;
4972}
4973
4974void notifywanChange(void)
4975{
4976        FILE *fp = fopen("/tmp/.wanchange", "wb");
4977        if (fp) {
4978                fputs("change", fp);
4979                fclose(fp);
4980        }
4981}
4982
4983static int _pidof(const char *name, pid_t ** pids)
4984{
4985        const char *p;
4986        char *e;
4987        DIR *dir;
4988        struct dirent *de;
4989        pid_t i;
4990        int count;
4991        char buf[256];
4992
4993        count = 0;
4994        *pids = NULL;
4995        if ((p = strchr(name, '/')) != NULL)
4996                name = p + 1;
4997        if ((dir = opendir("/proc")) != NULL) {
4998                while ((de = readdir(dir)) != NULL) {
4999                        i = strtol(de->d_name, &e, 10);
5000                        if (*e != 0)
5001                                continue;
5002                        if (strcmp(name, psname(i, buf, sizeof(buf))) == 0) {
5003                                if ((*pids = realloc(*pids, sizeof(pid_t) * (count + 1))) == NULL) {
5004                                        return -1;
5005                                }
5006                                (*pids)[count++] = i;
5007                        }
5008                }
5009        }
5010        closedir(dir);
5011        return count;
5012}
5013
5014int pidof(const char *name)
5015{
5016        pid_t *pids;
5017        pid_t p;
5018        if (!name)
5019                return -1;
5020        if (_pidof(name, &pids) > 0) {
5021                p = *pids;
5022                free(pids);
5023                return p;
5024        }
5025        return -1;
5026}
5027
5028int killall(const char *name, int sig)
5029{
5030        pid_t *pids;
5031        int i;
5032        int r;
5033
5034        if ((i = _pidof(name, &pids)) > 0) {
5035                r = 0;
5036                do {
5037                        r |= kill(pids[--i], sig);
5038                }
5039                while (i > 0);
5040                free(pids);
5041                return r;
5042        }
5043        return -2;
5044}
5045
5046void set_ip_forward(char c)
5047{
5048        char ch[8];
5049        sprintf(ch, "%c", c);
5050        writeprocsysnet("ipv4/ip_forward", ch);
5051}
5052
5053int ifexists(const char *ifname)
5054{
5055        return getifcount(ifname) > 0 ? 1 : 0;
5056}
5057
5058int getdevicecount(void)
5059{
5060        int count = 0;
5061#ifdef HAVE_ATH9K
5062        count += getath9kdevicecount();
5063#endif
5064        count += getifcount("wifi");
5065
5066        return count;
5067}
5068
5069int getifcount(const char *ifprefix)
5070{
5071        /*
5072         * char devcall[128];
5073         *
5074         * sprintf (devcall, "cat /proc/net/dev|grep \"%s\"|wc -l", ifprefix);
5075         * FILE *in = popen (devcall, "rb"); if (in == NULL) return 0; int count;
5076         * fscanf (in, "%d", &count); pclose (in); return count;
5077         */
5078        char *iflist = calloc(256, 1);
5079
5080        int c = getIfListB(iflist, ifprefix, 0, 1);
5081
5082        free(iflist);
5083        return c;
5084}
5085
5086static void skipline(FILE * in)
5087{
5088        while (1) {
5089                int c = getc(in);
5090
5091                if (c == EOF)
5092                        return;
5093                if (c == 0x0)
5094                        return;
5095                if (c == 0xa)
5096                        return;
5097        }
5098}
5099
5100/*
5101 * strips trailing char(s) c from string
5102 */
5103void strtrim_right(char *p, int c)
5104{
5105        char *end;
5106        int len;
5107
5108        len = strlen(p);
5109        while (*p && len) {
5110                end = p + len - 1;
5111                if (c == *end)
5112                        *end = 0;
5113                else
5114                        break;
5115                len = strlen(p);
5116        }
5117        return;
5118}
5119
5120int getIfList(char *buffer, const char *ifprefix)
5121{
5122        return getIfListB(buffer, ifprefix, 0, 0);
5123}
5124
5125static int ifcompare(const void *a, const void *b)
5126{
5127        return strcmp(*(const char **)a, *(const char **)b);
5128}
5129
5130// returns a physical interfacelist filtered by ifprefix. if ifprefix is
5131// NULL, all valid interfaces will be returned
5132int getIfListB(char *buffer, const char *ifprefix, int bridgesonly, int nosort)
5133{
5134        FILE *in = fopen("/proc/net/dev", "rb");
5135        char ifname[32];
5136
5137        // skip the first 2 lines
5138        skipline(in);
5139        skipline(in);
5140        int ifcount = 0;
5141        int count = 0;
5142        char **sort = NULL;
5143        while (1) {
5144                int c = getc(in);
5145
5146                if (c == 0 || c == EOF) {
5147                        fclose(in);
5148                        goto sort;
5149                }
5150                if (c == 0x20)
5151                        continue;
5152                if (c == ':' || ifcount == 30) {
5153                        ifname[ifcount++] = 0;
5154                        int skip = 0;
5155                        if (bridgesonly && !isbridge(ifname))
5156                                skip = 1;
5157                        if (ifprefix) {
5158                                if (strncmp(ifname, ifprefix, strlen(ifprefix))) {
5159                                        skip = 1;
5160                                }
5161                        } else {
5162                                if (!strncmp(ifname, "wifi", 4))
5163                                        skip = 1;
5164                                if (!strncmp(ifname, "wlan", 4))
5165                                        skip = 1;
5166                                if (!strncmp(ifname, "ifb", 3))
5167                                        skip = 1;
5168                                if (!strncmp(ifname, "imq", 3))
5169                                        skip = 1;
5170                                if (!strncmp(ifname, "etherip", 7))
5171                                        skip = 1;
5172                                if (!strncmp(ifname, "lo", 2))
5173                                        skip = 1;
5174                                if (!strncmp(ifname, "teql", 4))
5175                                        skip = 1;
5176                                if (!strncmp(ifname, "gre", 3))
5177                                        skip = 1;
5178                                if (!strncmp(ifname, "ppp", 3))
5179                                        skip = 1;
5180                                if (!strncmp(ifname, "tun", 3))
5181                                        skip = 1;
5182                                if (!strncmp(ifname, "tap", 3))
5183                                        skip = 1;
5184                        }
5185                        if (!skip) {
5186                                if (!sort) {
5187                                        sort = malloc(sizeof(char *));
5188                                } else {
5189                                        sort = realloc(sort, sizeof(char *) * (count + 1));
5190                                }
5191                                sort[count] = malloc(strlen(ifname) + 1);
5192                                strcpy(sort[count], ifname);
5193                                count++;
5194                        }
5195                        skip = 0;
5196                        ifcount = 0;
5197                        bzero(ifname, 32);
5198                        skipline(in);
5199                        continue;
5200                }
5201                if (ifcount < 30)
5202                        ifname[ifcount++] = c;
5203        }
5204      sort:;
5205        if (!nosort) {
5206                qsort(sort, count, sizeof(char *), ifcompare);
5207        }
5208        int i;
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                strcpy(buf, "Marvel Armada 385");
5274        }
5275        return buf;
5276#elif HAVE_ALPINE
5277        strcpy(buf, "Annapurna Labs Alpine");
5278        return buf;
5279#elif HAVE_IPQ806X
5280        strcpy(buf, "QCA IPQ806X");
5281        return buf;
5282#elif HAVE_UNIWIP
5283        strcpy(buf, "FreeScale MPC8314");
5284        return buf;
5285#elif HAVE_WDR4900
5286        strcpy(buf, "FreeScale P1014");
5287        return buf;
5288#elif HAVE_RB600
5289        strcpy(buf, "FreeScale MPC8343");
5290        return buf;
5291#elif HAVE_VENTANA
5292        strcpy(buf, "FreeScale i.MX6 Quad/DualLite");
5293        return buf;
5294#elif HAVE_NORTHSTAR
5295        FILE *fp = fopen("/proc/bcm_chipinfo", "rb");
5296        if (!fp) {
5297                strcpy(buf, "Broadcom BCM470X");
5298                return buf;
5299        }
5300        int chipid;
5301        int chiprevision;
5302        int packageoption;
5303        fscanf(fp, "%*s %X\n", &chipid);
5304        fscanf(fp, "%*s %X\n", &chiprevision);
5305        fscanf(fp, "%*s %X\n", &packageoption);
5306        fclose(fp);
5307        if (chipid == 53030 || chipid == 53010 || chipid == 53011 || chipid == 53012 || chipid == 53018 || chipid == 53019) {   // 53030
5308                if (packageoption == 0)
5309                        strcpy(buf, "Broadcom BCM4709");
5310                if (packageoption == 1)
5311                        strcpy(buf, "Broadcom BCM4707");
5312                if (packageoption == 2)
5313                        strcpy(buf, "Broadcom BCM4708");
5314        } else if (chipid == 53573) {
5315                strcpy(buf, "Broadcom BCM47189");
5316        } else
5317                strcpy(buf, "Broadcom BCM470X");
5318
5319        return buf;
5320#else
5321        FILE *fcpu = fopen("/proc/cpuinfo", "r");
5322
5323        if (fcpu == NULL) {
5324                return NULL;
5325        }
5326        int i;
5327
5328#ifdef HAVE_MAGICBOX
5329        int cnt = 0;
5330#endif
5331#ifdef HAVE_X86
5332        int cnt = 0;
5333#endif
5334        for (i = 0; i < 256; i++) {
5335                int c = getc(fcpu);
5336
5337                if (c == EOF) {
5338                        fclose(fcpu);
5339                        return NULL;
5340                }
5341                if (c == ':')
5342#ifdef HAVE_MAGICBOX
5343                        cnt++;
5344                if (cnt == 2)
5345                        break;
5346#elif HAVE_X86
5347                        cnt++;
5348                if (cnt == 5)
5349                        break;
5350#else
5351                        break;
5352#endif
5353        }
5354        getc(fcpu);
5355        for (i = 0; i < 256; i++) {
5356                int c = getc(fcpu);
5357
5358                if (c == EOF) {
5359                        fclose(fcpu);
5360                        return NULL;
5361                }
5362                if (c == 0xa || c == 0xd)
5363                        break;
5364                buf[i] = c;
5365        }
5366        buf[i] = 0;
5367        fclose(fcpu);
5368        return buf;
5369#endif
5370}
5371
5372#if defined(HAVE_MADWIFI_MIMO) || defined(HAVE_ATH9K)
5373
5374int isap8x(void)
5375{
5376#define CPUSTR "Atheros AR91"
5377        char *str = cpustring();
5378        if (str && !strncmp(str, CPUSTR, 12))
5379                return 1;
5380        else
5381                return 0;
5382#undef CPUSTR
5383
5384}
5385
5386#endif
5387
5388int led_control(int type, int act)
5389/*
5390 * type: LED_POWER, LED_DIAG, LED_DMZ, LED_CONNECTED, LED_BRIDGE, LED_VPN,
5391 * LED_SES, LED_SES2, LED_WLAN0, LED_WLAN1, LED_WLAN2, LED_SEC0, LED_SEC1, USB_POWER, USB_POWER1
5392 * act: LED_ON, LED_OFF, LED_FLASH
5393 * 1st hex number: 1 = inverted, 0 = normal
5394 */
5395{
5396#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))
5397        return 0;
5398#else
5399        int use_gpio = 0x0ff;
5400        int gpio_value;
5401        int enable;
5402        int disable;
5403
5404        int power_gpio = 0x0ff;
5405        int beeper_gpio = 0x0ff;
5406        int diag_gpio = 0x0ff;
5407        int diag_gpio_disabled = 0x0ff;
5408        int dmz_gpio = 0x0ff;
5409        int connected_gpio = 0x0ff;
5410        int disconnected_gpio = 0x0ff;
5411        int bridge_gpio = 0x0ff;
5412        int vpn_gpio = 0x0ff;
5413        int ses_gpio = 0x0ff;   // use for SES1 (Linksys), AOSS (Buffalo)
5414        int ses2_gpio = 0x0ff;
5415        int wlan_gpio = 0x0ff;  // wlan button led R7000
5416        int wlan0_gpio = 0x0ff; // use this only if wlan led is not controlled by hardware!
5417        int wlan1_gpio = 0x0ff;
5418        int wlan2_gpio = 0x0ff;
5419        int usb_gpio = 0x0ff;
5420        int usb_gpio1 = 0x0ff;
5421        int sec0_gpio = 0x0ff;  // security leds, wrt600n
5422        int sec1_gpio = 0x0ff;
5423        int usb_power = 0x0ff;
5424        int usb_power1 = 0x0ff;
5425        int v1func = 0;
5426        int connblue = nvram_matchi("connblue", 1) ? 1 : 0;
5427
5428        switch (getRouterBrand())       // gpio definitions here: 0xYZ,
5429                // Y=0:normal, Y=1:inverted, Z:gpio
5430                // number (f=disabled)
5431        {
5432#ifndef HAVE_BUFFALO
5433        case ROUTER_BOARD_TECHNAXX3G:
5434                usb_gpio = 0x109;
5435                diag_gpio = 0x10c;
5436                connected_gpio = 0x10b;
5437                ses_gpio = 0x10c;
5438                break;
5439#ifdef HAVE_WPE72
5440        case ROUTER_BOARD_NS5M:
5441                diag_gpio = 0x10d;
5442                break;
5443#endif
5444        case ROUTER_BOARD_UNIFI:
5445                ses_gpio = 0x001;
5446                sec0_gpio = 0x001;
5447                break;
5448        case ROUTER_UBNT_UAPAC:
5449                ses_gpio = 0x007;
5450                sec0_gpio = 0x007;
5451                break;
5452        case ROUTER_BOARD_AIRROUTER:
5453                power_gpio = 0x10b;
5454                diag_gpio = 0x00b;
5455                connected_gpio = 0x100;
5456                break;
5457        case ROUTER_BOARD_DANUBE:
5458#ifdef HAVE_WMBR_G300NH
5459                diag_gpio = 0x105;
5460                ses_gpio = 0x10e;
5461                sec0_gpio = 0x10e;
5462                connected_gpio = 0x111;
5463                disconnected_gpio = 0x112;
5464                power_gpio = 0x101;
5465#endif
5466#ifdef HAVE_SX763
5467//              diag_gpio = 0x105;
5468//              ses_gpio = 0x10e;
5469//              sec0_gpio = 0x10e;
5470                connected_gpio = 0x1de;
5471//              disconnected_gpio = 0x112;
5472//              power_gpio = 0x101;
5473#endif
5474                break;
5475#ifdef HAVE_UNIWIP
5476        case ROUTER_BOARD_UNIWIP:
5477                break;
5478#endif
5479#ifdef HAVE_WDR4900
5480        case ROUTER_BOARD_WDR4900:
5481                diag_gpio = 0x000;
5482                usb_gpio = 0x001;
5483                usb_gpio1 = 0x002;
5484                usb_power = 0x103;
5485                break;
5486#endif
5487#ifdef HAVE_WRT1900AC
5488        case ROUTER_WRT_1200AC:
5489        case ROUTER_WRT_1900ACS:
5490
5491        case ROUTER_WRT_1900ACV2:
5492                usb_power = 0x032;
5493        case ROUTER_WRT_1900AC:
5494                power_gpio = 0x000;
5495                diag_gpio = 0x100;
5496                connected_gpio = 0x006;
5497                disconnected_gpio = 0x007;
5498//              usb_gpio = 0x004;
5499//              usb_gpio1 = 0x005;
5500                ses_gpio = 0x009;
5501                break;
5502        case ROUTER_WRT_3200ACM:
5503//              usb_power = 0x02f;
5504                power_gpio = 0x000;
5505                diag_gpio = 0x100;
5506                connected_gpio = 0x006;
5507                disconnected_gpio = 0x007;
5508//              usb_gpio = 0x004;
5509//              usb_gpio1 = 0x005;
5510                ses_gpio = 0x009;
5511                break;
5512#endif
5513        case ROUTER_BOARD_PB42:
5514#ifdef HAVE_WA901
5515                diag_gpio = 0x102;
5516                ses_gpio = 0x004;
5517//              usb_gpio = 0x101;
5518#elif  HAVE_WR941
5519                diag_gpio = 0x102;
5520                ses_gpio = 0x005;
5521//              usb_gpio = 0x101;
5522#endif
5523#ifdef HAVE_MR3020
5524                connected_gpio = 0x11b;
5525                diag_gpio = 0x11a;
5526                usb_power = 0x008;
5527#elif HAVE_GL150
5528//              power_gpio = 0x11b;
5529//              diag_gpio = 0x01b;
5530//              usb_power = 0x008;
5531#elif HAVE_WR710
5532                power_gpio = 0x11b;
5533                diag_gpio = 0x01b;
5534#elif HAVE_WA701V2
5535                diag_gpio = 0x11b;
5536                ses_gpio = 0x001;
5537                sec0_gpio = 0x001;
5538#elif HAVE_WR703
5539                diag_gpio = 0x11b;
5540                ses_gpio = 0x001;
5541                sec0_gpio = 0x001;
5542                usb_power = 0x008;
5543#elif HAVE_WR842
5544                diag_gpio = 0x101;
5545                ses_gpio = 0x000;
5546                usb_power = 0x006;
5547
5548#elif HAVE_WR741V4
5549                diag_gpio = 0x11b;
5550                ses_gpio = 0x001;
5551                sec0_gpio = 0x001;
5552
5553#elif HAVE_MR3420
5554                diag_gpio = 0x101;
5555                connected_gpio = 0x108;
5556                usb_power = 0x006;
5557#elif HAVE_WR741
5558                diag_gpio = 0x101;
5559                ses_gpio = 0x000;
5560//              usb_gpio = 0x101;
5561#endif
5562#ifdef HAVE_WR1043
5563                diag_gpio = 0x102;
5564                ses_gpio = 0x005;
5565//              usb_gpio = 0x101;
5566#endif
5567#ifdef HAVE_WRT160NL
5568                power_gpio = 0x10e;
5569                connected_gpio = 0x109;
5570                ses_gpio = 0x108;
5571#endif
5572#ifdef HAVE_TG2521
5573                ses_gpio = 0x103;
5574                diag_gpio = 0x103;
5575                usb_power = 0x105;
5576#endif
5577#ifdef HAVE_TEW632BRP
5578                diag_gpio = 0x101;
5579                ses_gpio = 0x103;
5580#endif
5581#ifdef HAVE_WP543
5582                diag_gpio = 0x107;
5583                connected_gpio = 0x106;
5584#endif
5585#ifdef HAVE_WP546
5586                beeper_gpio = 0x001;
5587                diag_gpio = 0x107;
5588                connected_gpio = 0x106;
5589#endif
5590#ifdef HAVE_DIR825
5591                power_gpio = 0x102;
5592                diag_gpio = 0x101;
5593                connected_gpio = 0x10b;
5594                disconnected_gpio = 0x106;
5595                ses_gpio = 0x104;
5596                usb_gpio = 0x100;
5597//              wlan0_gpio = 0x0ff; //correct states missing
5598#endif
5599#ifdef HAVE_WNDR3700
5600                power_gpio = 0x102;
5601                diag_gpio = 0x101;
5602                connected_gpio = 0x106;
5603                ses_gpio = 0x104;
5604#endif
5605#ifdef HAVE_WZRG300NH
5606                diag_gpio = 0x101;
5607                connected_gpio = 0x112;
5608                ses_gpio = 0x111;
5609                sec0_gpio = 0x111;
5610#endif
5611#ifdef HAVE_DIR632
5612                power_gpio = 0x001;
5613                diag_gpio = 0x100;
5614                connected_gpio = 0x111;
5615                usb_gpio = 0x10b;
5616#endif
5617#ifdef HAVE_WZRG450
5618                diag_gpio = 0x10e;
5619                ses_gpio = 0x10d;
5620                sec0_gpio = 0x10d;
5621                usb_power = 0x010;
5622                connected_gpio = 0x12e; // card 1, gpio 14
5623#endif
5624#ifdef HAVE_WZRG300NH2
5625                diag_gpio = 0x110;
5626                ses_gpio = 0x126;       // card 1, gpio 6
5627                sec0_gpio = 0x126;
5628                usb_power = 0x00d;
5629                connected_gpio = 0x127; // card 1, gpio 7
5630#endif
5631#ifdef HAVE_WZRHPAG300NH
5632                diag_gpio = 0x101;
5633                connected_gpio = 0x133; // card 2 gpio 3
5634                sec0_gpio = 0x125;
5635                sec1_gpio = 0x131;
5636                ses_gpio = 0x125;       // card 1 gpio 5
5637                ses2_gpio = 0x131;      // card 2 gpio 5
5638                usb_power = 0x002;
5639#endif
5640#ifdef HAVE_DIR615C1
5641                power_gpio = 0x104;
5642                wlan0_gpio = 0x10f;
5643#endif
5644#ifdef HAVE_DIR615E
5645                power_gpio = 0x006;
5646                diag_gpio = 0x001;
5647                connected_gpio = 0x111;
5648                disconnected_gpio = 0x007;
5649                ses_gpio = 0x100;
5650#endif
5651#ifdef HAVE_DAP2230
5652                diag_gpio = 0x00b;
5653                power_gpio = 0x10b;
5654#elif HAVE_WR941V6
5655                disconnected_gpio = 0x00f;
5656                power_gpio = 0x112;
5657                diag_gpio = 0x012;
5658
5659#elif HAVE_WR841V12
5660                power_gpio = 0x101;
5661                diag_gpio = 0x001;
5662                ses_gpio = 0x103;
5663                sec0_gpio = 0x103;
5664                connected_gpio = 0x102;
5665#elif HAVE_WR841V11
5666                power_gpio = 0x101;
5667                diag_gpio = 0x001;
5668                ses_gpio = 0x103;
5669                sec0_gpio = 0x103;
5670                connected_gpio = 0x102;
5671#elif HAVE_WR841V9
5672                diag_gpio = 0x103;
5673#elif HAVE_WR842V2
5674                connected_gpio = 0x10e;
5675                usb_power = 0x204;
5676                usb_gpio = 0x10f;
5677#elif HAVE_WR841V8
5678                diag_gpio = 0x10f;
5679                connected_gpio = 0x10e;
5680#elif HAVE_DIR615I
5681                power_gpio = 0x00e;
5682                diag_gpio = 0x10f;
5683                connected_gpio = 0x10c;
5684                disconnected_gpio = 0x016;
5685#endif
5686#ifdef HAVE_WRT400
5687                power_gpio = 0x001;
5688                diag_gpio = 0x105;
5689                ses_gpio = 0x104;
5690                connected_gpio = 0x007;
5691#endif
5692#ifdef HAVE_ALFAAP94
5693                power_gpio = 0x005;
5694#endif
5695                break;
5696        case ROUTER_ALLNET01:
5697                connected_gpio = 0x100;
5698                break;
5699        case ROUTER_BOARD_WP54G:
5700                diag_gpio = 0x102;
5701                connected_gpio = 0x107;
5702                break;
5703        case ROUTER_BOARD_NP28G:
5704                diag_gpio = 0x102;
5705                connected_gpio = 0x106;
5706                break;
5707        case ROUTER_BOARD_GATEWORX_GW2369:
5708                connected_gpio = 0x102;
5709                break;
5710        case ROUTER_BOARD_GW2388:
5711        case ROUTER_BOARD_GW2380:
5712#ifdef HAVE_VENTANA
5713                power_gpio = 0x166;
5714                diag_gpio = 0x06F;
5715                connected_gpio = 0x066;
5716                disconnected_gpio = 0x067;
5717#else
5718                connected_gpio = 0x110; // 16 is mapped to front led
5719#endif
5720                break;
5721        case ROUTER_BOARD_GATEWORX:
5722#ifdef HAVE_WG302V1
5723                diag_gpio = 0x104;
5724                wlan0_gpio = 0x105;
5725#elif HAVE_WG302
5726                diag_gpio = 0x102;
5727                wlan0_gpio = 0x104;
5728#else
5729                if (nvram_match("DD_BOARD", "Gateworks Cambria GW2350")
5730                    || nvram_match("DD_BOARD2", "Gateworks Cambria GW2350"))
5731                        connected_gpio = 0x105;
5732                else if (nvram_match("DD_BOARD", "Gateworks Cambria GW2358-4")
5733                         || nvram_match("DD_BOARD2", "Gateworks Cambria GW2358-4"))
5734                        connected_gpio = 0x118;
5735                else
5736                        connected_gpio = 0x003;
5737#endif
5738                break;
5739        case ROUTER_BOARD_GATEWORX_SWAP:
5740                connected_gpio = 0x004;
5741                break;
5742        case ROUTER_BOARD_STORM:
5743                connected_gpio = 0x005;
5744                diag_gpio = 0x003;
5745                break;
5746        case ROUTER_LINKSYS_WRH54G:
5747                diag_gpio = 0x101;      // power led blink / off to indicate factory
5748                // defaults
5749                break;
5750        case ROUTER_WRT54G:
5751        case ROUTER_WRT54G_V8:
5752                power_gpio = 0x001;
5753                dmz_gpio = 0x107;
5754                connected_gpio = 0x103; // ses orange
5755                ses_gpio = 0x102;       // ses white
5756                ses2_gpio = 0x103;      // ses orange
5757                break;
5758        case ROUTER_WRT54G_V81:
5759                power_gpio = 0x101;
5760                dmz_gpio = 0x102;
5761                connected_gpio = 0x104; // ses orange
5762                ses_gpio = 0x103;       // ses white
5763                ses2_gpio = 0x104;      // ses orange
5764                break;
5765        case ROUTER_WRT54G1X:
5766                connected_gpio = 0x103;
5767                v1func = 1;
5768                break;
5769        case ROUTER_WRT350N:
5770                connected_gpio = 0x103;
5771                power_gpio = 0x001;
5772                ses2_gpio = 0x103;      // ses orange
5773                sec0_gpio = 0x109;
5774                usb_gpio = 0x10b;
5775                break;
5776        case ROUTER_WRT600N:
5777                power_gpio = 0x102;
5778                diag_gpio = 0x002;
5779                usb_gpio = 0x103;
5780                sec0_gpio = 0x109;
5781                sec1_gpio = 0x10b;
5782                break;
5783        case ROUTER_LINKSYS_WRT55AG:
5784                connected_gpio = 0x103;
5785                break;
5786        case ROUTER_DLINK_DIR330:
5787                diag_gpio = 0x106;
5788                connected_gpio = 0x100;
5789                usb_gpio = 0x104;
5790                break;
5791        case ROUTER_ASUS_RTN10PLUS:
5792//              diag_gpio = 0x10d;
5793//              connected_gpio = 0x108;
5794//              power_gpio = 0x109;
5795                break;
5796        case ROUTER_BOARD_DIR600B:
5797                diag_gpio = 0x10d;
5798                connected_gpio = 0x108;
5799                power_gpio = 0x109;
5800                break;
5801        case ROUTER_BOARD_DIR615D:
5802#ifdef HAVE_DIR615H
5803                diag_gpio = 0x007;
5804                connected_gpio = 0x10d;
5805                disconnected_gpio = 0x10c;
5806                ses_gpio = 0x10e;
5807                power_gpio = 0x009;
5808#else
5809                diag_gpio = 0x108;
5810                connected_gpio = 0x10c;
5811                disconnected_gpio = 0x10e;
5812                ses_gpio = 0x10b;
5813                power_gpio = 0x109;
5814#endif
5815                break;
5816                /*
5817                   DIR 882
5818                   power LED red diag = 8 inv, green 16 inv
5819
5820                 */
5821        case ROUTER_BOARD_W502U:
5822                connected_gpio = 0x10d;
5823                break;
5824        case ROUTER_BOARD_OPENRISC:
5825#ifndef HAVE_ERC
5826// ERC: diag button is used different / wlan button is handled by a script
5827                diag_gpio = 0x003;
5828                ses_gpio = 0x005;
5829#endif
5830                break;
5831        case ROUTER_BOARD_WR5422:
5832                ses_gpio = 0x10d;
5833                break;
5834        case ROUTER_BOARD_F5D8235:
5835                usb_gpio = 0x117;
5836                diag_gpio = 0x109;
5837                disconnected_gpio = 0x106;
5838                connected_gpio = 0x105;
5839                ses_gpio = 0x10c;
5840                break;
5841#else
5842        case ROUTER_BOARD_DANUBE:
5843#ifdef HAVE_WMBR_G300NH
5844                diag_gpio = 0x105;
5845                ses_gpio = 0x10e;
5846                sec0_gpio = 0x10e;
5847                connected_gpio = 0x111;
5848                disconnected_gpio = 0x112;
5849                power_gpio = 0x101;
5850#endif
5851                break;
5852        case ROUTER_BOARD_PB42:
5853#ifdef HAVE_WZRG300NH
5854                diag_gpio = 0x101;
5855                connected_gpio = 0x112;
5856                ses_gpio = 0x111;
5857                sec0_gpio = 0x111;
5858#endif
5859#ifdef HAVE_WZRHPAG300NH
5860                diag_gpio = 0x101;
5861                connected_gpio = 0x133;
5862                ses_gpio = 0x125;
5863                ses2_gpio = 0x131;
5864                sec0_gpio = 0x125;
5865                sec1_gpio = 0x131;
5866                usb_power = 0x002;
5867#endif
5868#ifdef HAVE_WZRG450
5869                diag_gpio = 0x10e;
5870                ses_gpio = 0x10d;
5871                sec0_gpio = 0x10d;
5872                usb_power = 0x010;
5873                connected_gpio = 0x12e; // card 1, gpio 14
5874#endif
5875#ifdef HAVE_WZRG300NH2
5876                diag_gpio = 0x110;
5877                ses_gpio = 0x126;
5878                sec0_gpio = 0x126;
5879                usb_power = 0x00d;
5880                connected_gpio = 0x127;
5881#endif
5882                break;
5883#endif
5884        case ROUTER_BOARD_HAMEA15:
5885                diag_gpio = 0x111;
5886                connected_gpio = 0x114;
5887//              ses_gpio = 0x10e;
5888                break;
5889        case ROUTER_BOARD_WCRGN:
5890                diag_gpio = 0x107;
5891                connected_gpio = 0x10b;
5892//              ses_gpio = 0x10e;
5893                break;
5894        case ROUTER_DIR882:
5895                diag_gpio = 0x108;
5896                power_gpio = 0x110;
5897                break;
5898        case ROUTER_DIR860LB1:
5899                power_gpio = 0x10f;
5900                diag_gpio = 0x10d;
5901                diag_gpio_disabled = 0x10f;
5902                disconnected_gpio = 0x10e;
5903                connected_gpio = 0x110;
5904                break;
5905        case ROUTER_DIR810L:
5906                power_gpio = 0x009;
5907                diag_gpio = 0x00d;
5908                diag_gpio_disabled = 0x009;
5909                connected_gpio = 0x128;
5910                disconnected_gpio = 0x00c;
5911                break;
5912        case ROUTER_WHR300HP2:
5913                power_gpio = 0x109;
5914                diag_gpio = 0x107;
5915                diag_gpio_disabled = 0x109;
5916                wlan0_gpio = 0x108;
5917                sec0_gpio = 0x10a;
5918                ses_gpio = 0x10a;
5919                connected_gpio = 0x139;
5920                disconnected_gpio = 0x13b;
5921                break;
5922        case ROUTER_BOARD_WHRG300N:
5923                diag_gpio = 0x107;
5924                connected_gpio = 0x109;
5925                ses_gpio = 0x10e;
5926                break;
5927#ifdef HAVE_WNR2200
5928        case ROUTER_BOARD_WHRHPGN:
5929                power_gpio = 0x122;
5930                diag_gpio = 0x121;
5931                connected_gpio = 0x107;
5932                usb_power = 0x024;      // enable usb port
5933                ses_gpio = 0x105;       //correct state missing
5934                usb_gpio = 0x108;
5935//              sec0_gpio = 0x104;
5936                break;
5937#elif HAVE_WNR2000
5938        case ROUTER_BOARD_WHRHPGN:
5939                power_gpio = 0x123;
5940                diag_gpio = 0x122;
5941                connected_gpio = 0x100;
5942//              ses_gpio = 0x104;
5943//              sec0_gpio = 0x104;
5944                break;
5945#elif HAVE_WLAEAG300N
5946        case ROUTER_BOARD_WHRHPGN:
5947                power_gpio = 0x110;
5948                diag_gpio = 0x111;
5949                connected_gpio = 0x106;
5950                ses_gpio = 0x10e;
5951                sec0_gpio = 0x10e;
5952                break;
5953#elif HAVE_CARAMBOLA
5954#ifdef HAVE_ERC
5955        case ROUTER_BOARD_WHRHPGN:
5956                vpn_gpio = 0x11B;
5957                wlan0_gpio = 0x000;
5958                break;
5959#else
5960        case ROUTER_BOARD_WHRHPGN:
5961//              usb_power = 0x01a;
5962//              usb_gpio = 0x001;
5963//              ses_gpio = 0x11b;
5964                break;
5965#endif
5966#elif HAVE_HORNET
5967        case ROUTER_BOARD_WHRHPGN:
5968                usb_power = 0x01a;
5969                usb_gpio = 0x001;
5970                ses_gpio = 0x11b;
5971                break;
5972#elif HAVE_RB2011
5973        case ROUTER_BOARD_WHRHPGN:
5974//              diag_gpio = 0x10f;
5975//              connected_gpio = 0x112;
5976//              disconnected_gpio = 0x113;
5977//              power_gpio = 0x10e;
5978//              usb_power = 0x01a;
5979//              usb_gpio = 0x10b;
5980//              ses_gpio = 0x11b;
5981                break;
5982#elif HAVE_WDR3500
5983        case ROUTER_BOARD_WHRHPGN:
5984                usb_gpio = 0x10b;
5985                usb_power = 0x00f;
5986                diag_gpio = 0x10e;
5987                connected_gpio = 0x10f;
5988                break;
5989#elif HAVE_WDR4300
5990        case ROUTER_BOARD_WHRHPGN:
5991                usb_gpio = 0x10b;
5992                usb_gpio1 = 0x10c;
5993                usb_power = 0x015;
5994                usb_power1 = 0x016;
5995                diag_gpio = 0x10e;
5996                connected_gpio = 0x10f;
5997                break;
5998#elif HAVE_WNDR3700V4
5999        case ROUTER_BOARD_WHRHPGN:
6000                diag_gpio = 0x102;
6001                power_gpio = 0x100;
6002                connected_gpio = 0x101;
6003                disconnected_gpio = 0x103;
6004                usb_power = 0x020;
6005                usb_gpio = 0x10d;
6006                ses_gpio = 0x110;
6007                break;
6008#elif HAVE_DAP3662
6009        case ROUTER_BOARD_WHRHPGN:
6010                diag_gpio = 0x10e;      // red
6011                diag_gpio_disabled = 0x117;     //
6012                power_gpio = 0x117;     // green
6013                break;
6014#elif HAVE_DIR862
6015        case ROUTER_BOARD_WHRHPGN:
6016                diag_gpio = 0x10e;      // orange
6017                diag_gpio_disabled = 0x113;     //
6018                power_gpio = 0x113;     // green
6019                connected_gpio = 0x116; // green
6020                disconnected_gpio = 0x117;      // orange
6021                break;
6022#elif HAVE_MMS344
6023        case ROUTER_BOARD_WHRHPGN:
6024                diag_gpio = 0x10e;
6025                break;
6026#elif HAVE_ARCHERC7
6027        case ROUTER_BOARD_WHRHPGN:
6028                diag_gpio = 0x10e;
6029                ses_gpio = 0x10f;
6030                sec0_gpio = 0x10f;
6031
6032                usb_power = 0x016;
6033                usb_gpio = 0x112;
6034
6035                usb_power1 = 0x015;
6036                usb_gpio1 = 0x113;
6037
6038                usb_gpio = 0x10f;
6039                break;
6040#elif HAVE_WR1043V2
6041        case ROUTER_BOARD_WHRHPGN:
6042                diag_gpio = 0x113;
6043//              connected_gpio = 0x112;
6044//              disconnected_gpio = 0x113;
6045//              power_gpio = 0x10e;
6046                usb_power = 0x015;
6047                usb_gpio = 0x10f;
6048                ses_gpio = 0x112;
6049                sec0_gpio = 0x112;
6050                break;
6051#elif HAVE_WZR450HP2
6052        case ROUTER_BOARD_WHRHPGN:
6053                diag_gpio = 0x114;
6054//              connected_gpio = 0x112;
6055//              disconnected_gpio = 0x113;
6056//              power_gpio = 0x10e;
6057//              usb_power = 0x01a;
6058//              usb_gpio = 0x10b;
6059
6060                connected_gpio = 0x10d;
6061                power_gpio = 0x113;
6062                ses_gpio = 0x103;
6063                sec0_gpio = 0x103;
6064                break;
6065#elif HAVE_DHP1565
6066        case ROUTER_BOARD_WHRHPGN:
6067                diag_gpio = 0x10e;
6068                diag_gpio_disabled = 0x116;
6069                connected_gpio = 0x112;
6070                disconnected_gpio = 0x113;
6071                power_gpio = 0x116;
6072                usb_gpio = 0x10b;
6073                ses_gpio = 0x10f;
6074                break;
6075#elif HAVE_E325N
6076        case ROUTER_BOARD_WHRHPGN:
6077                connected_gpio = 0x003;
6078                disconnected_gpio = 0x002;
6079                break;
6080#elif HAVE_XD3200
6081        case ROUTER_BOARD_WHRHPGN:
6082                break;
6083#elif HAVE_E380AC
6084        case ROUTER_BOARD_WHRHPGN:
6085                diag_gpio = 0x003;
6086                break;
6087#elif HAVE_WR615N
6088        case ROUTER_BOARD_WHRHPGN:
6089                diag_gpio = 0x101;
6090                connected_gpio = 0x102;
6091                disconnected_gpio = 0x103;
6092                ses_gpio = 0x10c;
6093                sec0_gpio = 0x10c;
6094                break;
6095#elif HAVE_E355AC
6096        case ROUTER_BOARD_WHRHPGN:
6097                diag_gpio = 0x002;
6098                break;
6099#elif HAVE_WR650AC
6100        case ROUTER_BOARD_WHRHPGN:
6101                ses_gpio = 0x114;
6102                sec0_gpio = 0x114;
6103                connected_gpio = 0x104;
6104                diag_gpio = 0x004;
6105                break;
6106#elif HAVE_DIR869
6107        case ROUTER_BOARD_WHRHPGN:
6108                disconnected_gpio = 0x10f;
6109                connected_gpio = 0x110;
6110                diag_gpio = 0x00f;
6111                break;
6112#elif HAVE_DIR859
6113        case ROUTER_BOARD_WHRHPGN:
6114                power_gpio = 0x10f;
6115                connected_gpio = 0x110;
6116                diag_gpio = 0x00f;
6117                break;
6118#elif HAVE_JWAP606
6119        case ROUTER_BOARD_WHRHPGN:
6120                diag_gpio = 0x10b;
6121                connected_gpio = 0x10d;
6122                disconnected_gpio = 0x10d;
6123                power_gpio = 0x10b;
6124//              usb_power = 0x01a;
6125//              usb_gpio = 0x10b;
6126//              ses_gpio = 0x11b;
6127                break;
6128#elif HAVE_DIR825C1
6129        case ROUTER_BOARD_WHRHPGN:
6130                diag_gpio = 0x10f;
6131                connected_gpio = 0x112;
6132                disconnected_gpio = 0x113;
6133                power_gpio = 0x10e;
6134//              usb_power = 0x01a;
6135                usb_gpio = 0x10b;
6136//              ses_gpio = 0x11b;
6137                break;
6138#elif HAVE_WDR2543
6139        case ROUTER_BOARD_WHRHPGN:
6140                diag_gpio = 0x100;
6141                usb_gpio = 0x108;
6142                break;
6143#elif HAVE_WASP
6144        case ROUTER_BOARD_WHRHPGN:
6145//              usb_power = 0x01a;
6146//              usb_gpio = 0x001;
6147//              ses_gpio = 0x11b;
6148                break;
6149#else
6150        case ROUTER_BOARD_WHRHPGN:
6151                diag_gpio = 0x101;
6152                connected_gpio = 0x106;
6153                ses_gpio = 0x100;
6154                sec0_gpio = 0x100;
6155                break;
6156#endif
6157        case ROUTER_BUFFALO_WBR54G:
6158                diag_gpio = 0x107;
6159                break;
6160        case ROUTER_BUFFALO_WBR2G54S:
6161                diag_gpio = 0x001;
6162                ses_gpio = 0x006;
6163                break;
6164        case ROUTER_BUFFALO_WLA2G54C:
6165                diag_gpio = 0x104;
6166                ses_gpio = 0x103;
6167                break;
6168        case ROUTER_BUFFALO_WLAH_G54:
6169                diag_gpio = 0x107;
6170                ses_gpio = 0x106;
6171                break;
6172        case ROUTER_BUFFALO_WAPM_HP_AM54G54:
6173                diag_gpio = 0x107;
6174                ses_gpio = 0x101;
6175                break;
6176        case ROUTER_BOARD_WHRAG108:
6177                diag_gpio = 0x107;
6178                bridge_gpio = 0x104;
6179                ses_gpio = 0x100;
6180                break;
6181        case ROUTER_BUFFALO_WHRG54S:
6182        case ROUTER_BUFFALO_WLI_TX4_G54HP:
6183                diag_gpio = 0x107;
6184                if (nvram_match("DD_BOARD", "Buffalo WHR-G125")) {
6185                        connected_gpio = 0x101;
6186                        sec0_gpio = 0x106;
6187                } else {
6188                        bridge_gpio = 0x101;
6189                        ses_gpio = 0x106;
6190                }
6191                break;
6192        case ROUTER_UBNT_UNIFIAC:
6193                power_gpio = 0x00e;
6194                diag_gpio = 0x00f;
6195                break;
6196        case ROUTER_D1800H:
6197                usb_gpio = 0x101;
6198                usb_power = 0x007;
6199                power_gpio = 0x002;
6200                diag_gpio = 0x00d;
6201                diag_gpio_disabled = 0x002;
6202                connected_gpio = 0x10f;
6203                disconnected_gpio = 0x10e;
6204                break;
6205        case ROUTER_BUFFALO_WZRRSG54:
6206                diag_gpio = 0x107;
6207                vpn_gpio = 0x101;
6208                ses_gpio = 0x106;
6209                break;
6210        case ROUTER_BUFFALO_WZRG300N:
6211                diag_gpio = 0x107;
6212                bridge_gpio = 0x101;
6213                break;
6214        case ROUTER_BUFFALO_WZRG144NH:
6215                diag_gpio = 0x103;
6216                bridge_gpio = 0x101;
6217                ses_gpio = 0x102;
6218                break;
6219        case ROUTER_BUFFALO_WZR900DHP:
6220        case ROUTER_BUFFALO_WZR600DHP2:
6221//              usb_power = 0x009;      // USB 2.0 ehci port
6222                usb_power1 = 0x10a;     // USB 3.0 xhci port
6223//              wlan0_gpio = 0x028; // wireless orange
6224//              wlan1_gpio = 0x029; // wireless blue
6225                connected_gpio = 0x02a; // connected blue
6226                sec0_gpio = 0x02b;
6227                sec1_gpio = 0x02c;
6228                // 0x2b strange led orange
6229                // 0x2c strange led blue
6230                power_gpio = 0x02e;
6231                diag_gpio = 0x02d;
6232                diag_gpio_disabled = 0x02e;
6233                usb_gpio = 0x02f;
6234                break;
6235
6236        case ROUTER_BUFFALO_WXR1900DHP:
6237                usb_power = 0x00d;      // USB 2.0 ehci port
6238                usb_power1 = 0x00e;     // USB 3.0 xhci port
6239//              wlan0_gpio = 0x028; // wireless orange
6240//              wlan1_gpio = 0x029; // wireless blue
6241                connected_gpio = 0x009; // connected blue
6242                disconnected_gpio = 0x00a;      // connected blue
6243                sec0_gpio = 0x00b;
6244                sec1_gpio = 0x00b;
6245                // 0x2b strange led orange
6246                // 0x2c strange led blue
6247                power_gpio = 0x006;
6248                diag_gpio = 0x005;
6249                diag_gpio_disabled = 0x006;
6250                break;
6251
6252        case ROUTER_BUFFALO_WZR1750:
6253                usb_power = 0x009;      // USB 2.0 ehci port
6254                usb_power1 = 0x10a;     // USB 3.0 xhci port
6255//              wlan0_gpio = 0x028; // wireless orange
6256//              wlan1_gpio = 0x029; // wireless blue
6257                connected_gpio = 0x02a; // connected blue
6258                sec0_gpio = 0x02b;
6259                sec1_gpio = 0x02c;
6260                // 0x2b strange led orange
6261                // 0x2c strange led blue
6262                power_gpio = 0x02d;
6263                diag_gpio = 0x02e;
6264                diag_gpio_disabled = 0x02d;
6265                usb_gpio = 0x02f;
6266                break;
6267#ifndef HAVE_BUFFALO
6268#ifdef HAVE_DIR300
6269        case ROUTER_BOARD_FONERA:
6270                diag_gpio = 0x003;
6271                bridge_gpio = 0x004;
6272                ses_gpio = 0x001;
6273                break;
6274#endif
6275#ifdef HAVE_WRT54G2
6276        case ROUTER_BOARD_FONERA:
6277                bridge_gpio = 0x004;
6278                ses_gpio = 0x104;
6279                diag_gpio = 0x103;
6280                break;
6281#endif
6282#ifdef HAVE_RTG32
6283        case ROUTER_BOARD_FONERA:
6284                break;
6285#endif
6286#ifdef HAVE_BWRG1000
6287        case ROUTER_BOARD_LS2:
6288                diag_gpio = 0x007;
6289                break;
6290#endif
6291#ifdef HAVE_DIR400
6292        case ROUTER_BOARD_FONERA2200:
6293                diag_gpio = 0x003;
6294                bridge_gpio = 0x004;
6295                ses_gpio = 0x001;
6296                break;
6297#endif
6298#ifdef HAVE_WRK54G
6299        case ROUTER_BOARD_FONERA:
6300                diag_gpio = 0x107;
6301                dmz_gpio = 0x005;
6302                break;
6303#endif
6304        case ROUTER_BOARD_TW6600:
6305                diag_gpio = 0x107;
6306                bridge_gpio = 0x104;
6307                ses_gpio = 0x100;
6308                break;
6309        case ROUTER_MOTOROLA:
6310                power_gpio = 0x001;
6311                diag_gpio = 0x101;      // power led blink / off to indicate factory
6312                // defaults
6313                break;
6314        case ROUTER_RT210W:
6315                power_gpio = 0x105;
6316                diag_gpio = 0x005;      // power led blink / off to indicate factory
6317                // defaults
6318                connected_gpio = 0x100;
6319                wlan0_gpio = 0x103;
6320                break;
6321        case ROUTER_RT480W:
6322        case ROUTER_BELKIN_F5D7230_V2000:
6323        case ROUTER_BELKIN_F5D7231:
6324                power_gpio = 0x105;
6325                diag_gpio = 0x005;      // power led blink / off to indicate factory
6326                // defaults
6327                connected_gpio = 0x100;
6328                break;
6329        case ROUTER_MICROSOFT_MN700:
6330                power_gpio = 0x006;
6331                diag_gpio = 0x106;      // power led blink / off to indicate factory
6332                // defaults
6333                break;
6334        case ROUTER_ASUS_WL500GD:
6335        case ROUTER_ASUS_WL520GUGC:
6336                diag_gpio = 0x000;      // power led blink / off to indicate factory
6337                // defaults
6338                break;
6339        case ROUTER_ASUS_WL500G_PRE:
6340        case ROUTER_ASUS_WL700GE:
6341                power_gpio = 0x101;
6342                diag_gpio = 0x001;      // power led blink / off to indicate factory
6343                // defaults
6344                break;
6345        case ROUTER_ASUS_WL550GE:
6346                power_gpio = 0x102;
6347                diag_gpio = 0x002;      // power led blink / off to indicate factory
6348                // defaults
6349                break;
6350        case ROUTER_WRT54G3G:
6351        case ROUTER_WRTSL54GS:
6352                power_gpio = 0x001;
6353                dmz_gpio = 0x100;
6354                connected_gpio = 0x107; // ses orange
6355                ses_gpio = 0x105;       // ses white
6356                ses2_gpio = 0x107;      // ses orange
6357                break;
6358        case ROUTER_MOTOROLA_WE800G:
6359        case ROUTER_MOTOROLA_V1:
6360                diag_gpio = 0x103;
6361                wlan0_gpio = 0x101;
6362                bridge_gpio = 0x105;
6363                break;
6364        case ROUTER_DELL_TRUEMOBILE_2300:
6365        case ROUTER_DELL_TRUEMOBILE_2300_V2:
6366                power_gpio = 0x107;
6367                diag_gpio = 0x007;      // power led blink / off to indicate factory
6368                // defaults
6369                wlan0_gpio = 0x106;
6370                break;
6371        case ROUTER_NETGEAR_WNR834B:
6372                power_gpio = 0x104;
6373                diag_gpio = 0x105;
6374                wlan0_gpio = 0x106;
6375                break;
6376        case ROUTER_SITECOM_WL105B:
6377                power_gpio = 0x003;
6378                diag_gpio = 0x103;      // power led blink / off to indicate factory
6379                // defaults
6380                wlan0_gpio = 0x104;
6381                break;
6382        case ROUTER_WRT300N:
6383                power_gpio = 0x001;
6384                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6385                break;
6386        case ROUTER_WRT150N:
6387                power_gpio = 0x001;
6388                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6389                sec0_gpio = 0x105;
6390                break;
6391        case ROUTER_WRT300NV11:
6392                ses_gpio = 0x105;
6393                sec0_gpio = 0x103;
6394                // diag_gpio = 0x11; //power led blink / off to indicate fac.def.
6395                break;
6396        case ROUTER_WRT310N:
6397                connected_gpio = 0x103; //ses orange
6398                power_gpio = 0x001;
6399                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6400                ses_gpio = 0x109;       // ses blue
6401                break;
6402        case ROUTER_WRT310NV2:
6403                connected_gpio = 0x102; // ses orange
6404                power_gpio = 0x001;
6405                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6406                ses_gpio = 0x104;       // ses blue
6407                break;
6408        case ROUTER_WRT160N:
6409                power_gpio = 0x001;
6410                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6411                connected_gpio = 0x103; // ses orange
6412                ses_gpio = 0x105;       // ses blue
6413                break;
6414        case ROUTER_WRT160NV3:
6415                power_gpio = 0x001;
6416                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6417                connected_gpio = 0x102; // ses orange
6418                ses_gpio = 0x104;       // ses blue
6419                break;
6420        case ROUTER_LINKSYS_E800:
6421        case ROUTER_LINKSYS_E900:
6422        case ROUTER_LINKSYS_E1500:
6423        case ROUTER_LINKSYS_E1550:
6424                power_gpio = 0x106;
6425                diag_gpio = 0x006;      // power led blink / off to indicate fac.def.
6426                ses_gpio = 0x108;       // ses blue
6427                break;
6428        case ROUTER_LINKSYS_E1000V2:
6429                power_gpio = 0x106;
6430                diag_gpio = 0x006;      // power led blink / off to indicate fac.def.
6431                connected_gpio = 0x007; // ses orange
6432                ses_gpio = 0x008;       // ses blue
6433                break;
6434        case ROUTER_LINKSYS_E2500:
6435                power_gpio = 0x106;
6436                diag_gpio = 0x006;      // power led blink / off to indicate fac.def.
6437                break;
6438        case ROUTER_LINKSYS_E3200:
6439                power_gpio = 0x103;
6440                diag_gpio = 0x003;      // power led blink / off to indicate fac.def.
6441                break;
6442        case ROUTER_LINKSYS_E4200:
6443                power_gpio = 0x105;     // white LED1
6444                diag_gpio = 0x103;      // power led blink / off to indicate fac.def.
6445//              connected_gpio = 0x103; // white LED2
6446                break;
6447        case ROUTER_LINKSYS_EA6500:
6448                diag_gpio = 0x101;      // white led blink / off to indicate fac.def.
6449                break;
6450        case ROUTER_LINKSYS_EA6500V2:
6451        case ROUTER_LINKSYS_EA6700:
6452        case ROUTER_LINKSYS_EA6400:
6453        case ROUTER_LINKSYS_EA6350:
6454        case ROUTER_LINKSYS_EA6900:
6455                usb_power = 0x009;      //usb power on/off
6456                usb_power1 = 0x00a;     //usb power on/off
6457                diag_gpio = 0x106;      // white led blink / off to indicate fac.def.
6458                connected_gpio = 0x008;
6459                break;
6460        case ROUTER_LINKSYS_EA8500:
6461                power_gpio = 0x100;     // power led
6462                diag_gpio = 0x000;      // power led orange     
6463                wlan0_gpio = 0x001;     // radio 0 
6464                ses_gpio = 0x102;       // wps led
6465                break;
6466        case ROUTER_ASUS_WL500G:
6467                power_gpio = 0x100;
6468                diag_gpio = 0x000;      // power led blink /off to indicate factory
6469                // defaults
6470                break;
6471        case ROUTER_ASUS_WL500W:
6472                power_gpio = 0x105;
6473                diag_gpio = 0x005;      // power led blink /off to indicate factory
6474                // defaults
6475                break;
6476        case ROUTER_LINKSYS_WTR54GS:
6477                diag_gpio = 0x001;
6478                break;
6479        case ROUTER_WAP54G_V1:
6480                diag_gpio = 0x103;
6481                wlan0_gpio = 0x104;     // LINK led
6482                break;
6483        case ROUTER_WAP54G_V3:
6484                ses_gpio = 0x10c;
6485                connected_gpio = 0x006;
6486                break;
6487        case ROUTER_NETGEAR_WNR834BV2:
6488                power_gpio = 0x002;
6489                diag_gpio = 0x003;      // power led amber
6490                connected_gpio = 0x007; // WAN led green
6491                break;
6492        case ROUTER_NETGEAR_WNDR3300:
6493                power_gpio = 0x005;
6494                diag_gpio = 0x105;      // power led blink /off to indicate factory defaults
6495                connected_gpio = 0x007; // WAN led green
6496                break;
6497        case ROUTER_ASKEY_RT220XD:
6498                wlan0_gpio = 0x100;
6499                dmz_gpio = 0x101;       // not soldered
6500                break;
6501        case ROUTER_WRT610N:
6502                power_gpio = 0x001;
6503                diag_gpio = 0x101;      // power led blink /off to indicate factory defaults
6504                connected_gpio = 0x103; // ses amber
6505                ses_gpio = 0x109;       // ses blue
6506                usb_gpio = 0x100;
6507                break;
6508        case ROUTER_WRT610NV2:
6509                power_gpio = 0x005;
6510                diag_gpio = 0x105;      // power led blink
6511                connected_gpio = 0x100; // ses amber
6512                ses_gpio = 0x103;       // ses blue
6513                usb_gpio = 0x007;
6514                break;
6515        case ROUTER_USR_5461:
6516                usb_gpio = 0x001;
6517                break;
6518        case ROUTER_USR_5465:
6519                //usb_gpio = 0x002; //or 0x001 ??
6520                break;
6521        case ROUTER_NETGEAR_WGR614L:
6522        case ROUTER_NETGEAR_WGR614V9:
6523                // power_gpio = 0x107;       // don't use - resets router
6524                diag_gpio = 0x006;
6525                connected_gpio = 0x104;
6526                break;
6527        case ROUTER_NETGEAR_WG602_V4:
6528                power_gpio = 0x101;     // trick: make lan led green for 100Mbps
6529                break;
6530        case ROUTER_BELKIN_F5D7231_V2000:
6531                connected_gpio = 0x104;
6532                diag_gpio = 0x001;      // power led blink /off to indicate factory defaults
6533                break;
6534        case ROUTER_NETGEAR_WNR3500L:
6535        case ROUTER_NETGEAR_WNR3500LV2:
6536                power_gpio = 0x003;     // power led green
6537                diag_gpio = 0x007;      // power led amber
6538                ses_gpio = 0x001;       // WPS led green
6539                connected_gpio = 0x002; // wan led green
6540                wlan1_gpio = 0x000;     // radio 1 blue led
6541                usb_gpio = 0x014;       // usb power
6542                break;
6543        case ROUTER_NETGEAR_WNDR3400:
6544                power_gpio = 0x003;     //power led green
6545                diag_gpio = 0x007;      // power led amber
6546                connected_gpio = 0x001; //wan led green
6547                usb_gpio = 0x102;       //usb led green
6548                wlan1_gpio = 0x000;     // radio 1 led blue
6549                break;
6550        case ROUTER_NETGEAR_WNDR4000:
6551                power_gpio = 0x000;     //power led green
6552                diag_gpio = 0x001;      // power led amber
6553                connected_gpio = 0x002; //wan led green
6554                wlan0_gpio = 0x003;     //radio 0 led green
6555                wlan1_gpio = 0x004;     // radio 1 led blue
6556                usb_gpio = 0x005;       //usb led green
6557                ses_gpio = 0x106;       // WPS led green - inverse
6558                ses2_gpio = 0x107;      // WLAN led green - inverse
6559                break;
6560        case ROUTER_DLINK_DIR860:
6561                usb_power = 0x00a;
6562                connected_gpio = 0x104;
6563                disconnected_gpio = 0x103;
6564                power_gpio = 0x101;
6565                diag_gpio = 0x100;
6566                diag_gpio_disabled = 0x101;
6567                break;
6568        case ROUTER_DLINK_DIR868:
6569        case ROUTER_DLINK_DIR868C:
6570                usb_power = 0x00a;
6571                connected_gpio = 0x103;
6572                disconnected_gpio = 0x101;
6573                power_gpio = 0x102;
6574                diag_gpio = 0x100;
6575                break;
6576
6577        case ROUTER_DLINK_DIR880:
6578                connected_gpio = 0x103;
6579                disconnected_gpio = 0x101;
6580                power_gpio = 0x102;
6581                diag_gpio = 0x100;
6582                diag_gpio_disabled = 0x102;
6583                usb_gpio = 0x108;
6584                usb_gpio1 = 0x10f;
6585//              wlan0_gpio = 0x10d;
6586//              wlan1_gpio = 0x10e;
6587                usb_power = 0x009;
6588                usb_power1 = 0x00a;
6589                break;
6590        case ROUTER_DLINK_DIR885:
6591                usb_power = 0x012;
6592                usb_gpio = 0x108;
6593                power_gpio = 0x100;
6594                diag_gpio = 0x102;
6595                diag_gpio_disabled = 0x100;
6596                disconnected_gpio = 0x103;
6597                connected_gpio = 0x101;
6598                wlan0_gpio = 0x10d;
6599                wlan1_gpio = 0x10e;
6600                break;
6601        case ROUTER_DLINK_DIR895:
6602                usb_power = 0x015;
6603                usb_power1 = 0x012;
6604                usb_gpio = 0x108;
6605                usb_gpio1 = 0x10f;
6606                power_gpio = 0x100;
6607                diag_gpio = 0x102;
6608                diag_gpio_disabled = 0x100;
6609                disconnected_gpio = 0x103;
6610                connected_gpio = 0x101;
6611                wlan0_gpio = 0x10d;
6612                wlan1_gpio = 0x10e;
6613                break;
6614        case ROUTER_DLINK_DIR890:
6615                usb_power = 0x015;
6616                usb_power1 = 0x012;
6617                usb_gpio = 0x108;
6618                usb_gpio1 = 0x10f;
6619                connected_gpio = 0x101;
6620                disconnected_gpio = 0x103;
6621                power_gpio = 0x102;
6622                diag_gpio = 0x002;
6623                break;
6624        case ROUTER_TRENDNET_TEW828:
6625                usb_gpio = 0x104;
6626                power_gpio = 0x106;
6627                diag_gpio = 0x006;
6628                break;
6629        case ROUTER_TRENDNET_TEW812:
6630                // gpio !1 = 2.4 ghz led
6631                // gpio !2 = 5 ghz led
6632                // gpio !3 = power somthing
6633                // gpio !8 = usb led
6634                //
6635                usb_gpio = 0x108;
6636                diag_gpio = 0x103;
6637                wlan0_gpio = 0x101;
6638                wlan1_gpio = 0x102;
6639                break;
6640        case ROUTER_ASUS_RTN18U:
6641                power_gpio = 0x100;
6642//              usb_power = 0x00d;      //usb power on/off
6643                if (nvram_match("bl_version", "3.0.0.7")) {
6644                        usb_gpio = 0x10e;
6645                        connected_gpio = 0x103;
6646                        disconnected_gpio = 0x106;
6647                } else if (nvram_match("bl_version", "1.0.0.0")) {
6648                        usb_gpio = 0x103;
6649                        connected_gpio = 0x106;
6650                        disconnected_gpio = 0x109;
6651                } else {
6652                        usb_gpio = 0x103;
6653                        usb_gpio1 = 0x10e;
6654                        connected_gpio = 0x106;
6655                        disconnected_gpio = 0x109;
6656                }
6657                break;
6658        case ROUTER_TPLINK_ARCHERC9:
6659                ses_gpio = 0x002;
6660                usb_gpio = 0x006;
6661                usb_gpio1 = 0x007;
6662                disconnected_gpio = 0x00f;
6663                connected_gpio = 0x00e;
6664                power_gpio = 0x112;
6665                diag_gpio = 0x012;
6666                usb_power = 0x00c;      // usb 3
6667                usb_power1 = 0x00d;     // usb 2
6668                break;
6669        case ROUTER_TPLINK_ARCHERC3150:
6670                ses_gpio = 0x002;
6671//              usb_gpio = 0x006;
6672//              usb_gpio1 = 0x007;
6673//              disconnected_gpio = 0x00f;
6674//              connected_gpio = 0x00e;
6675//              power_gpio = 0x112;
6676//              diag_gpio = 0x012;
6677                usb_power = 0x00c;      // usb 3
6678                usb_power1 = 0x00d;     // usb 2
6679                break;
6680        case ROUTER_ASUS_AC67U:
6681        case ROUTER_ASUS_AC56U:
6682                wlan1_gpio = 0x106;
6683                power_gpio = 0x103;
6684                usb_power = 0x009;      //usb power on/off
6685                usb_power1 = 0x00a;     //usb power on/off
6686                usb_gpio = 0x10e;
6687                usb_gpio1 = 0x100;
6688                diag_gpio = 0x003;
6689                connected_gpio = 0x101;
6690                disconnected_gpio = 0x102;
6691                break;
6692        case ROUTER_ASUS_AC3200:
6693                usb_power = 0x009;
6694                power_gpio = 0x103;
6695                connected_gpio = 0x105;
6696                diag_gpio = 0x003;
6697                // wps gpio = 14
6698                break;
6699        case ROUTER_ASUS_AC1200:
6700                usb_power = 0x10a;
6701                diag_gpio = 0x00a;
6702                diag_gpio_disabled = 0x10a;
6703                usb_gpio = 0x10f;
6704                break;
6705        case ROUTER_ASUS_AC88U:
6706        case ROUTER_ASUS_AC3100:
6707        case ROUTER_ASUS_AC5300:
6708                usb_power = 0x009;
6709                usb_gpio = 0x110;
6710                usb_gpio1 = 0x111;
6711                power_gpio = 0x103;
6712                diag_gpio = 0x003;
6713                connected_gpio = 0x005;
6714                disconnected_gpio = 0x115;
6715                ses_gpio = 0x113;
6716                // komisches symbol gpio 21
6717                // quantenna reset 8 inv (off / on to reset)   
6718                break;
6719        case ROUTER_ASUS_AC87U:
6720                usb_power = 0x009;
6721                power_gpio = 0x103;
6722                connected_gpio = 0x105;
6723                ses_gpio = 0x101;
6724                // quantenna reset 8 inv (off / on to reset)   
6725                break;
6726        case ROUTER_NETGEAR_EX6200:
6727                //power_gpio = 0x109;   // connected red
6728                diag_gpio = 0x101;      // Netgear logo
6729                connected_gpio = 0x108; // connected green
6730                wlan1_gpio = 0x10b;     // radio led red 2.4G
6731                wlan0_gpio = 0x10d;     // radio led red 5G
6732                usb_gpio = 0x105;       // usb led
6733                //usb_power = 0x000;    // usb enable
6734                break;
6735        case ROUTER_NETGEAR_AC1450:
6736                power_gpio = 0x102;     // power led green
6737                //diag_gpio = 0x103;    // power led orange
6738                diag_gpio = 0x101;      // Netgear logo
6739                connected_gpio = 0x10a; // wan led green - hw controlled
6740                wlan0_gpio = 0x10b;     // radio led blue
6741                usb_gpio = 0x108;       // usb led
6742                //usb_power = 0x000;    // usb enable
6743                break;
6744        case ROUTER_NETGEAR_R6250:
6745                power_gpio = 0x102;     // power led green
6746                //diag_gpio = 0x103;    // power led orange
6747                diag_gpio = 0x001;      // Netgear logo
6748                //emblem0_gpio = 0x001; // NETGEAR Emblem       
6749                //connected_gpio = 0x10f;       // wan led green
6750                wlan0_gpio = 0x10b;     // radio led blue
6751                usb_gpio = 0x108;       // usb led green
6752                //usb_power = 0x000;    // usb enable
6753                break;
6754        case ROUTER_NETGEAR_R6300:
6755                usb_gpio = 0x108;       //usb led
6756                usb_power = 0x000;      //usb power on/off
6757                connected_gpio = 0x10f; //green led
6758                power_gpio = 0x102;     //power orange led
6759                diag_gpio = 0x103;      //power led orange
6760                //diag_gpio_disabled=0x009;//netgear logo led r
6761                //emblem0_gpio = 0x101;   // NETGEAR Emblem l     
6762                //emblem1_gpio = 0x109;   // NETGEAR Emblem r
6763                wlan0_gpio = 0x10b;     // radio led blue
6764                break;
6765        case ROUTER_NETGEAR_R6300V2:
6766                power_gpio = 0x102;     // power led green
6767                //diag_gpio = 0x103;    // power led orange
6768                diag_gpio = 0x101;      // Netgear logo
6769                connected_gpio = 0x10a; // wan led green - hw controlled
6770                wlan0_gpio = 0x10b;     // radio led blue
6771                usb_gpio = 0x108;       // usb led
6772                //usb_power = 0x000;    // usb enable
6773                break;
6774        case ROUTER_NETGEAR_R6400:
6775                power_gpio = 0x101;     //
6776                connected_gpio = 0x107; //
6777                usb_power = 0x000;      //
6778                diag_gpio = 0x102;      //
6779                wlan0_gpio = 0x109;     // radio 0
6780                wlan1_gpio = 0x108;     // radio 1
6781                ses_gpio = 0x10a;       // wps led
6782                wlan_gpio = 0x10b;      // wifi button led
6783                usb_gpio = 0x10c;       // usb1
6784                usb_gpio1 = 0x10d;      // usb2
6785                break;
6786        case ROUTER_NETGEAR_R7000:
6787                power_gpio = 0x102;     // power led
6788                diag_gpio = 0x103;      // power led orange     
6789                connected_gpio = 0x109; // wan led
6790                usb_power = 0x000;      // usb enable
6791                wlan0_gpio = 0x10d;     // radio 0
6792                wlan1_gpio = 0x10c;     // radio 1
6793                ses_gpio = 0x10e;       // wps led
6794                //wlan_gpio = 0x10f;    // wifi button led
6795                usb_gpio = 0x111;       //usb1
6796                usb_gpio1 = 0x112;      //usb2
6797                break;
6798        case ROUTER_NETGEAR_R7500V2:
6799        case ROUTER_NETGEAR_R7500:
6800                power_gpio = 0x000;     // power led
6801                diag_gpio = 0x00a;      // power led orange     
6802                diag_gpio_disabled = 0x000;     // power led orange     
6803                connected_gpio = 0x007; // wan led
6804                usb_power = 0x010;      // usb enable
6805                usb_power1 = 0x00f;     // usb enable
6806                wlan0_gpio = 0x001;     // radio 0
6807                wlan1_gpio = 0x102;     // radio 1
6808                ses_gpio = 0x109;       // wps led
6809                wlan_gpio = 0x108;      // wifi button led
6810                usb_gpio = 0x004;       //usb1
6811                usb_gpio1 = 0x005;      //usb2
6812                break;
6813        case ROUTER_NETGEAR_R7800:
6814                power_gpio = 0x000;     // power led
6815                diag_gpio = 0x00a;      // power led orange     
6816                diag_gpio_disabled = 0x000;     // power led orange     
6817                connected_gpio = 0x007; // wan led
6818                usb_power = 0x010;      // usb enable
6819                usb_power1 = 0x00f;
6820                wlan0_gpio = 0x009;     // radio 5G
6821                wlan1_gpio = 0x008;     // radio 2G
6822                //ses_gpio = 0x109;     // wps button led used for 2G
6823                //wlan_gpio = 0x008;    // wifi button led used for 5G
6824                usb_gpio = 0x004;       //usb1
6825                usb_gpio1 = 0x005;      //usb2
6826                break;
6827        case ROUTER_ASROCK_G10:
6828                diag_gpio = 0x009;      // power led orange     
6829                connected_gpio = 0x008; // wan led
6830                disconnected_gpio = 0x007;      // wan led
6831                break;
6832        case ROUTER_NETGEAR_R9000:
6833
6834                power_gpio = 0x016;     // power led
6835                diag_gpio = 0x116;      // power led orange     
6836                diag_gpio_disabled = 0x016;     // power led orange     
6837                connected_gpio = 0x017; // wan led
6838//      usb_power = 0x010;      // usb enable
6839//      usb_power1 = 0x00f;
6840                ses_gpio = 0x127;       // wps button led used for 2G
6841                usb_gpio = 0x024;       //usb1
6842                usb_gpio1 = 0x025;      //usb2
6843                break;
6844        case ROUTER_TRENDNET_TEW827:
6845                power_gpio = 0x135;     // power led
6846                usb_gpio = 0x107;       // usb led
6847                break;
6848        case ROUTER_NETGEAR_R8000:
6849                power_gpio = 0x102;     // power led
6850                diag_gpio = 0x103;      // power led orange     
6851                connected_gpio = 0x109; // wan led green
6852                usb_power = 0x000;      // usb enable
6853                wlan0_gpio = 0x10d;     // radio 2G
6854                wlan1_gpio = 0x10c;     // radio 5G-1
6855                wlan2_gpio = 0x110;     // radio 5G-2
6856                ses_gpio = 0x10e;       // wps led
6857                wlan_gpio = 0x10f;      // wifi button led
6858                usb_gpio = 0x111;       //usb1
6859                usb_gpio1 = 0x112;      //usb2
6860                break;
6861        case ROUTER_NETGEAR_R8500:
6862                power_gpio = 0x102;     // power led
6863                diag_gpio = 0x10f;      //     
6864                connected_gpio = 0x109; // wan led white 1Gb amber 100Mb
6865                usb_power = 0x000;      // usb enable
6866                wlan0_gpio = 0x10b;     // radio 5G-1
6867                wlan1_gpio = 0x10d;     // radio 2G
6868                wlan2_gpio = 0x10c;     // radio 5G-2
6869                ses_gpio = 0x10e;       // wps led
6870                wlan_gpio = 0x014;      // wifi button led
6871                usb_gpio = 0x111;       //usb1
6872                usb_gpio1 = 0x112;      //usb2
6873                break;
6874        case ROUTER_NETGEAR_WNDR4500:
6875        case ROUTER_NETGEAR_WNDR4500V2:
6876                power_gpio = 0x102;     //power led green
6877                diag_gpio = 0x103;      // power led amber
6878                connected_gpio = 0x10f; //wan led green
6879                wlan0_gpio = 0x109;     //radio 0 led green
6880                wlan1_gpio = 0x10b;     // radio 1 led blue
6881                usb_gpio = 0x108;       //usb led green
6882                usb_gpio1 = 0x10e;      //usb1 led green
6883                break;
6884        case ROUTER_ASUS_RTN66:
6885        case ROUTER_ASUS_AC66U:
6886                power_gpio = 0x10c;
6887                diag_gpio = 0x00c;
6888                usb_gpio = 0x10f;
6889                break;
6890        case ROUTER_NETGEAR_WNR2000V2:
6891
6892                //power_gpio = ??;
6893                diag_gpio = 0x002;
6894                ses_gpio = 0x007;       //WPS led
6895                connected_gpio = 0x006;
6896                break;
6897        case ROUTER_WRT320N:
6898                power_gpio = 0x002;     //power/diag (disabled=blink)
6899                ses_gpio = 0x103;       // ses blue
6900                connected_gpio = 0x104; //ses orange
6901                break;
6902        case ROUTER_ASUS_RTN12:
6903                power_gpio = 0x102;
6904                diag_gpio = 0x002;      // power blink
6905                break;
6906        case ROUTER_BOARD_NEPTUNE:
6907//              usb_gpio = 0x108;
6908                // 0x10c //unknown gpio label, use as diag
6909#ifdef HAVE_RUT500
6910                diag_gpio = 0x10e;
6911#else
6912                diag_gpio = 0x10c;
6913#endif
6914                break;
6915        case ROUTER_ASUS_RTN10U:
6916                ses_gpio = 0x007;
6917                usb_gpio = 0x008;
6918                break;
6919        case ROUTER_ASUS_RTN12B:
6920                connected_gpio = 0x105;
6921                break;
6922        case ROUTER_ASUS_RTN10PLUSD1:
6923                ses_gpio = 0x007;
6924                power_gpio = 0x106;
6925                diag_gpio = 0x006;
6926                break;
6927        case ROUTER_ASUS_RTN10:
6928        case ROUTER_ASUS_RTN16:
6929        case ROUTER_NETCORE_NW618:
6930                power_gpio = 0x101;
6931                diag_gpio = 0x001;      // power blink
6932                break;
6933        case ROUTER_BELKIN_F7D3301:
6934        case ROUTER_BELKIN_F7D3302:
6935        case ROUTER_BELKIN_F7D4301:
6936        case ROUTER_BELKIN_F7D4302:
6937                power_gpio = 0x10a;     // green
6938                diag_gpio = 0x10b;      // red
6939                ses_gpio = 0x10d;       // wps orange
6940                break;
6941        case ROUTER_DYNEX_DX_NRUTER:
6942                power_gpio = 0x001;
6943                diag_gpio = 0x101;      // power blink
6944                connected_gpio = 0x100;
6945                sec0_gpio = 0x103;
6946                break;
6947#endif
6948        }
6949
6950        if (type == LED_DIAG && v1func == 1) {
6951                if (act == LED_ON)
6952                        C_led(1);
6953                else
6954                        C_led(0);
6955        }
6956
6957        switch (type) {
6958        case LED_POWER:
6959                use_gpio = power_gpio;
6960                break;
6961        case BEEPER:
6962                use_gpio = beeper_gpio;
6963                break;
6964        case USB_POWER:
6965                use_gpio = usb_power;
6966                break;
6967        case USB_POWER1:
6968                use_gpio = usb_power1;
6969                break;
6970        case LED_DIAG:
6971                if (act == LED_ON)
6972                        led_control(LED_DIAG_DISABLED, LED_OFF);
6973                else
6974                        led_control(LED_DIAG_DISABLED, LED_ON);
6975                use_gpio = diag_gpio;
6976                break;
6977        case LED_DIAG_DISABLED:
6978                use_gpio = diag_gpio_disabled;
6979                break;
6980        case LED_DMZ:
6981                use_gpio = dmz_gpio;
6982                break;
6983        case LED_CONNECTED:
6984                if (act == LED_ON)
6985                        led_control(LED_DISCONNECTED, LED_OFF);
6986                else
6987                        led_control(LED_DISCONNECTED, LED_ON);
6988                use_gpio = connblue ? ses_gpio : connected_gpio;
6989                break;
6990        case LED_DISCONNECTED:
6991                use_gpio = disconnected_gpio;
6992                break;
6993        case LED_BRIDGE:
6994                use_gpio = bridge_gpio;
6995                break;
6996        case LED_VPN:
6997                use_gpio = vpn_gpio;
6998                break;
6999        case LED_SES:
7000                use_gpio = connblue ? connected_gpio : ses_gpio;
7001                break;
7002        case LED_SES2:
7003                use_gpio = ses2_gpio;
7004                break;
7005        case LED_WLAN:
7006                use_gpio = wlan_gpio;
7007                break;
7008        case LED_WLAN0:
7009                use_gpio = wlan0_gpio;
7010                break;
7011        case LED_WLAN1:
7012                use_gpio = wlan1_gpio;
7013                break;
7014        case LED_WLAN2:
7015                use_gpio = wlan2_gpio;
7016                break;
7017        case LED_USB:
7018                use_gpio = usb_gpio;
7019                break;
7020        case LED_USB1:
7021                use_gpio = usb_gpio1;
7022                break;
7023        case LED_SEC0:
7024                use_gpio = sec0_gpio;
7025                break;
7026        case LED_SEC1:
7027                use_gpio = sec1_gpio;
7028                break;
7029        }
7030
7031        if ((use_gpio & 0x0ff) != 0x0ff) {
7032                gpio_value = use_gpio & 0x0ff;
7033                enable = (use_gpio & 0x100) == 0 ? 1 : 0;
7034                disable = (use_gpio & 0x100) == 0 ? 0 : 1;
7035                int setin = (use_gpio & 0x200) == 0 ? 0 : 1;
7036                switch (act) {
7037                case LED_ON:
7038                        set_gpio(gpio_value, enable);
7039                        if (setin)
7040                                get_gpio(gpio_value);
7041                        break;
7042                case LED_OFF:
7043                        set_gpio(gpio_value, disable);
7044                        break;
7045                case LED_FLASH: // will lit the led for 1 sec.
7046                        set_gpio(gpio_value, enable);
7047                        sleep(1);
7048                        set_gpio(gpio_value, disable);
7049                        break;
7050                }
7051        }
7052        return 1;
7053
7054#endif
7055}
7056
7057int file_to_buf(char *path, char *buf, int len)
7058{
7059        FILE *fp;
7060
7061        bzero(buf, len);
7062
7063        if ((fp = fopen(path, "r"))) {
7064                fgets(buf, len, fp);
7065                fclose(fp);
7066                return 1;
7067        }
7068
7069        return 0;
7070}
7071
7072int ishexit(char c)
7073{
7074
7075        if (strchr("01234567890abcdefABCDEF", c) != (char *)0)
7076                return 1;
7077
7078        return 0;
7079}
7080
7081int getMTD(char *name)
7082{
7083        char buf[32];
7084        int device = -1;
7085        char dev[32];
7086        char size[32];
7087        char esize[32];
7088        char n[32];
7089        sprintf(buf, "\"%s\"", name);
7090        FILE *fp = fopen("/proc/mtd", "rb");
7091        if (!fp)
7092                return -1;
7093        while (!feof(fp) && fscanf(fp, "%s %s %s %s", dev, size, esize, n) == 4) {
7094                if (!strcmp(n, buf)) {
7095                        if (dev[4] == ':') {
7096                                device = dev[3] - '0';
7097                        } else {
7098                                device = 10 + (dev[4] - '0');
7099                        }
7100
7101                        break;
7102                }
7103        }
7104        fclose(fp);
7105        return device;
7106}
7107
7108int insmod(char *module)
7109{
7110        static char word[256];
7111        char *next, *wordlist;
7112        int ret = 0;
7113        wordlist = module;
7114        foreach(word, wordlist, next) {
7115                ret |= _evalpid((char *[]) {
7116                                "insmod", word, NULL}, ">/dev/null", 0, NULL);
7117        }
7118        return ret;
7119}
7120
7121void rmmod(char *module)
7122{
7123        static char word[256];
7124        char *next, *wordlist;
7125        wordlist = module;
7126        foreach(word, wordlist, next) {
7127                _evalpid((char *[]) {
7128                         "rmmod", word, NULL}, ">/dev/null", 0, NULL);
7129        }
7130}
7131
7132#include "revision.h"
7133
7134char *getSoftwareRevision(void)
7135{
7136        return "" SVN_REVISION "";
7137}
7138
7139#ifdef HAVE_OLED
7140void initlcd()
7141{
7142
7143}
7144
7145void lcdmessage(char *message)
7146{
7147        eval("oled-print", "DD-WRT v24 sp2", "build:" SVN_REVISION, "3G/UMTS Router", message);
7148}
7149
7150void lcdmessaged(char *dual, char *message)
7151{
7152
7153}
7154
7155#endif
7156
7157#if 0
7158
7159static int fd;
7160
7161void SetEnvironment()
7162{
7163        system("stty ispeed 2400 < /dev/tts/1");
7164        system("stty raw < /dev/tts/1");
7165}
7166
7167int Cmd = 254;                  /* EZIO Command */
7168int cls = 1;                    /* Clear screen */
7169void Cls()
7170{
7171        write(fd, &Cmd, 1);
7172        write(fd, &cls, 1);
7173}
7174
7175int init = 0x28;
7176void Init()
7177{
7178        write(fd, &Cmd, 1);
7179        write(fd, &init, 1);
7180}
7181
7182int stopsend = 0x37;
7183void StopSend()
7184{
7185        write(fd, &Cmd, 1);
7186        write(fd, &init, 1);
7187}
7188
7189int home = 2;                   /* Home cursor */
7190void Home()
7191{
7192        write(fd, &Cmd, 1);
7193        write(fd, &home, 1);
7194}
7195
7196int readkey = 6;                /* Read key */
7197void ReadKey()
7198{
7199        write(fd, &Cmd, 1);
7200        write(fd, &readkey, 1);
7201}
7202
7203int blank = 8;                  /* Blank display */
7204void Blank()
7205{
7206        write(fd, &Cmd, 1);
7207        write(fd, &blank, 1);
7208}
7209
7210int hide = 12;                  /* Hide cursor & display blanked characters */
7211void Hide()
7212{
7213        write(fd, &Cmd, 1);
7214        write(fd, &hide, 1);
7215}
7216
7217int turn = 13;                  /* Turn On (blinking block cursor) */
7218void TurnOn()
7219{
7220        write(fd, &Cmd, 1);
7221        write(fd, &turn, 1);
7222}
7223
7224int show = 14;                  /* Show underline cursor */
7225void Show()
7226{
7227        write(fd, &Cmd, 1);
7228        write(fd, &show, 1);
7229}
7230
7231int movel = 16;                 /* Move cursor 1 character left */
7232void MoveL()
7233{
7234        write(fd, &Cmd, 1);
7235        write(fd, &movel, 1);
7236}
7237
7238int mover = 20;                 /* Move cursor 1 character right */
7239void MoveR()
7240{
7241        write(fd, &Cmd, 1);
7242        write(fd, &mover, 1);
7243}
7244
7245int scl = 24;                   /* Scroll cursor 1 character left */
7246void ScrollL()
7247{
7248        write(fd, &Cmd, 1);
7249        write(fd, &scl, 1);
7250}
7251
7252int scr = 28;                   /* Scroll cursor 1 character right */
7253void ScrollR()
7254{
7255        write(fd, &Cmd, 1);
7256        write(fd, &scr, 1);
7257}
7258
7259int setdis = 64;                /* Command */
7260void SetDis()
7261{
7262        write(fd, &Cmd, 1);
7263        write(fd, &setdis, 1);
7264
7265}
7266
7267int a, b;
7268void ShowMessage(char *str1, char *str2)
7269{
7270        char nul[] = "                                       ";
7271
7272        a = strlen(str1);
7273        b = 40 - a;
7274        write(fd, str1, a);
7275        write(fd, nul, b);
7276        write(fd, str2, strlen(str2));
7277}
7278
7279void initlcd()
7280{
7281
7282        fd = open("/dev/tts/1", O_RDWR);
7283
7284                                  /** Open Serial port (COM2) */
7285        if (fd > 0) {
7286                close(fd);
7287                SetEnvironment();       /* Set RAW mode */
7288                fd = open("/dev/tts/1", O_RDWR);
7289                Init();         /* Initialize EZIO twice */
7290                Init();
7291
7292                Cls();          /* Clear screen */
7293        }
7294        close(fd);
7295}
7296
7297void lcdmessage(char *message)
7298{
7299
7300        fd = open("/dev/tts/1", O_RDWR);
7301                                   /** Open Serial port (COM2) */
7302
7303        if (fd > 0) {
7304                Init();         /* Initialize EZIO twice */
7305                Init();
7306                SetDis();
7307                Cls();
7308                Home();
7309                ShowMessage("State", message);
7310                close(fd);
7311        }
7312}
7313
7314void lcdmessaged(char *dual, char *message)
7315{
7316
7317        fd = open("/dev/tts/1", O_RDWR);
7318
7319                                  /** Open Serial port (COM2) */
7320
7321        if (fd > 0) {
7322                Init();         /* Initialize EZIO twice */
7323                Init();
7324                SetDis();
7325                Cls();          /* Clear screen */
7326                Home();
7327                ShowMessage(dual, message);
7328                close(fd);
7329        }
7330}
7331
7332#endif
7333static int i64c(int i)
7334{
7335        i &= 0x3f;
7336        if (i == 0)
7337                return '.';
7338        if (i == 1)
7339                return '/';
7340        if (i < 12)
7341                return ('0' - 2 + i);
7342        if (i < 38)
7343                return ('A' - 12 + i);
7344        return ('a' - 38 + i);
7345}
7346
7347int crypt_make_salt(char *p, int cnt, int x)
7348{
7349        x += getpid() + time(NULL);
7350        do {
7351                /*
7352                 * x = (x*1664525 + 1013904223) % 2^32 generator is lame (low-order
7353                 * bit is not "random", etc...), but for our purposes it is good
7354                 * enough
7355                 */
7356                x = x * 1664525 + 1013904223;
7357                /*
7358                 * BTW, Park and Miller's "minimal standard generator" is x = x*16807
7359                 * % ((2^31)-1) It has no problem with visibly alternating lowest bit
7360                 * but is also weak in cryptographic sense + needs div, which needs
7361                 * more code (and slower) on many CPUs
7362                 */
7363                *p++ = i64c(x >> 16);
7364                *p++ = i64c(x >> 22);
7365        }
7366        while (--cnt);
7367        *p = '\0';
7368        return x;
7369}
7370
7371#include <crypt.h>
7372
7373char *zencrypt(char *passwd, char *passout)
7374{
7375        char salt[sizeof("$N$XXXXXXXX")];       /* "$N$XXXXXXXX" or "XX" */
7376
7377        strcpy(salt, "$1$");
7378        crypt_make_salt(salt + 3, 4, 0);
7379        strcpy(passout, crypt((char *)passwd, (char *)salt));
7380        return passout;
7381}
7382
7383int has_gateway(void)
7384{
7385        if (nvram_match("wk_mode", "gateway"))
7386                return 1;
7387        if (nvram_match("wk_mode", "olsr") && nvram_matchi("olsrd_gateway", 1))
7388                return 1;
7389        return 0;
7390}
7391
7392struct wifidevices {
7393        char *name;
7394        int vendor;
7395        int device;
7396};
7397
7398static struct wifidevices wdevices[] = {
7399        {"AR5210 802.11a", 0x168c, 0x0007},
7400        {"AR5210 802.11a", 0x168c, 0x0207},
7401        {"AR5211 802.11a", 0x168c, 0x0011},
7402        {"AR5211 802.11ab", 0x168c, 0x0012},
7403        {"AR5212", 0x168c, 0x0013},
7404        {"AR5212", 0x168c, 0x1014},
7405        {"AR2413", 0x168c, 0x001a},
7406        {"AR5413", 0x168c, 0x001b},
7407        {"AR542x", 0x168c, 0x001c},
7408        {"AR2417", 0x168c, 0x001d},
7409        {"AR5513", 0x168c, 0x0020},
7410        {"AR5416 802.11n", 0x168c, 0x0023},
7411        {"AR5418 802.11n", 0x168c, 0x0024},
7412        {"AR9160 802.11n", 0x168c, 0x0027},
7413        {"AR922X 802.11n", 0x168c, 0x0029},
7414        {"AR928X 802.11n", 0x168c, 0x002a},
7415        {"AR9285 802.11n", 0x168c, 0x002b},
7416        {"AR2427 802.11n", 0x168c, 0x002c},
7417        {"AR9227 802.11n", 0x168c, 0x002d},
7418        {"AR9287 802.11n", 0x168c, 0x002e},
7419        {"AR93xx 802.11n", 0x168c, 0x0030},
7420        {"AR9485 802.11n", 0x168c, 0x0032},
7421        {"AR958x 802.11n", 0x168c, 0x0033},
7422        {"AR9462 802.11n", 0x168c, 0x0034},
7423        {"QCA9565 802.11n", 0x168c, 0x0036},
7424        {"AR9485 802.11n", 0x168c, 0x0037},
7425        {"AR5002X", 0x168c, 0x9013},
7426        {"AR5006X", 0x168c, 0xff19},
7427        {"AR2425", 0x168c, 0xff1b},
7428        {"AR5008", 0x168c, 0xff1c},
7429        {"AR922x 802.11n", 0x168c, 0xff1d},
7430        {"QCA988x 802.11ac", 0x168c, 0x003c},
7431        {"QCA6174 802.11ac", 0x168c, 0x003e},
7432        {"QCA9980 802.11ac", 0x168c, 0x0040},
7433        {"QCA6174 802.11ac", 0x168c, 0x0041},
7434        {"QCA9377 802.11ac", 0x168c, 0x0042},
7435        {"QCA9984 802.11ac", 0x168c, 0x0046},
7436        {"QCA9887 802.11ac", 0x168c, 0x0050},
7437        {"QCA9888 802.11ac", 0x168c, 0x0056},
7438        {"88W8964 802.11ac", 0x11ab, 0x2b40},
7439        {"88W8864 802.11ac", 0x11ab, 0x2a55},
7440        {"88W8897 802.11ac", 0x11ab, 0x2b38},
7441        {"WIL6210 802.11ad", 0x1ae9, 0x0310},
7442        {"SD8887 802.11ac", 0x02df, 0x9135},
7443        {"MT7615 802.11ac", 0x14c3, 0x7615},
7444        {"MT7662E 802.11ac", 0x14c3, 0x7662},
7445
7446};
7447
7448char *getWifiDeviceName(char *prefix)
7449{
7450        char *globstring;
7451        int devnum;
7452        int device = 0, vendor = 0;
7453        int devcount;
7454        FILE *fp;
7455        sscanf(prefix, "ath%d", &devcount);
7456        asprintf(&globstring, "/proc/sys/dev/wifi%d/dev_vendor", devcount);
7457        fp = fopen(globstring, "rb");
7458        if (fp) {
7459                fscanf(fp, "%d", &vendor);
7460                fclose(fp);
7461        }
7462        free(globstring);
7463        asprintf(&globstring, "/proc/sys/dev/wifi%d/dev_device", devcount);
7464        fp = fopen(globstring, "rb");
7465        if (fp) {
7466                fscanf(fp, "%d", &device);
7467                fclose(fp);
7468        }
7469        free(globstring);
7470#ifdef HAVE_ATH9K
7471        if (!vendor || !device) {
7472                devnum = get_ath9k_phy_ifname(prefix);
7473                if (devnum == -1)
7474                        return NULL;
7475                asprintf(&globstring, "/sys/class/ieee80211/phy%d/device/vendor", devnum);
7476                fp = fopen(globstring, "rb");
7477                if (fp) {
7478                        fscanf(fp, "0x%x", &vendor);
7479                        fclose(fp);
7480                }
7481                free(globstring);
7482                asprintf(&globstring, "/sys/class/ieee80211/phy%d/device/device", devnum);
7483                fp = fopen(globstring, "rb");
7484                if (fp) {
7485                        fscanf(fp, "0x%x", &device);
7486                        fclose(fp);
7487                }
7488                free(globstring);
7489        }
7490#endif
7491#ifdef HAVE_RT2880
7492        if (!vendor || !device) {
7493
7494                if (!strncmp(prefix, "ra", 2) || !strncmp(prefix, "wl0", 3)) {
7495                        FILE *fp = fopen("/sys/bus/pci/devices/0000:01:00.0/device", "rb");
7496                        if (fp) {
7497                                fscanf(fp, "0x%x", &device);
7498                                fclose(fp);
7499                        }
7500                        fp = fopen("/sys/bus/pci/devices/0000:01:00.0/vendor", "rb");
7501                        if (fp) {
7502                                fscanf(fp, "0x%x", &vendor);
7503                                fclose(fp);
7504                        }
7505                }
7506
7507                if (!strncmp(prefix, "ba", 2) || !strncmp(prefix, "wl1", 3)) {
7508                        FILE *fp = fopen("/sys/bus/pci/devices/0000:02:00.0/device", "rb");
7509                        if (fp) {
7510                                fscanf(fp, "0x%x", &device);
7511                                fclose(fp);
7512                        }
7513                        fp = fopen("/sys/bus/pci/devices/0000:02:00.0/vendor", "rb");
7514                        if (fp) {
7515                                fscanf(fp, "0x%x", &vendor);
7516                                fclose(fp);
7517                        }
7518                }
7519        }
7520#endif
7521        if (!vendor || !device) {
7522                return NULL;
7523        }
7524        int i;
7525        for (i = 0; i < sizeof(wdevices) / sizeof(wdevices[0]); i++) {
7526                if (wdevices[i].vendor == vendor && wdevices[i].device == device)
7527                        return wdevices[i].name;
7528        }
7529        return NULL;
7530
7531}
7532
7533#ifdef HAVE_ATH9K
7534int getath9kdevicecount(void)
7535{
7536        glob_t globbuf;
7537        int globresult;
7538        int count = 0;
7539#ifndef HAVE_MADWIFI_MIMO
7540        if (1) {
7541#else
7542        if (nvram_match("mimo_driver", "ath9k")) {
7543#endif
7544                globresult = glob("/sys/class/ieee80211/phy*", GLOB_NOSORT, NULL, &globbuf);
7545                if (globresult == 0)
7546                        count = (int)globbuf.gl_pathc;
7547                globfree(&globbuf);
7548        }
7549#if (defined(HAVE_MMS344) || defined(HAVE_ARCHERC7)) && !defined(HAVE_DAP2330) && !defined(HAVE_WILLY)
7550        return 2;
7551#else
7552        return (count);
7553#endif
7554}
7555
7556int get_ath9k_phy_idx(int idx)
7557{
7558        // fprintf(stderr,"channel number %d of %d\n", i,achans.ic_nchans);
7559#ifdef HAVE_MVEBU
7560        return idx;
7561#else
7562        return idx - getifcount("wifi");
7563#endif
7564}
7565
7566int get_ath9k_phy_ifname(const char *ifname)
7567{
7568        int devnum;
7569        if (is_wil6210(ifname))
7570                return 2;
7571        if (strncmp(ifname, "ath", 3))
7572                return -1;
7573        if (!sscanf(ifname, "ath%d", &devnum))
7574                return -1;
7575        // fprintf(stderr,"channel number %d of %d\n", i,achans.ic_nchans);
7576        return get_ath9k_phy_idx(devnum);
7577}
7578
7579int is_ath9k(const char *prefix)
7580{
7581#ifdef HAVE_MVEBU
7582        return 1;
7583#endif
7584        glob_t globbuf;
7585        int count = 0;
7586        char *globstring;
7587        int globresult;
7588        int devnum;
7589        // get legacy interface count
7590#ifdef HAVE_MADWIFI_MIMO
7591        if (!nvram_match("mimo_driver", "ath9k"))
7592                return (0);
7593#endif
7594        // correct index if there are legacy cards arround
7595        devnum = get_ath9k_phy_ifname(prefix);
7596        if (devnum == -1)
7597                return 0;
7598        asprintf(&globstring, "/sys/class/ieee80211/phy%d", devnum);
7599        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
7600        free(globstring);
7601        if (globresult == 0)
7602                count = (int)globbuf.gl_pathc;
7603        globfree(&globbuf);
7604        return (count);
7605}
7606
7607int has_spectralscanning(const char *prefix)
7608{
7609#ifdef HAVE_MVEBU
7610        return 0;
7611#endif
7612        glob_t globbuf;
7613        int count = 0;
7614        char *globstring;
7615        int globresult;
7616        int devnum;
7617        // get legacy interface count
7618#ifdef HAVE_MADWIFI_MIMO
7619        if (!nvram_match("mimo_driver", "ath9k"))
7620                return (0);
7621#endif
7622        // correct index if there are legacy cards arround
7623        devnum = get_ath9k_phy_ifname(prefix);
7624        if (devnum == -1)
7625                return 0;
7626#ifdef HAVE_ATH10K
7627        if (is_ath10k(prefix))
7628                asprintf(&globstring, "/sys/kernel/debug/ieee80211/phy%d/ath10k/spectral_count", devnum);
7629        else
7630#endif
7631                asprintf(&globstring, "/sys/kernel/debug/ieee80211/phy%d/ath9k/spectral_count", devnum);
7632        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
7633        free(globstring);
7634        if (globresult == 0)
7635                count = (int)globbuf.gl_pathc;
7636        globfree(&globbuf);
7637        return (count);
7638}
7639#endif
7640
7641static int devicecountbydriver(const char *prefix, char *drivername)
7642{
7643        glob_t globbuf;
7644        int count = 0;
7645        char *globstring;
7646        int globresult;
7647        int devnum;
7648        // correct index if there are legacy cards arround... should not...
7649        devnum = get_ath9k_phy_ifname(prefix);
7650        if (devnum == -1)
7651                return 0;
7652        asprintf(&globstring, "/sys/class/ieee80211/phy%d/device/driver/module/drivers/pci:%s", devnum, drivername);
7653        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
7654        free(globstring);
7655        if (globresult == 0)
7656                count = (int)globbuf.gl_pathc;
7657        globfree(&globbuf);
7658        return (count);
7659
7660}
7661
7662#ifdef HAVE_ATH5K
7663int is_ath5k(const char *prefix)
7664{
7665        return devicecountbydriver(prefix, "ath5k");
7666}
7667#endif
7668#ifdef HAVE_MVEBU
7669int is_mvebu(const char *prefix)
7670{
7671        return devicecountbydriver(prefix, "mwlwifi");
7672}
7673#endif
7674#ifdef HAVE_ATH10K
7675int is_ath10k(const char *prefix)
7676{
7677        // get legacy interface count
7678#ifdef HAVE_MADWIFI_MIMO
7679        if (!nvram_match("mimo_driver", "ath9k"))
7680                return (0);
7681#endif
7682        return devicecountbydriver(prefix, "ath10k_pci");
7683}
7684
7685#endif
7686#ifdef HAVE_WIL6210
7687int is_wil6210(const char *prefix)
7688{
7689        if (!strcmp(prefix, "giwifi"))
7690                return 1;
7691        if (!strcmp(prefix, "ath2"))
7692                return 1;
7693        return 0;
7694        // get legacy interface count
7695//      return devicecountbydriver(prefix, "wil6210");
7696}
7697
7698#endif
7699
7700static int HTtoVHTindex(int mcs)
7701{
7702        if (mcs < 8)
7703                return mcs;
7704        if (mcs < 16)
7705                return mcs + 2;
7706        if (mcs < 24)
7707                return mcs + 4;
7708        return mcs + 6;
7709}
7710
7711int VHTTxRate(unsigned int mcs, unsigned int vhtmcs, unsigned int sgi, unsigned int bw)
7712{
7713        static int vHTTxRate20_800[40] = {
7714                6500, 13000, 19500, 26000, 39000, 52000, 58500, 65000, 78000, 78000,    // MCS 0 -8
7715                13000, 26000, 39000, 52000, 78000, 104000, 117000, 130000, 156000, 156000,      // MCS 8 - 15
7716                19500, 39000, 58500, 78000, 117000, 156000, 175500, 195000, 234000, 260000,     // MCS 16 - 23
7717                26000, 52000, 78000, 104000, 156000, 208000, 234000, 260000, 312000, 312000     // MCS 24 - 31
7718        };
7719        static int vHTTxRate20_400[40] = {
7720                7200, 14400, 21700, 28900, 43300, 57800, 65000, 72200, 86700, 86700,    //
7721                14444, 28889, 43333, 57778, 86667, 115556, 130000, 144444, 173300, 173300,      //
7722                21700, 43300, 65000, 86700, 130000, 173300, 195000, 216700, 260000, 288900,     //
7723                28900, 57800, 86700, 115600, 173300, 231100, 260000, 288900, 346700, 0  //
7724        };
7725        static int vHTTxRate40_800[40] = {
7726                13500, 27000, 40500, 54000, 81000, 108000, 121500, 135000, 162000, 180000,      //
7727                27000, 54000, 81000, 108000, 162000, 216000, 243000, 270000, 324000, 360000,    //
7728                40500, 81000, 121500, 162000, 243000, 324000, 364500, 405000, 486000, 540000,   //
7729                54000, 108000, 162000, 216000, 324000, 432000, 486000, 540000, 648000, 720000   //
7730        };
7731        static int vHTTxRate40_400[40] = {
7732                15000, 30000, 45000, 60000, 90000, 120000, 135000, 150000, 180000, 200000,      //
7733                30000, 60000, 90000, 120000, 180000, 240000, 270000, 300000, 360000, 400000,    //
7734                45000, 90000, 135000, 180000, 270000, 360000, 405000, 450000, 540000, 600000,   //
7735                60000, 120000, 180000, 240000, 360000, 480000, 540000, 600000, 720000, 800000   //
7736        };
7737        static int vHTTxRate80_800[40] = {
7738                29300, 58500, 87800, 117000, 175500, 234000, 263300, 292500, 351000, 390000,    //
7739                58500, 117000, 175500, 234000, 351000, 468000, 526500, 585000, 702000, 780000,
7740                87800, 175500, 263300, 351000, 526500, 702000, 0, 877500, 1053000, 1170000,     //
7741                117000, 234000, 351000, 468000, 702000, 936000, 1053000, 1170000, 1404000, 1560000
7742        };
7743        static int vHTTxRate80_400[40] = {
7744                32500, 65000, 97500, 130000, 195000, 260000, 292500, 325000, 390000, 433300,    //
7745                65000, 130000, 195000, 260000, 390000, 520000, 585000, 650000, 780000, 866700,  //
7746                97500, 195000, 292500, 390000, 585000, 780000, 0, 975000, 1170000, 1300000,     //
7747                130000, 260000, 390000, 520000, 780000, 1040000, 1170000, 1300000, 1560000, 1733300
7748        };
7749        static int vHTTxRate160_800[40] = {
7750                58500, 117000, 175500, 234000, 351000, 468000, 526500, 585000, 702000, 780000,
7751                117000, 234000, 351000, 468000, 702000, 936000, 1053000, 1170000, 1404000, 1560000,
7752                175500, 351000, 526500, 702000, 1053000, 1404000, 1579500, 1755000, 2106000, 2106000,
7753                234000, 468000, 702000, 936000, 1404000, 1872000, 2106000, 2340000, 2808000, 3120000,
7754
7755        };
7756        static int vHTTxRate160_400[40] = {
7757                65000, 130000, 195000, 260000, 390000, 520000, 585000, 650000, 780000, 866700,  //
7758                130000, 260000, 390000, 520000, 780000, 1040000, 1170000, 1300000, 1560000, 1733300,
7759                195000, 390000, 585000, 780000, 1170000, 1560000, 1755000, 1950000, 2340000, 2340000,
7760                260000, 520000, 780000, 1040000, 1560000, 2080000, 2340000, 2600000, 3120000, 3466700,
7761        };
7762
7763        int *table = vHTTxRate20_400;
7764//      fprintf(stderr, "sgi %d mcs %d vhtmcs %d\n", sgi, mcs, vhtmcs);
7765        if (sgi) {
7766                switch (bw) {
7767                case 20:
7768                        table = vHTTxRate20_400;
7769                        break;
7770                case 40:
7771                        table = vHTTxRate40_400;
7772                        break;
7773                case 80:
7774                        table = vHTTxRate80_400;
7775                        break;
7776                case 160:
7777                        table = vHTTxRate160_400;
7778                        break;
7779                }
7780        } else {
7781
7782                switch (bw) {
7783                case 20:
7784                        table = vHTTxRate20_800;
7785                        break;
7786                case 40:
7787                        table = vHTTxRate40_800;
7788                        break;
7789                case 80:
7790                        table = vHTTxRate80_800;
7791                        break;
7792                case 160:
7793                        table = vHTTxRate160_800;
7794                        break;
7795                }
7796        }
7797        if (vhtmcs == -1) {
7798                vhtmcs = HTtoVHTindex(mcs);
7799        }
7800
7801        return table[vhtmcs];
7802}
7803
7804int writeproc(char *path, char *value)
7805{
7806        int fd;
7807        fd = open(path, O_WRONLY);
7808        if (fd == -1) {
7809                fprintf(stderr, "cannot open %s\n", path);
7810                return -1;
7811        }
7812        write(fd, value, strlen(value));
7813        close(fd);
7814        return 0;
7815}
7816
7817int writeprocsysnet(char *path, char *value)
7818{
7819        char syspath[64];
7820        snprintf(syspath, 64, "/proc/sys/net/%s", path);
7821        return writeproc(syspath, value);
7822}
7823
7824int writeprocsys(char *path, char *value)
7825{
7826        char syspath[64];
7827        snprintf(syspath, 64, "/proc/sys/%s", path);
7828        return writeproc(syspath, value);
7829}
7830
7831int writevaproc(char *value, char *fmt, ...)
7832{
7833        char varbuf[256];
7834        va_list args;
7835
7836        va_start(args, (char *)fmt);
7837        vsnprintf(varbuf, sizeof(varbuf), fmt, args);
7838        va_end(args);
7839        return writeproc(varbuf, value);
7840}
7841
7842void set_smp_affinity(int irq, int cpu)
7843{
7844        char s_cpu[32];
7845        snprintf(s_cpu, sizeof(s_cpu), "%d", cpu);
7846        writevaproc(s_cpu, "/proc/irq/%d/smp_affinity", irq);
7847}
7848
7849/* gartarp */
7850
7851struct arph {
7852        uint16_t hw_type;
7853
7854#define ARPHDR_ETHER    1
7855
7856        uint16_t proto_type;
7857
7858        char ha_len;
7859        char pa_len;
7860
7861#define ARPOP_BROADCAST 1
7862#define ARPOP_REPLY     2
7863        uint16_t opcode;
7864        char source_add[ETH_ALEN];
7865        char source_ip[IP_ALEN];
7866        char dest_add[ETH_ALEN];
7867        char dest_ip[IP_ALEN];
7868
7869} __attribute__((packed));
7870
7871#define ARP_HLEN        sizeof(struct arph) + ETH_HLEN
7872#define BCAST           "\xff\xff\xff\xff\xff\xff"
7873
7874static inline int get_iface_attr(int sk, char *iface, char *hw, char *paddr)
7875{
7876        int ret;
7877        struct ifreq ifr;
7878
7879        strcpy(ifr.ifr_name, iface);
7880
7881        ret = ioctl(sk, SIOCGIFHWADDR, &ifr);
7882        if (unlikely(ret == -1)) {
7883                perror("ioctl SIOCGIFHWADDR");
7884                return ret;
7885        }
7886        memcpy(hw, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
7887
7888        ret = ioctl(sk, SIOCGIFADDR, &ifr);
7889        if (unlikely(ret == -1)) {
7890                perror("ioctl SIOCGIFADDR");
7891                return ret;
7892        }
7893        memcpy(paddr, ifr.ifr_addr.sa_data + 2, IP_ALEN);
7894
7895        return ret;
7896}
7897
7898static inline void setup_eth(struct ether_header *eth, char *hw_addr)
7899{
7900        memcpy(eth->ether_shost, hw_addr, ETH_ALEN);
7901        memcpy(eth->ether_dhost, BCAST, ETH_ALEN);
7902        eth->ether_type = htons(ETH_P_ARP);
7903}
7904
7905static inline void setup_garp(struct arph *arp, char *hw_addr, char *paddr)
7906{
7907        arp->hw_type = htons(ARPHDR_ETHER);
7908        arp->proto_type = htons(ETH_P_IP);
7909        arp->ha_len = ETH_ALEN;
7910        arp->pa_len = IP_ALEN;
7911
7912        memcpy(arp->source_add, hw_addr, ETH_ALEN);
7913        memcpy(arp->source_ip, paddr, IP_ALEN);
7914}
7915
7916static inline void setup_garp_broadcast(struct arph *arp, char *paddr)
7917{
7918        arp->opcode = htons(ARPOP_BROADCAST);
7919
7920        bzero(arp->dest_add, ETH_ALEN);
7921        memcpy(arp->dest_ip, paddr, IP_ALEN);
7922}
7923
7924static inline void setup_garp_reply(struct arph *arp, char *hw_addr, char *paddr)
7925{
7926        arp->opcode = htons(ARPOP_REPLY);
7927
7928        memcpy(arp->dest_add, hw_addr, ETH_ALEN);
7929        memcpy(arp->dest_ip, paddr, IP_ALEN);
7930}
7931
7932/*
7933 * send_garp
7934 *
7935 * - sends 20 gartuitous arps
7936 * in a 200 millisec interval.
7937 * One as braadcast and one as reply.
7938 *
7939 *
7940 * parameter iface: sending interface name
7941 *
7942 * returns false on failure
7943 *         true on success
7944 */
7945static int send_garp(char *iface)
7946{
7947        char pkt[ARP_HLEN];
7948        char iface_hw[ETH_ALEN];
7949        char iface_paddr[IP_ALEN];
7950        struct sockaddr_ll link;
7951        struct ether_header *eth;
7952        struct arph *arp;
7953        int rc;
7954        int sk;
7955        int n_garps = 10;
7956
7957        eth = (struct ether_header *)pkt;
7958        arp = (struct arph *)(pkt + ETH_HLEN);
7959
7960        sk = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
7961        if (unlikely(sk == -1)) {
7962                perror("socket");
7963                return sk;
7964        }
7965
7966        rc = get_iface_attr(sk, iface, iface_hw, iface_paddr);
7967        if (unlikely(rc == -1))
7968                goto out;
7969
7970        /* set link layer information for driver */
7971        bzero(&link, sizeof(link));
7972        link.sll_family = AF_PACKET;
7973        link.sll_ifindex = if_nametoindex(iface);
7974
7975        setup_eth(eth, iface_hw);
7976        setup_garp(arp, iface_hw, iface_paddr);
7977
7978        while (n_garps--) {
7979                setup_garp_broadcast(arp, iface_paddr);
7980                rc = sendto(sk, pkt, ARP_HLEN, 0, (struct sockaddr *)&link, sizeof(struct sockaddr_ll)
7981                    );
7982                if (unlikely(rc == -1)) {
7983                        perror("sendto");
7984                        goto out;
7985                }
7986
7987                setup_garp_reply(arp, iface_hw, iface_paddr);
7988                rc = sendto(sk, pkt, ARP_HLEN, 0, (struct sockaddr *)&link, sizeof(struct sockaddr_ll)
7989                    );
7990                if (unlikely(rc == -1)) {
7991                        perror("sendto");
7992                        goto out;
7993                }
7994                usleep(200000);
7995        }
7996
7997out:
7998        close(sk);
7999        return rc;
8000}
8001
8002int gratarp_main(char *iface)
8003{
8004        if (iface) {
8005                usleep(500000);
8006                send_garp(iface);
8007        }
8008
8009        return 0;
8010}
8011
8012/* NF Mark/Mask
8013 *
8014 * since multiple services needs a NF packet mark,
8015 * we need to use masks to split the 32bit value into several pieces
8016 *
8017 *                                             31       23       15       7      0
8018 * port_forwards         1 bit(s) offset 31  > 10000000 00000000 00000000 00000000
8019 * hotspot                               8 bit(s) offset 23  > 01111111 10000000 00000000 00000000
8020 * quality of service   13 bit(s) offset 10  > 00000000 01111111 11111100 00000000
8021 *
8022 * the remaining 11 bits are currently not in use
8023 */
8024
8025struct NF_MASKS {
8026        char *service_name;     // name of the service
8027        int bits_used;          // bits used by this service
8028        int bit_offset;         // position of the fist bit
8029};
8030
8031static struct NF_MASKS service_masks[] = {
8032        {"FORWARD", 1, 31},
8033        {"HOTSPOT", 8, 23},
8034        {"QOS", 13, 10},
8035};
8036
8037char *get_NFServiceMark(char *service, uint32 mark)
8038{
8039        static char buffer[24];
8040        bzero(&buffer, sizeof(buffer));
8041
8042#if defined(ARCH_broadcom) && !defined(HAVE_BCMMODERN)
8043// no mask support possible in kernel 2.4
8044        sprintf(buffer, "0x%x", mark);
8045        return buffer;
8046#else
8047        int x, offset, bitpos;
8048        uint32 nfmark = 0, nfmask = 0;
8049
8050        for (x = 0; x < sizeof(service_masks) / sizeof(struct NF_MASKS); x++) {
8051                if (strcmp(service, service_masks[x].service_name) == 0) {
8052                        if (mark >= (1 << service_masks[x].bits_used))
8053                                return "0xffffffff/0xffffffff";
8054
8055                        offset = service_masks[x].bit_offset;
8056                        bitpos = offset + service_masks[x].bits_used - 1;
8057
8058                        nfmark = (mark << offset);
8059
8060                        for (; bitpos >= offset; bitpos--)
8061                                nfmask |= (1 << bitpos);
8062
8063                        sprintf(buffer, "0x%x/0x%x", nfmark, nfmask);
8064                        return buffer;
8065                }
8066        }
8067        return "0xffffffff/0xffffffff";
8068#endif
8069}
8070
8071char *qos_nfmark(uint32 x)
8072{
8073        return get_NFServiceMark("QOS", x);
8074}
8075
8076void getPortMapping(int *vlanmap)
8077{
8078        if (nvram_match("vlan1ports", "0 5")) {
8079                vlanmap[0] = 0;
8080                vlanmap[5] = 5;
8081                if (nvram_match("vlan0ports", "4 3 2 1 5*")) {
8082                        vlanmap[1] = 4;
8083                        vlanmap[2] = 3;
8084                        vlanmap[3] = 2;
8085                        vlanmap[4] = 1;
8086                } else if (nvram_match("vlan0ports", "4 1 2 3 5*")) {
8087                        vlanmap[1] = 4;
8088                        vlanmap[2] = 1;
8089                        vlanmap[3] = 2;
8090                        vlanmap[4] = 3;
8091                } else          // nvram_match ("vlan0ports", "1 2 3 4 5*")
8092                        // nothing to do
8093                {
8094                }
8095        } else if (nvram_match("vlan2ports", "0 5u")) {
8096                vlanmap[0] = 0;
8097                vlanmap[5] = 5;
8098                if (nvram_match("vlan1ports", "4 3 2 1 5*")) {
8099                        vlanmap[1] = 4;
8100                        vlanmap[2] = 3;
8101                        vlanmap[3] = 2;
8102                        vlanmap[4] = 1;
8103                } else if (nvram_match("vlan1ports", "4 1 2 3 5*")) {
8104                        vlanmap[1] = 4;
8105                        vlanmap[2] = 1;
8106                        vlanmap[3] = 2;
8107                        vlanmap[4] = 3;
8108                }
8109                if (nvram_match("vlan1ports", "4 3 2 1 5*") && nvram_matchi("boardnum", 32)) {  //R7000
8110                        vlanmap[1] = 1;
8111                        vlanmap[2] = 2;
8112                        vlanmap[3] = 3;
8113                        vlanmap[4] = 4;
8114                }
8115        } else if (nvram_match("vlan1ports", "4 5")) {
8116                vlanmap[0] = 4;
8117                vlanmap[5] = 5;
8118                if (nvram_match("vlan0ports", "0 1 2 3 5*")) {
8119                        vlanmap[1] = 0;
8120                        vlanmap[2] = 1;
8121                        vlanmap[3] = 2;
8122                        vlanmap[4] = 3;
8123                } else          // nvram_match ("vlan0ports", "3 2 1 0 5*")
8124                {
8125                        vlanmap[1] = 3;
8126                        vlanmap[2] = 2;
8127                        vlanmap[3] = 1;
8128                        vlanmap[4] = 0;
8129                }
8130        } else if (nvram_match("vlan1ports", "1 5")) {  // Linksys WTR54GS
8131                vlanmap[5] = 5;
8132                vlanmap[0] = 1;
8133                vlanmap[1] = 0;
8134        } else if (nvram_match("vlan2ports", "0 8") || nvram_match("vlan2ports", "0 8u") || nvram_match("vlan2ports", "0 8t") || nvram_match("vlan2ports", "0 8*")) {
8135                vlanmap[0] = 0;
8136                vlanmap[5] = 8;
8137                if (nvram_match("vlan1ports", "4 3 2 1 8*")) {
8138                        vlanmap[1] = 4;
8139                        vlanmap[2] = 3;
8140                        vlanmap[3] = 2;
8141                        vlanmap[4] = 1;
8142                }
8143        } else if (nvram_match("vlan2ports", "4 8") || nvram_match("vlan2ports", "4 8u")) {
8144                vlanmap[0] = 4;
8145                vlanmap[5] = 8;
8146                if (nvram_match("vlan1ports", "0 1 2 3 8*")) {
8147                        vlanmap[1] = 0;
8148                        vlanmap[2] = 1;
8149                        vlanmap[3] = 2;
8150                        vlanmap[4] = 3;
8151                } else          // "3 2 1 0 8*"
8152                {
8153                        vlanmap[1] = 3;
8154                        vlanmap[2] = 2;
8155                        vlanmap[3] = 1;
8156                        vlanmap[4] = 0;
8157                }
8158                if (nvram_match("vlan1ports", "0 1 2 3 8*") && nvram_matchi("boardnum", 4536)) {        // WNDR4500/WNDR4500V2/R6300V1
8159                        vlanmap[1] = 3;
8160                        vlanmap[2] = 2;
8161                        vlanmap[3] = 1;
8162                        vlanmap[4] = 0;
8163                }
8164                if (nvram_match("vlan1ports", "3 2 1 0 5 7 8*") && nvram_matchi("boardnum", 32)) {
8165                        vlanmap[1] = 0;
8166                        vlanmap[2] = 1;
8167                        vlanmap[3] = 2;
8168                        vlanmap[4] = 3;
8169                }
8170        } else if (nvram_match("vlan1ports", "4 8")) {
8171                vlanmap[0] = 4;
8172                vlanmap[5] = 8;
8173                if (nvram_match("vlan2ports", "0 1 2 3 8*")) {
8174                        vlanmap[1] = 0;
8175                        vlanmap[2] = 1;
8176                        vlanmap[3] = 2;
8177                        vlanmap[4] = 3;
8178                }
8179        } else if (nvram_match("vlan2ports", "4 5") || nvram_match("vlan2ports", "4 5u")) {
8180                vlanmap[0] = 4;
8181                vlanmap[5] = 5;
8182                if (nvram_match("vlan1ports", "0 1 2 3 5*")) {
8183                        vlanmap[1] = 0;
8184                        vlanmap[2] = 1;
8185                        vlanmap[3] = 2;
8186                        vlanmap[4] = 3;
8187                } else {        // nvram_match ("vlan1ports", "3 2 1 0 5*")
8188                        vlanmap[1] = 3;
8189                        vlanmap[2] = 2;
8190                        vlanmap[3] = 1;
8191                        vlanmap[4] = 0;
8192                }
8193                if (nvram_match("vlan1ports", "0 1 2 3 5*") && nvram_matchi("boardnum", 679)) { //R6300V2
8194                        vlanmap[1] = 3;
8195                        vlanmap[2] = 2;
8196                        vlanmap[3] = 1;
8197                        vlanmap[4] = 0;
8198                }
8199
8200        } else if (nvram_match("vlan2ports", "0 5u")) {
8201                vlanmap[0] = 0;
8202                vlanmap[5] = 5;
8203
8204                vlanmap[1] = 1;
8205                vlanmap[2] = 2;
8206                vlanmap[3] = 3;
8207                vlanmap[4] = 4;
8208        }
8209
8210}
8211
8212u_int64_t freediskSpace(char *path)
8213{
8214        struct statfs sizefs;
8215
8216        if ((statfs(path, &sizefs) != 0) || (sizefs.f_type == 0x73717368) || (sizefs.f_type == 0x74717368) || (sizefs.f_type == 0x68737174)) {
8217                bzero(&sizefs, sizeof(sizefs));
8218        }
8219
8220        return (u_int64_t)sizefs.f_bsize * (u_int64_t)sizefs.f_bfree;
8221}
8222
8223void getSystemMac(char *newmac)
8224{
8225        int brand = getRouterBrand();
8226        switch (brand) {
8227        case ROUTER_ASUS_AC87U:
8228        case ROUTER_ASUS_AC88U:
8229        case ROUTER_ASUS_AC5300:
8230                strcpy(newmac, nvram_safe_get("et1macaddr"));
8231                break;
8232        case ROUTER_NETGEAR_R8000:
8233        case ROUTER_NETGEAR_R8500:
8234        case ROUTER_TRENDNET_TEW828:
8235        case ROUTER_ASUS_AC3100:
8236                strcpy(newmac, nvram_safe_get("et2macaddr"));
8237                break;
8238        case ROUTER_DLINK_DIR885:
8239                if (nvram_get("et0macaddr"))
8240                        strcpy(newmac, nvram_safe_get("et0macaddr"));
8241                else
8242                        strcpy(newmac, nvram_safe_get("et2macaddr"));
8243                break;
8244        default:
8245                strcpy(newmac, nvram_safe_get("et0macaddr"));
8246                break;
8247        }
8248
8249}
8250
8251void strcpyto(char *dest, char *src, char c)
8252{
8253        int cnt = 0;
8254        int len = strlen(src);
8255        while (cnt < len && src[cnt] != c) {
8256                dest[cnt] = src[cnt];
8257                cnt++;
8258        }
8259        dest[cnt] = '\0';
8260}
8261
8262char *chomp(char *s)
8263{
8264        char *c = (s) + strlen((s)) - 1;
8265        while ((c > (s)) && (*c == '\n' || *c == '\r' || *c == ' '))
8266                *c-- = '\0';
8267        return s;
8268}
8269
8270char *foreach_first(char *foreachwordlist, char *word)
8271{
8272        char *next = &foreachwordlist[strspn(foreachwordlist, " ")];
8273        strcpyto(word, next, ' ');
8274        next = strchr(next, ' ');
8275        return next;
8276}
8277
8278char *foreach_last(char *next, char *word)
8279{
8280        next = next ? &next[strspn(next, " ")] : "";
8281        strcpyto(word, next, ' ');
8282        next = strchr(next, ' ');
8283        return next;
8284}
8285
8286#define MAX_BRIDGES     1024
8287
8288#include <linux/if_bridge.h>
8289int isbridge(char *name)
8290{
8291        int i, num;
8292        char ifname[IFNAMSIZ];
8293        int ifindices[MAX_BRIDGES];
8294        int br_socket_fd = -1;
8295        unsigned long args[3] = { BRCTL_GET_BRIDGES,
8296                (unsigned long)ifindices, MAX_BRIDGES
8297        };
8298
8299        if ((br_socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
8300                return 0;
8301
8302        num = ioctl(br_socket_fd, SIOCGIFBR, args);
8303        close(br_socket_fd);
8304        if (num < 0) {
8305                return 0;
8306        }
8307
8308        for (i = 0; i < num; i++) {
8309                if (!if_indextoname(ifindices[i], ifname)) {
8310                        return 0;
8311                }
8312
8313                if (!strcmp(ifname, name))
8314                        return 1;
8315        }
8316        return 0;
8317
8318}
8319
8320int writeint(char *path, int a)
8321{
8322        int fd = open(path, O_WRONLY);
8323        if (fd == -1)
8324                return -1;
8325        char strval[32];
8326        snprintf(strval, sizeof(strval), "%d", a);
8327        write(fd, strval, strlen(strval));
8328        close(fd);
8329        return 0;
8330}
8331
8332int writestr(char *path, char *a)
8333{
8334        int fd = open(path, O_WRONLY);
8335        if (fd == -1)
8336                return -1;
8337        write(fd, a, strlen(a));
8338        close(fd);
8339        return 0;
8340}
8341
8342#if 0
8343int isbridge(char *name)
8344{
8345        char path[64];
8346        struct stat st;
8347        bzero(&st, sizeof(struct stat));
8348        sprintf(path, "/sys/class/net/%s/bridge", name);
8349        return (stat(path, &st) == 0) && (S_ISDIR(st.st_mode));
8350
8351}
8352#endif
8353
8354#if defined(HAVE_X86) || defined(HAVE_RB600) || defined(HAVE_EROUTER) && !defined(HAVE_WDR4900)
8355char *getdisc(void)             // works only for squashfs
8356{
8357        int i;
8358        static char ret[8];
8359        char *disks[] = { "sda2", "sdb2", "sdc2", "sdd2", "sde2", "sdf2", "sdg2", "sdh2",
8360                "sdi2", "mmcblk0p2"
8361        };
8362        for (i = 0; i < 10; i++) {
8363                char dev[64];
8364
8365                sprintf(dev, "/dev/%s", disks[i]);
8366                FILE *in = fopen(dev, "rb");
8367
8368                if (in == NULL)
8369                        continue;       // no second partition or disc does not
8370                // exist, skipping
8371                char buf[4];
8372
8373                fread(buf, 4, 1, in);
8374                if ((buf[0] == 't' && buf[1] == 'q' && buf[2] == 's' && buf[3] == 'h')
8375                    || (buf[0] == 'h' && buf[1] == 's' && buf[2] == 'q' && buf[3] == 't')
8376                    || (buf[0] == 'h' && buf[1] == 's' && buf[2] == 'q' && buf[3] == 's')) {
8377                        fclose(in);
8378                        // filesystem detected
8379                        bzero(ret, 8);
8380                        if (strlen(disks[i]) == 4)
8381                                strncpy(ret, disks[i], 3);
8382                        else
8383                                strncpy(ret, disks[i], 7);
8384                        return ret;
8385                }
8386                fclose(in);
8387        }
8388        return NULL;
8389}
8390#endif
Note: See TracBrowser for help on using the repository browser.