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

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

mr3240 support

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