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

Last change on this file since 18726 was 18726, checked in by BrainSlayer, 14 months ago

WR741 fixes

File size: 119.4 KB
Line 
1/*
2 * utils.c
3 *
4 * Copyright (C) 2007 Sebastian Gottschall <gottschall@dd-wrt.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * $Id:
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <errno.h>
27#include <net/if.h>
28#include <dirent.h>
29#include <unistd.h>
30#include <ctype.h>
31#include <syslog.h>
32#include <sys/socket.h>
33#include <sys/stat.h>
34#include <fcntl.h>
35#include <netinet/in.h>
36#include <stdarg.h>
37#include <sys/ioctl.h>
38#include <sys/sysinfo.h>
39#include <arpa/inet.h>
40#include <netpacket/packet.h>
41#include <netdb.h>
42#include <resolv.h>
43#include <signal.h>
44#ifdef HAVE_ATH9K
45#include <glob.h>
46#endif
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
64#ifndef IP_ALEN
65#define IP_ALEN 4
66#endif
67
68#ifndef unlikely
69#define unlikely(x)     __builtin_expect((x),0)
70#endif
71
72#define SIOCGMIIREG     0x8948  /* Read MII PHY register.  */
73#define SIOCSMIIREG     0x8949  /* Write MII PHY register.  */
74
75struct mii_ioctl_data {
76        unsigned short phy_id;
77        unsigned short reg_num;
78        unsigned short val_in;
79        unsigned short val_out;
80};
81
82#define TRX_MAGIC_F7D3301                       0x20100322      /* Belkin Share Max; router's birthday ? */
83#define TRX_MAGIC_F7D3302                       0x20090928      /* Belkin Share; router's birthday ? */
84#define TRX_MAGIC_F7D4302                       0x20091006      /* Belkin Play; router's birthday ? */
85
86#ifdef HAVE_FONERA
87static void inline getBoardMAC(char *mac)
88{
89        // 102
90        int i;
91        char op[32];
92        unsigned char data[256];
93        FILE *in;
94
95        sprintf(op, "/dev/mtdblock/%d", getMTD("board_config"));
96        in = fopen(op, "rb");
97        if (in == NULL)
98                return;
99        fread(data, 256, 1, in);
100        fclose(in);
101        sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", data[102] & 0xff,
102                data[103] & 0xff, data[104] & 0xff, data[105] & 0xff,
103                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) || ((month & 9) == 1)) -
145                (month == 2) - (!(((year % 4) == 0)
146                                  && (((year % 100) != 0)
147                                      || ((year % 400) == 0)))
148                                && (month == 2)));
149}
150
151#ifdef HAVE_AQOS
152
153/* obsolete
154static char *get_wshaper_dev(void)
155{
156//      if (nvram_match("wshaper_dev", "WAN"))
157                return get_wan_face();
158//      else
159//              return "br0";
160}
161*/
162
163static char *get_wanface(void)
164{
165        char *dev = get_wan_face();
166
167        if (!strcmp(dev, "br0"))
168                dev = NULL;
169        return dev;
170}
171
172void add_userip(char *ip, int idx, char *upstream, char *downstream,
173                char *lanstream)
174{
175        system2("iptables -t mangle -D FILTER_IN -j CONNMARK --save");
176        system2
177            ("iptables -t mangle -D FILTER_IN -p tcp -m length --length 0:64 --tcp-flags ACK ACK -j MARK --set-mark 0x64");
178        system2("iptables -t mangle -D FILTER_IN -j RETURN");
179
180        system2("iptables -t mangle -D FILTER_OUT -j CONNMARK --save");
181        system2("iptables -t mangle -D FILTER_OUT -j RETURN");
182
183        int base = 1200 + idx;
184        char *dev = get_wanface();
185
186        long int lanlevel = atol(lanstream);
187        if (lanlevel < 1)
188                lanlevel = 1000000;
189
190        if (dev) {
191                /* egress */
192                if (nvram_match("qos_type", "0"))
193                        sysprintf
194                            ("tc class add dev %s parent 1:2 classid 1:%d htb rate %skbit ceil %skbit prio 5",
195                             dev, base, upstream, upstream);
196                else
197                        sysprintf
198                            ("tc class add dev %s parent 1:1 classid 1:%d hfsc sc rate %skbit ul rate %skbit",
199                             dev, base, upstream, upstream);
200
201                sysprintf
202                    ("tc qdisc add dev %s handle %d: parent 1:%d sfq quantum 1514b perturb 15",
203                     dev, base, base);
204                sysprintf
205                    ("tc filter add dev %s protocol ip pref 5 handle 0x%x fw classid 1:%d",
206                     dev, base, base);
207        }
208
209        /* ingress */
210        if (nvram_match("qos_type", "0")) {
211                sysprintf
212                    ("tc class add dev %s parent 1:2 classid 1:%d htb rate %skbit ceil %skbit prio 5",
213                     "imq0", base, downstream, downstream);
214                sysprintf
215                    ("tc class add dev %s parent 1:2 classid 1:%d htb rate %dkbit ceil %dkbit prio 5",
216                     "imq1", base, lanlevel, lanlevel);
217        } else {
218                sysprintf
219                    ("tc class add dev %s parent 1:1 classid 1:%d hfsc sc rate %skbit ul rate %skbit",
220                     "imq0", base, downstream, downstream);
221                sysprintf
222                    ("tc class add dev %s parent 1:2 classid 1:%d hfsc sc rate %dkbit ul rate %dkbit",
223                     "imq1", base, lanlevel, lanlevel);
224        }
225
226        sysprintf
227            ("tc qdisc add dev %s handle %d: parent 1:%d sfq quantum 1514b perturb 15",
228             "imq0", base, base);
229
230        sysprintf
231            ("tc filter add dev %s protocol ip pref 5 handle 0x%x fw classid 1:%d",
232             "imq0", base, base);
233        sysprintf
234            ("tc filter add dev %s protocol ip pref 5 handle 0x%x fw classid 1:%d",
235             "imq1", base, base);
236
237        sysprintf
238            ("iptables -t mangle -A FILTER_IN -d %s -m mark --mark 1 -j MARK --set-mark %d",
239             ip, base);
240        sysprintf
241            ("iptables -t mangle -A FILTER_IN -s %s -m mark --mark 1 -j MARK --set-mark %d",
242             ip, base);
243        sysprintf
244            ("iptables -t mangle -A FILTER_OUT -d %s -m mark --mark 0 -j MARK --set-mark %d",
245             ip, base);
246        sysprintf
247            ("iptables -t mangle -A FILTER_OUT -s %s -m mark --mark 0 -j MARK --set-mark %d",
248             ip, base);
249
250        system2("iptables -t mangle -A FILTER_IN -j CONNMARK --save");
251        system2
252            ("iptables -t mangle -A FILTER_IN -p tcp -m length --length 0:64 --tcp-flags ACK ACK -j MARK --set-mark 0x64");
253        system2("iptables -t mangle -A FILTER_IN -j RETURN");
254
255        system2("iptables -t mangle -A FILTER_OUT -j CONNMARK --save");
256        system2("iptables -t mangle -A FILTER_OUT -j RETURN");
257}
258
259void add_usermac(char *mac, int idx, char *upstream, char *downstream,
260                 char *lanstream)
261{
262        int base = 1200 + idx;
263        char *dev = get_wanface();
264        long int lanlevel = atol(lanstream);
265
266        if (lanlevel < 1)
267                lanlevel = 1000000;
268
269        if (dev) {
270                /* egress */
271                if (nvram_match("qos_type", "0"))
272                        sysprintf
273                            ("tc class add dev %s parent 1:2 classid 1:%d htb rate %skbit ceil %skbit prio 5",
274                             dev, base, upstream, upstream);
275                else
276                        sysprintf
277                            ("tc class add dev %s parent 1:1 classid 1:%d hfsc sc rate %skbit ul rate %skbit",
278                             dev, base, upstream, upstream);
279
280                sysprintf
281                    ("tc qdisc add dev %s handle %d: parent 1:%d sfq quantum 1514b perturb 15",
282                     dev, base, base);
283                sysprintf
284                    ("tc filter add dev %s protocol ip pref 5 handle 0x%x fw classid 1:%d",
285                     dev, base, base);
286        }
287
288        /* ingress */
289        if (nvram_match("qos_type", "0")) {
290                sysprintf
291                    ("tc class add dev %s parent 1:2 classid 1:%d htb rate %skbit ceil %skbit prio 5",
292                     "imq0", base, downstream, downstream);
293                sysprintf
294                    ("tc class add dev %s parent 1:2 classid 1:%d htb rate %dkbit ceil %dkbit prio 5",
295                     "imq1", base, lanlevel, lanlevel);
296        } else {
297                sysprintf
298                    ("tc class add dev %s parent 1:1 classid 1:%d hfsc sc rate %skbit ul rate %skbit",
299                     "imq0", base, downstream, downstream);
300                sysprintf
301                    ("tc class add dev %s parent 1:2 classid 1:%d hfsc sc rate %dkbit ul rate %dkbit",
302                     "imq1", base, lanlevel, lanlevel);
303        }
304
305        sysprintf
306            ("tc qdisc add dev %s handle %d: parent 1:%d sfq quantum 1514b perturb 15",
307             "imq0", base, base);
308
309        sysprintf
310            ("tc filter add dev %s protocol ip pref 5 handle 0x%x fw classid 1:%d",
311             "imq0", base, base);
312        sysprintf
313            ("tc filter add dev %s protocol ip pref 5 handle 0x%x fw classid 1:%d",
314             "imq1", base, base);
315
316        sysprintf
317            ("iptables -t mangle -I FILTER_IN 2 -m mac --mac-source %s -m mark --mark 1 -j MARK --set-mark %d",
318             mac, base);
319}
320
321#endif
322int buf_to_file(char *path, char *buf)
323{
324        FILE *fp;
325
326        if ((fp = fopen(path, "w"))) {
327                fprintf(fp, "%s", buf);
328                fclose(fp);
329                return 1;
330        }
331
332        return 0;
333}
334
335int check_action(void)
336{
337        char buf[80] = "";
338
339        if (file_to_buf(ACTION_FILE, buf, sizeof(buf))) {
340                if (!strcmp(buf, "ACT_TFTP_UPGRADE")) {
341                        fprintf(stderr, "Upgrading from tftp now ...\n");
342                        return ACT_TFTP_UPGRADE;
343                }
344#ifdef HAVE_HTTPS
345                else if (!strcmp(buf, "ACT_WEBS_UPGRADE")) {
346                        fprintf(stderr, "Upgrading from web (https) now ...\n");
347                        return ACT_WEBS_UPGRADE;
348                }
349#endif
350                else if (!strcmp(buf, "ACT_WEB_UPGRADE")) {
351                        fprintf(stderr, "Upgrading from web (http) now ...\n");
352                        return ACT_WEB_UPGRADE;
353                } else if (!strcmp(buf, "ACT_SW_RESTORE")) {
354                        fprintf(stderr,
355                                "Receiving restore command from web ...\n");
356                        return ACT_SW_RESTORE;
357                } else if (!strcmp(buf, "ACT_HW_RESTORE")) {
358                        fprintf(stderr,
359                                "Receiving restore command from resetbutton ...\n");
360                        return ACT_HW_RESTORE;
361                } else if (!strcmp(buf, "ACT_NVRAM_COMMIT")) {
362                        fprintf(stderr, "Committing nvram now ...\n");
363                        return ACT_NVRAM_COMMIT;
364                } else if (!strcmp(buf, "ACT_ERASE_NVRAM")) {
365                        fprintf(stderr, "Erasing nvram now ...\n");
366                        return ACT_ERASE_NVRAM;
367                }
368        }
369        // fprintf(stderr, "Waiting for upgrading....\n");
370        return ACT_IDLE;
371}
372
373int check_vlan_support(void)
374{
375#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)
376        return 0;
377#else
378
379        int brand = getRouterBrand();
380
381        switch (brand) {
382#ifndef HAVE_BUFFALO
383        case ROUTER_ASUS_WL500GD:
384                return 1;
385                break;
386#endif
387        case ROUTER_BUFFALO_WLAG54C:
388        case ROUTER_BUFFALO_WLA2G54C:
389#ifndef HAVE_BUFFALO
390        case ROUTER_LINKSYS_WRT55AG:
391        case ROUTER_MOTOROLA_V1:
392        case ROUTER_MOTOROLA_WE800G:
393        case ROUTER_WAP54G_V1:
394        case ROUTER_SITECOM_WL105B:
395        case ROUTER_SITECOM_WL111:
396        case ROUTER_BUFFALO_WLI2_TX1_G54:
397        case ROUTER_BUFFALO_WLI_TX4_G54HP:
398        case ROUTER_BRCM4702_GENERIC:
399        case ROUTER_ASUS_WL500G:
400        case ROUTER_BELKIN_F5D7230_V2000:
401        case ROUTER_ASKEY_RT220XD:
402#endif
403                return 0;
404                break;
405        }
406
407        unsigned long boardflags =
408            strtoul(nvram_safe_get("boardflags"), NULL, 0);
409
410        if (boardflags & BFL_ENETVLAN)
411                return 1;
412
413        if (nvram_match("boardtype", "bcm94710dev")
414            || nvram_match("boardtype", "0x0101") || (boardflags & 0x0100))
415                return 1;
416        else
417                return 0;
418#endif
419}
420
421void setRouter(char *name)
422{
423#ifdef HAVE_POWERNOC_WORT54G
424        nvram_set(NVROUTER, "WORT54G");
425#elif HAVE_POWERNOC_WOAP54G
426        nvram_set(NVROUTER, "WOAP54G");
427#elif HAVE_ERC
428        nvram_set(NVROUTER, "ServiceGate v1.0");
429#elif HAVE_OMNI
430        nvram_set(NVROUTER, "Omni Wifi Router");
431#elif HAVE_ALFA_BRANDING
432        nvram_set(NVROUTER, "WLAN base-station");
433        if (name)
434                nvram_set("DD_BOARD2", name);
435#elif HAVE_MAKSAT
436        if (name)
437                nvram_set("DD_BOARD2", name);
438#ifdef HAVE_MAKSAT_BLANK
439        nvram_set(NVROUTER, "default");
440#else
441        nvram_set(NVROUTER, "MAKSAT");
442#endif
443#elif HAVE_TMK
444        if (name)
445                nvram_set("DD_BOARD2", name);
446        nvram_set(NVROUTER, "KMT-WAS");
447#elif HAVE_BKM
448        if (name)
449                nvram_set("DD_BOARD2", name);
450        nvram_set(NVROUTER, "BKM-HSDL");
451#elif HAVE_TRIMAX
452        if (name)
453                nvram_set("DD_BOARD2", name);
454        nvram_set(NVROUTER, "M2M Dynamics");
455#elif HAVE_WIKINGS
456        if (name)
457                nvram_set("DD_BOARD2", name);
458#ifdef HAVE_SUB3
459        nvram_set(NVROUTER, "ExcelMin");
460#elif HAVE_SUB6
461        nvram_set(NVROUTER, "ExcelMed");
462#else
463        nvram_set(NVROUTER, "Excellent");
464#endif
465#elif HAVE_ESPOD
466        if (name)
467                nvram_set("DD_BOARD2", name);
468#ifdef HAVE_SUB3
469        nvram_set(NVROUTER, "ESPOD ES-3680");
470#elif HAVE_SUB6
471        nvram_set(NVROUTER, "ESPOD ES-3680");
472#else
473        nvram_set(NVROUTER, "ESPOD ES-3680");
474#endif
475#elif HAVE_CARLSONWIRELESS
476        nvram_set(NVROUTER, "LH-135/270 ST");
477#else
478        if (name)
479                nvram_set(NVROUTER, name);
480#endif
481        cprintf("router is %s\n", getRouter());
482}
483
484char *getRouter()
485{
486        char *n = nvram_get(NVROUTER);
487
488        return n != NULL ? n : "Unknown Model";
489}
490
491int internal_getRouterBrand()
492{
493#if defined(HAVE_ALLNETWRT) && !defined(HAVE_ECB9750)
494        unsigned long boardnum = strtoul(nvram_safe_get("boardnum"), NULL, 0);
495
496        if (boardnum == 8 && nvram_match("boardtype", "0x048e")
497            && nvram_match("boardrev", "0x11")) {
498                setRouter("ALLNET EUROWRT 54");
499                return ROUTER_ALLNET01;
500        }
501        eval("event", "3", "1", "15");
502        return 0;
503#elif defined(HAVE_ALLNETWRT) && defined(HAVE_EOC5610)
504        setRouter("Allnet Outdoor A/B/G CPE");
505        return ROUTER_BOARD_LS2;
506#else
507#ifdef HAVE_NP28G
508        setRouter("Compex NP28G");
509        return ROUTER_BOARD_NP28G;
510#elif HAVE_WP54G
511        setRouter("Compex WP54G");
512        return ROUTER_BOARD_WP54G;
513#elif HAVE_ADM5120
514        if (!nvram_match("DD_BOARD", "OSBRiDGE 5LXi"))
515                setRouter("Tonze AP-120");
516        return ROUTER_BOARD_ADM5120;
517#elif HAVE_RB500
518        setRouter("Mikrotik RB500");
519        return ROUTER_BOARD_500;
520#elif HAVE_GEMTEK
521        setRouter("SuperGerry");
522        return ROUTER_SUPERGERRY;
523#elif HAVE_LAGUNA
524        char *filename = "/sys/devices/platform/cns3xxx-i2c.0/i2c-0/0-0050/eeprom";     /* bank2=0x100 kernel 3.0 */
525        FILE *file = fopen(filename, "rb");
526        if (!file) {
527                filename = "/sys/devices/platform/cns3xxx-i2c.0/i2c-adapter/i2c-0/0-0050/eeprom";       /* bank2=0x100 older kernel */
528                file = fopen(filename, "r");
529        }
530        if (file) {
531                fseek(file, 0x130, SEEK_SET);
532                char gwid[9];
533                fread(&gwid[0], 9, 1, file);
534                fclose(file);
535                if (!strncmp(gwid, "GW2388", 6)) {
536                        setRouter("Gateworks Laguna GW2388");
537                        return ROUTER_BOARD_GW2388;
538                } else if (!strncmp(gwid, "GW2380", 6)) {
539                        setRouter("Gateworks Laguna GW2380");
540                        return ROUTER_BOARD_GW2380;
541                } else {
542                        setRouter("Gateworks Laguna GWXXXX");
543                        return ROUTER_BOARD_GW2388;
544                }
545        } else {
546                setRouter("Gateworks Laguna UNKNOWN");
547                return ROUTER_BOARD_GW2388;
548
549        }
550#elif HAVE_MI424WR
551        setRouter("Actiontec MI424WR");
552        return ROUTER_BOARD_GATEWORX_GW2345;
553#elif HAVE_USR8200
554        setRouter("US Robotics USR8200");
555        return ROUTER_BOARD_GATEWORX;
556#elif HAVE_TONZE
557        setRouter("Tonze AP-425");
558        return ROUTER_BOARD_GATEWORX;
559#elif HAVE_NOP8670
560        setRouter("Senao NOP-8670");
561        return ROUTER_BOARD_GATEWORX;
562#elif HAVE_WRT300NV2
563        setRouter("Linksys WRT300N v2");
564        return ROUTER_BOARD_GATEWORX;
565#elif HAVE_WG302V1
566        setRouter("Netgear WG302 v1");
567        return ROUTER_BOARD_GATEWORX;
568#elif HAVE_WG302
569        setRouter("Netgear WG302 v2");
570        return ROUTER_BOARD_GATEWORX;
571#elif HAVE_PRONGHORN
572        setRouter("ADI Engineering Pronghorn Metro");
573        return ROUTER_BOARD_GATEWORX;
574#elif HAVE_GATEWORX
575        char *filename = "/sys/devices/platform/IXP4XX-I2C.0/i2c-adapter:i2c-0/0-0051/eeprom";  /* bank2=0x100
576                                                                                                 */
577        FILE *file = fopen(filename, "r");
578        if (!file) {
579                filename = "/sys/devices/platform/IXP4XX-I2C.0/i2c-0/0-0051/eeprom";    //for 2.6.34.6
580                file = fopen(filename, "r");
581        }
582        if (file)               // new detection scheme
583        {
584
585                char *gwid;
586                char temp[64];
587                int ret = fread(temp, 40, 1, file);
588                if (ret < 1) {
589                        fclose(file);
590                        goto old_way;
591                }
592                gwid = &temp[32];
593                gwid[8] = 0;
594                fclose(file);
595                if (!strncmp(gwid, "GW2347", 6)) {
596                        setRouter("Gateworks Avila GW2347");
597                        return ROUTER_BOARD_GATEWORX_SWAP;
598                }
599                if (!strncmp(gwid, "GW2357", 6)) {
600                        setRouter("Gateworks Avila GW2357");
601                        return ROUTER_BOARD_GATEWORX_SWAP;
602                }
603                if (!strncmp(gwid, "GW2353", 6)) {
604                        setRouter("Gateworks Avila GW2353");
605                        return ROUTER_BOARD_GATEWORX;
606                }
607                if (!strncmp(gwid, "GW2348-2", 8)) {
608                        setRouter("Gateworks Avila GW2348-2");
609                        return ROUTER_BOARD_GATEWORX;
610                }
611                if (!strncmp(gwid, "GW2348-4", 8)) {
612                        setRouter("Gateworks Avila GW2348-4");
613                        return ROUTER_BOARD_GATEWORX;
614                }
615                if (!strncmp(gwid, "GW2348", 6)) {
616                        setRouter("Gateworks Avila GW2348-4/2");
617                        return ROUTER_BOARD_GATEWORX;
618                }
619                if (!strncmp(gwid, "GW2358", 6)) {
620                        setRouter("Gateworks Cambria GW2358-4");
621                        return ROUTER_BOARD_GATEWORX;
622                }
623                if (!strncmp(gwid, "GW2350", 6)) {
624                        setRouter("Gateworks Cambria GW2350");
625                        return ROUTER_BOARD_GATEWORX;
626                }
627                if (!strncmp(gwid, "GW2369", 6)) {
628                        setRouter("Gateworks Avila GW2369");
629                        return ROUTER_BOARD_GATEWORX_GW2369;
630                }
631                if (!strncmp(gwid, "GW2355", 6)) {
632                        setRouter("Gateworks Avila GW2355");
633                        return ROUTER_BOARD_GATEWORX_GW2345;
634                }
635                if (!strncmp(gwid, "GW2345", 6)) {
636                        setRouter("Gateworks Avila GW2345");
637                        return ROUTER_BOARD_GATEWORX_GW2345;
638                }
639        }
640      old_way:;
641        struct mii_ioctl_data *data;
642        struct ifreq iwr;
643        int s = socket(AF_INET, SOCK_DGRAM, 0);
644
645        if (s < 0) {
646                fprintf(stderr, "socket(SOCK_DRAGM)\n");
647                setRouter("Gateworks Avila");
648                return ROUTER_BOARD_GATEWORX;
649        }
650        (void)strncpy(iwr.ifr_name, "ixp0", sizeof("ixp0"));
651        data = (struct mii_ioctl_data *)&iwr.ifr_data;
652        data->phy_id = 1;
653#define IX_ETH_ACC_MII_PHY_ID1_REG  0x2 /* PHY identifier 1 Register */
654#define IX_ETH_ACC_MII_PHY_ID2_REG  0x3 /* PHY identifier 2 Register */
655        data->reg_num = IX_ETH_ACC_MII_PHY_ID1_REG;
656        ioctl(s, SIOCGMIIREG, &iwr);
657        data->phy_id = 1;
658        data->reg_num = IX_ETH_ACC_MII_PHY_ID1_REG;
659        ioctl(s, SIOCGMIIREG, &iwr);
660        int reg1 = data->val_out;
661
662        data->phy_id = 1;
663        data->reg_num = IX_ETH_ACC_MII_PHY_ID2_REG;
664        ioctl(s, SIOCGMIIREG, &iwr);
665        int reg2 = data->val_out;
666
667        close(s);
668        fprintf(stderr, "phy id %X:%X\n", reg1, reg2);
669        if (reg1 == 0x2000 && reg2 == 0x5c90) {
670                setRouter("Avila GW2347");
671                return ROUTER_BOARD_GATEWORX_SWAP;
672        } else if (reg1 == 0x13 && reg2 == 0x7a11) {
673#if HAVE_ALFA_BRANDING
674                setRouter("WLAN base-station");
675#else
676                setRouter("Gateworks Avila GW2348-4/2");
677#endif
678                return ROUTER_BOARD_GATEWORX;
679        } else if (reg1 == 0x143 && reg2 == 0xbc31)     // broadcom phy
680        {
681                setRouter("ADI Engineering Pronghorn Metro");
682                return ROUTER_BOARD_GATEWORX;
683        } else if (reg1 == 0x22 && reg2 == 0x1450)      // kendin switch
684        {
685                setRouter("Gateworks Avila GW2345");
686                return ROUTER_BOARD_GATEWORX_GW2345;
687        } else if (reg1 == 0x0 && reg2 == 0x8201)       // realtek
688        {
689                setRouter("Compex WP188");
690                return ROUTER_BOARD_GATEWORX;
691        } else {
692                setRouter("Unknown");
693                return ROUTER_BOARD_GATEWORX;
694        }
695#elif HAVE_RT2880
696
697#ifdef HAVE_ECB9750
698#ifdef HAVE_ALLNETWRT
699        setRouter("Allnet 802.11n Router");
700#else
701        setRouter("Senao ECB-9750");
702#endif
703        return ROUTER_BOARD_ECB9750;
704#elif HAVE_ALLNET11N
705        setRouter("Allnet 802.11n Router");
706        return ROUTER_BOARD_WHRG300N;
707#elif HAVE_TECHNAXX3G
708        setRouter("Technaxx 3G Router");
709        return ROUTER_BOARD_TECHNAXX3G;
710#elif HAVE_AR670W
711        setRouter("Airlink 101 AR670W");
712        return ROUTER_BOARD_AR670W;
713#elif HAVE_AR690W
714        setRouter("Airlink 101 AR690W");
715        return ROUTER_BOARD_AR690W;
716#elif HAVE_RT15N
717        setRouter("Asus RT-N15");
718        return ROUTER_BOARD_RT15N;
719#elif HAVE_BR6574N
720        setRouter("Edimax BR-6574N");
721        return ROUTER_BOARD_BR6574N;
722#elif HAVE_ESR6650
723        setRouter("Senao ESR-6650");
724        return ROUTER_BOARD_ESR6650;
725#elif HAVE_EAP9550
726        setRouter("Senao EAP-9550");
727        return ROUTER_BOARD_EAP9550;
728#elif HAVE_ESR9752
729        setRouter("Senao ESR-9752");
730        return ROUTER_BOARD_ESR9752;
731#elif HAVE_ACXNR22
732        setRouter("Aceex NR22");
733        return ROUTER_BOARD_ACXNR22;
734#elif HAVE_W502U
735        setRouter("Alfa AIP-W502U");
736        return ROUTER_BOARD_W502U;
737#elif HAVE_DIR615
738        setRouter("Dlink-DIR615 rev d");
739        return ROUTER_BOARD_DIR615D;
740#elif HAVE_RT3352
741        setRouter("Ralink RT3352 Device");
742        return ROUTER_BOARD_RT3352;
743#elif HAVE_NEPTUNE
744        setRouter("Neptune-Mini");
745        return ROUTER_BOARD_NEPTUNE;
746#elif HAVE_TECHNAXX
747        setRouter("TECHNAXX Router-150 Wifi-N");
748        return ROUTER_BOARD_TECHNAXX;
749#elif HAVE_RT10N
750        setRouter("Asus RT-N10+");
751        return ROUTER_ASUS_RTN10PLUS;
752#elif HAVE_DIR600
753#ifdef HAVE_DIR300
754        setRouter("Dlink-DIR300 rev b");
755#else
756        setRouter("Dlink-DIR600 rev b");
757#endif
758        return ROUTER_BOARD_DIR600B;
759#elif HAVE_RT13NB1
760        setRouter("Asus RT-N13U B1");
761        return ROUTER_BOARD_WHRG300N;
762#elif HAVE_ASUSRTN13U
763        setRouter("Asus RT-N13U");
764        return ROUTER_BOARD_WHRG300N;
765#elif HAVE_F5D8235
766        setRouter("Belkin F5D8235-4 v2");
767        return ROUTER_BOARD_F5D8235;
768#elif HAVE_WCRGN
769        setRouter("Buffalo WCR-GN");
770        return ROUTER_BOARD_WCRGN;
771#elif HAVE_WHRG300N
772        setRouter("Buffalo WHR-G300N");
773        return ROUTER_BOARD_WHRG300N;
774#elif HAVE_WR5422
775        setRouter("Repotec RP-WR5422");
776        return ROUTER_BOARD_WR5422;
777#else
778        setRouter("Generic RT2880");
779        return ROUTER_BOARD_RT2880;
780#endif
781#elif HAVE_X86
782#ifdef HAVE_CORENET
783        setRouter("CORENET X86i");
784        return ROUTER_BOARD_X86;
785#else
786        setRouter("Generic X86");
787        return ROUTER_BOARD_X86;
788#endif
789#elif HAVE_XSCALE
790        setRouter("NewMedia Dual A/B/G");
791        return ROUTER_BOARD_XSCALE;
792#elif HAVE_MAGICBOX
793        setRouter("OpenRB PowerPC Board");
794        return ROUTER_BOARD_MAGICBOX;
795#elif HAVE_RB1000
796        setRouter("Mikrotik RB1000");
797        return ROUTER_BOARD_RB600;
798#elif HAVE_RB800
799        setRouter("Mikrotik RB800");
800        return ROUTER_BOARD_RB600;
801#elif HAVE_RB600
802        setRouter("Mikrotik RB600");
803        return ROUTER_BOARD_RB600;
804#elif HAVE_GWMF54G2
805        setRouter("Planex GW-MF54G2");
806        char mac[32];
807        getBoardMAC(mac);
808        if (!strncmp(mac, "00:19:3B", 8) || !strncmp(mac, "00:02:6F", 8)
809            || !strncmp(mac, "00:15:6D", 8)) {
810                fprintf(stderr, "unsupported board\n");
811                sys_reboot();
812        }
813        return ROUTER_BOARD_FONERA;
814#elif HAVE_WRT54GV7
815        setRouter("Linksys WRT54G v7");
816        return ROUTER_BOARD_FONERA;
817#elif HAVE_WRK54G
818        setRouter("Linksys WRK54G v3");
819        return ROUTER_BOARD_FONERA;
820#elif HAVE_WGT624
821        setRouter("Netgear WGT624 v4");
822        return ROUTER_BOARD_FONERA;
823#elif HAVE_WPE53G
824        setRouter("Compex WPE53G");
825        return ROUTER_BOARD_FONERA;
826#elif HAVE_NP25G
827        setRouter("Compex NP25G");
828        return ROUTER_BOARD_FONERA;
829#elif HAVE_MR3202A
830        setRouter("MR3202A");
831        return ROUTER_BOARD_FONERA;
832#elif HAVE_DLM101
833        setRouter("Doodle Labs DLM-101");
834        return ROUTER_BOARD_FONERA;
835#elif HAVE_AR430W
836        setRouter("Airlink-101 AR430W");
837        return ROUTER_BOARD_FONERA;
838#elif HAVE_DIR400
839        setRouter("D-Link DIR-400");
840        return ROUTER_BOARD_FONERA2200;
841#elif HAVE_WRT54G2
842        setRouter("Linksys WRT54G2 v1.1");
843        return ROUTER_BOARD_FONERA;
844#elif HAVE_RTG32
845        setRouter("Asus RT-G32");
846        return ROUTER_BOARD_FONERA;
847#elif HAVE_DIR300
848        setRouter("D-Link DIR-300");
849        return ROUTER_BOARD_FONERA;
850#elif HAVE_CNC
851        setRouter("WiFi4You Outdoor AP");
852        return ROUTER_BOARD_FONERA;
853#elif defined(HAVE_CORENET) && defined(HAVE_NS2)
854        setRouter("CORENET XNS2");
855        return ROUTER_BOARD_LS2;
856#elif defined(HAVE_CORENET) && defined(HAVE_LC2)
857        setRouter("CORENET XLO2");
858        return ROUTER_BOARD_LS2;
859#elif defined(HAVE_CORENET) && defined(HAVE_EOC2610)
860        setRouter("CORENET XC61");
861        return ROUTER_BOARD_FONERA;
862#elif defined(HAVE_CORENET) && defined(HAVE_EOC1650)
863        setRouter("CORENET XC65");
864        return ROUTER_BOARD_FONERA;
865#elif defined(HAVE_CORENET) && defined(HAVE_BS2)
866        setRouter("CORENET XBU2");
867        return ROUTER_BOARD_LS2;
868#elif defined(HAVE_CORENET) && defined(HAVE_BS2HP)
869        setRouter("CORENET MBU2i");
870        return ROUTER_BOARD_LS2;
871#elif HAVE_WBD500
872        setRouter("Wiligear WBD-500");
873        return ROUTER_BOARD_FONERA;
874#elif HAVE_EOC1650
875        setRouter("Senao EOC-1650");
876        return ROUTER_BOARD_FONERA;
877#elif HAVE_EOC2611
878        setRouter("Senao EOC-2611");
879        return ROUTER_BOARD_FONERA;
880#elif HAVE_EOC2610
881#ifdef HAVE_TRIMAX
882        setRouter("M2M-1200");
883#else
884        setRouter("Senao EOC-2610");
885#endif
886        return ROUTER_BOARD_FONERA;
887#elif HAVE_ECB3500
888        setRouter("Senao ECB-3500");
889        return ROUTER_BOARD_FONERA;
890#elif HAVE_EAP3660
891        setRouter("Senao EAP-3660");
892        return ROUTER_BOARD_FONERA;
893#elif HAVE_MR3201A
894        setRouter("Accton MR3201A");
895        return ROUTER_BOARD_FONERA;
896#elif HAVE_FONERA
897        struct mii_ioctl_data *data;
898        struct ifreq iwr;
899        char mac[32];
900        getBoardMAC(mac);
901        if (!strncmp(mac, "00:19:3B", 8) || !strncmp(mac, "00:02:6F", 8)
902            || !strncmp(mac, "00:15:6D", 8) || !strncmp(mac, "00:C0:CA", 8)) {
903                fprintf(stderr, "unsupported board\n");
904                sys_reboot();
905        }
906        int s = socket(AF_INET, SOCK_DGRAM, 0);
907
908        if (s < 0) {
909                fprintf(stderr, "socket(SOCK_DRAGM)\n");
910                setRouter("Fonera 2100/2200");
911                return ROUTER_BOARD_FONERA;
912        }
913        (void)strncpy(iwr.ifr_name, "eth0", sizeof("eth0"));
914        data = (struct mii_ioctl_data *)&iwr.ifr_data;
915        data->phy_id = 0x10;
916        data->reg_num = 0x2;
917        ioctl(s, SIOCGMIIREG, &iwr);
918        data->phy_id = 0x10;
919        data->reg_num = 0x2;
920        ioctl(s, SIOCGMIIREG, &iwr);
921        if (data->val_out == 0x0141) {
922                data->phy_id = 0x10;
923                data->reg_num = 0x3;
924                ioctl(s, SIOCGMIIREG, &iwr);
925                close(s);
926                if ((data->val_out & 0xfc00) != 0x0c00) // marvell phy
927                {
928                        setRouter("Fonera 2100/2200");
929                        return ROUTER_BOARD_FONERA;
930                } else {
931                        setRouter("Fonera 2201");
932                        return ROUTER_BOARD_FONERA2200;
933                }
934        } else {
935                setRouter("Fonera 2100/2200");
936                return ROUTER_BOARD_FONERA;
937        }
938#elif HAVE_MERAKI
939        setRouter("Meraki Mini");
940        return ROUTER_BOARD_MERAKI;
941#elif HAVE_BWRG1000
942        setRouter("Bountiful BWRG-1000");
943        return ROUTER_BOARD_LS2;
944#elif HAVE_WNR2200
945        setRouter("Netgear WNR2200");
946        nvram_default_get("ath0_rxantenna", "3");
947        nvram_default_get("ath0_txantenna", "3");
948        return ROUTER_BOARD_WHRHPGN;
949#elif HAVE_WNR2000
950        setRouter("Netgear WNR2000v3");
951        nvram_default_get("ath0_rxantenna", "3");
952        nvram_default_get("ath0_txantenna", "3");
953        return ROUTER_BOARD_WHRHPGN;
954#elif HAVE_WLAEAG300N
955#ifdef HAVE_BUFFALO
956        setRouter("WLAE-AG300N");
957#else
958        setRouter("Buffalo WLAE-AG300N");
959#endif
960        nvram_default_get("ath0_rxantenna", "3");
961        nvram_default_get("ath0_txantenna", "3");
962        return ROUTER_BOARD_WHRHPGN;
963#elif HAVE_HORNET
964        setRouter("Atheros Hornet");
965        nvram_default_get("ath0_rxantenna", "1");
966        nvram_default_get("ath0_txantenna", "1");
967        return ROUTER_BOARD_WHRHPGN;
968#elif HAVE_WASP
969        setRouter("Atheros Wasp");
970        nvram_default_get("ath0_rxantenna", "2");
971        nvram_default_get("ath0_txantenna", "2");
972        return ROUTER_BOARD_WHRHPGN;
973#elif HAVE_WHRHPG300N
974#ifdef HAVE_BUFFALO
975        setRouter("WHR-HP-G300N");
976#else
977        setRouter("Buffalo WHR-HP-G300N");
978#endif
979        nvram_default_get("ath0_rxantenna", "3");
980        nvram_default_get("ath0_txantenna", "3");
981        return ROUTER_BOARD_WHRHPGN;
982#elif HAVE_WHRG300NV2
983#ifdef HAVE_BUFFALO
984        setRouter("WHR-G300N");
985#else
986        setRouter("Buffalo WHR-G300N");
987#endif
988        nvram_default_get("ath0_rxantenna", "3");
989        nvram_default_get("ath0_txantenna", "3");
990        return ROUTER_BOARD_WHRHPGN;
991#elif HAVE_WHRHPGN
992#ifdef HAVE_BUFFALO
993        setRouter("WHR-HP-GN");
994#else
995        setRouter("Buffalo WHR-HP-GN");
996#endif
997        nvram_default_get("ath0_rxantenna", "1");
998        nvram_default_get("ath0_txantenna", "1");
999        return ROUTER_BOARD_WHRHPGN;
1000#elif HAVE_JJAP93
1001        setRouter("JJPLUS AP93");
1002        nvram_default_get("ath0_rxantenna", "1");
1003        nvram_default_get("ath0_txantenna", "1");
1004        return ROUTER_BOARD_PB42;
1005#elif HAVE_JJAP005
1006        setRouter("JJPLUS AP005");
1007        nvram_default_get("ath0_rxantenna", "1");
1008        nvram_default_get("ath0_txantenna", "1");
1009        return ROUTER_BOARD_PB42;
1010#elif HAVE_JJAP501
1011        setRouter("JJPLUS AP501");
1012        nvram_default_get("ath0_rxantenna", "3");
1013        nvram_default_get("ath0_txantenna", "3");
1014        return ROUTER_BOARD_PB42;
1015#elif HAVE_AC722
1016        setRouter("ACCTON AC722");
1017        nvram_default_get("ath0_rxantenna", "3");
1018        nvram_default_get("ath0_txantenna", "3");
1019        return ROUTER_BOARD_PB42;
1020#elif HAVE_AC622
1021        setRouter("ACCTON AC622");
1022        nvram_default_get("ath0_rxantenna", "3");
1023        nvram_default_get("ath0_txantenna", "3");
1024        return ROUTER_BOARD_PB42;
1025#elif HAVE_UBNTM
1026        typedef struct UBNTDEV {
1027                char *devicename;       // device name
1028                unsigned short devid;   // pci subdevice id
1029                char *rxchain;  // rx chainmask
1030                char *txchain;  // tx chainmask
1031                int dddev;      // dd-wrt device id
1032                int offset;     // frequency offset
1033        };
1034
1035        /* these values are guessed and need to be validated */
1036#define M900 (- (2427 - 907))
1037#define M365 (- (5540 - 3650))
1038#define M35 (- (5540 - 3540))
1039#define M10 (- (5540 - 10322))
1040        struct UBNTDEV dev[] = {
1041                {"Ubiquiti NanoStation M2", 0xe002, "3", "3", ROUTER_BOARD_NS2M, 0},    //
1042                {"Ubiquiti NanoStation M2", 0xe012, "3", "3", ROUTER_BOARD_NS2M, 0},    //
1043                {"Ubiquiti NanoStation M5", 0xe005, "3", "3", ROUTER_BOARD_NS5M, 0},    //
1044                {"Ubiquiti NanoStation M3", 0xe035, "3", "3", ROUTER_BOARD_NS5M, M35},  //
1045                {"Ubiquiti NanoStation M365", 0xe003, "3", "3", ROUTER_BOARD_NS5M, M365},       //
1046//              {"Ubiquiti NanoStation M900 GPS", 0xe0b9, "3", "3", ROUTER_BOARD_NS5M, M900},       //
1047                {"Ubiquiti Rocket M2", 0xe102, "3", "3", ROUTER_BOARD_R2M, 0},  //
1048                {"Ubiquiti Rocket M2", 0xe112, "3", "3", ROUTER_BOARD_R2M, 0},  //
1049                {"Ubiquiti Rocket M2", 0xe1b2, "3", "3", ROUTER_BOARD_R2M, 0},  //
1050                {"Ubiquiti Rocket M2 GPS", 0xe1c2, "3", "3", ROUTER_BOARD_R2M, 0},      //
1051                {"Ubiquiti Rocket M2 Titanium", 0xe1d2, "3", "3", ROUTER_BOARD_R2M, 0}, // Titanium
1052                {"Ubiquiti Rocket M5", 0xe105, "3", "3", ROUTER_BOARD_R5M, 0},  //
1053                {"Ubiquiti Rocket M5", 0xe1b5, "3", "3", ROUTER_BOARD_R5M, 0},  //
1054                {"Ubiquiti Rocket M5 GPS", 0xe1c5, "3", "3", ROUTER_BOARD_R5M, 0},      //
1055                {"Ubiquiti Rocket M5 Titanium", 0xe1d5, "3", "3", ROUTER_BOARD_R5M, 0}, // Titanium
1056                {"Ubiquiti Rocket M3", 0xe1c3, "3", "3", ROUTER_BOARD_R5M, M35},        //
1057                {"Ubiquiti Rocket M3 GPS", 0xe1e3, "3", "3", ROUTER_BOARD_R5M, M35},    //
1058                {"Ubiquiti Rocket M5 X3", 0xe3a5, "3", "3", ROUTER_BOARD_R5M, 0},       //
1059                {"Ubiquiti Rocket M365", 0xe1b3, "3", "3", ROUTER_BOARD_R5M, M365},     //
1060                {"Ubiquiti Rocket M365 GPS", 0xe1d3, "3", "3", ROUTER_BOARD_R5M, M365}, //
1061                {"Ubiquiti Rocket M900", 0xe1b9, "3", "3", ROUTER_BOARD_R2M, M900},     //
1062                {"Ubiquiti Rocket M900 GPS", 0xe1d9, "3", "3", ROUTER_BOARD_R2M, M900}, //
1063                {"Ubiquiti Bullet M2", 0xe202, "1", "1", ROUTER_BOARD_BS5M, 0}, //
1064                {"Ubiquiti Bullet M5", 0xe205, "1", "1", ROUTER_BOARD_BS5M, 0}, //
1065                {"Ubiquiti Airgrid M2", 0xe212, "1", "1", ROUTER_BOARD_BS2M, 0},        //
1066                {"Ubiquiti Airgrid M2", 0xe242, "1", "1", ROUTER_BOARD_BS2M, 0},        //
1067                {"Ubiquiti Airgrid M5", 0xe215, "1", "1", ROUTER_BOARD_BS5M, 0},        //
1068                {"Ubiquiti Airgrid M5", 0xe245, "1", "1", ROUTER_BOARD_BS5M, 0},        //
1069                {"Ubiquiti AirRouter", 0xe4a2, "3", "3", ROUTER_BOARD_NS2M, 0}, //
1070                {"Ubiquiti AirRouter", 0xe4b2, "3", "3", ROUTER_BOARD_NS2M, 0}, //
1071                {"Ubiquiti Pico M2", 0xe302, "1", "1", ROUTER_BOARD_BS2M, 0},   //
1072                {"Ubiquiti Pico M5", 0xe305, "1", "1", ROUTER_BOARD_BS5M, 0},   //
1073                {"Ubiquiti Airwire", 0xe405, "3", "3", ROUTER_BOARD_BS5M, 0},   //
1074                {"Ubiquiti Airwire", 0xe4a5, "3", "3", ROUTER_BOARD_BS5M, 0},   //
1075                {"Ubiquiti Loco M5", 0xe0a5, "3", "3", ROUTER_BOARD_NS5M, 0},   //
1076                {"Ubiquiti Loco M5", 0xe8a5, "3", "3", ROUTER_BOARD_NS5M, 0},   //
1077                {"Ubiquiti Loco M2", 0xe0a2, "3", "3", ROUTER_BOARD_NS5M, 0},   //
1078//              {"Ubiquiti Loco M2", 0xe8a2, "3", "3", ROUTER_BOARD_NS5M, 0},   //
1079                {"Ubiquiti Loco M900", 0xe009, "3", "3", ROUTER_BOARD_NS5M, M900},      //
1080                {"Ubiquiti NanoStation M900 Sector", 0xe0b9, "3", "3", ROUTER_BOARD_NS5M, M900},        //
1081                {"Ubiquiti LiteStation M25", 0xe115, "3", "3", ROUTER_BOARD_NS5M, 0},   //
1082                {"Ubiquiti PowerAP N", 0xe402, "3", "3", ROUTER_BOARD_NS2M, 0}, //
1083                {"Ubiquiti Simple AP", 0xe4a2, "3", "3", ROUTER_BOARD_R2M, 0},  //
1084                {"Ubiquiti PowerBridge M3", 0xe2a3, "3", "3", ROUTER_BOARD_R5M, M35},   //
1085                {"Ubiquiti PowerBridge M5", 0xe1a5, "3", "3", ROUTER_BOARD_R5M, 0},     //
1086                {"Ubiquiti PowerBridge M365", 0xe1a3, "3", "3", ROUTER_BOARD_R5M, M365},        //
1087                {"Ubiquiti PowerBridge M10", 0xe110, "3", "3", ROUTER_BOARD_R5M, M10},  //
1088                {"Ubiquiti NanoBridge M3", 0xe243, "3", "3", ROUTER_BOARD_BS5M, M35},   //
1089                {"Ubiquiti NanoBridge M365", 0xe233, "3", "3", ROUTER_BOARD_BS5M, M365},        //
1090                {"Ubiquiti NanoBridge M900", 0xe239, "3", "3", ROUTER_BOARD_BS5M, M900},        //
1091                {"Ubiquiti NanoBridge M5", 0xe235, "3", "3", ROUTER_BOARD_BS5M, 0},     //
1092                {"Ubiquiti NanoBridge M5", 0xe2b5, "3", "3", ROUTER_BOARD_BS5M, 0},     //
1093                {"Ubiquiti NanoBridge M2", 0xe232, "3", "3", ROUTER_BOARD_BS2M, 0},     //
1094                {"Ubiquiti 3G Station", 0xe6a2, "3", "3", ROUTER_BOARD_BS2M, 0},        //
1095                {"Ubiquiti 3G Station Professional", 0xe6b2, "3", "3", ROUTER_BOARD_BS2M, 0},   //
1096                {"Ubiquiti 3G Station Outdoor", 0xe6c2, "3", "3", ROUTER_BOARD_BS2M, 0},        //
1097                {"Ubiquiti WispStation M5", 0xe2a5, "3", "3", ROUTER_BOARD_BS5M, 0},    //
1098                {"Ubiquiti UniFi AP", 0xe502, "3", "3", ROUTER_BOARD_UNIFI, 0}, //
1099                {NULL, 0, NULL, NULL, 0},       //
1100        };
1101
1102#undef M35
1103#undef M365
1104#undef M900
1105#undef M10
1106
1107#if 0
1108        FILE *fp =
1109            fopen("/sys/bus/pci/devices/0000:00:00.0/subsystem_device", "rb");
1110        if (fp == NULL)
1111                return ROUTER_BOARD_PB42;
1112        int device;
1113        fscanf(fp, "0x%04X", &device);
1114        fclose(fp);
1115#else
1116        FILE *fp = fopen("/dev/mtdblock5", "rb");       //open board config
1117        int device = 0;
1118        if (fp) {
1119                fseek(fp, 0x1006, SEEK_SET);
1120                unsigned short cal[128];
1121                fread(&cal[0], 1, 256, fp);
1122                fclose(fp);
1123                int calcnt = 0;
1124                while (((cal[calcnt] & 0xffff) != 0xffff)) {
1125                        unsigned short reg = cal[calcnt++] & 0xffff;
1126                        if (reg == 0x602c || reg == 0x502c) {
1127                                calcnt++;
1128                                device = cal[calcnt++] & 0xffff;
1129                                break;
1130                        } else {
1131                                calcnt += 2;
1132                        }
1133                }
1134        }
1135#endif
1136        int devcnt = 0;
1137        while (dev[devcnt].devicename != NULL) {
1138                if (dev[devcnt].devid == device) {
1139                        nvram_default_get("ath0_rxantenna",
1140                                          dev[devcnt].rxchain);
1141                        nvram_default_get("ath0_txantenna",
1142                                          dev[devcnt].txchain);
1143                        if (dev[devcnt].offset) {
1144                                char foff[32];
1145                                sprintf(foff, "%d", dev[devcnt].offset);
1146                                nvram_set("ath0_offset", foff);
1147                        }
1148                        setRouter(dev[devcnt].devicename);
1149                        return dev[devcnt].dddev;
1150                }
1151                devcnt++;
1152        }
1153        setRouter("Ubiquiti Unknown Model");
1154        return ROUTER_BOARD_PB42;
1155#elif HAVE_NS2
1156        setRouter("Ubiquiti NanoStation 2");
1157        return ROUTER_BOARD_LS2;
1158#elif HAVE_EOC5510
1159        setRouter("Senao EOC-5510");
1160        return ROUTER_BOARD_LS2;
1161#elif HAVE_EOC5611
1162        setRouter("Senao EOC-5611");
1163        return ROUTER_BOARD_LS2;
1164#elif HAVE_EOC5610
1165        setRouter("Senao EOC-5610");
1166        return ROUTER_BOARD_LS2;
1167#elif HAVE_NS5
1168        setRouter("Ubiquiti NanoStation 5");
1169        return ROUTER_BOARD_LS2;
1170#elif HAVE_SOLO51
1171        setRouter("Alfa SoLo48-N");
1172        return ROUTER_BOARD_LS2;
1173#elif HAVE_NS3
1174        setRouter("Ubiquiti NanoStation 3");
1175        return ROUTER_BOARD_LS2;
1176#elif HAVE_BS5
1177        setRouter("Ubiquiti Bullet 5");
1178        return ROUTER_BOARD_LS2;
1179#elif HAVE_BS2
1180        setRouter("Ubiquiti Bullet 2");
1181        return ROUTER_BOARD_LS2;
1182#elif HAVE_PICO2
1183        setRouter("Ubiquiti PicoStation 2");
1184        return ROUTER_BOARD_LS2;
1185#elif HAVE_PICO2HP
1186        setRouter("Ubiquiti PicoStation 2 HP");
1187        return ROUTER_BOARD_LS2;
1188#elif HAVE_PICO5
1189        setRouter("Ubiquiti PicoStation 5");
1190        return ROUTER_BOARD_LS2;
1191#elif HAVE_MS2
1192        setRouter("Ubiquiti MiniStation");
1193        return ROUTER_BOARD_LS2;
1194#elif HAVE_BS2HP
1195        setRouter("Ubiquiti Bullet 2 HP");
1196        return ROUTER_BOARD_LS2;
1197#elif HAVE_LC2
1198        setRouter("Ubiquiti NanoStation 2 Loco");
1199        return ROUTER_BOARD_LS2;
1200#elif HAVE_LC5
1201        setRouter("Ubiquiti NanoStation 5 Loco");
1202        return ROUTER_BOARD_LS2;
1203#elif HAVE_PS2
1204        setRouter("Ubiquiti PowerStation 2");
1205        return ROUTER_BOARD_LS2;
1206#elif HAVE_PS5
1207        setRouter("Ubiquiti PowerStation 5");
1208        return ROUTER_BOARD_LS2;
1209#elif HAVE_LS2
1210        setRouter("Ubiquiti LiteStation 2");
1211        return ROUTER_BOARD_LS2;
1212#elif HAVE_LS5
1213        setRouter("Ubiquiti LiteStation 5");
1214        return ROUTER_BOARD_LS2;
1215#elif HAVE_WHRAG108
1216        setRouter("Buffalo WHR-HP-AG108");
1217        return ROUTER_BOARD_WHRAG108;
1218#elif HAVE_PB42
1219        setRouter("Atheros PB42");
1220        return ROUTER_BOARD_PB42;
1221#elif HAVE_RSPRO
1222        setRouter("Ubiquiti RouterStation Pro");
1223        return ROUTER_BOARD_PB42;
1224#elif HAVE_RS
1225#ifdef HAVE_DDLINK
1226        setRouter("ddlink1x1");
1227#else
1228        setRouter("Ubiquiti RouterStation");
1229#endif
1230        return ROUTER_BOARD_PB42;
1231#elif HAVE_E2100
1232        setRouter("Linksys E2100L");
1233        return ROUTER_BOARD_PB42;
1234#elif HAVE_WRT160NL
1235        setRouter("Linksys WRT160NL");
1236        return ROUTER_BOARD_PB42;
1237#elif HAVE_TG2521
1238        setRouter("ZCom TG-2521");
1239        return ROUTER_BOARD_PB42;
1240#elif HAVE_WZRG300NH2
1241        nvram_default_get("ath0_rxantenna", "3");
1242        nvram_default_get("ath0_txantenna", "3");
1243#ifdef HAVE_BUFFALO
1244        setRouter("WZR-HP-G300NH2");
1245#else
1246        setRouter("Buffalo WZR-HP-G300NH2");
1247#endif
1248        return ROUTER_BOARD_PB42;
1249#elif HAVE_WZRG450
1250        nvram_default_get("ath0_rxantenna", "7");
1251        nvram_default_get("ath0_txantenna", "7");
1252#ifdef HAVE_BUFFALO
1253        setRouter("WZR-HP-G450H");
1254#else
1255        setRouter("Buffalo WZR-HP-G450H");
1256#endif
1257        return ROUTER_BOARD_PB42;
1258#elif HAVE_WZRG300NH
1259#ifdef HAVE_BUFFALO
1260        setRouter("WZR-HP-G300NH");
1261#else
1262        setRouter("Buffalo WZR-HP-G300NH");
1263#endif
1264        nvram_default_get("ath0_rxantenna", "7");
1265        nvram_default_get("ath0_txantenna", "7");
1266        return ROUTER_BOARD_PB42;
1267#elif HAVE_WZRHPAG300NH
1268#ifdef HAVE_BUFFALO
1269        setRouter("WZR-HP-AG300H");
1270#else
1271        setRouter("Buffalo WZR-HP-AG300H");
1272#endif
1273        return ROUTER_BOARD_PB42;
1274#elif HAVE_DIR632
1275        nvram_default_get("ath0_rxantenna", "3");
1276        nvram_default_get("ath0_txantenna", "3");
1277        setRouter("Dlink-DIR-632A");
1278        return ROUTER_BOARD_PB42;
1279#elif HAVE_WNDR3700V2
1280        nvram_default_get("ath0_rxantenna", "3");
1281        nvram_default_get("ath0_txantenna", "3");
1282        nvram_default_get("ath1_rxantenna", "3");
1283        nvram_default_get("ath1_txantenna", "3");
1284        setRouter("Netgear WNDR3700 v2");
1285        return ROUTER_BOARD_PB42;
1286#elif HAVE_WNDR3700
1287        nvram_default_get("ath0_rxantenna", "3");
1288        nvram_default_get("ath0_txantenna", "3");
1289        nvram_default_get("ath1_rxantenna", "3");
1290        nvram_default_get("ath1_txantenna", "3");
1291        setRouter("Netgear WNDR3700");
1292        return ROUTER_BOARD_PB42;
1293#elif HAVE_DIR825
1294        nvram_default_get("ath0_rxantenna", "3");
1295        nvram_default_get("ath0_txantenna", "3");
1296        nvram_default_get("ath1_rxantenna", "3");
1297        nvram_default_get("ath1_txantenna", "3");
1298        setRouter("Dlink DIR-825");
1299        return ROUTER_BOARD_PB42;
1300#elif HAVE_TEW673GRU
1301        nvram_default_get("ath0_rxantenna", "3");
1302        nvram_default_get("ath0_txantenna", "3");
1303        nvram_default_get("ath1_rxantenna", "3");
1304        nvram_default_get("ath1_txantenna", "3");
1305        setRouter("Trendnet TEW-673GRU");
1306        return ROUTER_BOARD_PB42;
1307#elif HAVE_WRT400
1308        nvram_default_get("ath0_rxantenna", "3");
1309        nvram_default_get("ath0_txantenna", "3");
1310        nvram_default_get("ath1_rxantenna", "3");
1311        nvram_default_get("ath1_txantenna", "3");
1312        setRouter("Linksys WRT400N");
1313        return ROUTER_BOARD_PB42;
1314#elif HAVE_DIR615C1
1315        setRouter("D-Link DIR-615-C1");
1316        return ROUTER_BOARD_PB42;
1317#elif HAVE_DIR601A1
1318        nvram_default_get("ath0_rxantenna", "1");
1319        nvram_default_get("ath0_txantenna", "1");
1320        setRouter("D-Link DIR-601-A1");
1321        return ROUTER_BOARD_PB42;
1322#elif HAVE_DIR615E1
1323        nvram_default_get("ath0_rxantenna", "3");
1324        nvram_default_get("ath0_txantenna", "3");
1325        setRouter("D-Link DIR-615-E1");
1326        return ROUTER_BOARD_PB42;
1327#elif HAVE_DIR615E
1328        nvram_default_get("ath0_rxantenna", "3");
1329        nvram_default_get("ath0_txantenna", "3");
1330        setRouter("D-Link DIR-615-E3/E4");
1331        return ROUTER_BOARD_PB42;
1332#elif HAVE_TEW652BRP
1333        setRouter("Trendnet TEW-652BRP");
1334        return ROUTER_BOARD_PB42;
1335#elif HAVE_TEW632BRP
1336        setRouter("Trendnet TEW-632BRP");
1337        return ROUTER_BOARD_PB42;
1338#elif HAVE_WR841v3
1339        setRouter("TP-Link TL-WR841ND v3");
1340        return ROUTER_BOARD_PB42;
1341#elif HAVE_WR941
1342        setRouter("TP-Link TL-WR941ND v2/v3");
1343        return ROUTER_BOARD_PB42;
1344#elif HAVE_WR841v5
1345        nvram_default_get("ath0_rxantenna", "3");
1346        nvram_default_get("ath0_txantenna", "3");
1347        setRouter("TP-Link TL-WR841ND v5");
1348        return ROUTER_BOARD_PB42;
1349#elif HAVE_WR840v1
1350        nvram_default_get("ath0_rxantenna", "3");
1351        nvram_default_get("ath0_txantenna", "3");
1352        setRouter("TP-Link TL-WR840N v1");
1353        return ROUTER_BOARD_PB42;
1354#elif HAVE_WR841v7
1355        nvram_default_get("ath0_rxantenna", "3");
1356        nvram_default_get("ath0_txantenna", "3");
1357        setRouter("TP-Link TL-WR841ND v7");
1358        return ROUTER_BOARD_PB42;
1359#elif HAVE_WR740v1
1360        nvram_default_get("ath0_rxantenna", "1");
1361        nvram_default_get("ath0_txantenna", "1");
1362        setRouter("TP-Link TL-WR740N");
1363        return ROUTER_BOARD_PB42;
1364#elif HAVE_WA901v1
1365        nvram_default_get("ath0_rxantenna", "3");
1366        nvram_default_get("ath0_txantenna", "3");
1367        setRouter("TP-Link TL-WA901ND v1");
1368        return ROUTER_BOARD_PB42;
1369#elif HAVE_WR941v4
1370        setRouter("TP-Link TL-WR941ND v4");
1371        return ROUTER_BOARD_PB42;
1372#elif HAVE_WR743
1373        nvram_default_get("ath0_rxantenna", "1");
1374        nvram_default_get("ath0_txantenna", "1");
1375        setRouter("TP-Link TL-WR743ND v1");
1376        return ROUTER_BOARD_PB42;
1377#elif HAVE_WR740V4
1378        nvram_default_get("ath0_rxantenna", "1");
1379        nvram_default_get("ath0_txantenna", "1");
1380        setRouter("TP-Link TL-WR740N v4");
1381        return ROUTER_BOARD_PB42;
1382#elif HAVE_WR741V4
1383        nvram_default_get("ath0_rxantenna", "1");
1384        nvram_default_get("ath0_txantenna", "1");
1385        setRouter("TP-Link TL-WR741ND v4");
1386        return ROUTER_BOARD_PB42;
1387#elif HAVE_WR741
1388        nvram_default_get("ath0_rxantenna", "1");
1389        nvram_default_get("ath0_txantenna", "1");
1390        setRouter("TP-Link TL-WR741ND v1");
1391        return ROUTER_BOARD_PB42;
1392#elif HAVE_WR1043
1393        nvram_default_get("ath0_rxantenna", "7");
1394        nvram_default_get("ath0_txantenna", "7");
1395        setRouter("TP-Link TL-WR1043ND");
1396        return ROUTER_BOARD_PB42;
1397#elif HAVE_AP83
1398        setRouter("Atheros AP83");
1399        return ROUTER_BOARD_PB42;
1400#elif HAVE_WP543
1401        setRouter("Compex WP543");
1402        return ROUTER_BOARD_PB42;
1403#elif HAVE_JA76PF
1404        setRouter("JJPLUS JA76PF");
1405        return ROUTER_BOARD_PB42;
1406#elif HAVE_JWAP003
1407        setRouter("JJPLUS JWAP003");
1408        return ROUTER_BOARD_PB42;
1409#elif HAVE_ALFAAP94
1410        setRouter("Alfa AP94 Board");
1411        return ROUTER_BOARD_PB42;
1412#elif HAVE_LSX
1413        setRouter("Ubiquiti LiteStation-SR71");
1414        return ROUTER_BOARD_PB42;
1415#elif HAVE_WMBR_G300NH
1416        setRouter("Buffalo WBMR-HP-G300H");
1417        nvram_default_get("ath0_rxantenna", "3");
1418        nvram_default_get("ath0_txantenna", "3");
1419        return ROUTER_BOARD_DANUBE;
1420#elif HAVE_VF802
1421        setRouter("Vodafone Easybox 802");
1422        return ROUTER_BOARD_DANUBE;
1423#elif HAVE_VF803
1424        setRouter("Vodafone Easybox 803");
1425        return ROUTER_BOARD_DANUBE;
1426#elif HAVE_SX763
1427        setRouter("Gigaset SX763");
1428        return ROUTER_BOARD_DANUBE;
1429#elif HAVE_DANUBE
1430        setRouter("Infineon Danube");
1431        return ROUTER_BOARD_DANUBE;
1432#elif HAVE_WBD222
1433        setRouter("Wiligear WBD-222");
1434        return ROUTER_BOARD_STORM;
1435#elif HAVE_STORM
1436        setRouter("Wiligear WBD-111");
1437        return ROUTER_BOARD_STORM;
1438#elif HAVE_OPENRISC
1439        setRouter("Alekto OpenRisc");
1440        return ROUTER_BOARD_OPENRISC;
1441#elif HAVE_TW6600
1442        setRouter("AW-6660");
1443        return ROUTER_BOARD_TW6600;
1444#elif HAVE_ALPHA
1445        setRouter("Alfa Networks AP48");
1446        return ROUTER_BOARD_CA8;
1447#elif HAVE_USR5453
1448        setRouter("US Robotics USR5453");
1449        return ROUTER_BOARD_CA8;
1450#elif HAVE_RDAT81
1451        setRouter("Wistron RDAT-81");
1452        return ROUTER_BOARD_RDAT81;
1453#elif HAVE_RCAA01
1454        setRouter("Airlive WLA-9000AP");
1455        return ROUTER_BOARD_RCAA01;
1456#elif HAVE_CA8PRO
1457        setRouter("Wistron CA8-4 PRO");
1458        return ROUTER_BOARD_CA8PRO;
1459#elif HAVE_CA8
1460#ifdef HAVE_WHA5500CPE
1461        setRouter("Airlive WHA-5500CPE");
1462#elif HAVE_AIRMAX5
1463        setRouter("Airlive AirMax 5");
1464#else
1465        setRouter("Airlive WLA-5000AP");
1466#endif
1467        return ROUTER_BOARD_CA8;
1468#else
1469
1470        unsigned long boardnum = strtoul(nvram_safe_get("boardnum"), NULL, 0);
1471        unsigned long melco_id = strtoul(nvram_safe_get("melco_id"), NULL, 0);
1472
1473        if (boardnum == 42 && nvram_match("boardtype", "bcm94710ap")) {
1474                setRouter("Buffalo WBR-G54 / WLA-G54");
1475                return ROUTER_BUFFALO_WBR54G;
1476        }
1477#ifndef HAVE_BUFFALO
1478        if (nvram_match("boardnum", "mn700") &&
1479            nvram_match("boardtype", "bcm94710ap")) {
1480                setRouter("Microsoft MN-700");
1481                return ROUTER_MICROSOFT_MN700;
1482        }
1483
1484        if (nvram_match("boardnum", "asusX") &&
1485            nvram_match("boardtype", "bcm94710dev")) {
1486                setRouter("Asus WL-300g / WL-500g");
1487                return ROUTER_ASUS_WL500G;
1488        }
1489
1490        if (boardnum == 44 && nvram_match("boardtype", "bcm94710ap")) {
1491                setRouter("Dell TrueMobile 2300");
1492                return ROUTER_DELL_TRUEMOBILE_2300;
1493        }
1494#endif
1495
1496        if (boardnum == 100 && nvram_match("boardtype", "bcm94710dev")) {
1497                setRouter("Buffalo WLA-G54C");
1498                return ROUTER_BUFFALO_WLAG54C;
1499        }
1500#ifndef HAVE_BUFFALO
1501        if (boardnum == 45 && nvram_match("boardtype", "bcm95365r")) {
1502                setRouter("Asus WL-500g Deluxe");
1503                return ROUTER_ASUS_WL500GD;
1504        }
1505
1506        if (boardnum == 45 && nvram_match("boardtype", "0x0472")
1507            && nvram_match("boardrev", "0x23") && nvram_match("parkid", "1")) {
1508                setRouter("Asus WL-500W");
1509                return ROUTER_ASUS_WL500W;
1510        }
1511
1512        if (boardnum == 45 && nvram_match("boardtype", "0x467")) {
1513                char *hwver0 = nvram_safe_get("hardware_version");
1514
1515                if (startswith(hwver0, "WL320G")) {
1516                        setRouter("Asus WL-320gE/gP");
1517                        return ROUTER_ASUS_WL550GE;
1518                } else {
1519                        setRouter("Asus WL-550gE");
1520                        return ROUTER_ASUS_WL550GE;
1521                }
1522        }
1523#ifdef HAVE_BCMMODERN
1524        if (boardnum == 45 && nvram_match("boardtype", "0x04EC")
1525            && nvram_match("boardrev", "0x1402")) {
1526                setRouter("Asus RT-N10");
1527                return ROUTER_ASUS_RTN10;
1528        }
1529
1530        if (boardnum == 45 && nvram_match("boardtype", "0x0550")
1531            && nvram_match("boardrev", "0x1102")) {
1532                setRouter("Asus RT-N10U");
1533                return ROUTER_ASUS_RTN10U;
1534        }
1535
1536        if (boardnum == 45 && nvram_match("boardtype", "0x0550")
1537            && nvram_match("boardrev", "0x1442")) {
1538                setRouter("Asus RT-N53");
1539                return ROUTER_ASUS_RTN53;
1540        }
1541
1542        if (boardnum == 0 && nvram_match("boardtype", "0xF5B2")
1543            && nvram_match("boardrev", "0x1100")) {
1544                setRouter("Asus RT-N66U");
1545                return ROUTER_ASUS_RTN66;
1546        }
1547
1548        if (nvram_match("boardnum", "1") && nvram_match("boardtype", "0x054d")
1549            && nvram_match("boardrev", "0x1109")) {
1550                setRouter("NetCore NW715P");
1551                return ROUTER_NETCORE_NW715P;
1552        }
1553
1554        if (boardnum == 45 && nvram_match("boardtype", "0x04CD")
1555            && nvram_match("boardrev", "0x1201")) {
1556                setRouter("Asus RT-N12");
1557                return ROUTER_ASUS_RTN12;
1558        }
1559
1560        if (boardnum == 45 && nvram_match("boardtype", "0x054D")
1561            && nvram_match("boardrev", "0x1101")) {
1562                char *hwrev = nvram_safe_get("hardware_version");
1563                if (!strncmp(hwrev, "RTN12C1", 7))
1564                        setRouter("Asus RT-N12C1");
1565                else
1566                        setRouter("Asus RT-N12B");
1567                return ROUTER_ASUS_RTN12B;
1568        }
1569
1570        if (boardnum == 45 && nvram_match("boardtype", "0x04cf")
1571            && nvram_match("boardrev", "0x1218")) {
1572                setRouter("Asus RT-N16");
1573                return ROUTER_ASUS_RTN16;
1574        }
1575
1576        if (nvram_match("boardtype", "0xa4cf")
1577            && nvram_match("boardrev", "0x1100")) {
1578                setRouter("Belkin F5D8235-4 v3");
1579                return ROUTER_BELKIN_F5D8235V3;
1580        }
1581
1582        if (nvram_match("boardtype", "0xd4cf")
1583            && nvram_match("boardrev", "0x1204")) {
1584                setRouter("Belkin F7D4301 / F7D8301 v1");
1585                return ROUTER_BELKIN_F7D4301;
1586        }
1587
1588        if (nvram_match("boardtype", "0xa4cf")
1589            && nvram_match("boardrev", "0x1102")) {
1590                FILE *mtd1 = fopen("/dev/mtdblock/1", "rb");
1591                unsigned long trxhd;
1592                if (mtd1) {
1593                        fread(&trxhd, 4, 1, mtd1);
1594                        fclose(mtd1);
1595                        if (trxhd == TRX_MAGIC_F7D3301) {
1596                                setRouter("Belkin F7D3301 / F7D7301 v1");
1597                                return ROUTER_BELKIN_F7D3301;
1598                        }
1599                        if (trxhd == TRX_MAGIC_F7D3302) {
1600                                setRouter("Belkin F7D3302 / F7D7302 v1");
1601                                return ROUTER_BELKIN_F7D3302;
1602                        }
1603                }
1604                setRouter("Belkin F7D4302 / F7D8302 v1");
1605                return ROUTER_BELKIN_F7D4302;
1606        }
1607#endif
1608
1609#endif
1610        if (nvram_match("boardnum", "00") && nvram_match("boardtype", "0x0101")
1611            && nvram_match("boardrev", "0x10")) {
1612                setRouter("Buffalo WBR2-G54 / WBR2-G54S");
1613                return ROUTER_BUFFALO_WBR2G54S;
1614        }
1615
1616        if (boardnum == 2 && nvram_match("boardtype", "0x0101")
1617            && nvram_match("boardrev", "0x10")) {
1618                setRouter("Buffalo WLA2-G54C / WLI3-TX1-G54");
1619                return ROUTER_BUFFALO_WLA2G54C;
1620        }
1621        if (boardnum == 0 && melco_id == 29090
1622            && nvram_match("boardrev", "0x10")) {
1623                setRouter("Buffalo WLAH-G54");
1624                return ROUTER_BUFFALO_WLAH_G54;
1625
1626        }
1627        if (boardnum == 0 && melco_id == 31070
1628            && nvram_match("boardflags", "0x2288")
1629            && nvram_match("boardrev", "0x10")) {
1630                setRouter("Buffalo WAPM-HP-AM54G54");
1631                return ROUTER_BUFFALO_WAPM_HP_AM54G54;
1632        }
1633        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x11")
1634            && nvram_match("boardtype", "0x048e") && melco_id == 32093) {
1635                setRouter("Buffalo WHR-G125");
1636                return ROUTER_BUFFALO_WHRG54S;
1637        }
1638
1639        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x10")
1640            && nvram_match("boardtype", "0x048e") && melco_id == 32139) {
1641                setRouter("Buffalo WCA-G");
1642                return ROUTER_BUFFALO_WCAG;     //vlan1 is lan, vlan0 is unused, implementation not done. will me made after return to germany
1643        }
1644
1645        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x11")
1646            && nvram_match("boardtype", "0x048e") && melco_id == 32064) {
1647                setRouter("Buffalo WHR-HP-G125");
1648                return ROUTER_BUFFALO_WHRG54S;
1649        }
1650
1651        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x13")
1652            && nvram_match("boardtype", "0x467")) {
1653                if (nvram_match("boardflags", "0x1658")
1654                    || nvram_match("boardflags", "0x2658")
1655                    || nvram_match("boardflags", "0x3658")) {
1656                        setRouter("Buffalo WLI-TX4-G54HP");
1657                        return ROUTER_BUFFALO_WLI_TX4_G54HP;
1658                }
1659                if (!nvram_match("buffalo_hp", "1")
1660                    && nvram_match("boardflags", "0x2758")) {
1661                        setRouter("Buffalo WHR-G54S");
1662                        return ROUTER_BUFFALO_WHRG54S;
1663                }
1664                if (nvram_match("buffalo_hp", "1")
1665                    || nvram_match("boardflags", "0x1758")) {
1666#ifndef HAVE_BUFFALO
1667                        setRouter("Buffalo WHR-HP-G54");
1668#else
1669#ifdef BUFFALO_JP
1670                        setRouter("Buffalo AS-A100");
1671#else
1672                        setRouter("Buffalo WHR-HP-G54DD");
1673#endif
1674#endif
1675                        return ROUTER_BUFFALO_WHRG54S;
1676                }
1677        }
1678
1679        if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x10")
1680            && nvram_match("boardtype", "0x470")) {
1681                setRouter("Buffalo WHR-AM54G54");
1682                return ROUTER_BUFFALO_WHRAM54G54;
1683        }
1684
1685        if (boardnum == 42 && nvram_match("boardtype", "0x042f")) {
1686
1687                if (nvram_match("product_name", "WZR-RS-G54")
1688                    || melco_id == 30083) {
1689                        setRouter("Buffalo WZR-RS-G54");
1690                        return ROUTER_BUFFALO_WZRRSG54;
1691                }
1692                if (nvram_match("product_name", "WZR-HP-G54")
1693                    || melco_id == 30026) {
1694                        setRouter("Buffalo WZR-HP-G54");
1695                        return ROUTER_BUFFALO_WZRRSG54;
1696                }
1697                if (nvram_match("product_name", "WZR-G54") || melco_id == 30061) {
1698                        setRouter("Buffalo WZR-G54");
1699                        return ROUTER_BUFFALO_WZRRSG54;
1700                }
1701                if (nvram_match("melco_id", "290441dd")) {
1702                        setRouter("Buffalo WHR2-A54G54");
1703                        return ROUTER_BUFFALO_WZRRSG54;
1704                }
1705                if (nvram_match("product_name", "WHR3-AG54")
1706                    || nvram_match("product_name", "WHR3-B11")
1707                    || melco_id == 29130) {
1708                        setRouter("Buffalo WHR3-AG54");
1709                        return ROUTER_BUFFALO_WZRRSG54;
1710                }
1711                if (nvram_match("product_name", "WVR-G54-NF")
1712                    || melco_id == 28100) {
1713                        setRouter("Buffalo WVR-G54-NF");
1714                        return ROUTER_BUFFALO_WZRRSG54;
1715                }
1716                if (nvram_match("product_name", "WZR-G108") || melco_id == 31095
1717                    || melco_id == 30153) {
1718                        setRouter("Buffalo WZR-G108");
1719                        return ROUTER_BRCM4702_GENERIC;
1720                }
1721                if (melco_id > 0)       // e.g. 29115
1722                {
1723                        setRouter("Buffalo WZR series");
1724                        return ROUTER_BUFFALO_WZRRSG54;
1725                }
1726        }
1727#ifndef HAVE_BUFFALO
1728        if (boardnum == 42 && nvram_match("boardtype", "0x042f")
1729            && nvram_match("boardrev", "0x10"))
1730                // nvram_match ("boardflags","0x0018"))
1731        {
1732                setRouter("Linksys WRTSL54GS");
1733                return ROUTER_WRTSL54GS;
1734        }
1735
1736        if (boardnum == 42 && nvram_match("boardtype", "0x0101")
1737            && nvram_match("boardrev", "0x10")
1738            && nvram_match("boot_ver", "v3.6")) {
1739                setRouter("Linksys WRT54G3G");
1740                return ROUTER_WRT54G3G;
1741        }
1742
1743        if (nvram_match("boardtype", "0x042f")
1744            && nvram_match("boardrev", "0x10")) {
1745                char *hwver = nvram_safe_get("hardware_version");
1746
1747                if (boardnum == 45 || startswith(hwver, "WL500gp")
1748                    || startswith(hwver, "WL500gH")) {
1749                        setRouter("Asus WL-500g Premium");
1750                        return ROUTER_ASUS_WL500G_PRE;
1751                }
1752                if (boardnum == 44 || startswith(hwver, "WL700g")) {
1753                        setRouter("Asus WL-700gE");
1754                        return ROUTER_ASUS_WL700GE;
1755                }
1756        }
1757
1758        char *et0 = nvram_safe_get("et0macaddr");
1759
1760        if (boardnum == 100 && nvram_match("boardtype", "bcm94710r4")) {
1761                if (startswith(et0, "00:11:50")) {
1762                        setRouter("Belkin F5D7130 / F5D7330");
1763                        return ROUTER_RT210W;
1764                }
1765                if (startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
1766                        setRouter("Belkin F5D7230-4 v1000");
1767                        return ROUTER_RT210W;
1768                }
1769                if (startswith(et0, "00:01:E3") ||
1770                    startswith(et0, "00:01:e3") || startswith(et0, "00:90:96"))
1771                {
1772                        setRouter("Siemens SE505 v1");
1773                        return ROUTER_RT210W;
1774                } else {
1775                        setRouter("Askey RT210W generic");
1776                        return ROUTER_RT210W;
1777                }
1778        }
1779
1780        if (nvram_match("boardtype", "bcm94710r4")
1781            && nvram_match("boardnum", "")) {
1782                setRouter("Askey board RT2100W-D65)");
1783                return ROUTER_BRCM4702_GENERIC;
1784        }
1785
1786        if (boardnum == 0 && nvram_match("boardtype", "0x0100")
1787            && nvram_match("boardrev", "0x10")) {
1788                if (startswith(et0, "00:11:50") ||
1789                    startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd"))
1790                {
1791                        setRouter("Askey board RT2205(6)D-D56");
1792                } else {
1793                        setRouter("Belkin board F5D8230");
1794                }
1795                return ROUTER_ASKEY_RT220XD;
1796        }
1797
1798        if (nvram_match("boardtype", "0x0101")) {
1799                if (startswith(et0, "00:11:50") ||
1800                    startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd"))
1801                {
1802                        if (nvram_match("Belkin_ver", "2000")) {
1803                                setRouter("Belkin F5D7230-4 v2000");
1804                                return ROUTER_BELKIN_F5D7230_V2000;
1805                        } else {
1806                                setRouter("Belkin F5D7230-4 v1444");
1807                                return ROUTER_RT480W;
1808                        }
1809                }
1810                if (startswith(et0, "00:01:E3") ||
1811                    startswith(et0, "00:01:e3") || startswith(et0, "00:90:96"))
1812                {
1813                        setRouter("Siemens SE505 v2");
1814                        return ROUTER_RT480W;
1815                }
1816        }
1817        if (boardnum == 1 && nvram_match("boardtype", "0x456")
1818            && nvram_match("test_led_gpio", "2")) {
1819                setRouter("Belkin F5D7230-4 v3000");
1820                return ROUTER_BELKIN_F5D7230_V3000;
1821        }
1822
1823        if (nvram_match("boardtype", "0x456")
1824            && nvram_match("hw_model", "F5D7231-4")) {
1825                setRouter("Belkin F5D7231-4 v1212UK");
1826                return ROUTER_BELKIN_F5D7231;
1827        }
1828
1829        if (boardnum == 8 && nvram_match("boardtype", "0x0467"))        // fccid:
1830                // K7SF5D7231B
1831        {
1832                setRouter("Belkin F5D7231-4 v2000");
1833                return ROUTER_BELKIN_F5D7231_V2000;
1834        }
1835
1836        if (nvram_match("boardtype", "0x467")) {
1837                if (startswith(et0, "00:11:50") ||
1838                    startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd"))
1839                {
1840                        setRouter("Belkin F5D7231-4 v2000");
1841                        return ROUTER_BELKIN_F5D7231;
1842                }
1843        }
1844#endif
1845        if (boardnum == 2 && nvram_match("boardtype", "bcm94710dev") && melco_id == 29016)      // Buffalo
1846                // WLI2-TX1-G54)
1847        {
1848                setRouter("Buffalo WLI2-TX1-G54");
1849                return ROUTER_BUFFALO_WLI2_TX1_G54;
1850        }
1851#ifndef HAVE_BUFFALO
1852
1853        char *gemtek = nvram_safe_get("GemtekPmonVer");
1854        unsigned long gemteknum = strtoul(gemtek, NULL, 0);
1855
1856        if (boardnum == 2 && (gemteknum == 10 || gemteknum == 11) &&
1857            (startswith(et0, "00:0C:E5") ||
1858             startswith(et0, "00:0c:e5") ||
1859             startswith(et0, "00:11:22") ||
1860             startswith(et0, "00:0C:10") ||
1861             startswith(et0, "00:0c:10") ||
1862             startswith(et0, "00:0C:11") || startswith(et0, "00:0c:11"))) {
1863                setRouter("Motorola WE800G v1");
1864                return ROUTER_MOTOROLA_WE800G;
1865        }
1866
1867        if (boardnum == 2
1868            && (startswith(gemtek, "RC") || gemteknum == 1 || gemteknum == 10))
1869        {
1870                setRouter("Linksys WAP54G v1.x");
1871                return ROUTER_WAP54G_V1;
1872        }
1873
1874        if (boardnum == 2 && gemteknum == 1) {
1875                setRouter("Sitecom WL-105(b)");
1876                return ROUTER_SITECOM_WL105B;
1877        }
1878
1879        if (boardnum == 2 && gemteknum == 7
1880            && nvram_match("boardtype", "bcm94710dev")) {
1881                setRouter("Sitecom WL-111");
1882                return ROUTER_SITECOM_WL111;
1883        }
1884
1885        if (gemteknum == 9)     // Must be Motorola wr850g v1 or we800g v1 or
1886                // Linksys wrt55ag v1
1887        {
1888                if (startswith(et0, "00:0C:E5") ||
1889                    startswith(et0, "00:0c:e5") ||
1890                    startswith(et0, "00:0C:10") ||
1891                    startswith(et0, "00:0c:10") ||
1892                    startswith(et0, "00:0C:11") ||
1893                    startswith(et0, "00:0c:11") ||
1894                    startswith(et0, "00:11:22") ||
1895                    startswith(et0, "00:0C:90") || startswith(et0, "00:0c:90"))
1896                {
1897                        if (!strlen(nvram_safe_get("phyid_num"))) {
1898                                insmod("switch-core");  // get phy type
1899                                insmod("switch-robo");
1900                                rmmod("switch-robo");
1901                                rmmod("switch-core");
1902                                nvram_set("boardnum", "2");
1903                                nvram_set("boardtype", "bcm94710dev");
1904                        }
1905                        if (nvram_match("phyid_num", "0x00000000")) {
1906                                setRouter("Motorola WE800G v1");
1907                                return ROUTER_MOTOROLA_WE800G;
1908                        } else  // phyid_num == 0xffffffff
1909                        {
1910                                setRouter("Motorola WR850G v1");
1911                                return ROUTER_MOTOROLA_V1;
1912                        }
1913                } else {
1914                        setRouter("Linksys WRT55AG v1");
1915                        return ROUTER_LINKSYS_WRT55AG;
1916                }
1917        }
1918#endif
1919        if (boardnum == 0 && nvram_match("boardtype", "0x478")
1920            && nvram_match("cardbus", "0") && nvram_match("boardrev", "0x10")
1921            && nvram_match("boardflags", "0x110") && melco_id == 32027) {
1922                setRouter("Buffalo WZR-G144NH");
1923                return ROUTER_BUFFALO_WZRG144NH;
1924        }
1925
1926        if (boardnum == 20060330 && nvram_match("boardtype", "0x0472")) {
1927                setRouter("Buffalo WZR-G300N");
1928                return ROUTER_BUFFALO_WZRG300N;
1929        }
1930#ifndef HAVE_BUFFALO
1931
1932        if (boardnum == 8 && nvram_match("boardtype", "0x0472")
1933            && nvram_match("cardbus", "1")) {
1934                setRouter("Netgear WNR834B");
1935                return ROUTER_NETGEAR_WNR834B;
1936        }
1937
1938        if (boardnum == 1 && nvram_match("boardtype", "0x0472")
1939            && nvram_match("boardrev", "0x23")) {
1940                if (nvram_match("cardbus", "1")) {
1941                        setRouter("Netgear WNR834B v2");
1942                        return ROUTER_NETGEAR_WNR834BV2;
1943                } else {
1944                        setRouter("Netgear WNDR3300");
1945                        return ROUTER_NETGEAR_WNDR3300;
1946                }
1947        }
1948
1949        if (boardnum == 42)     // Get Linksys N models
1950        {
1951                if (nvram_match("boot_hw_model", "WRT300N")
1952                    && nvram_match("boot_hw_ver", "1.1")) {
1953                        setRouter("Linksys WRT300N v1.1");
1954                        return ROUTER_WRT300NV11;
1955                } else if (nvram_match("boot_hw_model", "WRT150N")
1956                           && nvram_match("boot_hw_ver", "1")) {
1957                        setRouter("Linksys WRT150N v1");
1958                        return ROUTER_WRT150N;
1959                } else if (nvram_match("boot_hw_model", "WRT150N")
1960                           && nvram_match("boot_hw_ver", "1.1")) {
1961                        setRouter("Linksys WRT150N v1.1");
1962                        return ROUTER_WRT150N;
1963                } else if (nvram_match("boot_hw_model", "WRT150N")
1964                           && nvram_match("boot_hw_ver", "1.2")) {
1965                        setRouter("Linksys WRT150N v1.2");
1966                        return ROUTER_WRT150N;
1967                } else if (nvram_match("boot_hw_model", "WRT160N")
1968                           && nvram_match("boot_hw_ver", "1.0")) {
1969                        setRouter("Linksys WRT160N");
1970                        return ROUTER_WRT160N;
1971                } else if (nvram_match("boot_hw_model", "WRT160N")
1972                           && nvram_match("boot_hw_ver", "3.0")) {
1973                        setRouter("Linksys WRT160N v3");
1974                        return ROUTER_WRT160NV3;
1975                } else if (nvram_match("boot_hw_model", "M10")
1976                           && nvram_match("boot_hw_ver", "1.0")) {
1977                        setRouter("Cisco Valet M10 v1");        // renamed wrt160nv3
1978                        return ROUTER_WRT160NV3;
1979                } else if (nvram_match("boot_hw_model", "E100")
1980                           && nvram_match("boot_hw_ver", "1.0")) {
1981                        setRouter("Linksys E1000 v1");  // renamed wrt160nv3
1982                        return ROUTER_WRT160NV3;
1983                } else if (nvram_match("boot_hw_model", "E1000")
1984                           && nvram_match("boot_hw_ver", "2.0")) {
1985                        setRouter("Linksys E1000 v2");
1986                        return ROUTER_LINKSYS_E1000V2;
1987                } else if (nvram_match("boot_hw_model", "E1000")
1988                           && nvram_match("boot_hw_ver", "2.1")) {
1989                        setRouter("Linksys E1000 v2.1");
1990                        return ROUTER_LINKSYS_E1000V2;
1991                } else if (nvram_match("boot_hw_model", "WRT310N")
1992                           && nvram_match("boot_hw_ver", "1.0")) {
1993                        setRouter("Linksys WRT310N");
1994                        return ROUTER_WRT310N;
1995                } else if (nvram_match("boot_hw_model", "WRT310N")
1996                           && nvram_match("boot_hw_ver", "2.0")) {
1997                        setRouter("Linksys WRT310N v2");
1998                        return ROUTER_WRT310NV2;
1999                } else if (nvram_match("boot_hw_model", "M20")
2000                           && nvram_match("boot_hw_ver", "1.0")) {
2001                        setRouter("Cisco Valet Plus M20");      // ranamed wrt310nv2
2002                        return ROUTER_WRT310NV2;
2003                } else if (nvram_match("boot_hw_model", "E2500")
2004                           && nvram_match("boot_hw_ver", "1.0")) {
2005                        setRouter("Linksys E2500");
2006                        return ROUTER_LINKSYS_E2500;
2007                } else if (nvram_match("boot_hw_model", "E3200")
2008                           && nvram_match("boot_hw_ver", "1.0")) {
2009                        setRouter("Linksys E3200");
2010                        return ROUTER_LINKSYS_E3200;
2011                } else if (nvram_match("boot_hw_model", "E4200")
2012                           && nvram_match("boot_hw_ver", "1.0")) {
2013                        setRouter("Linksys E4200");
2014                        return ROUTER_LINKSYS_E4200;
2015                }
2016        }
2017
2018        if (boardnum == 42 && nvram_match("boardtype", "0x0472")
2019            && nvram_match("cardbus", "1")) {
2020                setRouter("Linksys WRT300N v1");
2021                return ROUTER_WRT300N;
2022        }
2023
2024        if (boardnum == 42 &&
2025            nvram_match("boardtype", "0x478") && nvram_match("cardbus", "1")) {
2026                setRouter("Linksys WRT350N");
2027                return ROUTER_WRT350N;
2028        }
2029
2030        if (nvram_match("boardnum", "20070615") &&
2031            nvram_match("boardtype", "0x478") && nvram_match("cardbus", "0")) {
2032                if (nvram_match("switch_type", "BCM5395")) {
2033                        setRouter("Linksys WRT600N v1.1");
2034                        return ROUTER_WRT600N;
2035                } else {
2036                        setRouter("Linksys WRT600N");
2037                        return ROUTER_WRT600N;
2038                }
2039        }
2040
2041        if (nvram_match("boardtype", "0x478")
2042            && nvram_match("boot_hw_model", "WRT610N")) {
2043                setRouter("Linksys WRT610N");
2044                return ROUTER_WRT610N;
2045        }
2046#ifdef HAVE_BCMMODERN
2047        if (nvram_match("boardtype", "0x04cf")
2048            && nvram_match("boot_hw_model", "WRT610N")) {
2049                setRouter("Linksys WRT610N v2");
2050                return ROUTER_WRT610NV2;
2051        }
2052
2053        if (nvram_match("boardtype", "0x04cf")
2054            && nvram_match("boot_hw_model", "E300")) {
2055                setRouter("Linksys E3000");     // renamed wrt610nv2
2056                return ROUTER_WRT610NV2;
2057        }
2058#endif
2059
2060        if (boardnum == 42 && nvram_match("boardtype", "bcm94710dev")) {
2061                setRouter("Linksys WRT54G v1.x");
2062                return ROUTER_WRT54G1X;
2063        }
2064
2065        if ((boardnum == 1 || boardnum == 0)
2066            && nvram_match("boardtype", "0x0446")) {
2067                setRouter("U.S.Robotics USR5430");
2068                return ROUTER_USR_5430;
2069        }
2070
2071        if (boardnum == 1 && nvram_match("boardtype", "0x456")
2072            && nvram_match("test_led_gpio", "0")) {
2073                setRouter("Netgear WG602 v3");
2074                return ROUTER_NETGEAR_WG602_V3;
2075        }
2076
2077        if (boardnum == 10496 && nvram_match("boardtype", "0x456")) {
2078                setRouter("U.S.Robotics USR5461");
2079                return ROUTER_USR_5461;
2080        }
2081
2082        if (boardnum == 10500 && nvram_match("boardtype", "0x456")) {
2083                setRouter("U.S.Robotics USR5432");
2084                return ROUTER_USR_5461; // should work in the same way
2085        }
2086
2087        if (boardnum == 10506 && nvram_match("boardtype", "0x456")) {
2088                setRouter("U.S.Robotics USR5451");
2089                return ROUTER_USR_5461; // should work in the same way
2090        }
2091
2092        if (boardnum == 10512 && nvram_match("boardtype", "0x456")) {
2093                setRouter("U.S.Robotics USR5441");
2094                return ROUTER_USR_5461; // should work in the same way
2095        }
2096
2097        if ((boardnum == 35324 || boardnum == 38256)
2098            && nvram_match("boardtype", "0x048e")) {
2099                setRouter("U.S.Robotics USR5465");
2100                return ROUTER_USR_5465;
2101        }
2102
2103        if (boardnum == 35334 && nvram_match("boardtype", "0x048e")) {
2104                setRouter("U.S.Robotics USR5455");
2105                return ROUTER_USR_5465; // should work in the same way
2106        }
2107
2108        if (boardnum == 1024 && nvram_match("boardtype", "0x0446")) {
2109                char *cfe = nvram_safe_get("cfe_version");
2110
2111                if (strstr(cfe, "WRE54G")) {
2112                        setRouter("Linksys WRE54G v1");
2113                        return ROUTER_WAP54G_V2;
2114                } else if (strstr(cfe, "iewsonic")) {
2115                        setRouter("Viewsonic WAPBR-100");
2116                        return ROUTER_VIEWSONIC_WAPBR_100;
2117                } else {
2118                        setRouter("Linksys WAP54G v2");
2119                        return ROUTER_WAP54G_V2;
2120                }
2121        }
2122
2123        if (nvram_invmatch("CFEver", "")) {
2124                char *cfe = nvram_safe_get("CFEver");
2125
2126                if (!strncmp(cfe, "MotoWR", 6)) {
2127                        setRouter("Motorola WR850G v2/v3");
2128                        return ROUTER_MOTOROLA;
2129                }
2130        }
2131
2132        if (boardnum == 44 && (nvram_match("boardtype", "0x0101")
2133                               || nvram_match("boardtype", "0x0101\r"))) {
2134                char *cfe = nvram_safe_get("CFEver");
2135
2136                if (!strncmp(cfe, "GW_WR110G", 9)) {
2137                        setRouter("Sparklan WX-6615GT");
2138                        return ROUTER_DELL_TRUEMOBILE_2300_V2;
2139                } else {
2140                        setRouter("Dell TrueMobile 2300 v2");
2141                        return ROUTER_DELL_TRUEMOBILE_2300_V2;
2142                }
2143        }
2144#endif
2145        if (nvram_match("boardtype", "bcm94710ap")) {
2146                setRouter("Buffalo WBR-B11");
2147                return ROUTER_BUFFALO_WBR54G;
2148        }
2149#ifndef HAVE_BUFFALO
2150        if (boardnum == 0 && nvram_match("boardtype", "0x048e") &&      // cfe sets boardnum="", strtoul -> 0
2151            nvram_match("boardrev", "0x35")) {
2152                setRouter("D-Link DIR-320");
2153                // apply some fixes
2154                if (nvram_get("vlan2ports") != NULL) {
2155                        nvram_unset("vlan2ports");
2156                        nvram_unset("vlan2hwname");
2157                }
2158                return ROUTER_DLINK_DIR320;
2159        }
2160        if (nvram_match("model_name", "DIR-330") &&
2161            nvram_match("boardrev", "0x10")) {
2162                setRouter("D-Link DIR-330");
2163                nvram_set("wan_ifnames", "eth0");       // quirk
2164                nvram_set("wan_ifname", "eth0");
2165                if (nvram_match("et0macaddr", "00:90:4c:4e:00:0c")) {
2166                        FILE *in = fopen("/dev/mtdblock/1", "rb");
2167
2168                        fseek(in, 0x7a0022, SEEK_SET);
2169                        char mac[32];
2170
2171                        fread(mac, 32, 1, in);
2172                        fclose(in);
2173                        mac[17] = 0;
2174                        if (sv_valid_hwaddr(mac)) {
2175                                nvram_set("et0macaddr", mac);
2176                                fprintf(stderr, "restore D-Link MAC\n");
2177                                nvram_commit();
2178                                sys_reboot();
2179                        }
2180                }
2181                /*
2182                 * if (nvram_get("vlan2ports")!=NULL) { nvram_unset("vlan2ports");
2183                 * nvram_unset("vlan2hwname"); }
2184                 */
2185                return ROUTER_DLINK_DIR330;
2186        }
2187        if (boardnum == 42 && nvram_match("boardtype", "0x048e")
2188            && nvram_match("boardrev", "0x10")) {
2189                if (nvram_match("boardflags", "0x20750")) {
2190                        setRouter("Linksys WRT54G2 / GS2");     // router is wrt54g2v1/v1.3/gs2v1
2191                } else {
2192                        setRouter("Linksys WRT54Gv8 / GSv7");
2193                }
2194                return ROUTER_WRT54G_V8;
2195        }
2196
2197        if (boardnum == 8 && nvram_match("boardtype", "0x048e")
2198            && nvram_match("boardrev", "0x11")) {
2199                setRouter("ALLNET EUROWRT 54"); //ALLNET01
2200                return ROUTER_ALLNET01;
2201        }
2202
2203        if (boardnum == 01 && nvram_match("boardtype", "0x048e")
2204            && nvram_match("boardrev", "0x11")
2205            && (nvram_match("boardflags", "0x650")
2206                || nvram_match("boardflags", "0x0458"))) {
2207                setRouter("Netgear WG602 v4");
2208                return ROUTER_NETGEAR_WG602_V4;
2209        }
2210
2211        if (boardnum == 1 && nvram_match("boardtype", "0x048e")
2212            && nvram_match("boardrev", "0x35")
2213            && nvram_match("parefldovoltage", "0x28")) {
2214                setRouter("NetCore NW618 / Rosewill RNX-GX4");
2215                return ROUTER_NETCORE_NW618;
2216        }
2217
2218        if (boardnum == 42 && nvram_match("boardtype", "0x048E")
2219            && nvram_match("boardrev", "0x10")) {
2220                setRouter("Linksys WRH54G");
2221                return ROUTER_LINKSYS_WRH54G;
2222        }
2223
2224        if (nvram_match("boardnum", "00") && nvram_match("boardtype", "0x048E")
2225            && nvram_match("boardrev", "0x10")) {
2226                setRouter("Linksys WRT54G v8.1");
2227                return ROUTER_WRT54G_V81;
2228        }
2229
2230        if (boardnum == 45 && nvram_match("boardtype", "0x456")) {
2231                setRouter("Asus WL-520G");
2232                return ROUTER_ASUS_WL520G;
2233        }
2234
2235        if (nvram_match("boardtype", "0x48E")
2236            && nvram_match("boardrev", "0x10")) {
2237                char *hwver = nvram_safe_get("hardware_version");
2238
2239                if (boardnum == 45 && startswith(hwver, "WL500GPV2")) {
2240                        setRouter("Asus WL-500G Premium v2");
2241                        return ROUTER_ASUS_WL500G_PRE_V2;
2242                } else if (boardnum == 45 && startswith(hwver, "WL330GE")) {
2243                        setRouter("Asus WL-330GE");
2244                        return ROUTER_ASUS_330GE;
2245                } else if (boardnum == 45 || startswith(hwver, "WL500GU")
2246                           || startswith(hwver, "WL500GC")) {
2247                        setRouter("Asus WL-520GU/GC");
2248                        return ROUTER_ASUS_WL520GUGC;
2249                }
2250        }
2251
2252        if ((boardnum == 83258 || boardnum == 1 || boardnum == 0123)    //or 01 or 001 or 0x01
2253            && (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
2254        {
2255                setRouter("Netgear WGR614v8/L/WW");
2256                return ROUTER_NETGEAR_WGR614L;
2257        }
2258
2259        if (boardnum == 3805 && nvram_match("boardtype", "0x48E")
2260            && nvram_match("boardrev", "0x10")) {
2261                setRouter("Netgear WGR614v9");
2262                return ROUTER_NETGEAR_WGR614V9;
2263        }
2264
2265        if (boardnum == 56 && nvram_match("boardtype", "0x456")
2266            && nvram_match("boardrev", "0x10")) {
2267                setRouter("Linksys WTR54GS");
2268                return ROUTER_LINKSYS_WTR54GS;
2269        }
2270
2271        if (nvram_match("boardnum", "WAP54GV3_8M_0614")
2272            && (nvram_match("boardtype", "0x0467")
2273                || nvram_match("boardtype", "0x467"))
2274            && nvram_match("WAPver", "3")) {
2275                setRouter("Linksys WAP54G v3.x");
2276                return ROUTER_WAP54G_V3;
2277        }
2278#ifdef HAVE_BCMMODERN
2279        if (boardnum == 1 && nvram_match("boardtype", "0xE4CD")
2280            && nvram_match("boardrev", "0x1700")) {
2281                setRouter("Netgear WNR2000 v2");
2282                return ROUTER_NETGEAR_WNR2000V2;
2283        }
2284
2285        if ((boardnum == 1 || boardnum == 3500)
2286            && nvram_match("boardtype", "0x04CF")
2287            && (nvram_match("boardrev", "0x1213")
2288                || nvram_match("boardrev", "02"))) {
2289                setRouter("Netgear WNR3500v2/U/L");
2290                return ROUTER_NETGEAR_WNR3500L;
2291        }
2292
2293        if (nvram_match("boardnum", "01") && nvram_match("boardtype", "0xb4cf")
2294            && nvram_match("boardrev", "0x1100")) {
2295                setRouter("Netgear WNDR3400");
2296                return ROUTER_NETGEAR_WNDR3400;
2297        }
2298
2299        if (nvram_match("boardnum", "01") && nvram_match("boardtype", "0xF52C")
2300            && nvram_match("boardrev", "0x1101")) {
2301                setRouter("Netgear WNDR4000");
2302                return ROUTER_NETGEAR_WNDR4000;
2303        }
2304
2305        if (nvram_match("boardnum", "4536")
2306            && nvram_match("boardtype", "0xf52e")
2307            && nvram_match("boardrev", "0x1102")) {
2308                setRouter("Netgear WNDR4500");
2309                return ROUTER_NETGEAR_WNDR4500;
2310        }
2311
2312        if ((boardnum == 42 || boardnum == 66)
2313            && nvram_match("boardtype", "0x04EF")
2314            && (nvram_match("boardrev", "0x1304")
2315                || nvram_match("boardrev", "0x1305"))) {
2316                setRouter("Linksys WRT320N");
2317                return ROUTER_WRT320N;
2318        }
2319
2320        if (boardnum == 42 && nvram_match("boardtype", "0x04EF")
2321            && nvram_match("boardrev", "0x1307")) {
2322                setRouter("Linksys E2000");     // renamed (and fixed reset button) wrt320n
2323                return ROUTER_WRT320N;
2324        }
2325#endif
2326
2327        if (boardnum == 94703 && nvram_match("boardtype", "0x04c0")
2328            && nvram_match("boardrev", "0x1100")) {
2329                setRouter("Dynex DX-NRUTER");
2330                return ROUTER_DYNEX_DX_NRUTER;
2331        }
2332
2333        setRouter("Linksys WRT54G/GL/GS");
2334        return ROUTER_WRT54G;
2335#else
2336        eval("event", "3", "1", "15");
2337        return 0;
2338#endif
2339#endif
2340#endif
2341}
2342
2343static int router_type = -1;
2344int getRouterBrand()
2345{
2346        if (router_type == -1)
2347                router_type = internal_getRouterBrand();
2348        return router_type;
2349}
2350
2351int get_ppp_pid(char *file)
2352{
2353        char buf[80];
2354        int pid = -1;
2355
2356        if (file_to_buf(file, buf, sizeof(buf))) {
2357                char tmp[80], tmp1[80];
2358
2359                snprintf(tmp, sizeof(tmp), "/var/run/%s.pid", buf);
2360                file_to_buf(tmp, tmp1, sizeof(tmp1));
2361                pid = atoi(tmp1);
2362        }
2363        return pid;
2364}
2365
2366int check_wan_link(int num)
2367{
2368        int wan_link = 0;
2369
2370        if ((nvram_match("wan_proto", "pptp")
2371#ifdef HAVE_L2TP
2372             || nvram_match("wan_proto", "l2tp")
2373#endif
2374#ifdef HAVE_PPPOE
2375             || nvram_match("wan_proto", "pppoe")
2376#endif
2377#ifdef HAVE_PPPOA
2378             || nvram_match("wan_proto", "pppoa")
2379#endif
2380#ifdef HAVE_3G
2381             || nvram_match("wan_proto", "3g")
2382#endif
2383             || nvram_match("wan_proto", "heartbeat"))
2384            && !nvram_match("3gdata", "hso")) {
2385                FILE *fp;
2386                char filename[80];
2387                char *name;
2388
2389                if (num == 0)
2390                        strcpy(filename, "/tmp/ppp/link");
2391                if ((fp = fopen(filename, "r"))) {
2392                        int pid = -1;
2393
2394                        fclose(fp);
2395                        if (nvram_match("wan_proto", "heartbeat")) {
2396                                char buf[20];
2397
2398                                file_to_buf("/tmp/ppp/link", buf, sizeof(buf));
2399                                pid = atoi(buf);
2400                        } else
2401                                pid = get_ppp_pid(filename);
2402
2403                        name = find_name_by_proc(pid);
2404                        if (!strncmp(name, "pppoecd", 7) ||     // for PPPoE
2405                            !strncmp(name, "pppd", 4) ||        // for PPTP
2406                            !strncmp(name, "bpalogin", 8))      // for HeartBeat
2407                                wan_link = 1;   // connect
2408                        else {
2409                                printf("The %s had been died, remove %s\n",
2410                                       nvram_safe_get("wan_proto"), filename);
2411                                wan_link = 0;   // For some reason, the pppoed had been died,
2412                                // by link file still exist.
2413                                unlink(filename);
2414                        }
2415                }
2416        } else {
2417                if (nvram_invmatch("wan_ipaddr", "0.0.0.0"))
2418                        wan_link = 1;
2419        }
2420
2421        return wan_link;
2422}
2423
2424#if defined(HAVE_BUFFALO) || defined(HAVE_BUFFALO_BL_DEFAULTS) || defined(HAVE_WMBR_G300NH)
2425void *getUEnv(char *name)
2426{
2427#ifdef HAVE_WZRG300NH
2428#define UOFFSET 0x40000
2429#elif HAVE_WZRHPAG300NH
2430#define UOFFSET 0x40000
2431#elif HAVE_WZRG450
2432#define UOFFSET 0x40000
2433#elif HAVE_WMBR_G300NH
2434#define UOFFSET 0x0
2435#else
2436#define UOFFSET 0x3E000
2437#endif
2438//      static char res[64];
2439        static char res[256];
2440        memset(res, 0, sizeof(res));
2441        //fprintf(stderr,"[u-boot env]%s\n",name);
2442#ifdef HAVE_WMBR_G300NH
2443        FILE *fp = fopen("/dev/mtdblock/1", "rb");
2444#else
2445        FILE *fp = fopen("/dev/mtdblock/0", "rb");
2446#endif
2447        fseek(fp, UOFFSET, SEEK_SET);
2448        char *mem = safe_malloc(0x2000);
2449        fread(mem, 0x2000, 1, fp);
2450        fclose(fp);
2451        int s = (0x2000 - 1) - strlen(name);
2452        int i;
2453        int l = strlen(name);
2454        for (i = 0; i < s; i++) {
2455                if (!strncmp(mem + i, name, l)) {
2456                        strncpy(res, mem + i + l + 1, sizeof(res) - 1);
2457                        free(mem);
2458                        return res;
2459                }
2460        }
2461        free(mem);
2462        return NULL;
2463}
2464#endif
2465
2466char *get_wan_ipaddr(void)
2467{
2468        char *wan_ipaddr;
2469        char *wan_proto = nvram_safe_get("wan_proto");
2470        int wan_link = check_wan_link(0);
2471
2472        if (!strcmp(wan_proto, "pptp")) {
2473                wan_ipaddr =
2474                    wan_link ? nvram_safe_get("pptp_get_ip") :
2475                    nvram_safe_get("wan_ipaddr");
2476        } else if (!strcmp(wan_proto, "pppoe")
2477#ifdef HAVE_PPPOATM
2478                   || !strcmp(wan_proto, "pppoa")
2479#endif
2480#ifdef HAVE_3G
2481                   || !strcmp(wan_proto, "3g")
2482#endif
2483            ) {
2484                wan_ipaddr =
2485                    wan_link ? nvram_safe_get("wan_ipaddr") : "0.0.0.0";
2486#ifdef HAVE_L2TP
2487        } else if (!strcmp(wan_proto, "l2tp")) {
2488                wan_ipaddr =
2489                    wan_link ? nvram_safe_get("l2tp_get_ip") :
2490                    nvram_safe_get("wan_ipaddr");
2491#endif
2492        } else {
2493                wan_ipaddr = nvram_safe_get("wan_ipaddr");
2494        }
2495        return wan_ipaddr;
2496}
2497
2498/*
2499 * Find process name by pid from /proc directory
2500 */
2501char *find_name_by_proc(int pid)
2502{
2503        FILE *fp;
2504        char line[254];
2505        char filename[80];
2506        static char name[80];
2507
2508        snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
2509
2510        if ((fp = fopen(filename, "r"))) {
2511                fgets(line, sizeof(line), fp);
2512                /*
2513                 * Buffer should contain a string like "Name: binary_name"
2514                 */
2515                sscanf(line, "%*s %s", name);
2516                fclose(fp);
2517                return name;
2518        }
2519
2520        return "";
2521}
2522
2523int diag_led_4702(int type, int act)
2524{
2525
2526#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)
2527        return 0;
2528#else
2529        if (act == START_LED) {
2530                switch (type) {
2531                case DMZ:
2532                        writeproc("/proc/sys/diag","1");
2533                        break;
2534                }
2535        } else {
2536                switch (type) {
2537                case DMZ:
2538                        writeproc("/proc/sys/diag","0");
2539                        break;
2540                }
2541        }
2542        return 0;
2543#endif
2544}
2545
2546int C_led_4702(int i)
2547{
2548#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)
2549        return 0;
2550#else
2551        FILE *fp;
2552        char string[10];
2553        int flg;
2554
2555        memset(string, 0, 10);
2556        /*
2557         * get diag before set
2558         */
2559        if ((fp = fopen("/proc/sys/diag", "r"))) {
2560                fgets(string, sizeof(string), fp);
2561                fclose(fp);
2562        } else
2563                perror("/proc/sys/diag");
2564
2565        if (i)
2566                flg = atoi(string) | 0x10;
2567        else
2568                flg = atoi(string) & 0xef;
2569
2570        memset(string, 0, 10);
2571        sprintf(string, "%d", flg);
2572        writeproc("/proc/sys/diag",string);
2573
2574        return 0;
2575#endif
2576}
2577
2578unsigned int read_gpio(char *device)
2579{
2580        FILE *fp;
2581        unsigned int val;
2582
2583        if ((fp = fopen(device, "r"))) {
2584                fread(&val, 4, 1, fp);
2585                fclose(fp);
2586                // fprintf(stderr, "----- gpio %s = [%X]\n",device,val);
2587                return val;
2588        } else {
2589                perror(device);
2590                return 0;
2591        }
2592}
2593
2594unsigned int write_gpio(char *device, unsigned int val)
2595{
2596        FILE *fp;
2597
2598        if ((fp = fopen(device, "w"))) {
2599                fwrite(&val, 4, 1, fp);
2600                fclose(fp);
2601                // fprintf(stderr, "----- set gpio %s = [%X]\n",device,val);
2602                return 1;
2603        } else {
2604                perror(device);
2605                return 0;
2606        }
2607}
2608
2609static char hw_error = 0;
2610int diag_led_4704(int type, int act)
2611{
2612#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)
2613        return 0;
2614#else
2615        unsigned int control, in, outen, out;
2616
2617#ifdef BCM94712AGR
2618        /*
2619         * The router will crash, if we load the code into broadcom demo board.
2620         */
2621        return 1;
2622#endif
2623        // int brand;
2624        control = read_gpio("/dev/gpio/control");
2625        in = read_gpio("/dev/gpio/in");
2626        out = read_gpio("/dev/gpio/out");
2627        outen = read_gpio("/dev/gpio/outen");
2628
2629        write_gpio("/dev/gpio/outen", (outen & 0x7c) | 0x83);
2630        switch (type) {
2631        case DIAG:              // GPIO 1
2632                if (hw_error) {
2633                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x00);
2634                        return 1;
2635                }
2636
2637                if (act == STOP_LED) {  // stop blinking
2638                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x83);
2639                        // cprintf("tallest:=====( DIAG STOP_LED !!)=====\n");
2640                } else if (act == START_LED) {  // start blinking
2641                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x81);
2642                        // cprintf("tallest:=====( DIAG START_LED !!)=====\n");
2643                } else if (act == MALFUNCTION_LED) {    // start blinking
2644                        write_gpio("/dev/gpio/out", (out & 0x7c) | 0x00);
2645                        hw_error = 1;
2646                        // cprintf("tallest:=====( DIAG MALFUNCTION_LED !!)=====\n");
2647                }
2648                break;
2649
2650        }
2651        return 1;
2652#endif
2653}
2654
2655int diag_led_4712(int type, int act)
2656{
2657        unsigned int control, in, outen, out, ctr_mask, out_mask;
2658
2659#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)
2660        return 0;
2661#else
2662
2663#ifdef BCM94712AGR
2664        /*
2665         * The router will crash, if we load the code into broadcom demo board.
2666         */
2667        return 1;
2668#endif
2669        control = read_gpio("/dev/gpio/control");
2670        in = read_gpio("/dev/gpio/in");
2671        out = read_gpio("/dev/gpio/out");
2672        outen = read_gpio("/dev/gpio/outen");
2673
2674        ctr_mask = ~(1 << type);
2675        out_mask = (1 << type);
2676
2677        write_gpio("/dev/gpio/control", control & ctr_mask);
2678        write_gpio("/dev/gpio/outen", outen | out_mask);
2679
2680        if (act == STOP_LED) {  // stop blinking
2681                // cprintf("%s: Stop GPIO %d\n", __FUNCTION__, type);
2682                write_gpio("/dev/gpio/out", out | out_mask);
2683        } else if (act == START_LED) {  // start blinking
2684                // cprintf("%s: Start GPIO %d\n", __FUNCTION__, type);
2685                write_gpio("/dev/gpio/out", out & ctr_mask);
2686        }
2687
2688        return 1;
2689#endif
2690}
2691
2692int C_led_4712(int i)
2693{
2694        if (i == 1)
2695                return diag_led(DIAG, START_LED);
2696        else
2697                return diag_led(DIAG, STOP_LED);
2698}
2699
2700int C_led(int i)
2701{
2702        int brand = getRouterBrand();
2703
2704        if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
2705                return C_led_4702(i);
2706        else if (brand == ROUTER_WRT54G)
2707                return C_led_4712(i);
2708        else
2709                return 0;
2710}
2711
2712int diag_led(int type, int act)
2713{
2714        int brand = getRouterBrand();
2715
2716        if (brand == ROUTER_WRT54G || brand == ROUTER_WRT54G3G
2717            || brand == ROUTER_WRT300NV11)
2718                return diag_led_4712(type, act);
2719        else if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
2720                return diag_led_4702(type, act);
2721        else if ((brand == ROUTER_WRTSL54GS
2722                  || brand == ROUTER_WRT310N || brand == ROUTER_WRT350N
2723                  || brand == ROUTER_BUFFALO_WZRG144NH) && type == DIAG)
2724                return diag_led_4704(type, act);
2725        else {
2726                if (type == DMZ) {
2727                        if (act == START_LED)
2728                                return led_control(LED_DMZ, LED_ON);
2729                        if (act == STOP_LED)
2730                                return led_control(LED_DMZ, LED_OFF);
2731                        return 1;
2732                }
2733        }
2734        return 0;
2735}
2736
2737#ifdef HAVE_MADWIFI
2738static char *stalist[] = {
2739        "ath0", "ath1", "ath2", "ath3", "ath4", "ath5", "ath6", "ath8", "ath9"
2740};
2741
2742char *getWifi(char *ifname)
2743{
2744        if (!strncmp(ifname, "ath0", 4))
2745                return "wifi0";
2746        if (!strncmp(ifname, "ath1", 4))
2747                return "wifi1";
2748        if (!strncmp(ifname, "ath2", 4))
2749                return "wifi2";
2750        if (!strncmp(ifname, "ath3", 4))
2751                return "wifi3";
2752        return NULL;
2753}
2754
2755char *getWDSSTA(void)
2756{
2757
2758        int c = getdevicecount();
2759        int i;
2760
2761        for (i = 0; i < c; i++) {
2762                char mode[32];
2763                char netmode[32];
2764
2765                sprintf(mode, "ath%d_mode", i);
2766                sprintf(netmode, "ath%d_net_mode", i);
2767                if (nvram_match(mode, "wdssta")
2768                    && !nvram_match(netmode, "disabled")) {
2769                        return stalist[i];
2770                }
2771
2772        }
2773        return NULL;
2774}
2775
2776char *getSTA(void)
2777{
2778
2779#ifdef HAVE_WAVESAT
2780        if (nvram_match("ofdm_mode", "sta"))
2781                return "ofdm";
2782#endif
2783        int c = getdevicecount();
2784        int i;
2785
2786        for (i = 0; i < c; i++) {
2787                if (nvram_nmatch("sta", "ath%d_mode", i)
2788                    && !nvram_nmatch("disabled", "ath%d_net_mode", i)) {
2789                        return stalist[i];
2790                }
2791
2792        }
2793        return NULL;
2794}
2795
2796char *getWET(void)
2797{
2798#ifdef HAVE_WAVESAT
2799        if (nvram_match("ofdm_mode", "bridge"))
2800                return "ofdm";
2801#endif
2802        int c = getdevicecount();
2803        int i;
2804
2805        for (i = 0; i < c; i++) {
2806                if (nvram_nmatch("wet", "ath%d_mode", i)
2807                    && !nvram_nmatch("disabled", "ath%d_net_mode", i)) {
2808                        return stalist[i];
2809                }
2810
2811        }
2812        return NULL;
2813}
2814
2815#elif defined(HAVE_RT2880) || defined(HAVE_RT61)
2816
2817char *getSTA()
2818{
2819        int c = get_wl_instances();
2820        int i;
2821
2822        for (i = 0; i < c; i++) {
2823                if (nvram_nmatch("sta", "wl%d_mode", i)) {
2824                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2825                                return "ra0";
2826                }
2827
2828                if (nvram_nmatch("apsta", "wl%d_mode", i)) {
2829                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2830                                return "apcli0";
2831                }
2832
2833        }
2834        return NULL;
2835}
2836
2837char *getWET()
2838{
2839        int c = get_wl_instances();
2840        int i;
2841
2842        for (i = 0; i < c; i++) {
2843                if (!nvram_nmatch("disabled", "wl%d_net_mode", i)
2844                    && nvram_nmatch("wet", "wl%d_mode", i))
2845                        return "ra0";
2846
2847                if (!nvram_nmatch("disabled", "wl%d_net_mode", i)
2848                    && nvram_nmatch("apstawet", "wl%d_mode", i))
2849                        return "apcli0";
2850
2851        }
2852        return NULL;
2853}
2854
2855#else
2856char *getSTA()
2857{
2858        int c = get_wl_instances();
2859        int i;
2860
2861        for (i = 0; i < c; i++) {
2862                if (nvram_nmatch("sta", "wl%d_mode", i)
2863                    || nvram_nmatch("apsta", "wl%d_mode", i)) {
2864                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2865                                return get_wl_instance_name(i);
2866                        // else
2867                        // return nvram_nget ("wl%d_ifname", i);
2868                }
2869
2870        }
2871        return NULL;
2872}
2873
2874char *getWET()
2875{
2876        int c = get_wl_instances();
2877        int i;
2878
2879        for (i = 0; i < c; i++) {
2880                if (nvram_nmatch("wet", "wl%d_mode", i)
2881                    || nvram_nmatch("apstawet", "wl%d_mode", i)) {
2882                        if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2883                                return get_wl_instance_name(i);
2884                        // else
2885                        // return nvram_nget ("wl%d_ifname", i);
2886
2887                }
2888
2889        }
2890        return NULL;
2891}
2892
2893#endif
2894// note - broadcast addr returned in ipaddr
2895void get_broadcast(char *ipaddr, char *netmask)
2896{
2897        int ip2[4], mask2[4];
2898        unsigned char ip[4], mask[4];
2899
2900        if (!ipaddr || !netmask)
2901                return;
2902
2903        sscanf(ipaddr, "%d.%d.%d.%d", &ip2[0], &ip2[1], &ip2[2], &ip2[3]);
2904        sscanf(netmask, "%d.%d.%d.%d", &mask2[0], &mask2[1], &mask2[2],
2905               &mask2[3]);
2906        int i = 0;
2907
2908        for (i = 0; i < 4; i++) {
2909                ip[i] = ip2[i];
2910                mask[i] = mask2[i];
2911                // ip[i] = (ip[i] & mask[i]) | !mask[i];
2912                ip[i] = (ip[i] & mask[i]) | (0xff & ~mask[i]);
2913        }
2914
2915        sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
2916#ifdef WDS_DEBUG
2917        fprintf(fp, "get_broadcast return %s\n", value);
2918#endif
2919
2920}
2921
2922char *get_wan_face(void)
2923{
2924        static char localwanface[IFNAMSIZ];
2925        if (nvram_match("wan_proto", "disabled"))
2926                return "br0";
2927
2928        /*
2929         * if (nvram_match ("pptpd_client_enable", "1")) { strncpy (localwanface,
2930         * "ppp0", IFNAMSIZ); return localwanface; }
2931         */
2932        if (nvram_match("wan_proto", "pptp")
2933#ifdef HAVE_L2TP
2934            || nvram_match("wan_proto", "l2tp")
2935#endif
2936#ifdef HAVE_3G
2937            || nvram_match("wan_proto", "3g")
2938#endif
2939#ifdef HAVE_PPPOATM
2940            || nvram_match("wan_proto", "pppoa")
2941#endif
2942            || nvram_match("wan_proto", "pppoe")) {
2943                if (nvram_match("pppd_pppifname", ""))
2944                        strncpy(localwanface, "ppp0", IFNAMSIZ);
2945                else
2946                        strncpy(localwanface, nvram_safe_get("pppd_pppifname"),
2947                                IFNAMSIZ);
2948        }
2949#ifndef HAVE_MADWIFI
2950        else if (getSTA()) {
2951                strcpy(localwanface, getSTA());
2952        }
2953#else
2954        else if (getSTA()) {
2955                if (nvram_match("wifi_bonding", "1"))
2956                        strcpy(localwanface, "bond0");
2957                else
2958                        strcpy(localwanface, getSTA());
2959        }
2960#endif
2961        else
2962                strncpy(localwanface, nvram_safe_get("wan_ifname"), IFNAMSIZ);
2963
2964        return localwanface;
2965}
2966
2967static int _pidof(const char *name, pid_t ** pids)
2968{
2969        const char *p;
2970        char *e;
2971        DIR *dir;
2972        struct dirent *de;
2973        pid_t i;
2974        int count;
2975        char buf[256];
2976
2977        count = 0;
2978        *pids = NULL;
2979        if ((p = strchr(name, '/')) != NULL)
2980                name = p + 1;
2981        if ((dir = opendir("/proc")) != NULL) {
2982                while ((de = readdir(dir)) != NULL) {
2983                        i = strtol(de->d_name, &e, 10);
2984                        if (*e != 0)
2985                                continue;
2986                        if (strcmp(name, psname(i, buf, sizeof(buf))) == 0) {
2987                                if ((*pids =
2988                                     realloc(*pids,
2989                                             sizeof(pid_t) * (count + 1))) ==
2990                                    NULL) {
2991                                        return -1;
2992                                }
2993                                (*pids)[count++] = i;
2994                        }
2995                }
2996        }
2997        closedir(dir);
2998        return count;
2999}
3000
3001int pidof(const char *name)
3002{
3003        pid_t *pids;
3004        pid_t p;
3005
3006        if (_pidof(name, &pids) > 0) {
3007                p = *pids;
3008                free(pids);
3009                return p;
3010        }
3011        return -1;
3012}
3013
3014int killall(const char *name, int sig)
3015{
3016        pid_t *pids;
3017        int i;
3018        int r;
3019
3020        if ((i = _pidof(name, &pids)) > 0) {
3021                r = 0;
3022                do {
3023                        r |= kill(pids[--i], sig);
3024                }
3025                while (i > 0);
3026                free(pids);
3027                return r;
3028        }
3029        return -2;
3030}
3031
3032void set_ip_forward(char c)
3033{
3034        FILE *fp;
3035        char ch[8];
3036        sprintf(ch,"%c",c);
3037        writeproc("/proc/sys/net/ipv4/ip_forward",ch);
3038}
3039
3040int ifexists(const char *ifname)
3041{
3042        return getifcount(ifname) > 0 ? 1 : 0;
3043}
3044
3045int getdevicecount(void)
3046{
3047        int count = 0;
3048#ifdef HAVE_ATH9K
3049        count += getath9kdevicecount();
3050#endif
3051        count += getifcount("wifi");
3052
3053        return count;
3054}
3055
3056int getifcount(const char *ifprefix)
3057{
3058        /*
3059         * char devcall[128];
3060         *
3061         * sprintf (devcall, "cat /proc/net/dev|grep \"%s\"|wc -l", ifprefix);
3062         * FILE *in = popen (devcall, "rb"); if (in == NULL) return 0; int count;
3063         * fscanf (in, "%d", &count); pclose (in); return count;
3064         */
3065        char *iflist = safe_malloc(256);
3066
3067        memset(iflist, 0, 256);
3068        int c = getIfList(iflist, ifprefix);
3069
3070        free(iflist);
3071        return c;
3072}
3073
3074static void skipline(FILE * in)
3075{
3076        while (1) {
3077                int c = getc(in);
3078
3079                if (c == EOF)
3080                        return;
3081                if (c == 0x0)
3082                        return;
3083                if (c == 0xa)
3084                        return;
3085        }
3086}
3087
3088/*
3089 * strips trailing char(s) c from string
3090 */
3091void strtrim_right(char *p, int c)
3092{
3093        char *end;
3094        int len;
3095
3096        len = strlen(p);
3097        while (*p && len) {
3098                end = p + len - 1;
3099                if (c == *end)
3100                        *end = 0;
3101                else
3102                        break;
3103                len = strlen(p);
3104        }
3105        return;
3106}
3107
3108// returns a physical interfacelist filtered by ifprefix. if ifprefix is
3109// NULL, all valid interfaces will be returned
3110int getIfList(char *buffer, const char *ifprefix)
3111{
3112        FILE *in = fopen("/proc/net/dev", "rb");
3113        char ifname[32];
3114
3115        // skip the first 2 lines
3116        skipline(in);
3117        skipline(in);
3118        int ifcount = 0;
3119        int count = 0;
3120
3121        while (1) {
3122                int c = getc(in);
3123
3124                if (c == 0 || c == EOF) {
3125                        if (count)
3126                                buffer[strlen(buffer) - 1] = 0; // fixup last space
3127                        fclose(in);
3128                        return count;
3129                }
3130                if (c == 0x20)
3131                        continue;
3132                if (c == ':' || ifcount == 30) {
3133                        ifname[ifcount++] = 0;
3134                        int skip = 0;
3135
3136                        if (ifprefix) {
3137                                if (strncmp(ifname, ifprefix, strlen(ifprefix))) {
3138                                        skip = 1;
3139                                }
3140                        } else {
3141                                if (!strncmp(ifname, "wifi", 4))
3142                                        skip = 1;
3143                                if (!strncmp(ifname, "ifb", 3))
3144                                        skip = 1;
3145                                if (!strncmp(ifname, "imq", 3))
3146                                        skip = 1;
3147                                if (!strncmp(ifname, "etherip", 7))
3148                                        skip = 1;
3149                                if (!strncmp(ifname, "lo", 2))
3150                                        skip = 1;
3151                                if (!strncmp(ifname, "teql", 4))
3152                                        skip = 1;
3153                                if (!strncmp(ifname, "gre", 3))
3154                                        skip = 1;
3155                                if (!strncmp(ifname, "ppp", 3))
3156                                        skip = 1;
3157                                if (!strncmp(ifname, "tun", 3))
3158                                        skip = 1;
3159                                if (!strncmp(ifname, "tap", 3))
3160                                        skip = 1;
3161                        }
3162                        if (!skip) {
3163                                strcat(buffer, ifname);
3164                                strcat(buffer, " ");
3165                                count++;
3166                        }
3167                        skip = 0;
3168                        ifcount = 0;
3169                        memset(ifname, 0, 32);
3170                        skipline(in);
3171                        continue;
3172                }
3173                if (ifcount < 30)
3174                        ifname[ifcount++] = c;
3175        }
3176}
3177
3178/*
3179 * Example: legal_hwaddr("00:11:22:33:44:aB"); return true;
3180 * legal_hwaddr("00:11:22:33:44:5"); return false;
3181 * legal_hwaddr("00:11:22:33:44:HH"); return false;
3182 */
3183int sv_valid_hwaddr(char *value)
3184{
3185        unsigned int hwaddr[6];
3186        int tag = TRUE;
3187        int i, count;
3188
3189        /*
3190         * Check for bad, multicast, broadcast, or null address
3191         */
3192        for (i = 0, count = 0; *(value + i); i++) {
3193                if (*(value + i) == ':') {
3194                        if ((i + 1) % 3 != 0) {
3195                                tag = FALSE;
3196                                break;
3197                        }
3198                        count++;
3199                } else if (ishexit(*(value + i)))       /* one of 0 1 2 3 4 5 6 7 8 9
3200                                                         * a b c d e f A B C D E F */
3201                        continue;
3202                else {
3203                        tag = FALSE;
3204                        break;
3205                }
3206        }
3207
3208        if (!tag || i != 17 || count != 5)      /* must have 17's characters and 5's
3209                                                 * ':' */
3210                tag = FALSE;
3211        else if (sscanf(value, "%x:%x:%x:%x:%x:%x",
3212                        &hwaddr[0], &hwaddr[1], &hwaddr[2],
3213                        &hwaddr[3], &hwaddr[4], &hwaddr[5]) != 6) {
3214                tag = FALSE;
3215        } else
3216                tag = TRUE;
3217#ifdef WDS_DEBUG
3218        if (tag == FALSE)
3219                fprintf(fp, "failed valid_hwaddr\n");
3220#endif
3221
3222        return tag;
3223}
3224
3225char *cpustring(void)
3226{
3227        static char buf[256];
3228#ifdef HAVE_RB600
3229        strcpy(buf, "FreeScale MPC8343");
3230        return buf;
3231#else
3232        FILE *fcpu = fopen("/proc/cpuinfo", "r");
3233
3234        if (fcpu == NULL) {
3235                return NULL;
3236        }
3237        int i;
3238
3239#ifdef HAVE_MAGICBOX
3240        int cnt = 0;
3241#endif
3242#ifdef HAVE_X86
3243        int cnt = 0;
3244#endif
3245        for (i = 0; i < 256; i++) {
3246                int c = getc(fcpu);
3247
3248                if (c == EOF) {
3249                        fclose(fcpu);
3250                        return NULL;
3251                }
3252                if (c == ':')
3253#ifdef HAVE_MAGICBOX
3254                        cnt++;
3255                if (cnt == 2)
3256                        break;
3257#elif HAVE_X86
3258                        cnt++;
3259                if (cnt == 5)
3260                        break;
3261#else
3262                        break;
3263#endif
3264        }
3265        getc(fcpu);
3266        for (i = 0; i < 256; i++) {
3267                int c = getc(fcpu);
3268
3269                if (c == EOF) {
3270                        fclose(fcpu);
3271                        return NULL;
3272                }
3273                if (c == 0xa || c == 0xd)
3274                        break;
3275                buf[i] = c;
3276        }
3277        buf[i] = 0;
3278        fclose(fcpu);
3279        return buf;
3280#endif
3281}
3282
3283#if defined(HAVE_MADWIFI_MIMO) || defined(HAVE_ATH9K)
3284
3285int isap8x(void)
3286{
3287#define CPUSTR "Atheros AR91"
3288        char *str = cpustring();
3289        if (str && !strncmp(str, CPUSTR, 12))
3290                return 1;
3291        else
3292                return 0;
3293#undef CPUSTR
3294
3295}
3296
3297#endif
3298
3299int led_control(int type, int act)
3300/*
3301 * type: LED_POWER, LED_DIAG, LED_DMZ, LED_CONNECTED, LED_BRIDGE, LED_VPN,
3302 * LED_SES, LED_SES2, LED_WLAN0, LED_WLAN1, LED_SEC0, LED_SEC1, USB_POWER
3303 * act: LED_ON, LED_OFF, LED_FLASH
3304 */
3305{
3306#if (defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_MAGICBOX)  || defined(HAVE_RB600) || 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))
3307        return 0;
3308#else
3309        int use_gpio = 0x0ff;
3310        int gpio_value;
3311        int enable;
3312        int disable;
3313
3314        int power_gpio = 0x0ff;
3315        int diag_gpio = 0x0ff;
3316        int dmz_gpio = 0x0ff;
3317        int connected_gpio = 0x0ff;
3318        int disconnected_gpio = 0x0ff;
3319        int bridge_gpio = 0x0ff;
3320        int vpn_gpio = 0x0ff;
3321        int ses_gpio = 0x0ff;   // use for SES1 (Linksys), AOSS (Buffalo)
3322        int ses2_gpio = 0x0ff;
3323        int wlan0_gpio = 0x0ff; // use this only if wlan led is not controlled by hardware!
3324        int wlan1_gpio = 0x0ff; // use this only if wlan led is not controlled by hardware!
3325        int usb_gpio = 0x0ff;
3326        int sec0_gpio = 0x0ff;  // security leds, wrt600n
3327        int sec1_gpio = 0x0ff;
3328        int usb_power = 0x0ff;
3329        int v1func = 0;
3330        int connblue = nvram_match("connblue", "1") ? 1 : 0;
3331
3332        switch (getRouterBrand())       // gpio definitions here: 0xYZ,
3333                // Y=0:normal, Y=1:inverted, Z:gpio
3334                // number (f=disabled)
3335        {
3336#ifndef HAVE_BUFFALO
3337        case ROUTER_BOARD_TECHNAXX3G:
3338                usb_gpio = 0x109;
3339                diag_gpio = 0x10c;
3340                connected_gpio = 0x10b;
3341                ses_gpio = 0x10c;
3342                break;
3343        case ROUTER_BOARD_UNIFI:
3344                diag_gpio = 0x001;
3345                break;
3346        case ROUTER_BOARD_DANUBE:
3347#ifdef HAVE_WMBR_G300NH
3348                diag_gpio = 0x105;
3349                ses_gpio = 0x10e;
3350                sec0_gpio = 0x10e;
3351                connected_gpio = 0x111;
3352                disconnected_gpio = 0x112;
3353                power_gpio = 0x101;
3354#endif
3355#ifdef HAVE_SX763
3356//              diag_gpio = 0x105;
3357//              ses_gpio = 0x10e;
3358//              sec0_gpio = 0x10e;
3359                connected_gpio = 0x1de;
3360//              disconnected_gpio = 0x112;
3361//              power_gpio = 0x101;
3362#endif
3363                break;
3364        case ROUTER_BOARD_PB42:
3365#ifdef HAVE_WR941
3366                diag_gpio = 0x102;
3367                ses_gpio = 0x005;
3368//              usb_gpio = 0x101;
3369#endif
3370#ifdef HAVE_WR741V4
3371                diag_gpio = 0x11b;
3372                ses_gpio = 0x001;
3373                sec0_gpio = 0x001;
3374//              usb_gpio = 0x101;
3375#elif HAVE_WR741
3376                diag_gpio = 0x101;
3377                ses_gpio = 0x000;
3378//              usb_gpio = 0x101;
3379#endif
3380#ifdef HAVE_WR1043
3381                diag_gpio = 0x102;
3382                ses_gpio = 0x005;
3383//              usb_gpio = 0x101;
3384#endif
3385#ifdef HAVE_WRT160NL
3386                power_gpio = 0x10e;
3387                connected_gpio = 0x109;
3388                ses_gpio = 0x108;
3389#endif
3390#ifdef HAVE_TG2521
3391                ses_gpio = 0x103;
3392                diag_gpio = 0x103;
3393                usb_power = 0x105;
3394#endif
3395#ifdef HAVE_TEW632BRP
3396                diag_gpio = 0x101;
3397                ses_gpio = 0x103;
3398#endif
3399#ifdef HAVE_WP543
3400                diag_gpio = 0x107;
3401                connected_gpio = 0x106;
3402#endif
3403#ifdef HAVE_DIR825
3404                power_gpio = 0x102;
3405                diag_gpio = 0x101;
3406                connected_gpio = 0x10b;
3407                disconnected_gpio = 0x106;
3408                ses_gpio = 0x104;
3409#endif
3410#ifdef HAVE_WNDR3700
3411                power_gpio = 0x102;
3412                diag_gpio = 0x101;
3413                connected_gpio = 0x106;
3414                ses_gpio = 0x104;
3415#endif
3416#ifdef HAVE_WZRG300NH
3417                diag_gpio = 0x101;
3418                connected_gpio = 0x112;
3419                ses_gpio = 0x111;
3420                sec0_gpio = 0x111;
3421#endif
3422#ifdef HAVE_DIR632
3423                power_gpio = 0x001;
3424                diag_gpio = 0x100;
3425                connected_gpio = 0x111;
3426                usb_gpio = 0x10b;
3427#endif
3428#ifdef HAVE_WZRG450
3429                diag_gpio = 0x10e;
3430                ses_gpio = 0x10d;
3431                sec0_gpio = 0x10d;
3432                usb_power = 0x010;
3433                connected_gpio = 0x12e; // card 1, gpio 14
3434#endif
3435#ifdef HAVE_WZRG300NH2
3436                diag_gpio = 0x110;
3437                ses_gpio = 0x126;       // card 1, gpio 6
3438                sec0_gpio = 0x126;
3439                usb_power = 0x00d;
3440                connected_gpio = 0x127; // card 1, gpio 7
3441#endif
3442#ifdef HAVE_WZRHPAG300NH
3443                diag_gpio = 0x101;
3444                connected_gpio = 0x133; // card 2 gpio 3
3445                sec0_gpio = 0x125;
3446                sec1_gpio = 0x131;
3447                ses_gpio = 0x125;       // card 1 gpio 5
3448                ses2_gpio = 0x131;      // card 2 gpio 5
3449                usb_power = 0x002;
3450#endif
3451#ifdef HAVE_DIR615E
3452                power_gpio = 0x006;
3453                diag_gpio = 0x001;
3454                connected_gpio = 0x111;
3455                disconnected_gpio = 0x007;
3456                ses_gpio = 0x100;
3457#endif
3458#ifdef HAVE_WRT400
3459                power_gpio = 0x001;
3460                diag_gpio = 0x105;
3461                ses_gpio = 0x104;
3462                connected_gpio = 0x007;
3463#endif
3464#ifdef HAVE_ALFAAP94
3465                power_gpio = 0x005;
3466#endif
3467                break;
3468        case ROUTER_ALLNET01:
3469                connected_gpio = 0x100;
3470                break;
3471        case ROUTER_BOARD_WP54G:
3472                diag_gpio = 0x102;
3473                connected_gpio = 0x107;
3474                break;
3475        case ROUTER_BOARD_NP28G:
3476                diag_gpio = 0x102;
3477                connected_gpio = 0x106;
3478                break;
3479        case ROUTER_BOARD_GATEWORX_GW2369:
3480                connected_gpio = 0x102;
3481                break;
3482        case ROUTER_BOARD_GW2388:
3483        case ROUTER_BOARD_GW2380:
3484                connected_gpio = 0x110; // 16 is mapped to front led
3485                break;
3486        case ROUTER_BOARD_GATEWORX:
3487#ifdef HAVE_WG302V1
3488                diag_gpio = 0x104;
3489                wlan0_gpio = 0x105;
3490#elif HAVE_WG302
3491                diag_gpio = 0x102;
3492                wlan0_gpio = 0x104;
3493#else
3494                if (nvram_match("DD_BOARD", "Gateworks Cambria GW2350")
3495                    || nvram_match("DD_BOARD2", "Gateworks Cambria GW2350"))
3496                        connected_gpio = 0x105;
3497                else if (nvram_match("DD_BOARD", "Gateworks Cambria GW2358-4")
3498                         || nvram_match("DD_BOARD2",
3499                                        "Gateworks Cambria GW2358-4"))
3500                        connected_gpio = 0x118;
3501                else
3502                        connected_gpio = 0x003;
3503#endif
3504                break;
3505        case ROUTER_BOARD_GATEWORX_SWAP:
3506                connected_gpio = 0x004;
3507                break;
3508        case ROUTER_BOARD_STORM:
3509                connected_gpio = 0x005;
3510                diag_gpio = 0x003;
3511                break;
3512        case ROUTER_LINKSYS_WRH54G:
3513                diag_gpio = 0x101;      // power led blink / off to indicate factory
3514                // defaults
3515                break;
3516        case ROUTER_WRT54G:
3517        case ROUTER_WRT54G_V8:
3518                power_gpio = 0x001;
3519                dmz_gpio = 0x107;
3520                connected_gpio = 0x103; // ses orange
3521                ses_gpio = 0x102;       // ses white
3522                ses2_gpio = 0x103;      // ses orange
3523                break;
3524        case ROUTER_WRT54G_V81:
3525                power_gpio = 0x101;
3526                dmz_gpio = 0x102;
3527                connected_gpio = 0x104; // ses orange
3528                ses_gpio = 0x103;       // ses white
3529                ses2_gpio = 0x104;      // ses orange
3530                break;
3531        case ROUTER_WRT54G1X:
3532                connected_gpio = 0x103;
3533                v1func = 1;
3534                break;
3535        case ROUTER_WRT350N:
3536                connected_gpio = 0x103;
3537                power_gpio = 0x001;
3538                ses2_gpio = 0x103;      // ses orange
3539                sec0_gpio = 0x109;
3540                usb_gpio = 0x10b;
3541                break;
3542        case ROUTER_WRT600N:
3543                power_gpio = 0x102;
3544                diag_gpio = 0x002;
3545                usb_gpio = 0x103;
3546                sec0_gpio = 0x109;
3547                sec1_gpio = 0x10b;
3548                break;
3549        case ROUTER_LINKSYS_WRT55AG:
3550                connected_gpio = 0x103;
3551                break;
3552        case ROUTER_DLINK_DIR330:
3553                diag_gpio = 0x106;
3554                connected_gpio = 0x100;
3555                usb_gpio = 0x104;
3556                break;
3557        case ROUTER_ASUS_RTN10PLUS:
3558//              diag_gpio = 0x10d;
3559//              connected_gpio = 0x108;
3560//              power_gpio = 0x109;
3561                break;
3562        case ROUTER_BOARD_DIR600B:
3563                diag_gpio = 0x10d;
3564                connected_gpio = 0x108;
3565                power_gpio = 0x109;
3566                break;
3567        case ROUTER_BOARD_DIR615D:
3568                diag_gpio = 0x108;
3569                connected_gpio = 0x10c;
3570                disconnected_gpio = 0x10e;
3571                ses_gpio = 0x10b;
3572                power_gpio = 0x109;
3573                break;
3574        case ROUTER_BOARD_W502U:
3575                connected_gpio = 0x10d;
3576                break;
3577        case ROUTER_BOARD_OPENRISC:
3578#ifndef HAVE_ERC
3579// ERC: diag button is used different / wlan button is handled by a script
3580                diag_gpio = 0x003;
3581                ses_gpio = 0x005;
3582#endif
3583                break;
3584        case ROUTER_BOARD_WR5422:
3585                ses_gpio = 0x10d;
3586                break;
3587        case ROUTER_BOARD_F5D8235:
3588                usb_gpio = 0x117;
3589                diag_gpio = 0x109;
3590                disconnected_gpio = 0x106;
3591                connected_gpio = 0x105;
3592                ses_gpio = 0x10c;
3593                break;
3594#else
3595        case ROUTER_BOARD_DANUBE:
3596#ifdef HAVE_WMBR_G300NH
3597                diag_gpio = 0x105;
3598                ses_gpio = 0x10e;
3599                sec0_gpio = 0x10e;
3600                connected_gpio = 0x111;
3601                disconnected_gpio = 0x112;
3602                power_gpio = 0x101;
3603#endif
3604                break;
3605        case ROUTER_BOARD_PB42:
3606#ifdef HAVE_WZRG300NH
3607                diag_gpio = 0x101;
3608                connected_gpio = 0x112;
3609                ses_gpio = 0x111;
3610                sec0_gpio = 0x111;
3611#endif
3612#ifdef HAVE_WZRHPAG300NH
3613                diag_gpio = 0x101;
3614                connected_gpio = 0x133;
3615                ses_gpio = 0x125;
3616                ses2_gpio = 0x131;
3617                sec0_gpio = 0x125;
3618                sec1_gpio = 0x131;
3619                usb_power = 0x002;
3620#endif
3621#ifdef HAVE_WZRG450
3622                diag_gpio = 0x10e;
3623                ses_gpio = 0x10d;
3624                sec0_gpio = 0x10d;
3625                usb_power = 0x010;
3626                connected_gpio = 0x12e; // card 1, gpio 14
3627#endif
3628#ifdef HAVE_WZRG300NH2
3629                diag_gpio = 0x110;
3630                ses_gpio = 0x126;
3631                sec0_gpio = 0x126;
3632                usb_power = 0x00d;
3633                connected_gpio = 0x127;
3634#endif
3635                break;
3636#endif
3637        case ROUTER_BOARD_WCRGN:
3638                diag_gpio = 0x107;
3639                connected_gpio = 0x10b;
3640//              ses_gpio = 0x10e;
3641                break;
3642        case ROUTER_BOARD_WHRG300N:
3643                diag_gpio = 0x107;
3644                connected_gpio = 0x109;
3645                ses_gpio = 0x10e;
3646                break;
3647#ifdef HAVE_WNR2200
3648        case ROUTER_BOARD_WHRHPGN:
3649                power_gpio = 0x122;
3650                diag_gpio = 0x121;
3651                connected_gpio = 0x107;
3652                usb_power = 0x024;      // enable usb port
3653//              ses_gpio = 0x104;
3654//              sec0_gpio = 0x104;
3655                break;
3656#elif HAVE_WNR2000
3657        case ROUTER_BOARD_WHRHPGN:
3658                power_gpio = 0x123;
3659                diag_gpio = 0x122;
3660                connected_gpio = 0x100;
3661//              ses_gpio = 0x104;
3662//              sec0_gpio = 0x104;
3663                break;
3664#elif HAVE_WLAEAG300N
3665        case ROUTER_BOARD_WHRHPGN:
3666                power_gpio = 0x110;
3667                diag_gpio = 0x111;
3668                connected_gpio = 0x106;
3669                ses_gpio = 0x10e;
3670                sec0_gpio = 0x10e;
3671                break;
3672#elif HAVE_HORNET
3673        case ROUTER_BOARD_WHRHPGN:
3674                usb_power = 0x01a;
3675                usb_gpio = 0x001;
3676                ses_gpio = 0x11b;
3677                break;
3678#elif HAVE_WASP
3679        case ROUTER_BOARD_WHRHPGN:
3680//              usb_power = 0x01a;
3681//              usb_gpio = 0x001;
3682//              ses_gpio = 0x11b;
3683                break;
3684#else
3685        case ROUTER_BOARD_WHRHPGN:
3686                diag_gpio = 0x101;
3687                connected_gpio = 0x106;
3688                ses_gpio = 0x100;
3689                sec0_gpio = 0x100;
3690                break;
3691#endif
3692        case ROUTER_BUFFALO_WBR54G:
3693                diag_gpio = 0x107;
3694                break;
3695        case ROUTER_BUFFALO_WBR2G54S:
3696                diag_gpio = 0x001;
3697                ses_gpio = 0x006;
3698                break;
3699        case ROUTER_BUFFALO_WLA2G54C:
3700                diag_gpio = 0x104;
3701                ses_gpio = 0x103;
3702                break;
3703        case ROUTER_BUFFALO_WLAH_G54:
3704                diag_gpio = 0x107;
3705                ses_gpio = 0x106;
3706                break;
3707        case ROUTER_BUFFALO_WAPM_HP_AM54G54:
3708                diag_gpio = 0x107;
3709                ses_gpio = 0x101;
3710                break;
3711        case ROUTER_BOARD_WHRAG108:
3712                diag_gpio = 0x107;
3713                bridge_gpio = 0x104;
3714                ses_gpio = 0x100;
3715                break;
3716        case ROUTER_BUFFALO_WHRG54S:
3717        case ROUTER_BUFFALO_WLI_TX4_G54HP:
3718                diag_gpio = 0x107;
3719                if (nvram_match("DD_BOARD", "Buffalo WHR-G125")) {
3720                        connected_gpio = 0x101;
3721                        sec0_gpio = 0x106;
3722                } else {
3723                        bridge_gpio = 0x101;
3724                        ses_gpio = 0x106;
3725                }
3726                break;
3727        case ROUTER_BUFFALO_WZRRSG54:
3728                diag_gpio = 0x107;
3729                vpn_gpio = 0x101;
3730                ses_gpio = 0x106;
3731                break;
3732        case ROUTER_BUFFALO_WZRG300N:
3733                diag_gpio = 0x107;
3734                bridge_gpio = 0x101;
3735                break;
3736        case ROUTER_BUFFALO_WZRG144NH:
3737                diag_gpio = 0x103;
3738                bridge_gpio = 0x101;
3739                ses_gpio = 0x102;
3740                break;
3741#ifndef HAVE_BUFFALO
3742#ifdef HAVE_DIR300
3743        case ROUTER_BOARD_FONERA:
3744                diag_gpio = 0x003;
3745                bridge_gpio = 0x004;
3746                ses_gpio = 0x001;
3747                break;
3748#endif
3749#ifdef HAVE_WRT54G2
3750        case ROUTER_BOARD_FONERA:
3751                bridge_gpio = 0x004;
3752                ses_gpio = 0x104;
3753                diag_gpio = 0x103;
3754                break;
3755#endif
3756#ifdef HAVE_RTG32
3757        case ROUTER_BOARD_FONERA:
3758                break;
3759#endif
3760#ifdef HAVE_BWRG1000
3761        case ROUTER_BOARD_LS2:
3762                diag_gpio = 0x007;
3763                break;
3764#endif
3765#ifdef HAVE_DIR400
3766        case ROUTER_BOARD_FONERA2200:
3767                diag_gpio = 0x003;
3768                bridge_gpio = 0x004;
3769                ses_gpio = 0x001;
3770                break;
3771#endif
3772#ifdef HAVE_WRK54G
3773        case ROUTER_BOARD_FONERA:
3774                diag_gpio = 0x107;
3775                dmz_gpio = 0x005;
3776                break;
3777#endif
3778        case ROUTER_BOARD_TW6600:
3779                diag_gpio = 0x107;
3780                bridge_gpio = 0x104;
3781                ses_gpio = 0x100;
3782                break;
3783        case ROUTER_MOTOROLA:
3784                power_gpio = 0x001;
3785                diag_gpio = 0x101;      // power led blink / off to indicate factory
3786                // defaults
3787                break;
3788        case ROUTER_RT210W:
3789                power_gpio = 0x105;
3790                diag_gpio = 0x005;      // power led blink / off to indicate factory
3791                // defaults
3792                connected_gpio = 0x100;
3793                wlan0_gpio = 0x103;
3794                break;
3795        case ROUTER_RT480W:
3796        case ROUTER_BELKIN_F5D7230_V2000:
3797        case ROUTER_BELKIN_F5D7231:
3798                power_gpio = 0x105;
3799                diag_gpio = 0x005;      // power led blink / off to indicate factory
3800                // defaults
3801                connected_gpio = 0x100;
3802                break;
3803        case ROUTER_MICROSOFT_MN700:
3804                power_gpio = 0x006;
3805                diag_gpio = 0x106;      // power led blink / off to indicate factory
3806                // defaults
3807                break;
3808        case ROUTER_ASUS_WL500GD:
3809        case ROUTER_ASUS_WL520GUGC:
3810                diag_gpio = 0x000;      // power led blink / off to indicate factory
3811                // defaults
3812                break;
3813        case ROUTER_ASUS_WL500G_PRE:
3814        case ROUTER_ASUS_WL700GE:
3815                power_gpio = 0x101;
3816                diag_gpio = 0x001;      // power led blink / off to indicate factory
3817                // defaults
3818                break;
3819        case ROUTER_ASUS_WL550GE:
3820                power_gpio = 0x102;
3821                diag_gpio = 0x002;      // power led blink / off to indicate factory
3822                // defaults
3823                break;
3824        case ROUTER_WRT54G3G:
3825        case ROUTER_WRTSL54GS:
3826                power_gpio = 0x001;
3827                dmz_gpio = 0x100;
3828                connected_gpio = 0x107; // ses orange
3829                ses_gpio = 0x105;       // ses white
3830                ses2_gpio = 0x107;      // ses orange
3831                break;
3832        case ROUTER_MOTOROLA_WE800G:
3833        case ROUTER_MOTOROLA_V1:
3834                diag_gpio = 0x103;
3835                wlan0_gpio = 0x101;
3836                bridge_gpio = 0x105;
3837                break;
3838        case ROUTER_DELL_TRUEMOBILE_2300:
3839        case ROUTER_DELL_TRUEMOBILE_2300_V2:
3840                power_gpio = 0x107;
3841                diag_gpio = 0x007;      // power led blink / off to indicate factory
3842                // defaults
3843                wlan0_gpio = 0x106;
3844                break;
3845        case ROUTER_NETGEAR_WNR834B:
3846                power_gpio = 0x104;
3847                diag_gpio = 0x105;
3848                wlan0_gpio = 0x106;
3849                break;
3850        case ROUTER_SITECOM_WL105B:
3851                power_gpio = 0x003;
3852                diag_gpio = 0x103;      // power led blink / off to indicate factory
3853                // defaults
3854                wlan0_gpio = 0x104;
3855                break;
3856        case ROUTER_WRT300N:
3857                power_gpio = 0x001;
3858                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
3859                break;
3860        case ROUTER_WRT150N:
3861                power_gpio = 0x001;
3862                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
3863                sec0_gpio = 0x105;
3864                break;
3865        case ROUTER_WRT300NV11:
3866                ses_gpio = 0x105;
3867                // diag_gpio = 0x11; //power led blink / off to indicate fac.def.
3868                break;
3869        case ROUTER_WRT310N:
3870                connected_gpio = 0x103; //ses orange
3871                power_gpio = 0x001;
3872                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
3873                ses_gpio = 0x109;       // ses blue
3874                break;
3875        case ROUTER_WRT310NV2:
3876                connected_gpio = 0x102; // ses orange
3877                power_gpio = 0x001;
3878                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
3879                ses_gpio = 0x104;       // ses blue
3880                break;
3881        case ROUTER_WRT160N:
3882                power_gpio = 0x001;
3883                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
3884                connected_gpio = 0x103; // ses orange
3885                ses_gpio = 0x105;       // ses blue
3886                break;
3887        case ROUTER_WRT160NV3:
3888                power_gpio = 0x001;
3889                diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
3890                connected_gpio = 0x102; // ses orange
3891                ses_gpio = 0x104;       // ses blue
3892                break;
3893        case ROUTER_LINKSYS_E1000V2:
3894                power_gpio = 0x106;
3895                diag_gpio = 0x006;      // power led blink / off to indicate fac.def.
3896                connected_gpio = 0x007; // ses orange
3897                ses_gpio = 0x008;       // ses blue
3898                break;
3899        case ROUTER_LINKSYS_E2500:
3900                power_gpio = 0x103;
3901                diag_gpio = 0x003;
3902                break;
3903        case ROUTER_LINKSYS_E3200:
3904                power_gpio = 0x103;
3905                diag_gpio = 0x003;      // power led blink / off to indicate fac.def.
3906                break;
3907        case ROUTER_LINKSYS_E4200:
3908                power_gpio = 0x105;     // white LED1
3909                diag_gpio = 0x005;      // power led blink / off to indicate fac.def.
3910                connected_gpio = 0x103; // white LED2
3911                break;
3912        case ROUTER_ASUS_WL500G:
3913                power_gpio = 0x100;
3914                diag_gpio = 0x000;      // power led blink /off to indicate factory
3915                // defaults
3916                break;
3917        case ROUTER_ASUS_WL500W:
3918                power_gpio = 0x105;
3919                diag_gpio = 0x005;      // power led blink /off to indicate factory
3920                // defaults
3921                break;
3922        case ROUTER_LINKSYS_WTR54GS:
3923                diag_gpio = 0x001;
3924                break;
3925        case ROUTER_WAP54G_V1:
3926                diag_gpio = 0x103;
3927                wlan0_gpio = 0x104;     // LINK led
3928                break;
3929        case ROUTER_WAP54G_V3:
3930                ses_gpio = 0x10c;
3931                connected_gpio = 0x006;
3932                break;
3933        case ROUTER_NETGEAR_WNR834BV2:
3934                power_gpio = 0x002;
3935                diag_gpio = 0x003;      // power led amber
3936                connected_gpio = 0x007; // WAN led green
3937                break;
3938        case ROUTER_NETGEAR_WNDR3300:
3939                power_gpio = 0x005;
3940                diag_gpio = 0x105;      // power led blink /off to indicate factory defaults
3941                connected_gpio = 0x007; // WAN led green
3942                break;
3943        case ROUTER_ASKEY_RT220XD:
3944                wlan0_gpio = 0x100;
3945                dmz_gpio = 0x101;       // not soldered
3946                break;
3947        case ROUTER_WRT610N:
3948                power_gpio = 0x001;
3949                connected_gpio = 0x103; // ses amber
3950                ses_gpio = 0x109;       // ses blue
3951                usb_gpio = 0x100;
3952                break;
3953        case ROUTER_WRT610NV2:
3954                power_gpio = 0x005;
3955                connected_gpio = 0x100; // ses amber
3956                ses_gpio = 0x103;       // ses blue
3957                usb_gpio = 0x007;
3958                break;
3959        case ROUTER_USR_5461:
3960                usb_gpio = 0x001;
3961                break;
3962        case ROUTER_USR_5465:
3963                //usb_gpio = 0x002; //or 0x001 ??
3964                break;
3965        case ROUTER_NETGEAR_WGR614L:
3966        case ROUTER_NETGEAR_WGR614V9:
3967                // power_gpio = 0x107;       // don't use - resets router
3968                diag_gpio = 0x006;
3969                connected_gpio = 0x104;
3970                break;
3971        case ROUTER_NETGEAR_WG602_V4:
3972                power_gpio = 0x101;     // trick: make lan led green for 100Mbps
3973                break;
3974        case ROUTER_BELKIN_F5D7231_V2000:
3975                connected_gpio = 0x104;
3976                diag_gpio = 0x001;      // power led blink /off to indicate factory defaults
3977                break;
3978        case ROUTER_NETGEAR_WNR3500L:
3979                power_gpio = 0x003;     //power led green
3980                diag_gpio = 0x007;      // power led amber
3981                ses_gpio = 0x001;       // WPS led green
3982                connected_gpio = 0x002; //wan led green
3983                break;
3984        case ROUTER_NETGEAR_WNDR3400:
3985                power_gpio = 0x003;     //power led green
3986                diag_gpio = 0x007;      // power led amber
3987                connected_gpio = 0x001; //wan led green
3988                usb_gpio = 0x102;       //usb led green
3989                wlan1_gpio = 0x000;     // radio 1 led blue
3990                break;
3991        case ROUTER_NETGEAR_WNDR4000:
3992                power_gpio = 0x000;     //power led green
3993                diag_gpio = 0x001;      // power led amber
3994                connected_gpio = 0x002; //wan led green
3995                wlan0_gpio = 0x003;     //radio 0 led green
3996                wlan1_gpio = 0x004;     // radio 1 led blue
3997                usb_gpio = 0x005;       //usb led green
3998                ses_gpio = 0x106;       // WPS led green - inverse
3999                ses2_gpio = 0x107;      // WLAN led green - inverse
4000                break;
4001        case ROUTER_NETGEAR_WNR2000V2:
4002                //power_gpio = ??;
4003                diag_gpio = 0x002;
4004                ses_gpio = 0x007;       //WPS led
4005                connected_gpio = 0x006;
4006                break;
4007        case ROUTER_WRT320N:
4008                power_gpio = 0x002;     //power/diag (disabled=blink)
4009                ses_gpio = 0x103;       // ses blue
4010                connected_gpio = 0x104; //ses orange
4011                break;
4012        case ROUTER_ASUS_RTN12:
4013                power_gpio = 0x102;
4014                diag_gpio = 0x002;      // power blink
4015                break;
4016        case ROUTER_BOARD_NEPTUNE:
4017//              usb_gpio = 0x108;
4018                // 0x10c //unknown gpio label, use as diag
4019                diag_gpio = 0x10c;
4020                break;
4021        case ROUTER_ASUS_RTN10U:
4022                ses_gpio = 0x007;
4023                usb_gpio = 0x008;
4024                break;
4025        case ROUTER_ASUS_RTN12B:
4026                connected_gpio = 0x105;
4027                break;
4028        case ROUTER_ASUS_RTN10:
4029        case ROUTER_ASUS_RTN16:
4030        case ROUTER_NETCORE_NW618:
4031                power_gpio = 0x101;
4032                diag_gpio = 0x001;      // power blink
4033                break;
4034        case ROUTER_BELKIN_F7D3301:
4035        case ROUTER_BELKIN_F7D3302:
4036        case ROUTER_BELKIN_F7D4301:
4037        case ROUTER_BELKIN_F7D4302:
4038                power_gpio = 0x10a;     // green
4039                diag_gpio = 0x10b;      // red
4040                ses_gpio = 0x10d;       // wps orange
4041                break;
4042        case ROUTER_DYNEX_DX_NRUTER:
4043                power_gpio = 0x001;
4044                diag_gpio = 0x101;      // power blink
4045                connected_gpio = 0x100;
4046                sec0_gpio = 0x103;
4047                break;
4048#endif
4049        }
4050        if (type == LED_DIAG && v1func == 1) {
4051                if (act == LED_ON)
4052                        C_led(1);
4053                else
4054                        C_led(0);
4055        }
4056
4057        switch (type) {
4058        case LED_POWER:
4059                use_gpio = power_gpio;
4060                break;
4061        case USB_POWER:
4062                use_gpio = usb_power;
4063                break;
4064        case LED_DIAG:
4065                use_gpio = diag_gpio;
4066                break;
4067        case LED_DMZ:
4068                use_gpio = dmz_gpio;
4069                break;
4070        case LED_CONNECTED:
4071                if (act == LED_ON)
4072                        led_control(LED_DISCONNECTED, LED_OFF);
4073                else
4074                        led_control(LED_DISCONNECTED, LED_ON);
4075                use_gpio = connblue ? ses_gpio : connected_gpio;
4076                break;
4077        case LED_DISCONNECTED:
4078                use_gpio = disconnected_gpio;
4079                break;
4080        case LED_BRIDGE:
4081                use_gpio = bridge_gpio;
4082                break;
4083        case LED_VPN:
4084                use_gpio = vpn_gpio;
4085                break;
4086        case LED_SES:
4087                use_gpio = connblue ? connected_gpio : ses_gpio;
4088                break;
4089        case LED_SES2:
4090                use_gpio = ses2_gpio;
4091                break;
4092        case LED_WLAN0:
4093                use_gpio = wlan0_gpio;
4094                break;
4095        case LED_WLAN1:
4096                use_gpio = wlan1_gpio;
4097                break;
4098        case LED_USB:
4099                use_gpio = usb_gpio;
4100                break;
4101        case LED_SEC0:
4102                use_gpio = sec0_gpio;
4103                break;
4104        case LED_SEC1:
4105                use_gpio = sec1_gpio;
4106                break;
4107        }
4108        if ((use_gpio & 0x0ff) != 0x0ff) {
4109                gpio_value = use_gpio & 0x0ff;
4110                enable = (use_gpio & 0x100) == 0 ? 1 : 0;
4111                disable = (use_gpio & 0x100) == 0 ? 0 : 1;
4112                switch (act) {
4113                case LED_ON:
4114                        set_gpio(gpio_value, enable);
4115                        break;
4116                case LED_OFF:
4117                        set_gpio(gpio_value, disable);
4118                        break;
4119                case LED_FLASH: // will lit the led for 1 sec.
4120                        set_gpio(gpio_value, enable);
4121                        sleep(1);
4122                        set_gpio(gpio_value, disable);
4123                        break;
4124                }
4125        }
4126        return 1;
4127
4128#endif
4129}
4130
4131int file_to_buf(char *path, char *buf, int len)
4132{
4133        FILE *fp;
4134
4135        memset(buf, 0, len);
4136
4137        if ((fp = fopen(path, "r"))) {
4138                fgets(buf, len, fp);
4139                fclose(fp);
4140                return 1;
4141        }
4142
4143        return 0;
4144}
4145
4146int ishexit(char c)
4147{
4148
4149        if (strchr("01234567890abcdefABCDEF", c) != (char *)0)
4150                return 1;
4151
4152        return 0;
4153}
4154
4155int getMTD(char *name)
4156{
4157        char buf[128];
4158        int device;
4159
4160        sprintf(buf, "cat /proc/mtd|grep \"%s\"", name);
4161        FILE *fp = popen(buf, "rb");
4162
4163        fscanf(fp, "%s", &buf[0]);
4164        device = buf[3] - '0';
4165        pclose(fp);
4166        return device;
4167}
4168
4169int insmod(char *module)
4170{
4171        return eval("insmod", module);
4172}
4173
4174void rmmod(char *module)
4175{
4176        eval("rmmod", module);
4177}
4178
4179#include "revision.h"
4180
4181char *getSoftwareRevision(void)
4182{
4183        return "" SVN_REVISION "";
4184}
4185
4186#ifdef HAVE_OLED
4187void initlcd()
4188{
4189
4190}
4191
4192void lcdmessage(char *message)
4193{
4194        eval("oled-print", "DD-WRT v24 sp2", "build:" SVN_REVISION,
4195             "3G/UMTS Router", message);
4196}
4197
4198void lcdmessaged(char *dual, char *message)
4199{
4200
4201}
4202
4203#endif
4204
4205#if 0
4206
4207static int fd;
4208
4209void SetEnvironment()
4210{
4211        system("stty ispeed 2400 < /dev/tts/1");
4212        system("stty raw < /dev/tts/1");
4213}
4214
4215int Cmd = 254;                  /* EZIO Command */
4216int cls = 1;                    /* Clear screen */
4217void Cls()
4218{
4219        write(fd, &Cmd, 1);
4220        write(fd, &cls, 1);
4221}
4222
4223int init = 0x28;
4224void Init()
4225{
4226        write(fd, &Cmd, 1);
4227        write(fd, &init, 1);
4228}
4229
4230int stopsend = 0x37;
4231void StopSend()
4232{
4233        write(fd, &Cmd, 1);
4234        write(fd, &init, 1);
4235}
4236
4237int home = 2;                   /* Home cursor */
4238void Home()
4239{
4240        write(fd, &Cmd, 1);
4241        write(fd, &home, 1);
4242}
4243
4244int readkey = 6;                /* Read key */
4245void ReadKey()
4246{
4247        write(fd, &Cmd, 1);
4248        write(fd, &readkey, 1);
4249}
4250
4251int blank = 8;                  /* Blank display */
4252void Blank()
4253{
4254        write(fd, &Cmd, 1);
4255        write(fd, &blank, 1);
4256}
4257
4258int hide = 12;                  /* Hide cursor & display blanked characters */
4259void Hide()
4260{
4261        write(fd, &Cmd, 1);
4262        write(fd, &hide, 1);
4263}
4264
4265int turn = 13;                  /* Turn On (blinking block cursor) */
4266void TurnOn()
4267{
4268        write(fd, &Cmd, 1);
4269        write(fd, &turn, 1);
4270}
4271
4272int show = 14;                  /* Show underline cursor */
4273void Show()
4274{
4275        write(fd, &Cmd, 1);
4276        write(fd, &show, 1);
4277}
4278
4279int movel = 16;                 /* Move cursor 1 character left */
4280void MoveL()
4281{
4282        write(fd, &Cmd, 1);
4283        write(fd, &movel, 1);
4284}
4285
4286int mover = 20;                 /* Move cursor 1 character right */
4287void MoveR()
4288{
4289        write(fd, &Cmd, 1);
4290        write(fd, &mover, 1);
4291}
4292
4293int scl = 24;                   /* Scroll cursor 1 character left */
4294void ScrollL()
4295{
4296        write(fd, &Cmd, 1);
4297        write(fd, &scl, 1);
4298}
4299
4300int scr = 28;                   /* Scroll cursor 1 character right */
4301void ScrollR()
4302{
4303        write(fd, &Cmd, 1);
4304        write(fd, &scr, 1);
4305}
4306
4307int setdis = 64;                /* Command */
4308void SetDis()
4309{
4310        write(fd, &Cmd, 1);
4311        write(fd, &setdis, 1);
4312
4313}
4314
4315int a, b;
4316void ShowMessage(char *str1, char *str2)
4317{
4318        char nul[] = "                                       ";
4319
4320        a = strlen(str1);
4321        b = 40 - a;
4322        write(fd, str1, a);
4323        write(fd, nul, b);
4324        write(fd, str2, strlen(str2));
4325}
4326
4327void initlcd()
4328{
4329
4330        fd = open("/dev/tts/1", O_RDWR);
4331
4332                                  /** Open Serial port (COM2) */
4333        if (fd > 0) {
4334                close(fd);
4335                SetEnvironment();       /* Set RAW mode */
4336                fd = open("/dev/tts/1", O_RDWR);
4337                Init();         /* Initialize EZIO twice */
4338                Init();
4339
4340                Cls();          /* Clear screen */
4341        }
4342        close(fd);
4343}
4344
4345void lcdmessage(char *message)
4346{
4347
4348        fd = open("/dev/tts/1", O_RDWR);
4349                                   /** Open Serial port (COM2) */
4350
4351        if (fd > 0) {
4352                Init();         /* Initialize EZIO twice */
4353                Init();
4354                SetDis();
4355                Cls();
4356                Home();
4357                ShowMessage("State", message);
4358                close(fd);
4359        }
4360}
4361
4362void lcdmessaged(char *dual, char *message)
4363{
4364
4365        fd = open("/dev/tts/1", O_RDWR);
4366
4367                                  /** Open Serial port (COM2) */
4368
4369        if (fd > 0) {
4370                Init();         /* Initialize EZIO twice */
4371                Init();
4372                SetDis();
4373                Cls();          /* Clear screen */
4374                Home();
4375                ShowMessage(dual, message);
4376                close(fd);
4377        }
4378}
4379
4380#endif
4381static int i64c(int i)
4382{
4383        i &= 0x3f;
4384        if (i == 0)
4385                return '.';
4386        if (i == 1)
4387                return '/';
4388        if (i < 12)
4389                return ('0' - 2 + i);
4390        if (i < 38)
4391                return ('A' - 12 + i);
4392        return ('a' - 38 + i);
4393}
4394
4395int crypt_make_salt(char *p, int cnt, int x)
4396{
4397        x += getpid() + time(NULL);
4398        do {
4399                /*
4400                 * x = (x*1664525 + 1013904223) % 2^32 generator is lame (low-order
4401                 * bit is not "random", etc...), but for our purposes it is good
4402                 * enough
4403                 */
4404                x = x * 1664525 + 1013904223;
4405                /*
4406                 * BTW, Park and Miller's "minimal standard generator" is x = x*16807
4407                 * % ((2^31)-1) It has no problem with visibly alternating lowest bit
4408                 * but is also weak in cryptographic sense + needs div, which needs
4409                 * more code (and slower) on many CPUs
4410                 */
4411                *p++ = i64c(x >> 16);
4412                *p++ = i64c(x >> 22);
4413        }
4414        while (--cnt);
4415        *p = '\0';
4416        return x;
4417}
4418
4419#include <crypt.h>
4420#define MD5_OUT_BUFSIZE 36
4421
4422char *zencrypt(char *passwd)
4423{
4424        char salt[sizeof("$N$XXXXXXXX")];       /* "$N$XXXXXXXX" or "XX" */
4425        static char passout[MD5_OUT_BUFSIZE];
4426
4427        strcpy(salt, "$1$");
4428        crypt_make_salt(salt + 3, 4, 0);
4429        strcpy(passout, crypt((unsigned char *)passwd, (unsigned char *)salt));
4430        return passout;
4431}
4432
4433int has_gateway(void)
4434{
4435        if (nvram_match("wk_mode", "gateway"))
4436                return 1;
4437        if (nvram_match("wk_mode", "olsr") && nvram_match("olsrd_gateway", "1"))
4438                return 1;
4439        return 0;
4440}
4441
4442#ifdef HAVE_ATH9K
4443int getath9kdevicecount(void)
4444{
4445        glob_t globbuf;
4446        int globresult;
4447        int count = 0;
4448#ifndef HAVE_MADWIFI_MIMO
4449        if (1) {
4450#else
4451        if (nvram_match("mimo_driver", "ath9k")) {
4452#endif
4453                globresult =
4454                    glob("/sys/class/ieee80211/phy*", GLOB_NOSORT, NULL,
4455                         &globbuf);
4456                if (globresult == 0)
4457                        count = (int)globbuf.gl_pathc;
4458                globfree(&globbuf);
4459        }
4460        return (count);
4461}
4462
4463int get_ath9k_phy_idx(int idx)
4464{
4465        // fprintf(stderr,"channel number %d of %d\n", i,achans.ic_nchans);
4466        return idx - getifcount("wifi");
4467}
4468
4469int is_ath9k(const char *prefix)
4470{
4471        glob_t globbuf;
4472        int count = 0;
4473        char globstring[1024];
4474        int globresult;
4475        int devnum;
4476        // get legacy interface count
4477#ifdef HAVE_MADWIFI_MIMO
4478        if (!nvram_match("mimo_driver", "ath9k"))
4479                return (0);
4480#endif
4481        if (!sscanf(prefix, "ath%d", &devnum))
4482                return (0);
4483        // correct index if there are legacy cards arround
4484        devnum = get_ath9k_phy_idx(devnum);
4485        sprintf(globstring, "/sys/class/ieee80211/phy%d", devnum);
4486        globresult = glob(globstring, GLOB_NOSORT, NULL, &globbuf);
4487        if (globresult == 0)
4488                count = (int)globbuf.gl_pathc;
4489        globfree(&globbuf);
4490        return (count);
4491}
4492#endif
4493
4494double HTTxRate20_800(unsigned int index)
4495{
4496        static const double vHTTxRate20_800[24] =
4497            { 6.5, 13.0, 19.5, 26.0, 39.0, 52.0, 58.5, 65.0, 13.0, 26.0, 39.0,
4498                52.0, 78.0, 104.0, 117.0, 130.0,
4499                19.5, 39.0, 58.5, 78.0, 117.0, 156.0, 175.5, 195.0
4500        };
4501        if (index > sizeof(HTTxRate20_800) / sizeof(double) - 1) {
4502                fprintf(stderr, "utils.c HTTxRate20_800() index overflow\n");
4503                return 0.0;
4504        }
4505        return vHTTxRate20_800[index];
4506}
4507
4508double HTTxRate20_400(unsigned int index)
4509{
4510        static const double vHTTxRate20_400[24] =
4511            { 7.2, 14.4, 21.7, 28.9, 43.3, 57.8, 65.0, 72.2, 14.444, 28.889,
4512                43.333, 57.778, 86.667, 115.556, 130.000, 144.444,
4513                21.7, 43.3, 65.0, 86.7, 130.0, 173.3, 195.0, 216.7
4514        };
4515        if (index > sizeof(vHTTxRate20_400) / sizeof(double) - 1) {
4516                fprintf(stderr, "utils.c HTTxRate20_400() index overflow\n");
4517                return 0.0;
4518        }
4519        return vHTTxRate20_400[index];
4520}
4521
4522double HTTxRate40_800(unsigned int index)
4523{
4524        static const double vHTTxRate40_800[25] =
4525            { 13.5, 27.0, 40.5, 54.0, 81.0, 108.0, 121.5, 135.0, 27.0, 54.0,
4526                81.0, 108.0, 162.0, 216.0, 243.0, 270.0,
4527                40.5, 81.0, 121.5, 162.0, 243.0, 324.0, 364.5, 405.0, 6.0
4528        };
4529        if (index > sizeof(vHTTxRate40_800) / sizeof(double) - 1) {
4530                fprintf(stderr, "utils.c HTTxRate40_800() index overflow\n");
4531                return 0.0;
4532        }
4533        return vHTTxRate40_800[index];
4534}
4535
4536double HTTxRate40_400(unsigned int index)
4537{
4538        static const double vHTTxRate40_400[25] =
4539            { 15.0, 30.0, 45.0, 60.0, 90.0, 120.0, 135.0, 150.0, 30.0, 60.0,
4540                90.0, 120.0, 180.0, 240.0, 270.0, 300.0,
4541                45.0, 90.0, 135.0, 180.0, 270.0, 360.0, 405.0, 450.0, 6.7
4542        };
4543        if (index > sizeof(vHTTxRate40_400) / sizeof(double) - 1) {
4544                fprintf(stderr, "utils.c HTTxRate40_400() index overflow\n");
4545                return 0.0;
4546        }
4547        return vHTTxRate40_400[index];
4548}
4549
4550
4551int writeproc(char *path,char *value)
4552{
4553        FILE *fp;
4554        fp = fopen(path,"wb");
4555        if (fp==NULL) {
4556                return -1;
4557        }
4558        fprintf(fp,value);
4559        fclose(fp);
4560        return 0;   
4561}
4562
4563int writevaproc(char *value, char *fmt,...)
4564{
4565        char varbuf[256];
4566        va_list args;
4567
4568        va_start(args, (char *)fmt);
4569        vsnprintf(varbuf, sizeof(varbuf), fmt, args);
4570        va_end(args);
4571        return writeproc(varbuf,value);;
4572
4573}
4574/* gartarp */
4575
4576struct arph {
4577        uint16_t hw_type;
4578
4579#define ARPHDR_ETHER    1
4580
4581        uint16_t proto_type;
4582
4583        char ha_len;
4584        char pa_len;
4585
4586#define ARPOP_BROADCAST 1
4587#define ARPOP_REPLY     2
4588        uint16_t opcode;
4589        char source_add[ETH_ALEN];
4590        char source_ip[IP_ALEN];
4591        char dest_add[ETH_ALEN];
4592        char dest_ip[IP_ALEN];
4593
4594} __attribute__((packed));
4595
4596#define ARP_HLEN        sizeof(struct arph) + ETH_HLEN
4597#define BCAST           "\xff\xff\xff\xff\xff\xff"
4598
4599static inline int get_iface_attr(int sk, char *iface, char *hw, char *paddr)
4600{
4601        int ret;
4602        struct ifreq ifr;
4603
4604        strcpy(ifr.ifr_name, iface);
4605
4606        ret = ioctl(sk, SIOCGIFHWADDR, &ifr);
4607        if (unlikely(ret == -1)) {
4608                perror("ioctl SIOCGIFHWADDR");
4609                return ret;
4610        }
4611        memcpy(hw, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
4612
4613        ret = ioctl(sk, SIOCGIFADDR, &ifr);
4614        if (unlikely(ret == -1)) {
4615                perror("ioctl SIOCGIFADDR");
4616                return ret;
4617        }
4618        memcpy(paddr, ifr.ifr_addr.sa_data + 2, IP_ALEN);
4619
4620        return ret;
4621}
4622
4623static inline void setup_eth(struct ether_header *eth, char *hw_addr)
4624{
4625        memcpy(eth->ether_shost, hw_addr, ETH_ALEN);
4626        memcpy(eth->ether_dhost, BCAST, ETH_ALEN);
4627        eth->ether_type = htons(ETH_P_ARP);
4628}
4629
4630static inline void setup_garp(struct arph *arp, char *hw_addr, char *paddr)
4631{
4632        arp->hw_type = htons(ARPHDR_ETHER);
4633        arp->proto_type = htons(ETH_P_IP);
4634        arp->ha_len = ETH_ALEN;
4635        arp->pa_len = IP_ALEN;
4636
4637        memcpy(arp->source_add, hw_addr, ETH_ALEN);
4638        memcpy(arp->source_ip, paddr, IP_ALEN);
4639}
4640
4641static inline void setup_garp_broadcast(struct arph *arp, char *paddr)
4642{
4643        arp->opcode = htons(ARPOP_BROADCAST);
4644
4645        memset(arp->dest_add, 0, ETH_ALEN);
4646        memcpy(arp->dest_ip, paddr, IP_ALEN);
4647}
4648
4649static inline void setup_garp_reply(struct arph *arp, char *hw_addr,
4650                                    char *paddr)
4651{
4652        arp->opcode = htons(ARPOP_REPLY);
4653
4654        memcpy(arp->dest_add, hw_addr, ETH_ALEN);
4655        memcpy(arp->dest_ip, paddr, IP_ALEN);
4656}
4657
4658/*
4659 * send_garp
4660 *
4661 * - sends 20 gartuitous arps
4662 * in a 200 millisec interval.
4663 * One as braadcast and one as reply.
4664 *
4665 *
4666 * parameter iface: sending interface name
4667 *
4668 * returns false on failure
4669 *         true on success
4670 */
4671static int send_garp(char *iface)
4672{
4673        char pkt[ARP_HLEN];
4674        char iface_hw[ETH_ALEN];
4675        char iface_paddr[IP_ALEN];
4676        struct sockaddr_ll link;
4677        struct ether_header *eth;
4678        struct arph *arp;
4679        int rc;
4680        int sk;
4681        int n_garps = 10;
4682
4683        eth = (struct ether_header *)pkt;
4684        arp = (struct arph *)(pkt + ETH_HLEN);
4685
4686        sk = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
4687        if (unlikely(sk == -1)) {
4688                perror("socket");
4689                return sk;
4690        }
4691
4692        rc = get_iface_attr(sk, iface, iface_hw, iface_paddr);
4693        if (unlikely(rc == -1))
4694                goto out;
4695
4696        /* set link layer information for driver */
4697        memset(&link, 0, sizeof(link));
4698        link.sll_family = AF_PACKET;
4699        link.sll_ifindex = if_nametoindex(iface);
4700
4701        setup_eth(eth, iface_hw);
4702        setup_garp(arp, iface_hw, iface_paddr);
4703
4704        while (n_garps--) {
4705                setup_garp_broadcast(arp, iface_paddr);
4706                rc = sendto(sk,
4707                            pkt,
4708                            ARP_HLEN,
4709                            0,
4710                            (struct sockaddr *)&link, sizeof(struct sockaddr_ll)
4711                    );
4712                if (unlikely(rc == -1)) {
4713                        perror("sendto");
4714                        goto out;
4715                }
4716
4717                setup_garp_reply(arp, iface_hw, iface_paddr);
4718                rc = sendto(sk,
4719                            pkt,
4720                            ARP_HLEN,
4721                            0,
4722                            (struct sockaddr *)&link, sizeof(struct sockaddr_ll)
4723                    );
4724                if (unlikely(rc == -1)) {
4725                        perror("sendto");
4726                        goto out;
4727                }
4728                usleep(200000);
4729        }
4730
4731out:
4732        close(sk);
4733        return rc;
4734}
4735
4736int gratarp_main(char *iface)
4737{
4738        if (iface) {
4739                usleep(500000);
4740                send_garp(iface);
4741        }
4742
4743        return 0;
4744}
4745
4746/* NF Mark/Mask
4747 *
4748 * since multiple services needs a NF packet mark,
4749 * we need to use masks to split the 32bit value into several pieces
4750 *
4751 *                                             31       23       15       7      0
4752 * port_forwards         1 bit(s) offset 31  > 10000000 00000000 00000000 00000000
4753 * sputnik agent         8 bit(s) offset 23  > 01111111 10000000 00000000 00000000
4754 * quality of service   12 bit(s) offset 11  > 00000000 01111111 11111000 00000000
4755 *
4756 * the remaining 11 bits are currently not in use
4757 */
4758
4759struct NF_MASKS {
4760        char *service_name;     // name of the service
4761        int      bits_used;             // bits used by this service
4762        int  bit_offset;        // position of the fist bit
4763};
4764
4765static struct NF_MASKS service_masks[] = {
4766        {"FORWARD",     1, 31},
4767        {"SPUTNIK",     8, 23},
4768        {"QOS",         12, 11},
4769};
4770
4771char *
4772get_NFServiceMark(char *service, uint32 mark)
4773{
4774        int x, offset, bitpos;
4775        uint32 nfmark = 0, nfmask = 0;
4776
4777        static char buffer[24];
4778
4779        for (x=0; x < sizeof(service_masks) / sizeof(struct NF_MASKS); x++) {
4780                if (strcmp(service, service_masks[x].service_name) == 0)
4781                {
4782                        if (mark >= (1<<service_masks[x].bits_used))
4783                                return "0xffffffff/0xffffffff";
4784
4785                        offset = service_masks[x].bit_offset;
4786                        bitpos = offset + service_masks[x].bits_used - 1;
4787
4788                        nfmark = (mark << offset);
4789
4790                        for(; bitpos>=offset; bitpos--)
4791                                nfmask |= (1 << bitpos);
4792
4793                        sprintf(buffer, "0x%x/0x%x", nfmark, nfmask);
4794                        //fprintf(stderr, "%s\n", buffer);
4795
4796                        return buffer;
4797                }
4798        }
4799        return "0xffffffff/0xffffffff";
4800}
4801
Note: See TracBrowser for help on using the repository browser.