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

Last change on this file since 8945 was 8945, checked in by eko, 5 years ago

daysformonth helper function

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