root/src/router/libutils/utils.c

Revision 12344, 77.0 kB (checked in by eko, 5 months ago)

Buffalo WHR-G125 leds support. Revert to original firmware Buffalo is now available here: http://www.dd-wrt.com/dd-wrtv2/downloads/others/eko/Buffalo/WHR-G125%20revert/WHR-G125-revert-to-original.bin

Line 
1 // #define CDEBUG
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <net/if.h>
8 #include <dirent.h>
9 #include <unistd.h>
10 #include <ctype.h>
11 #include <syslog.h>
12 #include <sys/socket.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <netinet/in.h>
16 #include <stdarg.h>
17 #include <sys/ioctl.h>
18 #include <sys/sysinfo.h>
19 #include <arpa/inet.h>
20 #include <netdb.h>
21 #include <resolv.h>
22 #include <signal.h>
23
24 #include <utils.h>
25 #include <wlutils.h>
26 #include <bcmnvram.h>
27 #include <shutils.h>
28 #include <cy_conf.h>
29 #include <code_pattern.h>
30 #include <bcmdevs.h>
31 #include <net/route.h>
32 #include <cy_conf.h>
33 #include <bcmdevs.h>
34 #include <linux/if_ether.h>
35 // #include <linux/mii.h>
36 #include <linux/sockios.h>
37 #include <cymac.h>
38 #include <broadcom.h>
39 #define SIOCGMIIREG     0x8948  /* Read MII PHY register.  */
40 #define SIOCSMIIREG     0x8949  /* Write MII PHY register.  */
41
42 struct mii_ioctl_data {
43         unsigned short phy_id;
44         unsigned short reg_num;
45         unsigned short val_in;
46         unsigned short val_out;
47 };
48
49 #ifdef HAVE_FONERA
50 static void inline getBoardMAC(char *mac)
51 {
52         // 102
53         int i;
54         char op[32];
55         unsigned char data[256];
56         FILE *in;
57
58         sprintf(op, "/dev/mtdblock/%d", getMTD("board_config"));
59         in = fopen(op, "rb");
60         if (in == NULL)
61                 return;
62         fread(data, 256, 1, in);
63         fclose(in);
64         sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", data[102] & 0xff,
65                 data[103] & 0xff, data[104] & 0xff, data[105] & 0xff,
66                 data[106] & 0xff, data[107] & 0xff);
67 }
68 #endif
69
70 int count_processes(char *pidName)
71 {
72         FILE *fp;
73         char line[254];
74         char safename[64];
75
76         sprintf(safename, " %s ", pidName);
77         char zombie[64];
78
79         sprintf(zombie, "Z   [%s]", pidName);   // do not count zombies
80         int i = 0;
81
82         cprintf("Search for %s\n", pidName);
83         if ((fp = popen("ps", "r"))) {
84                 while (fgets(line, sizeof(line), fp) != NULL) {
85                         if (strstr(line, safename) && !strstr(line, zombie)) {
86                                 i++;
87                         }
88                 }
89                 pclose(fp);
90         }
91         cprintf("Search done... %d\n", i);
92
93         return i;
94 }
95
96 /*
97  * This function returns the number of days for the given month in the given
98  * year
99  */
100 unsigned int daysformonth(unsigned int month, unsigned int year)
101 {
102         return (30 + (((month & 9) == 8) || ((month & 9) == 1)) -
103                 (month == 2) - (!(((year % 4) == 0)
104                                   && (((year % 100) != 0)
105                                       || ((year % 400) == 0)))
106                                 && (month == 2)));
107 }
108
109 #ifdef HAVE_AQOS
110
111 static char *get_wshaper_dev(void)
112 {
113         if (nvram_match("wshaper_dev", "WAN"))
114                 return get_wan_face();
115         else
116                 return "br0";
117 }
118
119 void add_userip(char *ip, int idx, char *upstream, char *downstream)
120 {
121         int base = 120 + idx;
122         char up[32];
123         char down[32];
124         char ups[32];
125         char downs[32];
126
127         if (nvram_match("qos_type", "1")) {
128                 sprintf(up, "1:%d", base);
129                 sprintf(down, "1:%d", base + 1);
130                 sprintf(ups, "%skbit", upstream);
131                 sprintf(downs, "%skbit", downstream);
132                 sysprintf
133                     ("tc class add dev %s parent 1:1 classid 1:%d htb rate %skbit ceil %skbit",
134                      "imq0", base, upstream, upstream);
135                 sysprintf
136                     ("tc qdisc add dev %s parent 1:%d sfq quantum 1514b perturb 15",
137                      "imq0", base);
138                 sysprintf
139                     ("tc filter add dev %s protocol ip parent 1:0 prio 1 u32 match ip src %s flowid 1:%d",
140                      "imq0", ip, base);
141
142                 sysprintf
143                     ("tc class add dev imq0 parent 1:1 classid 1:%d htb rate %skbit ceil %skbit",
144                      base + 1, downstream, downstream);
145                 sysprintf
146                     ("tc qdisc add dev imq0 parent 1:%d sfq quantum 1514b perturb 15",
147                      base + 1, base + 1);
148                 sysprintf
149                     ("tc filter add dev imq0 protocol ip parent 1:0 prio 1 u32 match ip dst %s flowid 1:%d",
150                      ip, base + 1);
151
152         } else {
153                 sprintf(up, "1:%d", base);
154                 sprintf(down, "1:%d", base + 1);
155                 sprintf(ups, "%skbit", upstream);
156                 sprintf(downs, "%skbit", downstream);
157                 sysprintf
158                     ("tc class add dev %s parent 1:2 classid 1:%d htb rate %skbit ceil %skbit",
159                      "imq0", base, upstream, upstream);
160                 sysprintf
161                     ("tc qdisc add dev %s parent 1:%d sfq quantum 1514b perturb 15",
162                      "imq0", base);
163                 sysprintf
164                     ("tc filter add dev %s protocol ip parent 1:0 prio 1 u32 match ip src %s flowid 1:%d",
165                      "imq0", ip, base);
166
167                 sysprintf
168                     ("tc class add dev imq0 parent 1:2 classid 1:%d htb rate %skbit ceil %skbit",
169                      base + 1, downstream, downstream);
170                 sysprintf
171                     ("tc qdisc add dev imq0 parent 1:%d sfq quantum 1514b perturb 15",
172                      base + 1, base + 1);
173                 sysprintf
174                     ("tc filter add dev imq0 protocol ip parent 1:0 prio 1 u32 match ip dst %s flowid 1:%d",
175                      ip, base + 1);
176         }
177 }
178
179 void add_usermac(char *mac, int idx, char *upstream, char *downstream)
180 {
181         unsigned char octet[6];
182
183         ether_atoe(mac, octet);
184         int base = 120 + idx;
185         char up[32];
186         char down[32];
187         char ups[32];
188         char downs[32];
189         char oct2[32];
190         char oct4[32];
191         char doct2[32];
192         char doct4[32];
193
194         sprintf(up, "1:%d", base);
195         sprintf(down, "1:%d", base + 1);
196         sprintf(ups, "%skbit", upstream);
197         sprintf(downs, "%skbit", downstream);
198
199         sprintf(oct2, "%02X%02X", octet[4], octet[5]);
200         sprintf(oct4, "%02X%02X%02X%02X", octet[0], octet[1], octet[2],
201                 octet[3]);
202
203         sprintf(doct4, "%02X%02X%02X%02X", octet[2], octet[3], octet[4],
204                 octet[5]);
205         sprintf(doct2, "%02X%02X", octet[0], octet[1]);
206
207         if (nvram_match("qos_type", "1")) {
208                 // up
209                 sysprintf("tc class add dev %s parent 1:1 classid 1:%d htb rate %skbit ceil %skbit", "imq0", base, upstream, upstream); //
210                 sysprintf
211                     ("tc qdisc add dev %s parent 1:%d sfq quantum 1514b perturb 15",
212                      "imq0", base);
213                 sysprintf
214                     ("tc filter add dev %s protocol ip parent 1:0 prio 1 u32 match u16 0x0800 0xFFFF at -2 match u16 0x%s 0xFFFF at -4 match u32 0x%s 0xFFFFFFFF at -8 flowid 1:%d",
215                      "imq0", oct2, oct4, base);
216
217                 // down
218                 if (strcmp(get_wshaper_dev(), "br0")) {
219                         /*
220                          * use separate root class, since no other class is created for br0
221                          * if qos is wan based
222                          */
223                         sysprintf
224                             ("tc class add dev br0 parent 1: classid 1:%d htb rate %skbit ceil %skbit",
225                              base + 1, downstream, downstream);
226                         sysprintf
227                             ("tc qdisc add dev br0 parent 1:%d sfq quantum 1514b perturb 15",
228                              base + 1, base + 1);
229                         sysprintf
230                             ("tc filter add dev br0 protocol ip parent 1:0 prio 1 u32 match u16 0x0800 0xFFFF at -2 match u32 0x%s 0xFFFFFFFF at -12 match u16 0x%s 0xFFFF at -14 flowid 1:%d",
231                              doct4, doct2, base + 1);
232                 } else {
233                         /*
234                          * use root class of br0 interface which was created by the wshaper
235                          */
236                         // br0 -> imq0 changed, in lan-briding, we need to use IMQ
237                         sysprintf
238                             ("tc class add dev imq0 parent 1:1 classid 1:%d htb rate %skbit ceil %skbit",
239                              base + 1, downstream, downstream);
240                         sysprintf
241                             ("tc qdisc add dev imq0 parent 1:%d sfq quantum 1514b perturb 15",
242                              base + 1, base + 1);
243                         sysprintf
244                             ("tc filter add dev imq0 protocol ip parent 1:0 prio 1 u32 match u16 0x0800 0xFFFF at -2 match u32 0x%s 0xFFFFFFFF at -12 match u16 0x%s 0xFFFF at -14 flowid 1:%d",
245                              doct4, doct2, base + 1);
246                 }
247
248         } else {
249                 // up
250                 sysprintf("tc class add dev %s parent 1:2 classid 1:%d htb rate %skbit ceil %skbit", "imq0", base, upstream, upstream); //
251                 sysprintf
252                     ("tc qdisc add dev %s parent 1:%d sfq quantum 1514b perturb 15",
253                      "imq0", base);
254                 sysprintf
255                     ("tc filter add dev %s protocol ip parent 1:0 prio 1 u32 match u16 0x0800 0xFFFF at -2 match u16 0x%s 0xFFFF at -4 match u32 0x%s 0xFFFFFFFF at -8 flowid 1:%d",
256                      "imq0", oct2, oct4, base);
257
258                 // down
259                 if (strcmp(get_wshaper_dev(), "br0")) {
260                         /*
261                          * use separate root class, since no other class is created for br0
262                          * if qos is wan based
263                          */
264                         sysprintf
265                             ("tc class add dev br0 parent 1: classid 1:%d htb rate %skbit ceil %skbit",
266                              base + 1, downstream, downstream);
267                         sysprintf
268                             ("tc qdisc add dev br0 parent 1:%d sfq quantum 1514b perturb 15",
269                              base + 1, base + 1);
270                         sysprintf
271                             ("tc filter add dev br0 protocol ip parent 1:0 prio 1 u32 match u16 0x0800 0xFFFF at -2 match u32 0x%s 0xFFFFFFFF at -12 match u16 0x%s 0xFFFF at -14 flowid 1:%d",
272                              doct4, doct2, base + 1);
273                 } else {
274                         /*
275                          * use root class of br0 interface which was created by the wshaper
276                          */
277                         // br0 -> imq0 changed, in lan-briding, we need to use IMQ
278                         sysprintf
279                             ("tc class add dev imq0 parent 1:2 classid 1:%d htb rate %skbit ceil %skbit",
280                              base + 1, downstream, downstream);
281                         sysprintf
282                             ("tc qdisc add dev imq0 parent 1:%d sfq quantum 1514b perturb 15",
283                              base + 1, base + 1);
284                         sysprintf
285                             ("tc filter add dev imq0 protocol ip parent 1:0 prio 1 u32 match u16 0x0800 0xFFFF at -2 match u32 0x%s 0xFFFFFFFF at -12 match u16 0x%s 0xFFFF at -14 flowid 1:%d",
286                              doct4, doct2, base + 1);
287                 }
288         }
289         /*
290          * mac downstream matching can only be made directly on the connected
291          * interface
292          */
293         char iflist[256];
294
295         getIfList(iflist, NULL);
296         static char word[256];
297         char *next, *wordlist;
298
299         foreach(word, iflist, next) {
300                 if (nvram_nmatch("0", "%s_bridged", word)) {
301                         sysprintf
302                             ("tc class add dev %s parent 1: classid 1:%d htb rate %skbit ceil %skbit",
303                              word, base + 1, downstream, downstream);
304                         sysprintf
305                             ("tc qdisc add dev %s parent 1:%d sfq quantum 1514b perturb 15",
306                              word, base + 1, base + 1);
307                         sysprintf
308                             ("tc filter add dev %s protocol ip parent 1:0 prio 1 u32 match u16 0x0800 0xFFFF at -2 match u32 0x%s 0xFFFFFFFF at -12 match u16 0x%s 0xFFFF at -14 flowid 1:%d",
309                              word, doct4, doct2, base + 1);
310                 }
311         }
312
313 }
314
315 #endif
316 int buf_to_file(char *path, char *buf)
317 {
318         FILE *fp;
319
320         if ((fp = fopen(path, "w"))) {
321                 fprintf(fp, "%s", buf);
322                 fclose(fp);
323                 return 1;
324         }
325
326         return 0;
327 }
328
329 int check_action(void)
330 {
331         char buf[80] = "";
332
333         if (file_to_buf(ACTION_FILE, buf, sizeof(buf))) {
334                 if (!strcmp(buf, "ACT_TFTP_UPGRADE")) {
335                         fprintf(stderr, "Upgrading from tftp now ...\n");
336                         return ACT_TFTP_UPGRADE;
337                 }
338 #ifdef HAVE_HTTPS
339                 else if (!strcmp(buf, "ACT_WEBS_UPGRADE")) {
340                         fprintf(stderr, "Upgrading from web (https) now ...\n");
341                         return ACT_WEBS_UPGRADE;
342                 }
343 #endif
344                 else if (!strcmp(buf, "ACT_WEB_UPGRADE")) {
345                         fprintf(stderr, "Upgrading from web (http) now ...\n");
346                         return ACT_WEB_UPGRADE;
347                 } else if (!strcmp(buf, "ACT_SW_RESTORE")) {
348                         fprintf(stderr,
349                                 "Receiving restore command from web ...\n");
350                         return ACT_SW_RESTORE;
351                 } else if (!strcmp(buf, "ACT_HW_RESTORE")) {
352                         fprintf(stderr,
353                                 "Receiving restore command from resetbutton ...\n");
354                         return ACT_HW_RESTORE;
355                 } else if (!strcmp(buf, "ACT_NVRAM_COMMIT")) {
356                         fprintf(stderr, "Committing nvram now ...\n");
357                         return ACT_NVRAM_COMMIT;
358                 } else if (!strcmp(buf, "ACT_ERASE_NVRAM")) {
359                         fprintf(stderr, "Erasing nvram now ...\n");
360                         return ACT_ERASE_NVRAM;
361                 }
362         }
363         // fprintf(stderr, "Waiting for upgrading....\n");
364         return ACT_IDLE;
365 }
366
367 int check_vlan_support(void)
368 {
369 #if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || defined(HAVE_FONERA) || defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_WHRAG108) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_LSX) || defined(HAVE_DANUBE) || defined(HAVE_STORM) || defined(HAVE_ADM5120) || defined(HAVE_RT2880)
370         return 0;
371 #else
372
373         int brand = getRouterBrand();
374
375         switch (brand) {
376 #ifndef HAVE_BUFFALO
377         case ROUTER_ASUS_WL500GD:
378                 return 1;
379                 break;
380 #endif
381         case ROUTER_BUFFALO_WLAG54C:
382         case ROUTER_BUFFALO_WLA2G54C:
383 #ifndef HAVE_BUFFALO
384         case ROUTER_LINKSYS_WRT55AG:
385         case ROUTER_MOTOROLA_V1:
386         case ROUTER_MOTOROLA_WE800G:
387         case ROUTER_WAP54G_V1:
388         case ROUTER_SITECOM_WL105B:
389         case ROUTER_SITECOM_WL111:
390         case ROUTER_BUFFALO_WLI2_TX1_G54:
391         case ROUTER_BUFFALO_WLI_TX4_G54HP:
392         case ROUTER_BRCM4702_GENERIC:
393         case ROUTER_ASUS_WL500G:
394         case ROUTER_BELKIN_F5D7230_V2000:
395         case ROUTER_ASKEY_RT220XD:
396 #endif
397                 return 0;
398                 break;
399         }
400
401         uint boardflags = strtoul(nvram_safe_get("boardflags"), NULL, 0);
402
403         if (boardflags & BFL_ENETVLAN)
404                 return 1;
405
406         if (nvram_match("boardtype", "bcm94710dev")
407             || nvram_match("boardtype", "0x0101") || (boardflags & 0x0100))
408                 return 1;
409         else
410                 return 0;
411 #endif
412 }
413
414 void setRouter(char *name)
415 {
416 #ifdef HAVE_POWERNOC_WORT54G
417         nvram_set(NVROUTER, "WORT54G");
418 #elif HAVE_POWERNOC_WOAP54G
419         nvram_set(NVROUTER, "WOAP54G");
420 #elif HAVE_ERC
421         nvram_set(NVROUTER, "ServiceGate v1.0");
422 #elif HAVE_OMNI
423         nvram_set(NVROUTER, "Omni Wifi Router");
424 #elif HAVE_ALFA_BRANDING
425         nvram_set(NVROUTER, "WLAN base-station");
426         if (name)
427                 nvram_set("DD_BOARD2", name);
428 #elif HAVE_MAKSAT
429         if (name)
430                 nvram_set("DD_BOARD2", name);
431 #ifdef HAVE_MAKSAT_BLANK
432         nvram_set(NVROUTER, "default");
433 #else
434         nvram_set(NVROUTER, "MAKSAT");
435 #endif
436 #elif HAVE_TMK
437         if (name)
438                 nvram_set("DD_BOARD2", name);
439         nvram_set(NVROUTER, "KMT-WAS");
440 #else
441         if (name)
442                 nvram_set(NVROUTER, name);
443 #endif
444 }
445
446 char *getRouter()
447 {
448         char *n = nvram_get(NVROUTER);
449
450         return n != NULL ? n : "Unknown Model";
451 }
452
453 int internal_getRouterBrand()
454 {
455 #if defined(HAVE_ALLNETWRT) && !defined(HAVE_ECB9750)
456         uint boardnum = strtoul(nvram_safe_get("boardnum"), NULL, 0);
457
458         if (boardnum == 8 && nvram_match("boardtype", "0x048e")
459             && nvram_match("boardrev", "0x11")) {
460                 cprintf("router is ALLNET01\n");
461                 setRouter("ALLNET EUROWRT 54");
462                 return ROUTER_ALLNET01;
463         }
464         eval("event", "3", "1", "15");
465         return 0;
466 #elif defined(HAVE_ALLNETWRT) && defined(HAVE_EOC5610)
467         setRouter("Allnet Outdoor A/B/G CPE");
468         return ROUTER_BOARD_LS2;
469 #else
470 #ifdef HAVE_NP28G
471         setRouter("Compex NP28G");
472         return ROUTER_BOARD_NP28G;
473 #elif HAVE_WP54G
474         setRouter("Compex WP54G");
475         return ROUTER_BOARD_WP54G;
476 #elif HAVE_ADM5120
477         setRouter("Tonze AP-120");
478         return ROUTER_BOARD_ADM5120;
479 #elif HAVE_RB500
480         setRouter("Mikrotik RB500");
481         return ROUTER_BOARD_500;
482 #elif HAVE_GEMTEK
483         setRouter("SuperGerry");
484         return ROUTER_SUPERGERRY;
485 #elif HAVE_TONZE
486         setRouter("Tonze AP-425");
487         return ROUTER_BOARD_GATEWORX;
488 #elif HAVE_NOP8670
489         setRouter("Senao NOP-8670");
490         return ROUTER_BOARD_GATEWORX;
491 #elif HAVE_WRT300NV2
492         setRouter("Linksys WRT300N v2");
493         return ROUTER_BOARD_GATEWORX;
494 #elif HAVE_WG302V1
495         setRouter("Netgear WG302v1");
496         return ROUTER_BOARD_GATEWORX;
497 #elif HAVE_WG302
498         setRouter("Netgear WG302v2");
499         return ROUTER_BOARD_GATEWORX;
500 #elif HAVE_GATEWORX
501         char *filename = "/sys/devices/platform/IXP4XX-I2C.0/i2c-adapter:i2c-0/0-0051/eeprom";  /* bank2=0x100
502                                                                                                  */
503         FILE *file = fopen(filename, "r");
504
505         if (file)               // new detection scheme
506         {
507                 fseek(file, 32, SEEK_SET);
508                 char gwid[7];
509
510                 gwid[6] = 0;
511                 int ret = fread(gwid, 6, 1, file);
512
513                 if (ret < 1) {
514                         fclose(file);
515                         goto old_way;
516                 }
517                 fclose(file);
518                 if (!strncmp(gwid, "GW2347", 6)) {
519                         setRouter("Avila GW2347");
520                         return ROUTER_BOARD_GATEWORX_SWAP;
521                 }
522                 if (!strncmp(gwid, "GW2357", 6)) {
523                         setRouter("Avila GW2357");
524                         return ROUTER_BOARD_GATEWORX_SWAP;
525                 }
526                 if (!strncmp(gwid, "GW2353", 6)) {
527                         setRouter("Avila GW2343");
528                         return ROUTER_BOARD_GATEWORX;
529                 }
530                 if (!strncmp(gwid, "GW2348", 6)) {
531                         setRouter("Avila GW2348-4/2");
532                         return ROUTER_BOARD_GATEWORX;
533                 }
534                 if (!strncmp(gwid, "GW2358", 6)) {
535                         setRouter("Cambria GW2358-4");
536                         return ROUTER_BOARD_GATEWORX;
537                 }
538                 if (!strncmp(gwid, "GW2350", 6)) {
539                         setRouter("Cambria GW2350");
540                         return ROUTER_BOARD_GATEWORX;
541                 }
542                 if (!strncmp(gwid, "GW2355", 6)) {
543                         setRouter("Avila GW2355");
544                         return ROUTER_BOARD_GATEWORX_GW2345;
545                 }
546                 if (!strncmp(gwid, "GW2345", 6)) {
547                         setRouter("Avila GW2345");
548                         return ROUTER_BOARD_GATEWORX_GW2345;
549                 }
550         }
551       old_way:;
552         struct mii_ioctl_data *data;
553         struct ifreq iwr;
554         int s = socket(AF_INET, SOCK_DGRAM, 0);
555
556         if (s < 0) {
557                 fprintf(stderr, "socket(SOCK_DRAGM)\n");
558                 setRouter("Avila Gateworks");
559                 return ROUTER_BOARD_GATEWORX;
560         }
561         (void)strncpy(iwr.ifr_name, "ixp0", sizeof("ixp0"));
562         data = (struct mii_ioctl_data *)&iwr.ifr_data;
563         data->phy_id = 1;
564 #define IX_ETH_ACC_MII_PHY_ID1_REG  0x2 /* PHY identifier 1 Register */
565 #define IX_ETH_ACC_MII_PHY_ID2_REG  0x3 /* PHY identifier 2 Register */
566         data->reg_num = IX_ETH_ACC_MII_PHY_ID1_REG;
567         ioctl(s, SIOCGMIIREG, &iwr);
568         data->phy_id = 1;
569         data->reg_num = IX_ETH_ACC_MII_PHY_ID1_REG;
570         ioctl(s, SIOCGMIIREG, &iwr);
571         int reg1 = data->val_out;
572
573         data->phy_id = 1;
574         data->reg_num = IX_ETH_ACC_MII_PHY_ID2_REG;
575         ioctl(s, SIOCGMIIREG, &iwr);
576         int reg2 = data->val_out;
577
578         close(s);
579         fprintf(stderr, "phy id %X:%X\n", reg1, reg2);
580         if (reg1 == 0x2000 && reg2 == 0x5c90) {
581                 setRouter("Avila GW2347");
582                 return ROUTER_BOARD_GATEWORX_SWAP;
583         } else if (reg1 == 0x13 && reg2 == 0x7a11) {
584 #if HAVE_ALFA_BRANDING
585                 setRouter("WLAN base-station");
586 #else
587                 setRouter("Avila GW2348-4/2");
588 #endif
589                 return ROUTER_BOARD_GATEWORX;
590         } else if (reg1 == 0x143 && reg2 == 0xbc31)     // broadcom phy
591         {
592                 setRouter("ADI Engineering Pronghorn Metro");
593                 return ROUTER_BOARD_GATEWORX;
594         } else if (reg1 == 0x22 && reg2 == 0x1450)      // kendin switch
595         {
596                 setRouter("Avila GW2345");
597                 return ROUTER_BOARD_GATEWORX_GW2345;
598         } else if (reg1 == 0x0 && reg2 == 0x8201)       // realtek
599         {
600                 setRouter("Compex WP188");
601                 return ROUTER_BOARD_GATEWORX;
602         } else {
603                 setRouter("Unknown");
604                 return ROUTER_BOARD_GATEWORX;
605         }
606 #elif HAVE_RT2880
607 #ifdef HAVE_ECB9750
608 #ifdef HAVE_ALLNETWRT
609         setRouter("Allnet 802.11n Router");
610 #else
611         setRouter("Senao ECB-9750");
612 #endif
613         return ROUTER_BOARD_ECB9750;
614 #elif HAVE_ALLNET11N
615         setRouter("Allnet 802.11n Router");
616         return ROUTER_BOARD_WHRG300N;
617 #elif HAVE_ESR6650
618         setRouter("Senao ESR6650");
619         return ROUTER_BOARD_ESR6650;
620 #elif HAVE_WHRG300N
621         setRouter("Buffalo WHR-G300N");
622         return ROUTER_BOARD_WHRG300N;
623 #else
624         setRouter("Generic RT2880");
625         return ROUTER_BOARD_RT2880;
626 #endif
627 #elif HAVE_X86
628         setRouter("Generic X86");
629         return ROUTER_BOARD_X86;
630 #elif HAVE_XSCALE
631         setRouter("NewMedia Dual A/B/G");
632         return ROUTER_BOARD_XSCALE;
633 #elif HAVE_MAGICBOX
634         setRouter("OpenRB PowerPC Board");
635         return ROUTER_BOARD_MAGICBOX;
636 #elif HAVE_GWMF54G2
637         setRouter("Planex GW-MF54G2");
638         char mac[32];
639         getBoardMAC(mac);
640         if (!strncmp(mac, "00:19:3B", 8) || !strncmp(mac, "00:02:6F", 8)
641             || !strncmp(mac, "00:15:6D", 8)) {
642                 fprintf(stderr, "unsupported board\n");
643                 sys_reboot();
644         }
645         return ROUTER_BOARD_FONERA;
646 #elif HAVE_WRT54GV7
647         setRouter("Linksys WRT54G v7");
648         return ROUTER_BOARD_FONERA;
649 #elif HAVE_WRK54G
650         setRouter("Linksys WRK54G v3");
651         return ROUTER_BOARD_FONERA;
652 #elif HAVE_WGT624
653         setRouter("Netgear WGT624 v4");
654         return ROUTER_BOARD_FONERA;
655 #elif HAVE_MR3202A
656         setRouter("MR3202A");
657         return ROUTER_BOARD_FONERA;
658 #elif HAVE_AR430W
659         setRouter("Airlink-101 AR430W");
660         return ROUTER_BOARD_FONERA;
661 #elif HAVE_DIR400
662         setRouter("D-Link DIR-400");
663         return ROUTER_BOARD_FONERA2200;
664 #elif HAVE_WRT54G2
665         setRouter("Linksys WRT54G2 v1.1");
666         return ROUTER_BOARD_FONERA;
667 #elif HAVE_DIR300
668         setRouter("D-Link DIR-300");
669         return ROUTER_BOARD_FONERA;
670 #elif HAVE_CNC
671         setRouter("WiFi4You Outdoor AP");
672         return ROUTER_BOARD_FONERA;
673 #elif HAVE_WBD500
674         setRouter("Wiligear WBD-500");
675         return ROUTER_BOARD_FONERA;
676 #elif HAVE_EOC1650
677         setRouter("Senao EOC-1650");
678         return ROUTER_BOARD_FONERA;
679 #elif HAVE_EOC2610
680 #ifdef HAVE_TRIMAX
681         setRouter("TMAX-1200");
682 #else
683         setRouter("Senao EOC-2610");
684 #endif
685         return ROUTER_BOARD_FONERA;
686 #elif HAVE_ECB3500
687         setRouter("Senao ECB-3500");
688         return ROUTER_BOARD_FONERA;
689 #elif HAVE_EAP3660
690         setRouter("Senao EAP-3660");
691         return ROUTER_BOARD_FONERA;
692 #elif HAVE_MR3201A
693         setRouter("Accton MR3201A");
694         return ROUTER_BOARD_FONERA;
695 #elif HAVE_FONERA
696         struct mii_ioctl_data *data;
697         struct ifreq iwr;
698         char mac[32];
699         getBoardMAC(mac);
700         if (!strncmp(mac, "00:19:3B", 8) || !strncmp(mac, "00:02:6F", 8)
701             || !strncmp(mac, "00:15:6D", 8)) {
702                 fprintf(stderr, "unsupported board\n");
703                 sys_reboot();
704         }
705         int s = socket(AF_INET, SOCK_DGRAM, 0);
706
707         if (s < 0) {
708                 fprintf(stderr, "socket(SOCK_DRAGM)\n");
709                 setRouter("Fonera 2100/2200");
710                 return ROUTER_BOARD_FONERA;
711         }
712         (void)strncpy(iwr.ifr_name, "eth0", sizeof("eth0"));
713         data = (struct mii_ioctl_data *)&iwr.ifr_data;
714         data->phy_id = 0x10;
715         data->reg_num = 0x2;
716         ioctl(s, SIOCGMIIREG, &iwr);
717         data->phy_id = 0x10;
718         data->reg_num = 0x2;
719         ioctl(s, SIOCGMIIREG, &iwr);
720         if (data->val_out == 0x0141) {
721                 data->phy_id = 0x10;
722                 data->reg_num = 0x3;
723                 ioctl(s, SIOCGMIIREG, &iwr);
724                 close(s);
725                 if ((data->val_out & 0xfc00) != 0x0c00) // marvell phy
726                 {
727                         setRouter("Fonera 2100/2200");
728                         return ROUTER_BOARD_FONERA;
729                 } else {
730                         setRouter("Fonera 2201");
731                         return ROUTER_BOARD_FONERA2200;
732                 }
733         } else {
734                 setRouter("Fonera 2100/2200");
735                 return ROUTER_BOARD_FONERA;
736         }
737 #elif HAVE_MERAKI
738         setRouter("Meraki Mini");
739         return ROUTER_BOARD_MERAKI;
740 #elif defined(HAVE_CORENET) && defined(HAVE_NS2)
741         setRouter("CORENET UNS2");
742         return ROUTER_BOARD_LS2;
743 #elif HAVE_BWRG1000
744         setRouter("Bountiful BWRG-1000");
745         return ROUTER_BOARD_LS2;
746 #elif HAVE_NS2
747         setRouter("Ubiquiti Nanostation 2");
748         return ROUTER_BOARD_LS2;
749 #elif HAVE_EOC5610
750         setRouter("Senao EOC-5610");
751         return ROUTER_BOARD_LS2;
752 #elif HAVE_NS5
753         setRouter("Ubiquiti Nanostation 5");
754         return ROUTER_BOARD_LS2;
755 #elif HAVE_NS3
756         setRouter("Ubiquiti Nanostation 3");
757         return ROUTER_BOARD_LS2;
758 #elif HAVE_BS5
759         setRouter("Ubiquiti Bullet 5");
760         return ROUTER_BOARD_LS2;
761 #elif HAVE_BS2
762         setRouter("Ubiquiti Bullet 2");
763         return ROUTER_BOARD_LS2;
764 #elif HAVE_PICO2
765         setRouter("Ubiquiti PicoStation 2");
766         return ROUTER_BOARD_LS2;
767 #elif HAVE_PICO2HP
768         setRouter("Ubiquiti PicoStation 2 HP");
769         return ROUTER_BOARD_LS2;
770 #elif HAVE_PICO5
771         setRouter("Ubiquiti PicoStation 5");
772         return ROUTER_BOARD_LS2;
773 #elif HAVE_MS2
774         setRouter("Ubiquiti MiniStation");
775         return ROUTER_BOARD_LS2;
776 #elif HAVE_BS2HP
777         setRouter("Ubiquiti Bullet 2 HP");
778         return ROUTER_BOARD_LS2;
779 #elif HAVE_LC2
780         setRouter("Ubiquiti Nanostation Loco 2");
781         return ROUTER_BOARD_LS2;
782 #elif HAVE_LC5
783         setRouter("Ubiquiti Nanostation Loco 5");
784         return ROUTER_BOARD_LS2;
785 #elif HAVE_PS2
786         setRouter("Ubiquiti Powerstation 2");
787         return ROUTER_BOARD_LS2;
788 #elif HAVE_PS5
789         setRouter("Ubiquiti Powerstation 5");
790         return ROUTER_BOARD_LS2;
791 #elif HAVE_LS2
792         setRouter("Ubiquiti Litestation 2");
793         return ROUTER_BOARD_LS2;
794 #elif HAVE_LS5
795         setRouter("Ubiquiti Litestation 5");
796         return ROUTER_BOARD_LS2;
797 #elif HAVE_WHRAG108
798         setRouter("Buffalo WHR-HP-AG108");
799         return ROUTER_BOARD_WHRAG108;
800 #elif HAVE_PB42
801         setRouter("Atheros PB42");
802         return ROUTER_BOARD_PB42;
803 #elif HAVE_RS
804         #ifdef HAVE_DDLINK
805         setRouter("ddlink2x2");
806         #else
807         setRouter("Ubiquiti RouterStation");
808         #endif
809         return ROUTER_BOARD_PB42;
810 #elif HAVE_LSX
811         setRouter("Ubiquiti LSX");
812         return ROUTER_BOARD_PB42;
813 #elif HAVE_DANUBE
814         setRouter("Infineon Danube");
815         return ROUTER_BOARD_DANUBE;
816 #elif HAVE_STORM
817         setRouter("Wiligear WBD-111");
818         return ROUTER_BOARD_STORM;
819 #elif HAVE_TW6600
820         setRouter("AW-6660");
821         return ROUTER_BOARD_TW6600;
822 #elif HAVE_ALPHA
823         setRouter("Alfa Networks AP48");
824         return ROUTER_BOARD_CA8;
825 #elif HAVE_USR5453
826         setRouter("US Robotics USR5453");
827         return ROUTER_BOARD_CA8;
828 #elif HAVE_RDAT81
829         setRouter("Wistron RDAT-81");
830         return ROUTER_BOARD_RDAT81;
831 #elif HAVE_RCAA01
832         setRouter("Airlive WLA-9000AP");
833         return ROUTER_BOARD_RCAA01;
834 #elif HAVE_CA8PRO
835         setRouter("Wistron CA8-4 PRO");
836         return ROUTER_BOARD_CA8PRO;
837 #elif HAVE_CA8
838 #ifdef HAVE_WHA5500CPE
839         setRouter("Airlive WHA-5500CPE");
840 #elif HAVE_AIRMAX5
841         setRouter("Airlive AirMax 5");
842 #else
843         setRouter("Airlive WLA-5000AP");
844 #endif
845         return ROUTER_BOARD_CA8;
846 #else
847
848         uint boardnum = strtoul(nvram_safe_get("boardnum"), NULL, 0);
849
850         if (boardnum == 42 && nvram_match("boardtype", "bcm94710ap")) {
851                 cprintf("router is buffalo\n");
852                 setRouter("Buffalo WBR-G54 / WLA-G54");
853                 return ROUTER_BUFFALO_WBR54G;
854         }
855 #ifndef HAVE_BUFFALO
856         if (nvram_match("boardnum", "mn700") &&
857             nvram_match("boardtype", "bcm94710ap")) {
858                 cprintf("router is Microsoft MN-700\n");
859                 setRouter("Microsoft MN-700");
860                 return ROUTER_MICROSOFT_MN700;
861         }
862
863         if (nvram_match("boardnum", "asusX") &&
864             nvram_match("boardtype", "bcm94710dev")) {
865                 cprintf("router is Asus WL300g / WL500g\n");
866                 setRouter("Asus WL-300g / WL-500g");
867                 return ROUTER_ASUS_WL500G;
868         }
869
870         if (boardnum == 44 && nvram_match("boardtype", "bcm94710ap")) {
871                 cprintf("router is Dell TrueMobile 2300\n");
872                 setRouter("Dell TrueMobile 2300");
873                 return ROUTER_DELL_TRUEMOBILE_2300;
874         }
875 #endif
876
877         if (boardnum == 100 && nvram_match("boardtype", "bcm94710dev")) {
878                 cprintf("router is buffalo\n");
879                 setRouter("Buffalo WLA-G54C");
880                 return ROUTER_BUFFALO_WLAG54C;
881         }
882 #ifndef HAVE_BUFFALO
883         if (boardnum == 45 && nvram_match("boardtype", "bcm95365r")) {
884                 cprintf("router is Asus WL-500GD\n");
885                 setRouter("Asus WL-500g Deluxe");
886                 return ROUTER_ASUS_WL500GD;
887         }
888
889         if (boardnum == 45 && nvram_match("boardtype", "0x0472")
890             && nvram_match("boardrev", "0x23") && nvram_match("parkid", "1")) {
891                 cprintf("router is Asus WL-500W\n");
892                 setRouter("Asus WL-500W");
893                 return ROUTER_ASUS_WL500W;
894         }
895
896         if (boardnum == 45 && nvram_match("boardtype", "0x467")) {
897                 char *hwver0 = nvram_safe_get("hardware_version");
898
899                 if (startswith(hwver0, "WL320G")) {
900                         cprintf("router is Asus WL-320gE/gP\n");
901                         setRouter("Asus WL-320gE/gP");
902                         return ROUTER_ASUS_WL550GE;
903                 } else {
904                         cprintf("router is Asus WL-550gE\n");
905                         setRouter("Asus WL-550gE");
906                         return ROUTER_ASUS_WL550GE;
907                 }
908         }
909 #endif
910         if (nvram_match("boardnum", "00") && nvram_match("boardtype", "0x0101")
911             && nvram_match("boardrev", "0x10")) {
912                 cprintf("router is Buffalo wbr2\n");
913                 setRouter("Buffalo WBR2-G54 / WBR2-G54S");
914                 return ROUTER_BUFFALO_WBR2G54S;
915         }
916
917         if (boardnum == 2 && nvram_match("boardtype", "0x0101")
918             && nvram_match("boardrev", "0x10")) {
919                 cprintf("router is buffalo wla2-g54c\n");
920                 setRouter("Buffalo WLA2-G54C / WLI3-TX1-G54");
921                 return ROUTER_BUFFALO_WLA2G54C;
922         }
923         if (boardnum == 0 && nvram_match("melco_id", "29090")
924             && nvram_match("boardflags", "0x0010")
925             && nvram_match("boardrev", "0x10")) {
926                 cprintf("router is Buffalo WLAH-G54\n");
927                 setRouter("Buffalo WLAH-G54");
928                 return ROUTER_BUFFALO_WLAH_G54;
929
930         }
931         if (boardnum == 0 && nvram_match("melco_id", "31070")
932             && nvram_match("boardflags", "0x2288")
933             && nvram_match("boardrev", "0x10")) {
934                 cprintf("router is Buffalo WAPM-HP-AM54G54\n");
935                 setRouter("Buffalo WAPM-HP-AM54G54");
936                 return ROUTER_BUFFALO_WAPM_HP_AM54G54;
937         }
938         if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x11")
939             && nvram_match("boardtype", "0x048e")
940             && nvram_match("melco_id", "32093")) {
941                 cprintf("router is Buffalo WHR-G125\n");
942                 setRouter("Buffalo WHR-G125");
943                 return ROUTER_BUFFALO_WHRG54S;
944         }
945
946         if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x10")
947             && nvram_match("boardtype", "0x048e")
948             && nvram_match("melco_id", "32139")) {
949                 cprintf("router is Buffalo WCA-G\n");
950                 setRouter("Buffalo WCA-G");
951                 return ROUTER_BUFFALO_WCAG;     //vlan1 is lan, vlan0 is unused, implementation not done. will me made after return to germany
952         }
953
954         if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x11")
955             && nvram_match("boardtype", "0x048e")
956             && nvram_match("melco_id", "32064")) {
957                 cprintf("router is Buffalo WHR-HP-G125\n");
958                 setRouter("Buffalo WHR-HP-G125");
959                 return ROUTER_BUFFALO_WHRG54S;
960         }
961
962         if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x13")
963             && nvram_match("boardtype", "0x467")) {
964                 if (nvram_match("boardflags", "0x1658")
965                     || nvram_match("boardflags", "0x2658")
966                     || nvram_match("boardflags", "0x3658")) {
967                         cprintf("router is Buffalo WLI-TX4-G54HP\n");
968                         setRouter("Buffalo WLI-TX4-G54HP");
969                         return ROUTER_BUFFALO_WLI_TX4_G54HP;
970                 }
971                 if (!nvram_match("buffalo_hp", "1")
972                     && nvram_match("boardflags", "0x2758")) {
973                         cprintf("router is Buffalo WHR-G54S\n");
974                         setRouter("Buffalo WHR-G54S");
975                         return ROUTER_BUFFALO_WHRG54S;
976                 }
977                 if (nvram_match("buffalo_hp", "1")
978                     || nvram_match("boardflags", "0x1758")) {
979 #ifndef HAVE_BUFFALO
980                         cprintf("router is Buffalo WHR-HP-G54\n");
981                         setRouter("Buffalo WHR-HP-G54");
982 #else
983                         cprintf("router is Buffalo WHR-HP-G54DD\n");
984 #ifdef BUFFALO_JP
985                         setRouter("Buffalo AS-A100");
986 #else
987                         setRouter("Buffalo WHR-HP-G54DD");
988 #endif
989 #endif
990                         return ROUTER_BUFFALO_WHRG54S;
991                 }
992         }
993
994         if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x10")
995             && nvram_match("boardtype", "0x470")) {
996                 cprintf("router is Buffalo WHR-AM54G54\n");
997                 setRouter("Buffalo WHR-AM54G54");
998                 return ROUTER_BUFFALO_WHRAM54G54;
999         }
1000
1001         if (boardnum == 42 && nvram_match("boardtype", "0x042f")) {
1002                 uint melco_id = strtoul(nvram_safe_get("melco_id"), NULL, 0);
1003
1004                 if (nvram_match("product_name", "WZR-RS-G54")
1005                     || melco_id == 30083) {
1006                         cprintf("router is Buffalo WZR-RS-G54\n");
1007                         setRouter("Buffalo WZR-RS-G54");
1008                         return ROUTER_BUFFALO_WZRRSG54;
1009                 }
1010                 if (nvram_match("product_name", "WZR-HP-G54")
1011                     || melco_id == 30026) {
1012                         cprintf("router is Buffalo WZR-HP-G54\n");
1013                         setRouter("Buffalo WZR-HP-G54");
1014                         return ROUTER_BUFFALO_WZRRSG54;
1015                 }
1016                 if (nvram_match("product_name", "WZR-G54") || melco_id == 30061) {
1017                         cprintf("router is Buffalo WZR-G54\n");
1018                         setRouter("Buffalo WZR-G54");
1019                         return ROUTER_BUFFALO_WZRRSG54;
1020                 }
1021                 if (nvram_match("melco_id", "290441dd")) {
1022                         cprintf("router is Buffalo WHR2-A54G54\n");
1023                         setRouter("Buffalo WHR2-A54G54");
1024                         return ROUTER_BUFFALO_WZRRSG54;
1025                 }
1026                 if (nvram_match("product_name", "WHR3-AG54")
1027                     || nvram_match("product_name", "WHR3-B11")
1028                     || melco_id == 29130) {
1029                         cprintf("router is Buffalo WHR3-AG54\n");
1030                         setRouter("Buffalo WHR3-AG54");
1031                         return ROUTER_BUFFALO_WZRRSG54;
1032                 }
1033                 if (nvram_match("product_name", "WVR-G54-NF")
1034                     || melco_id == 28100) {
1035                         cprintf("router is Buffalo WVR-G54-NF\n");
1036                         setRouter("Buffalo WVR-G54-NF");
1037                         return ROUTER_BUFFALO_WZRRSG54;
1038                 }
1039                 if (nvram_match("product_name", "WZR-G108") || melco_id == 31095
1040                     || melco_id == 30153) {
1041                         cprintf("router is Buffalo WZR-G108\n");
1042                         setRouter("Buffalo WZR-G108");
1043                         return ROUTER_BRCM4702_GENERIC;
1044                 }
1045                 if (melco_id > 0)       // e.g. 29115
1046                 {
1047                         cprintf("router is Buffalo WZR series\n");
1048                         setRouter("Buffalo WZR series");
1049                         return ROUTER_BUFFALO_WZRRSG54;
1050                 }
1051         }
1052 #ifndef HAVE_BUFFALO
1053         if (boardnum == 42 && nvram_match("boardtype", "0x042f")
1054             && nvram_match("boardrev", "0x10"))
1055                 // nvram_match ("boardflags","0x0018"))
1056         {
1057                 cprintf("router is Linksys WRTSL54GS\n");
1058                 setRouter("Linksys WRTSL54GS");
1059                 return ROUTER_WRTSL54GS;
1060         }
1061
1062         if (boardnum == 42 && nvram_match("boardtype", "0x0101")
1063             && nvram_match("boardrev", "0x10")
1064             && nvram_match("boot_ver", "v3.6")) {
1065                 cprintf("router is Linksys WRT54G3G\n");
1066                 setRouter("Linksys WRT54G3G");
1067                 return ROUTER_WRT54G3G;
1068         }
1069
1070         if (nvram_match("boardtype", "0x042f")
1071             && nvram_match("boardrev", "0x10")) {
1072                 char *hwver = nvram_safe_get("hardware_version");
1073
1074                 if (boardnum == 45 || startswith(hwver, "WL500gp")
1075                     || startswith(hwver, "WL500gH")) {
1076                         cprintf("router is Asus WL-500g Premium\n");
1077                         setRouter("Asus WL-500g Premium");
1078                         return ROUTER_ASUS_WL500G_PRE;
1079                 }
1080         }
1081
1082         char *et0 = nvram_safe_get("et0macaddr");
1083
1084         if (boardnum == 100 && nvram_match("boardtype", "bcm94710r4")) {
1085                 if (startswith(et0, "00:11:50")) {
1086                         cprintf("router is Belkin F5D7130 / F5D7330\n");
1087                         setRouter("Belkin F5D7130 / F5D7330");
1088                         return ROUTER_RT210W;
1089                 }
1090                 if (startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
1091                         cprintf("router is Belkin F5D7230 v1000\n");
1092                         setRouter("Belkin F5D7230-4 v1000");
1093                         return ROUTER_RT210W;
1094                 }
1095                 if (startswith(et0, "00:01:E3") ||
1096                     startswith(et0, "00:01:e3") || startswith(et0, "00:90:96"))
1097                 {
1098                         cprintf("router is Siemens\n");
1099                         setRouter("Siemens SE505 v1");
1100                         return ROUTER_RT210W;
1101                 } else {
1102                         cprintf("router is Askey generic\n");
1103                         setRouter("RT210W generic");
1104                         return ROUTER_RT210W;
1105                 }
1106         }
1107
1108         if (nvram_match("boardtype", "bcm94710r4")
1109             && nvram_match("boardnum", "")) {
1110                 cprintf("router is Askey board RT2100W\n");
1111                 setRouter("Askey board RT2100W-D65)");
1112                 return ROUTER_BRCM4702_GENERIC;
1113         }
1114
1115         if (boardnum == 0 && nvram_match("boardtype", "0x0100")
1116             && nvram_match("boardrev", "0x10")) {
1117                 cprintf("router is Askey board RT2205(6)D-D56\n");
1118                 if (startswith(et0, "00:11:50") ||
1119                     startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd"))
1120                 {
1121                         setRouter("Askey board RT2205(6)D-D56");
1122                 } else {
1123                         setRouter("Belkin board F5D8230");
1124                 }
1125                 return ROUTER_ASKEY_RT220XD;
1126         }
1127
1128         if (nvram_match("boardtype", "0x0101")) {
1129                 if (startswith(et0, "00:11:50") ||
1130                     startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd"))
1131                 {
1132                         if (nvram_match("Belkin_ver", "2000")) {
1133                                 cprintf("router is Belkin F5D7230-4 v2000\n");
1134                                 setRouter("Belkin F5D7230-4 v2000");
1135                                 return ROUTER_BELKIN_F5D7230_V2000;
1136                         } else {
1137                                 cprintf("router is Belkin F5D7230-4 v1444\n");
1138                                 setRouter("Belkin F5D7230-4 v1444");
1139                                 return ROUTER_RT480W;
1140                         }
1141                 }
1142                 if (startswith(et0, "00:01:E3") ||
1143                     startswith(et0, "00:01:e3") || startswith(et0, "00:90:96"))
1144                 {
1145                         cprintf("router is Siemens / Askey\n");
1146                         setRouter("Siemens SE505 v2");
1147                         return ROUTER_RT480W;
1148                 }
1149         }
1150         if (boardnum == 1 && nvram_match("boardtype", "0x456")
1151             && nvram_match("test_led_gpio", "2")) {
1152                 cprintf("router is Belkin F5D7230-4 v3000\n");
1153                 setRouter("Belkin F5D7230-4 v3000");
1154                 return ROUTER_BELKIN_F5D7230_V3000;
1155         }
1156
1157         if (nvram_match("boardtype", "0x456")
1158             && nvram_match("hw_model", "F5D7231-4")) {
1159                 cprintf("router is Belkin F5D7231-4 v1212UK\n");
1160                 setRouter("Belkin F5D7231-4 v1212UK");
1161                 return ROUTER_BELKIN_F5D7231;
1162         }
1163
1164         if (boardnum == 8 && nvram_match("boardtype", "0x0467"))        // fccid:
1165                 // K7SF5D7231B
1166         {
1167                 cprintf("router is Belkin F5D7231-4 v2000\n");
1168                 setRouter("Belkin F5D7231-4 v2000");
1169                 return ROUTER_BELKIN_F5D7231_V2000;
1170         }
1171
1172         if (nvram_match("boardtype", "0x467")) {
1173                 if (startswith(et0, "00:11:50") ||
1174                     startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd"))
1175                 {
1176                         cprintf("router is Belkin F5D7231-4 v2000\n");
1177                         setRouter("Belkin F5D7231-4 v2000");
1178                         return ROUTER_BELKIN_F5D7231;
1179                 }
1180         }
1181 #endif
1182         if (boardnum == 2 && nvram_match("boardtype", "bcm94710dev") && nvram_match("melco_id", "29016"))       // Buffalo
1183                 // WLI2-TX1-G54)
1184         {
1185                 cprintf("router is Buffalo WLI2-TX1-G54\n");
1186                 setRouter("Buffalo WLI2-TX1-G54");
1187                 return ROUTER_BUFFALO_WLI2_TX1_G54;
1188         }
1189 #ifndef HAVE_BUFFALO
1190
1191         char *gemtek = nvram_safe_get("GemtekPmonVer");
1192         uint gemteknum = strtoul(gemtek, NULL, 0);
1193
1194         if (boardnum == 2 && gemteknum == 10 &&
1195             (startswith(et0, "00:0C:E5") ||
1196              startswith(et0, "00:0c:e5") ||
1197              startswith(et0, "00:0C:10") ||
1198              startswith(et0, "00:0c:10") ||
1199              startswith(et0, "00:0C:11") || startswith(et0, "00:0c:11"))) {
1200                 cprintf("router Motorola WE800G v1\n");
1201                 setRouter("Motorola WE800G v1");
1202                 return ROUTER_MOTOROLA_WE800G;
1203         }
1204
1205         if (boardnum == 2
1206             && (startswith(gemtek, "RC") || gemteknum == 1
1207                 || gemteknum == 10)) {
1208                 cprintf("router is Linksys wap54g v1.x\n");
1209                 setRouter("Linksys WAP54G v1.x");
1210                 return ROUTER_WAP54G_V1;
1211         }
1212
1213         if (boardnum == 2 && gemteknum == 1) {
1214                 cprintf("router is Sitecom wl-105b\n");
1215                 setRouter("Sitecom WL-105(b)");
1216                 return ROUTER_SITECOM_WL105B;
1217         }
1218
1219         if (boardnum == 2 && gemteknum == 7
1220             && nvram_match("boardtype", "bcm94710dev")) {
1221                 cprintf("router is Sitecom wl-111\n");
1222                 setRouter("Sitecom WL-111");
1223                 return ROUTER_SITECOM_WL111;
1224         }
1225
1226         if (gemteknum == 9)     // Must be Motorola wr850g v1 or we800g v1 or
1227                 // Linksys wrt55ag v1
1228         {
1229                 if (startswith(et0, "00:0C:E5") ||
1230                     startswith(et0, "00:0c:e5") ||
1231                     startswith(et0, "00:0C:10") ||
1232                     startswith(et0, "00:0c:10") ||
1233                     startswith(et0, "00:0C:11") ||
1234                     startswith(et0, "00:0c:11") ||
1235                     startswith(et0, "00:11:22") ||
1236                     startswith(et0, "00:0C:90") || startswith(et0, "00:0c:90"))
1237                 {
1238                         if (!strlen(nvram_safe_get("phyid_num"))) {
1239                                 insmod("switch-core");  // get phy type
1240                                 insmod("switch-robo");
1241                                 rmmod("switch-robo");
1242                                 rmmod("switch-core");
1243                                 nvram_set("boardnum", "2");
1244                                 nvram_set("boardtype", "bcm94710dev");
1245                         }
1246                         if (nvram_match("phyid_num", "0x00000000")) {
1247                                 cprintf("router Motorola WE800G v1\n");
1248                                 setRouter("Motorola WE800G v1");
1249                                 return ROUTER_MOTOROLA_WE800G;
1250                         } else  // phyid_num == 0xffffffff
1251                         {
1252                                 cprintf("router Motorola WR850G v1\n");
1253                                 setRouter("Motorola WR850G v1");
1254                                 return ROUTER_MOTOROLA_V1;
1255                         }
1256                 } else {
1257                         cprintf("router is linksys WRT55AG\n");
1258                         setRouter("Linksys WRT55AG v1");
1259                         return ROUTER_LINKSYS_WRT55AG;
1260                 }
1261         }
1262 #endif
1263         if (boardnum == 0 && nvram_match("boardtype", "0x478")
1264             && nvram_match("cardbus", "0") && nvram_match("boardrev", "0x10")
1265             && nvram_match("boardflags", "0x110")
1266             && nvram_match("melco_id", "32027")) {
1267                 setRouter("Buffalo WZR-G144NH");
1268                 return ROUTER_BUFFALO_WZRG144NH;
1269         }
1270
1271         if (boardnum == 20060330 && nvram_match("boardtype", "0x0472")) {
1272                 setRouter("Buffalo WZR-G300N");
1273                 return ROUTER_BUFFALO_WZRG300N;
1274         }
1275 #ifndef HAVE_BUFFALO
1276
1277         if (boardnum == 8 && nvram_match("boardtype", "0x0472")
1278             && nvram_match("cardbus", "1")) {
1279                 cprintf("router is Netgear WNR834B\n");
1280                 setRouter("Netgear WNR834B");
1281                 return ROUTER_NETGEAR_WNR834B;
1282         }
1283
1284         if (boardnum == 1 && nvram_match("boardtype", "0x0472")
1285             && nvram_match("boardrev", "0x23")) {
1286                 if (nvram_match("cardbus", "1")) {
1287                         cprintf("router is Netgear WNR834B v2\n");
1288                         setRouter("Netgear WNR834B v2");
1289                         return ROUTER_NETGEAR_WNR834BV2;
1290                 } else {
1291                         cprintf("router is Netgear WNDR-3300\n");
1292                         setRouter("Netgear WNDR3300");
1293                         return ROUTER_NETGEAR_WNDR3300;
1294                 }
1295         }
1296
1297         if (boardnum == 42)     // Get Linksys N models
1298         {
1299                 if (nvram_match("boot_hw_model", "WRT300N")
1300                     && nvram_match("boot_hw_ver", "1.1")) {
1301                         setRouter("Linksys WRT300N v1.1");
1302                         return ROUTER_WRT300NV11;
1303                 } else if (nvram_match("boot_hw_model", "WRT150N")
1304                            && nvram_match("boot_hw_ver", "1")) {
1305                         setRouter("Linksys WRT150N v1");
1306                         return ROUTER_WRT150N;
1307                 } else if (nvram_match("boot_hw_model", "WRT150N")
1308                            && nvram_match("boot_hw_ver", "1.1")) {
1309                         setRouter("Linksys WRT150N v1.1");
1310                         // return ROUTER_WRT150NV11;
1311                         return ROUTER_WRT150N;
1312                 } else if (nvram_match("boot_hw_model", "WRT150N")
1313                            && nvram_match("boot_hw_ver", "1.2")) {
1314                         setRouter("Linksys WRT150N v1.2");
1315                         // return ROUTER_WRT150NV12;
1316                         return ROUTER_WRT150N;
1317                 } else if (nvram_match("boot_hw_model", "WRT160N")
1318                            && nvram_match("boot_hw_ver", "1.0")) {
1319                         setRouter("Linksys WRT160N");
1320                         return ROUTER_WRT160N;
1321                 } else if (nvram_match("boot_hw_model", "WRT310N")
1322                            && nvram_match("boot_hw_ver", "1.0")) {
1323                         setRouter("Linksys WRT310N");
1324                         return ROUTER_WRT310N;
1325                 }
1326         }
1327
1328         if (boardnum == 42 && nvram_match("boardtype", "0x0472")
1329             && nvram_match("cardbus", "1")) {
1330                 setRouter("Linksys WRT300N v1");
1331                 return ROUTER_WRT300N;
1332         }
1333
1334         if (boardnum == 42 &&
1335             nvram_match("boardtype", "0x478") && nvram_match("cardbus", "1")) {
1336                 cprintf("router is Linksys WRT350N\n");
1337                 setRouter("Linksys WRT350N");
1338                 return ROUTER_WRT350N;
1339         }
1340
1341         if (nvram_match("boardnum", "20070615") &&
1342             nvram_match("boardtype", "0x478") && nvram_match("cardbus", "0")
1343             && nvram_match("switch_type", "BCM5395")) {
1344                 cprintf("router is Linksys WRT600N v1.1\n");
1345                 setRouter("Linksys WRT600N v1.1");
1346                 return ROUTER_WRT600N;
1347         }
1348
1349         if (nvram_match("boardnum", "20070615") &&
1350             nvram_match("boardtype", "0x478") && nvram_match("cardbus", "0")) {
1351                 cprintf("router is Linksys WRT600N\n");
1352                 setRouter("Linksys WRT600N");
1353                 return ROUTER_WRT600N;
1354         }
1355
1356         if (nvram_match("boardtype", "0x478")
1357             && nvram_match("boot_hw_model", "WRT610N")) {
1358                 cprintf("router is Linksys WRT610N\n");
1359                 setRouter("Linksys WRT610N");
1360                 return ROUTER_WRT610N;
1361         }
1362
1363         if (boardnum == 42 && nvram_match("boardtype", "bcm94710dev")) {
1364                 cprintf("router is Linksys WRT54G v1.x\n");
1365                 setRouter("Linksys WRT54G v1.x");
1366                 return ROUTER_WRT54G1X;
1367         }
1368
1369         if ((boardnum == 1 || boardnum == 0)
1370             && nvram_match("boardtype", "0x0446")) {
1371                 cprintf("router is U.S. Robotics USR5430\n");
1372                 setRouter("U.S.Robotics USR5430");
1373                 return ROUTER_USR_5430;
1374         }
1375
1376         if (boardnum == 1 && nvram_match("boardtype", "0x456")
1377             && nvram_match("test_led_gpio", "0")) {
1378                 cprintf("router is Netgear WG602 v3\n");
1379                 setRouter("Netgear WG602 v3");
1380                 return ROUTER_NETGEAR_WG602_V3;
1381         }
1382
1383         if (boardnum == 10496 && nvram_match("boardtype", "0x456")) {
1384                 cprintf("router is U.S. Robotics USR5461\n");
1385                 setRouter("U.S.Robotics USR5461");
1386                 return ROUTER_USR_5461;
1387         }
1388
1389         if (boardnum == 10500 && nvram_match("boardtype", "0x456")) {
1390                 cprintf("router is U.S. Robotics USR5432\n");
1391                 setRouter("U.S.Robotics USR5432");
1392                 return ROUTER_USR_5461; // should work in the same way
1393         }
1394
1395         if (boardnum == 10506 && nvram_match("boardtype", "0x456")) {
1396                 cprintf("router is U.S. Robotics USR5451\n");
1397                 setRouter("U.S.Robotics USR5451");
1398                 return ROUTER_USR_5461; // should work in the same way
1399         }
1400
1401         if (boardnum == 10512 && nvram_match("boardtype", "0x456")) {
1402                 cprintf("router is U.S. Robotics USR5441\n");
1403                 setRouter("U.S.Robotics USR5441");
1404                 return ROUTER_USR_5461; // should work in the same way
1405         }
1406
1407         if (boardnum == 1024 && nvram_match("boardtype", "0x0446")) {
1408                 char *cfe = nvram_safe_get("cfe_version");
1409
1410                 if (strstr(cfe, "iewsonic")) {
1411                         cprintf("router is Viewsonic WAPBR-100\n");
1412                         setRouter("Viewsonic WAPBR-100");
1413                         return ROUTER_VIEWSONIC_WAPBR_100;
1414                 } else {
1415                         cprintf("router is Linksys WAP54G v2\n");
1416                         setRouter("Linksys WAP54G v2");
1417                         return ROUTER_WAP54G_V2;
1418                 }
1419         }
1420
1421         if (nvram_invmatch("CFEver", "")) {
1422                 char *cfe = nvram_safe_get("CFEver");
1423
1424                 if (!strncmp(cfe, "MotoWR", 6)) {
1425                         cprintf("router is motorola\n");
1426                         setRouter("Motorola WR850G v2/v3");
1427                         return ROUTER_MOTOROLA;
1428                 }
1429         }
1430
1431         if (boardnum == 44 && (nvram_match("boardtype", "0x0101")
1432                                || nvram_match("boardtype", "0x0101\r"))) {
1433                 char *cfe = nvram_safe_get("CFEver");
1434
1435                 if (!strncmp(cfe, "GW_WR110G", 9)) {
1436                         cprintf("router is Sparklan WX-6615GT\n");
1437                         setRouter("Sparklan WX-6615GT");
1438                         return ROUTER_DELL_TRUEMOBILE_2300_V2;
1439                 } else {
1440                         cprintf("router is Dell TrueMobile 2300 v2\n");
1441                         setRouter("Dell TrueMobile 2300 v2");
1442                         return ROUTER_DELL_TRUEMOBILE_2300_V2;
1443                 }
1444         }
1445 #endif
1446         if (nvram_match("boardtype", "bcm94710ap")) {
1447                 cprintf("router is Buffalo old 4710\n");
1448                 setRouter("Buffalo WBR-B11");
1449                 return ROUTER_BUFFALO_WBR54G;
1450         }
1451 #ifndef HAVE_BUFFALO
1452         if (nvram_match("boardtype", "0x048e") &&
1453             nvram_match("boardrev", "0x35") &&
1454             nvram_match("sdram_init", "0x000b")) {
1455                 cprintf("router is D-Link DIR-320\n");
1456                 setRouter("D-Link DIR-320");
1457                 // apply some fixes
1458                 if (nvram_get("vlan2ports") != NULL) {
1459                         nvram_unset("vlan2ports");
1460                         nvram_unset("vlan2hwname");
1461                 }
1462                 return ROUTER_DLINK_DIR320;
1463         }
1464         if (nvram_match("model_name", "DIR-330") &&
1465             nvram_match("boardrev", "0x10")) {
1466                 cprintf("router is D-Link DIR-330\n");
1467                 setRouter("D-Link DIR-330");
1468                 nvram_set("wan_ifnames", "eth0");       // quirk
1469                 nvram_set("wan_ifname", "eth0");
1470                 if (nvram_match("et0macaddr", "00:90:4c:4e:00:0c")) {
1471                         FILE *in = fopen("/dev/mtdblock/1", "rb");
1472
1473                         fseek(in, 0x7a0022, SEEK_SET);
1474                         char mac[32];
1475
1476                         fread(mac, 32, 1, in);
1477                         fclose(in);
1478                         mac[17] = 0;
1479                         if (sv_valid_hwaddr(mac)) {
1480                                 nvram_set("et0macaddr", mac);
1481                                 fprintf(stderr, "restore D-Link MAC\n");
1482                                 nvram_commit();
1483                                 sys_reboot();
1484                         }
1485                 }
1486                 /*
1487                  * if (nvram_get("vlan2ports")!=NULL) { nvram_unset("vlan2ports");
1488                  * nvram_unset("vlan2hwname"); }
1489                  */
1490                 return ROUTER_DLINK_DIR330;
1491         }
1492         if (boardnum == 42 && nvram_match("boardtype", "0x048e")
1493             && nvram_match("boardrev", "0x10")) {
1494                 if (nvram_match("boardflags", "0x20750")) {
1495                 cprintf("router is wrt54g2v1/v1.3/gs2v1\n");
1496                 setRouter("Linksys WRT54G2 / GS2");
1497                 }
1498                 else {
1499                 cprintf("router is wrt54gv8/gsv7\n");
1500                 setRouter("Linksys WRT54Gv8 / GSv7");                   
1501                 }
1502                 return ROUTER_WRT54G_V8;
1503         }
1504
1505         if (boardnum == 8 && nvram_match("boardtype", "0x048e")
1506             && nvram_match("boardrev", "0x11")) {
1507                 cprintf("router is ALLNET01\n");
1508                 setRouter("ALLNET EUROWRT 54");
1509                 return ROUTER_ALLNET01;
1510         }
1511
1512         if (boardnum == 01 && nvram_match("boardtype", "0x048e")
1513             && nvram_match("boardrev", "0x11")
1514             && (nvram_match("boardflags", "0x650")
1515                 || nvram_match("boardflags", "0x0458"))) {
1516                 cprintf("router is Netgear WG602 v4\n");
1517                 setRouter("Netgear WG602 v4");
1518                 return ROUTER_NETGEAR_WG602_V4;
1519         }
1520
1521         if (boardnum == 1 && nvram_match("boardtype", "0x048e")
1522             && nvram_match("boardrev", "0x35")
1523             && nvram_match("parefldovoltage", "0x28")) {
1524                 cprintf("router is netcore nw618\n");
1525                 setRouter("NetCore NW618");
1526                 return ROUTER_WRT54G;
1527         }
1528
1529         if (boardnum == 42 && nvram_match("boardtype", "0x048E")
1530             && nvram_match("boardrev", "0x10")) {
1531                 cprintf("router is Linksys WRH54G\n");
1532                 setRouter("Linksys WRH54G");
1533                 return ROUTER_LINKSYS_WRH54G;
1534         }
1535
1536         if (nvram_match("boardnum", "00") && nvram_match("boardtype", "0x048E")
1537             && nvram_match("boardrev", "0x10")) {
1538                 cprintf("router is Linksys WRT54G v8.1\n");
1539                 setRouter("Linksys WRT54G v8.1");
1540                 return ROUTER_WRT54G_V81;
1541         }
1542
1543         if (boardnum == 45 && nvram_match("boardtype", "0x456")) {
1544                 cprintf("router is Asus WL-520G\n");
1545                 setRouter("Asus WL-520G");
1546                 return ROUTER_ASUS_WL520G;
1547         }
1548
1549         if (nvram_match("boardtype", "0x48E")
1550             && nvram_match("boardrev", "0x10")) {
1551                 char *hwver = nvram_safe_get("hardware_version");
1552
1553                 if (boardnum == 45 && startswith(hwver, "WL500GPV2")) {
1554                         cprintf("router is Asus WL-500G Premium V2\n");
1555                         setRouter("Asus WL-500G Premium V2");
1556                         return ROUTER_ASUS_WL500G_PRE_V2;
1557                 } else if (boardnum == 45 && startswith(hwver, "WL330GE")) {
1558                         cprintf("router is Asus WL-330GE\n");
1559                         setRouter("Asus WL-330GE");
1560                         return ROUTER_ASUS_330GE;
1561                 } else if (boardnum == 45 || startswith(hwver, "WL500GU")
1562                            || startswith(hwver, "WL500GC")) {
1563                         cprintf("router is Asus WL-520GU/GC\n");
1564                         setRouter("Asus WL-520GU/GC");
1565                         return ROUTER_ASUS_WL520GUGC;
1566                 }
1567         }
1568
1569         if ((boardnum == 83258 || boardnum == 1 || boardnum == 0123)    //or 01 or 001 or 0x01
1570             && (nvram_match("boardtype", "0x048e")
1571                 || nvram_match("boardtype", "0x48E"))
1572             && (nvram_match("boardrev", "0x11")
1573                 || nvram_match("boardrev", "0x10"))
1574             && (nvram_match("boardflags", "0x750")
1575                 || nvram_match("boardflags", "0x0750"))) {
1576                 if (nvram_match("sdram_init", "0x000A"))        //16 MB ram
1577                 {
1578                         cprintf("router is Netgear WGR614v8/L/WW\n");
1579                         setRouter("Netgear WGR614v8/L/WW");
1580                         return ROUTER_NETGEAR_WGR614L;
1581                 } else if (nvram_match("sdram_init", "0x0002")) //8 MB ram
1582                 {
1583                         cprintf("router is Netgear WGR614v9\n");
1584                         setRouter("Netgear WGR614v9");
1585                         return ROUTER_NETGEAR_WGR614L;
1586                 }
1587         }
1588
1589         if (boardnum == 56 && nvram_match("boardtype", "0x456")
1590             && nvram_match("boardrev", "0x10")) {
1591                 cprintf("router is wtr54gs\n");
1592                 setRouter("Linksys WTR54GS");
1593                 return ROUTER_LINKSYS_WTR54GS;
1594         }
1595
1596         if (nvram_match("boardnum", "WAP54GV3_8M_0614")
1597             && (nvram_match("boardtype", "0x0467")
1598                 || nvram_match("boardtype", "0x467"))
1599             && nvram_match("WAPver", "3")) {
1600                 cprintf("router is WAP54G v3.x\n");
1601                 setRouter("Linksys WAP54G v3.x");
1602                 return ROUTER_WAP54G_V3;
1603         }
1604
1605         setRouter("Linksys WRT54G/GL/GS");
1606         cprintf("router is wrt54g\n");
1607         return ROUTER_WRT54G;
1608 #else
1609         eval("event", "3", "1", "15");
1610         return 0;
1611 #endif
1612 #endif
1613 #endif
1614 }
1615
1616 static int router_type = -1;
1617 int getRouterBrand()
1618 {
1619         if (router_type == -1)
1620                 router_type = internal_getRouterBrand();
1621         return router_type;
1622 }
1623
1624 int get_ppp_pid(char *file)
1625 {
1626         char buf[80];
1627         int pid = -1;
1628
1629         if (file_to_buf(file, buf, sizeof(buf))) {
1630                 char tmp[80], tmp1[80];
1631
1632                 snprintf(tmp, sizeof(tmp), "/var/run/%s.pid", buf);
1633                 file_to_buf(tmp, tmp1, sizeof(tmp1));
1634                 pid = atoi(tmp1);
1635         }
1636         return pid;
1637 }
1638
1639 int check_wan_link(int num)
1640 {
1641         int wan_link = 0;
1642
1643         if (nvram_match("wan_proto", "pptp")
1644             || nvram_match("wan_proto", "l2tp")
1645             || nvram_match("wan_proto", "pppoe")
1646             || nvram_match("wan_proto", "3g")
1647             || nvram_match("wan_proto", "heartbeat")) {
1648                 FILE *fp;
1649                 char filename[80];
1650                 char *name;
1651
1652                 if (num == 0)
1653                         strcpy(filename, "/tmp/ppp/link");
1654                 if ((fp = fopen(filename, "r"))) {
1655                         int pid = -1;
1656
1657                         fclose(fp);
1658                         if (nvram_match("wan_proto", "heartbeat")) {
1659                                 char buf[20];
1660
1661                                 file_to_buf("/tmp/ppp/link", buf, sizeof(buf));
1662                                 pid = atoi(buf);
1663                         } else
1664                                 pid = get_ppp_pid(filename);
1665
1666                         name = find_name_by_proc(pid);
1667                         if (!strncmp(name, "pppoecd", 7) ||     // for PPPoE
1668                             !strncmp(name, "pppd", 4) ||        // for PPTP
1669                             !strncmp(name, "bpalogin", 8))      // for HeartBeat
1670                                 wan_link = 1;   // connect
1671                         else {
1672                                 printf("The %s had been died, remove %s\n",
1673                                        nvram_safe_get("wan_proto"), filename);
1674                                 wan_link = 0;   // For some reason, the pppoed had been died,
1675                                 // by link file still exist.
1676                                 unlink(filename);
1677                         }
1678                 }
1679         } else {
1680                 if (nvram_invmatch("wan_ipaddr", "0.0.0.0"))
1681                         wan_link = 1;
1682         }
1683
1684         return wan_link;
1685 }
1686
1687 /*
1688  * Find process name by pid from /proc directory
1689  */
1690 char *find_name_by_proc(int pid)
1691 {
1692         FILE *fp;
1693         char line[254];
1694         char filename[80];
1695         static char name[80];
1696
1697         snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
1698
1699         if ((fp = fopen(filename, "r"))) {
1700                 fgets(line, sizeof(line), fp);
1701                 /*
1702                  * Buffer should contain a string like "Name: binary_name"
1703                  */
1704                 sscanf(line, "%*s %s", name);
1705                 fclose(fp);
1706                 return name;
1707         }
1708
1709         return "";
1710 }
1711
1712 int diag_led_4702(int type, int act)
1713 {
1714
1715 #if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || defined(HAVE_FONERA) || defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_WHRAG108) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_FONERA) || defined(HAVE_LSX) || defined(HAVE_DANUBE) || defined(HAVE_STORM) || defined(HAVE_ADM5120) || defined(HAVE_RT2880)
1716         return 0;
1717 #else
1718         if (act == START_LED) {
1719                 switch (type) {
1720                 case DMZ:
1721                         system2("echo 1 > /proc/sys/diag");
1722                         break;
1723                 }
1724         } else {
1725                 switch (type) {
1726                 case DMZ:
1727                         system2("echo 0 > /proc/sys/diag");
1728                         break;
1729                 }
1730         }
1731         return 0;
1732 #endif
1733 }
1734
1735 int C_led_4702(int i)
1736 {
1737 #if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || defined(HAVE_FONERA) || defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_WHRAG108) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_LSX) || defined(HAVE_DANUBE) || defined(HAVE_STORM) || defined(HAVE_ADM5120) || defined(HAVE_RT2880)
1738         return 0;
1739 #else
1740         FILE *fp;
1741         char string[10];
1742         int flg;
1743
1744         memset(string, 0, 10);
1745         /*
1746          * get diag before set
1747          */
1748         if ((fp = fopen("/proc/sys/diag", "r"))) {
1749                 fgets(string, sizeof(string), fp);
1750                 fclose(fp);
1751         } else
1752                 perror("/proc/sys/diag");
1753
1754         if (i)
1755                 flg = atoi(string) | 0x10;
1756         else
1757                 flg = atoi(string) & 0xef;
1758
1759         memset(string, 0, 10);
1760         sprintf(string, "%d", flg);
1761         if ((fp = fopen("/proc/sys/diag", "w"))) {
1762                 fputs(string, fp);
1763                 fclose(fp);
1764         } else
1765                 perror("/proc/sys/diag");
1766
1767         return 0;
1768 #endif
1769 }
1770
1771 unsigned int read_gpio(char *device)
1772 {
1773         FILE *fp;
1774         unsigned int val;
1775
1776         if ((fp = fopen(device, "r"))) {
1777                 fread(&val, 4, 1, fp);
1778                 fclose(fp);
1779                 // fprintf(stderr, "----- gpio %s = [%X]\n",device,val);
1780                 return val;
1781         } else {
1782                 perror(device);
1783                 return 0;
1784         }
1785 }
1786
1787 unsigned int write_gpio(char *device, unsigned int val)
1788 {
1789         FILE *fp;
1790
1791         if ((fp = fopen(device, "w"))) {
1792                 fwrite(&val, 4, 1, fp);
1793                 fclose(fp);
1794                 // fprintf(stderr, "----- set gpio %s = [%X]\n",device,val);
1795                 return 1;
1796         } else {
1797                 perror(device);
1798                 return 0;
1799         }
1800 }
1801
1802 static char hw_error = 0;
1803 int diag_led_4704(int type, int act)
1804 {
1805 #if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || defined(HAVE_FONERA) || defined(HAVE_MERAKI)|| defined(HAVE_LS2) || defined(HAVE_WHRAG108) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_LSX) || defined(HAVE_DANUBE) || defined(HAVE_STORM) || defined(HAVE_ADM5120) || defined(HAVE_RT2880)
1806         return 0;
1807 #else
1808         unsigned int control, in, outen, out;
1809
1810 #ifdef BCM94712AGR
1811         /*
1812          * The router will crash, if we load the code into broadcom demo board.
1813          */
1814         return 1;
1815 #endif
1816         // int brand;
1817         control = read_gpio("/dev/gpio/control");
1818         in = read_gpio("/dev/gpio/in");
1819         out = read_gpio("/dev/gpio/out");
1820         outen = read_gpio("/dev/gpio/outen");
1821
1822         write_gpio("/dev/gpio/outen", (outen & 0x7c) | 0x83);
1823         switch (type) {
1824         case DIAG:              // GPIO 1
1825                 if (hw_error) {
1826                         write_gpio("/dev/gpio/out", (out & 0x7c) | 0x00);
1827                         return 1;
1828                 }
1829
1830                 if (act == STOP_LED) {  // stop blinking
1831                         write_gpio("/dev/gpio/out", (out & 0x7c) | 0x83);
1832                         // cprintf("tallest:=====( DIAG STOP_LED !!)=====\n");
1833                 } else if (act == START_LED) {  // start blinking
1834                         write_gpio("/dev/gpio/out", (out & 0x7c) | 0x81);
1835                         // cprintf("tallest:=====( DIAG START_LED !!)=====\n");
1836                 } else if (act == MALFUNCTION_LED) {    // start blinking
1837                         write_gpio("/dev/gpio/out", (out & 0x7c) | 0x00);
1838                         hw_error = 1;
1839                         // cprintf("tallest:=====( DIAG MALFUNCTION_LED !!)=====\n");
1840                 }
1841                 break;
1842
1843         }
1844         return 1;
1845 #endif
1846 }
1847
1848 int diag_led_4712(int type, int act)
1849 {
1850         unsigned int control, in, outen, out, ctr_mask, out_mask;
1851
1852 #if defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_XSCALE) || defined(HAVE_MAGICBOX) || defined(HAVE_FONERA)|| defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_WHRAG108) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_LSX) || defined(HAVE_DANUBE) || defined(HAVE_STORM) || defined(HAVE_ADM5120) || defined(HAVE_RT2880)
1853         return 0;
1854 #else
1855
1856 #ifdef BCM94712AGR
1857         /*
1858          * The router will crash, if we load the code into broadcom demo board.
1859          */
1860         return 1;
1861 #endif
1862         control = read_gpio("/dev/gpio/control");
1863         in = read_gpio("/dev/gpio/in");
1864         out = read_gpio("/dev/gpio/out");
1865         outen = read_gpio("/dev/gpio/outen");
1866
1867         ctr_mask = ~(1 << type);
1868         out_mask = (1 << type);
1869
1870         write_gpio("/dev/gpio/control", control & ctr_mask);
1871         write_gpio("/dev/gpio/outen", outen | out_mask);
1872
1873         if (act == STOP_LED) {  // stop blinking
1874                 // cprintf("%s: Stop GPIO %d\n", __FUNCTION__, type);
1875                 write_gpio("/dev/gpio/out", out | out_mask);
1876         } else if (act == START_LED) {  // start blinking
1877                 // cprintf("%s: Start GPIO %d\n", __FUNCTION__, type);
1878                 write_gpio("/dev/gpio/out", out & ctr_mask);
1879         }
1880
1881         return 1;
1882 #endif
1883 }
1884
1885 int C_led_4712(int i)
1886 {
1887         if (i == 1)
1888                 return diag_led(DIAG, START_LED);
1889         else
1890                 return diag_led(DIAG, STOP_LED);
1891 }
1892
1893 int C_led(int i)
1894 {
1895         int brand = getRouterBrand();
1896
1897         if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
1898                 return C_led_4702(i);
1899         else if (brand == ROUTER_WRT54G)
1900                 return C_led_4712(i);
1901         else
1902                 return 0;
1903 }
1904
1905 int diag_led(int type, int act)
1906 {
1907         int brand = getRouterBrand();
1908
1909         if (brand == ROUTER_WRT54G || brand == ROUTER_WRT54G3G
1910             || brand == ROUTER_WRT300NV11)
1911                 return diag_led_4712(type, act);
1912         else if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
1913                 return diag_led_4702(type, act);
1914         else if ((brand == ROUTER_WRTSL54GS
1915                   || brand == ROUTER_WRT310N || brand == ROUTER_WRT350N
1916                   || brand == ROUTER_BUFFALO_WZRG144NH) && type == DIAG)
1917                 return diag_led_4704(type, act);
1918         else {
1919                 if (type == DMZ) {
1920                         if (act == START_LED)
1921                                 return led_control(LED_DMZ, LED_ON);
1922                         if (act == STOP_LED)
1923                                 return led_control(LED_DMZ, LED_OFF);
1924                         return 1;
1925                 }
1926         }
1927         return 0;
1928 }
1929
1930 #ifdef HAVE_MADWIFI
1931 static char *stalist[] = {
1932         "ath0", "ath1", "ath2", "ath3", "ath4", "ath5", "ath6", "ath8", "ath9"
1933 };
1934
1935 char *getWifi(char *ifname)
1936 {
1937         if (!strcmp(ifname, "ath0"))
1938                 return "wifi0";
1939         if (!strcmp(ifname, "ath1"))
1940                 return "wifi1";
1941         if (!strcmp(ifname, "ath2"))
1942                 return "wifi2";
1943         if (!strcmp(ifname, "ath3"))
1944                 return "wifi3";
1945         return NULL;
1946 }
1947
1948 char *getWDSSTA(void)
1949 {
1950
1951         int c = getifcount("wifi");
1952         int i;
1953
1954         for (i = 0; i < c; i++) {
1955                 char mode[32];
1956                 char netmode[32];
1957
1958                 sprintf(mode, "ath%d_mode", i);
1959                 sprintf(netmode, "ath%d_net_mode", i);
1960                 if (nvram_match(mode, "wdssta")
1961                     && !nvram_match(netmode, "disabled")) {
1962                         return stalist[i];
1963                 }
1964
1965         }
1966         return NULL;
1967 }
1968
1969 char *getSTA(void)
1970 {
1971
1972 #ifdef HAVE_WAVESAT
1973         if (nvram_match("ofdm_mode", "sta"))
1974                 return "ofdm";
1975 #endif
1976         int c = getifcount("wifi");
1977         int i;
1978
1979         for (i = 0; i < c; i++) {
1980                 char mode[32];
1981                 char netmode[32];
1982
1983                 sprintf(mode, "ath%d_mode", i);
1984                 sprintf(netmode, "ath%d_net_mode", i);
1985                 if (nvram_match(mode, "sta")
1986                     && !nvram_match(netmode, "disabled")) {
1987                         return stalist[i];
1988                 }
1989
1990         }
1991         return NULL;
1992 }
1993
1994 char *getWET(void)
1995 {
1996 #ifdef HAVE_WAVESAT
1997         if (nvram_match("ofdm_mode", "bridge"))
1998                 return "ofdm";
1999 #endif
2000         int c = getifcount("wifi");
2001         int i;
2002
2003         for (i = 0; i < c; i++) {
2004                 char mode[32];
2005                 char netmode[32];
2006
2007                 sprintf(mode, "ath%d_mode", i);
2008                 sprintf(netmode, "ath%d_net_mode", i);
2009                 if (nvram_match(mode, "wet")
2010                     && !nvram_match(netmode, "disabled")) {
2011                         return stalist[i];
2012                 }
2013
2014         }
2015         return NULL;
2016 }
2017
2018 #elif HAVE_RT2880
2019
2020 char *getSTA()
2021 {
2022         int c = get_wl_instances();
2023         int i;
2024
2025         for (i = 0; i < c; i++) {
2026                 if (nvram_nmatch("sta", "wl%d_mode", i)) {
2027                         if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2028                                 return "ra0";
2029                 }
2030
2031                 if (nvram_nmatch("apsta", "wl%d_mode", i)) {
2032                         if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2033                                 return "apcli0";
2034                 }
2035
2036         }
2037         return NULL;
2038 }
2039
2040 char *getWET()
2041 {
2042         int c = get_wl_instances();
2043         int i;
2044
2045         for (i = 0; i < c; i++) {
2046                 if (!nvram_nmatch("disabled", "wl%d_net_mode", i)
2047                     && nvram_nmatch("wet", "wl%d_mode", i))
2048                         return "ra0";
2049
2050                 if (!nvram_nmatch("disabled", "wl%d_net_mode", i)
2051                     && nvram_nmatch("apstawet", "wl%d_mode", i))
2052                         return "apcli0";
2053
2054         }
2055         return NULL;
2056 }
2057
2058 #else
2059 char *getSTA()
2060 {
2061         int c = get_wl_instances();
2062         int i;
2063
2064         for (i = 0; i < c; i++) {
2065                 if (nvram_nmatch("sta", "wl%d_mode", i)
2066                     || nvram_nmatch("apsta", "wl%d_mode", i)) {
2067                         if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2068                                 return get_wl_instance_name(i);
2069                         // else
2070                         // return nvram_nget ("wl%d_ifname", i);
2071                 }
2072
2073         }
2074         return NULL;
2075 }
2076
2077 char *getWET()
2078 {
2079         int c = get_wl_instances();
2080         int i;
2081
2082         for (i = 0; i < c; i++) {
2083                 if (nvram_nmatch("wet", "wl%d_mode", i)
2084                     || nvram_nmatch("apstawet", "wl%d_mode", i)) {
2085                         if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2086                                 return get_wl_instance_name(i);
2087                         // else
2088                         // return nvram_nget ("wl%d_ifname", i);
2089
2090                 }
2091
2092         }
2093         return NULL;
2094 }
2095
2096 #endif
2097 // note - broadcast addr returned in ipaddr
2098 void get_broadcast(char *ipaddr, char *netmask)
2099 {
2100         int ip2[4], mask2[4];
2101         unsigned char ip[4], mask[4];
2102
2103         if (!ipaddr || !netmask)
2104                 return;
2105
2106         sscanf(ipaddr, "%d.%d.%d.%d", &ip2[0], &ip2[1], &ip2[2], &ip2[3]);
2107         sscanf(netmask, "%d.%d.%d.%d", &mask2[0], &mask2[1], &mask2[2],
2108                &mask2[3]);
2109         int i = 0;
2110
2111         for (i = 0; i < 4; i++) {
2112                 ip[i] = ip2[i];
2113                 mask[i] = mask2[i];
2114                 // ip[i] = (ip[i] & mask[i]) | !mask[i];
2115                 ip[i] = (ip[i] & mask[i]) | (0xff & ~mask[i]);
2116         }
2117
2118         sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
2119 #ifdef WDS_DEBUG
2120         fprintf(fp, "get_broadcast return %s\n", value);
2121 #endif
2122
2123 }
2124
2125 char *get_wan_face(void)
2126 {
2127         static char localwanface[IFNAMSIZ];
2128
2129         /*
2130          * if (nvram_match ("pptpd_client_enable", "1")) { strncpy (localwanface,
2131          * "ppp0", IFNAMSIZ); return localwanface; }
2132          */
2133         if (nvram_match("wan_proto", "pptp")
2134             || nvram_match("wan_proto", "l2tp")
2135             || nvram_match("wan_proto", "3g")
2136             || nvram_match("wan_proto", "pppoe")) {
2137                 if (nvram_match("pppd_pppifname", ""))
2138                         strncpy(localwanface, "ppp0", IFNAMSIZ);
2139                 else
2140                         strncpy(localwanface, nvram_safe_get("pppd_pppifname"),
2141                                 IFNAMSIZ);
2142         }
2143 #ifndef HAVE_MADWIFI
2144         else if (getSTA()) {
2145                 strcpy(localwanface, getSTA());
2146         }
2147 #else
2148         else if (getSTA()) {
2149                 if (nvram_match("wifi_bonding", "1"))
2150                         strcpy(localwanface, "bond0");
2151                 else
2152                         strcpy(localwanface, getSTA());
2153         }
2154 #endif
2155         else
2156                 strncpy(localwanface, nvram_safe_get("wan_ifname"), IFNAMSIZ);
2157
2158         return localwanface;
2159 }
2160
2161 static int _pidof(const char *name, pid_t ** pids)
2162 {
2163         const char *p;
2164         char *e;
2165         DIR *dir;
2166         struct dirent *de;
2167         pid_t i;
2168         int count;
2169         char buf[256];
2170
2171         count = 0;
2172         *pids = NULL;
2173         if ((p = strchr(name, '/')) != NULL)
2174                 name = p + 1;
2175         if ((dir = opendir("/proc")) != NULL) {
2176                 while ((de = readdir(dir)) != NULL) {
2177                         i = strtol(de->d_name, &e, 10);
2178                         if (*e != 0)
2179                                 continue;
2180                         if (strcmp(name, psname(i, buf, sizeof(buf))) == 0) {
2181                                 if ((*pids =
2182                                      realloc(*pids,
2183                                              sizeof(pid_t) * (count + 1))) ==
2184                                     NULL) {
2185                                         return -1;
2186                                 }
2187                                 (*pids)[count++] = i;
2188                         }
2189                 }
2190         }
2191         closedir(dir);
2192         return count;
2193 }
2194
2195 int pidof(const char *name)
2196 {
2197         pid_t *pids;
2198         pid_t p;
2199
2200         if (_pidof(name, &pids) > 0) {
2201                 p = *pids;
2202                 free(pids);
2203                 return p;
2204         }
2205         return -1;
2206 }
2207
2208 int killall(const char *name, int sig)
2209 {
2210         pid_t *pids;
2211         int i;
2212         int r;
2213
2214         if ((i = _pidof(name, &pids)) > 0) {
2215                 r = 0;
2216                 do {
2217                         r |= kill(pids[--i], sig);
2218                 }
2219                 while (i > 0);
2220                 free(pids);
2221                 return r;
2222         }
2223         return -2;
2224 }
2225
2226 void set_ip_forward(char c)
2227 {
2228         FILE *fp;
2229
2230         if ((fp = fopen("/proc/sys/net/ipv4/ip_forward", "r+"))) {
2231                 fputc(c, fp);
2232                 fclose(fp);
2233         } else {
2234                 perror("/proc/sys/net/ipv4/ip_forward");
2235         }
2236 }
2237
2238 int ifexists(const char *ifname)
2239 {
2240         return getifcount(ifname) > 0 ? 1 : 0;
2241 }
2242
2243 int getifcount(const char *ifprefix)
2244 {
2245         /*
2246          * char devcall[128];
2247          *
2248          * sprintf (devcall, "cat /proc/net/dev|grep \"%s\"|wc -l", ifprefix);
2249          * FILE *in = popen (devcall, "rb"); if (in == NULL) return 0; int count;
2250          * fscanf (in, "%d", &count); pclose (in); return count;
2251          */
2252         char *iflist = malloc(256);
2253
2254         memset(iflist, 0, 256);
2255         int c = getIfList(iflist, ifprefix);
2256
2257         free(iflist);
2258         return c;
2259 }
2260
2261 static void skipline(FILE * in)
2262 {
2263         while (1) {
2264                 int c = getc(in);
2265
2266                 if (c == EOF)
2267                         return;
2268                 if (c == 0x0)
2269                         return;
2270                 if (c == 0xa)
2271                         return;
2272         }
2273 }
2274
2275 /*
2276  * strips trailing char(s) c from string
2277  */
2278 void strtrim_right(char *p, int c)
2279 {
2280         char *end;
2281         int len;
2282
2283         len = strlen(p);
2284         while (*p && len) {
2285                 end = p + len - 1;
2286                 if (c == *end)
2287                         *end = 0;
2288                 else
2289                         break;
2290                 len = strlen(p);
2291         }
2292         return;
2293 }
2294
2295 // returns a physical interfacelist filtered by ifprefix. if ifprefix is
2296 // NULL, all valid interfaces will be returned
2297 int getIfList(char *buffer, const char *ifprefix)
2298 {
2299         FILE *in = fopen("/proc/net/dev", "rb");
2300         char ifname[32];
2301
2302         // skip the first 2 lines
2303         skipline(in);
2304         skipline(in);
2305         int ifcount = 0;
2306         int count = 0;
2307
2308         while (1) {
2309                 int c = getc(in);
2310
2311                 if (c == EOF) {
2312                         if (count)
2313                                 buffer[strlen(buffer) - 1] = 0; // fixup last space
2314                         fclose(in);
2315                         return count;
2316                 }
2317                 if (c == 0) {
2318                         if (count)
2319                                 buffer[strlen(buffer) - 1] = 0; // fixup last space
2320                         fclose(in);
2321                         return count;
2322                 }
2323                 if (c == 0x20)
2324                         continue;
2325                 if (c == ':' || ifcount == 30) {
2326                         ifname[ifcount++] = 0;
2327                         int skip = 0;
2328
2329                         if (ifprefix) {
2330                                 if (strncmp(ifname, ifprefix, strlen(ifprefix))) {
2331                                         skip = 1;
2332                                 }
2333                         } else {
2334                                 if (!strncmp(ifname, "wifi", 4))
2335                                         skip = 1;
2336                                 if (!strncmp(ifname, "ifb", 3))
2337                                         skip = 1;
2338                                 if (!strncmp(ifname, "imq", 3))
2339                                         skip = 1;
2340                                 if (!strncmp(ifname, "etherip", 7))
2341                                         skip = 1;
2342                                 if (!strncmp(ifname, "lo", 2))
2343                                         skip = 1;
2344                                 if (!strncmp(ifname, "teql", 4))
2345                                         skip = 1;
2346                                 if (!strncmp(ifname, "gre", 3))
2347                                         skip = 1;
2348                                 if (!strncmp(ifname, "ppp", 3))
2349                                         skip = 1;
2350                                 if (!strncmp(ifname, "tun", 3))
2351                                         skip = 1;
2352                                 if (!strncmp(ifname, "tap", 3))
2353                                         skip = 1;
2354                         }
2355                         if (!skip) {
2356                                 strcat(buffer, ifname);
2357                                 strcat(buffer, " ");
2358                                 count++;
2359                         }
2360                         skip = 0;
2361                         ifcount = 0;
2362                         memset(ifname, 0, 32);
2363                         skipline(in);
2364                         continue;
2365                 }
2366                 if (ifcount < 30)
2367                         ifname[ifcount++] = c;
2368         }
2369 }
2370
2371 /*
2372  * Example: legal_hwaddr("00:11:22:33:44:aB"); return true;
2373  * legal_hwaddr("00:11:22:33:44:5"); return false;
2374  * legal_hwaddr("00:11:22:33:44:HH"); return false;
2375  */
2376 int sv_valid_hwaddr(char *value)
2377 {
2378         unsigned int hwaddr[6];
2379         int tag = TRUE;
2380         int i, count;
2381
2382         /*
2383          * Check for bad, multicast, broadcast, or null address
2384          */
2385         for (i = 0, count = 0; *(value + i); i++) {
2386                 if (*(value + i) == ':') {
2387                         if ((i + 1) % 3 != 0) {
2388                                 tag = FALSE;
2389                                 break;
2390                         }
2391                         count++;
2392                 } else if (ishexit(*(value + i)))       /* one of 0 1 2 3 4 5 6 7 8 9
2393                                                          * a b c d e f A B C D E F */
2394                         continue;
2395                 else {
2396                         tag = FALSE;
2397                         break;
2398                 }
2399         }
2400
2401         if (!tag || i != 17 || count != 5)      /* must have 17's characters and 5's
2402                                                  * ':' */
2403                 tag = FALSE;
2404         else if (sscanf(value, "%x:%x:%x:%x:%x:%x",
2405                         &hwaddr[0], &hwaddr[1], &hwaddr[2],
2406                         &hwaddr[3], &hwaddr[4], &hwaddr[5]) != 6) {
2407                 tag = FALSE;
2408         } else
2409                 tag = TRUE;
2410 #ifdef WDS_DEBUG
2411         if (tag == FALSE)
2412                 fprintf(fp, "failed valid_hwaddr\n");
2413 #endif
2414
2415         return tag;
2416 }
2417
2418 int led_control(int type, int act)
2419 /*
2420  * type: LED_POWER, LED_DIAG, LED_DMZ, LED_CONNECTED, LED_BRIDGE, LED_VPN,
2421  * LED_SES, LED_SES2, LED_WLAN act: LED_ON, LED_OFF, LED_FLASH
2422  */
2423 {
2424 #if (defined(HAVE_GEMTEK) || defined(HAVE_RB500) || defined(HAVE_MAGICBOX) || defined(HAVE_MERAKI) || defined(HAVE_LS2) || defined(HAVE_X86) || defined(HAVE_CA8) || defined(HAVE_LS5) )  && (!defined(HAVE_DIR300) && !defined(HAVE_WRT54G2) && !defined(HAVE_DIR400) && !defined(HAVE_BWRG1000))
2425         return 0;
2426 #else
2427         int use_gpio = 0x0ff;
2428         int gpio_value;
2429         int enable;
2430         int disable;
2431
2432         int power_gpio = 0x0ff;
2433         int diag_gpio = 0x0ff;
2434         int dmz_gpio = 0x0ff;
2435         int connected_gpio = 0x0ff;
2436         int bridge_gpio = 0x0ff;
2437         int vpn_gpio = 0x0ff;
2438         int ses_gpio = 0x0ff;   // use for SES1 (Linksys), AOSS (Buffalo)
2439         int ses2_gpio = 0x0ff;
2440         int wlan_gpio = 0x0ff;  // use this only if wlan led is not controlled by hardware!
2441         int usb_gpio = 0x0ff;
2442         int sec0_gpio = 0x0ff;  // security leds, wrt600n
2443         int sec1_gpio = 0x0ff;
2444         int v1func = 0;
2445
2446         switch (getRouterBrand())       // gpio definitions here: 0xYZ,
2447                 // Y=0:normal, Y=1:inverted, Z:gpio
2448                 // number (f=disabled)
2449         {
2450 #ifndef HAVE_BUFFALO
2451         case ROUTER_ALLNET01:
2452                 connected_gpio = 0x100;
2453                 break;
2454         case ROUTER_BOARD_WP54G:
2455                 diag_gpio = 0x102;
2456                 connected_gpio = 0x107;
2457                 break;
2458         case ROUTER_BOARD_NP28G:
2459                 diag_gpio = 0x102;
2460                 connected_gpio = 0x106;
2461                 break;
2462         case ROUTER_BOARD_GATEWORX:
2463 #ifdef HAVE_WG302V1
2464                 diag_gpio = 0x104;
2465                 wlan_gpio = 0x105;
2466 #elif HAVE_WG302
2467                 diag_gpio = 0x102;
2468                 wlan_gpio = 0x104;
2469 #else
2470                 if (nvram_match("DD_BOARD", "Cambria GW2350")
2471                     || nvram_match("DD_BOARD2", "Cambria GW2350"))
2472                         connected_gpio = 0x105;
2473                 else if (nvram_match("DD_BOARD", "Cambria GW2358-4")
2474                          || nvram_match("DD_BOARD2", "Cambria GW2358-4"))
2475                         connected_gpio = 0x118;
2476                 else
2477                         connected_gpio = 0x003;
2478 #endif
2479                 break;
2480         case ROUTER_BOARD_GATEWORX_SWAP:
2481                 connected_gpio = 0x004;
2482                 break;
2483         case ROUTER_BOARD_STORM:
2484                 connected_gpio = 0x005;
2485                 diag_gpio = 0x003;
2486                 break;
2487         case ROUTER_LINKSYS_WRH54G:
2488                 diag_gpio = 0x101;      // power led blink / off to indicate factory
2489                 // defaults
2490                 break;
2491         case ROUTER_WRT54G:
2492         case ROUTER_WRT54G_V8:
2493                 power_gpio = 0x001;
2494                 dmz_gpio = 0x107;
2495                 connected_gpio = 0x103; // ses orange
2496                 ses_gpio = 0x102;       // ses white
2497                 ses2_gpio = 0x103;      // ses orange
2498                 break;
2499         case ROUTER_WRT54G_V81:
2500                 power_gpio = 0x101;
2501                 dmz_gpio = 0x102;
2502                 connected_gpio = 0x104; // ses orange
2503                 ses_gpio = 0x103;       // ses white
2504                 ses2_gpio = 0x104;      // ses orange
2505                 break;
2506         case ROUTER_WRT54G1X:
2507                 connected_gpio = 0x103;
2508                 v1func = 1;
2509                 break;
2510         case ROUTER_WRT350N:
2511                 connected_gpio = 0x103;
2512                 power_gpio = 0x001;
2513                 ses2_gpio = 0x103;      // ses orange
2514                 sec0_gpio = 0x109;
2515                 usb_gpio = 0x10b;
2516                 break;
2517         case ROUTER_WRT600N:
2518                 power_gpio = 0x102;
2519                 diag_gpio = 0x002;
2520                 usb_gpio = 0x103;
2521                 sec0_gpio = 0x109;
2522                 sec1_gpio = 0x10b;
2523                 break;
2524         case ROUTER_LINKSYS_WRT55AG:
2525                 connected_gpio = 0x103;
2526                 break;
2527         case ROUTER_DLINK_DIR330:
2528                 diag_gpio = 0x106;
2529                 connected_gpio = 0x100;
2530                 usb_gpio = 0x104;
2531                 break;
2532 #endif
2533         case ROUTER_BOARD_WHRG300N:
2534                 diag_gpio = 0x107;
2535                 connected_gpio = 0x109;
2536                 ses_gpio = 0x10e;
2537                 break;
2538         case ROUTER_BUFFALO_WBR54G:
2539                 diag_gpio = 0x107;
2540                 break;
2541         case ROUTER_BUFFALO_WBR2G54S:
2542                 diag_gpio = 0x001;
2543                 ses_gpio = 0x006;
2544                 break;
2545         case ROUTER_BUFFALO_WLA2G54C:
2546                 diag_gpio = 0x104;
2547                 ses_gpio = 0x103;
2548                 break;
2549         case ROUTER_BUFFALO_WLAH_G54:
2550                 diag_gpio = 0x107;
2551                 ses_gpio = 0x106;
2552                 break;
2553         case ROUTER_BUFFALO_WAPM_HP_AM54G54:
2554                 diag_gpio = 0x107;
2555                 ses_gpio = 0x101;
2556                 break;
2557         case ROUTER_BOARD_WHRAG108:
2558                 diag_gpio = 0x107;
2559                 bridge_gpio = 0x104;
2560                 ses_gpio = 0x100;
2561                 break;
2562         case ROUTER_BUFFALO_WHRG54S:
2563         case ROUTER_BUFFALO_WLI_TX4_G54HP:
2564                 diag_gpio = 0x107;     
2565                 if (nvram_match("DD_BOARD", "Buffalo WHR-G125"))
2566                 {
2567                 connected_gpio = 0x101;
2568                 sec0_gpio = 0x106;                     
2569                 }
2570                 else
2571                 {
2572                 bridge_gpio = 0x101;
2573                 ses_gpio = 0x106;
2574                 }
2575                 break;
2576         case ROUTER_BUFFALO_WZRRSG54:
2577                 diag_gpio = 0x107;
2578                 vpn_gpio = 0x101;
2579                 ses_gpio = 0x106;
2580                 break;
2581         case ROUTER_BUFFALO_WZRG300N:
2582                 diag_gpio = 0x107;
2583                 bridge_gpio = 0x101;
2584                 break;
2585         case ROUTER_BUFFALO_WZRG144NH:
2586                 diag_gpio = 0x103;
2587                 bridge_gpio = 0x101;
2588                 ses_gpio = 0x102;
2589                 break;
2590 #ifndef HAVE_BUFFALO
2591 #ifdef HAVE_DIR300
2592         case ROUTER_BOARD_FONERA:
2593                 diag_gpio = 0x003;
2594                 bridge_gpio = 0x004;
2595                 ses_gpio = 0x001;
2596                 break;
2597 #endif
2598 #ifdef HAVE_WRT54G2
2599         case ROUTER_BOARD_FONERA:
2600                 bridge_gpio = 0x004;
2601                 ses_gpio = 0x104;
2602                 diag_gpio = 0x103;
2603                 break;
2604 #endif
2605 #ifdef HAVE_BWRG1000
2606         case ROUTER_BOARD_LS2:
2607                 diag_gpio = 0x007;
2608                 break;
2609 #endif
2610 #ifdef HAVE_DIR400
2611         case ROUTER_BOARD_FONERA2200:
2612                 diag_gpio = 0x003;
2613                 bridge_gpio = 0x004;
2614                 ses_gpio = 0x001;
2615                 break;
2616 #endif
2617 #ifdef HAVE_WRK54G
2618         case ROUTER_BOARD_FONERA:
2619                 diag_gpio = 0x107;
2620                 dmz_gpio = 0x005;
2621                 break;
2622 #endif
2623         case ROUTER_BOARD_TW6600:
2624                 diag_gpio = 0x107;
2625                 bridge_gpio = 0x104;
2626                 ses_gpio = 0x100;
2627                 break;
2628         case ROUTER_MOTOROLA:
2629                 power_gpio = 0x001;
2630                 diag_gpio = 0x101;      // power led blink / off to indicate factory
2631                 // defaults
2632                 break;
2633         case ROUTER_RT210W:
2634                 power_gpio = 0x105;
2635                 diag_gpio = 0x005;      // power led blink / off to indicate factory
2636                 // defaults
2637                 connected_gpio = 0x100;
2638                 wlan_gpio = 0x103;
2639                 break;
2640         case ROUTER_RT480W:
2641         case ROUTER_BELKIN_F5D7230_V2000:
2642         case ROUTER_BELKIN_F5D7231:
2643                 power_gpio = 0x105;
2644                 diag_gpio = 0x005;      // power led blink / off to indicate factory
2645                 // defaults
2646                 connected_gpio = 0x100;
2647                 break;
2648         case ROUTER_MICROSOFT_MN700:
2649                 power_gpio = 0x006;
2650                 diag_gpio = 0x106;      // power led blink / off to indicate factory
2651                 // defaults
2652                 break;
2653         case ROUTER_ASUS_WL500GD:
2654         case ROUTER_ASUS_WL520GUGC:
2655                 diag_gpio = 0x000;      // power led blink / off to indicate factory
2656                 // defaults
2657                 break;
2658         case ROUTER_ASUS_WL500G_PRE:
2659                 power_gpio = 0x101;
2660                 diag_gpio = 0x001;      // power led blink / off to indicate factory
2661                 // defaults
2662                 break;
2663         case ROUTER_ASUS_WL550GE:
2664                 power_gpio = 0x102;
2665                 diag_gpio = 0x002;      // power led blink / off to indicate factory
2666                 // defaults
2667                 break;
2668         case ROUTER_WRT54G3G:
2669         case ROUTER_WRTSL54GS:
2670                 power_gpio = 0x001;
2671                 dmz_gpio = 0x100;
2672                 connected_gpio = 0x107; // ses orange
2673                 ses_gpio = 0x105;       // ses white
2674                 ses2_gpio = 0x107;      // ses orange
2675                 break;
2676         case ROUTER_MOTOROLA_WE800G:
2677         case ROUTER_MOTOROLA_V1:
2678                 diag_gpio = 0x103;
2679                 wlan_gpio = 0x101;
2680                 bridge_gpio = 0x105;
2681                 break;
2682         case ROUTER_DELL_TRUEMOBILE_2300:
2683         case ROUTER_DELL_TRUEMOBILE_2300_V2:
2684                 power_gpio = 0x107;
2685                 diag_gpio = 0x007;      // power led blink / off to indicate factory
2686                 // defaults
2687                 wlan_gpio = 0x106;
2688                 break;
2689         case ROUTER_NETGEAR_WNR834B:
2690                 power_gpio = 0x104;
2691                 diag_gpio = 0x105;
2692                 wlan_gpio = 0x106;
2693                 break;
2694         case ROUTER_SITECOM_WL105B:
2695                 power_gpio = 0x003;
2696                 diag_gpio = 0x103;      // power led blink / off to indicate factory
2697                 // defaults
2698                 wlan_gpio = 0x104;
2699                 break;
2700         case ROUTER_WRT150N:
2701         case ROUTER_WRT300N:
2702                 power_gpio = 0x001;
2703                 diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
2704                 break;
2705         case ROUTER_WRT300NV11:
2706                 ses_gpio = 0x105;
2707                 // diag_gpio = 0x11; //power led blink / off to indicate fac.def.
2708                 break;
2709         case ROUTER_WRT310N:
2710                 connected_gpio = 0x103;
2711                 power_gpio = 0x001;
2712                 diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
2713                 ses2_gpio = 0x103;      // ses orange
2714         case ROUTER_WRT160N:
2715                 power_gpio = 0x001;
2716                 diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
2717                 //
2718                 connected_gpio = 0x103; // ses orange
2719                 ses_gpio = 0x105;       // ses blue
2720                 break;
2721         case ROUTER_ASUS_WL500G:
2722                 power_gpio = 0x100;
2723                 diag_gpio = 0x000;      // power led blink /off to indicate factory
2724                 // defaults
2725                 break;
2726         case ROUTER_ASUS_WL500W:
2727                 power_gpio = 0x105;
2728                 diag_gpio = 0x005;      // power led blink /off to indicate factory
2729                 // defaults
2730                 break;
2731         case ROUTER_LINKSYS_WTR54GS:
2732                 diag_gpio = 0x001;
2733                 break;
2734         case ROUTER_WAP54G_V1:
2735                 diag_gpio = 0x103;
2736                 wlan_gpio = 0x104;      // LINK led
2737                 break;
2738         case ROUTER_WAP54G_V3:
2739                 ses_gpio = 0x10c;
2740                 connected_gpio = 0x006;
2741                 break;
2742         case ROUTER_NETGEAR_WNR834BV2:
2743                 power_gpio = 0x002;
2744                 diag_gpio = 0x003;      // power led amber
2745                 connected_gpio = 0x007; // WAN led green
2746                 break;
2747         case ROUTER_NETGEAR_WNDR3300:
2748                 power_gpio = 0x005;
2749                 diag_gpio = 0x105;      // power led blink /off to indicate factory defaults
2750                 connected_gpio = 0x007; // WAN led green
2751                 break;
2752         case ROUTER_ASKEY_RT220XD:
2753                 wlan_gpio = 0x100;
2754                 dmz_gpio = 0x101;       // not soldered
2755                 break;
2756         case ROUTER_WRT610N:
2757                 power_gpio = 0x001;
2758                 connected_gpio = 0x103; // ses amber
2759                 ses_gpio = 0x109;       // ses blue
2760                 usb_gpio = 0x100;
2761                 break;
2762         case ROUTER_USR_5461:
2763                 usb_gpio = 0x001;
2764                 break;
2765         case ROUTER_NETGEAR_WGR614L:
2766                 // power_gpio = 0x107;       // don't use - resets router
2767                 diag_gpio = 0x006;
2768                 connected_gpio = 0x104;
2769                 break;
2770         case ROUTER_NETGEAR_WG602_V4:
2771                 power_gpio = 0x101;     // trick: make lan led green for 100Mbps
2772                 break;
2773         case ROUTER_BELKIN_F5D7231_V2000:
2774                 connected_gpio = 0x104;
2775                 diag_gpio = 0x001;      // power led blink /off to indicate factory defaults
2776                 break;
2777
2778 #endif
2779         }
2780         if (type == LED_DIAG && v1func == 1) {
2781                 if (act == LED_ON)
2782                         C_led(1);
2783                 else
2784                         C_led(0);
2785         }
2786
2787         switch (type) {
2788         case LED_POWER:
2789                 use_gpio = power_gpio;
2790                 break;
2791         case LED_DIAG:
2792                 use_gpio = diag_gpio;
2793                 break;
2794         case LED_DMZ:
2795                 use_gpio = dmz_gpio;
2796                 break;
2797         case LED_CONNECTED:
2798                 use_gpio = connected_gpio;
2799                 break;
2800         case LED_BRIDGE:
2801                 use_gpio = bridge_gpio;
2802                 break;
2803         case LED_VPN:
2804                 use_gpio = vpn_gpio;
2805                 break;
2806         case LED_SES:
2807                 use_gpio = ses_gpio;
2808                 break;
2809         case LED_SES2:
2810                 use_gpio = ses2_gpio;
2811                 break;
2812         case LED_WLAN:
2813                 use_gpio = wlan_gpio;
2814                 break;
2815         case LED_USB:
2816                 use_gpio = usb_gpio;
2817                 break;
2818         case LED_SEC0:
2819                 use_gpio = sec0_gpio;
2820                 break;
2821         case LED_SEC1:
2822                 use_gpio = sec1_gpio;
2823                 break;
2824         }
2825         if ((use_gpio & 0x0ff) != 0x0ff) {
2826                 gpio_value = use_gpio & 0x0ff;
2827                 enable = (use_gpio & 0x100) == 0 ? 1 : 0;
2828                 disable = (use_gpio & 0x100) == 0 ? 0 : 1;
2829                 switch (act) {
2830                 case LED_ON:
2831                         set_gpio(gpio_value, enable);
2832                         break;
2833                 case LED_OFF:
2834                         set_gpio(gpio_value, disable);
2835                         break;
2836                 case LED_FLASH: // will lit the led for 1 sec.
2837                         set_gpio(gpio_value, enable);
2838                         sleep(1);
2839                         set_gpio(gpio_value, disable);
2840                         break;
2841                 }
2842         }
2843         return 1;
2844
2845 #endif
2846 }
2847
2848 int file_to_buf(char *path, char *buf, int len)
2849 {
2850         FILE *fp;
2851
2852         memset(buf, 0, len);
2853
2854         if ((fp = fopen(path, "r"))) {
2855                 fgets(buf, len, fp);
2856                 fclose(fp);
2857                 return 1;
2858         }
2859
2860         return 0;
2861 }
2862
2863 int ishexit(char c)
2864 {
2865
2866         if (strchr("01234567890abcdefABCDEF", c) != (char *)0)
2867                 return 1;
2868
2869         return 0;
2870 }
2871
2872 int getMTD(char *name)
2873 {
2874         char buf[128];
2875         int device;
2876
2877         sprintf(buf, "cat /proc/mtd|grep \"%s\"", name);
2878         FILE *fp = popen(buf, "rb");
2879
2880         fscanf(fp, "%s", &buf[0]);
2881         device = buf[3] - '0';
2882         pclose(fp);
2883         return device;
2884 }
2885
2886 int insmod(char *module)
2887 {
2888         return eval("insmod", module);
2889 }
2890
2891 void rmmod(char *module)
2892 {
2893         eval("rmmod", module);
2894 }
2895
2896 #include "revision.h"
2897
2898 char *getSoftwareRevision(void)
2899 {
2900         return "" SVN_REVISION "";
2901 }
2902
2903 #ifdef HAVE_OLED
2904 void initlcd()
2905 {
2906
2907 }
2908
2909 void lcdmessage(char *message)
2910 {
2911         eval("oled-print", "DD-WRT v24 sp2", "build:" SVN_REVISION,
2912              "3G/UMTS Router", message);
2913 }
2914
2915 void lcdmessaged(char *dual, char *message)
2916 {
2917
2918 }
2919
2920 #endif
2921
2922 #if 0
2923
2924 static int fd;
2925
2926 void SetEnvironment()
2927 {
2928         system("stty ispeed 2400 < /dev/tts/1");
2929         system("stty raw < /dev/tts/1");
2930 }
2931
2932 int Cmd = 254;                  /* EZIO Command */
2933 int cls = 1;                    /* Clear screen */
2934 void Cls()
2935 {
2936         write(fd, &Cmd, 1);
2937         write(fd, &cls, 1);
2938 }
2939
2940 int init = 0x28;
2941 void Init()
2942 {
2943         write(fd, &Cmd, 1);
2944         write(fd, &init, 1);
2945 }
2946
2947 int stopsend = 0x37;
2948 void StopSend()
2949 {
2950         write(fd, &Cmd, 1);
2951         write(fd, &init, 1);
2952 }
2953
2954 int home = 2;                   /* Home cursor */
2955 void Home()
2956 {
2957         write(fd, &Cmd, 1);
2958         write(fd, &home, 1);
2959 }
2960
2961 int readkey = 6;                /* Read key */
2962 void ReadKey()
2963 {
2964         write(fd, &Cmd, 1);
2965         write(fd, &readkey, 1);
2966 }
2967
2968 int blank = 8;                  /* Blank display */
2969 void Blank()
2970 {
2971         write(fd, &Cmd, 1);
2972         write(fd, &blank, 1);
2973 }
2974
2975 int hide = 12;                  /* Hide cursor & display blanked characters */
2976 void Hide()
2977 {
2978         write(fd, &Cmd, 1);
2979         write(fd, &hide, 1);
2980 }
2981
2982 int turn = 13;                  /* Turn On (blinking block cursor) */
2983 void TurnOn()
2984 {
2985         write(fd, &Cmd, 1);
2986         write(fd, &turn, 1);
2987 }
2988
2989 int show = 14;                  /* Show underline cursor */
2990 void Show()
2991 {
2992         write(fd, &Cmd, 1);
2993         write(fd, &show, 1);
2994 }
2995
2996 int movel = 16;                 /* Move cursor 1 character left */
2997 void MoveL()
2998 {
2999         write(fd, &Cmd, 1);
3000         write(fd, &movel, 1);
3001 }
3002
3003 int mover = 20;                 /* Move cursor 1 character right */
3004 void MoveR()
3005 {
3006         write(fd, &Cmd, 1);
3007         write(fd, &mover, 1);
3008 }
3009
3010 int scl = 24;                   /* Scroll cursor 1 character left */
3011 void ScrollL()
3012 {
3013         write(fd, &Cmd, 1);
3014         write(fd, &scl, 1);
3015 }
3016
3017 int scr = 28;                   /* Scroll cursor 1 character right */
3018 void ScrollR()
3019 {
3020         write(fd, &Cmd, 1);
3021         write(fd, &scr, 1);
3022 }
3023
3024 int setdis = 64;                /* Command */
3025 void SetDis()
3026 {
3027         write(fd, &Cmd, 1);
3028         write(fd, &setdis, 1);
3029
3030 }
3031
3032 int a, b;
3033 void ShowMessage(char *str1, char *str2)
3034 {
3035         char nul[] = "                                       ";
3036
3037         a = strlen(str1);
3038         b = 40 - a;
3039         write(fd, str1, a);
3040         write(fd, nul, b);
3041         write(fd, str2, strlen(str2));
3042 }
3043
3044 void initlcd()
3045 {
3046
3047         fd = open("/dev/tts/1", O_RDWR);
3048
3049                                   /** Open Serial port (COM2) */
3050         if (fd > 0) {
3051                 close(fd);
3052                 SetEnvironment();       /* Set RAW mode */
3053                 fd = open("/dev/tts/1", O_RDWR);
3054                 Init();         /* Initialize EZIO twice */
3055                 Init();
3056
3057                 Cls();          /* Clear screen */
3058         }
3059         close(fd);
3060 }
3061
3062 void lcdmessage(char *message)
3063 {
3064
3065         fd = open("/dev/tts/1", O_RDWR);
3066                                    /** Open Serial port (COM2) */
3067
3068         if (fd > 0) {
3069                 Init();         /* Initialize EZIO twice */
3070                 Init();
3071                 SetDis();
3072                 Cls();
3073                 Home();
3074                 ShowMessage("State", message);
3075                 close(fd);
3076         }
3077 }
3078
3079 void lcdmessaged(char *dual, char *message)
3080 {
3081
3082         fd = open("/dev/tts/1", O_RDWR);
3083
3084                                   /** Open Serial port (COM2) */
3085
3086         if (fd > 0) {
3087                 Init();         /* Initialize EZIO twice */
3088                 Init();
3089                 SetDis();
3090                 Cls();          /* Clear screen */
3091                 Home();
3092                 ShowMessage(dual, message);
3093                 close(fd);
3094         }
3095 }
3096
3097 #endif
3098 static int i64c(int i)
3099 {
3100         i &= 0x3f;
3101         if (i == 0)
3102                 return '.';
3103         if (i == 1)
3104                 return '/';
3105         if (i < 12)
3106                 return ('0' - 2 + i);
3107         if (i < 38)
3108                 return ('A' - 12 + i);
3109         return ('a' - 38 + i);
3110 }
3111
3112 int crypt_make_salt(char *p, int cnt, int x)
3113 {
3114         x += getpid() + time(NULL);
3115         do {
3116                 /*
3117                  * x = (x*1664525 + 1013904223) % 2^32 generator is lame (low-order
3118                  * bit is not "random", etc...), but for our purposes it is good
3119                  * enough
3120                  */
3121                 x = x * 1664525 + 1013904223;
3122                 /*
3123                  * BTW, Park and Miller's "minimal standard generator" is x = x*16807
3124                  * % ((2^31)-1) It has no problem with visibly alternating lowest bit
3125                  * but is also weak in cryptographic sense + needs div, which needs
3126                  * more code (and slower) on many CPUs
3127                  */
3128                 *p++ = i64c(x >> 16);
3129                 *p++ = i64c(x >> 22);
3130         }
3131         while (--cnt);
3132         *p = '\0';
3133         return x;
3134 }
3135
3136 #define MD5_OUT_BUFSIZE 36
3137
3138 char *zencrypt(char *passwd)
3139 {
3140         char salt[sizeof("$N$XXXXXXXX")];       /* "$N$XXXXXXXX" or "XX" */
3141         static char passout[MD5_OUT_BUFSIZE];
3142
3143         strcpy(salt, "$1$");
3144         crypt_make_salt(salt + 3, 4, 0);
3145         return md5_crypt(passout, (unsigned char *)passwd,
3146                          (unsigned char *)salt);
3147 }
Note: See TracBrowser for help on using the browser.