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

Last change on this file since 19041 was 19041, checked in by BrainSlayer, 13 months ago

more fancy

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