source: src/router/shared/utils.c @ 9828

Last change on this file since 9828 was 9828, checked in by BrainSlayer, 5 years ago

reduce probes on interfaces, reduces also useless system messages

File size: 102.3 KB
Line 
1//#define CDEBUG
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <errno.h>
7#include <net/if.h>
8#include <dirent.h>
9#include <unistd.h>
10#include <ctype.h>
11#include <syslog.h>
12#include <sys/socket.h>
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <netinet/in.h>
16#include <stdarg.h>
17#include <sys/ioctl.h>
18#include <sys/sysinfo.h>
19#include <arpa/inet.h>
20#include <netdb.h>
21#include <resolv.h>
22#include <signal.h>
23
24
25
26#include <utils.h>
27#include <wlutils.h>
28#include <bcmnvram.h>
29#include <shutils.h>
30#include <cy_conf.h>
31#include <code_pattern.h>
32#include <bcmdevs.h>
33#include <net/route.h>
34#include <cy_conf.h>
35#include <bcmdevs.h>
36#include <linux/if_ether.h>
37//#include <linux/mii.h>
38#include <linux/sockios.h>
39#include <cymac.h>
40#include <broadcom.h>
41
42#define SIOCGMIIREG     0x8948  /* Read MII PHY register.       */
43#define SIOCSMIIREG     0x8949  /* Write MII PHY register.      */
44void show_hw_type (int type);
45
46struct mii_ioctl_data
47{
48  unsigned short phy_id;
49  unsigned short reg_num;
50  unsigned short val_in;
51  unsigned short val_out;
52};
53
54
55int
56getcpurev (void)
57{
58  FILE *fp = fopen ("/proc/cpuinfo", "rb");
59  if (fp == NULL)
60    {
61      return -1;
62    }
63  int cnt = 0;
64  int b = 0;
65  while (b != EOF)
66    {
67      b = getc (fp);
68      if (b == ':')
69        cnt++;
70      if (cnt == 3)
71        {
72          getc (fp);
73          char cpurev[13];
74          int i = 0;
75          for (i = 0; i < 12; i++)
76            cpurev[i] = getc (fp);
77          cpurev[i] = 0;
78          fclose (fp);
79          if (!strcmp (cpurev, "BCM4710 V0.0")) // BCM4702, BCM4710 (old 125 MHz)
80            return 0;
81          if (!strcmp (cpurev, "BCM3302 V0.6")) // BCM4704
82            return 6;
83          if (!strcmp (cpurev, "BCM3302 V0.7")) // BCM4712, BCM5365
84            return 7;
85          if (!strcmp (cpurev, "BCM3302 V0.8")) // BCM5350, BCM5352
86            return 8;
87          if (!strcmp (cpurev, "BCM3302 V2.9")) // BCM5354
88            return 29;
89          return -1;
90        }
91    }
92  fclose (fp);
93  return -1;
94}
95
96int
97cpu_plltype (void)
98{
99  int cpurev = getcpurev ();
100  int cputype = check_hw_type ();
101
102  if (cpurev == 0)              // BCM4702, BCM4710 (old 125 MHz)
103    return 0;
104  if (cpurev == 6)              // BCM4704
105    return 0;
106  if (cpurev == 7 && cputype == BCM5365_CHIP)   // BCM5365 only supports fixed 200 MHz
107    return 0;
108  if (cpurev == 7 && cputype != BCM5365_CHIP)   // BCM4712
109    return 4;
110  if (cpurev == 8 && cputype == BCM5350_CHIP)   // BCM5350
111    return 3;
112  if (cpurev == 8 && cputype != BCM5350_CHIP)   // BCM5352
113    return 7;
114  if (cpurev == 29)             // BCM5354, only supports fixed 240 MHz
115    return 0;
116  if (cputype == BCM4705_BCM5397_EWC_CHIP)      // BCM4705
117    return 0;                   // could use table 2
118
119  return 0;
120}
121
122int
123startswith (char *source, char *cmp)
124{
125  return !strncmp (source, cmp, strlen (cmp));
126/*  int i;
127  if (cmp == NULL)
128    return 0;
129  if (source == NULL)
130    return 0;
131  int slen = strlen (source);
132  int clen = strlen (cmp);
133  if (clen > slen)
134    return 0;
135
136  for (i = 0; i < clen; i++)
137    if (source[i] != cmp[i])
138      return 0;
139  return 1;*/
140}
141
142int
143count_occurences (char *source, int cmp)
144{
145  int i, cnt = 0;
146  int len = strlen (source);
147
148  for (i = 0; i < len; i++)
149    {
150      if (source[i] == cmp)
151        cnt++;
152    }
153  return cnt;
154}
155
156int
157pos_nthoccurence (char *source, int cmp, int which)
158{
159  int i, cnt = 0;
160  int len = strlen (source);
161
162  for (i = 0; i < len; i++)
163    {
164      if (source[i] == cmp)
165        cnt++;
166      if (cnt == which)
167        return i;
168    }
169  return -1;
170}
171
172char *
173substring (int start, int stop, const char *src, char *dst)
174{
175  int count = stop - start;
176
177  sprintf (dst, "%.*s", count, src + start);
178
179  return dst;
180}
181
182/*  This function returns the number of days for the given month in the given year    */
183unsigned int
184daysformonth (unsigned int month, unsigned int year)
185{
186  return (30 + (((month & 9) == 8) || ((month & 9) == 1)) - (month == 2) -
187          (!(((year % 4) == 0)
188             && (((year % 100) != 0) || ((year % 400) == 0)))
189           && (month == 2)));
190}
191
192/* given month, day, year, returns day of week, eg. Monday = 0 etc.    */
193int
194weekday (int month, int day, int year)
195{
196  int ix, tx, vx;
197
198  switch (month)
199    {
200    case 2:
201    case 6:
202      vx = 0;
203      break;
204    case 8:
205      vx = 4;
206      break;
207    case 10:
208      vx = 8;
209      break;
210    case 9:
211    case 12:
212      vx = 12;
213      break;
214    case 3:
215    case 11:
216      vx = 16;
217      break;
218    case 1:
219    case 5:
220      vx = 20;
221      break;
222    case 4:
223    case 7:
224      vx = 24;
225      break;
226    }
227
228  if (year > 1900)              // 1900 was not a leap year
229    year -= 1900;
230  ix = ((year - 21) % 28) + vx + (month > 2);   // take care of February
231  tx = (ix + (ix / 4)) % 7 + day;       // take care of leap year
232
233  return (tx % 7);
234
235}
236
237void
238setRouter (char *name)
239{
240#ifdef HAVE_POWERNOC_WORT54G
241  nvram_set (NVROUTER, "WORT54G");
242#elif HAVE_POWERNOC_WOAP54G
243  nvram_set (NVROUTER, "WOAP54G");
244#elif HAVE_OMNI
245  nvram_set (NVROUTER, "Omni Wifi Router");
246#elif HAVE_MAKSAT
247  nvram_set (NVROUTER, "MAKSAT");
248#else
249  if (name)
250    nvram_set (NVROUTER, name);
251#endif
252}
253
254char *
255getRouter ()
256{
257  char *n = nvram_get (NVROUTER);
258  return n != NULL ? n : "Unknown Model";
259}
260
261
262
263int
264internal_getRouterBrand ()
265{
266
267#ifdef HAVE_RB500
268  setRouter ("Mikrotik RB500");
269  return ROUTER_BOARD_500;
270#elif HAVE_GEMTEK
271  setRouter ("SuperGerry");
272  return ROUTER_SUPERGERRY;
273#elif HAVE_TONZE
274  setRouter ("Tonze AP-425");
275  return ROUTER_BOARD_GATEWORX;
276#elif HAVE_NOP8670
277  setRouter ("Senao NOP-8670");
278  return ROUTER_BOARD_GATEWORX;
279#elif HAVE_WRT300NV2
280  setRouter ("Linksys WRT300N v2");
281  return ROUTER_BOARD_GATEWORX;
282#elif HAVE_GATEWORX
283  char *filename = "/sys/devices/platform/IXP4XX-I2C.0/i2c-adapter:i2c-0/0-0051/eeprom";        /* bank2=0x100 */
284  FILE *file = fopen (filename, "r");
285  if (file)                     //new detection scheme
286    {
287      fseek (file, 32, SEEK_SET);
288      char gwid[7];
289      gwid[6] = 0;
290      int ret = fread (gwid, 6, 1, file);
291      if (ret < 1)
292        {
293          fclose (file);
294          goto old_way;
295        }
296      fclose (file);
297      if (!strcmp (gwid, "GW2347"))
298        {
299          setRouter ("Avila GW2347");
300          return ROUTER_BOARD_GATEWORX_SWAP;
301        }
302      if (!strcmp (gwid, "GW2357"))
303        {
304          setRouter ("Avila GW2357");
305          return ROUTER_BOARD_GATEWORX_SWAP;
306        }
307      if (!strcmp (gwid, "GW2353"))
308        {
309          setRouter ("Avila GW2343");
310          return ROUTER_BOARD_GATEWORX;
311        }
312      if (!strcmp (gwid, "GW2348"))
313        {
314          setRouter ("Avila GW2348-4/2");
315          return ROUTER_BOARD_GATEWORX;
316        }
317      if (!strcmp (gwid, "GW2358"))
318        {
319          setRouter ("Cambria GW2358-4");
320          return ROUTER_BOARD_GATEWORX;
321        }
322      if (!strcmp (gwid, "GW2355"))
323        {
324          setRouter ("Avila GW2355");
325          return ROUTER_BOARD_GATEWORX_GW2345;
326        }
327      if (!strcmp (gwid, "GW2345"))
328        {
329          setRouter ("Avila GW2345");
330          return ROUTER_BOARD_GATEWORX_GW2345;
331        }
332    }
333old_way:;
334  struct mii_ioctl_data *data;
335  struct ifreq iwr;
336  int s = socket (AF_INET, SOCK_DGRAM, 0);
337  if (s < 0)
338    {
339      fprintf (stderr, "socket(SOCK_DRAGM)\n");
340      setRouter ("Avila Gateworks");
341      return ROUTER_BOARD_GATEWORX;
342    }
343  (void) strncpy (iwr.ifr_name, "ixp0", sizeof ("ixp0"));
344  data = (struct mii_ioctl_data *) &iwr.ifr_data;
345  data->phy_id = 1;
346#define IX_ETH_ACC_MII_PHY_ID1_REG  0x2 /* PHY identifier 1 Register */
347#define IX_ETH_ACC_MII_PHY_ID2_REG  0x3 /* PHY identifier 2 Register */
348  data->reg_num = IX_ETH_ACC_MII_PHY_ID1_REG;
349  ioctl (s, SIOCGMIIREG, &iwr);
350  data->phy_id = 1;
351  data->reg_num = IX_ETH_ACC_MII_PHY_ID1_REG;
352  ioctl (s, SIOCGMIIREG, &iwr);
353  int reg1 = data->val_out;
354  data->phy_id = 1;
355  data->reg_num = IX_ETH_ACC_MII_PHY_ID2_REG;
356  ioctl (s, SIOCGMIIREG, &iwr);
357  int reg2 = data->val_out;
358  close (s);
359  fprintf (stderr, "phy id %X:%X\n", reg1, reg2);
360  if (reg1 == 0x2000 && reg2 == 0x5c90)
361    {
362      setRouter ("Avila GW2347");
363      return ROUTER_BOARD_GATEWORX_SWAP;
364    }
365  else if (reg1 == 0x13 && reg2 == 0x7a11)
366    {
367      setRouter ("Avila GW2348-4/2");
368      return ROUTER_BOARD_GATEWORX;
369    }
370  else if (reg1 == 0x22 && reg2 == 0x1450)      //kendin switch
371    {
372      setRouter ("Avila GW2345");
373      return ROUTER_BOARD_GATEWORX_GW2345;
374    }
375  else if (reg1 == 0x0 && reg2 == 0x8201)       //realtek
376    {
377      setRouter ("Compex WP188");
378      return ROUTER_BOARD_GATEWORX;
379    }
380  else
381    {
382      setRouter ("Unknown");
383      return ROUTER_BOARD_GATEWORX;
384    }
385#elif HAVE_X86
386  setRouter ("Generic X86");
387  return ROUTER_BOARD_X86;
388#elif HAVE_XSCALE
389  setRouter ("NewMedia Dual A/B/G");
390  return ROUTER_BOARD_XSCALE;
391#elif HAVE_MAGICBOX
392  setRouter ("MagicBox");
393  return ROUTER_BOARD_MAGICBOX;
394#elif HAVE_WRT54GV7
395  setRouter ("Linksys WRT54G v7");
396  return ROUTER_BOARD_FONERA;
397#elif HAVE_WRK54G
398  setRouter ("Linksys WRK54G v3");
399  return ROUTER_BOARD_FONERA;
400#elif HAVE_MR3202A
401  setRouter ("MR3202A");
402  return ROUTER_BOARD_FONERA;
403#elif HAVE_AR430W
404  setRouter ("Airlink-101 AR430W");
405  return ROUTER_BOARD_FONERA;
406#elif HAVE_DIR400
407  setRouter ("D-Link DIR-400");
408  return ROUTER_BOARD_FONERA2200;
409#elif HAVE_DIR300
410  setRouter ("D-Link DIR-300");
411  return ROUTER_BOARD_FONERA;
412#elif HAVE_FONERA
413  struct mii_ioctl_data *data;
414  struct ifreq iwr;
415  int s = socket (AF_INET, SOCK_DGRAM, 0);
416  if (s < 0)
417    {
418      fprintf (stderr, "socket(SOCK_DRAGM)\n");
419      setRouter ("Fonera 2100/2200");
420      return ROUTER_BOARD_FONERA;
421    }
422  (void) strncpy (iwr.ifr_name, "eth0", sizeof ("eth0"));
423  data = (struct mii_ioctl_data *) &iwr.ifr_data;
424  data->phy_id = 0x10;
425  data->reg_num = 0x2;
426  ioctl (s, SIOCGMIIREG, &iwr);
427  data->phy_id = 0x10;
428  data->reg_num = 0x2;
429  ioctl (s, SIOCGMIIREG, &iwr);
430  if (data->val_out == 0x0141)
431    {
432      data->phy_id = 0x10;
433      data->reg_num = 0x3;
434      ioctl (s, SIOCGMIIREG, &iwr);
435      close (s);
436      if ((data->val_out & 0xfc00) != 0x0c00)   // marvell phy
437        {
438          setRouter ("Fonera 2100/2200");
439          return ROUTER_BOARD_FONERA;
440        }
441      else
442        {
443          setRouter ("Fonera 2201");
444          return ROUTER_BOARD_FONERA2200;
445        }
446    }
447  else
448    {
449      setRouter ("Fonera 2100/2200");
450      return ROUTER_BOARD_FONERA;
451    }
452#elif HAVE_MERAKI
453  setRouter ("Meraki Mini");
454  return ROUTER_BOARD_MERAKI;
455#elif HAVE_NS2
456  setRouter ("Ubiquiti Nanostation 2");
457  return ROUTER_BOARD_LS2;
458#elif HAVE_NS5
459  setRouter ("Ubiquiti Nanostation 5");
460  return ROUTER_BOARD_LS2;
461#elif HAVE_PS2
462  setRouter ("Ubiquiti Powerstation 2");
463  return ROUTER_BOARD_LS2;
464#elif HAVE_PS5
465  setRouter ("Ubiquiti Powerstation 5");
466  return ROUTER_BOARD_LS2;
467#elif HAVE_LS2
468  setRouter ("Ubiquiti Litestation 2");
469  return ROUTER_BOARD_LS2;
470#elif HAVE_LS5
471  setRouter ("Ubiquiti Litestation 5");
472  return ROUTER_BOARD_LS2;
473#elif HAVE_WHRAG108
474  setRouter ("Buffalo WHR-HP-AG108");
475  return ROUTER_BOARD_WHRAG108;
476#elif HAVE_PB42
477  setRouter ("Atheros PB42");
478  return ROUTER_BOARD_PB42;
479#elif HAVE_LSX
480  setRouter ("Ubiquiti LSX");
481  return ROUTER_BOARD_PB42;
482#elif HAVE_TW6600
483  setRouter ("AW-6600");
484  return ROUTER_BOARD_TW6600;
485#elif HAVE_USR5453
486  setRouter ("US Robotics USR5453");
487  return ROUTER_BOARD_CA8;
488#elif HAVE_CA8PRO
489  setRouter ("Wistron CA8-4 PRO");
490  return ROUTER_BOARD_CA8PRO;
491#elif HAVE_CA8
492  setRouter ("Wistron CA8-4");
493  return ROUTER_BOARD_CA8;
494#else
495
496  uint boardnum = strtoul (nvram_safe_get ("boardnum"), NULL, 0);
497
498  if (boardnum == 42 && nvram_match ("boardtype", "bcm94710ap"))
499    {
500      cprintf ("router is buffalo\n");
501      setRouter ("Buffalo WBR-G54 / WLA-G54");
502      return ROUTER_BUFFALO_WBR54G;
503    }
504#ifndef HAVE_BUFFALO
505  if (nvram_match ("boardnum", "mn700") &&
506      nvram_match ("boardtype", "bcm94710ap"))
507    {
508      cprintf ("router is Microsoft MN-700\n");
509      setRouter ("Microsoft MN-700");
510      return ROUTER_MICROSOFT_MN700;
511    }
512
513  if (nvram_match ("boardnum", "asusX") &&
514      nvram_match ("boardtype", "bcm94710dev"))
515    {
516      cprintf ("router is Asus WL300g / WL500g\n");
517      setRouter ("Asus WL-300g / WL-500g");
518      return ROUTER_ASUS_WL500G;
519    }
520
521  if (boardnum == 44 && nvram_match ("boardtype", "bcm94710ap"))
522    {
523      cprintf ("router is Dell TrueMobile 2300\n");
524      setRouter ("Dell TrueMobile 2300");
525      return ROUTER_DELL_TRUEMOBILE_2300;
526    }
527#endif
528
529  if (boardnum == 100 && nvram_match ("boardtype", "bcm94710dev"))
530    {
531      cprintf ("router is buffalo\n");
532      setRouter ("Buffalo WLA-G54C");
533      return ROUTER_BUFFALO_WLAG54C;
534    }
535
536#ifndef HAVE_BUFFALO
537  if (boardnum == 45 && nvram_match ("boardtype", "bcm95365r"))
538    {
539      cprintf ("router is Asus WL-500GD\n");
540      setRouter ("Asus WL-500g Deluxe");
541      return ROUTER_ASUS_WL500GD;
542    }
543
544  if (boardnum == 45 && nvram_match ("boardtype", "0x0472")
545      && nvram_match ("boardrev", "0x23") && nvram_match ("parkid", "1"))
546    {
547      cprintf ("router is Asus WL-500W\n");
548      setRouter ("Asus WL-500W");
549      return ROUTER_ASUS_WL500W;
550    }
551
552  if (boardnum == 45 && nvram_match ("boardtype", "0x467"))
553    {
554      cprintf ("router is Asus WL-550gE\n");
555      setRouter ("Asus WL-550gE");
556      return ROUTER_ASUS_WL550GE;
557    }
558#endif
559  if (nvram_match ("boardnum", "00") &&
560      nvram_match ("boardtype", "0x0101") && nvram_match ("boardrev", "0x10"))
561    {
562      cprintf ("router is Buffalo wbr2\n");
563      setRouter ("Buffalo WBR2-G54 / WBR2-G54S");
564      return ROUTER_BUFFALO_WBR2G54S;
565    }
566
567  if (boardnum == 2 &&
568      nvram_match ("boardtype", "0x0101") && nvram_match ("boardrev", "0x10"))
569    {
570      cprintf ("router is buffalo wla2-g54c\n");
571      setRouter ("Buffalo WLA2-G54C / WLI3-TX1-G54");
572      return ROUTER_BUFFALO_WLA2G54C;
573    }
574  if (boardnum == 0 && nvram_match ("melco_id", "29090")
575      && nvram_match ("boardflags", "0x0010")
576      && nvram_match ("boardrev", "0x10"))
577    {
578      cprintf ("router is Buffalo WLAH-G54\n");
579      setRouter ("Buffalo WLAH-G54");
580      return ROUTER_BUFFALO_WLAH_G54;
581
582    }
583  if (boardnum == 0 && nvram_match ("melco_id", "31070")
584      && nvram_match ("boardflags", "0x2288")
585      && nvram_match ("boardrev", "0x10"))
586    {
587      cprintf ("router is Buffalo WAPM-HP-AM54G54\n");
588      setRouter ("Buffalo WAPM-HP-AM54G54");
589      return ROUTER_BUFFALO_WAPM_HP_AM54G54;
590    }
591  if (nvram_match ("boardnum", "00") && nvram_match ("boardrev", "0x11")
592      && nvram_match ("boardtype", "0x048e")
593      && nvram_match ("melco_id", "32093"))
594    {
595      cprintf ("router is Buffalo WHR-G125\n");
596      setRouter ("Buffalo WHR-G125");
597      return ROUTER_BUFFALO_WHRG54S;
598    }
599
600  if (nvram_match ("boardnum", "00") &&
601      nvram_match ("boardrev", "0x13") && nvram_match ("boardtype", "0x467"))
602    {
603      if (nvram_match ("boardflags", "0x1658")
604          || nvram_match ("boardflags", "0x2658")
605          || nvram_match ("boardflags", "0x3658"))
606        {
607          cprintf ("router is Buffalo WLI-TX4-G54HP\n");
608          setRouter ("Buffalo WLI-TX4-G54HP");
609          return ROUTER_BUFFALO_WLI_TX4_G54HP;
610        }
611      if (!nvram_match ("buffalo_hp", "1")
612          && nvram_match ("boardflags", "0x2758"))
613        {
614          cprintf ("router is Buffalo WHR-G54S\n");
615          setRouter ("Buffalo WHR-G54S");
616          return ROUTER_BUFFALO_WHRG54S;
617        }
618      if (nvram_match ("buffalo_hp", "1")
619          || nvram_match ("boardflags", "0x1758"))
620        {
621#ifndef HAVE_BUFFALO
622          cprintf ("router is Buffalo WHR-HP-G54\n");
623          setRouter ("Buffalo WHR-HP-G54");
624#else
625          cprintf ("router is Buffalo WHR-HP-G54DD\n");
626#ifdef BUFFALO_JP
627          setRouter ("Buffalo AS-A100");
628#else
629          setRouter ("Buffalo WHR-HP-G54DD");
630#endif
631#endif
632          return ROUTER_BUFFALO_WHRG54S;
633        }
634    }
635
636  if (nvram_match ("boardnum", "00") &&
637      nvram_match ("boardrev", "0x10") && nvram_match ("boardtype", "0x470"))
638    {
639      cprintf ("router is Buffalo WHR-AM54G54\n");
640      setRouter ("Buffalo WHR-AM54G54");
641      return ROUTER_BUFFALO_WHRAM54G54;
642    }
643
644
645  if (boardnum == 42 && nvram_match ("boardtype", "0x042f"))
646    {
647      uint melco_id = strtoul (nvram_safe_get ("melco_id"), NULL, 0);
648
649      if (nvram_match ("product_name", "WZR-RS-G54") || melco_id == 30083)
650        {
651          cprintf ("router is Buffalo WZR-RS-G54\n");
652          setRouter ("Buffalo WZR-RS-G54");
653          return ROUTER_BUFFALO_WZRRSG54;
654        }
655      if (nvram_match ("product_name", "WZR-HP-G54") || melco_id == 30026)
656        {
657          cprintf ("router is Buffalo WZR-HP-G54\n");
658          setRouter ("Buffalo WZR-HP-G54");
659          return ROUTER_BUFFALO_WZRRSG54;
660        }
661      if (nvram_match ("product_name", "WZR-G54") || melco_id == 30061)
662        {
663          cprintf ("router is Buffalo WZR-G54\n");
664          setRouter ("Buffalo WZR-G54");
665          return ROUTER_BUFFALO_WZRRSG54;
666        }
667      if (nvram_match ("melco_id", "290441dd"))
668        {
669          cprintf ("router is Buffalo WHR2-A54G54\n");
670          setRouter ("Buffalo WHR2-A54G54");
671          return ROUTER_BUFFALO_WZRRSG54;
672        }
673      if (nvram_match ("product_name", "WHR3-AG54")
674          || nvram_match ("product_name", "WHR3-B11") || melco_id == 29130)
675        {
676          cprintf ("router is Buffalo WHR3-AG54\n");
677          setRouter ("Buffalo WHR3-AG54");
678          return ROUTER_BUFFALO_WZRRSG54;
679        }
680      if (nvram_match ("product_name", "WVR-G54-NF") || melco_id == 28100)
681        {
682          cprintf ("router is Buffalo WVR-G54-NF\n");
683          setRouter ("Buffalo WVR-G54-NF");
684          return ROUTER_BUFFALO_WZRRSG54;
685        }
686      if (melco_id > 0)         //e.g. 29115
687        {
688          cprintf ("router is Buffalo WZR series\n");
689          setRouter ("Buffalo WZR series");
690          return ROUTER_BUFFALO_WZRRSG54;
691        }
692    }
693
694#ifndef HAVE_BUFFALO
695  if (boardnum == 42 &&
696      nvram_match ("boardtype", "0x042f") && nvram_match ("boardrev", "0x10"))
697//      nvram_match ("boardflags","0x0018"))
698    {
699      cprintf ("router is Linksys WRTSL54GS\n");
700      setRouter ("Linksys WRTSL54GS");
701      return ROUTER_WRTSL54GS;
702    }
703
704  if (boardnum == 42 && nvram_match ("boardtype", "0x0101")
705      && nvram_match ("boardrev", "0x10") && nvram_match ("boot_ver", "v3.6"))
706    {
707      cprintf ("router is Linksys WRT54G3G\n");
708      setRouter ("Linksys WRT54G3G");
709      return ROUTER_WRT54G3G;
710    }
711
712  if (boardnum == 45 &&
713      nvram_match ("boardtype", "0x042f") && nvram_match ("boardrev", "0x10"))
714    {
715      cprintf ("router is Asus WL-500g Premium\n");
716      setRouter ("Asus WL-500g Premium");
717      return ROUTER_ASUS_WL500G_PRE;
718    }
719
720
721  char *et0 = nvram_safe_get ("et0macaddr");
722
723  if (boardnum == 100 && nvram_match ("boardtype", "bcm94710r4"))
724    {
725      if (startswith (et0, "00:11:50"))
726        {
727          cprintf ("router is Belkin F5D7130 / F5D7330\n");
728          setRouter ("Belkin F5D7130 / F5D7330");
729          return ROUTER_RT210W;
730        }
731      if (startswith (et0, "00:30:BD") || startswith (et0, "00:30:bd"))
732        {
733          cprintf ("router is Belkin F5D7230 v1000\n");
734          setRouter ("Belkin F5D7230-4 v1000");
735          return ROUTER_RT210W;
736        }
737      if (startswith (et0, "00:01:E3") ||
738          startswith (et0, "00:01:e3") || startswith (et0, "00:90:96"))
739        {
740          cprintf ("router is Siemens\n");
741          setRouter ("Siemens SE505 v1");
742          return ROUTER_RT210W;
743        }
744      else
745        {
746          cprintf ("router is Askey generic\n");
747          setRouter ("RT210W generic");
748          return ROUTER_RT210W;
749        }
750    }
751
752  if (nvram_match ("boardtype", "bcm94710r4") && nvram_match ("boardnum", ""))
753    {
754      cprintf ("router is Askey board RT2100W\n");
755      setRouter ("Askey board RT2100W-D65)");
756      return ROUTER_BRCM4702_GENERIC;
757    }
758
759  if (boardnum == 0 && nvram_match ("boardtype", "0x0100")
760      && nvram_match ("boardrev", "0x10"))
761    {
762      cprintf ("router is Askey board RT2205(6)D-D56\n");
763      if (startswith (et0, "00:11:50") ||
764          startswith (et0, "00:30:BD") || startswith (et0, "00:30:bd"))
765        {
766          setRouter ("Askey board RT2205(6)D-D56");
767        }
768      else
769        {
770          setRouter ("Belkin board F5D8230");
771        }
772      return ROUTER_ASKEY_RT220XD;
773    }
774
775  if (nvram_match ("boardtype", "0x0101"))
776    {
777      if (startswith (et0, "00:11:50") ||
778          startswith (et0, "00:30:BD") || startswith (et0, "00:30:bd"))
779        {
780          if (nvram_match ("Belkin_ver", "2000"))
781            {
782              cprintf ("router is Belkin F5D7230-4 v2000\n");
783              setRouter ("Belkin F5D7230-4 v2000");
784              return ROUTER_BELKIN_F5D7230_V2000;
785            }
786          else
787            {
788              cprintf ("router is Belkin F5D7230-4 v1444\n");
789              setRouter ("Belkin F5D7230-4 v1444");
790              return ROUTER_RT480W;
791            }
792        }
793      if (startswith (et0, "00:01:E3") ||
794          startswith (et0, "00:01:e3") || startswith (et0, "00:90:96"))
795        {
796          cprintf ("router is Siemens / Askey\n");
797          setRouter ("Siemens SE505 v2");
798          return ROUTER_RT480W;
799        }
800    }
801
802  if (nvram_match ("boardtype", "0x456")
803      && nvram_match ("hw_model", "F5D7231-4"))
804    {
805      cprintf ("router is Belkin F5D7231-4 v1212UK\n");
806      setRouter ("Belkin F5D7231-4 v1212UK");
807      return ROUTER_BELKIN_F5D7231;
808    }
809
810  if (boardnum == 8 && nvram_match ("boardtype", "0x0467"))     //fccid: K7SF5D7231B
811    {
812      cprintf ("router is Belkin F5D7231-4 v2000\n");
813      setRouter ("Belkin F5D7231-4 v2000");
814      return ROUTER_BELKIN_F5D7231;
815    }
816
817  if (nvram_match ("boardtype", "0x467"))
818    {
819      if (startswith (et0, "00:11:50") ||
820          startswith (et0, "00:30:BD") || startswith (et0, "00:30:bd"))
821        {
822          cprintf ("router is Belkin F5D7231-4 v2000\n");
823          setRouter ("Belkin F5D7231-4 v2000");
824          return ROUTER_BELKIN_F5D7231;
825        }
826    }
827#endif
828  if (boardnum == 2 && nvram_match ("boardtype", "bcm94710dev") && nvram_match ("melco_id", "29016"))   //Buffalo WLI2-TX1-G54)
829    {
830      cprintf ("router is Buffalo WLI2-TX1-G54\n");
831      setRouter ("Buffalo WLI2-TX1-G54");
832      return ROUTER_BUFFALO_WLI2_TX1_G54;
833    }
834#ifndef HAVE_BUFFALO
835
836  char *gemtek = nvram_safe_get ("GemtekPmonVer");
837  uint gemteknum = strtoul (gemtek, NULL, 0);
838
839  if (boardnum == 2 && gemteknum == 10 &&
840      (startswith (et0, "00:0C:E5") ||
841       startswith (et0, "00:0c:e5") ||
842       startswith (et0, "00:0C:10") ||
843       startswith (et0, "00:0c:10") ||
844       startswith (et0, "00:0C:11") || startswith (et0, "00:0c:11")))
845    {
846      cprintf ("router Motorola WE800G v1\n");
847      setRouter ("Motorola WE800G v1");
848      return ROUTER_MOTOROLA_WE800G;
849    }
850
851  if (boardnum == 2
852      && (startswith (gemtek, "RC") || gemteknum == 1 || gemteknum == 10))
853    {
854      cprintf ("router is Linksys wap54g v1.x\n");
855      setRouter ("Linksys WAP54G v1.x");
856      return ROUTER_WAP54G_V1;
857    }
858
859  if (boardnum == 2 && gemteknum == 1)
860    {
861      cprintf ("router is Sitecom wl-105b\n");
862      setRouter ("Sitecom WL-105(b)");
863      return ROUTER_SITECOM_WL105B;
864    }
865
866  if (boardnum == 2 && gemteknum == 7
867      && nvram_match ("boardtype", "bcm94710dev"))
868    {
869      cprintf ("router is Sitecom wl-111\n");
870      setRouter ("Sitecom WL-111");
871      return ROUTER_SITECOM_WL111;
872    }
873
874  if (gemteknum == 9)           //Must be Motorola wr850g v1 or we800g v1 or Linksys wrt55ag v1
875    {
876      if (startswith (et0, "00:0C:E5") ||
877          startswith (et0, "00:0c:e5") ||
878          startswith (et0, "00:0C:10") ||
879          startswith (et0, "00:0c:10") ||
880          startswith (et0, "00:0C:11") ||
881          startswith (et0, "00:0c:11") ||
882          startswith (et0, "00:11:22") ||
883          startswith (et0, "00:0C:90") || startswith (et0, "00:0c:90"))
884        {
885          if (!strlen (nvram_safe_get ("phyid_num")))
886            {
887              eval ("insmod", "switch-core");   //get phy type
888              eval ("insmod", "switch-robo");
889              eval ("rmmod", "switch-robo");
890              eval ("rmmod", "switch-core");
891              nvram_set ("boardnum", "2");
892              nvram_set ("boardtype", "bcm94710dev");
893            }
894          if (nvram_match ("phyid_num", "0x00000000"))
895            {
896              cprintf ("router Motorola WE800G v1\n");
897              setRouter ("Motorola WE800G v1");
898              return ROUTER_MOTOROLA_WE800G;
899            }
900          else                  //phyid_num == 0xffffffff
901            {
902              cprintf ("router Motorola WR850G v1\n");
903              setRouter ("Motorola WR850G v1");
904              return ROUTER_MOTOROLA_V1;
905            }
906        }
907      else
908        {
909          cprintf ("router is linksys WRT55AG\n");
910          setRouter ("Linksys WRT55AG v1");
911          return ROUTER_LINKSYS_WRT55AG;
912        }
913    }
914#endif
915  if (boardnum == 0 && nvram_match ("boardtype", "0x478")
916      && nvram_match ("cardbus", "0") && nvram_match ("boardrev", "0x10")
917      && nvram_match ("boardflags", "0x110")
918      && nvram_match ("melco_id", "32027"))
919    {
920      setRouter ("Buffalo WZR-G144NH");
921      return ROUTER_BUFFALO_WZRG144NH;
922    }
923
924
925  if (boardnum == 20060330 && nvram_match ("boardtype", "0x0472"))
926    {
927      setRouter ("Buffalo WZR-G300N");
928      return ROUTER_BUFFALO_WZRG300N;
929    }
930#ifndef HAVE_BUFFALO
931
932  if (boardnum == 8 &&
933      nvram_match ("boardtype", "0x0472") && nvram_match ("cardbus", "1"))
934    {
935      cprintf ("router is Netgear WNR834B\n");
936      setRouter ("Netgear WNR834B");
937      return ROUTER_NETGEAR_WNR834B;
938    }
939
940  if (boardnum == 1 &&
941      nvram_match ("boardtype", "0x0472") && nvram_match ("cardbus", "1"))
942    {
943      cprintf ("router is Netgear WNR834B v2\n");
944      setRouter ("Netgear WNR834B v2");
945      return ROUTER_NETGEAR_WNR834BV2;
946    }
947
948  if (boardnum == 1 &&
949      nvram_match ("boardtype", "0x0472") && nvram_match ("boardrev", "0x23"))
950    {
951      cprintf ("router is Netgear WNDR-3300\n");
952      setRouter ("Netgear WNDR3300");
953      return ROUTER_NETGEAR_WNDR3300;
954    }
955
956  if (boardnum == 42)           //Get Linksys N models
957    {
958      if (nvram_match ("boot_hw_model", "WRT300N")
959          && nvram_match ("boot_hw_ver", "1.1"))
960        {
961          setRouter ("Linksys WRT300N v1.1");
962          return ROUTER_WRT300NV11;
963        }
964      else if (nvram_match ("boot_hw_model", "WRT150N")
965               && nvram_match ("boot_hw_ver", "1"))
966        {
967          setRouter ("Linksys WRT150N v1");
968          return ROUTER_WRT150N;
969        }
970      else if (nvram_match ("boot_hw_model", "WRT150N")
971               && nvram_match ("boot_hw_ver", "1.1"))
972        {
973          setRouter ("Linksys WRT150N v1.1");
974//              return ROUTER_WRT150NV11;
975          return ROUTER_WRT150N;
976        }
977      else if (nvram_match ("boot_hw_model", "WRT150N")
978               && nvram_match ("boot_hw_ver", "1.2"))
979        {
980          setRouter ("Linksys WRT150N v1.2");
981//              return ROUTER_WRT150NV12;
982          return ROUTER_WRT150N;
983        }
984      else if (nvram_match ("boot_hw_model", "WRT160N")
985               && nvram_match ("boot_hw_ver", "1.0"))
986        {
987          setRouter ("Linksys WRT160N");
988          return ROUTER_WRT160N;
989        }
990      else if (nvram_match ("boot_hw_model", "WRT310N")
991               && nvram_match ("boot_hw_ver", "1.0"))
992        {
993          setRouter ("Linksys WRT310N");
994          return ROUTER_WRT310N;
995        }
996    }
997
998  if (boardnum == 42 &&
999      nvram_match ("boardtype", "0x0472") && nvram_match ("cardbus", "1"))
1000    {
1001      setRouter ("Linksys WRT300N v1");
1002      return ROUTER_WRT300N;
1003    }
1004
1005
1006  if (boardnum == 42 &&
1007      nvram_match ("boardtype", "0x478") && nvram_match ("cardbus", "1"))
1008    {
1009      cprintf ("router is Linksys WRT350N\n");
1010      setRouter ("Linksys WRT350N");
1011      return ROUTER_WRT350N;
1012    }
1013
1014  if (nvram_match ("boardnum", "20070615") &&
1015      nvram_match ("boardtype", "0x478") && nvram_match ("cardbus", "0")
1016      && nvram_match ("switch_type", "BCM5395"))
1017    {
1018      cprintf ("router is Linksys WRT600N v1.1\n");
1019      setRouter ("Linksys WRT600N v1.1");
1020      return ROUTER_WRT600N;
1021    }
1022  if (nvram_match ("boardnum", "20070615") &&
1023      nvram_match ("boardtype", "0x478") && nvram_match ("cardbus", "0"))
1024    {
1025      cprintf ("router is Linksys WRT600N\n");
1026      setRouter ("Linksys WRT600N");
1027      return ROUTER_WRT600N;
1028    }
1029
1030  if (boardnum == 42 && nvram_match ("boardtype", "bcm94710dev"))
1031    {
1032      cprintf ("router is Linksys WRT54G v1.x\n");
1033      setRouter ("Linksys WRT54G v1.x");
1034      return ROUTER_WRT54G1X;
1035    }
1036
1037  if ((boardnum == 1 || boardnum == 0) && nvram_match ("boardtype", "0x0446"))
1038    {
1039      cprintf ("router is U.S. Robotics USR5430\n");
1040      setRouter ("U.S.Robotics USR5430");
1041      return ROUTER_USR_5430;
1042    }
1043
1044
1045  if (boardnum == 1 && nvram_match ("boardtype", "0x456"))
1046    {
1047      cprintf ("router is Netgear WG602 v3\n");
1048      setRouter ("Netgear WG602 v3");
1049      return ROUTER_NETGEAR_WG602_V3;
1050    }
1051
1052  if (boardnum == 10496 && nvram_match ("boardtype", "0x456"))
1053    {
1054      cprintf ("router is U.S. Robotics USR5461\n");
1055      setRouter ("U.S.Robotics USR5461");
1056      return ROUTER_USR_5461;
1057    }
1058   
1059  if (boardnum == 10500 && nvram_match ("boardtype", "0x456"))
1060    {
1061      cprintf ("router is U.S. Robotics USR5432\n");
1062      setRouter ("U.S.Robotics USR5432");
1063      return ROUTER_USR_5461;   //should work in the same way
1064    }
1065   
1066  if (boardnum == 10506 && nvram_match ("boardtype", "0x456"))
1067    {
1068      cprintf ("router is U.S. Robotics USR5451\n");
1069      setRouter ("U.S.Robotics USR5451");
1070      return ROUTER_USR_5461;   //should work in the same way
1071    }
1072
1073  if (boardnum == 1024 && nvram_match ("boardtype", "0x0446"))
1074    {
1075      char *cfe = nvram_safe_get ("cfe_version");
1076      if (strstr (cfe, "iewsonic"))
1077        {
1078          cprintf ("router is Viewsonic WAPBR-100\n");
1079          setRouter ("Viewsonic WAPBR-100");
1080          return ROUTER_VIEWSONIC_WAPBR_100;
1081        }
1082      else
1083        {
1084          cprintf ("router is Linksys WAP54G v2\n");
1085          setRouter ("Linksys WAP54G v2");
1086          return ROUTER_WAP54G_V2;
1087        }
1088    }
1089
1090  if (nvram_invmatch ("CFEver", ""))
1091    {
1092      char *cfe = nvram_safe_get ("CFEver");
1093      if (!strncmp (cfe, "MotoWR", 6))
1094        {
1095          cprintf ("router is motorola\n");
1096          setRouter ("Motorola WR850G v2/v3");
1097          return ROUTER_MOTOROLA;
1098        }
1099    }
1100
1101  if (boardnum == 44 &&
1102      (nvram_match ("boardtype", "0x0101")
1103       || nvram_match ("boardtype", "0x0101\r")))
1104    {
1105      char *cfe = nvram_safe_get ("CFEver");
1106      if (!strncmp (cfe, "GW_WR110G", 9))
1107        {
1108          cprintf ("router is Sparklan WX-6615GT\n");
1109          setRouter ("Sparklan WX-6615GT");
1110          return ROUTER_DELL_TRUEMOBILE_2300_V2;
1111        }
1112      else
1113        {
1114          cprintf ("router is Dell TrueMobile 2300 v2\n");
1115          setRouter ("Dell TrueMobile 2300 v2");
1116          return ROUTER_DELL_TRUEMOBILE_2300_V2;
1117        }
1118    }
1119#endif
1120  if (nvram_match ("boardtype", "bcm94710ap"))
1121    {
1122      cprintf ("router is Buffalo old 4710\n");
1123      setRouter ("Buffalo WBR-B11");
1124      return ROUTER_BUFFALO_WBR54G;
1125    }
1126#ifndef HAVE_BUFFALO
1127  if (nvram_match ("boardtype", "0x048e") &&
1128      nvram_match ("boardrev", "0x35") &&
1129      nvram_match ("sdram_init", "0x000b"))
1130    {
1131      cprintf ("router is D-Link DIR-320\n");
1132      setRouter ("D-Link DIR-320");
1133      //apply some fixes
1134      if (nvram_get ("vlan2ports") != NULL)
1135        {
1136          nvram_unset ("vlan2ports");
1137          nvram_unset ("vlan2hwname");
1138        }
1139      return ROUTER_DLINK_DIR320;
1140    }
1141  if (nvram_match ("model_name", "DIR-330") &&
1142      nvram_match ("boardrev", "0x10"))
1143    {
1144      cprintf ("router is D-Link DIR-330\n");
1145      setRouter ("D-Link DIR-330");
1146      nvram_set ("wan_ifnames", "eth0");        // quirk
1147      nvram_set ("wan_ifname", "eth0");
1148      if (nvram_match ("et0macaddr", "00:90:4c:4e:00:0c"))
1149        {
1150          FILE *in = fopen ("/dev/mtdblock/1", "rb");
1151          fseek (in, 0x7a0022, SEEK_SET);
1152          char mac[32];
1153          fread (mac, 32, 1, in);
1154          fclose (in);
1155          mac[17] = 0;
1156          if (sv_valid_hwaddr (mac))
1157            {
1158              nvram_set ("et0macaddr", mac);
1159              fprintf (stderr, "restore D-Link MAC\n");
1160              nvram_commit ();
1161              sys_reboot ();
1162            }
1163        }
1164/*      if (nvram_get("vlan2ports")!=NULL)
1165      {
1166        nvram_unset("vlan2ports");
1167        nvram_unset("vlan2hwname");
1168      }*/
1169      return ROUTER_DLINK_DIR330;
1170    }
1171  if (boardnum == 42 &&
1172      nvram_match ("boardtype", "0x048e") && nvram_match ("boardrev", "0x10"))
1173    {
1174      cprintf ("router is wrt54g v8\n");
1175      setRouter ("Linksys WRT54Gv8 / GSv7");
1176      return ROUTER_WRT54G_V8;
1177    }
1178
1179  if (boardnum == 8 &&
1180      nvram_match ("boardtype", "0x048e") && nvram_match ("boardrev", "0x11"))
1181    {
1182      cprintf ("router is ALLNET01\n");
1183      setRouter ("ALLNET01");
1184      return ROUTER_ALLNET01;
1185    }
1186
1187  if (boardnum == 1 &&
1188      nvram_match ("boardtype", "0x048e") && nvram_match ("boardrev", "0x11"))
1189    {
1190      cprintf ("router is Netgear WG602 v4\n");
1191      setRouter ("Netgear WG602 v4");
1192      return ROUTER_NETGEAR_WG602_V4;
1193    }
1194
1195  if (boardnum == 1 &&
1196      nvram_match ("boardtype", "0x048e") && nvram_match ("boardrev", "0x35")
1197      && nvram_match ("parefldovoltage", "0x28"))
1198    {
1199      cprintf ("router is netcore nw618\n");
1200      setRouter ("NetCore NW618");
1201      return ROUTER_WRT54G;
1202    }
1203
1204  if (boardnum == 42 &&
1205      nvram_match ("boardtype", "0x048E") && nvram_match ("boardrev", "0x10"))
1206    {
1207      cprintf ("router is Linksys WRH54G\n");
1208      setRouter ("Linksys WRH54G");
1209      return ROUTER_LINKSYS_WRH54G;
1210    }
1211
1212  if (nvram_match ("boardnum", "00") &&
1213      nvram_match ("boardtype", "0x048E") && nvram_match ("boardrev", "0x10"))
1214    {
1215      cprintf ("router is Linksys WRT54G v8.1\n");
1216      setRouter ("Linksys WRT54G v8.1");
1217      return ROUTER_WRT54G_V81;
1218    }
1219
1220  if (boardnum == 45 && nvram_match ("boardtype", "0x456"))
1221    {
1222      cprintf ("router is Asus WL-520G\n");
1223      setRouter ("Asus WL-520G");
1224      return ROUTER_ASUS_WL520G;
1225    }
1226
1227  if (boardnum == 45 &&
1228      nvram_match ("boardtype", "0x48E") && nvram_match ("boardrev", "0x10"))
1229    {
1230      char *hwver = nvram_safe_get ("hardware_version");
1231      if (startswith (hwver, "WL500GPV2"))
1232        {
1233          cprintf ("router is Asus WL-500G Premium V2\n");
1234          setRouter ("Asus WL-500G Premium V2");
1235          return ROUTER_ASUS_WL500G_PRE_V2;
1236        }
1237      else
1238        {
1239          cprintf ("router is Asus WL-520GU/GC\n");
1240          setRouter ("Asus WL-520GU/GC");
1241          return ROUTER_ASUS_WL520GUGC;
1242        }
1243    }
1244
1245  if (boardnum == 83258 &&
1246      nvram_match ("boardtype", "0x48E") && nvram_match ("boardrev", "0x10"))
1247    {
1248      cprintf ("router is Netgear WGR614L\n");
1249      setRouter ("Netgear WGR614L");
1250      return ROUTER_NETGEAR_WGR614L;
1251    }
1252
1253  if (boardnum == 56 &&
1254      nvram_match ("boardtype", "0x456") && nvram_match ("boardrev", "0x10"))
1255    {
1256      cprintf ("router is wtr54gs\n");
1257      setRouter ("Linksys WTR54GS");
1258      return ROUTER_LINKSYS_WTR54GS;
1259    }
1260
1261  if (nvram_match ("boardnum", "WAP54GV3_8M_0614")
1262      && (nvram_match ("boardtype", "0x0467")
1263          || nvram_match ("boardtype", "0x467"))
1264      && nvram_match ("WAPver", "3"))
1265    {
1266      cprintf ("router is WAP54G v3.x\n");
1267      setRouter ("Linksys WAP54G v3.x");
1268      return ROUTER_WAP54G_V3;
1269    }
1270
1271  setRouter ("Linksys WRT54G/GL/GS");
1272  cprintf ("router is wrt54g\n");
1273  return ROUTER_WRT54G;
1274#else
1275  eval ("event", "3", "1", "15");
1276  return 0;
1277#endif
1278#endif
1279
1280}
1281
1282int
1283has_mimo (char *prefix)
1284{
1285  if (nvram_nmatch ("n", "%s_phytypes", prefix))
1286    return 1;
1287  return 0;
1288}
1289
1290static int router_type = -1;
1291int
1292getRouterBrand ()
1293{
1294  if (router_type == -1)
1295    router_type = internal_getRouterBrand ();
1296  return router_type;
1297}
1298
1299
1300int
1301diag_led_4702 (int type, int act)
1302{
1303
1304#if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || 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)
1305  return 0;
1306#else
1307  if (act == START_LED)
1308    {
1309      switch (type)
1310        {
1311        case DMZ:
1312          system2 ("echo 1 > /proc/sys/diag");
1313          break;
1314        }
1315    }
1316  else
1317    {
1318      switch (type)
1319        {
1320        case DMZ:
1321          system2 ("echo 0 > /proc/sys/diag");
1322          break;
1323        }
1324    }
1325  return 0;
1326#endif
1327}
1328
1329int
1330C_led_4702 (int i)
1331{
1332#if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || 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)
1333  return 0;
1334#else
1335  FILE *fp;
1336  char string[10];
1337  int flg;
1338
1339  memset (string, 0, 10);
1340  /* get diag before set */
1341  if ((fp = fopen ("/proc/sys/diag", "r")))
1342    {
1343      fgets (string, sizeof (string), fp);
1344      fclose (fp);
1345    }
1346  else
1347    perror ("/proc/sys/diag");
1348
1349  if (i)
1350    flg = atoi (string) | 0x10;
1351  else
1352    flg = atoi (string) & 0xef;
1353
1354  memset (string, 0, 10);
1355  sprintf (string, "%d", flg);
1356  if ((fp = fopen ("/proc/sys/diag", "w")))
1357    {
1358      fputs (string, fp);
1359      fclose (fp);
1360    }
1361  else
1362    perror ("/proc/sys/diag");
1363
1364  return 0;
1365#endif
1366}
1367
1368unsigned int
1369read_gpio (char *device)
1370{
1371  FILE *fp;
1372  unsigned int val;
1373
1374  if ((fp = fopen (device, "r")))
1375    {
1376      fread (&val, 4, 1, fp);
1377      fclose (fp);
1378      //fprintf(stderr, "----- gpio %s = [%X]\n",device,val);
1379      return val;
1380    }
1381  else
1382    {
1383      perror (device);
1384      return 0;
1385    }
1386}
1387
1388unsigned int
1389write_gpio (char *device, unsigned int val)
1390{
1391  FILE *fp;
1392
1393  if ((fp = fopen (device, "w")))
1394    {
1395      fwrite (&val, 4, 1, fp);
1396      fclose (fp);
1397      //fprintf(stderr, "----- set gpio %s = [%X]\n",device,val);
1398      return 1;
1399    }
1400  else
1401    {
1402      perror (device);
1403      return 0;
1404    }
1405}
1406
1407static char hw_error = 0;
1408int
1409diag_led_4704 (int type, int act)
1410{
1411#if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || 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)
1412  return 0;
1413#else
1414  unsigned int control, in, outen, out;
1415
1416#ifdef BCM94712AGR
1417  /* The router will crash, if we load the code into broadcom demo board. */
1418  return 1;
1419#endif
1420  //int brand;
1421  control = read_gpio ("/dev/gpio/control");
1422  in = read_gpio ("/dev/gpio/in");
1423  out = read_gpio ("/dev/gpio/out");
1424  outen = read_gpio ("/dev/gpio/outen");
1425
1426  write_gpio ("/dev/gpio/outen", (outen & 0x7c) | 0x83);
1427  switch (type)
1428    {
1429    case DIAG:                  // GPIO 1
1430      if (hw_error)
1431        {
1432          write_gpio ("/dev/gpio/out", (out & 0x7c) | 0x00);
1433          return 1;
1434        }
1435
1436      if (act == STOP_LED)
1437        {                       // stop blinking
1438          write_gpio ("/dev/gpio/out", (out & 0x7c) | 0x83);
1439          //cprintf("tallest:=====( DIAG STOP_LED !!)=====\n");
1440        }
1441      else if (act == START_LED)
1442        {                       // start blinking
1443          write_gpio ("/dev/gpio/out", (out & 0x7c) | 0x81);
1444          //cprintf("tallest:=====( DIAG START_LED !!)=====\n");
1445        }
1446      else if (act == MALFUNCTION_LED)
1447        {                       // start blinking
1448          write_gpio ("/dev/gpio/out", (out & 0x7c) | 0x00);
1449          hw_error = 1;
1450          //cprintf("tallest:=====( DIAG MALFUNCTION_LED !!)=====\n");
1451        }
1452      break;
1453
1454    }
1455  return 1;
1456#endif
1457}
1458
1459int
1460diag_led_4712 (int type, int act)
1461{
1462  unsigned int control, in, outen, out, ctr_mask, out_mask;
1463#if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || 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)
1464  return 0;
1465#else
1466
1467
1468#ifdef BCM94712AGR
1469  /* The router will crash, if we load the code into broadcom demo board. */
1470  return 1;
1471#endif
1472  control = read_gpio ("/dev/gpio/control");
1473  in = read_gpio ("/dev/gpio/in");
1474  out = read_gpio ("/dev/gpio/out");
1475  outen = read_gpio ("/dev/gpio/outen");
1476
1477  ctr_mask = ~(1 << type);
1478  out_mask = (1 << type);
1479
1480  write_gpio ("/dev/gpio/control", control & ctr_mask);
1481  write_gpio ("/dev/gpio/outen", outen | out_mask);
1482
1483  if (act == STOP_LED)
1484    {                           // stop blinking
1485      //cprintf("%s: Stop GPIO %d\n", __FUNCTION__, type);
1486      write_gpio ("/dev/gpio/out", out | out_mask);
1487    }
1488  else if (act == START_LED)
1489    {                           // start blinking
1490      //cprintf("%s: Start GPIO %d\n", __FUNCTION__, type);
1491      write_gpio ("/dev/gpio/out", out & ctr_mask);
1492    }
1493
1494  return 1;
1495#endif
1496}
1497
1498int
1499C_led_4712 (int i)
1500{
1501  if (i == 1)
1502    return diag_led (DIAG, START_LED);
1503  else
1504    return diag_led (DIAG, STOP_LED);
1505}
1506
1507int
1508C_led (int i)
1509{
1510//show_hw_type(check_hw_type());
1511  int brand = getRouterBrand ();
1512
1513  if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
1514    return C_led_4702 (i);
1515  else if (brand == ROUTER_WRT54G)
1516    return C_led_4712 (i);
1517  else
1518    return 0;
1519}
1520
1521int
1522diag_led (int type, int act)
1523{
1524  int brand = getRouterBrand ();
1525
1526  if (brand == ROUTER_WRT54G || brand == ROUTER_WRT54G3G
1527      || brand == ROUTER_WRT300NV11)
1528    return diag_led_4712 (type, act);
1529  else if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
1530    return diag_led_4702 (type, act);
1531  else
1532    if ((brand == ROUTER_WRTSL54GS || brand == ROUTER_WRT350N
1533         || brand == ROUTER_WRT310N
1534         || brand == ROUTER_BUFFALO_WZRG144NH) && type == DIAG)
1535    return diag_led_4704 (type, act);
1536  else
1537    {
1538      if (type == DMZ)
1539        {
1540          if (act == START_LED)
1541            return led_control (LED_DMZ, LED_ON);
1542          if (act == STOP_LED)
1543            return led_control (LED_DMZ, LED_OFF);
1544          return 1;
1545        }
1546    }
1547  return 0;
1548}
1549
1550int
1551led_control (int type, int act)
1552/* type: LED_POWER, LED_DIAG, LED_DMZ, LED_CONNECTED, LED_BRIDGE, LED_VPN, LED_SES, LED_SES2, LED_WLAN
1553 * act: LED_ON, LED_OFF, LED_FLASH */
1554{
1555#if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_MAGICBOX) || defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_LS5)  && !defined(HAVE_DIR300) && !defined(HAVE_DIR400)
1556  return 0;
1557#else
1558
1559  int use_gpio = 0x0f;
1560  int gpio_value;
1561  int enable;
1562  int disable;
1563
1564  int power_gpio = 0x0f;
1565  int diag_gpio = 0x0f;
1566  int dmz_gpio = 0x0f;
1567  int connected_gpio = 0x0f;
1568  int bridge_gpio = 0x0f;
1569  int vpn_gpio = 0x0f;
1570  int ses_gpio = 0x0f;          //use for SES1 (Linksys), AOSS (Buffalo) ....
1571  int ses2_gpio = 0x0f;
1572  int wlan_gpio = 0x0f;         //use this only if wlan led is not controlled by hardware!
1573  int usb_gpio = 0x0f;
1574  int v1func = 0;
1575  switch (getRouterBrand ())    //gpio definitions here: 0xYZ, Y=0:normal, Y=1:inverted, Z:gpio number (f=disabled)
1576    {
1577#ifndef HAVE_BUFFALO
1578    case ROUTER_BOARD_GATEWORX:
1579      connected_gpio = 0x3;
1580      break;
1581    case ROUTER_BOARD_GATEWORX_SWAP:
1582      connected_gpio = 0x4;
1583      break;
1584    case ROUTER_LINKSYS_WRH54G:
1585      diag_gpio = 0x11;         //power led blink / off to indicate factory defaults
1586      break;
1587    case ROUTER_WRT54G:
1588    case ROUTER_WRT54G_V8:
1589      power_gpio = 0x01;
1590      dmz_gpio = 0x17;
1591      connected_gpio = 0x13;    //ses orange
1592      ses_gpio = 0x12;          //ses white
1593      ses2_gpio = 0x13;         //ses orange
1594      break;
1595    case ROUTER_WRT54G_V81:
1596      power_gpio = 0x11;
1597      dmz_gpio = 0x12;
1598      connected_gpio = 0x14;    //ses orange
1599      ses_gpio = 0x13;          //ses white
1600      ses2_gpio = 0x14;         //ses orange
1601      break;
1602    case ROUTER_WRT54G1X:
1603      connected_gpio = 0x13;
1604      v1func = 1;
1605      break;
1606    case ROUTER_WRT350N:
1607      connected_gpio = 0x13;
1608      power_gpio = 0x01;
1609      ses2_gpio = 0x13;         //ses orange
1610//      usb_gpio = 0x04;                   
1611      break;
1612    case ROUTER_WRT600N:
1613      connected_gpio = 0x13;
1614//      power_gpio = 0x01;
1615      ses2_gpio = 0x18;         //ses orange                   
1616      break;
1617    case ROUTER_LINKSYS_WRT55AG:
1618      connected_gpio = 0x13;
1619      break;
1620    case ROUTER_DLINK_DIR330:
1621      diag_gpio = 0x16;
1622      connected_gpio = 0x14;
1623      break;
1624#endif
1625    case ROUTER_BUFFALO_WBR54G:
1626      diag_gpio = 0x17;
1627      break;
1628    case ROUTER_BUFFALO_WBR2G54S:
1629      diag_gpio = 0x01;
1630      ses_gpio = 0x06;
1631      break;
1632    case ROUTER_BUFFALO_WLA2G54C:
1633      diag_gpio = 0x14;
1634      ses_gpio = 0x13;
1635      break;
1636    case ROUTER_BUFFALO_WLAH_G54:
1637      diag_gpio = 0x17;
1638      ses_gpio = 0x16;
1639      break;
1640    case ROUTER_BUFFALO_WAPM_HP_AM54G54:
1641      diag_gpio = 0x17;
1642      ses_gpio = 0x11;
1643      break;
1644    case ROUTER_BOARD_WHRAG108:
1645      diag_gpio = 0x17;
1646      bridge_gpio = 0x14;
1647      ses_gpio = 0x10;
1648      break;
1649    case ROUTER_BUFFALO_WHRG54S:
1650    case ROUTER_BUFFALO_WLI_TX4_G54HP:
1651      diag_gpio = 0x17;
1652      bridge_gpio = 0x11;
1653      ses_gpio = 0x16;
1654      break;
1655    case ROUTER_BUFFALO_WZRRSG54:
1656      diag_gpio = 0x17;
1657      vpn_gpio = 0x11;
1658      ses_gpio = 0x16;
1659      break;
1660    case ROUTER_BUFFALO_WZRG300N:
1661      diag_gpio = 0x17;
1662      bridge_gpio = 0x11;
1663      break;
1664    case ROUTER_BUFFALO_WZRG144NH:
1665      diag_gpio = 0x13;
1666      bridge_gpio = 0x11;
1667      ses_gpio = 0x12;
1668      break;
1669#ifndef HAVE_BUFFALO
1670#ifdef HAVE_DIR300
1671    case ROUTER_BOARD_FONERA:
1672      diag_gpio = 0x03;
1673      bridge_gpio = 0x04;
1674      ses_gpio = 0x01;
1675      break;
1676#endif
1677#ifdef HAVE_DIR400
1678    case ROUTER_BOARD_FONERA2200:
1679      diag_gpio = 0x03;
1680      bridge_gpio = 0x04;
1681      ses_gpio = 0x01;
1682      break;
1683#endif
1684#ifdef HAVE_WRK54G
1685    case ROUTER_BOARD_FONERA:
1686      diag_gpio = 0x17;
1687      dmz_gpio = 0x05;
1688      break;
1689#endif
1690    case ROUTER_BOARD_TW6600:
1691      diag_gpio = 0x17;
1692      bridge_gpio = 0x14;
1693      ses_gpio = 0x10;
1694      break;
1695    case ROUTER_MOTOROLA:
1696      power_gpio = 0x01;
1697      diag_gpio = 0x11;         //power led blink / off to indicate factory defaults
1698      break;
1699    case ROUTER_RT210W:
1700      power_gpio = 0x15;
1701      diag_gpio = 0x05;         //power led blink / off to indicate factory defaults
1702      connected_gpio = 0x10;
1703      wlan_gpio = 0x13;
1704      break;
1705    case ROUTER_RT480W:
1706    case ROUTER_BELKIN_F5D7230_V2000:
1707    case ROUTER_BELKIN_F5D7231:
1708      power_gpio = 0x15;
1709      diag_gpio = 0x05;         //power led blink / off to indicate factory defaults
1710      connected_gpio = 0x10;
1711      break;
1712    case ROUTER_MICROSOFT_MN700:
1713      power_gpio = 0x06;
1714      diag_gpio = 0x16;         //power led blink / off to indicate factory defaults
1715      break;
1716    case ROUTER_ASUS_WL500GD:
1717    case ROUTER_ASUS_WL520GUGC:
1718      diag_gpio = 0x00;         //power led blink / off to indicate factory defaults
1719      break;
1720    case ROUTER_ASUS_WL500G_PRE:
1721      power_gpio = 0x11;
1722      diag_gpio = 0x01;         //power led blink / off to indicate factory defaults
1723      break;
1724    case ROUTER_ASUS_WL550GE:
1725      power_gpio = 0x12;
1726      diag_gpio = 0x02;         //power led blink / off to indicate factory defaults
1727      break;
1728    case ROUTER_WRT54G3G:
1729    case ROUTER_WRTSL54GS:
1730      power_gpio = 0x01;
1731      dmz_gpio = 0x10;
1732      connected_gpio = 0x17;    //ses orange
1733      ses_gpio = 0x15;          //ses white
1734      ses2_gpio = 0x17;         //ses orange   
1735      break;
1736    case ROUTER_MOTOROLA_WE800G:
1737    case ROUTER_MOTOROLA_V1:
1738      diag_gpio = 0x13;
1739      wlan_gpio = 0x11;
1740      bridge_gpio = 0x15;
1741      break;
1742    case ROUTER_DELL_TRUEMOBILE_2300:
1743    case ROUTER_DELL_TRUEMOBILE_2300_V2:
1744      power_gpio = 0x17;
1745      diag_gpio = 0x07;         //power led blink / off to indicate factory defaults
1746      wlan_gpio = 0x16;
1747      break;
1748    case ROUTER_NETGEAR_WNR834B:
1749      power_gpio = 0x14;
1750      diag_gpio = 0x15;
1751      wlan_gpio = 0x16;
1752      break;
1753    case ROUTER_SITECOM_WL105B:
1754      power_gpio = 0x03;
1755      diag_gpio = 0x13;         //power led blink / off to indicate factory defaults
1756      wlan_gpio = 0x14;
1757      break;
1758    case ROUTER_WRT150N:
1759    case ROUTER_WRT300N:
1760      power_gpio = 0x01;
1761      diag_gpio = 0x11;         //power led blink / off to indicate fac.def.
1762      break;
1763    case ROUTER_WRT300NV11:
1764      ses_gpio = 0x15;
1765//      diag_gpio = 0x11;               //power led blink / off to indicate fac.def.
1766      break;
1767    case ROUTER_WRT310N:
1768      connected_gpio = 0x13;
1769      power_gpio = 0x01;
1770      diag_gpio = 0x11;         //power led blink / off to indicate fac.def.
1771      ses2_gpio = 0x13;         //ses orange
1772    case ROUTER_WRT160N:
1773      power_gpio = 0x01;
1774      diag_gpio = 0x11;         //power led blink / off to indicate fac.def.   
1775      connected_gpio = 0x13;    //ses orange
1776      ses_gpio = 0x15;          //ses blue
1777      break;
1778    case ROUTER_ASUS_WL500G:
1779      power_gpio = 0x10;
1780      diag_gpio = 0x00;         //power led blink /off to indicate factory defaults
1781      break;
1782    case ROUTER_ASUS_WL500W:
1783      power_gpio = 0x15;
1784      diag_gpio = 0x05;         //power led blink /off to indicate factory defaults
1785      break;
1786    case ROUTER_LINKSYS_WTR54GS:
1787      diag_gpio = 0x01;
1788      break;
1789    case ROUTER_WAP54G_V1:
1790      diag_gpio = 0x13;
1791      wlan_gpio = 0x14;         //LINK led
1792      break;
1793    case ROUTER_WAP54G_V3:
1794      ses_gpio = 0x1c;
1795      connected_gpio = 0x06;
1796      break;
1797    case ROUTER_NETGEAR_WNR834BV2:
1798      power_gpio = 0x02;
1799      diag_gpio = 0x03;         //power led amber   
1800      connected_gpio = 0x07;    //WAN led green 
1801      break;
1802    case ROUTER_ASKEY_RT220XD:
1803      wlan_gpio = 0x10;
1804      dmz_gpio = 0x11;          //not soldered 
1805      break;
1806#endif
1807    }
1808  if (type == LED_DIAG && v1func == 1)
1809    {
1810      if (act == LED_ON)
1811        C_led (1);
1812      else
1813        C_led (0);
1814    }
1815
1816  switch (type)
1817    {
1818    case LED_POWER:
1819      use_gpio = power_gpio;
1820      break;
1821    case LED_DIAG:
1822      use_gpio = diag_gpio;
1823      break;
1824    case LED_DMZ:
1825      use_gpio = dmz_gpio;
1826      break;
1827    case LED_CONNECTED:
1828      use_gpio = connected_gpio;
1829      break;
1830    case LED_BRIDGE:
1831      use_gpio = bridge_gpio;
1832      break;
1833    case LED_VPN:
1834      use_gpio = vpn_gpio;
1835      break;
1836    case LED_SES:
1837      use_gpio = ses_gpio;
1838      break;
1839    case LED_SES2:
1840      use_gpio = ses2_gpio;
1841      break;
1842    case LED_WLAN:
1843      use_gpio = wlan_gpio;
1844      break;
1845    case LED_USB:
1846      use_gpio = usb_gpio;
1847      break;
1848    }
1849  if ((use_gpio & 0x0f) != 0x0f)
1850    {
1851      gpio_value = use_gpio & 0x0f;
1852      enable = (use_gpio & 0x10) == 0 ? 1 : 0;
1853      disable = (use_gpio & 0x10) == 0 ? 0 : 1;
1854      switch (act)
1855        {
1856        case LED_ON:
1857          set_gpio (gpio_value, enable);
1858          break;
1859        case LED_OFF:
1860          set_gpio (gpio_value, disable);
1861          break;
1862        case LED_FLASH: //will lit the led for 1 sec.
1863          set_gpio (gpio_value, enable);
1864          sleep (1);
1865          set_gpio (gpio_value, disable);
1866          break;
1867        }
1868    }
1869  return 1;
1870
1871#endif
1872}
1873
1874
1875char *
1876get_mac_from_ip (char *ip)
1877{
1878  FILE *fp;
1879  char line[100];
1880  char ipa[50];                 // ip address
1881  char hwa[50];                 // HW address / MAC
1882  char mask[50];                // ntemask   
1883  char dev[50];                 // interface
1884  int type;                     // HW type
1885  int flags;                    // flags
1886  static char mac[20];
1887
1888
1889  if ((fp = fopen ("/proc/net/arp", "r")) == NULL)
1890    return NULL;
1891
1892  // Bypass header -- read until newline
1893  if (fgets (line, sizeof (line), fp) != (char *) NULL)
1894    {
1895      // Read the ARP cache entries.
1896      // IP address       HW type     Flags       HW address            Mask     Device
1897      // 192.168.1.1      0x1         0x2         00:90:4C:21:00:2A     *        eth0
1898      for (; fgets (line, sizeof (line), fp);)
1899        {
1900          if (sscanf
1901              (line, "%s 0x%x 0x%x %100s %100s %100s\n", ipa, &type, &flags,
1902               hwa, mask, dev) != 6)
1903            continue;
1904          //cprintf("ip1=[%s] ip2=[%s] mac=[%s] (flags & ATF_COM)=%d\n", ip, ipa, hwa, (flags & ATF_COM));
1905          if (strcmp (ip, ipa))
1906            continue;
1907          //if (!(flags & ATF_COM)) {       //ATF_COM = 0x02   completed entry (ha valid)
1908          strcpy (mac, hwa);
1909          fclose (fp);
1910          return mac;
1911          //}
1912        }
1913    }
1914
1915  fclose (fp);
1916  return "";
1917}
1918
1919
1920int isListed(char *listname, char *value)
1921{
1922char *next, word[32];
1923char *list = nvram_get(listname);
1924if (!list)
1925    return 0;
1926  foreach (word, list, next)
1927  {
1928  if (!strcmp(word,value))
1929    return 1;
1930  }
1931return 0;
1932}
1933
1934void addList(char *listname, char *value)
1935{
1936int listlen=0;
1937if (isListed(listname,value))
1938    return;
1939char *list = nvram_get(listname);
1940char *newlist;
1941if (list)
1942    listlen=strlen(list);
1943newlist = malloc(strlen(value+2)+listlen);
1944if (list)
1945sprintf(newlist,"%s %s",list,value);   
1946else
1947sprintf(newlist,"%s",value);   
1948nvram_set(listname,newlist);
1949free(newlist);
1950}
1951
1952struct dns_lists *
1953get_dns_list (void)
1954{
1955  char list[254];
1956  char *next, word[254];
1957  struct dns_lists *dns_list = NULL;
1958  int i, match = 0, altdns_index = 1;
1959
1960  dns_list = (struct dns_lists *) malloc (sizeof (struct dns_lists));
1961  memset (dns_list, 0, sizeof (struct dns_lists));
1962
1963  dns_list->num_servers = 0;
1964
1965  // nvram_safe_get("wan_dns") ==> Set by user
1966  // nvram_safe_get("wan_get_dns") ==> Get from DHCP, PPPoE or PPTP
1967  // The nvram_safe_get("wan_dns") priority is higher than nvram_safe_get("wan_get_dns")
1968  snprintf (list, sizeof (list), "%s %s %s", nvram_safe_get ("sv_localdns"),
1969            nvram_safe_get ("wan_dns"), nvram_safe_get ("wan_get_dns"));
1970  foreach (word, list, next)
1971  {
1972    if (strcmp (word, "0.0.0.0") && strcmp (word, ""))
1973      {
1974        match = 0;
1975        for (i = 0; i < dns_list->num_servers; i++)
1976          {                     // Skip same DNS
1977            if (!strcmp (dns_list->dns_server[i], word))
1978              match = 1;
1979          }
1980        if (!match)
1981          {
1982            snprintf (dns_list->dns_server[dns_list->num_servers],
1983                      sizeof (dns_list->dns_server[dns_list->num_servers]),
1984                      "%s", word);
1985            dns_list->num_servers++;
1986          }
1987      }
1988    if (dns_list->num_servers == 3)
1989      break;                    // We only need 3 DNS entries
1990  }
1991
1992  /* if < 3 DNS servers found, try to insert alternates */
1993  while (dns_list->num_servers < 3 && altdns_index <= 3)
1994    {
1995      char altdnsvar[32] = {
1996        0
1997      };
1998
1999      snprintf (altdnsvar, 31, "altdns%d", altdns_index);
2000
2001      if (strlen (nvram_safe_get (altdnsvar)) > 0)
2002        {
2003          snprintf (dns_list->dns_server[dns_list->num_servers],
2004                    sizeof (dns_list->dns_server[dns_list->num_servers]),
2005                    "%s", nvram_safe_get (altdnsvar));
2006          dns_list->num_servers++;
2007        }
2008      altdns_index++;
2009    }
2010  return dns_list;
2011}
2012
2013int
2014dns_to_resolv (void)
2015{
2016  FILE *fp_w;
2017  struct dns_lists *dns_list = NULL;
2018  int i = 0;
2019
2020  /* Save DNS to resolv.conf */
2021  if (!(fp_w = fopen (RESOLV_FILE, "w")))
2022    {
2023      perror (RESOLV_FILE);
2024      return errno;
2025    }
2026  if (nvram_invmatch ("wan_get_domain", ""))
2027    {
2028      fprintf (fp_w, "search %s\n", nvram_safe_get ("wan_get_domain"));
2029    }
2030  else if (nvram_invmatch ("wan_domain", ""))
2031    {
2032      fprintf (fp_w, "search %s\n", nvram_safe_get ("wan_domain"));
2033    }
2034  if (nvram_invmatch ("lan_domain", ""))
2035    {
2036      fprintf (fp_w, "search %s\n", nvram_safe_get ("lan_domain"));
2037    }
2038  if (nvram_match ("dnsmasq_enable", "1"))
2039    {
2040      fprintf (fp_w, "nameserver %s\n", nvram_get ("lan_ipaddr"));
2041      fclose (fp_w);
2042      if (!(fp_w = fopen (RESOLV_FORW, "w")))
2043        {
2044          perror (RESOLV_FORW);
2045          return errno;
2046        }
2047    }
2048
2049  dns_list = get_dns_list ();
2050
2051  for (i = 0; i < dns_list->num_servers; i++)
2052    fprintf (fp_w, "nameserver %s\n", dns_list->dns_server[i]);
2053
2054  /* Put a pseudo DNS IP to trigger Connect On Demand */
2055  if (dns_list->num_servers == 0 &&
2056      (nvram_match ("wan_proto", "pppoe") || nvram_match ("wan_proto", "pptp")
2057       || nvram_match ("wan_proto", "l2tp"))
2058      && nvram_match ("ppp_demand", "1"))
2059    fprintf (fp_w, "nameserver 1.1.1.1\n");
2060
2061  fclose (fp_w);
2062  if (dns_list)
2063    free (dns_list);
2064
2065  eval ("touch", "/tmp/hosts");
2066
2067  return 1;
2068}
2069
2070/* Example:
2071 * lan_ipaddr = 192.168.1.1
2072 * get_dns_ip("lan_ipaddr", 1); produces "168"
2073 */
2074int
2075get_single_ip (char *ipaddr, int which)
2076{
2077  int ip[4] = {
2078    0, 0, 0, 0
2079  };
2080  int ret;
2081
2082  ret = sscanf (ipaddr, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
2083
2084  return ip[which];
2085}
2086
2087char *
2088get_complete_lan_ip (char *ip)
2089{
2090  static char ipaddr[20];
2091
2092  int i[4];
2093
2094  if (sscanf
2095      (nvram_safe_get ("lan_ipaddr"), "%d.%d.%d.%d", &i[0], &i[1], &i[2],
2096       &i[3]) != 4)
2097    return "0.0.0.0";
2098
2099  snprintf (ipaddr, sizeof (ipaddr), "%d.%d.%d.%s", i[0], i[1], i[2], ip);
2100
2101  return ipaddr;
2102}
2103
2104char *
2105get_wan_face (void)
2106{
2107  static char localwanface[IFNAMSIZ];
2108/*  if (nvram_match ("pptpd_client_enable", "1"))
2109    {
2110        strncpy (localwanface, "ppp0", IFNAMSIZ);
2111        return localwanface;
2112    }*/
2113  if (nvram_match ("wan_proto", "pptp") || nvram_match ("wan_proto", "l2tp")
2114      || nvram_match ("wan_proto", "pppoe"))
2115    {
2116      if (nvram_match ("pppd_pppifname", ""))
2117        strncpy (localwanface, "ppp0", IFNAMSIZ);
2118      else
2119        strncpy (localwanface, nvram_safe_get ("pppd_pppifname"), IFNAMSIZ);
2120    }
2121#ifndef HAVE_MADWIFI
2122  else if (getSTA ())
2123    {
2124      strcpy (localwanface, getSTA ());
2125    }
2126#else
2127  else if (getSTA ())
2128    {
2129      if (nvram_match ("wifi_bonding", "1"))
2130        strcpy (localwanface, "bond0");
2131      else
2132        strcpy (localwanface, getSTA ());
2133    }
2134#endif
2135  else
2136    strncpy (localwanface, nvram_safe_get ("wan_ifname"), IFNAMSIZ);
2137
2138  return localwanface;
2139}
2140
2141int
2142get_ppp_pid (char *file)
2143{
2144  char buf[80];
2145  int pid = -1;
2146  if (file_to_buf (file, buf, sizeof (buf)))
2147    {
2148      char tmp[80], tmp1[80];
2149      snprintf (tmp, sizeof (tmp), "/var/run/%s.pid", buf);
2150      file_to_buf (tmp, tmp1, sizeof (tmp1));
2151      pid = atoi (tmp1);
2152    }
2153  return pid;
2154}
2155
2156/*
2157 =====================================================================================
2158                                by tallest
2159 =====================================================================================
2160 */
2161
2162
2163int
2164check_wan_link (int num)
2165{
2166  int wan_link = 0;
2167
2168  if (nvram_match ("wan_proto", "pptp")
2169      || nvram_match ("wan_proto", "l2tp")
2170      || nvram_match ("wan_proto", "pppoe")
2171      || nvram_match ("wan_proto", "heartbeat"))
2172    {
2173      FILE *fp;
2174      char filename[80];
2175      char *name;
2176
2177      if (num == 0)
2178        strcpy (filename, "/tmp/ppp/link");
2179      if ((fp = fopen (filename, "r")))
2180        {
2181          int pid = -1;
2182          fclose (fp);
2183          if (nvram_match ("wan_proto", "heartbeat"))
2184            {
2185              char buf[20];
2186              file_to_buf ("/tmp/ppp/link", buf, sizeof (buf));
2187              pid = atoi (buf);
2188            }
2189          else
2190            pid = get_ppp_pid (filename);
2191
2192          name = find_name_by_proc (pid);
2193          if (!strncmp (name, "pppoecd", 7) ||  // for PPPoE
2194              !strncmp (name, "pppd", 4) ||     // for PPTP
2195              !strncmp (name, "bpalogin", 8))   // for HeartBeat
2196            wan_link = 1;       //connect
2197          else
2198            {
2199              printf ("The %s had been died, remove %s\n",
2200                      nvram_safe_get ("wan_proto"), filename);
2201              wan_link = 0;     // For some reason, the pppoed had been died, by link file still exist.
2202              unlink (filename);
2203            }
2204        }
2205    }
2206  else
2207    {
2208      if (nvram_invmatch ("wan_ipaddr", "0.0.0.0"))
2209        wan_link = 1;
2210    }
2211
2212  return wan_link;
2213}
2214
2215int
2216get_int_len (int num)
2217{
2218  char buf[80];
2219
2220  snprintf (buf, sizeof (buf), "%d", num);
2221
2222  return strlen (buf);
2223}
2224
2225int
2226file_to_buf (char *path, char *buf, int len)
2227{
2228  FILE *fp;
2229
2230  memset (buf, 0, len);
2231
2232  if ((fp = fopen (path, "r")))
2233    {
2234      fgets (buf, len, fp);
2235      fclose (fp);
2236      return 1;
2237    }
2238
2239  return 0;
2240}
2241
2242int
2243buf_to_file (char *path, char *buf)
2244{
2245  FILE *fp;
2246
2247  if ((fp = fopen (path, "w")))
2248    {
2249      fprintf (fp, "%s", buf);
2250      fclose (fp);
2251      return 1;
2252    }
2253
2254  return 0;
2255}
2256
2257
2258#define READ_BUF_SIZE 254
2259/* from busybox find_pid_by_name.c */
2260pid_t *
2261find_pid_by_name (char *pidName)
2262{
2263  DIR *dir;
2264  struct dirent *next;
2265  pid_t *pidList = NULL;
2266  int i = 0;
2267
2268  dir = opendir ("/proc");
2269
2270  while ((next = readdir (dir)) != NULL)
2271    {
2272      FILE *status;
2273      char filename[READ_BUF_SIZE];
2274      char buffer[READ_BUF_SIZE];
2275      char name[READ_BUF_SIZE];
2276
2277      /* Must skip ".." since that is outside /proc */
2278      if (strcmp (next->d_name, "..") == 0)
2279        continue;
2280
2281      /* If it isn't a number, we don't want it */
2282      if (!isdigit (*next->d_name))
2283        continue;
2284
2285      sprintf (filename, "/proc/%s/status", next->d_name);
2286      if (!(status = fopen (filename, "r")))
2287        {
2288          continue;
2289        }
2290      if (fgets (buffer, READ_BUF_SIZE - 1, status) == NULL)
2291        {
2292          fclose (status);
2293          continue;
2294        }
2295      fclose (status);
2296
2297      /* Buffer should contain a string like "Name:   binary_name" */
2298      sscanf (buffer, "%*s %s", name);
2299      //printf("buffer=[%s] name=[%s]\n",buffer,name);
2300      if (strcmp (name, pidName) == 0)
2301        {
2302          pidList = realloc (pidList, sizeof (pid_t) * (i + 2));
2303          pidList[i++] = strtol (next->d_name, NULL, 0);
2304        }
2305    }
2306
2307  if (pidList)
2308    pidList[i] = 0;
2309  else
2310    {
2311      pidList = realloc (pidList, sizeof (pid_t));
2312      pidList[0] = -1;
2313    }
2314  return pidList;
2315
2316}
2317
2318/* Find first process pid with same name from ps command */
2319int
2320find_pid_by_ps (char *pidName)
2321{
2322  FILE *fp;
2323  int pid = -1;
2324  char line[254];
2325
2326  if ((fp = popen ("ps", "r")))
2327    {
2328      while (fgets (line, sizeof (line), fp) != NULL)
2329        {
2330          if (strstr (line, pidName))
2331            {
2332              sscanf (line, "%d", &pid);
2333              printf ("%s pid is %d\n", pidName, pid);
2334              break;
2335            }
2336        }
2337      pclose (fp);
2338    }
2339
2340  return pid;
2341}
2342
2343/* Find process name by pid from /proc directory */
2344char *
2345find_name_by_proc (int pid)
2346{
2347  FILE *fp;
2348  char line[254];
2349  char filename[80];
2350  static char name[80];
2351
2352  snprintf (filename, sizeof (filename), "/proc/%d/status", pid);
2353
2354  if ((fp = fopen (filename, "r")))
2355    {
2356      fgets (line, sizeof (line), fp);
2357      /* Buffer should contain a string like "Name:   binary_name" */
2358      sscanf (line, "%*s %s", name);
2359      fclose (fp);
2360      return name;
2361    }
2362
2363  return "";
2364}
2365
2366/* Find all process pid with same name from ps command */
2367int *
2368find_all_pid_by_ps (char *pidName)
2369{
2370  FILE *fp;
2371  int pid = -1;
2372  char line[254];
2373  int *pidList = NULL;
2374  int i = 0;
2375  cprintf ("Search for %s\n", pidName);
2376  if ((fp = popen ("ps", "r")))
2377    {
2378      while (fgets (line, sizeof (line), fp) != NULL)
2379        {
2380          if (strstr (line, pidName))
2381            {
2382              sscanf (line, "%d", &pid);
2383              cprintf ("%s pid is %d\n", pidName, pid);
2384              pidList = realloc (pidList, sizeof (int) * (i + 2));
2385              pidList[i++] = pid;
2386            }
2387        }
2388      pclose (fp);
2389    }
2390  if (pidList)
2391    pidList[i] = 0;
2392  else
2393    {
2394      pidList = realloc (pidList, sizeof (int));
2395      pidList[0] = -1;
2396    }
2397  cprintf ("Search done...\n");
2398
2399  return pidList;
2400}
2401
2402
2403int
2404count_processes (char *pidName)
2405{
2406  FILE *fp;
2407  char line[254];
2408  char safename[64];
2409  sprintf (safename, " %s ", pidName);
2410  char zombie[64];
2411  sprintf (zombie, "Z   [%s]", pidName);        // do not count zombies
2412  int i = 0;
2413  cprintf ("Search for %s\n", pidName);
2414  if ((fp = popen ("ps", "r")))
2415    {
2416      while (fgets (line, sizeof (line), fp) != NULL)
2417        {
2418          if (strstr (line, safename) && !strstr (line, zombie))
2419            {
2420              i++;
2421            }
2422        }
2423      pclose (fp);
2424    }
2425  cprintf ("Search done... %d\n", i);
2426
2427  return i;
2428}
2429
2430void
2431encode (char *buf, int len)
2432{
2433  int i;
2434  char ch;
2435
2436  for (i = 0; i < len; i++)
2437    {
2438      ch = (buf[i] & 0x03) << 6;
2439      buf[i] = (buf[i] >> 2);
2440      buf[i] &= 0x3f;
2441      buf[i] |= ch;
2442      buf[i] = ~buf[i];
2443    }
2444}
2445
2446void
2447decode (char *buf, int len)
2448{
2449  int i;
2450  char ch;
2451
2452  for (i = 0; i < len; i++)
2453    {
2454      ch = (buf[i] & 0xC0) >> 6;
2455      buf[i] = (buf[i] << 2) | ch;
2456      buf[i] = ~buf[i];
2457    }
2458}
2459
2460/*      v1.41.7 => 014107
2461 *      v1.2    => 0102
2462 */
2463long
2464convert_ver (char *ver)
2465{
2466  char buf[10];
2467  int v[3];
2468  int ret;
2469
2470  ret = sscanf (ver, "v%d.%d.%d", &v[0], &v[1], &v[2]);
2471
2472  if (ret == 2)
2473    {
2474      snprintf (buf, sizeof (buf), "%02d%02d", v[0], v[1]);
2475      return atol (buf);
2476    }
2477  else if (ret == 3)
2478    {
2479      snprintf (buf, sizeof (buf), "%02d%02d%02d", v[0], v[1], v[2]);
2480      return atol (buf);
2481    }
2482  else
2483    return -1;
2484}
2485
2486/* To avoid user to download old image that is not support intel flash to new hardware with intel flash.
2487 */
2488int
2489check_flash (void)
2490{
2491  // The V2 image can support intel flash completely, so we don't want to check.
2492  if (check_hw_type () == BCM4712_CHIP)
2493    return FALSE;
2494
2495  // The V1.X some images cann't support intel flash, so we want to avoid user to downgrade.
2496  if (nvram_match ("skip_amd_check", "1"))
2497    {
2498      if (strstr (nvram_safe_get ("flash_type"), "Intel")
2499          && nvram_invmatch ("skip_intel_check", "1"))
2500        return TRUE;
2501      else
2502        return FALSE;
2503    }
2504  else                          // Cann't downgrade to old firmware version, no matter AMD or Intel flash
2505    return TRUE;
2506}
2507
2508int
2509check_action (void)
2510{
2511  char buf[80] = "";
2512
2513  if (file_to_buf (ACTION_FILE, buf, sizeof (buf)))
2514    {
2515      if (!strcmp (buf, "ACT_TFTP_UPGRADE"))
2516        {
2517          fprintf (stderr, "Upgrading from tftp now ...\n");
2518          return ACT_TFTP_UPGRADE;
2519        }
2520#ifdef HAVE_HTTPS
2521      else if (!strcmp (buf, "ACT_WEBS_UPGRADE"))
2522        {
2523          fprintf (stderr, "Upgrading from web (https) now ...\n");
2524          return ACT_WEBS_UPGRADE;
2525        }
2526#endif
2527      else if (!strcmp (buf, "ACT_WEB_UPGRADE"))
2528        {
2529          fprintf (stderr, "Upgrading from web (http) now ...\n");
2530          return ACT_WEB_UPGRADE;
2531        }
2532      else if (!strcmp (buf, "ACT_SW_RESTORE"))
2533        {
2534          fprintf (stderr, "Receiving restore command from web ...\n");
2535          return ACT_SW_RESTORE;
2536        }
2537      else if (!strcmp (buf, "ACT_HW_RESTORE"))
2538        {
2539          fprintf (stderr,
2540                   "Receiving restore command from resetbutton ...\n");
2541          return ACT_HW_RESTORE;
2542        }
2543      else if (!strcmp (buf, "ACT_NVRAM_COMMIT"))
2544        {
2545          fprintf (stderr, "Committing nvram now ...\n");
2546          return ACT_NVRAM_COMMIT;
2547        }
2548      else if (!strcmp (buf, "ACT_ERASE_NVRAM"))
2549        {
2550          fprintf (stderr, "Erasing nvram now ...\n");
2551          return ACT_ERASE_NVRAM;
2552        }
2553    }
2554  //fprintf(stderr, "Waiting for upgrading....\n");
2555  return ACT_IDLE;
2556}
2557
2558int
2559check_now_boot (void)
2560{
2561  char *ver = nvram_safe_get ("pmon_ver");
2562  char *cfe = nvram_safe_get ("CFEver");
2563  // for 4712
2564  // The boot_ver value is lower v2.0 (no included)
2565  if (!strncmp (ver, "PMON", 4))
2566    {
2567      cprintf ("The boot is PMON\n");
2568      return PMON_BOOT;
2569    }
2570  // for 4712
2571  // The boot_ver value is higher v2.0 (included)
2572  else if (!strncmp (ver, "CFE", 3))
2573    {
2574      cprintf ("The boot is CFE\n");
2575      return CFE_BOOT;
2576    }
2577  else if (!strncmp (ver, "2", 1))
2578    {
2579      cprintf ("The boot is CFE %s\n", ver);
2580      return CFE_BOOT;
2581    }
2582  else if (!strncmp (cfe, "MotoWR", 6))
2583    {
2584      cprintf ("The boot is Motorola CFE\n");
2585      return CFE_BOOT;
2586    }
2587  else
2588    {
2589      cprintf ("The boot is UNKNOWN\n");
2590      return UNKNOWN_BOOT;
2591    }
2592}
2593
2594void
2595show_hw_type (int type)
2596{
2597  cprintf ("The chipset is ");
2598  if (type == BCM4702_CHIP)
2599    cprintf ("BCM4702\n");
2600  else if (type == BCM5325E_CHIP)
2601    cprintf ("BCM4712L + BCM5325E\n");
2602  else if (type == BCM5365_CHIP)
2603    cprintf ("BCM5365\n");
2604  else if (type == BCM5350_CHIP)
2605    cprintf ("BCM5350\n");
2606  else if (type == BCM4704_BCM5325F_CHIP)
2607    cprintf ("BCM4704 + BCM5325F\n");
2608  else if (type == BCM5352E_CHIP)
2609    cprintf ("BCM5352E\n");
2610  else if (type == BCM5354G_CHIP)
2611    cprintf ("BCM5354G\n");
2612  else if (type == BCM4712_CHIP)
2613    cprintf ("BCM4712 + ADMtek\n");
2614  else if (type == BCM4704_BCM5325F_EWC_CHIP)
2615    cprintf ("BCM4704 + BCM5325F for EWC\n");
2616  else if (type == BCM4705L_BCM5325E_EWC_CHIP)
2617    cprintf ("BCM4705L + BCM5325E for EWC\n");
2618  else if (type == BCM4705_BCM5397_EWC_CHIP)
2619    cprintf ("BCM4705 + BCM5397 for EWC\n");
2620  else if (type == BCM4705G_BCM5395S_EWC_CHIP)
2621    cprintf ("BCM4705G + BCM5395S for EWC\n");
2622  else if (type == BCM4704_BCM5325F_CHIP)
2623    cprintf ("BCM4704 + BCM5325F\n");
2624  else
2625    cprintf ("not defined\n");
2626
2627}
2628
2629int
2630check_hw_type (void)
2631{
2632
2633  char *boardtype = nvram_safe_get ("boardtype");
2634  uint boardflags = strtoul (nvram_safe_get ("boardflags"), NULL, 0);
2635  uint btype = strtoul (boardtype, NULL, 0);
2636  char *vlan0 = nvram_safe_get ("vlan0ports");
2637  char *vlan1 = nvram_safe_get ("vlan1ports");
2638
2639  if (!strncmp (boardtype, "bcm94710", 8))
2640    return BCM4702_CHIP;
2641  else if (btype == 0x0708 && !(boardflags & BFL_ENETADM))
2642    return BCM5325E_CHIP;
2643  else if (btype == 0x456 && getRouterBrand () == ROUTER_BELKIN_F5D7231)        //stupid Belkin!
2644    return BCM5352E_CHIP;
2645  else if (btype == 0x456)
2646    return BCM5350_CHIP;
2647  else if (!strncmp (boardtype, "bcm95365", 8))
2648    return BCM5365_CHIP;
2649  else if (btype == 0x048e)
2650    return BCM5354G_CHIP;
2651  else if (btype == 0x042f && !(boardflags & BFL_ENETADM))
2652    return BCM4704_BCM5325F_CHIP;
2653  else if (btype == 0x478 && strstr (vlan0, "5*"))      /* WRT300NV1.1 */
2654    return BCM4705L_BCM5325E_EWC_CHIP;
2655  else if ((btype == 0x478 && (strstr (vlan0, "8*") || strstr (vlan1, "8*"))) || nvram_match ("boot_hw_model", "WRT350N"))      /* WRT350N */
2656    return BCM4705_BCM5397_EWC_CHIP;
2657  else if (btype == 0x489 || nvram_match ("boot_hw_model", "WRT310N"))  /* WRT310N, temporal boardtype 0x478, wait for braodcom's txt file */
2658    return BCM4705G_BCM5395S_EWC_CHIP;
2659  else if (btype == 0x0467)
2660    return BCM5352E_CHIP;
2661  else if (btype == 0x0101 && !(boardflags & BFL_ENETADM))
2662    return BCM4712_BCM5325E_CHIP;
2663  else if ((btype == 0x0101 || btype == 0x0446) && (boardflags & BFL_ENETADM))  //0x446 is wap54g v2
2664    return BCM4712_CHIP;
2665  else if (btype == 0x0472 && !(boardflags & BFL_ENETADM))
2666    return BCM4704_BCM5325F_EWC_CHIP;
2667  else
2668    return NO_DEFINE_CHIP;
2669}
2670
2671int
2672is_exist (char *filename)
2673{
2674  FILE *fp;
2675
2676  if ((fp = fopen (filename, "r")))
2677    {
2678      fclose (fp);
2679      return 1;
2680    }
2681  return 0;
2682}
2683
2684int
2685ct_openlog (const char *ident, int option, int facility, char *log_name)
2686{
2687  int level = atoi (nvram_safe_get (log_name));
2688
2689  switch (level)
2690    {
2691    case CONSOLE_ONLY:
2692      break;
2693    }
2694  return level;
2695}
2696
2697
2698void
2699ct_syslog (int level, int enable, const char *fmt, ...)
2700{
2701  char buf[1000];
2702  va_list args;
2703
2704  va_start (args, fmt);
2705  vsnprintf (buf, sizeof (buf), fmt, args);
2706  va_end (args);
2707
2708  switch (enable)
2709    {
2710    case CONSOLE_ONLY:
2711      cprintf ("[%d] %s\n", getpid (), buf);    // print to console
2712      break;
2713    }
2714}
2715
2716void
2717ct_logger (int level, const char *fmt, ...)
2718{
2719}
2720
2721void
2722set_ip_forward (char c)
2723{
2724  FILE *fp;
2725
2726  if ((fp = fopen ("/proc/sys/net/ipv4/ip_forward", "r+")))
2727    {
2728      fputc (c, fp);
2729      fclose (fp);
2730    }
2731  else
2732    {
2733      perror ("/proc/sys/net/ipv4/ip_forward");
2734    }
2735}
2736
2737
2738static char *device_name[] = {
2739  "eth0", "qos0"
2740};
2741
2742char *
2743get_device_name (void)
2744{
2745  int i;
2746
2747  switch (check_hw_type ())
2748    {
2749    case BCM5325E_CHIP:
2750    case BCM5350_CHIP:
2751    case BCM5365_CHIP:
2752    case BCM4704_BCM5325F_CHIP:
2753    case BCM4704_BCM5325F_EWC_CHIP:
2754    case BCM5352E_CHIP:
2755    case BCM5354G_CHIP:
2756    case BCM4712_BCM5325E_CHIP:
2757    case BCM4705L_BCM5325E_EWC_CHIP:
2758      i = 0;
2759      break;
2760    case BCM4702_CHIP:
2761    case BCM4712_CHIP:
2762    default:
2763      i = 1;
2764      break;
2765    }
2766
2767  return device_name[i];
2768}
2769
2770char *
2771strncpyz (char *dest, char const *src, size_t size)
2772{
2773  if (!size--)
2774    return dest;
2775  strncpy (dest, src, size);
2776  dest[size] = 0;               /* Make sure the string is null terminated */
2777  return dest;
2778}
2779
2780static int
2781sockets_open (int domain, int type, int protocol)
2782{
2783  int fd = socket (domain, type, protocol);
2784
2785  if (fd < 0)
2786    cprintf ("sockets_open: no usable address was found.\n");
2787  return fd;
2788}
2789
2790int
2791sys_netdev_ioctl (int family, int socket, char *if_name, int cmd,
2792                  struct ifreq *ifr)
2793{
2794  int rc, s;
2795
2796  if ((s = socket) < 0)
2797    {
2798      if ((s = sockets_open (family, family == AF_PACKET ? SOCK_PACKET :
2799                             SOCK_DGRAM,
2800                             family == AF_PACKET ? htons (ETH_P_ALL) : 0)) <
2801          0)
2802        {
2803          cprintf ("sys_netdev_ioctl: failed\n");
2804          return -1;
2805        }
2806    }
2807  strncpyz (ifr->ifr_name, if_name, IFNAMSIZ);
2808  rc = ioctl (s, cmd, ifr);
2809  if (socket < 0)
2810    close (s);
2811  return rc;
2812}
2813
2814int
2815set_register_value (unsigned short port_addr, unsigned short option_content)
2816{
2817  struct ifreq ifr;
2818  struct mii_ioctl_data stats;
2819
2820  stats.phy_id = port_addr;
2821  stats.val_in = option_content;
2822
2823  ifr.ifr_data = (void *) &stats;
2824
2825  if (sys_netdev_ioctl (AF_INET, -1, get_device_name (), SIOCSMIIREG, &ifr) <
2826      0)
2827    return -1;
2828
2829  return 0;
2830}
2831
2832unsigned long
2833get_register_value (unsigned short id, unsigned short num)
2834{
2835  struct ifreq ifr;
2836  struct mii_ioctl_data stats;
2837
2838  stats.phy_id = id;
2839  stats.reg_num = num;
2840  stats.val_in = 0;
2841  stats.val_out = 0;
2842
2843  ifr.ifr_data = (void *) &stats;
2844
2845  sys_netdev_ioctl (AF_INET, -1, get_device_name (), SIOCGMIIREG, &ifr);
2846
2847  return ((stats.val_in << 16) | stats.val_out);
2848}
2849
2850
2851struct wl_assoc_mac *
2852get_wl_assoc_mac (int *c)
2853{
2854  FILE *fp;
2855  struct wl_assoc_mac *wlmac = NULL;
2856  int count;
2857  char line[80];
2858  char list[2][20];
2859
2860  wlmac = NULL;
2861  count = *c = 0;
2862
2863#ifdef HAVE_MSSID
2864  char assoccmd[4][32] = {
2865    "wl assoclist", "wl -i wl0.1 assoclist", "wl -i wl0.2 assoclist",
2866    "wl -i wl0.3 assoclist"
2867  };
2868  int ifcnt = 4;
2869#else
2870  char assoccmd[1][16] = {
2871    "wl assoclist"
2872  };
2873  int ifcnt = 1;
2874#endif
2875  int i;
2876  int gotit = 0;
2877//  fprintf(stderr,"assoclist\n");
2878
2879  for (i = 0; i < ifcnt; i++)
2880    {
2881      if (i)
2882        {
2883          char checkif[12];
2884          sprintf (checkif, "wl0.%d", i);
2885          if (!ifexists (checkif))
2886            break;
2887        }
2888      if ((fp = popen (assoccmd[i], "r")))
2889        {
2890          gotit = 1;
2891          while (fgets (line, sizeof (line), fp) != NULL)
2892            {
2893              strcpy (list[0], "");
2894              strcpy (list[1], "");
2895
2896              if (sscanf (line, "%s %s", list[0], list[1]) != 2)        // assoclist 00:11:22:33:44:55
2897                continue;
2898              if (strcmp (list[0], "assoclist"))
2899                continue;
2900
2901              wlmac =
2902                realloc (wlmac, sizeof (struct wl_assoc_mac) * (count + 1));
2903
2904              memset (&wlmac[count], 0, sizeof (struct wl_assoc_mac));
2905              strncpy (wlmac[count].mac, list[1], sizeof (wlmac[0].mac));
2906              count++;
2907            }
2908
2909          pclose (fp);
2910        }
2911    }
2912
2913  if (gotit)
2914    {
2915      //cprintf("Count of wl assoclist mac is %d\n", count);
2916      *c = count;
2917      return wlmac;
2918    }
2919  else
2920    return NULL;
2921}
2922
2923struct mtu_lists mtu_list[] = {
2924#ifdef BUFFALO_JP
2925  {
2926   "pppoe", "576", "1454"},
2927#else
2928  {
2929   "pppoe", "576", "1492"},
2930#endif
2931  {
2932   "pptp", "576", "1460"},
2933  {
2934   "l2tp", "576", "1460"},
2935  {
2936   "dhcp", "576", "1500"},
2937  {
2938   "static", "576", "1500"},
2939  {
2940   "heartbeat", "576", "1500"},
2941  {
2942   "default", "576", "1500"},   // The value must be at last
2943};
2944
2945struct mtu_lists *
2946get_mtu (char *proto)
2947{
2948  struct mtu_lists *v = NULL;
2949
2950  for (v = mtu_list; v < &mtu_list[STRUCT_LEN (mtu_list)]; v++)
2951    {
2952      if (!strcmp (proto, v->proto))
2953        return v;
2954    }
2955  return v;                     // Use default settings
2956}
2957
2958void
2959set_host_domain_name (void)
2960{
2961  char *wan_hostname = nvram_safe_get ("wan_hostname");
2962  char *wan_domain = nvram_safe_get ("wan_domain");
2963
2964  /* Allow you to use gethostname to get Host Name */
2965  /* If wan_hostname is blank then we do nothing, we leave to what it was set at boot */
2966  if (strlen (wan_hostname) > 0)
2967    sethostname (wan_hostname, strlen (wan_hostname));
2968
2969  /* Allow you to use getdomainname to get Domain Name */
2970  if (strlen (wan_domain) > 0 && strlen (wan_domain) <= 64)     //no more than 64
2971    setdomainname (wan_domain, strlen (wan_domain));
2972  else
2973    {
2974      char *wan_get_domain = nvram_safe_get ("wan_get_domain");
2975      setdomainname (wan_get_domain, strlen (wan_get_domain));
2976    }
2977}
2978
2979int
2980first_time (void)
2981{
2982  struct sysinfo info;
2983
2984  sysinfo (&info);
2985  if (info.uptime < 20L)
2986    return 1;
2987  return 0;
2988}
2989
2990int
2991check_vlan_support (void)
2992{
2993#if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || 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)
2994  return 0;
2995#else
2996
2997
2998  int brand = getRouterBrand ();
2999  switch (brand)
3000    {
3001#ifndef HAVE_BUFFALO
3002    case ROUTER_ASUS_WL500GD:
3003      return 1;
3004      break;
3005#endif
3006    case ROUTER_BUFFALO_WLAG54C:
3007    case ROUTER_BUFFALO_WLA2G54C:
3008#ifndef HAVE_BUFFALO
3009    case ROUTER_LINKSYS_WRT55AG:
3010    case ROUTER_MOTOROLA_V1:
3011    case ROUTER_MOTOROLA_WE800G:
3012    case ROUTER_WAP54G_V1:
3013    case ROUTER_SITECOM_WL105B:
3014    case ROUTER_SITECOM_WL111:
3015    case ROUTER_BUFFALO_WLI2_TX1_G54:
3016    case ROUTER_BUFFALO_WLI_TX4_G54HP:
3017    case ROUTER_BRCM4702_GENERIC:
3018    case ROUTER_ASUS_WL500G:
3019    case ROUTER_BELKIN_F5D7230_V2000:
3020#endif
3021      return 0;
3022      break;
3023    }
3024
3025  uint boardflags = strtoul (nvram_safe_get ("boardflags"), NULL, 0);
3026  if (boardflags & BFL_ENETVLAN)
3027    return 1;
3028
3029  if (nvram_match ("boardtype", "bcm94710dev")
3030      || nvram_match ("boardtype", "0x0101") || (boardflags & 0x0100))
3031    return 1;
3032  else
3033    return 0;
3034#endif
3035}
3036
3037#ifdef CDEBUG
3038int
3039coreleft (void)
3040{
3041  struct sysinfo info;
3042  sysinfo (&info);
3043  return info.freeram;
3044}
3045
3046int
3047mcoreleft (void)
3048{
3049  struct mallinfo minfo;
3050  minfo = mallinfo ();
3051  return minfo.uordblks;
3052  //int uordblks; /* total allocated space */
3053
3054}
3055#endif
3056
3057#define sin_addr(s) (((struct sockaddr_in *)(s))->sin_addr)
3058
3059//#define WDS_DEBUG 1
3060#undef WDS_DEBUG
3061#ifdef WDS_DEBUG
3062FILE *fp;
3063#endif
3064
3065
3066int
3067wds_dev_config (int dev, int up)
3068{
3069  char wds_var[32] = "";
3070  char wds_enable_var[32] = "";
3071  char wds_dev[32] = "";
3072  char *wds = (void *) 0;
3073  char wds_gw_var[32] = "";
3074  char *gw = (void *) 0;
3075  int s = -1;
3076  struct ifreq ifr;
3077
3078#ifdef WDS_DEBUG
3079  fp = fopen ("/tmp/.wds_debug.log", "a");
3080#endif
3081
3082  memset (&ifr, 0, sizeof (struct ifreq));
3083
3084  snprintf (wds_var, 31, "wl_wds%d", dev);
3085  snprintf (wds_enable_var, 31, "%s_enable", wds_var);
3086
3087  if ((wds = nvram_safe_get (wds_enable_var)) == NULL ||
3088      strcmp (wds, "0") == 0)
3089    return -1;
3090#ifdef HAVE_MSSID
3091  snprintf (wds_dev, 31, "wds0.%d", dev + 1);
3092#else
3093  snprintf (wds_dev, 31, "wds0.491%d", 50 + dev + 1);
3094#endif
3095  snprintf (ifr.ifr_name, IFNAMSIZ, wds_dev);
3096#ifdef WDS_DEBUG
3097  fprintf (fp, "opening kernelsocket\n");
3098#endif
3099  if ((s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
3100    return -1;
3101
3102  if (up)
3103    {
3104      char wds_hwaddr_var[32] = "";
3105      char wds_ip_var[32] = "";
3106      char wds_netmask_var[32] = "";
3107      char *wds_list = (void *) 0;
3108      char *hwaddr = (void *) 0;
3109      char *ip = (void *) 0;
3110      char *netmask = (void *) 0;
3111
3112#ifdef WDS_DEBUG
3113      fprintf (fp, "running up\n");
3114#endif
3115
3116      wds_list = nvram_safe_get ("wl0_wds");
3117      if (wds_list == (void *) 0 || strlen (wds_list) <= 0)
3118        return 0;
3119
3120      snprintf (wds_hwaddr_var, 31, "%s_hwaddr", wds_var);
3121      snprintf (wds_ip_var, 31, "%s_ipaddr", wds_var);
3122      snprintf (wds_netmask_var, 31, "%s_netmask", wds_var);
3123
3124      hwaddr = nvram_safe_get (wds_hwaddr_var);
3125      ip = nvram_safe_get (wds_ip_var);
3126      netmask = nvram_safe_get (wds_netmask_var);
3127
3128      if (!strstr (wds_list, hwaddr))
3129        {
3130          close (s);
3131          return -1;
3132        }
3133
3134#ifdef WDS_DEBUG
3135      fprintf (fp, "checking validity\n");
3136#endif
3137
3138      if (!sv_valid_hwaddr (hwaddr) || !sv_valid_ipaddr (ip)
3139          || !sv_valid_ipaddr (netmask))
3140        {
3141          close (s);
3142          return -1;
3143        }
3144
3145#ifdef WDS_DEBUG
3146      fprintf (fp, "valid mac %s ip %s nm %s\n", hwaddr, ip, netmask);
3147#endif
3148
3149      sysprintf ("ifconfig %s down", wds_dev);
3150
3151      sysprintf ("ifconfig %s %s netmask %s up", wds_dev, ip, netmask);
3152
3153      snprintf (wds_gw_var, 31, "%s_gw", wds_var);
3154      gw = nvram_safe_get (wds_gw_var);
3155      if (strcmp (gw, "0.0.0.0") != 0)
3156        {
3157          get_network (ip, netmask);
3158          route_del (wds_dev, 0, ip, gw, netmask);
3159          route_add (wds_dev, 0, ip, gw, netmask);
3160        }
3161
3162    }
3163  else
3164    {
3165#ifdef WDS_DEBUG
3166      fprintf (fp, "running down\n");
3167#endif
3168      sysprintf ("ifconfig %s down", wds_dev);
3169
3170    }
3171
3172#ifdef WDS_DEBUG
3173  fprintf (fp, "running ioctl\n");
3174  fclose (fp);
3175#endif
3176
3177  close (s);
3178
3179  return 0;
3180}
3181
3182
3183int
3184ishexit (char c)
3185{
3186
3187  if (strchr ("01234567890abcdefABCDEF", c) != (char *) 0)
3188    return 1;
3189
3190  return 0;
3191}
3192
3193
3194/* Example:
3195 * legal_hwaddr("00:11:22:33:44:aB"); return true;
3196 * legal_hwaddr("00:11:22:33:44:5"); return false;
3197 * legal_hwaddr("00:11:22:33:44:HH"); return false;
3198 */
3199int
3200sv_valid_hwaddr (char *value)
3201{
3202  unsigned int hwaddr[6];
3203  int tag = TRUE;
3204  int i, count;
3205
3206  /* Check for bad, multicast, broadcast, or null address */
3207  for (i = 0, count = 0; *(value + i); i++)
3208    {
3209      if (*(value + i) == ':')
3210        {
3211          if ((i + 1) % 3 != 0)
3212            {
3213              tag = FALSE;
3214              break;
3215            }
3216          count++;
3217        }
3218      else if (ishexit (*(value + i)))  /* one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F */
3219        continue;
3220      else
3221        {
3222          tag = FALSE;
3223          break;
3224        }
3225    }
3226
3227  if (!tag || i != 17 || count != 5)    /* must have 17's characters and 5's ':' */
3228    tag = FALSE;
3229  else if (sscanf (value, "%x:%x:%x:%x:%x:%x",
3230                   &hwaddr[0], &hwaddr[1], &hwaddr[2],
3231                   &hwaddr[3], &hwaddr[4], &hwaddr[5]) != 6)
3232    {
3233      tag = FALSE;
3234    }
3235  else
3236    tag = TRUE;
3237#ifdef WDS_DEBUG
3238  if (tag == FALSE)
3239    fprintf (fp, "failed valid_hwaddr\n");
3240#endif
3241
3242  return tag;
3243}
3244
3245
3246int
3247sv_valid_range (char *value, int low, int high)
3248{
3249  if (!isdigit (value[0]) || atoi (value) < low || atoi (value) > high)
3250    return FALSE;
3251  else
3252    return TRUE;
3253
3254}
3255
3256int
3257sv_valid_statics (char *value)
3258{
3259  char ip[16] = {
3260    0
3261  }, mac[18] =
3262  {
3263  0}, hostname[255] =
3264  {
3265  0}, *p = value;
3266
3267  if (NULL == value)
3268    return FALSE;
3269
3270  do
3271    {
3272      while (isspace (*p++) && p - value < strlen (value))
3273        ;
3274
3275      if (p - value >= strlen (value))
3276        return FALSE;
3277
3278      if (sscanf (p, "%15s%17s%254s", ip, mac, hostname) < 3)
3279        return FALSE;
3280
3281      if (!sv_valid_ipaddr (ip) || !sv_valid_hwaddr (mac)
3282          || strlen (hostname) <= 0)
3283        return FALSE;
3284
3285    }
3286  while ((p = strpbrk (p, "\n\r")) && p - value < strlen (value));
3287
3288  return TRUE;
3289}
3290
3291/* Example:
3292 * legal_ipaddr("192.168.1.1"); return true;
3293 * legal_ipaddr("192.168.1.1111"); return false;
3294 */
3295int
3296sv_valid_ipaddr (char *value)
3297{
3298  struct in_addr ipaddr;
3299  int ip[4], ret = 0;
3300
3301  ret = sscanf (value, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
3302
3303  if (ret != 4 || !inet_aton (value, &ipaddr))
3304    return FALSE;
3305  else
3306    return TRUE;
3307
3308}
3309
3310// note - network address returned in ipaddr
3311void
3312get_network (char *ipaddr, char *netmask)
3313{
3314  int ip[4], mask[4];
3315
3316  if (!ipaddr || !netmask)
3317    return;
3318
3319  sscanf (ipaddr, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
3320  sscanf (netmask, "%d.%d.%d.%d", &mask[0], &mask[1], &mask[2], &mask[3]);
3321
3322  ip[0] &= mask[0];
3323  ip[1] &= mask[1];
3324  ip[2] &= mask[2];
3325  ip[3] &= mask[3];
3326
3327  sprintf (ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
3328#ifdef WDS_DEBUG
3329  fprintf (fp, "get_network return %s\n", ipaddr);
3330#endif
3331
3332}
3333
3334// note - broadcast addr returned in ipaddr
3335void
3336get_broadcast (char *ipaddr, char *netmask)
3337{
3338  int ip2[4], mask2[4];
3339  unsigned char ip[4], mask[4];
3340  if (!ipaddr || !netmask)
3341    return;
3342
3343  sscanf (ipaddr, "%d.%d.%d.%d", &ip2[0], &ip2[1], &ip2[2], &ip2[3]);
3344  sscanf (netmask, "%d.%d.%d.%d", &mask2[0], &mask2[1], &mask2[2], &mask2[3]);
3345  int i = 0;
3346  for (i = 0; i < 4; i++)
3347    {
3348      ip[i] = ip2[i];
3349      mask[i] = mask2[i];
3350//      ip[i] = (ip[i] & mask[i]) | !mask[i];
3351      ip[i] = (ip[i] & mask[i]) | (0xff & ~mask[i]);
3352    }
3353
3354  sprintf (ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
3355#ifdef WDS_DEBUG
3356  fprintf (fp, "get_broadcast return %s\n", value);
3357#endif
3358
3359}
3360
3361/* note: copied from Broadcom code and put in shared via this file */
3362
3363int
3364route_manip (int cmd, char *name, int metric, char *dst, char *gateway,
3365             char *genmask)
3366{
3367  int s;
3368  struct rtentry rt;
3369
3370  //dprintf("cmd=[%d] name=[%s] ipaddr=[%s] netmask=[%s] gateway=[%s] metric=[%d]\n",cmd,name,dst,genmask,gateway,metric);
3371
3372  /* Open a raw socket to the kernel */
3373  if ((s = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
3374    goto err;
3375
3376  /* Fill in rtentry */
3377  memset (&rt, 0, sizeof (rt));
3378  if (dst)
3379    inet_aton (dst, &sin_addr (&rt.rt_dst));
3380  if (gateway)
3381    inet_aton (gateway, &sin_addr (&rt.rt_gateway));
3382  if (genmask)
3383    inet_aton (genmask, &sin_addr (&rt.rt_genmask));
3384  rt.rt_metric = metric;
3385  rt.rt_flags = RTF_UP;
3386  if (sin_addr (&rt.rt_gateway).s_addr)
3387    rt.rt_flags |= RTF_GATEWAY;
3388  if (sin_addr (&rt.rt_genmask).s_addr == INADDR_BROADCAST)
3389    rt.rt_flags |= RTF_HOST;
3390  rt.rt_dev = name;
3391
3392  /* Force address family to AF_INET */
3393  rt.rt_dst.sa_family = AF_INET;
3394  rt.rt_gateway.sa_family = AF_INET;
3395  rt.rt_genmask.sa_family = AF_INET;
3396
3397  if (ioctl (s, cmd, &rt) < 0)
3398    goto err;
3399
3400  close (s);
3401  return 0;
3402
3403err:close (s);
3404  perror (name);
3405  return errno;
3406}
3407
3408int
3409route_add (char *name, int metric, char *dst, char *gateway, char *genmask)
3410{
3411  return route_manip (SIOCADDRT, name, metric, dst, gateway, genmask);
3412}
3413
3414int
3415route_del (char *name, int metric, char *dst, char *gateway, char *genmask)
3416{
3417  return route_manip (SIOCDELRT, name, metric, dst, gateway, genmask);
3418}
3419
3420//#endif
3421
3422
3423#ifdef HAVE_MADWIFI
3424static char *stalist[] = {
3425  "ath0", "ath1", "ath2", "ath3", "ath4", "ath5", "ath6", "ath8", "ath9"
3426};
3427char *
3428getSTA (void)
3429{
3430
3431#ifdef HAVE_WAVESAT
3432  if (nvram_match ("ofdm_mode", "sta"))
3433    return "ofdm";
3434#endif
3435  int c = getifcount ("wifi");
3436  int i;
3437  for (i = 0; i < c; i++)
3438    {
3439      char mode[32];
3440      char netmode[32];
3441      sprintf (mode, "ath%d_mode", i);
3442      sprintf (netmode, "ath%d_net_mode", i);
3443      if (nvram_match (mode, "sta") && !nvram_match (netmode, "disabled"))
3444        {
3445          return stalist[i];
3446        }
3447
3448    }
3449  return NULL;
3450}
3451
3452char *
3453getWET (void)
3454{
3455#ifdef HAVE_WAVESAT
3456  if (nvram_match ("ofdm_mode", "bridge"))
3457    return "ofdm";
3458#endif
3459  int c = getifcount ("wifi");
3460  int i;
3461  for (i = 0; i < c; i++)
3462    {
3463      char mode[32];
3464      char netmode[32];
3465      sprintf (mode, "ath%d_mode", i);
3466      sprintf (netmode, "ath%d_net_mode", i);
3467      if (nvram_match (mode, "wet") && !nvram_match (netmode, "disabled"))
3468        {
3469          return stalist[i];
3470        }
3471
3472    }
3473  return NULL;
3474}
3475#else
3476char *
3477getSTA ()
3478{
3479  int c = get_wl_instances ();
3480  int i;
3481  for (i = 0; i < c; i++)
3482    {
3483      if (nvram_nmatch ("sta", "wl%d_mode", i)
3484          || nvram_nmatch ("apsta", "wl%d_mode", i))
3485        {
3486          if (!nvram_nmatch ("disabled", "wl%d_net_mode", i))
3487            return get_wl_instance_name (i);
3488//       else
3489//        return nvram_nget ("wl%d_ifname", i);
3490        }
3491
3492    }
3493  return NULL;
3494}
3495
3496char *
3497getWET ()
3498{
3499  int c = get_wl_instances ();
3500  int i;
3501  for (i = 0; i < c; i++)
3502    {
3503      if (nvram_nmatch ("wet", "wl%d_mode", i)
3504          || nvram_nmatch ("apstawet", "wl%d_mode", i))
3505        {
3506          if (!nvram_nmatch ("disabled", "wl%d_net_mode", i))
3507            return get_wl_instance_name (i);
3508//       else
3509//        return nvram_nget ("wl%d_ifname", i);
3510
3511        }
3512
3513    }
3514  return NULL;
3515}
3516
3517
3518#endif
3519
3520
3521int
3522ifexists (const char *ifname)
3523{
3524  return getifcount (ifname) > 0 ? 1 : 0;
3525}
3526
3527int
3528getifcount (const char *ifprefix)
3529{
3530/*  char devcall[128];
3531
3532  sprintf (devcall, "cat /proc/net/dev|grep \"%s\"|wc -l", ifprefix);
3533  FILE *in = popen (devcall, "rb");
3534  if (in == NULL)
3535    return 0;
3536  int count;
3537  fscanf (in, "%d", &count);
3538  pclose (in);
3539  return count;*/
3540  char *iflist = malloc (256);
3541  memset (iflist, 0, 256);
3542  int c = getIfList (iflist, ifprefix);
3543  free (iflist);
3544  return c;
3545}
3546
3547static void
3548skipline (FILE * in)
3549{
3550  while (1)
3551    {
3552      int c = getc (in);
3553      if (c == EOF)
3554        return;
3555      if (c == 0x0)
3556        return;
3557      if (c == 0xa)
3558        return;
3559    }
3560}
3561
3562//returns a physical interfacelist filtered by ifprefix. if ifprefix is NULL, all valid interfaces will be returned
3563int
3564getIfList (char *buffer, const char *ifprefix)
3565{
3566  FILE *in = fopen ("/proc/net/dev", "rb");
3567  char ifname[32];
3568//skip the first 2 lines
3569  skipline (in);
3570  skipline (in);
3571  int ifcount = 0;
3572  int count = 0;
3573  while (1)
3574    {
3575      int c = getc (in);
3576      if (c == EOF)
3577        {
3578          if (count)
3579            buffer[strlen (buffer) - 1] = 0;    //fixup last space
3580          fclose (in);
3581          return count;
3582        }
3583      if (c == 0)
3584        {
3585          if (count)
3586            buffer[strlen (buffer) - 1] = 0;    //fixup last space
3587          fclose (in);
3588          return count;
3589        }
3590      if (c == 0x20)
3591        continue;
3592      if (c == ':' || ifcount == 30)
3593        {
3594          ifname[ifcount++] = 0;
3595          int skip = 0;
3596          if (ifprefix)
3597            {
3598              if (strncmp (ifname, ifprefix, strlen (ifprefix)))
3599                {
3600                  skip = 1;
3601                }
3602            }
3603          else
3604            {
3605              if (!strncmp (ifname, "wifi", 4))
3606                skip = 1;
3607              if (!strncmp (ifname, "imq", 3))
3608                skip = 1;
3609              if (!strncmp (ifname, "lo", 2))
3610                skip = 1;
3611              if (!strncmp (ifname, "teql", 4))
3612                skip = 1;
3613              if (!strncmp (ifname, "gre", 3))
3614                skip = 1;
3615              if (!strncmp (ifname, "ppp", 3))
3616                skip = 1;
3617              if (!strncmp (ifname, "tun", 3))
3618                skip = 1;
3619              if (!strncmp (ifname, "tap", 3))
3620                skip = 1;
3621            }
3622          if (!skip)
3623            {
3624              strcat (buffer, ifname);
3625              strcat (buffer, " ");
3626              count++;
3627            }
3628          skip = 0;
3629          ifcount = 0;
3630          memset (ifname, 0, 32);
3631          skipline (in);
3632          continue;
3633        }
3634      if (ifcount < 30)
3635        ifname[ifcount++] = c;
3636    }
3637}
3638void
3639getIfLists (char *eths, int size)
3640{
3641  char eths2[256];
3642  memset (eths, 0, size);
3643  memset (eths2, 0, 256);
3644#ifdef HAVE_XSCALE
3645  getIfList (eths, "ixp");
3646  getIfList (eths2, "eth");
3647  sprintf (eths, "%s %s", eths, eths2);
3648#else
3649  getIfList (eths, "eth");
3650#endif
3651  memset (eths2, 0, 256);
3652  getIfList (eths2, "vlan");
3653  sprintf (eths, "%s %s", eths, eths2);
3654#ifdef HAVE_MADWIFI
3655  memset (eths2, 0, 256);
3656  getIfList (eths2, "ath");
3657  sprintf (eths, "%s %s", eths, eths2);
3658#else
3659  memset (eths2, 0, 256);
3660  getIfList (eths2, "wl");
3661  sprintf (eths, "%s %s", eths, eths2);
3662#endif
3663#ifdef HAVE_WAVESAT
3664  memset (eths2, 0, 256);
3665  getIfList (eths2, "ofdm");
3666  sprintf (eths, "%s %s", eths, eths2);
3667#endif
3668
3669}
3670
3671int
3672contains (const char *string, char value)
3673{
3674  if (string == NULL)
3675    return 0;
3676  int len = strlen (string);
3677  int i;
3678  for (i = 0; i < len; i++)
3679    {
3680      if (string[i] == value)
3681        return 1;
3682    }
3683  return 0;
3684}
3685
3686int
3687haswifi (void)
3688{
3689#ifdef HAVE_NOWIFI
3690  return 0;
3691#elif HAVE_MADWIFI
3692  return getifcount ("wifi") > 0 ? 1 : 0;
3693#else
3694  return 1;
3695#endif
3696}
3697
3698static uint32_t
3699str_to_addr (const char *addr)
3700{
3701  uint32_t split[4];
3702  uint32_t ip;
3703
3704  sscanf (addr, "%d.%d.%d.%d", &split[0], &split[1], &split[2], &split[3]);
3705
3706  ip = (split[0] << 24) | (split[1] << 16) | (split[2] << 8) | (split[3]);
3707
3708  return htonl (ip);
3709}
3710
3711void
3712getHostName (char *buf, char *ip)
3713{
3714  struct hostent *host;
3715  struct in_addr addr;
3716  res_init ();
3717  addr.s_addr = str_to_addr (ip);
3718  host = gethostbyaddr ((char *) &addr, 4, AF_INET);
3719  if (!host || !host->h_name)
3720    strcpy (buf, "unknown");
3721  else
3722    strcpy (buf, host->h_name);
3723}
3724
3725void
3726getinterfacelist (const char *ifprefix, char *buffer)
3727{
3728  int count = getifcount (ifprefix);
3729  int i;
3730  for (i = 0; i < count; i++)
3731    {
3732      char ifname[32];
3733      sprintf (ifname, "%s%d", ifprefix, i);
3734      strcat (buffer, ifname);
3735      if (i < count - 1)
3736        strcat (buffer, " ");
3737    }
3738}
3739
3740/*
3741 *     the following code was taken from:
3742 *
3743 *      Copyright (C) 2006 Jonathan Zarate
3744 *
3745 *      Licensed under GNU GPL v2 or later.     
3746 */
3747
3748int
3749f_exists (const char *path)     // note: anything but a directory
3750{
3751  struct stat st;
3752  return (stat (path, &st) == 0) && (!S_ISDIR (st.st_mode));
3753}
3754
3755int
3756f_read (const char *path, void *buffer, int max)
3757{
3758  int f;
3759  int n;
3760
3761  if ((f = open (path, O_RDONLY)) < 0)
3762    return -1;
3763  n = read (f, buffer, max);
3764  close (f);
3765  return n;
3766}
3767
3768
3769int
3770f_read_string (const char *path, char *buffer, int max)
3771{
3772  if (max <= 0)
3773    return -1;
3774  int n = f_read (path, buffer, max - 1);
3775  buffer[(n > 0) ? n : 0] = 0;
3776  return n;
3777}
3778
3779
3780int
3781wait_file_exists (const char *name, int max, int invert)
3782{
3783  while (max-- > 0)
3784    {
3785      if (f_exists (name) ^ invert)
3786        return 1;
3787      sleep (1);
3788    }
3789  return 0;
3790}
3791
3792char *
3793psname (int pid, char *buffer, int maxlen)
3794{
3795  char buf[512];
3796  char path[64];
3797  char *p;
3798
3799  if (maxlen <= 0)
3800    return NULL;
3801  *buffer = 0;
3802  sprintf (path, "/proc/%d/stat", pid);
3803  if ((f_read_string (path, buf, sizeof (buf)) > 4)
3804      && ((p = strrchr (buf, ')')) != NULL))
3805    {
3806      *p = 0;
3807      if (((p = strchr (buf, '(')) != NULL) && (atoi (buf) == pid))
3808        {
3809          strlcpy (buffer, p + 1, maxlen);
3810        }
3811    }
3812  return buffer;
3813}
3814
3815static int
3816_pidof (const char *name, pid_t ** pids)
3817{
3818  const char *p;
3819  char *e;
3820  DIR *dir;
3821  struct dirent *de;
3822  pid_t i;
3823  int count;
3824  char buf[256];
3825
3826  count = 0;
3827  *pids = NULL;
3828  if ((p = strchr (name, '/')) != NULL)
3829    name = p + 1;
3830  if ((dir = opendir ("/proc")) != NULL)
3831    {
3832      while ((de = readdir (dir)) != NULL)
3833        {
3834          i = strtol (de->d_name, &e, 10);
3835          if (*e != 0)
3836            continue;
3837          if (strcmp (name, psname (i, buf, sizeof (buf))) == 0)
3838            {
3839              if ((*pids =
3840                   realloc (*pids, sizeof (pid_t) * (count + 1))) == NULL)
3841                {
3842                  return -1;
3843                }
3844              (*pids)[count++] = i;
3845            }
3846        }
3847    }
3848  closedir (dir);
3849  return count;
3850}
3851
3852int
3853pidof (const char *name)
3854{
3855  pid_t *pids;
3856  pid_t p;
3857
3858  if (_pidof (name, &pids) > 0)
3859    {
3860      p = *pids;
3861      free (pids);
3862      return p;
3863    }
3864  return -1;
3865}
3866
3867int
3868killall (const char *name, int sig)
3869{
3870  pid_t *pids;
3871  int i;
3872  int r;
3873
3874  if ((i = _pidof (name, &pids)) > 0)
3875    {
3876      r = 0;
3877      do
3878        {
3879          r |= kill (pids[--i], sig);
3880        }
3881      while (i > 0);
3882      free (pids);
3883      return r;
3884    }
3885  return -2;
3886}
3887
3888int
3889isGrep (char *string, char *cmp)
3890{
3891  char devcall[128];
3892  int res;
3893  sprintf (devcall, "%s|grep \"%s\"|/bin/wc -l", string, cmp);
3894//system(devcall);
3895  FILE *in = popen (devcall, "rb");
3896  fscanf (in, "%d", &res);
3897  pclose (in);
3898  return res > 0 ? 1 : 0;
3899
3900}
3901
3902int
3903softkill (char *name)
3904{
3905  killall (name, SIGKILL);
3906  return 0;
3907}
3908static void
3909to64 (char *s, long v, int n)
3910{
3911
3912  unsigned char itoa64[] =
3913    "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
3914
3915  while (--n >= 0)
3916    {
3917      *s++ = itoa64[v & 0x3f];
3918      v >>= 6;
3919    }
3920}
3921
3922char *
3923zencrypt (char *passwd)
3924{
3925  char salt[6];
3926  struct timeval tv;
3927  char *crypt (const char *, const char *);
3928
3929  gettimeofday (&tv, 0);
3930
3931  to64 (&salt[0], random (), 3);
3932  to64 (&salt[3], tv.tv_usec, 3);
3933  salt[5] = '\0';
3934
3935  return crypt (passwd, salt);
3936}
3937
3938void
3939getLANMac (char *newmac)
3940{
3941  strcpy (newmac, nvram_safe_get ("et0macaddr"));
3942#ifndef HAVE_BUFFALO
3943
3944  if (nvram_match ("port_swap", "1"))
3945    {
3946      if (strlen (nvram_safe_get ("et1macaddr")) != 0)  //safe: maybe et1macaddr not there?
3947        {
3948          strcpy (newmac, nvram_safe_get ("et1macaddr"));
3949        }
3950      else
3951        {
3952          MAC_ADD (newmac);     //et0macaddr +1
3953        }
3954    }
3955#endif
3956  return;
3957}
3958
3959void
3960getWirelessMac (char *newmac)
3961{
3962#ifdef HAVE_BUFFALO
3963  strcpy (newmac, nvram_safe_get ("il0macaddr"));
3964#else
3965//      if (strlen(nvram_safe_get ("il0macaddr")) != 0)
3966//              {
3967//              strcpy (newmac, nvram_safe_get ("il0macaddr"));
3968//              }
3969//      else
3970  {
3971    if (nvram_match ("port_swap", "1"))
3972      {
3973        if (strlen (nvram_safe_get ("et1macaddr")) != 0)        //safe: maybe et1macaddr not there?
3974          {
3975            strcpy (newmac, nvram_safe_get ("et1macaddr"));
3976            MAC_ADD (newmac);   //et1macaddr +2
3977            MAC_ADD (newmac);
3978          }
3979        else
3980          {
3981            strcpy (newmac, nvram_safe_get ("et0macaddr"));
3982            MAC_ADD (newmac);   //et0macaddr +3
3983            MAC_ADD (newmac);
3984            MAC_ADD (newmac);
3985          }
3986      }
3987    else
3988      {
3989        strcpy (newmac, nvram_safe_get ("et0macaddr"));
3990        MAC_ADD (newmac);       //et0macaddr +2
3991        MAC_ADD (newmac);
3992      }
3993  }
3994#endif
3995  return;
3996}
3997
3998void
3999getWANMac (char *newmac)
4000{
4001  strcpy (newmac, nvram_safe_get ("et0macaddr"));
4002#ifndef HAVE_BUFFALO
4003  MAC_ADD (newmac);             //et0macaddr +1
4004
4005  if (nvram_match ("port_swap", "1"))
4006    {
4007      if (strlen (nvram_safe_get ("et1macaddr")) != 0)  //safe: maybe et1macaddr not there?
4008        {
4009          strcpy (newmac, nvram_safe_get ("et1macaddr"));
4010          MAC_ADD (newmac);     //et1macaddr +1                     
4011        }
4012      else
4013        {
4014          MAC_ADD (newmac);     //et0macaddr +2
4015        }
4016    }
4017#endif
4018  return;
4019}
4020
4021
4022
4023#ifdef HAVE_AQOS
4024
4025static char *
4026get_wshaper_dev (void)
4027{
4028  if (nvram_match ("wshaper_dev", "WAN"))
4029    return get_wan_face ();
4030  else
4031    return "br0";
4032}
4033
4034void
4035add_userip (char *ip, int idx, char *upstream, char *downstream)
4036{
4037  int base = 120 + idx;
4038  char up[32];
4039  char down[32];
4040  char ups[32];
4041  char downs[32];
4042  sprintf (up, "1:%d", base);
4043  sprintf (down, "1:%d", base + 1);
4044  sprintf (ups, "%skbit", upstream);
4045  sprintf (downs, "%skbit", downstream);
4046  if (nvram_match ("qos_type", "0"))
4047    {
4048      eval ("tc", "class", "add", "dev", get_wshaper_dev (), "parent", "1:",
4049            "classid", up, "htb", "rate", ups, "ceil", ups);
4050      eval ("tc", "filter", "add", "dev", get_wshaper_dev (), "parent", "1:",
4051            "protocol", "ip", "prio", "1", "u32", "match", "ip", "src", ip,
4052            "flowid", up);
4053      eval ("tc", "class", "add", "dev", "imq0", "parent", "1:", "classid",
4054            down, "htb", "rate", downs, "ceil", downs);
4055      eval ("tc", "filter", "add", "dev", "imq0", "parent", "1:", "protocol",
4056            "ip", "prio", "1", "u32", "match", "ip", "dst", ip, "flowid",
4057            down);
4058    }
4059  else
4060    {
4061      eval ("tc", "class", "add", "dev", get_wshaper_dev (), "parent", "1:",
4062            "classid", up, "htb", "rate", ups, "ceil", ups);
4063      eval ("tc", "filter", "add", "dev", get_wshaper_dev (), "parent", "1:",
4064            "protocol", "ip", "prio", "1", "u32", "match", "ip", "src", ip,
4065            "flowid", up);
4066      eval ("tc", "class", "add", "dev", "imq0", "parent", "1:", "classid",
4067            down, "htb", "rate", downs, "ceil", downs);
4068      eval ("tc", "filter", "add", "dev", "imq0", "parent", "1:", "protocol",
4069            "ip", "prio", "1", "u32", "match", "ip", "dst", ip, "flowid",
4070            down);
4071    }
4072
4073}
4074
4075void
4076add_usermac (char *mac, int idx, char *upstream, char *downstream)
4077{
4078  unsigned char octet[6];
4079  ether_atoe (mac, octet);
4080
4081  int base = 120 + idx;
4082  char up[32];
4083  char down[32];
4084  char ups[32];
4085  char downs[32];
4086  char oct2[32];
4087  char oct4[32];
4088  char doct2[32];
4089  char doct4[32];
4090  sprintf (up, "1:%d", base);
4091  sprintf (down, "1:%d", base + 1);
4092  sprintf (ups, "%skbit", upstream);
4093  sprintf (downs, "%skbit", downstream);
4094
4095  sprintf (oct2, "%X%X", octet[4], octet[5]);
4096  sprintf (oct4, "%X%X%X%X", octet[0], octet[1], octet[2], octet[3]);
4097
4098  sprintf (doct4, "%X%X%X%X", octet[2], octet[3], octet[4], octet[5]);
4099  sprintf (doct2, "%X%X", octet[0], octet[1]);
4100
4101  if (nvram_match ("qos_type", "0"))
4102    {
4103      eval ("tc", "class", "add", "dev", get_wshaper_dev (), "parent", "1:",
4104            "classid", up, "htb", "rate", ups, "ceil", ups);
4105      eval ("tc", "filter", "add", "dev", get_wshaper_dev (), "parent", "1:",
4106            "protocol", "ip", "prio", "1", "u32", "match", "u16", "0x0800",
4107            "0xFFFF", "at", "-2", "match", "u16", oct2, "0xFFFF", "at", "-4",
4108            "match", "u32", oct4, "0xFFFFFFFF", "at", "-8", "flowid", up);
4109      eval ("tc", "class", "add", "dev", "imq0", "parent", "1:", "classid",
4110            down, "htb", "rate", downs, "ceil", downs);
4111      eval ("tc", "filter", "add", "dev", "imq0", "parent", "1:", "protocol",
4112            "ip", "prio", "1", "u32", "match", "u16", "0x0800", "0xFFFF",
4113            "at", "-2", "match", "u32", doct4, "0xFFFFFFFF", "at", "-12",
4114            "match", "u16", doct2, "0xFFFF", "at", "-14", "flowid", down);
4115    }
4116  else
4117    {
4118      eval ("tc", "class", "add", "dev", get_wshaper_dev (), "parent", "1:",
4119            "classid", up, "htb", "rate", ups, "ceil", ups);
4120      eval ("tc", "filter", "add", "dev", get_wshaper_dev (), "parent", "1:",
4121            "protocol", "ip", "prio", "1", "u32", "match", "u16", "0x0800",
4122            "0xFFFF", "at", "-2", "match", "u16", oct2, "0xFFFF", "at", "-4",
4123            "match", "u32", oct4, "0xFFFFFFFF", "at", "-8", "flowid", up);
4124      eval ("tc", "class", "add", "dev", "imq0", "parent", "1:", "classid",
4125            down, "htb", "rate", downs, "ceil", downs);
4126      eval ("tc", "filter", "add", "dev", "imq0", "parent", "1:", "protocol",
4127            "ip", "prio", "1", "u32", "match", "u16", "0x0800", "0xFFFF",
4128            "at", "-2", "match", "u32", doct4, "0xFFFFFFFF", "at", "-12",
4129            "match", "u16", doct2, "0xFFFF", "at", "-14", "flowid", down);
4130    }
4131
4132}
4133
4134
4135#endif
4136
4137
4138
4139#ifdef HAVE_X86
4140
4141static int fd;
4142
4143void
4144SetEnvironment ()
4145{
4146  system ("stty ispeed 2400 < /dev/tts/1");
4147  system ("stty raw < /dev/tts/1");
4148}
4149
4150int Cmd = 254;                  /* EZIO Command */
4151int cls = 1;                    /* Clear screen */
4152void
4153Cls ()
4154{
4155  write (fd, &Cmd, 1);
4156  write (fd, &cls, 1);
4157}
4158
4159int init = 0x28;
4160void
4161Init ()
4162{
4163  write (fd, &Cmd, 1);
4164  write (fd, &init, 1);
4165}
4166
4167int stopsend = 0x37;
4168void
4169StopSend ()
4170{
4171  write (fd, &Cmd, 1);
4172  write (fd, &init, 1);
4173}
4174
4175int home = 2;                   /* Home cursor */
4176void
4177Home ()
4178{
4179  write (fd, &Cmd, 1);
4180  write (fd, &home, 1);
4181}
4182
4183int readkey = 6;                /* Read key */
4184void
4185ReadKey ()
4186{
4187  write (fd, &Cmd, 1);
4188  write (fd, &readkey, 1);
4189}
4190
4191int blank = 8;                  /* Blank display */
4192void
4193Blank ()
4194{
4195  write (fd, &Cmd, 1);
4196  write (fd, &blank, 1);
4197}
4198
4199int hide = 12;                  /* Hide cursor & display blanked characters */
4200void
4201Hide ()
4202{
4203  write (fd, &Cmd, 1);
4204  write (fd, &hide, 1);
4205}
4206
4207int turn = 13;                  /* Turn On (blinking block cursor) */
4208void
4209TurnOn ()
4210{
4211  write (fd, &Cmd, 1);
4212  write (fd, &turn, 1);
4213}
4214
4215int show = 14;                  /* Show underline cursor */
4216void
4217Show ()
4218{
4219  write (fd, &Cmd, 1);
4220  write (fd, &show, 1);
4221}
4222
4223int movel = 16;                 /* Move cursor 1 character left */
4224void
4225MoveL ()
4226{
4227  write (fd, &Cmd, 1);
4228  write (fd, &movel, 1);
4229}
4230
4231int mover = 20;                 /* Move cursor 1 character right */
4232void
4233MoveR ()
4234{
4235  write (fd, &Cmd, 1);
4236  write (fd, &mover, 1);
4237}
4238
4239int scl = 24;                   /* Scroll cursor 1 character left */
4240void
4241ScrollL ()
4242{
4243  write (fd, &Cmd, 1);
4244  write (fd, &scl, 1);
4245}
4246
4247int scr = 28;                   /* Scroll cursor 1 character right */
4248void
4249ScrollR ()
4250{
4251  write (fd, &Cmd, 1);
4252  write (fd, &scr, 1);
4253}
4254
4255int setdis = 64;                /* Command */
4256void
4257SetDis ()
4258{
4259  write (fd, &Cmd, 1);
4260  write (fd, &setdis, 1);
4261
4262}
4263
4264
4265int a, b;
4266void
4267ShowMessage (char *str1, char *str2)
4268{
4269  char nul[] = "                                       ";
4270  a = strlen (str1);
4271  b = 40 - a;
4272  write (fd, str1, a);
4273  write (fd, nul, b);
4274  write (fd, str2, strlen (str2));
4275}
4276
4277void
4278initlcd ()
4279{
4280
4281  fd = open ("/dev/tts/1", O_RDWR);
4282                                  /** Open Serial port (COM2) */
4283  if (fd > 0)
4284    {
4285      close (fd);
4286      SetEnvironment ();        /* Set RAW mode */
4287      fd = open ("/dev/tts/1", O_RDWR);
4288      Init ();                  /* Initialize EZIO twice */
4289      Init ();
4290
4291      Cls ();                   /* Clear screen */
4292    }
4293  close (fd);
4294}
4295
4296void
4297lcdmessage (char *message)
4298{
4299  fd = open ("/dev/tts/1", O_RDWR);/** Open Serial port (COM2) */
4300
4301  if (fd > 0)
4302    {
4303      Init ();                  /* Initialize EZIO twice */
4304      Init ();
4305      SetDis ();
4306      Cls ();
4307      Home ();
4308      ShowMessage ("State", message);
4309      close (fd);
4310    }
4311}
4312void
4313lcdmessaged (char *dual, char *message)
4314{
4315
4316  fd = open ("/dev/tts/1", O_RDWR);
4317                                  /** Open Serial port (COM2) */
4318
4319  if (fd > 0)
4320    {
4321      Init ();                  /* Initialize EZIO twice */
4322      Init ();
4323      SetDis ();
4324      Cls ();                   /* Clear screen */
4325      Home ();
4326      ShowMessage (dual, message);
4327      close (fd);
4328    }
4329}
4330
4331
4332#endif
4333
4334
4335int
4336getmask (char *nmask)
4337{
4338
4339  int loopmask = 0;
4340  int ip[4] = {
4341    0, 0, 0, 0
4342  };
4343
4344  sscanf (nmask, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
4345
4346  int n = 8;
4347
4348  for (--n; n >= 0; --n)        //test all 4 bytes in one pass
4349    {
4350      if (ip[0] & 1 << n)
4351        loopmask++;
4352      if (ip[1] & 1 << n)
4353        loopmask++;
4354      if (ip[2] & 1 << n)
4355        loopmask++;
4356      if (ip[3] & 1 << n)
4357        loopmask++;
4358    }
4359  return loopmask;
4360}
4361
4362int
4363doMultiCast (void)
4364{
4365  char name[80], *next;
4366  int ifcount = 0;
4367  if (nvram_match ("wan_proto", "disabled"))
4368    return 0;
4369  if (nvram_match ("block_multicast", "0"))
4370    {
4371      ifcount++;
4372    }
4373  foreach (name, nvram_safe_get ("lan_ifnames"), next)
4374  {
4375    if (nvram_nmatch ("1", "%s_multicast", name)
4376        && nvram_nmatch ("0", "%s_bridged", name))
4377      {
4378        ifcount++;
4379      }
4380  }
4381  return ifcount;
4382}
4383
4384int
4385getMTD (char *name)
4386{
4387  char buf[128];
4388  int device;
4389  sprintf (buf, "cat /proc/mtd|grep \"%s\"", name);
4390  FILE *fp = popen (buf, "rb");
4391  fscanf (fp, "%s", &buf[0]);
4392  device = buf[3] - '0';
4393  pclose (fp);
4394  return device;
4395}
4396
4397static int
4398sockaddr_to_dotted (struct sockaddr *saddr, char *buf)
4399{
4400  buf[0] = '\0';
4401  if (saddr->sa_family == AF_INET)
4402    {
4403      inet_ntop (AF_INET, &((struct sockaddr_in *) saddr)->sin_addr, buf,
4404                 128);
4405      return 0;
4406    }
4407  if (saddr->sa_family == AF_INET6)
4408    {
4409      inet_ntop (AF_INET6, &((struct sockaddr_in6 *) saddr)->sin6_addr, buf,
4410                 128);
4411      return 0;
4412    }
4413  return -1;
4414}
4415
4416void
4417getIPFromName (char *name, char *ip)
4418{
4419  struct addrinfo *result = NULL;
4420  int rc;
4421  struct addrinfo hint;
4422  memset (&hint, 0, sizeof (hint));
4423  hint.ai_socktype = SOCK_STREAM;
4424  rc = getaddrinfo (name, NULL, &hint, &result);
4425  if (!result)                  //give it a second try
4426    rc = getaddrinfo (name, NULL, &hint, &result);
4427
4428  if (result)
4429    {
4430      sockaddr_to_dotted (result->ai_addr, ip);
4431    }
4432  else
4433    sprintf (ip, "0.0.0.0");
4434}
4435
4436/* Example:
4437 * legal_ip_netmask("192.168.1.1","255.255.255.0","192.168.1.100"); return true;
4438 * legal_ip_netmask("192.168.1.1","255.255.255.0","192.168.2.100"); return false;
4439 */
4440int
4441legal_ip_netmask (char *sip, char *smask, char *dip)
4442{
4443  struct in_addr ipaddr, netaddr, netmask;
4444  int tag;
4445
4446  inet_aton (nvram_safe_get (sip), &netaddr);
4447  inet_aton (nvram_safe_get (smask), &netmask);
4448  inet_aton (dip, &ipaddr);
4449
4450  netaddr.s_addr &= netmask.s_addr;
4451
4452  if (netaddr.s_addr != (ipaddr.s_addr & netmask.s_addr))
4453    tag = FALSE;
4454  else
4455    tag = TRUE;
4456
4457
4458  return tag;
4459}
4460
4461/* Example:
4462 * ISDIGIT("", 0); return true;
4463 * ISDIGIT("", 1); return false;
4464 * ISDIGIT("123", 1); return true;
4465 */
4466int
4467ISDIGIT (char *value, int flag)
4468{
4469  int i, tag = TRUE;
4470
4471
4472  if (!strcmp (value, ""))
4473    {
4474      if (flag)
4475        return 0;               // null
4476      else
4477        return 1;
4478    }
4479
4480  for (i = 0; *(value + i); i++)
4481    {
4482      if (!isdigit (*(value + i)))
4483        {
4484          tag = FALSE;
4485          break;
4486        }
4487    }
4488  return tag;
4489}
4490
4491
4492void
4493addAction (char *action)
4494{
4495  char *actionstack = "";
4496  char *next;
4497  char service[80];
4498  char *services = nvram_safe_get ("action_service");
4499  foreach (service, services, next)
4500  {
4501    if (!strcmp (service, action))
4502      {
4503        return;
4504      }
4505  }
4506  if (strlen (services) > 0)
4507    {
4508      actionstack = malloc (strlen (services) + strlen (action) + 2);
4509      memset (actionstack, 0, strlen (services) + strlen (action) + 2);
4510      strcpy (actionstack, action);
4511      strcat (actionstack, " ");
4512      strcat (actionstack, nvram_safe_get ("action_service"));
4513      nvram_set ("action_service", actionstack);
4514      free (actionstack);
4515    }
4516  else
4517    {
4518      nvram_set ("action_service", action);
4519    }
4520
4521
4522}
4523
4524void
4525rep (char *in, char from, char to)
4526{
4527  int i;
4528  int slen = strlen (in);
4529  for (i = 0; i < slen; i++)
4530    if (in[i] == from)
4531      in[i] = to;
4532
4533}
4534
4535#include "l7protocols.h"
4536void
4537get_filter_services (char *services)
4538{
4539
4540  l7filters *filters = filters_list;
4541  int namelen, protolen;
4542  char temp[128] = "";
4543
4544  while (filters->name)         //add l7 and p2p filters
4545    {
4546      namelen = strlen (filters->name);
4547      protolen = strlen (filters->protocol);
4548
4549      sprintf (temp, "$NAME:%03d:%s$PROT:%03d:%s$PORT:003:0:0<&nbsp;>",
4550               namelen, filters->name, protolen, filters->protocol);
4551      strcat (services, temp);
4552      filters++;
4553    }
4554
4555  strcat (services, nvram_safe_get ("filter_services"));        //this is user defined filters
4556  strcat (services, nvram_safe_get ("filter_services_1"));
4557
4558  return;
4559}
4560
4561
4562int
4563endswith (char *str, char *cmp)
4564{
4565  int cmp_len, str_len, i;
4566  if (cmp == NULL)
4567    return 0;
4568  if (str == NULL)
4569    return 0;
4570  cmp_len = strlen (cmp);
4571  str_len = strlen (str);
4572  if (cmp_len > str_len)
4573    return (0);
4574  for (i = 0; i < cmp_len; i++)
4575    {
4576      if (str[(str_len - 1) - i] != cmp[(cmp_len - 1) - i])
4577        return (0);
4578    }
4579  return (1);
4580}
Note: See TracBrowser for help on using the repository browser.