source: src/router/libutils/utils.c

Last change on this file was 32737, checked in by brainslayer, 7 days ago

fix small typo

File size: 234.3 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, "Marvell Armada 370/XP");
5272        } else {
5273                strcpy(buf, "Marvell 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                connected_gpio = 0x103;
5896                disconnected_gpio = 0x104;
5897                diag_gpio = 0x108;
5898                power_gpio = 0x110;
5899                usb_gpio = 0x10c;
5900                usb_gpio1 = 0x10e;
5901                break;
5902        case ROUTER_DIR860LB1:
5903                power_gpio = 0x10f;
5904                diag_gpio = 0x10d;
5905                diag_gpio_disabled = 0x10f;
5906                disconnected_gpio = 0x10e;
5907                connected_gpio = 0x110;
5908                break;
5909        case ROUTER_DIR810L:
5910                power_gpio = 0x009;
5911                diag_gpio = 0x00d;
5912                diag_gpio_disabled = 0x009;
5913                connected_gpio = 0x128;
5914                disconnected_gpio = 0x00c;
5915                break;
5916        case ROUTER_WHR300HP2:
5917                power_gpio = 0x109;
5918                diag_gpio = 0x107;
5919                diag_gpio_disabled = 0x109;
5920                wlan0_gpio = 0x108;
5921                sec0_gpio = 0x10a;
5922                ses_gpio = 0x10a;
5923                connected_gpio = 0x139;
5924                disconnected_gpio = 0x13b;
5925                break;
5926        case ROUTER_BOARD_WHRG300N:
5927                diag_gpio = 0x107;
5928                connected_gpio = 0x109;
5929                ses_gpio = 0x10e;
5930                break;
5931#ifdef HAVE_WNR2200
5932        case ROUTER_BOARD_WHRHPGN:
5933                power_gpio = 0x122;
5934                diag_gpio = 0x121;
5935                connected_gpio = 0x107;
5936                usb_power = 0x024;      // enable usb port
5937                ses_gpio = 0x105;       //correct state missing
5938                usb_gpio = 0x108;
5939//              sec0_gpio = 0x104;
5940                break;
5941#elif HAVE_WNR2000
5942        case ROUTER_BOARD_WHRHPGN:
5943                power_gpio = 0x123;
5944                diag_gpio = 0x122;
5945                connected_gpio = 0x100;
5946//              ses_gpio = 0x104;
5947//              sec0_gpio = 0x104;
5948                break;
5949#elif HAVE_WLAEAG300N
5950        case ROUTER_BOARD_WHRHPGN:
5951                power_gpio = 0x110;
5952                diag_gpio = 0x111;
5953                connected_gpio = 0x106;
5954                ses_gpio = 0x10e;
5955                sec0_gpio = 0x10e;
5956                break;
5957#elif HAVE_CARAMBOLA
5958#ifdef HAVE_ERC
5959        case ROUTER_BOARD_WHRHPGN:
5960                vpn_gpio = 0x11B;
5961                wlan0_gpio = 0x000;
5962                break;
5963#else
5964        case ROUTER_BOARD_WHRHPGN:
5965//              usb_power = 0x01a;
5966//              usb_gpio = 0x001;
5967//              ses_gpio = 0x11b;
5968                break;
5969#endif
5970#elif HAVE_HORNET
5971        case ROUTER_BOARD_WHRHPGN:
5972                usb_power = 0x01a;
5973                usb_gpio = 0x001;
5974                ses_gpio = 0x11b;
5975                break;
5976#elif HAVE_RB2011
5977        case ROUTER_BOARD_WHRHPGN:
5978//              diag_gpio = 0x10f;
5979//              connected_gpio = 0x112;
5980//              disconnected_gpio = 0x113;
5981//              power_gpio = 0x10e;
5982//              usb_power = 0x01a;
5983//              usb_gpio = 0x10b;
5984//              ses_gpio = 0x11b;
5985                break;
5986#elif HAVE_WDR3500
5987        case ROUTER_BOARD_WHRHPGN:
5988                usb_gpio = 0x10b;
5989                usb_power = 0x00f;
5990                diag_gpio = 0x10e;
5991                connected_gpio = 0x10f;
5992                break;
5993#elif HAVE_WDR4300
5994        case ROUTER_BOARD_WHRHPGN:
5995                usb_gpio = 0x10b;
5996                usb_gpio1 = 0x10c;
5997                usb_power = 0x015;
5998                usb_power1 = 0x016;
5999                diag_gpio = 0x10e;
6000                connected_gpio = 0x10f;
6001                break;
6002#elif HAVE_WNDR3700V4
6003        case ROUTER_BOARD_WHRHPGN:
6004                diag_gpio = 0x102;
6005                power_gpio = 0x100;
6006                connected_gpio = 0x101;
6007                disconnected_gpio = 0x103;
6008                usb_power = 0x020;
6009                usb_gpio = 0x10d;
6010                ses_gpio = 0x110;
6011                break;
6012#elif HAVE_DAP3662
6013        case ROUTER_BOARD_WHRHPGN:
6014                diag_gpio = 0x10e;      // red
6015                diag_gpio_disabled = 0x117;     //
6016                power_gpio = 0x117;     // green
6017                break;
6018#elif HAVE_DIR862
6019        case ROUTER_BOARD_WHRHPGN:
6020                diag_gpio = 0x10e;      // orange
6021                diag_gpio_disabled = 0x113;     //
6022                power_gpio = 0x113;     // green
6023                connected_gpio = 0x116; // green
6024                disconnected_gpio = 0x117;      // orange
6025                break;
6026#elif HAVE_MMS344
6027        case ROUTER_BOARD_WHRHPGN:
6028                diag_gpio = 0x10e;
6029                break;
6030#elif HAVE_ARCHERC7
6031        case ROUTER_BOARD_WHRHPGN:
6032                diag_gpio = 0x10e;
6033                ses_gpio = 0x10f;
6034                sec0_gpio = 0x10f;
6035
6036                usb_power = 0x016;
6037                usb_gpio = 0x112;
6038
6039                usb_power1 = 0x015;
6040                usb_gpio1 = 0x113;
6041
6042                usb_gpio = 0x10f;
6043                break;
6044#elif HAVE_WR1043V2
6045        case ROUTER_BOARD_WHRHPGN:
6046                diag_gpio = 0x113;
6047//              connected_gpio = 0x112;
6048//              disconnected_gpio = 0x113;
6049//              power_gpio = 0x10e;
6050                usb_power = 0x015;
6051                usb_gpio = 0x10f;
6052                ses_gpio = 0x112;
6053                sec0_gpio = 0x112;
6054                break;
6055#elif HAVE_WZR450HP2
6056        case ROUTER_BOARD_WHRHPGN:
6057                diag_gpio = 0x114;
6058//              connected_gpio = 0x112;
6059//              disconnected_gpio = 0x113;
6060//              power_gpio = 0x10e;
6061//              usb_power = 0x01a;
6062//              usb_gpio = 0x10b;
6063
6064                connected_gpio = 0x10d;
6065                power_gpio = 0x113;
6066                ses_gpio = 0x103;
6067                sec0_gpio = 0x103;
6068                break;
6069#elif HAVE_DHP1565
6070        case ROUTER_BOARD_WHRHPGN:
6071                diag_gpio = 0x10e;
6072                diag_gpio_disabled = 0x116;
6073                connected_gpio = 0x112;
6074                disconnected_gpio = 0x113;
6075                power_gpio = 0x116;
6076                usb_gpio = 0x10b;
6077                ses_gpio = 0x10f;
6078                break;
6079#elif HAVE_E325N
6080        case ROUTER_BOARD_WHRHPGN:
6081                connected_gpio = 0x003;
6082                disconnected_gpio = 0x002;
6083                break;
6084#elif HAVE_XD3200
6085        case ROUTER_BOARD_WHRHPGN:
6086                break;
6087#elif HAVE_E380AC
6088        case ROUTER_BOARD_WHRHPGN:
6089                diag_gpio = 0x003;
6090                break;
6091#elif HAVE_WR615N
6092        case ROUTER_BOARD_WHRHPGN:
6093                diag_gpio = 0x101;
6094                connected_gpio = 0x102;
6095                disconnected_gpio = 0x103;
6096                ses_gpio = 0x10c;
6097                sec0_gpio = 0x10c;
6098                break;
6099#elif HAVE_E355AC
6100        case ROUTER_BOARD_WHRHPGN:
6101                diag_gpio = 0x002;
6102                break;
6103#elif HAVE_WR650AC
6104        case ROUTER_BOARD_WHRHPGN:
6105                ses_gpio = 0x114;
6106                sec0_gpio = 0x114;
6107                connected_gpio = 0x104;
6108                diag_gpio = 0x004;
6109                break;
6110#elif HAVE_DIR869
6111        case ROUTER_BOARD_WHRHPGN:
6112                disconnected_gpio = 0x10f;
6113                connected_gpio = 0x110;
6114                diag_gpio = 0x00f;
6115                break;
6116#elif HAVE_DIR859
6117        case ROUTER_BOARD_WHRHPGN:
6118                power_gpio = 0x10f;
6119                connected_gpio = 0x110;
6120                diag_gpio = 0x00f;
6121                break;
6122#elif HAVE_JWAP606
6123        case ROUTER_BOARD_WHRHPGN:
6124                diag_gpio = 0x10b;
6125                connected_gpio = 0x10d;
6126                disconnected_gpio = 0x10d;
6127                power_gpio = 0x10b;
6128//              usb_power = 0x01a;
6129//              usb_gpio = 0x10b;
6130//              ses_gpio = 0x11b;
6131                break;
6132#elif HAVE_DIR825C1
6133        case ROUTER_BOARD_WHRHPGN:
6134                diag_gpio = 0x10f;
6135                connected_gpio = 0x112;
6136                disconnected_gpio = 0x113;
6137                power_gpio = 0x10e;
6138//              usb_power = 0x01a;
6139                usb_gpio = 0x10b;
6140//              ses_gpio = 0x11b;
6141                break;
6142#elif HAVE_WDR2543
6143        case ROUTER_BOARD_WHRHPGN:
6144                diag_gpio = 0x100;
6145                usb_gpio = 0x108;
6146                break;
6147#elif HAVE_WASP
6148        case ROUTER_BOARD_WHRHPGN:
6149//              usb_power = 0x01a;
6150//              usb_gpio = 0x001;
6151//              ses_gpio = 0x11b;
6152                break;
6153#else
6154        case ROUTER_BOARD_WHRHPGN:
6155                diag_gpio = 0x101;
6156                connected_gpio = 0x106;
6157                ses_gpio = 0x100;
6158                sec0_gpio = 0x100;
6159                break;
6160#endif
6161        case ROUTER_BUFFALO_WBR54G:
6162                diag_gpio = 0x107;
6163                break;
6164        case ROUTER_BUFFALO_WBR2G54S:
6165                diag_gpio = 0x001;
6166                ses_gpio = 0x006;
6167                break;
6168        case ROUTER_BUFFALO_WLA2G54C:
6169                diag_gpio = 0x104;
6170                ses_gpio = 0x103;
6171                break;
6172        case ROUTER_BUFFALO_WLAH_G54:
6173                diag_gpio = 0x107;
6174                ses_gpio = 0x106;
6175                break;
6176        case ROUTER_BUFFALO_WAPM_HP_AM54G54:
6177                diag_gpio = 0x107;
6178                ses_gpio = 0x101;
6179                break;
6180        case ROUTER_BOARD_WHRAG108:
6181                diag_gpio = 0x107;
6182                bridge_gpio = 0x104;
6183                ses_gpio = 0x100;
6184                break;
6185        case ROUTER_BUFFALO_WHRG54S:
6186        case ROUTER_BUFFALO_WLI_TX4_G54HP:
6187                diag_gpio = 0x107;
6188                if (nvram_match("DD_BOARD", "Buffalo WHR-G125")) {
6189                        connected_gpio = 0x101;
6190                        sec0_gpio = 0x106;
6191                } else {
6192                        bridge_gpio = 0x101;
6193                        ses_gpio = 0x106;
6194                }
6195                break;
6196        case ROUTER_UBNT_UNIFIAC:
6197                power_gpio = 0x00e;
6198                diag_gpio = 0x00f;
6199                break;
6200        case ROUTER_D1800H:
6201                usb_gpio = 0x101;
6202                usb_power = 0x007;
6203                power_gpio = 0x002;
6204                diag_gpio = 0x00d;
6205                diag_gpio_disabled = 0x002;
6206                connected_gpio = 0x10f;
6207                disconnected_gpio = 0x10e;
6208                break;
6209        case ROUTER_BUFFALO_WZRRSG54:
6210                diag_gpio = 0x107;
6211                vpn_gpio = 0x101;
6212                ses_gpio = 0x106;
6213                break;
6214        case ROUTER_BUFFALO_WZRG300N:
6215                diag_gpio = 0x107;
6216                bridge_gpio = 0x101;
6217                break;
6218        case ROUTER_BUFFALO_WZRG144NH:
6219                diag_gpio = 0x103;
6220                bridge_gpio = 0x101;
6221                ses_gpio = 0x102;
6222                break;
6223        case ROUTER_BUFFALO_WZR900DHP:
6224        case ROUTER_BUFFALO_WZR600DHP2:
6225//              usb_power = 0x009;      // USB 2.0 ehci port
6226                usb_power1 = 0x10a;     // USB 3.0 xhci port
6227//              wlan0_gpio = 0x028; // wireless orange
6228//              wlan1_gpio = 0x029; // wireless blue
6229                connected_gpio = 0x02a; // connected blue
6230                sec0_gpio = 0x02b;
6231                sec1_gpio = 0x02c;
6232                // 0x2b strange led orange
6233                // 0x2c strange led blue
6234                power_gpio = 0x02e;
6235                diag_gpio = 0x02d;
6236                diag_gpio_disabled = 0x02e;
6237                usb_gpio = 0x02f;
6238                break;
6239
6240        case ROUTER_BUFFALO_WXR1900DHP:
6241                usb_power = 0x00d;      // USB 2.0 ehci port
6242                usb_power1 = 0x00e;     // USB 3.0 xhci port
6243//              wlan0_gpio = 0x028; // wireless orange
6244//              wlan1_gpio = 0x029; // wireless blue
6245                connected_gpio = 0x009; // connected blue
6246                disconnected_gpio = 0x00a;      // connected blue
6247                sec0_gpio = 0x00b;
6248                sec1_gpio = 0x00b;
6249                // 0x2b strange led orange
6250                // 0x2c strange led blue
6251                power_gpio = 0x006;
6252                diag_gpio = 0x005;
6253                diag_gpio_disabled = 0x006;
6254                break;
6255
6256        case ROUTER_BUFFALO_WZR1750:
6257                usb_power = 0x009;      // USB 2.0 ehci port
6258                usb_power1 = 0x10a;     // USB 3.0 xhci port
6259//              wlan0_gpio = 0x028; // wireless orange
6260//              wlan1_gpio = 0x029; // wireless blue
6261                connected_gpio = 0x02a; // connected blue
6262                sec0_gpio = 0x02b;
6263                sec1_gpio = 0x02c;
6264                // 0x2b strange led orange
6265                // 0x2c strange led blue
6266                power_gpio = 0x02d;
6267                diag_gpio = 0x02e;
6268                diag_gpio_disabled = 0x02d;
6269                usb_gpio = 0x02f;
6270                break;
6271#ifndef HAVE_BUFFALO
6272#ifdef HAVE_DIR300
6273        case ROUTER_BOARD_FONERA:
6274                diag_gpio = 0x003;
6275                bridge_gpio = 0x004;
6276                ses_gpio = 0x001;
6277                break;
6278#endif
6279#ifdef HAVE_WRT54G2
6280        case ROUTER_BOARD_FONERA:
6281                bridge_gpio = 0x004;
6282                ses_gpio = 0x104;
6283                diag_gpio = 0x103;
6284                break;
6285#endif
6286#ifdef HAVE_RTG32
6287        case ROUTER_BOARD_FONERA:
6288                break;
6289#endif
6290#ifdef HAVE_BWRG1000
6291        case ROUTER_BOARD_LS2:
6292                diag_gpio = 0x007;
6293                break;
6294#endif
6295#ifdef HAVE_DIR400
6296        case ROUTER_BOARD_FONERA2200:
6297                diag_gpio = 0x003;
6298                bridge_gpio = 0x004;
6299                ses_gpio = 0x001;
6300                break;
6301#endif
6302#ifdef HAVE_WRK54G
6303        case ROUTER_BOARD_FONERA:
6304                diag_gpio = 0x107;
6305                dmz_gpio = 0x005;
6306                break;
6307#endif
6308        case ROUTER_BOARD_TW6600:
6309                diag_gpio = 0x107;
6310                bridge_gpio = 0x104;
6311                ses_gpio = 0x100;
6312                break;
6313        case ROUTER_MOTOROLA:
6314                power_gpio = 0x001;
6315                diag_gpio = 0x101;      // power led blink / off to indicate factory
6316                // defaults
6317                break;
6318        case ROUTER_RT210W:
6319                power_gpio = 0x105;
6320                diag_gpio = 0x005;      // power led blink / off to indicate factory
6321                // defaults
6322                connected_gpio = 0x100;
6323                wlan0_gpio = 0x103;
6324                break;
6325        case ROUTER_RT480W:
6326        case ROUTER_BELKIN_F5D7230_V2000:
6327        case ROUTER_BELKIN_F5D7231:
6328                power_gpio = 0x105;
6329                diag_gpio = 0x005;      // power led blink / off to indicate factory
6330                // defaults
6331                connected_gpio = 0x100;
6332                break;
6333        case ROUTER_MICROSOFT_MN700:
6334                power_gpio = 0x006;
6335                diag_gpio = 0x106;      // power led blink / off to indicate factory
6336                // defaults
6337                break;
6338        case ROUTER_ASUS_WL500GD:
6339        case ROUTER_ASUS_WL520GUGC:
6340                diag_gpio = 0x000;      // power led blink / off to indicate factory
6341                // defaults
6342                break;
6343        case ROUTER_ASUS_WL500G_PRE:
6344        case ROUTER_ASUS_WL700GE:
6345                power_gpio = 0x101;
6346                diag_gpio = 0x001;      // power led blink / off to indicate factory
6347                // defaults
6348                break;
6349        case ROUTER_ASUS_WL550GE:
6350                power_gpio = 0x102;
6351                diag_gpio = 0x002;      // power led blink / off to indicate factory
6352                // defaults
6353                break;
6354        case ROUTER_WRT54G3G:
6355        case ROUTER_WRTSL54GS:
6356                power_gpio = 0x001;
6357                dmz_gpio = 0x100;
6358                connected_gpio = 0x107; // ses orange
6359                ses_gpio = 0x105;       // ses white
6360                ses2_gpio = 0x107;      // ses orange
6361                break;
6362        case ROUTER_MOTOROLA_WE800G:
6363        case ROUTER_MOTOROLA_V1:
6364                diag_gpio = 0x103;
6365                wlan0_gpio = 0x101;
6366                bridge_gpio = 0x105;
6367                break;
6368        case ROUTER_DELL_TRUEMOBILE_2300:
6369        case ROUTER_DELL_TRUEMOBILE_2300_V2:
6370                power_gpio = 0x107;
6371                diag_gpio = 0x007;      // power led blink / off to indicate factory
6372                // defaults
6373                wlan0_gpio = 0x106;
6374                break;
6375        case ROUTER_NETGEAR_WNR834B:
6376                power_gpio = 0x104;
6377                diag_gpio = 0x105;
6378                wlan0_gpio = 0x106;
6379                break;
6380        case ROUTER_SITECOM_WL105B:
6381                power_gpio = 0x003;
6382                diag_gpio = 0x103;      // power led blink / off to indicate factory
6383                // defaults
6384                wlan0_gpio = 0x104;
6385                break;
6386        case ROUTER_WRT300N:
6387                power_gpio = 0x001;
6388                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6389                break;
6390        case ROUTER_WRT150N:
6391                power_gpio = 0x001;
6392                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6393                sec0_gpio = 0x105;
6394                break;
6395        case ROUTER_WRT300NV11:
6396                ses_gpio = 0x105;
6397                sec0_gpio = 0x103;
6398                // diag_gpio = 0x11; //power led blink / off to indicate fac.def.
6399                break;
6400        case ROUTER_WRT310N:
6401                connected_gpio = 0x103; //ses orange
6402                power_gpio = 0x001;
6403                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6404                ses_gpio = 0x109;       // ses blue
6405                break;
6406        case ROUTER_WRT310NV2:
6407                connected_gpio = 0x102; // ses orange
6408                power_gpio = 0x001;
6409                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6410                ses_gpio = 0x104;       // ses blue
6411                break;
6412        case ROUTER_WRT160N:
6413                power_gpio = 0x001;
6414                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6415                connected_gpio = 0x103; // ses orange
6416                ses_gpio = 0x105;       // ses blue
6417                break;
6418        case ROUTER_WRT160NV3:
6419                power_gpio = 0x001;
6420                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
6421                connected_gpio = 0x102; // ses orange
6422                ses_gpio = 0x104;       // ses blue
6423                break;
6424        case ROUTER_LINKSYS_E800:
6425        case ROUTER_LINKSYS_E900:
6426        case ROUTER_LINKSYS_E1500:
6427        case ROUTER_LINKSYS_E1550:
6428                power_gpio = 0x106;
6429                diag_gpio = 0x006;      // power led blink / off to indicate fac.def.
6430                ses_gpio = 0x108;       // ses blue
6431                break;
6432        case ROUTER_LINKSYS_E1000V2:
6433                power_gpio = 0x106;
6434                diag_gpio = 0x006;      // power led blink / off to indicate fac.def.
6435                connected_gpio = 0x007; // ses orange
6436                ses_gpio = 0x008;       // ses blue
6437                break;
6438        case ROUTER_LINKSYS_E2500:
6439                power_gpio = 0x106;
6440                diag_gpio = 0x006;      // power led blink / off to indicate fac.def.
6441                break;
6442        case ROUTER_LINKSYS_E3200:
6443                power_gpio = 0x103;
6444                diag_gpio = 0x003;      // power led blink / off to indicate fac.def.
6445                break;
6446        case ROUTER_LINKSYS_E4200:
6447                power_gpio = 0x105;     // white LED1
6448                diag_gpio = 0x103;      // power led blink / off to indicate fac.def.
6449//              connected_gpio = 0x103; // white LED2
6450                break;
6451        case ROUTER_LINKSYS_EA6500:
6452                diag_gpio = 0x101;      // white led blink / off to indicate fac.def.
6453                break;
6454        case ROUTER_LINKSYS_EA6500V2:
6455        case ROUTER_LINKSYS_EA6700:
6456        case ROUTER_LINKSYS_EA6400:
6457        case ROUTER_LINKSYS_EA6350:
6458        case ROUTER_LINKSYS_EA6900:
6459                usb_power = 0x009;      //usb power on/off
6460                usb_power1 = 0x00a;     //usb power on/off
6461                diag_gpio = 0x106;      // white led blink / off to indicate fac.def.
6462                connected_gpio = 0x008;
6463                break;
6464        case ROUTER_LINKSYS_EA8500:
6465                power_gpio = 0x100;     // power led
6466                diag_gpio = 0x000;      // power led orange     
6467                wlan0_gpio = 0x001;     // radio 0 
6468                ses_gpio = 0x102;       // wps led
6469                break;
6470        case ROUTER_ASUS_WL500G:
6471                power_gpio = 0x100;
6472                diag_gpio = 0x000;      // power led blink /off to indicate factory
6473                // defaults
6474                break;
6475        case ROUTER_ASUS_WL500W:
6476                power_gpio = 0x105;
6477                diag_gpio = 0x005;      // power led blink /off to indicate factory
6478                // defaults
6479                break;
6480        case ROUTER_LINKSYS_WTR54GS:
6481                diag_gpio = 0x001;
6482                break;
6483        case ROUTER_WAP54G_V1:
6484                diag_gpio = 0x103;
6485                wlan0_gpio = 0x104;     // LINK led
6486                break;
6487        case ROUTER_WAP54G_V3:
6488                ses_gpio = 0x10c;
6489                connected_gpio = 0x006;
6490                break;
6491        case ROUTER_NETGEAR_WNR834BV2:
6492                power_gpio = 0x002;
6493                diag_gpio = 0x003;      // power led amber
6494                connected_gpio = 0x007; // WAN led green
6495                break;
6496        case ROUTER_NETGEAR_WNDR3300:
6497                power_gpio = 0x005;
6498                diag_gpio = 0x105;      // power led blink /off to indicate factory defaults
6499                connected_gpio = 0x007; // WAN led green
6500                break;
6501        case ROUTER_ASKEY_RT220XD:
6502                wlan0_gpio = 0x100;
6503                dmz_gpio = 0x101;       // not soldered
6504                break;
6505        case ROUTER_WRT610N:
6506                power_gpio = 0x001;
6507                diag_gpio = 0x101;      // power led blink /off to indicate factory defaults
6508                connected_gpio = 0x103; // ses amber
6509                ses_gpio = 0x109;       // ses blue
6510                usb_gpio = 0x100;
6511                break;
6512        case ROUTER_WRT610NV2:
6513                power_gpio = 0x005;
6514                diag_gpio = 0x105;      // power led blink
6515                connected_gpio = 0x100; // ses amber
6516                ses_gpio = 0x103;       // ses blue
6517                usb_gpio = 0x007;
6518                break;
6519        case ROUTER_USR_5461:
6520                usb_gpio = 0x001;
6521                break;
6522        case ROUTER_USR_5465:
6523                //usb_gpio = 0x002; //or 0x001 ??
6524                break;
6525        case ROUTER_NETGEAR_WGR614L:
6526        case ROUTER_NETGEAR_WGR614V9:
6527                // power_gpio = 0x107;       // don't use - resets router
6528                diag_gpio = 0x006;
6529                connected_gpio = 0x104;
6530                break;
6531        case ROUTER_NETGEAR_WG602_V4:
6532                power_gpio = 0x101;     // trick: make lan led green for 100Mbps
6533                break;
6534        case ROUTER_BELKIN_F5D7231_V2000:
6535                connected_gpio = 0x104;
6536                diag_gpio = 0x001;      // power led blink /off to indicate factory defaults
6537                break;
6538        case ROUTER_NETGEAR_WNR3500L:
6539        case ROUTER_NETGEAR_WNR3500LV2:
6540                power_gpio = 0x003;     // power led green
6541                diag_gpio = 0x007;      // power led amber
6542                ses_gpio = 0x001;       // WPS led green
6543                connected_gpio = 0x002; // wan led green
6544                wlan1_gpio = 0x000;     // radio 1 blue led
6545                usb_gpio = 0x014;       // usb power
6546                break;
6547        case ROUTER_NETGEAR_WNDR3400:
6548                power_gpio = 0x003;     //power led green
6549                diag_gpio = 0x007;      // power led amber
6550                connected_gpio = 0x001; //wan led green
6551                usb_gpio = 0x102;       //usb led green
6552                wlan1_gpio = 0x000;     // radio 1 led blue
6553                break;
6554        case ROUTER_NETGEAR_WNDR4000:
6555                power_gpio = 0x000;     //power led green
6556                diag_gpio = 0x001;      // power led amber
6557                connected_gpio = 0x002; //wan led green
6558                wlan0_gpio = 0x003;     //radio 0 led green
6559                wlan1_gpio = 0x004;     // radio 1 led blue
6560                usb_gpio = 0x005;       //usb led green
6561                ses_gpio = 0x106;       // WPS led green - inverse
6562                ses2_gpio = 0x107;      // WLAN led green - inverse
6563                break;
6564        case ROUTER_DLINK_DIR860:
6565                usb_power = 0x00a;
6566                connected_gpio = 0x104;
6567                disconnected_gpio = 0x103;
6568                power_gpio = 0x101;
6569                diag_gpio = 0x100;
6570                diag_gpio_disabled = 0x101;
6571                break;
6572        case ROUTER_DLINK_DIR868:
6573        case ROUTER_DLINK_DIR868C:
6574                usb_power = 0x00a;
6575                connected_gpio = 0x103;
6576                disconnected_gpio = 0x101;
6577                power_gpio = 0x102;
6578                diag_gpio = 0x100;
6579                break;
6580
6581        case ROUTER_DLINK_DIR880:
6582                connected_gpio = 0x103;
6583                disconnected_gpio = 0x101;
6584                power_gpio = 0x102;
6585                diag_gpio = 0x100;
6586                diag_gpio_disabled = 0x102;
6587                usb_gpio = 0x108;
6588                usb_gpio1 = 0x10f;
6589//              wlan0_gpio = 0x10d;
6590//              wlan1_gpio = 0x10e;
6591                usb_power = 0x009;
6592                usb_power1 = 0x00a;
6593                break;
6594        case ROUTER_DLINK_DIR885:
6595                usb_power = 0x012;
6596                usb_gpio = 0x108;
6597                power_gpio = 0x100;
6598                diag_gpio = 0x102;
6599                diag_gpio_disabled = 0x100;
6600                disconnected_gpio = 0x103;
6601                connected_gpio = 0x101;
6602                wlan0_gpio = 0x10d;
6603                wlan1_gpio = 0x10e;
6604                break;
6605        case ROUTER_DLINK_DIR895:
6606                usb_power = 0x015;
6607                usb_power1 = 0x012;
6608                usb_gpio = 0x108;
6609                usb_gpio1 = 0x10f;
6610                power_gpio = 0x100;
6611                diag_gpio = 0x102;
6612                diag_gpio_disabled = 0x100;
6613                disconnected_gpio = 0x103;
6614                connected_gpio = 0x101;
6615                wlan0_gpio = 0x10d;
6616                wlan1_gpio = 0x10e;
6617                break;
6618        case ROUTER_DLINK_DIR890:
6619                usb_power = 0x015;
6620                usb_power1 = 0x012;
6621                usb_gpio = 0x108;
6622                usb_gpio1 = 0x10f;
6623                connected_gpio = 0x101;
6624                disconnected_gpio = 0x103;
6625                power_gpio = 0x102;
6626                diag_gpio = 0x002;
6627                break;
6628        case ROUTER_TRENDNET_TEW828:
6629                usb_gpio = 0x104;
6630                power_gpio = 0x106;
6631                diag_gpio = 0x006;
6632                break;
6633        case ROUTER_TRENDNET_TEW812:
6634                // gpio !1 = 2.4 ghz led
6635                // gpio !2 = 5 ghz led
6636                // gpio !3 = power somthing
6637                // gpio !8 = usb led
6638                //
6639                usb_gpio = 0x108;
6640                diag_gpio = 0x103;
6641                wlan0_gpio = 0x101;
6642                wlan1_gpio = 0x102;
6643                break;
6644        case ROUTER_ASUS_RTN18U:
6645                power_gpio = 0x100;
6646//              usb_power = 0x00d;      //usb power on/off
6647                if (nvram_match("bl_version", "3.0.0.7")) {
6648                        usb_gpio = 0x10e;
6649                        connected_gpio = 0x103;
6650                        disconnected_gpio = 0x106;
6651                } else if (nvram_match("bl_version", "1.0.0.0")) {
6652                        usb_gpio = 0x103;
6653                        connected_gpio = 0x106;
6654                        disconnected_gpio = 0x109;
6655                } else {
6656                        usb_gpio = 0x103;
6657                        usb_gpio1 = 0x10e;
6658                        connected_gpio = 0x106;
6659                        disconnected_gpio = 0x109;
6660                }
6661                break;
6662        case ROUTER_TPLINK_ARCHERC9:
6663                ses_gpio = 0x002;
6664                usb_gpio = 0x006;
6665                usb_gpio1 = 0x007;
6666                disconnected_gpio = 0x00f;
6667                connected_gpio = 0x00e;
6668                power_gpio = 0x112;
6669                diag_gpio = 0x012;
6670                usb_power = 0x00c;      // usb 3
6671                usb_power1 = 0x00d;     // usb 2
6672                break;
6673        case ROUTER_TPLINK_ARCHERC3150:
6674                ses_gpio = 0x002;
6675//              usb_gpio = 0x006;
6676//              usb_gpio1 = 0x007;
6677//              disconnected_gpio = 0x00f;
6678//              connected_gpio = 0x00e;
6679//              power_gpio = 0x112;
6680//              diag_gpio = 0x012;
6681                usb_power = 0x00c;      // usb 3
6682                usb_power1 = 0x00d;     // usb 2
6683                break;
6684        case ROUTER_ASUS_AC67U:
6685        case ROUTER_ASUS_AC56U:
6686                wlan1_gpio = 0x106;
6687                power_gpio = 0x103;
6688                usb_power = 0x009;      //usb power on/off
6689                usb_power1 = 0x00a;     //usb power on/off
6690                usb_gpio = 0x10e;
6691                usb_gpio1 = 0x100;
6692                diag_gpio = 0x003;
6693                connected_gpio = 0x101;
6694                disconnected_gpio = 0x102;
6695                break;
6696        case ROUTER_ASUS_AC3200:
6697                usb_power = 0x009;
6698                power_gpio = 0x103;
6699                connected_gpio = 0x105;
6700                diag_gpio = 0x003;
6701                // wps gpio = 14
6702                break;
6703        case ROUTER_ASUS_AC1200:
6704                usb_power = 0x10a;
6705                diag_gpio = 0x00a;
6706                diag_gpio_disabled = 0x10a;
6707                usb_gpio = 0x10f;
6708                break;
6709        case ROUTER_ASUS_AC88U:
6710        case ROUTER_ASUS_AC3100:
6711        case ROUTER_ASUS_AC5300:
6712                usb_power = 0x009;
6713                usb_gpio = 0x110;
6714                usb_gpio1 = 0x111;
6715                power_gpio = 0x103;
6716                diag_gpio = 0x003;
6717                connected_gpio = 0x005;
6718                disconnected_gpio = 0x115;
6719                ses_gpio = 0x113;
6720                // komisches symbol gpio 21
6721                // quantenna reset 8 inv (off / on to reset)   
6722                break;
6723        case ROUTER_ASUS_AC87U:
6724                usb_power = 0x009;
6725                power_gpio = 0x103;
6726                connected_gpio = 0x105;
6727                ses_gpio = 0x101;
6728                // quantenna reset 8 inv (off / on to reset)   
6729                break;
6730        case ROUTER_NETGEAR_EX6200:
6731                //power_gpio = 0x109;   // connected red
6732                diag_gpio = 0x101;      // Netgear logo
6733                connected_gpio = 0x108; // connected green
6734                wlan1_gpio = 0x10b;     // radio led red 2.4G
6735                wlan0_gpio = 0x10d;     // radio led red 5G
6736                usb_gpio = 0x105;       // usb led
6737                //usb_power = 0x000;    // usb enable
6738                break;
6739        case ROUTER_NETGEAR_AC1450:
6740                power_gpio = 0x102;     // power led green
6741                //diag_gpio = 0x103;    // power led orange
6742                diag_gpio = 0x101;      // Netgear logo
6743                connected_gpio = 0x10a; // wan led green - hw controlled
6744                wlan0_gpio = 0x10b;     // radio led blue
6745                usb_gpio = 0x108;       // usb led
6746                //usb_power = 0x000;    // usb enable
6747                break;
6748        case ROUTER_NETGEAR_R6250:
6749                power_gpio = 0x102;     // power led green
6750                //diag_gpio = 0x103;    // power led orange
6751                diag_gpio = 0x001;      // Netgear logo
6752                //emblem0_gpio = 0x001; // NETGEAR Emblem       
6753                //connected_gpio = 0x10f;       // wan led green
6754                wlan0_gpio = 0x10b;     // radio led blue
6755                usb_gpio = 0x108;       // usb led green
6756                //usb_power = 0x000;    // usb enable
6757                break;
6758        case ROUTER_NETGEAR_R6300:
6759                usb_gpio = 0x108;       //usb led
6760                usb_power = 0x000;      //usb power on/off
6761                connected_gpio = 0x10f; //green led
6762                power_gpio = 0x102;     //power orange led
6763                diag_gpio = 0x103;      //power led orange
6764                //diag_gpio_disabled=0x009;//netgear logo led r
6765                //emblem0_gpio = 0x101;   // NETGEAR Emblem l     
6766                //emblem1_gpio = 0x109;   // NETGEAR Emblem r
6767                wlan0_gpio = 0x10b;     // radio led blue
6768                break;
6769        case ROUTER_NETGEAR_R6300V2:
6770                power_gpio = 0x102;     // power led green
6771                //diag_gpio = 0x103;    // power led orange
6772                diag_gpio = 0x101;      // Netgear logo
6773                connected_gpio = 0x10a; // wan led green - hw controlled
6774                wlan0_gpio = 0x10b;     // radio led blue
6775                usb_gpio = 0x108;       // usb led
6776                //usb_power = 0x000;    // usb enable
6777                break;
6778        case ROUTER_NETGEAR_R6400:
6779                power_gpio = 0x101;     //
6780                connected_gpio = 0x107; //
6781                usb_power = 0x000;      //
6782                diag_gpio = 0x102;      //
6783                wlan0_gpio = 0x109;     // radio 0
6784                wlan1_gpio = 0x108;     // radio 1
6785                ses_gpio = 0x10a;       // wps led
6786                wlan_gpio = 0x10b;      // wifi button led
6787                usb_gpio = 0x10c;       // usb1
6788                usb_gpio1 = 0x10d;      // usb2
6789                break;
6790        case ROUTER_NETGEAR_R7000:
6791                power_gpio = 0x102;     // power led
6792                diag_gpio = 0x103;      // power led orange     
6793                connected_gpio = 0x109; // wan led
6794                usb_power = 0x000;      // usb enable
6795                wlan0_gpio = 0x10d;     // radio 0
6796                wlan1_gpio = 0x10c;     // radio 1
6797                ses_gpio = 0x10e;       // wps led
6798                //wlan_gpio = 0x10f;    // wifi button led
6799                usb_gpio = 0x111;       //usb1
6800                usb_gpio1 = 0x112;      //usb2
6801                break;
6802        case ROUTER_NETGEAR_R7500V2:
6803        case ROUTER_NETGEAR_R7500:
6804                power_gpio = 0x000;     // power led
6805                diag_gpio = 0x00a;      // power led orange     
6806                diag_gpio_disabled = 0x000;     // power led orange     
6807                connected_gpio = 0x007; // wan led
6808                usb_power = 0x010;      // usb enable
6809                usb_power1 = 0x00f;     // usb enable
6810                wlan0_gpio = 0x001;     // radio 0
6811                wlan1_gpio = 0x102;     // radio 1
6812                ses_gpio = 0x109;       // wps led
6813                wlan_gpio = 0x108;      // wifi button led
6814                usb_gpio = 0x004;       //usb1
6815                usb_gpio1 = 0x005;      //usb2
6816                break;
6817        case ROUTER_NETGEAR_R7800:
6818                power_gpio = 0x000;     // power led
6819                diag_gpio = 0x00a;      // power led orange     
6820                diag_gpio_disabled = 0x000;     // power led orange     
6821                connected_gpio = 0x007; // wan led
6822                usb_power = 0x010;      // usb enable
6823                usb_power1 = 0x00f;
6824                wlan0_gpio = 0x009;     // radio 5G
6825                wlan1_gpio = 0x008;     // radio 2G
6826                //ses_gpio = 0x109;     // wps button led used for 2G
6827                //wlan_gpio = 0x008;    // wifi button led used for 5G
6828                usb_gpio = 0x004;       //usb1
6829                usb_gpio1 = 0x005;      //usb2
6830                break;
6831        case ROUTER_ASROCK_G10:
6832                diag_gpio = 0x009;      // power led orange     
6833                connected_gpio = 0x008; // wan led
6834                disconnected_gpio = 0x007;      // wan led
6835                break;
6836        case ROUTER_NETGEAR_R9000:
6837
6838                power_gpio = 0x016;     // power led
6839                diag_gpio = 0x116;      // power led orange     
6840                diag_gpio_disabled = 0x016;     // power led orange     
6841                connected_gpio = 0x017; // wan led
6842//      usb_power = 0x010;      // usb enable
6843//      usb_power1 = 0x00f;
6844                ses_gpio = 0x127;       // wps button led used for 2G
6845                usb_gpio = 0x024;       //usb1
6846                usb_gpio1 = 0x025;      //usb2
6847                break;
6848        case ROUTER_TRENDNET_TEW827:
6849                power_gpio = 0x135;     // power led
6850                usb_gpio = 0x107;       // usb led
6851                break;
6852        case ROUTER_NETGEAR_R8000:
6853                power_gpio = 0x102;     // power led
6854                diag_gpio = 0x103;      // power led orange     
6855                connected_gpio = 0x109; // wan led green
6856                usb_power = 0x000;      // usb enable
6857                wlan0_gpio = 0x10d;     // radio 2G
6858                wlan1_gpio = 0x10c;     // radio 5G-1
6859                wlan2_gpio = 0x110;     // radio 5G-2
6860                ses_gpio = 0x10e;       // wps led
6861                wlan_gpio = 0x10f;      // wifi button led
6862                usb_gpio = 0x111;       //usb1
6863                usb_gpio1 = 0x112;      //usb2
6864                break;
6865        case ROUTER_NETGEAR_R8500:
6866                power_gpio = 0x102;     // power led
6867                diag_gpio = 0x10f;      //     
6868                connected_gpio = 0x109; // wan led white 1Gb amber 100Mb
6869                usb_power = 0x000;      // usb enable
6870                wlan0_gpio = 0x10b;     // radio 5G-1
6871                wlan1_gpio = 0x10d;     // radio 2G
6872                wlan2_gpio = 0x10c;     // radio 5G-2
6873                ses_gpio = 0x10e;       // wps led
6874                wlan_gpio = 0x014;      // wifi button led
6875                usb_gpio = 0x111;       //usb1
6876                usb_gpio1 = 0x112;      //usb2
6877                break;
6878        case ROUTER_NETGEAR_WNDR4500:
6879        case ROUTER_NETGEAR_WNDR4500V2:
6880                power_gpio = 0x102;     //power led green
6881                diag_gpio = 0x103;      // power led amber
6882                connected_gpio = 0x10f; //wan led green
6883                wlan0_gpio = 0x109;     //radio 0 led green
6884                wlan1_gpio = 0x10b;     // radio 1 led blue
6885                usb_gpio = 0x108;       //usb led green
6886                usb_gpio1 = 0x10e;      //usb1 led green
6887                break;
6888        case ROUTER_ASUS_RTN66:
6889        case ROUTER_ASUS_AC66U:
6890                power_gpio = 0x10c;
6891                diag_gpio = 0x00c;
6892                usb_gpio = 0x10f;
6893                break;
6894        case ROUTER_NETGEAR_WNR2000V2:
6895
6896                //power_gpio = ??;
6897                diag_gpio = 0x002;
6898                ses_gpio = 0x007;       //WPS led
6899                connected_gpio = 0x006;
6900                break;
6901        case ROUTER_WRT320N:
6902                power_gpio = 0x002;     //power/diag (disabled=blink)
6903                ses_gpio = 0x103;       // ses blue
6904                connected_gpio = 0x104; //ses orange
6905                break;
6906        case ROUTER_ASUS_RTN12:
6907                power_gpio = 0x102;
6908                diag_gpio = 0x002;      // power blink
6909                break;
6910        case ROUTER_BOARD_NEPTUNE:
6911//              usb_gpio = 0x108;
6912                // 0x10c //unknown gpio label, use as diag
6913#ifdef HAVE_RUT500
6914                diag_gpio = 0x10e;
6915#else
6916                diag_gpio = 0x10c;
6917#endif
6918                break;
6919        case ROUTER_ASUS_RTN10U:
6920                ses_gpio = 0x007;
6921                usb_gpio = 0x008;
6922                break;
6923        case ROUTER_ASUS_RTN12B:
6924                connected_gpio = 0x105;
6925                break;
6926        case ROUTER_ASUS_RTN10PLUSD1:
6927                ses_gpio = 0x007;
6928                power_gpio = 0x106;
6929                diag_gpio = 0x006;
6930                break;
6931        case ROUTER_ASUS_RTN10:
6932        case ROUTER_ASUS_RTN16:
6933        case ROUTER_NETCORE_NW618:
6934                power_gpio = 0x101;
6935                diag_gpio = 0x001;      // power blink
6936                break;
6937        case ROUTER_BELKIN_F7D3301:
6938        case ROUTER_BELKIN_F7D3302:
6939        case ROUTER_BELKIN_F7D4301:
6940        case ROUTER_BELKIN_F7D4302:
6941                power_gpio = 0x10a;     // green
6942                diag_gpio = 0x10b;      // red
6943                ses_gpio = 0x10d;       // wps orange
6944                break;
6945        case ROUTER_DYNEX_DX_NRUTER:
6946                power_gpio = 0x001;
6947                diag_gpio = 0x101;      // power blink
6948                connected_gpio = 0x100;
6949                sec0_gpio = 0x103;
6950                break;
6951#endif
6952        }
6953
6954        if (type == LED_DIAG && v1func == 1) {
6955                if (act == LED_ON)
6956                        C_led(1);
6957                else
6958                        C_led(0);
6959        }
6960
6961        switch (type) {
6962        case LED_POWER:
6963                use_gpio = power_gpio;
6964                break;
6965        case BEEPER:
6966                use_gpio = beeper_gpio;
6967                break;
6968        case USB_POWER:
6969                use_gpio = usb_power;
6970                break;
6971        case USB_POWER1:
6972                use_gpio = usb_power1;
6973                break;
6974        case LED_DIAG:
6975                if (act == LED_ON)
6976                        led_control(LED_DIAG_DISABLED, LED_OFF);
6977                else
6978                        led_control(LED_DIAG_DISABLED, LED_ON);
6979                use_gpio = diag_gpio;
6980                break;
6981        case LED_DIAG_DISABLED:
6982                use_gpio = diag_gpio_disabled;
6983                break;
6984        case LED_DMZ:
6985                use_gpio = dmz_gpio;
6986                break;
6987        case LED_CONNECTED:
6988                if (act == LED_ON)
6989                        led_control(LED_DISCONNECTED, LED_OFF);
6990                else
6991                        led_control(LED_DISCONNECTED, LED_ON);
6992                use_gpio = connblue ? ses_gpio : connected_gpio;
6993                break;
6994        case LED_DISCONNECTED:
6995                use_gpio = disconnected_gpio;
6996                break;
6997        case LED_BRIDGE:
6998                use_gpio = bridge_gpio;
6999                break;
7000        case LED_VPN:
7001                use_gpio = vpn_gpio;
7002                break;
7003        case LED_SES:
7004                use_gpio = connblue ? connected_gpio : ses_gpio;
7005                break;
7006        case LED_SES2:
7007                use_gpio = ses2_gpio;
7008                break;
7009        case LED_WLAN:
7010                use_gpio = wlan_gpio;
7011                break;
7012        case LED_WLAN0:
7013                use_gpio = wlan0_gpio;
7014                break;
7015        case LED_WLAN1:
7016                use_gpio = wlan1_gpio;
7017                break;
7018        case LED_WLAN2:
7019                use_gpio = wlan2_gpio;
7020                break;
7021        case LED_USB:
7022                use_gpio = usb_gpio;
7023                break;
7024        case LED_USB1:
7025                use_gpio = usb_gpio1;
7026                break;
7027        case LED_SEC0:
7028                use_gpio = sec0_gpio;
7029                break;
7030        case LED_SEC1:
7031                use_gpio = sec1_gpio;
7032                break;
7033        }
7034
7035        if ((use_gpio & 0x0ff) != 0x0ff) {
7036                gpio_value = use_gpio & 0x0ff;
7037                enable = (use_gpio & 0x100) == 0 ? 1 : 0;
7038                disable = (use_gpio & 0x100) == 0 ? 0 : 1;
7039                int setin = (use_gpio & 0x200) == 0 ? 0 : 1;
7040                switch (act) {
7041                case LED_ON:
7042                        set_gpio(gpio_value, enable);
7043                        if (setin)
7044                                get_gpio(gpio_value);
7045                        break;
7046                case LED_OFF:
7047                        set_gpio(gpio_value, disable);
7048                        break;
7049                case LED_FLASH: // will lit the led for 1 sec.
7050                        set_gpio(gpio_value, enable);
7051                        sleep(1);
7052                        set_gpio(gpio_value, disable);
7053                        break;
7054                }
7055        }
7056        return 1;
7057
7058#endif
7059}
7060
7061int file_to_buf(char *path, char *buf, int len)
7062{
7063        FILE *fp;
7064
7065        bzero(buf, len);
7066
7067        if ((fp = fopen(path, "r"))) {
7068                fgets(buf, len, fp);
7069                fclose(fp);
7070                return 1;
7071        }
7072
7073        return 0;
7074}
7075
7076int ishexit(char c)
7077{
7078
7079        if (strchr("01234567890abcdefABCDEF", c) != (char *)0)
7080                return 1;
7081
7082        return 0;
7083}
7084
7085int getMTD(char *name)
7086{
7087        char buf[32];
7088        int device = -1;
7089        char dev[32];
7090        char size[32];
7091        char esize[32];
7092        char n[32];
7093        sprintf(buf, "\"%s\"", name);
7094        FILE *fp = fopen("/proc/mtd", "rb");
7095        if (!fp)
7096                return -1;
7097        while (!feof(fp) && fscanf(fp, "%s %s %s %s", dev, size, esize, n) == 4) {
7098                if (!strcmp(n, buf)) {
7099                        if (dev[4] == ':') {
7100                                device = dev[3] - '0';
7101                        } else {
7102                                device = 10 + (dev[4] - '0');
7103                        }
7104
7105                        break;
7106                }
7107        }
7108        fclose(fp);
7109        return device;
7110}
7111
7112int insmod(char *module)
7113{
7114        static char word[256];
7115        char *next, *wordlist;
7116        int ret = 0;
7117        wordlist = module;
7118        foreach(word, wordlist, next) {
7119                ret |= _evalpid((char * const[]) {
7120                                "insmod", word, NULL}, ">/dev/null", 0, NULL);
7121        }
7122        return ret;
7123}
7124
7125void rmmod(char *module)
7126{
7127        static char word[256];
7128        char *next, *wordlist;
7129        wordlist = module;
7130        foreach(word, wordlist, next) {
7131                _evalpid((char *const[]) {
7132                         "rmmod", word, NULL}, ">/dev/null", 0, NULL);
7133        }
7134}
7135
7136#include "revision.h"
7137
7138char *getSoftwareRevision(void)
7139{
7140        return "" SVN_REVISION "";
7141}
7142
7143#ifdef HAVE_OLED
7144void initlcd()
7145{
7146
7147}
7148
7149void lcdmessage(char *message)
7150{
7151        eval("oled-print", "DD-WRT v24 sp2", "build:" SVN_REVISION, "3G/UMTS Router", message);
7152}
7153
7154void lcdmessaged(char *dual, char *message)
7155{
7156
7157}
7158
7159#endif
7160
7161#if 0
7162
7163static int fd;
7164
7165void SetEnvironment()
7166{
7167        system("stty ispeed 2400 < /dev/tts/1");
7168        system("stty raw < /dev/tts/1");
7169}
7170
7171int Cmd = 254;                  /* EZIO Command */
7172int cls = 1;                    /* Clear screen */
7173void Cls()
7174{
7175        write(fd, &Cmd, 1);
7176        write(fd, &cls, 1);
7177}
7178
7179int init = 0x28;
7180void Init()
7181{
7182        write(fd, &Cmd, 1);
7183        write(fd, &init, 1);
7184}
7185
7186int stopsend = 0x37;
7187void StopSend()
7188{
7189        write(fd, &Cmd, 1);
7190        write(fd, &init, 1);
7191}
7192
7193int home = 2;                   /* Home cursor */
7194void Home()
7195{
7196        write(fd, &Cmd, 1);
7197        write(fd, &home, 1);
7198}
7199
7200int readkey = 6;                /* Read key */
7201void ReadKey()
7202{
7203        write(fd, &Cmd, 1);
7204        write(fd, &readkey, 1);
7205}
7206
7207int blank = 8;                  /* Blank display */
7208void Blank()
7209{
7210        write(fd, &Cmd, 1);
7211        write(fd, &blank, 1);
7212}
7213
7214int hide = 12;                  /* Hide cursor & display blanked characters */
7215void Hide()
7216{
7217        write(fd, &Cmd, 1);
7218        write(fd, &hide, 1);
7219}
7220
7221int turn = 13;                  /* Turn On (blinking block cursor) */
7222void TurnOn()
7223{
7224        write(fd, &Cmd, 1);
7225        write(fd, &turn, 1);
7226}
7227
7228int show = 14;                  /* Show underline cursor */
7229void Show()
7230{
7231        write(fd, &Cmd, 1);
7232        write(fd, &show, 1);
7233}
7234
7235int movel = 16;                 /* Move cursor 1 character left */
7236void MoveL()
7237{
7238        write(fd, &Cmd, 1);
7239        write(fd, &movel, 1);
7240}
7241
7242int mover = 20;                 /* Move cursor 1 character right */
7243void MoveR()
7244{
7245        write(fd, &Cmd, 1);
7246        write(fd, &mover, 1);
7247}
7248
7249int scl = 24;                   /* Scroll cursor 1 character left */
7250void ScrollL()
7251{
7252        write(fd, &Cmd, 1);
7253        write(fd, &scl, 1);
7254}
7255
7256int scr = 28;                   /* Scroll cursor 1 character right */
7257void ScrollR()
7258{
7259        write(fd, &Cmd, 1);
7260        write(fd, &scr, 1);
7261}
7262
7263int setdis = 64;                /* Command */
7264void SetDis()
7265{
7266        write(fd, &Cmd, 1);
7267        write(fd, &setdis, 1);
7268
7269}
7270
7271int a, b;
7272void ShowMessage(char *str1, char *str2)
7273{
7274        char nul[] = "                                       ";
7275
7276        a = strlen(str1);
7277        b = 40 - a;
7278        write(fd, str1, a);
7279        write(fd, nul, b);
7280        write(fd, str2, strlen(str2));
7281}
7282
7283void initlcd()
7284{
7285
7286        fd = open("/dev/tts/1", O_RDWR);
7287
7288                                  /** Open Serial port (COM2) */
7289        if (fd > 0) {
7290                close(fd);
7291                SetEnvironment();       /* Set RAW mode */
7292                fd = open("/dev/tts/1", O_RDWR);
7293                Init();         /* Initialize EZIO twice */
7294                Init();
7295
7296                Cls();          /* Clear screen */
7297        }
7298        close(fd);
7299}
7300
7301void lcdmessage(char *message)
7302{
7303
7304        fd = open("/dev/tts/1", O_RDWR);
7305                                   /** Open Serial port (COM2) */
7306
7307        if (fd > 0) {
7308                Init();         /* Initialize EZIO twice */
7309                Init();
7310                SetDis();
7311                Cls();
7312                Home();
7313                ShowMessage("State", message);
7314                close(fd);
7315        }
7316}
7317
7318void lcdmessaged(char *dual, char *message)
7319{
7320
7321        fd = open("/dev/tts/1", O_RDWR);
7322
7323                                  /** Open Serial port (COM2) */
7324
7325        if (fd > 0) {
7326                Init();         /* Initialize EZIO twice */
7327                Init();
7328                SetDis();
7329                Cls();          /* Clear screen */
7330                Home();
7331                ShowMessage(dual, message);
7332                close(fd);
7333        }
7334}
7335
7336#endif
7337static int i64c(int i)
7338{
7339        i &= 0x3f;
7340        if (i == 0)
7341                return '.';
7342        if (i == 1)
7343                return '/';
7344        if (i < 12)
7345                return ('0' - 2 + i);
7346        if (i < 38)
7347                return ('A' - 12 + i);
7348        return ('a' - 38 + i);
7349}
7350
7351int crypt_make_salt(char *p, int cnt, int x)
7352{
7353        x += getpid() + time(NULL);
7354        do {
7355                /*
7356                 * x = (x*1664525 + 1013904223) % 2^32 generator is lame (low-order
7357                 * bit is not "random", etc...), but for our purposes it is good
7358                 * enough
7359                 */
7360                x = x * 1664525 + 1013904223;
7361                /*
7362                 * BTW, Park and Miller's "minimal standard generator" is x = x*16807
7363                 * % ((2^31)-1) It has no problem with visibly alternating lowest bit
7364                 * but is also weak in cryptographic sense + needs div, which needs
7365                 * more code (and slower) on many CPUs
7366                 */
7367                *p++ = i64c(x >> 16);
7368                *p++ = i64c(x >> 22);
7369        }
7370        while (--cnt);
7371        *p = '\0';
7372        return x;
7373}
7374
7375#include <crypt.h>
7376
7377char *getUUID(char *buf)
7378{
7379        FILE *fp = fopen("/proc/sys/kernel/random/uuid", "rb");
7380        if (fp) {
7381                fscanf(fp, "%s", buf);
7382                fclose(fp);
7383                return buf;
7384        }
7385        return NULL;
7386}
7387
7388char *zencrypt(char *passwd, char *passout)
7389{
7390        char salt[sizeof("$N$XXXXXXXX")];       /* "$N$XXXXXXXX" or "XX" */
7391
7392        strcpy(salt, "$1$");
7393        crypt_make_salt(salt + 3, 4, 0);
7394        strcpy(passout, crypt((char *)passwd, (char *)salt));
7395        return passout;
7396}
7397
7398int has_gateway(void)
7399{
7400        if (nvram_match("wk_mode", "gateway"))
7401                return 1;
7402        if (nvram_match("wk_mode", "olsr") && nvram_matchi("olsrd_gateway", 1))
7403                return 1;
7404        return 0;
7405}
7406
7407struct wifidevices {
7408        char *name;
7409        int vendor;
7410        int device;
7411};
7412
7413static struct wifidevices wdevices[] = {
7414        {"AR5210 802.11a", 0x168c, 0x0007},
7415        {"AR5210 802.11a", 0x168c, 0x0207},
7416        {"AR5211 802.11a", 0x168c, 0x0011},
7417        {"AR5211 802.11ab", 0x168c, 0x0012},
7418        {"AR5212", 0x168c, 0x0013},
7419        {"AR5212", 0x168c, 0x1014},
7420        {"AR2413", 0x168c, 0x001a},
7421        {"AR5413", 0x168c, 0x001b},
7422        {"AR542x", 0x168c, 0x001c},
7423        {"AR2417", 0x168c, 0x001d},
7424        {"AR5513", 0x168c, 0x0020},
7425        {"AR5416 802.11n", 0x168c, 0x0023},
7426        {"AR5418 802.11n", 0x168c, 0x0024},
7427        {"AR9160 802.11n", 0x168c, 0x0027},
7428        {"AR922X 802.11n", 0x168c, 0x0029},
7429        {"AR928X 802.11n", 0x168c, 0x002a},
7430        {"AR9285 802.11n", 0x168c, 0x002b},
7431        {"AR2427 802.11n", 0x168c, 0x002c},
7432        {"AR9227 802.11n", 0x168c, 0x002d},
7433        {"AR9287 802.11n", 0x168c, 0x002e},
7434        {"AR93xx 802.11n", 0x168c, 0x0030},
7435        {"AR9485 802.11n", 0x168c, 0x0032},
7436        {"AR958x 802.11n", 0x168c, 0x0033},
7437        {"AR9462 802.11n", 0x168c, 0x0034},
7438        {"QCA9565 802.11n", 0x168c, 0x0036},
7439        {"AR9485 802.11n", 0x168c, 0x0037},
7440        {"AR5002X", 0x168c, 0x9013},
7441        {"AR5006X", 0x168c, 0xff19},
7442        {"AR2425", 0x168c, 0xff1b},
7443        {"AR5008", 0x168c, 0xff1c},
7444        {"AR922x 802.11n", 0x168c, 0xff1d},
7445        {"QCA988x 802.11ac", 0x168c, 0x003c},
7446        {"QCA6174 802.11ac", 0x168c, 0x003e},
7447        {"QCA9980 802.11ac", 0x168c, 0x0040},
7448        {"QCA6174 802.11ac", 0x168c, 0x0041},
7449        {"QCA9377 802.11ac", 0x168c, 0x0042},
7450        {"QCA9984 802.11ac", 0x168c, 0x0046},
7451        {"QCA9887 802.11ac", 0x168c, 0x0050},
7452        {"QCA9888 802.11ac", 0x168c, 0x0056},
7453        {"88W8964 802.11ac", 0x11ab, 0x2b40},
7454        {"88W8864 802.11ac", 0x11ab, 0x2a55},
7455        {"88W8897 802.11ac", 0x11ab, 0x2b38},
7456        {"WIL6210 802.11ad", 0x1ae9, 0x0310},
7457        {"SD8887 802.11ac", 0x02df, 0x9135},
7458        {"MT7615 802.11ac", 0x14c3, 0x7615},
7459        {"MT7662E 802.11ac", 0x14c3, 0x7662},
7460
7461};
7462
7463char *getWifiDeviceName(char *prefix)
7464{
7465        char *globstring;
7466        int devnum;
7467        int device = 0, vendor = 0;
7468        int devcount;
7469        FILE *fp;
7470        sscanf(prefix, "ath%d", &devcount);
7471        asprintf(&globstring, "/proc/sys/dev/wifi%d/dev_vendor", devcount);
7472        fp = fopen(globstring, "rb");
7473        if (fp) {
7474                fscanf(fp, "%d", &vendor);
7475                fclose(fp);
7476        }
7477        free(globstring);
7478        asprintf(&globstring, "/proc/sys/dev/wifi%d/dev_device", devcount);
7479        fp = fopen(globstring, "rb");
7480        if (fp) {
7481                fscanf(fp, "%d", &device);
7482                fclose(fp);
7483        }
7484        free(globstring);
7485#ifdef HAVE_ATH9K
7486        if (!vendor || !device) {
7487                devnum = get_ath9k_phy_ifname(prefix);
7488                if (devnum == -1)
7489                        return NULL;
7490                asprintf(&globstring, "/sys/class/ieee80211/phy%d/device/vendor", devnum);
7491                fp = fopen(globstring, "rb");
7492                if (fp) {
7493                        fscanf(fp, "0x%x", &vendor);
7494                        fclose(fp);
7495                }
7496                free(globstring);
7497                asprintf(&globstring, "/sys/class/ieee80211/phy%d/device/device", devnum);
7498                fp = fopen(globstring, "rb");
7499                if (fp) {
7500                        fscanf(fp, "0x%x", &device);
7501                        fclose(fp);
7502                }
7503                free(globstring);
7504        }
7505#endif
7506#ifdef HAVE_RT2880
7507        if (!vendor || !device) {
7508
7509                if (!strncmp(prefix, "ra", 2) || !strncmp(prefix, "wl0", 3)) {
7510                        FILE *fp = fopen("/sys/bus/pci/devices/0000:01:00.0/device", "rb");
7511                        if (fp) {
7512                                fscanf(fp, "0x%x", &device);
7513                                fclose(fp);
7514                        }
7515                        fp = fopen("/sys/bus/pci/devices/0000:01:00.0/vendor", "rb");
7516                        if (fp) {
7517                                fscanf(fp, "0x%x", &vendor);
7518                                fclose(fp);
7519                        }
7520                }
7521
7522                if (!strncmp(prefix, "ba", 2) || !strncmp(prefix, "wl1", 3)) {
7523                        FILE *fp = fopen("/sys/bus/pci/devices/0000:02:00.0/device", "rb");
7524                        if (fp) {
7525                                fscanf(fp, "0x%x", &device);
7526                                fclose(fp);
7527                        }
7528                        fp = fopen("/sys/bus/pci/devices/0000:02:00.0/vendor", "rb");
7529                        if (fp) {
7530                                fscanf(fp, "0x%x", &vendor);
7531                                fclose(fp);
7532                        }
7533                }
7534        }
7535#endif
7536        if (!vendor || !device) {
7537                return NULL;
7538        }
7539        int i;
7540        for (i = 0; i < sizeof(wdevices) / sizeof(wdevices[0]); i++) {
7541                if (wdevices[i].vendor == vendor && wdevices[i].device == device)
7542                        return wdevices[i].name;
7543        }
7544        return NULL;
7545
7546}
7547
7548#ifdef HAVE_ATH9K
7549int getath9kdevicecount(void)
7550{
7551        glob_t globbuf;
7552        int globresult;
7553        int count = 0;
7554#ifndef HAVE_MADWIFI_MIMO
7555        if (1) {
7556#else
7557        if (nvram_match("mimo_driver", "ath9k")) {
7558#endif
7559                globresult = glob("/sys/class/ieee80211/phy*", GLOB_NOSORT, NULL, &globbuf);
7560                if (globresult == 0)
7561                        count = (int)globbuf.gl_pathc;
7562                globfree(&globbuf);
7563        }
7564#if (defined(HAVE_MMS344) || defined(HAVE_ARCHERC7)) && !defined(HAVE_DAP2330) && !defined(HAVE_WILLY)
7565        return 2;
7566#else
7567        return (count);
7568#endif
7569}
7570
7571int get_ath9k_phy_idx(int idx)
7572{
7573        // fprintf(stderr,"channel number %d of %d\n", i,achans.ic_nchans);
7574#ifdef HAVE_MVEBU
7575        return idx;
7576#else
7577        return idx - getifcount("wifi");
7578#endif
7579}
7580
7581int get_ath9k_phy_ifname(const char *ifname)
7582{
7583        int devnum;
7584        if (is_wil6210(ifname))
7585                return 2;
7586        if (strncmp(ifname, "ath", 3))
7587                return -1;
7588        if (!sscanf(ifname, "ath%d", &devnum))
7589                return -1;
7590        // fprintf(stderr,"channel number %d of %d\n", i,achans.ic_nchans);
7591        return get_ath9k_phy_idx(devnum);
7592}
7593
7594int is_ath9k(const char *prefix)
7595{
7596#ifdef HAVE_MVEBU
7597        return 1;
7598#endif
7599        glob_t globbuf;
7600        int count = 0;
7601        char *globstring;
7602        int globresult;
7603        int devnum;
7604        // get legacy interface count
7605#ifdef HAVE_MADWIFI_MIMO
7606        if (!nvram_match("mimo_driver", "ath9k"))
7607                return (0);
7608#endif
7609        // correct index if there are legacy cards arround
7610        devnum = get_ath9k_phy_ifname(prefix);
7611        if (devnum == -1)
7612                return 0;
7613        asprintf(&globstring, "/sys/class/ieee80211/phy%d", devnum);
7614        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
7615        free(globstring);
7616        if (globresult == 0)
7617                count = (int)globbuf.gl_pathc;
7618        globfree(&globbuf);
7619        return (count);
7620}
7621
7622int has_spectralscanning(const char *prefix)
7623{
7624#ifdef HAVE_MVEBU
7625        return 0;
7626#endif
7627        glob_t globbuf;
7628        int count = 0;
7629        char *globstring;
7630        int globresult;
7631        int devnum;
7632        // get legacy interface count
7633#ifdef HAVE_MADWIFI_MIMO
7634        if (!nvram_match("mimo_driver", "ath9k"))
7635                return (0);
7636#endif
7637        // correct index if there are legacy cards arround
7638        devnum = get_ath9k_phy_ifname(prefix);
7639        if (devnum == -1)
7640                return 0;
7641#ifdef HAVE_ATH10K
7642        if (is_ath10k(prefix))
7643                asprintf(&globstring, "/sys/kernel/debug/ieee80211/phy%d/ath10k/spectral_count", devnum);
7644        else
7645#endif
7646                asprintf(&globstring, "/sys/kernel/debug/ieee80211/phy%d/ath9k/spectral_count", devnum);
7647        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
7648        free(globstring);
7649        if (globresult == 0)
7650                count = (int)globbuf.gl_pathc;
7651        globfree(&globbuf);
7652        return (count);
7653}
7654#endif
7655
7656static int devicecountbydriver(const char *prefix, char *drivername)
7657{
7658        glob_t globbuf;
7659        int count = 0;
7660        char *globstring;
7661        int globresult;
7662        int devnum;
7663        // correct index if there are legacy cards arround... should not...
7664        devnum = get_ath9k_phy_ifname(prefix);
7665        if (devnum == -1)
7666                return 0;
7667        asprintf(&globstring, "/sys/class/ieee80211/phy%d/device/driver/module/drivers/pci:%s", devnum, drivername);
7668        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
7669        free(globstring);
7670        if (globresult == 0)
7671                count = (int)globbuf.gl_pathc;
7672        globfree(&globbuf);
7673        return (count);
7674
7675}
7676
7677#ifdef HAVE_ATH5K
7678int is_ath5k(const char *prefix)
7679{
7680        return devicecountbydriver(prefix, "ath5k");
7681}
7682#endif
7683#ifdef HAVE_MVEBU
7684int is_mvebu(const char *prefix)
7685{
7686        return devicecountbydriver(prefix, "mwlwifi");
7687}
7688#endif
7689#ifdef HAVE_ATH10K
7690int is_ath10k(const char *prefix)
7691{
7692        // get legacy interface count
7693#ifdef HAVE_MADWIFI_MIMO
7694        if (!nvram_match("mimo_driver", "ath9k"))
7695                return (0);
7696#endif
7697        return devicecountbydriver(prefix, "ath10k_pci");
7698}
7699
7700#endif
7701#ifdef HAVE_WIL6210
7702int is_wil6210(const char *prefix)
7703{
7704        if (!strcmp(prefix, "giwifi"))
7705                return 1;
7706        if (!strcmp(prefix, "ath2"))
7707                return 1;
7708        return 0;
7709        // get legacy interface count
7710//      return devicecountbydriver(prefix, "wil6210");
7711}
7712
7713#endif
7714
7715static int HTtoVHTindex(int mcs)
7716{
7717        if (mcs < 8)
7718                return mcs;
7719        if (mcs < 16)
7720                return mcs + 2;
7721        if (mcs < 24)
7722                return mcs + 4;
7723        return mcs + 6;
7724}
7725
7726int VHTTxRate(unsigned int mcs, unsigned int vhtmcs, unsigned int sgi, unsigned int bw)
7727{
7728        static int vHTTxRate20_800[40] = {
7729                6500, 13000, 19500, 26000, 39000, 52000, 58500, 65000, 78000, 78000,    // MCS 0 -8
7730                13000, 26000, 39000, 52000, 78000, 104000, 117000, 130000, 156000, 156000,      // MCS 8 - 15
7731                19500, 39000, 58500, 78000, 117000, 156000, 175500, 195000, 234000, 260000,     // MCS 16 - 23
7732                26000, 52000, 78000, 104000, 156000, 208000, 234000, 260000, 312000, 312000     // MCS 24 - 31
7733        };
7734        static int vHTTxRate20_400[40] = {
7735                7200, 14400, 21700, 28900, 43300, 57800, 65000, 72200, 86700, 86700,    //
7736                14444, 28889, 43333, 57778, 86667, 115556, 130000, 144444, 173300, 173300,      //
7737                21700, 43300, 65000, 86700, 130000, 173300, 195000, 216700, 260000, 288900,     //
7738                28900, 57800, 86700, 115600, 173300, 231100, 260000, 288900, 346700, 0  //
7739        };
7740        static int vHTTxRate40_800[40] = {
7741                13500, 27000, 40500, 54000, 81000, 108000, 121500, 135000, 162000, 180000,      //
7742                27000, 54000, 81000, 108000, 162000, 216000, 243000, 270000, 324000, 360000,    //
7743                40500, 81000, 121500, 162000, 243000, 324000, 364500, 405000, 486000, 540000,   //
7744                54000, 108000, 162000, 216000, 324000, 432000, 486000, 540000, 648000, 720000   //
7745        };
7746        static int vHTTxRate40_400[40] = {
7747                15000, 30000, 45000, 60000, 90000, 120000, 135000, 150000, 180000, 200000,      //
7748                30000, 60000, 90000, 120000, 180000, 240000, 270000, 300000, 360000, 400000,    //
7749                45000, 90000, 135000, 180000, 270000, 360000, 405000, 450000, 540000, 600000,   //
7750                60000, 120000, 180000, 240000, 360000, 480000, 540000, 600000, 720000, 800000   //
7751        };
7752        static int vHTTxRate80_800[40] = {
7753                29300, 58500, 87800, 117000, 175500, 234000, 263300, 292500, 351000, 390000,    //
7754                58500, 117000, 175500, 234000, 351000, 468000, 526500, 585000, 702000, 780000,
7755                87800, 175500, 263300, 351000, 526500, 702000, 0, 877500, 1053000, 1170000,     //
7756                117000, 234000, 351000, 468000, 702000, 936000, 1053000, 1170000, 1404000, 1560000
7757        };
7758        static int vHTTxRate80_400[40] = {
7759                32500, 65000, 97500, 130000, 195000, 260000, 292500, 325000, 390000, 433300,    //
7760                65000, 130000, 195000, 260000, 390000, 520000, 585000, 650000, 780000, 866700,  //
7761                97500, 195000, 292500, 390000, 585000, 780000, 0, 975000, 1170000, 1300000,     //
7762                130000, 260000, 390000, 520000, 780000, 1040000, 1170000, 1300000, 1560000, 1733300
7763        };
7764        static int vHTTxRate160_800[40] = {
7765                58500, 117000, 175500, 234000, 351000, 468000, 526500, 585000, 702000, 780000,
7766                117000, 234000, 351000, 468000, 702000, 936000, 1053000, 1170000, 1404000, 1560000,
7767                175500, 351000, 526500, 702000, 1053000, 1404000, 1579500, 1755000, 2106000, 2106000,
7768                234000, 468000, 702000, 936000, 1404000, 1872000, 2106000, 2340000, 2808000, 3120000,
7769
7770        };
7771        static int vHTTxRate160_400[40] = {
7772                65000, 130000, 195000, 260000, 390000, 520000, 585000, 650000, 780000, 866700,  //
7773                130000, 260000, 390000, 520000, 780000, 1040000, 1170000, 1300000, 1560000, 1733300,
7774                195000, 390000, 585000, 780000, 1170000, 1560000, 1755000, 1950000, 2340000, 2340000,
7775                260000, 520000, 780000, 1040000, 1560000, 2080000, 2340000, 2600000, 3120000, 3466700,
7776        };
7777
7778        int *table = vHTTxRate20_400;
7779//      fprintf(stderr, "sgi %d mcs %d vhtmcs %d\n", sgi, mcs, vhtmcs);
7780        if (sgi) {
7781                switch (bw) {
7782                case 20:
7783                        table = vHTTxRate20_400;
7784                        break;
7785                case 40:
7786                        table = vHTTxRate40_400;
7787                        break;
7788                case 80:
7789                        table = vHTTxRate80_400;
7790                        break;
7791                case 160:
7792                        table = vHTTxRate160_400;
7793                        break;
7794                }
7795        } else {
7796
7797                switch (bw) {
7798                case 20:
7799                        table = vHTTxRate20_800;
7800                        break;
7801                case 40:
7802                        table = vHTTxRate40_800;
7803                        break;
7804                case 80:
7805                        table = vHTTxRate80_800;
7806                        break;
7807                case 160:
7808                        table = vHTTxRate160_800;
7809                        break;
7810                }
7811        }
7812        if (vhtmcs == -1) {
7813                vhtmcs = HTtoVHTindex(mcs);
7814        }
7815
7816        return table[vhtmcs];
7817}
7818
7819int writeproc(char *path, char *value)
7820{
7821        int fd;
7822        fd = open(path, O_WRONLY);
7823        if (fd == -1) {
7824                fprintf(stderr, "cannot open %s\n", path);
7825                return -1;
7826        }
7827        write(fd, value, strlen(value));
7828        close(fd);
7829        return 0;
7830}
7831
7832int writeprocsysnet(char *path, char *value)
7833{
7834        char syspath[64];
7835        snprintf(syspath, 64, "/proc/sys/net/%s", path);
7836        return writeproc(syspath, value);
7837}
7838
7839int writeprocsys(char *path, char *value)
7840{
7841        char syspath[64];
7842        snprintf(syspath, 64, "/proc/sys/%s", path);
7843        return writeproc(syspath, value);
7844}
7845
7846int writevaproc(char *value, char *fmt, ...)
7847{
7848        char varbuf[256];
7849        va_list args;
7850
7851        va_start(args, (char *)fmt);
7852        vsnprintf(varbuf, sizeof(varbuf), fmt, args);
7853        va_end(args);
7854        return writeproc(varbuf, value);
7855}
7856
7857void set_smp_affinity(int irq, int cpu)
7858{
7859        char s_cpu[32];
7860        snprintf(s_cpu, sizeof(s_cpu), "%d", cpu);
7861        writevaproc(s_cpu, "/proc/irq/%d/smp_affinity", irq);
7862}
7863
7864/* gartarp */
7865
7866struct arph {
7867        uint16_t hw_type;
7868
7869#define ARPHDR_ETHER    1
7870
7871        uint16_t proto_type;
7872
7873        char ha_len;
7874        char pa_len;
7875
7876#define ARPOP_BROADCAST 1
7877#define ARPOP_REPLY     2
7878        uint16_t opcode;
7879        char source_add[ETH_ALEN];
7880        char source_ip[IP_ALEN];
7881        char dest_add[ETH_ALEN];
7882        char dest_ip[IP_ALEN];
7883
7884} __attribute__((packed));
7885
7886#define ARP_HLEN        sizeof(struct arph) + ETH_HLEN
7887#define BCAST           "\xff\xff\xff\xff\xff\xff"
7888
7889static inline int get_iface_attr(int sk, char *iface, char *hw, char *paddr)
7890{
7891        int ret;
7892        struct ifreq ifr;
7893
7894        strcpy(ifr.ifr_name, iface);
7895
7896        ret = ioctl(sk, SIOCGIFHWADDR, &ifr);
7897        if (unlikely(ret == -1)) {
7898                perror("ioctl SIOCGIFHWADDR");
7899                return ret;
7900        }
7901        memcpy(hw, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
7902
7903        ret = ioctl(sk, SIOCGIFADDR, &ifr);
7904        if (unlikely(ret == -1)) {
7905                perror("ioctl SIOCGIFADDR");
7906                return ret;
7907        }
7908        memcpy(paddr, ifr.ifr_addr.sa_data + 2, IP_ALEN);
7909
7910        return ret;
7911}
7912
7913static inline void setup_eth(struct ether_header *eth, char *hw_addr)
7914{
7915        memcpy(eth->ether_shost, hw_addr, ETH_ALEN);
7916        memcpy(eth->ether_dhost, BCAST, ETH_ALEN);
7917        eth->ether_type = htons(ETH_P_ARP);
7918}
7919
7920static inline void setup_garp(struct arph *arp, char *hw_addr, char *paddr)
7921{
7922        arp->hw_type = htons(ARPHDR_ETHER);
7923        arp->proto_type = htons(ETH_P_IP);
7924        arp->ha_len = ETH_ALEN;
7925        arp->pa_len = IP_ALEN;
7926
7927        memcpy(arp->source_add, hw_addr, ETH_ALEN);
7928        memcpy(arp->source_ip, paddr, IP_ALEN);
7929}
7930
7931static inline void setup_garp_broadcast(struct arph *arp, char *paddr)
7932{
7933        arp->opcode = htons(ARPOP_BROADCAST);
7934
7935        bzero(arp->dest_add, ETH_ALEN);
7936        memcpy(arp->dest_ip, paddr, IP_ALEN);
7937}
7938
7939static inline void setup_garp_reply(struct arph *arp, char *hw_addr, char *paddr)
7940{
7941        arp->opcode = htons(ARPOP_REPLY);
7942
7943        memcpy(arp->dest_add, hw_addr, ETH_ALEN);
7944        memcpy(arp->dest_ip, paddr, IP_ALEN);
7945}
7946
7947/*
7948 * send_garp
7949 *
7950 * - sends 20 gartuitous arps
7951 * in a 200 millisec interval.
7952 * One as braadcast and one as reply.
7953 *
7954 *
7955 * parameter iface: sending interface name
7956 *
7957 * returns false on failure
7958 *         true on success
7959 */
7960static int send_garp(char *iface)
7961{
7962        char pkt[ARP_HLEN];
7963        char iface_hw[ETH_ALEN];
7964        char iface_paddr[IP_ALEN];
7965        struct sockaddr_ll link;
7966        struct ether_header *eth;
7967        struct arph *arp;
7968        int rc;
7969        int sk;
7970        int n_garps = 10;
7971
7972        eth = (struct ether_header *)pkt;
7973        arp = (struct arph *)(pkt + ETH_HLEN);
7974
7975        sk = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
7976        if (unlikely(sk == -1)) {
7977                perror("socket");
7978                return sk;
7979        }
7980
7981        rc = get_iface_attr(sk, iface, iface_hw, iface_paddr);
7982        if (unlikely(rc == -1))
7983                goto out;
7984
7985        /* set link layer information for driver */
7986        bzero(&link, sizeof(link));
7987        link.sll_family = AF_PACKET;
7988        link.sll_ifindex = if_nametoindex(iface);
7989
7990        setup_eth(eth, iface_hw);
7991        setup_garp(arp, iface_hw, iface_paddr);
7992
7993        while (n_garps--) {
7994                setup_garp_broadcast(arp, iface_paddr);
7995                rc = sendto(sk, pkt, ARP_HLEN, 0, (struct sockaddr *)&link, sizeof(struct sockaddr_ll)
7996                    );
7997                if (unlikely(rc == -1)) {
7998                        perror("sendto");
7999                        goto out;
8000                }
8001
8002                setup_garp_reply(arp, iface_hw, iface_paddr);
8003                rc = sendto(sk, pkt, ARP_HLEN, 0, (struct sockaddr *)&link, sizeof(struct sockaddr_ll)
8004                    );
8005                if (unlikely(rc == -1)) {
8006                        perror("sendto");
8007                        goto out;
8008                }
8009                usleep(200000);
8010        }
8011
8012out:
8013        close(sk);
8014        return rc;
8015}
8016
8017int gratarp_main(char *iface)
8018{
8019        if (iface) {
8020                usleep(500000);
8021                send_garp(iface);
8022        }
8023
8024        return 0;
8025}
8026
8027/* NF Mark/Mask
8028 *
8029 * since multiple services needs a NF packet mark,
8030 * we need to use masks to split the 32bit value into several pieces
8031 *
8032 *                                             31       23       15       7      0
8033 * port_forwards         1 bit(s) offset 31  > 10000000 00000000 00000000 00000000
8034 * hotspot                               8 bit(s) offset 23  > 01111111 10000000 00000000 00000000
8035 * quality of service   13 bit(s) offset 10  > 00000000 01111111 11111100 00000000
8036 *
8037 * the remaining 11 bits are currently not in use
8038 */
8039
8040struct NF_MASKS {
8041        char *service_name;     // name of the service
8042        int bits_used;          // bits used by this service
8043        int bit_offset;         // position of the fist bit
8044};
8045
8046static struct NF_MASKS service_masks[] = {
8047        {"FORWARD", 1, 31},
8048        {"HOTSPOT", 8, 23},
8049        {"QOS", 13, 10},
8050};
8051
8052char *get_NFServiceMark(char *service, uint32 mark)
8053{
8054        static char buffer[32];
8055        bzero(&buffer, sizeof(buffer));
8056
8057#if defined(ARCH_broadcom) && !defined(HAVE_BCMMODERN)
8058// no mask support possible in kernel 2.4
8059        sprintf(buffer, "0x%x", mark);
8060        return buffer;
8061#else
8062        int x, offset, bitpos;
8063        uint32 nfmark = 0, nfmask = 0;
8064
8065        for (x = 0; x < sizeof(service_masks) / sizeof(struct NF_MASKS); x++) {
8066                if (strcmp(service, service_masks[x].service_name) == 0) {
8067                        if (mark >= (1 << service_masks[x].bits_used))
8068                                return "0xffffffff/0xffffffff";
8069
8070                        offset = service_masks[x].bit_offset;
8071                        bitpos = offset + service_masks[x].bits_used - 1;
8072
8073                        nfmark = (mark << offset);
8074
8075                        for (; bitpos >= offset; bitpos--)
8076                                nfmask |= (1 << bitpos);
8077
8078                        sprintf(buffer, "0x%x/0x%x", nfmark, nfmask);
8079                        return buffer;
8080                }
8081        }
8082        return "0xffffffff/0xffffffff";
8083#endif
8084}
8085
8086char *qos_nfmark(uint32 x)
8087{
8088        return get_NFServiceMark("QOS", x);
8089}
8090
8091void getPortMapping(int *vlanmap)
8092{
8093        if (nvram_match("vlan1ports", "0 5")) {
8094                vlanmap[0] = 0;
8095                vlanmap[5] = 5;
8096                if (nvram_match("vlan0ports", "4 3 2 1 5*")) {
8097                        vlanmap[1] = 4;
8098                        vlanmap[2] = 3;
8099                        vlanmap[3] = 2;
8100                        vlanmap[4] = 1;
8101                } else if (nvram_match("vlan0ports", "4 1 2 3 5*")) {
8102                        vlanmap[1] = 4;
8103                        vlanmap[2] = 1;
8104                        vlanmap[3] = 2;
8105                        vlanmap[4] = 3;
8106                } else          // nvram_match ("vlan0ports", "1 2 3 4 5*")
8107                        // nothing to do
8108                {
8109                }
8110        } else if (nvram_match("vlan2ports", "0 5u")) {
8111                vlanmap[0] = 0;
8112                vlanmap[5] = 5;
8113                if (nvram_match("vlan1ports", "4 3 2 1 5*")) {
8114                        vlanmap[1] = 4;
8115                        vlanmap[2] = 3;
8116                        vlanmap[3] = 2;
8117                        vlanmap[4] = 1;
8118                } else if (nvram_match("vlan1ports", "4 1 2 3 5*")) {
8119                        vlanmap[1] = 4;
8120                        vlanmap[2] = 1;
8121                        vlanmap[3] = 2;
8122                        vlanmap[4] = 3;
8123                }
8124                if (nvram_match("vlan1ports", "4 3 2 1 5*") && nvram_matchi("boardnum", 32)) {  //R7000
8125                        vlanmap[1] = 1;
8126                        vlanmap[2] = 2;
8127                        vlanmap[3] = 3;
8128                        vlanmap[4] = 4;
8129                }
8130        } else if (nvram_match("vlan1ports", "4 5")) {
8131                vlanmap[0] = 4;
8132                vlanmap[5] = 5;
8133                if (nvram_match("vlan0ports", "0 1 2 3 5*")) {
8134                        vlanmap[1] = 0;
8135                        vlanmap[2] = 1;
8136                        vlanmap[3] = 2;
8137                        vlanmap[4] = 3;
8138                } else          // nvram_match ("vlan0ports", "3 2 1 0 5*")
8139                {
8140                        vlanmap[1] = 3;
8141                        vlanmap[2] = 2;
8142                        vlanmap[3] = 1;
8143                        vlanmap[4] = 0;
8144                }
8145        } else if (nvram_match("vlan1ports", "1 5")) {  // Linksys WTR54GS
8146                vlanmap[5] = 5;
8147                vlanmap[0] = 1;
8148                vlanmap[1] = 0;
8149        } else if (nvram_match("vlan2ports", "0 8") || nvram_match("vlan2ports", "0 8u") || nvram_match("vlan2ports", "0 8t") || nvram_match("vlan2ports", "0 8*")) {
8150                vlanmap[0] = 0;
8151                vlanmap[5] = 8;
8152                if (nvram_match("vlan1ports", "4 3 2 1 8*")) {
8153                        vlanmap[1] = 4;
8154                        vlanmap[2] = 3;
8155                        vlanmap[3] = 2;
8156                        vlanmap[4] = 1;
8157                }
8158        } else if (nvram_match("vlan2ports", "4 8") || nvram_match("vlan2ports", "4 8u")) {
8159                vlanmap[0] = 4;
8160                vlanmap[5] = 8;
8161                if (nvram_match("vlan1ports", "0 1 2 3 8*")) {
8162                        vlanmap[1] = 0;
8163                        vlanmap[2] = 1;
8164                        vlanmap[3] = 2;
8165                        vlanmap[4] = 3;
8166                } else          // "3 2 1 0 8*"
8167                {
8168                        vlanmap[1] = 3;
8169                        vlanmap[2] = 2;
8170                        vlanmap[3] = 1;
8171                        vlanmap[4] = 0;
8172                }
8173                if (nvram_match("vlan1ports", "0 1 2 3 8*") && nvram_matchi("boardnum", 4536)) {        // WNDR4500/WNDR4500V2/R6300V1
8174                        vlanmap[1] = 3;
8175                        vlanmap[2] = 2;
8176                        vlanmap[3] = 1;
8177                        vlanmap[4] = 0;
8178                }
8179                if (nvram_match("vlan1ports", "3 2 1 0 5 7 8*") && nvram_matchi("boardnum", 32)) {
8180                        vlanmap[1] = 0;
8181                        vlanmap[2] = 1;
8182                        vlanmap[3] = 2;
8183                        vlanmap[4] = 3;
8184                }
8185        } else if (nvram_match("vlan1ports", "4 8")) {
8186                vlanmap[0] = 4;
8187                vlanmap[5] = 8;
8188                if (nvram_match("vlan2ports", "0 1 2 3 8*")) {
8189                        vlanmap[1] = 0;
8190                        vlanmap[2] = 1;
8191                        vlanmap[3] = 2;
8192                        vlanmap[4] = 3;
8193                }
8194        } else if (nvram_match("vlan2ports", "4 5") || nvram_match("vlan2ports", "4 5u")) {
8195                vlanmap[0] = 4;
8196                vlanmap[5] = 5;
8197                if (nvram_match("vlan1ports", "0 1 2 3 5*")) {
8198                        vlanmap[1] = 0;
8199                        vlanmap[2] = 1;
8200                        vlanmap[3] = 2;
8201                        vlanmap[4] = 3;
8202                } else {        // nvram_match ("vlan1ports", "3 2 1 0 5*")
8203                        vlanmap[1] = 3;
8204                        vlanmap[2] = 2;
8205                        vlanmap[3] = 1;
8206                        vlanmap[4] = 0;
8207                }
8208                if (nvram_match("vlan1ports", "0 1 2 3 5*") && nvram_matchi("boardnum", 679)) { //R6300V2
8209                        vlanmap[1] = 3;
8210                        vlanmap[2] = 2;
8211                        vlanmap[3] = 1;
8212                        vlanmap[4] = 0;
8213                }
8214
8215        } else if (nvram_match("vlan2ports", "0 5u")) {
8216                vlanmap[0] = 0;
8217                vlanmap[5] = 5;
8218
8219                vlanmap[1] = 1;
8220                vlanmap[2] = 2;
8221                vlanmap[3] = 3;
8222                vlanmap[4] = 4;
8223        }
8224
8225}
8226
8227u_int64_t freediskSpace(char *path)
8228{
8229        struct statfs sizefs;
8230
8231        if ((statfs(path, &sizefs) != 0) || (sizefs.f_type == 0x73717368) || (sizefs.f_type == 0x74717368) || (sizefs.f_type == 0x68737174)) {
8232                bzero(&sizefs, sizeof(sizefs));
8233        }
8234
8235        return (u_int64_t)sizefs.f_bsize * (u_int64_t)sizefs.f_bfree;
8236}
8237
8238void getSystemMac(char *newmac)
8239{
8240        int brand = getRouterBrand();
8241        switch (brand) {
8242        case ROUTER_ASUS_AC87U:
8243        case ROUTER_ASUS_AC88U:
8244        case ROUTER_ASUS_AC5300:
8245                strcpy(newmac, nvram_safe_get("et1macaddr"));
8246                break;
8247        case ROUTER_NETGEAR_R8000:
8248        case ROUTER_NETGEAR_R8500:
8249        case ROUTER_TRENDNET_TEW828:
8250        case ROUTER_ASUS_AC3100:
8251                strcpy(newmac, nvram_safe_get("et2macaddr"));
8252                break;
8253        case ROUTER_DLINK_DIR885:
8254                if (nvram_get("et0macaddr"))
8255                        strcpy(newmac, nvram_safe_get("et0macaddr"));
8256                else
8257                        strcpy(newmac, nvram_safe_get("et2macaddr"));
8258                break;
8259        default:
8260                strcpy(newmac, nvram_safe_get("et0macaddr"));
8261                break;
8262        }
8263
8264}
8265
8266void strcpyto(char *dest, char *src, char c)
8267{
8268        int cnt = 0;
8269        int len = strlen(src);
8270        while (cnt < len && src[cnt] != c) {
8271                dest[cnt] = src[cnt];
8272                cnt++;
8273        }
8274        dest[cnt] = '\0';
8275}
8276
8277char *chomp(char *s)
8278{
8279        char *c = (s) + strlen((s)) - 1;
8280        while ((c > (s)) && (*c == '\n' || *c == '\r' || *c == ' '))
8281                *c-- = '\0';
8282        return s;
8283}
8284
8285char *foreach_first(char *foreachwordlist, char *word)
8286{
8287        char *next = &foreachwordlist[strspn(foreachwordlist, " ")];
8288        strcpyto(word, next, ' ');
8289        next = strchr(next, ' ');
8290        return next;
8291}
8292
8293char *foreach_last(char *next, char *word)
8294{
8295        next = next ? &next[strspn(next, " ")] : "";
8296        strcpyto(word, next, ' ');
8297        next = strchr(next, ' ');
8298        return next;
8299}
8300
8301#define MAX_BRIDGES     1024
8302
8303#include <linux/if_bridge.h>
8304int isbridge(char *name)
8305{
8306        int i, num;
8307        char ifname[IFNAMSIZ];
8308        int ifindices[MAX_BRIDGES];
8309        int br_socket_fd = -1;
8310        unsigned long args[3] = { BRCTL_GET_BRIDGES,
8311                (unsigned long)ifindices, MAX_BRIDGES
8312        };
8313
8314        if ((br_socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
8315                return 0;
8316
8317        num = ioctl(br_socket_fd, SIOCGIFBR, args);
8318        close(br_socket_fd);
8319        if (num < 0) {
8320                return 0;
8321        }
8322
8323        for (i = 0; i < num; i++) {
8324                if (!if_indextoname(ifindices[i], ifname)) {
8325                        return 0;
8326                }
8327
8328                if (!strcmp(ifname, name))
8329                        return 1;
8330        }
8331        return 0;
8332
8333}
8334
8335int writeint(char *path, int a)
8336{
8337        int fd = open(path, O_WRONLY);
8338        if (fd == -1)
8339                return -1;
8340        char strval[32];
8341        snprintf(strval, sizeof(strval), "%d", a);
8342        write(fd, strval, strlen(strval));
8343        close(fd);
8344        return 0;
8345}
8346
8347int writestr(char *path, char *a)
8348{
8349        int fd = open(path, O_WRONLY);
8350        if (fd == -1)
8351                return -1;
8352        write(fd, a, strlen(a));
8353        close(fd);
8354        return 0;
8355}
8356
8357#if 0
8358int isbridge(char *name)
8359{
8360        char path[64];
8361        struct stat st;
8362        bzero(&st, sizeof(struct stat));
8363        sprintf(path, "/sys/class/net/%s/bridge", name);
8364        return (stat(path, &st) == 0) && (S_ISDIR(st.st_mode));
8365
8366}
8367#endif
8368
8369#if defined(HAVE_X86) || defined(HAVE_RB600) || defined(HAVE_EROUTER) && !defined(HAVE_WDR4900)
8370char *getdisc(void)             // works only for squashfs
8371{
8372        int i;
8373        static char ret[8];
8374        char *disks[] = { "sda2", "sdb2", "sdc2", "sdd2", "sde2", "sdf2", "sdg2", "sdh2",
8375                "sdi2", "mmcblk0p2"
8376        };
8377        for (i = 0; i < 10; i++) {
8378                char dev[64];
8379
8380                sprintf(dev, "/dev/%s", disks[i]);
8381                FILE *in = fopen(dev, "rb");
8382
8383                if (in == NULL)
8384                        continue;       // no second partition or disc does not
8385                // exist, skipping
8386                char buf[4];
8387
8388                fread(buf, 4, 1, in);
8389                if ((buf[0] == 't' && buf[1] == 'q' && buf[2] == 's' && buf[3] == 'h')
8390                    || (buf[0] == 'h' && buf[1] == 's' && buf[2] == 'q' && buf[3] == 't')
8391                    || (buf[0] == 'h' && buf[1] == 's' && buf[2] == 'q' && buf[3] == 's')) {
8392                        fclose(in);
8393                        // filesystem detected
8394                        bzero(ret, 8);
8395                        if (strlen(disks[i]) == 4)
8396                                strncpy(ret, disks[i], 3);
8397                        else
8398                                strncpy(ret, disks[i], 7);
8399                        return ret;
8400                }
8401                fclose(in);
8402        }
8403        return NULL;
8404}
8405#endif
Note: See TracBrowser for help on using the repository browser.