root/src/router/libutils/utils.c

Revision 12468, 77.6 kB (checked in by BrainSlayer, 4 months ago)

new definitions

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 defined(HAVE_CORENET) && defined(HAVE_NS2)
674         setRouter("CORENET XNS2");
675         return ROUTER_BOARD_LS2;
676 #elif defined(HAVE_CORENET) && defined(HAVE_LC2)
677         setRouter("CORENET XLO2");
678         return ROUTER_BOARD_LS2;
679 #elif defined(HAVE_CORENET) && defined(HAVE_EOC2610)
680         setRouter("CORENET XC61");
681         return ROUTER_BOARD_FONERA;
682 #elif defined(HAVE_CORENET) && defined(HAVE_EOC1650)
683         setRouter("CORENET XC65");
684         return ROUTER_BOARD_FONERA;
685 #elif defined(HAVE_CORENET) && defined(HAVE_BS2)
686         setRouter("CORENET XBU2");
687         return ROUTER_BOARD_LS2;
688 #elif defined(HAVE_CORENET) && defined(HAVE_BS2HP)
689         setRouter("CORENET MBU2i");
690         return ROUTER_BOARD_LS2;
691 #elif HAVE_WBD500
692         setRouter("Wiligear WBD-500");
693         return ROUTER_BOARD_FONERA;
694 #elif HAVE_EOC1650
695         setRouter("Senao EOC-1650");
696         return ROUTER_BOARD_FONERA;
697 #elif HAVE_EOC2610
698 #ifdef HAVE_TRIMAX
699         setRouter("TMAX-1200");
700 #else
701         setRouter("Senao EOC-2610");
702 #endif
703         return ROUTER_BOARD_FONERA;
704 #elif HAVE_ECB3500
705         setRouter("Senao ECB-3500");
706         return ROUTER_BOARD_FONERA;
707 #elif HAVE_EAP3660
708         setRouter("Senao EAP-3660");
709         return ROUTER_BOARD_FONERA;
710 #elif HAVE_MR3201A
711         setRouter("Accton MR3201A");
712         return ROUTER_BOARD_FONERA;
713 #elif HAVE_FONERA
714         struct mii_ioctl_data *data;
715         struct ifreq iwr;
716         char mac[32];
717         getBoardMAC(mac);
718         if (!strncmp(mac, "00:19:3B", 8) || !strncmp(mac, "00:02:6F", 8)
719             || !strncmp(mac, "00:15:6D", 8) || !strncmp(mac, "00:C0:CA", 8)) {
720                 fprintf(stderr, "unsupported board\n");
721                 sys_reboot();
722         }
723         int s = socket(AF_INET, SOCK_DGRAM, 0);
724
725         if (s < 0) {
726                 fprintf(stderr, "socket(SOCK_DRAGM)\n");
727                 setRouter("Fonera 2100/2200");
728                 return ROUTER_BOARD_FONERA;
729         }
730         (void)strncpy(iwr.ifr_name, "eth0", sizeof("eth0"));
731         data = (struct mii_ioctl_data *)&iwr.ifr_data;
732         data->phy_id = 0x10;
733         data->reg_num = 0x2;
734         ioctl(s, SIOCGMIIREG, &iwr);
735         data->phy_id = 0x10;
736         data->reg_num = 0x2;
737         ioctl(s, SIOCGMIIREG, &iwr);
738         if (data->val_out == 0x0141) {
739                 data->phy_id = 0x10;
740                 data->reg_num = 0x3;
741                 ioctl(s, SIOCGMIIREG, &iwr);
742                 close(s);
743                 if ((data->val_out & 0xfc00) != 0x0c00) // marvell phy
744                 {
745                         setRouter("Fonera 2100/2200");
746                         return ROUTER_BOARD_FONERA;
747                 } else {
748                         setRouter("Fonera 2201");
749                         return ROUTER_BOARD_FONERA2200;
750                 }
751         } else {
752                 setRouter("Fonera 2100/2200");
753                 return ROUTER_BOARD_FONERA;
754         }
755 #elif HAVE_MERAKI
756         setRouter("Meraki Mini");
757         return ROUTER_BOARD_MERAKI;
758 #elif HAVE_BWRG1000
759         setRouter("Bountiful BWRG-1000");
760         return ROUTER_BOARD_LS2;
761 #elif HAVE_NS2
762         setRouter("Ubiquiti Nanostation 2");
763         return ROUTER_BOARD_LS2;
764 #elif HAVE_EOC5610
765         setRouter("Senao EOC-5610");
766         return ROUTER_BOARD_LS2;
767 #elif HAVE_NS5
768         setRouter("Ubiquiti Nanostation 5");
769         return ROUTER_BOARD_LS2;
770 #elif HAVE_NS3
771         setRouter("Ubiquiti Nanostation 3");
772         return ROUTER_BOARD_LS2;
773 #elif HAVE_BS5
774         setRouter("Ubiquiti Bullet 5");
775         return ROUTER_BOARD_LS2;
776 #elif HAVE_BS2
777         setRouter("Ubiquiti Bullet 2");
778         return ROUTER_BOARD_LS2;
779 #elif HAVE_PICO2
780         setRouter("Ubiquiti PicoStation 2");
781         return ROUTER_BOARD_LS2;
782 #elif HAVE_PICO2HP
783         setRouter("Ubiquiti PicoStation 2 HP");
784         return ROUTER_BOARD_LS2;
785 #elif HAVE_PICO5
786         setRouter("Ubiquiti PicoStation 5");
787         return ROUTER_BOARD_LS2;
788 #elif HAVE_MS2
789         setRouter("Ubiquiti MiniStation");
790         return ROUTER_BOARD_LS2;
791 #elif HAVE_BS2HP
792         setRouter("Ubiquiti Bullet 2 HP");
793         return ROUTER_BOARD_LS2;
794 #elif HAVE_LC2
795         setRouter("Ubiquiti Nanostation Loco 2");
796         return ROUTER_BOARD_LS2;
797 #elif HAVE_LC5
798         setRouter("Ubiquiti Nanostation Loco 5");
799         return ROUTER_BOARD_LS2;
800 #elif HAVE_PS2
801         setRouter("Ubiquiti Powerstation 2");
802         return ROUTER_BOARD_LS2;
803 #elif HAVE_PS5
804         setRouter("Ubiquiti Powerstation 5");
805         return ROUTER_BOARD_LS2;
806 #elif HAVE_LS2
807         setRouter("Ubiquiti Litestation 2");
808         return ROUTER_BOARD_LS2;
809 #elif HAVE_LS5
810         setRouter("Ubiquiti Litestation 5");
811         return ROUTER_BOARD_LS2;
812 #elif HAVE_WHRAG108
813         setRouter("Buffalo WHR-HP-AG108");
814         return ROUTER_BOARD_WHRAG108;
815 #elif HAVE_PB42
816         setRouter("Atheros PB42");
817         return ROUTER_BOARD_PB42;
818 #elif HAVE_RS
819         #ifdef HAVE_DDLINK
820         setRouter("ddlink2x2");
821         #else
822         setRouter("Ubiquiti RouterStation");
823         #endif
824         return ROUTER_BOARD_PB42;
825 #elif HAVE_LSX
826         setRouter("Ubiquiti LSX");
827         return ROUTER_BOARD_PB42;
828 #elif HAVE_DANUBE
829         setRouter("Infineon Danube");
830         return ROUTER_BOARD_DANUBE;
831 #elif HAVE_STORM
832         setRouter("Wiligear WBD-111");
833         return ROUTER_BOARD_STORM;
834 #elif HAVE_TW6600
835         setRouter("AW-6660");
836         return ROUTER_BOARD_TW6600;
837 #elif HAVE_ALPHA
838         setRouter("Alfa Networks AP48");
839         return ROUTER_BOARD_CA8;
840 #elif HAVE_USR5453
841         setRouter("US Robotics USR5453");
842         return ROUTER_BOARD_CA8;
843 #elif HAVE_RDAT81
844         setRouter("Wistron RDAT-81");
845         return ROUTER_BOARD_RDAT81;
846 #elif HAVE_RCAA01
847         setRouter("Airlive WLA-9000AP");
848         return ROUTER_BOARD_RCAA01;
849 #elif HAVE_CA8PRO
850         setRouter("Wistron CA8-4 PRO");
851         return ROUTER_BOARD_CA8PRO;
852 #elif HAVE_CA8
853 #ifdef HAVE_WHA5500CPE
854         setRouter("Airlive WHA-5500CPE");
855 #elif HAVE_AIRMAX5
856         setRouter("Airlive AirMax 5");
857 #else
858         setRouter("Airlive WLA-5000AP");
859 #endif
860         return ROUTER_BOARD_CA8;
861 #else
862
863         uint boardnum = strtoul(nvram_safe_get("boardnum"), NULL, 0);
864
865         if (boardnum == 42 && nvram_match("boardtype", "bcm94710ap")) {
866                 cprintf("router is buffalo\n");
867                 setRouter("Buffalo WBR-G54 / WLA-G54");
868                 return ROUTER_BUFFALO_WBR54G;
869         }
870 #ifndef HAVE_BUFFALO
871         if (nvram_match("boardnum", "mn700") &&
872             nvram_match("boardtype", "bcm94710ap")) {
873                 cprintf("router is Microsoft MN-700\n");
874                 setRouter("Microsoft MN-700");
875                 return ROUTER_MICROSOFT_MN700;
876         }
877
878         if (nvram_match("boardnum", "asusX") &&
879             nvram_match("boardtype", "bcm94710dev")) {
880                 cprintf("router is Asus WL300g / WL500g\n");
881                 setRouter("Asus WL-300g / WL-500g");
882                 return ROUTER_ASUS_WL500G;
883         }
884
885         if (boardnum == 44 && nvram_match("boardtype", "bcm94710ap")) {
886                 cprintf("router is Dell TrueMobile 2300\n");
887                 setRouter("Dell TrueMobile 2300");
888                 return ROUTER_DELL_TRUEMOBILE_2300;
889         }
890 #endif
891
892         if (boardnum == 100 && nvram_match("boardtype", "bcm94710dev")) {
893                 cprintf("router is buffalo\n");
894                 setRouter("Buffalo WLA-G54C");
895                 return ROUTER_BUFFALO_WLAG54C;
896         }
897 #ifndef HAVE_BUFFALO
898         if (boardnum == 45 && nvram_match("boardtype", "bcm95365r")) {
899                 cprintf("router is Asus WL-500GD\n");
900                 setRouter("Asus WL-500g Deluxe");
901                 return ROUTER_ASUS_WL500GD;
902         }
903
904         if (boardnum == 45 && nvram_match("boardtype", "0x0472")
905             && nvram_match("boardrev", "0x23") && nvram_match("parkid", "1")) {
906                 cprintf("router is Asus WL-500W\n");
907                 setRouter("Asus WL-500W");
908                 return ROUTER_ASUS_WL500W;
909         }
910
911         if (boardnum == 45 && nvram_match("boardtype", "0x467")) {
912                 char *hwver0 = nvram_safe_get("hardware_version");
913
914                 if (startswith(hwver0, "WL320G")) {
915                         cprintf("router is Asus WL-320gE/gP\n");
916                         setRouter("Asus WL-320gE/gP");
917                         return ROUTER_ASUS_WL550GE;
918                 } else {
919                         cprintf("router is Asus WL-550gE\n");
920                         setRouter("Asus WL-550gE");
921                         return ROUTER_ASUS_WL550GE;
922                 }
923         }
924 #endif
925         if (nvram_match("boardnum", "00") && nvram_match("boardtype", "0x0101")
926             && nvram_match("boardrev", "0x10")) {
927                 cprintf("router is Buffalo wbr2\n");
928                 setRouter("Buffalo WBR2-G54 / WBR2-G54S");
929                 return ROUTER_BUFFALO_WBR2G54S;
930         }
931
932         if (boardnum == 2 && nvram_match("boardtype", "0x0101")
933             && nvram_match("boardrev", "0x10")) {
934                 cprintf("router is buffalo wla2-g54c\n");
935                 setRouter("Buffalo WLA2-G54C / WLI3-TX1-G54");
936                 return ROUTER_BUFFALO_WLA2G54C;
937         }
938         if (boardnum == 0 && nvram_match("melco_id", "29090")
939             && nvram_match("boardflags", "0x0010")
940             && nvram_match("boardrev", "0x10")) {
941                 cprintf("router is Buffalo WLAH-G54\n");
942                 setRouter("Buffalo WLAH-G54");
943                 return ROUTER_BUFFALO_WLAH_G54;
944
945         }
946         if (boardnum == 0 && nvram_match("melco_id", "31070")
947             && nvram_match("boardflags", "0x2288")
948             && nvram_match("boardrev", "0x10")) {
949                 cprintf("router is Buffalo WAPM-HP-AM54G54\n");
950                 setRouter("Buffalo WAPM-HP-AM54G54");
951                 return ROUTER_BUFFALO_WAPM_HP_AM54G54;
952         }
953         if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x11")
954             && nvram_match("boardtype", "0x048e")
955             && nvram_match("melco_id", "32093")) {
956                 cprintf("router is Buffalo WHR-G125\n");
957                 setRouter("Buffalo WHR-G125");
958                 return ROUTER_BUFFALO_WHRG54S;
959         }
960
961         if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x10")
962             && nvram_match("boardtype", "0x048e")
963             && nvram_match("melco_id", "32139")) {
964                 cprintf("router is Buffalo WCA-G\n");
965                 setRouter("Buffalo WCA-G");
966                 return ROUTER_BUFFALO_WCAG;     //vlan1 is lan, vlan0 is unused, implementation not done. will me made after return to germany
967         }
968
969         if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x11")
970             && nvram_match("boardtype", "0x048e")
971             && nvram_match("melco_id", "32064")) {
972                 cprintf("router is Buffalo WHR-HP-G125\n");
973                 setRouter("Buffalo WHR-HP-G125");
974                 return ROUTER_BUFFALO_WHRG54S;
975         }
976
977         if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x13")
978             && nvram_match("boardtype", "0x467")) {
979                 if (nvram_match("boardflags", "0x1658")
980                     || nvram_match("boardflags", "0x2658")
981                     || nvram_match("boardflags", "0x3658")) {
982                         cprintf("router is Buffalo WLI-TX4-G54HP\n");
983                         setRouter("Buffalo WLI-TX4-G54HP");
984                         return ROUTER_BUFFALO_WLI_TX4_G54HP;
985                 }
986                 if (!nvram_match("buffalo_hp", "1")
987                     && nvram_match("boardflags", "0x2758")) {
988                         cprintf("router is Buffalo WHR-G54S\n");
989                         setRouter("Buffalo WHR-G54S");
990                         return ROUTER_BUFFALO_WHRG54S;
991                 }
992                 if (nvram_match("buffalo_hp", "1")
993                     || nvram_match("boardflags", "0x1758")) {
994 #ifndef HAVE_BUFFALO
995                         cprintf("router is Buffalo WHR-HP-G54\n");
996                         setRouter("Buffalo WHR-HP-G54");
997 #else
998                         cprintf("router is Buffalo WHR-HP-G54DD\n");
999 #ifdef BUFFALO_JP
1000                         setRouter("Buffalo AS-A100");
1001 #else
1002                         setRouter("Buffalo WHR-HP-G54DD");
1003 #endif
1004 #endif
1005                         return ROUTER_BUFFALO_WHRG54S;
1006                 }
1007         }
1008
1009         if (nvram_match("boardnum", "00") && nvram_match("boardrev", "0x10")
1010             && nvram_match("boardtype", "0x470")) {
1011                 cprintf("router is Buffalo WHR-AM54G54\n");
1012                 setRouter("Buffalo WHR-AM54G54");
1013                 return ROUTER_BUFFALO_WHRAM54G54;
1014         }
1015
1016         if (boardnum == 42 && nvram_match("boardtype", "0x042f")) {
1017                 uint melco_id = strtoul(nvram_safe_get("melco_id"), NULL, 0);
1018
1019                 if (nvram_match("product_name", "WZR-RS-G54")
1020                     || melco_id == 30083) {
1021                         cprintf("router is Buffalo WZR-RS-G54\n");
1022                         setRouter("Buffalo WZR-RS-G54");
1023                         return ROUTER_BUFFALO_WZRRSG54;
1024                 }
1025                 if (nvram_match("product_name", "WZR-HP-G54")
1026                     || melco_id == 30026) {
1027                         cprintf("router is Buffalo WZR-HP-G54\n");
1028                         setRouter("Buffalo WZR-HP-G54");
1029                         return ROUTER_BUFFALO_WZRRSG54;
1030                 }
1031                 if (nvram_match("product_name", "WZR-G54") || melco_id == 30061) {
1032                         cprintf("router is Buffalo WZR-G54\n");
1033                         setRouter("Buffalo WZR-G54");
1034                         return ROUTER_BUFFALO_WZRRSG54;
1035                 }
1036                 if (nvram_match("melco_id", "290441dd")) {
1037                         cprintf("router is Buffalo WHR2-A54G54\n");
1038                         setRouter("Buffalo WHR2-A54G54");
1039                         return ROUTER_BUFFALO_WZRRSG54;
1040                 }
1041                 if (nvram_match("product_name", "WHR3-AG54")
1042                     || nvram_match("product_name", "WHR3-B11")
1043                     || melco_id == 29130) {
1044                         cprintf("router is Buffalo WHR3-AG54\n");
1045                         setRouter("Buffalo WHR3-AG54");
1046                         return ROUTER_BUFFALO_WZRRSG54;
1047                 }
1048                 if (nvram_match("product_name", "WVR-G54-NF")
1049                     || melco_id == 28100) {
1050                         cprintf("router is Buffalo WVR-G54-NF\n");
1051                         setRouter("Buffalo WVR-G54-NF");
1052                         return ROUTER_BUFFALO_WZRRSG54;
1053                 }
1054                 if (nvram_match("product_name", "WZR-G108") || melco_id == 31095
1055                     || melco_id == 30153) {
1056                         cprintf("router is Buffalo WZR-G108\n");
1057                         setRouter("Buffalo WZR-G108");
1058                         return ROUTER_BRCM4702_GENERIC;
1059                 }
1060                 if (melco_id > 0)       // e.g. 29115
1061                 {
1062                         cprintf("router is Buffalo WZR series\n");
1063                         setRouter("Buffalo WZR series");
1064                         return ROUTER_BUFFALO_WZRRSG54;
1065                 }
1066         }
1067 #ifndef HAVE_BUFFALO
1068         if (boardnum == 42 && nvram_match("boardtype", "0x042f")
1069             && nvram_match("boardrev", "0x10"))
1070                 // nvram_match ("boardflags","0x0018"))
1071         {
1072                 cprintf("router is Linksys WRTSL54GS\n");
1073                 setRouter("Linksys WRTSL54GS");
1074                 return ROUTER_WRTSL54GS;
1075         }
1076
1077         if (boardnum == 42 && nvram_match("boardtype", "0x0101")
1078             && nvram_match("boardrev", "0x10")
1079             && nvram_match("boot_ver", "v3.6")) {
1080                 cprintf("router is Linksys WRT54G3G\n");
1081                 setRouter("Linksys WRT54G3G");
1082                 return ROUTER_WRT54G3G;
1083         }
1084
1085         if (nvram_match("boardtype", "0x042f")
1086             && nvram_match("boardrev", "0x10")) {
1087                 char *hwver = nvram_safe_get("hardware_version");
1088
1089                 if (boardnum == 45 || startswith(hwver, "WL500gp")
1090                     || startswith(hwver, "WL500gH")) {
1091                         cprintf("router is Asus WL-500g Premium\n");
1092                         setRouter("Asus WL-500g Premium");
1093                         return ROUTER_ASUS_WL500G_PRE;
1094                 }
1095         }
1096
1097         char *et0 = nvram_safe_get("et0macaddr");
1098
1099         if (boardnum == 100 && nvram_match("boardtype", "bcm94710r4")) {
1100                 if (startswith(et0, "00:11:50")) {
1101                         cprintf("router is Belkin F5D7130 / F5D7330\n");
1102                         setRouter("Belkin F5D7130 / F5D7330");
1103                         return ROUTER_RT210W;
1104                 }
1105                 if (startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd")) {
1106                         cprintf("router is Belkin F5D7230 v1000\n");
1107                         setRouter("Belkin F5D7230-4 v1000");
1108                         return ROUTER_RT210W;
1109                 }
1110                 if (startswith(et0, "00:01:E3") ||
1111                     startswith(et0, "00:01:e3") || startswith(et0, "00:90:96"))
1112                 {
1113                         cprintf("router is Siemens\n");
1114                         setRouter("Siemens SE505 v1");
1115                         return ROUTER_RT210W;
1116                 } else {
1117                         cprintf("router is Askey generic\n");
1118                         setRouter("RT210W generic");
1119                         return ROUTER_RT210W;
1120                 }
1121         }
1122
1123         if (nvram_match("boardtype", "bcm94710r4")
1124             && nvram_match("boardnum", "")) {
1125                 cprintf("router is Askey board RT2100W\n");
1126                 setRouter("Askey board RT2100W-D65)");
1127                 return ROUTER_BRCM4702_GENERIC;
1128         }
1129
1130         if (boardnum == 0 && nvram_match("boardtype", "0x0100")
1131             && nvram_match("boardrev", "0x10")) {
1132                 cprintf("router is Askey board RT2205(6)D-D56\n");
1133                 if (startswith(et0, "00:11:50") ||
1134                     startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd"))
1135                 {
1136                         setRouter("Askey board RT2205(6)D-D56");
1137                 } else {
1138                         setRouter("Belkin board F5D8230");
1139                 }
1140                 return ROUTER_ASKEY_RT220XD;
1141         }
1142
1143         if (nvram_match("boardtype", "0x0101")) {
1144                 if (startswith(et0, "00:11:50") ||
1145                     startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd"))
1146                 {
1147                         if (nvram_match("Belkin_ver", "2000")) {
1148                                 cprintf("router is Belkin F5D7230-4 v2000\n");
1149                                 setRouter("Belkin F5D7230-4 v2000");
1150                                 return ROUTER_BELKIN_F5D7230_V2000;
1151                         } else {
1152                                 cprintf("router is Belkin F5D7230-4 v1444\n");
1153                                 setRouter("Belkin F5D7230-4 v1444");
1154                                 return ROUTER_RT480W;
1155                         }
1156                 }
1157                 if (startswith(et0, "00:01:E3") ||
1158                     startswith(et0, "00:01:e3") || startswith(et0, "00:90:96"))
1159                 {
1160                         cprintf("router is Siemens / Askey\n");
1161                         setRouter("Siemens SE505 v2");
1162                         return ROUTER_RT480W;
1163                 }
1164         }
1165         if (boardnum == 1 && nvram_match("boardtype", "0x456")
1166             && nvram_match("test_led_gpio", "2")) {
1167                 cprintf("router is Belkin F5D7230-4 v3000\n");
1168                 setRouter("Belkin F5D7230-4 v3000");
1169                 return ROUTER_BELKIN_F5D7230_V3000;
1170         }
1171
1172         if (nvram_match("boardtype", "0x456")
1173             && nvram_match("hw_model", "F5D7231-4")) {
1174                 cprintf("router is Belkin F5D7231-4 v1212UK\n");
1175                 setRouter("Belkin F5D7231-4 v1212UK");
1176                 return ROUTER_BELKIN_F5D7231;
1177         }
1178
1179         if (boardnum == 8 && nvram_match("boardtype", "0x0467"))        // fccid:
1180                 // K7SF5D7231B
1181         {
1182                 cprintf("router is Belkin F5D7231-4 v2000\n");
1183                 setRouter("Belkin F5D7231-4 v2000");
1184                 return ROUTER_BELKIN_F5D7231_V2000;
1185         }
1186
1187         if (nvram_match("boardtype", "0x467")) {
1188                 if (startswith(et0, "00:11:50") ||
1189                     startswith(et0, "00:30:BD") || startswith(et0, "00:30:bd"))
1190                 {
1191                         cprintf("router is Belkin F5D7231-4 v2000\n");
1192                         setRouter("Belkin F5D7231-4 v2000");
1193                         return ROUTER_BELKIN_F5D7231;
1194                 }
1195         }
1196 #endif
1197         if (boardnum == 2 && nvram_match("boardtype", "bcm94710dev") && nvram_match("melco_id", "29016"))       // Buffalo
1198                 // WLI2-TX1-G54)
1199         {
1200                 cprintf("router is Buffalo WLI2-TX1-G54\n");
1201                 setRouter("Buffalo WLI2-TX1-G54");
1202                 return ROUTER_BUFFALO_WLI2_TX1_G54;
1203         }
1204 #ifndef HAVE_BUFFALO
1205
1206         char *gemtek = nvram_safe_get("GemtekPmonVer");
1207         uint gemteknum = strtoul(gemtek, NULL, 0);
1208
1209         if (boardnum == 2 && gemteknum == 10 &&
1210             (startswith(et0, "00:0C:E5") ||
1211              startswith(et0, "00:0c:e5") ||
1212              startswith(et0, "00:0C:10") ||
1213              startswith(et0, "00:0c:10") ||
1214              startswith(et0, "00:0C:11") || startswith(et0, "00:0c:11"))) {
1215                 cprintf("router Motorola WE800G v1\n");
1216                 setRouter("Motorola WE800G v1");
1217                 return ROUTER_MOTOROLA_WE800G;
1218         }
1219
1220         if (boardnum == 2
1221             && (startswith(gemtek, "RC") || gemteknum == 1
1222                 || gemteknum == 10)) {
1223                 cprintf("router is Linksys wap54g v1.x\n");
1224                 setRouter("Linksys WAP54G v1.x");
1225                 return ROUTER_WAP54G_V1;
1226         }
1227
1228         if (boardnum == 2 && gemteknum == 1) {
1229                 cprintf("router is Sitecom wl-105b\n");
1230                 setRouter("Sitecom WL-105(b)");
1231                 return ROUTER_SITECOM_WL105B;
1232         }
1233
1234         if (boardnum == 2 && gemteknum == 7
1235             && nvram_match("boardtype", "bcm94710dev")) {
1236                 cprintf("router is Sitecom wl-111\n");
1237                 setRouter("Sitecom WL-111");
1238                 return ROUTER_SITECOM_WL111;
1239         }
1240
1241         if (gemteknum == 9)     // Must be Motorola wr850g v1 or we800g v1 or
1242                 // Linksys wrt55ag v1
1243         {
1244                 if (startswith(et0, "00:0C:E5") ||
1245                     startswith(et0, "00:0c:e5") ||
1246                     startswith(et0, "00:0C:10") ||
1247                     startswith(et0, "00:0c:10") ||
1248                     startswith(et0, "00:0C:11") ||
1249                     startswith(et0, "00:0c:11") ||
1250                     startswith(et0, "00:11:22") ||
1251                     startswith(et0, "00:0C:90") || startswith(et0, "00:0c:90"))
1252                 {
1253                         if (!strlen(nvram_safe_get("phyid_num"))) {
1254                                 insmod("switch-core");  // get phy type
1255                                 insmod("switch-robo");
1256                                 rmmod("switch-robo");
1257                                 rmmod("switch-core");
1258                                 nvram_set("boardnum", "2");
1259                                 nvram_set("boardtype", "bcm94710dev");
1260                         }
1261                         if (nvram_match("phyid_num", "0x00000000")) {
1262                                 cprintf("router Motorola WE800G v1\n");
1263                                 setRouter("Motorola WE800G v1");
1264                                 return ROUTER_MOTOROLA_WE800G;
1265                         } else  // phyid_num == 0xffffffff
1266                         {
1267                                 cprintf("router Motorola WR850G v1\n");
1268                                 setRouter("Motorola WR850G v1");
1269                                 return ROUTER_MOTOROLA_V1;
1270                         }
1271                 } else {
1272                         cprintf("router is linksys WRT55AG\n");
1273                         setRouter("Linksys WRT55AG v1");
1274                         return ROUTER_LINKSYS_WRT55AG;
1275                 }
1276         }
1277 #endif
1278         if (boardnum == 0 && nvram_match("boardtype", "0x478")
1279             && nvram_match("cardbus", "0") && nvram_match("boardrev", "0x10")
1280             && nvram_match("boardflags", "0x110")
1281             && nvram_match("melco_id", "32027")) {
1282                 setRouter("Buffalo WZR-G144NH");
1283                 return ROUTER_BUFFALO_WZRG144NH;
1284         }
1285
1286         if (boardnum == 20060330 && nvram_match("boardtype", "0x0472")) {
1287                 setRouter("Buffalo WZR-G300N");
1288                 return ROUTER_BUFFALO_WZRG300N;
1289         }
1290 #ifndef HAVE_BUFFALO
1291
1292         if (boardnum == 8 && nvram_match("boardtype", "0x0472")
1293             && nvram_match("cardbus", "1")) {
1294                 cprintf("router is Netgear WNR834B\n");
1295                 setRouter("Netgear WNR834B");
1296                 return ROUTER_NETGEAR_WNR834B;
1297         }
1298
1299         if (boardnum == 1 && nvram_match("boardtype", "0x0472")
1300             && nvram_match("boardrev", "0x23")) {
1301                 if (nvram_match("cardbus", "1")) {
1302                         cprintf("router is Netgear WNR834B v2\n");
1303                         setRouter("Netgear WNR834B v2");
1304                         return ROUTER_NETGEAR_WNR834BV2;
1305                 } else {
1306                         cprintf("router is Netgear WNDR-3300\n");
1307                         setRouter("Netgear WNDR3300");
1308                         return ROUTER_NETGEAR_WNDR3300;
1309                 }
1310         }
1311
1312         if (boardnum == 42)     // Get Linksys N models
1313         {
1314                 if (nvram_match("boot_hw_model", "WRT300N")
1315                     && nvram_match("boot_hw_ver", "1.1")) {
1316                         setRouter("Linksys WRT300N v1.1");
1317                         return ROUTER_WRT300NV11;
1318                 } else if (nvram_match("boot_hw_model", "WRT150N")
1319                            && nvram_match("boot_hw_ver", "1")) {
1320                         setRouter("Linksys WRT150N v1");
1321                         return ROUTER_WRT150N;
1322                 } else if (nvram_match("boot_hw_model", "WRT150N")
1323                            && nvram_match("boot_hw_ver", "1.1")) {
1324                         setRouter("Linksys WRT150N v1.1");
1325                         // return ROUTER_WRT150NV11;
1326                         return ROUTER_WRT150N;
1327                 } else if (nvram_match("boot_hw_model", "WRT150N")
1328                            && nvram_match("boot_hw_ver", "1.2")) {
1329                         setRouter("Linksys WRT150N v1.2");
1330                         // return ROUTER_WRT150NV12;
1331                         return ROUTER_WRT150N;
1332                 } else if (nvram_match("boot_hw_model", "WRT160N")
1333                            && nvram_match("boot_hw_ver", "1.0")) {
1334                         setRouter("Linksys WRT160N");
1335                         return ROUTER_WRT160N;
1336                 } else if (nvram_match("boot_hw_model", "WRT310N")
1337                            && nvram_match("boot_hw_ver", "1.0")) {
1338                         setRouter("Linksys WRT310N");
1339                         return ROUTER_WRT310N;
1340                 }
1341         }
1342
1343         if (boardnum == 42 && nvram_match("boardtype", "0x0472")
1344             && nvram_match("cardbus", "1")) {
1345                 setRouter("Linksys WRT300N v1");
1346                 return ROUTER_WRT300N;
1347         }
1348
1349         if (boardnum == 42 &&
1350             nvram_match("boardtype", "0x478") && nvram_match("cardbus", "1")) {
1351                 cprintf("router is Linksys WRT350N\n");
1352                 setRouter("Linksys WRT350N");
1353                 return ROUTER_WRT350N;
1354         }
1355
1356         if (nvram_match("boardnum", "20070615") &&
1357             nvram_match("boardtype", "0x478") && nvram_match("cardbus", "0")
1358             && nvram_match("switch_type", "BCM5395")) {
1359                 cprintf("router is Linksys WRT600N v1.1\n");
1360                 setRouter("Linksys WRT600N v1.1");
1361                 return ROUTER_WRT600N;
1362         }
1363
1364         if (nvram_match("boardnum", "20070615") &&
1365             nvram_match("boardtype", "0x478") && nvram_match("cardbus", "0")) {
1366                 cprintf("router is Linksys WRT600N\n");
1367                 setRouter("Linksys WRT600N");
1368                 return ROUTER_WRT600N;
1369         }
1370
1371         if (nvram_match("boardtype", "0x478")
1372             && nvram_match("boot_hw_model", "WRT610N")) {
1373                 cprintf("router is Linksys WRT610N\n");
1374                 setRouter("Linksys WRT610N");
1375                 return ROUTER_WRT610N;
1376         }
1377
1378         if (boardnum == 42 && nvram_match("boardtype", "bcm94710dev")) {
1379                 cprintf("router is Linksys WRT54G v1.x\n");
1380                 setRouter("Linksys WRT54G v1.x");
1381                 return ROUTER_WRT54G1X;
1382         }
1383
1384         if ((boardnum == 1 || boardnum == 0)
1385             && nvram_match("boardtype", "0x0446")) {
1386                 cprintf("router is U.S. Robotics USR5430\n");
1387                 setRouter("U.S.Robotics USR5430");
1388                 return ROUTER_USR_5430;
1389         }
1390
1391         if (boardnum == 1 && nvram_match("boardtype", "0x456")
1392             && nvram_match("test_led_gpio", "0")) {
1393                 cprintf("router is Netgear WG602 v3\n");
1394                 setRouter("Netgear WG602 v3");
1395                 return ROUTER_NETGEAR_WG602_V3;
1396         }
1397
1398         if (boardnum == 10496 && nvram_match("boardtype", "0x456")) {
1399                 cprintf("router is U.S. Robotics USR5461\n");
1400                 setRouter("U.S.Robotics USR5461");
1401                 return ROUTER_USR_5461;
1402         }
1403
1404         if (boardnum == 10500 && nvram_match("boardtype", "0x456")) {
1405                 cprintf("router is U.S. Robotics USR5432\n");
1406                 setRouter("U.S.Robotics USR5432");
1407                 return ROUTER_USR_5461; // should work in the same way
1408         }
1409
1410         if (boardnum == 10506 && nvram_match("boardtype", "0x456")) {
1411                 cprintf("router is U.S. Robotics USR5451\n");
1412                 setRouter("U.S.Robotics USR5451");
1413                 return ROUTER_USR_5461; // should work in the same way
1414         }
1415
1416         if (boardnum == 10512 && nvram_match("boardtype", "0x456")) {
1417                 cprintf("router is U.S. Robotics USR5441\n");
1418                 setRouter("U.S.Robotics USR5441");
1419                 return ROUTER_USR_5461; // should work in the same way
1420         }
1421
1422         if (boardnum == 1024 && nvram_match("boardtype", "0x0446")) {
1423                 char *cfe = nvram_safe_get("cfe_version");
1424
1425                 if (strstr(cfe, "iewsonic")) {
1426                         cprintf("router is Viewsonic WAPBR-100\n");
1427                         setRouter("Viewsonic WAPBR-100");
1428                         return ROUTER_VIEWSONIC_WAPBR_100;
1429                 } else {
1430                         cprintf("router is Linksys WAP54G v2\n");
1431                         setRouter("Linksys WAP54G v2");
1432                         return ROUTER_WAP54G_V2;
1433                 }
1434         }
1435
1436         if (nvram_invmatch("CFEver", "")) {
1437                 char *cfe = nvram_safe_get("CFEver");
1438
1439                 if (!strncmp(cfe, "MotoWR", 6)) {
1440                         cprintf("router is motorola\n");
1441                         setRouter("Motorola WR850G v2/v3");
1442                         return ROUTER_MOTOROLA;
1443                 }
1444         }
1445
1446         if (boardnum == 44 && (nvram_match("boardtype", "0x0101")
1447                                || nvram_match("boardtype", "0x0101\r"))) {
1448                 char *cfe = nvram_safe_get("CFEver");
1449
1450                 if (!strncmp(cfe, "GW_WR110G", 9)) {
1451                         cprintf("router is Sparklan WX-6615GT\n");
1452                         setRouter("Sparklan WX-6615GT");
1453                         return ROUTER_DELL_TRUEMOBILE_2300_V2;
1454                 } else {
1455                         cprintf("router is Dell TrueMobile 2300 v2\n");
1456                         setRouter("Dell TrueMobile 2300 v2");
1457                         return ROUTER_DELL_TRUEMOBILE_2300_V2;
1458                 }
1459         }
1460 #endif
1461         if (nvram_match("boardtype", "bcm94710ap")) {
1462                 cprintf("router is Buffalo old 4710\n");
1463                 setRouter("Buffalo WBR-B11");
1464                 return ROUTER_BUFFALO_WBR54G;
1465         }
1466 #ifndef HAVE_BUFFALO
1467         if (nvram_match("boardtype", "0x048e") &&
1468             nvram_match("boardrev", "0x35") &&
1469             nvram_match("sdram_init", "0x000b")) {
1470                 cprintf("router is D-Link DIR-320\n");
1471                 setRouter("D-Link DIR-320");
1472                 // apply some fixes
1473                 if (nvram_get("vlan2ports") != NULL) {
1474                         nvram_unset("vlan2ports");
1475                         nvram_unset("vlan2hwname");
1476                 }
1477                 return ROUTER_DLINK_DIR320;
1478         }
1479         if (nvram_match("model_name", "DIR-330") &&
1480             nvram_match("boardrev", "0x10")) {
1481                 cprintf("router is D-Link DIR-330\n");
1482                 setRouter("D-Link DIR-330");
1483                 nvram_set("wan_ifnames", "eth0");       // quirk
1484                 nvram_set("wan_ifname", "eth0");
1485                 if (nvram_match("et0macaddr", "00:90:4c:4e:00:0c")) {
1486                         FILE *in = fopen("/dev/mtdblock/1", "rb");
1487
1488                         fseek(in, 0x7a0022, SEEK_SET);
1489                         char mac[32];
1490
1491                         fread(mac, 32, 1, in);
1492                         fclose(in);
1493                         mac[17] = 0;
1494                         if (sv_valid_hwaddr(mac)) {
1495                                 nvram_set("et0macaddr", mac);
1496                                 fprintf(stderr, "restore D-Link MAC\n");
1497                                 nvram_commit();
1498                                 sys_reboot();
1499                         }
1500                 }
1501                 /*
1502                  * if (nvram_get("vlan2ports")!=NULL) { nvram_unset("vlan2ports");
1503                  * nvram_unset("vlan2hwname"); }
1504                  */
1505                 return ROUTER_DLINK_DIR330;
1506         }
1507         if (boardnum == 42 && nvram_match("boardtype", "0x048e")
1508             && nvram_match("boardrev", "0x10")) {
1509                 if (nvram_match("boardflags", "0x20750")) {
1510                 cprintf("router is wrt54g2v1/v1.3/gs2v1\n");
1511                 setRouter("Linksys WRT54G2 / GS2");
1512                 }
1513                 else {
1514                 cprintf("router is wrt54gv8/gsv7\n");
1515                 setRouter("Linksys WRT54Gv8 / GSv7");                   
1516                 }
1517                 return ROUTER_WRT54G_V8;
1518         }
1519
1520         if (boardnum == 8 && nvram_match("boardtype", "0x048e")
1521             && nvram_match("boardrev", "0x11")) {
1522                 cprintf("router is ALLNET01\n");
1523                 setRouter("ALLNET EUROWRT 54");
1524                 return ROUTER_ALLNET01;
1525         }
1526
1527         if (boardnum == 01 && nvram_match("boardtype", "0x048e")
1528             && nvram_match("boardrev", "0x11")
1529             && (nvram_match("boardflags", "0x650")
1530                 || nvram_match("boardflags", "0x0458"))) {
1531                 cprintf("router is Netgear WG602 v4\n");
1532                 setRouter("Netgear WG602 v4");
1533                 return ROUTER_NETGEAR_WG602_V4;
1534         }
1535
1536         if (boardnum == 1 && nvram_match("boardtype", "0x048e")
1537             && nvram_match("boardrev", "0x35")
1538             && nvram_match("parefldovoltage", "0x28")) {
1539                 cprintf("router is netcore nw618\n");
1540                 setRouter("NetCore NW618");
1541                 return ROUTER_WRT54G;
1542         }
1543
1544         if (boardnum == 42 && nvram_match("boardtype", "0x048E")
1545             && nvram_match("boardrev", "0x10")) {
1546                 cprintf("router is Linksys WRH54G\n");
1547                 setRouter("Linksys WRH54G");
1548                 return ROUTER_LINKSYS_WRH54G;
1549         }
1550
1551         if (nvram_match("boardnum", "00") && nvram_match("boardtype", "0x048E")
1552             && nvram_match("boardrev", "0x10")) {
1553                 cprintf("router is Linksys WRT54G v8.1\n");
1554                 setRouter("Linksys WRT54G v8.1");
1555                 return ROUTER_WRT54G_V81;
1556         }
1557
1558         if (boardnum == 45 && nvram_match("boardtype", "0x456")) {
1559                 cprintf("router is Asus WL-520G\n");
1560                 setRouter("Asus WL-520G");
1561                 return ROUTER_ASUS_WL520G;
1562         }
1563
1564         if (nvram_match("boardtype", "0x48E")
1565             && nvram_match("boardrev", "0x10")) {
1566                 char *hwver = nvram_safe_get("hardware_version");
1567
1568                 if (boardnum == 45 && startswith(hwver, "WL500GPV2")) {
1569                         cprintf("router is Asus WL-500G Premium V2\n");
1570                         setRouter("Asus WL-500G Premium V2");
1571                         return ROUTER_ASUS_WL500G_PRE_V2;
1572                 } else if (boardnum == 45 && startswith(hwver, "WL330GE")) {
1573                         cprintf("router is Asus WL-330GE\n");
1574                         setRouter("Asus WL-330GE");
1575                         return ROUTER_ASUS_330GE;
1576                 } else if (boardnum == 45 || startswith(hwver, "WL500GU")
1577                            || startswith(hwver, "WL500GC")) {
1578                         cprintf("router is Asus WL-520GU/GC\n");
1579                         setRouter("Asus WL-520GU/GC");
1580                         return ROUTER_ASUS_WL520GUGC;
1581                 }
1582         }
1583
1584         if ((boardnum == 83258 || boardnum == 1 || boardnum == 0123)    //or 01 or 001 or 0x01
1585             && (nvram_match("boardtype", "0x048e")
1586                 || nvram_match("boardtype", "0x48E"))
1587             && (nvram_match("boardrev", "0x11")
1588                 || nvram_match("boardrev", "0x10"))
1589             && (nvram_match("boardflags", "0x750")
1590                 || nvram_match("boardflags", "0x0750"))) {
1591                 if (nvram_match("sdram_init", "0x000A"))        //16 MB ram
1592                 {
1593                         cprintf("router is Netgear WGR614v8/L/WW\n");
1594                         setRouter("Netgear WGR614v8/L/WW");
1595                         return ROUTER_NETGEAR_WGR614L;
1596                 } else if (nvram_match("sdram_init", "0x0002")) //8 MB ram
1597                 {
1598                         cprintf("router is Netgear WGR614v9\n");
1599                         setRouter("Netgear WGR614v9");
1600                         return ROUTER_NETGEAR_WGR614L;
1601                 }
1602         }
1603
1604         if (boardnum == 56 && nvram_match("boardtype", "0x456")
1605             && nvram_match("boardrev", "0x10")) {
1606                 cprintf("router is wtr54gs\n");
1607                 setRouter("Linksys WTR54GS");
1608                 return ROUTER_LINKSYS_WTR54GS;
1609         }
1610
1611         if (nvram_match("boardnum", "WAP54GV3_8M_0614")
1612             && (nvram_match("boardtype", "0x0467")
1613                 || nvram_match("boardtype", "0x467"))
1614             && nvram_match("WAPver", "3")) {
1615                 cprintf("router is WAP54G v3.x\n");
1616                 setRouter("Linksys WAP54G v3.x");
1617                 return ROUTER_WAP54G_V3;
1618         }
1619
1620         setRouter("Linksys WRT54G/GL/GS");
1621         cprintf("router is wrt54g\n");
1622         return ROUTER_WRT54G;
1623 #else
1624         eval("event", "3", "1", "15");
1625         return 0;
1626 #endif
1627 #endif
1628 #endif
1629 }
1630
1631 static int router_type = -1;
1632 int getRouterBrand()
1633 {
1634         if (router_type == -1)
1635                 router_type = internal_getRouterBrand();
1636         return router_type;
1637 }
1638
1639 int get_ppp_pid(char *file)
1640 {
1641         char buf[80];
1642         int pid = -1;
1643
1644         if (file_to_buf(file, buf, sizeof(buf))) {
1645                 char tmp[80], tmp1[80];
1646
1647                 snprintf(tmp, sizeof(tmp), "/var/run/%s.pid", buf);
1648                 file_to_buf(tmp, tmp1, sizeof(tmp1));
1649                 pid = atoi(tmp1);
1650         }
1651         return pid;
1652 }
1653
1654 int check_wan_link(int num)
1655 {
1656         int wan_link = 0;
1657
1658         if ((nvram_match("wan_proto", "pptp")
1659             || nvram_match("wan_proto", "l2tp")
1660             || nvram_match("wan_proto", "pppoe")
1661             || nvram_match("wan_proto", "3g")
1662             || nvram_match("wan_proto", "heartbeat")) && !nvram_match("3gdata","hso")) {
1663                 FILE *fp;
1664                 char filename[80];
1665                 char *name;
1666
1667                 if (num == 0)
1668                         strcpy(filename, "/tmp/ppp/link");
1669                 if ((fp = fopen(filename, "r"))) {
1670                         int pid = -1;
1671
1672                         fclose(fp);
1673                         if (nvram_match("wan_proto", "heartbeat")) {
1674                                 char buf[20];
1675
1676                                 file_to_buf("/tmp/ppp/link", buf, sizeof(buf));
1677                                 pid = atoi(buf);
1678                         } else
1679                                 pid = get_ppp_pid(filename);
1680
1681                         name = find_name_by_proc(pid);
1682                         if (!strncmp(name, "pppoecd", 7) ||     // for PPPoE
1683                             !strncmp(name, "pppd", 4) ||        // for PPTP
1684                             !strncmp(name, "bpalogin", 8))      // for HeartBeat
1685                                 wan_link = 1;   // connect
1686                         else {
1687                                 printf("The %s had been died, remove %s\n",
1688                                        nvram_safe_get("wan_proto"), filename);
1689                                 wan_link = 0;   // For some reason, the pppoed had been died,
1690                                 // by link file still exist.
1691                                 unlink(filename);
1692                         }
1693                 }
1694         } else {
1695                 if (nvram_invmatch("wan_ipaddr", "0.0.0.0"))
1696                         wan_link = 1;
1697         }
1698
1699         return wan_link;
1700 }
1701
1702 /*
1703  * Find process name by pid from /proc directory
1704  */
1705 char *find_name_by_proc(int pid)
1706 {
1707         FILE *fp;
1708         char line[254];
1709         char filename[80];
1710         static char name[80];
1711
1712         snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
1713
1714         if ((fp = fopen(filename, "r"))) {
1715                 fgets(line, sizeof(line), fp);
1716                 /*
1717                  * Buffer should contain a string like "Name: binary_name"
1718                  */
1719                 sscanf(line, "%*s %s", name);
1720                 fclose(fp);
1721                 return name;
1722         }
1723
1724         return "";
1725 }
1726
1727 int diag_led_4702(int type, int act)
1728 {
1729
1730 #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)
1731         return 0;
1732 #else
1733         if (act == START_LED) {
1734                 switch (type) {
1735                 case DMZ:
1736                         system2("echo 1 > /proc/sys/diag");
1737                         break;
1738                 }
1739         } else {
1740                 switch (type) {
1741                 case DMZ:
1742                         system2("echo 0 > /proc/sys/diag");
1743                         break;
1744                 }
1745         }
1746         return 0;
1747 #endif
1748 }
1749
1750 int C_led_4702(int i)
1751 {
1752 #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)
1753         return 0;
1754 #else
1755         FILE *fp;
1756         char string[10];
1757         int flg;
1758
1759         memset(string, 0, 10);
1760         /*
1761          * get diag before set
1762          */
1763         if ((fp = fopen("/proc/sys/diag", "r"))) {
1764                 fgets(string, sizeof(string), fp);
1765                 fclose(fp);
1766         } else
1767                 perror("/proc/sys/diag");
1768
1769         if (i)
1770                 flg = atoi(string) | 0x10;
1771         else
1772                 flg = atoi(string) & 0xef;
1773
1774         memset(string, 0, 10);
1775         sprintf(string, "%d", flg);
1776         if ((fp = fopen("/proc/sys/diag", "w"))) {
1777                 fputs(string, fp);
1778                 fclose(fp);
1779         } else
1780                 perror("/proc/sys/diag");
1781
1782         return 0;
1783 #endif
1784 }
1785
1786 unsigned int read_gpio(char *device)
1787 {
1788         FILE *fp;
1789         unsigned int val;
1790
1791         if ((fp = fopen(device, "r"))) {
1792                 fread(&val, 4, 1, fp);
1793                 fclose(fp);
1794                 // fprintf(stderr, "----- gpio %s = [%X]\n",device,val);
1795                 return val;
1796         } else {
1797                 perror(device);
1798                 return 0;
1799         }
1800 }
1801
1802 unsigned int write_gpio(char *device, unsigned int val)
1803 {
1804         FILE *fp;
1805
1806         if ((fp = fopen(device, "w"))) {
1807                 fwrite(&val, 4, 1, fp);
1808                 fclose(fp);
1809                 // fprintf(stderr, "----- set gpio %s = [%X]\n",device,val);
1810                 return 1;
1811         } else {
1812                 perror(device);
1813                 return 0;
1814         }
1815 }
1816
1817 static char hw_error = 0;
1818 int diag_led_4704(int type, int act)
1819 {
1820 #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)
1821         return 0;
1822 #else
1823         unsigned int control, in, outen, out;
1824
1825 #ifdef BCM94712AGR
1826         /*
1827          * The router will crash, if we load the code into broadcom demo board.
1828          */
1829         return 1;
1830 #endif
1831         // int brand;
1832         control = read_gpio("/dev/gpio/control");
1833         in = read_gpio("/dev/gpio/in");
1834         out = read_gpio("/dev/gpio/out");
1835         outen = read_gpio("/dev/gpio/outen");
1836
1837         write_gpio("/dev/gpio/outen", (outen & 0x7c) | 0x83);
1838         switch (type) {
1839         case DIAG:              // GPIO 1
1840                 if (hw_error) {
1841                         write_gpio("/dev/gpio/out", (out & 0x7c) | 0x00);
1842                         return 1;
1843                 }
1844
1845                 if (act == STOP_LED) {  // stop blinking
1846                         write_gpio("/dev/gpio/out", (out & 0x7c) | 0x83);
1847                         // cprintf("tallest:=====( DIAG STOP_LED !!)=====\n");
1848                 } else if (act == START_LED) {  // start blinking
1849                         write_gpio("/dev/gpio/out", (out & 0x7c) | 0x81);
1850                         // cprintf("tallest:=====( DIAG START_LED !!)=====\n");
1851                 } else if (act == MALFUNCTION_LED) {    // start blinking
1852                         write_gpio("/dev/gpio/out", (out & 0x7c) | 0x00);
1853                         hw_error = 1;
1854                         // cprintf("tallest:=====( DIAG MALFUNCTION_LED !!)=====\n");
1855                 }
1856                 break;
1857
1858         }
1859         return 1;
1860 #endif
1861 }
1862
1863 int diag_led_4712(int type, int act)
1864 {
1865         unsigned int control, in, outen, out, ctr_mask, out_mask;
1866
1867 #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)
1868         return 0;
1869 #else
1870
1871 #ifdef BCM94712AGR
1872         /*
1873          * The router will crash, if we load the code into broadcom demo board.
1874          */
1875         return 1;
1876 #endif
1877         control = read_gpio("/dev/gpio/control");
1878         in = read_gpio("/dev/gpio/in");
1879         out = read_gpio("/dev/gpio/out");
1880         outen = read_gpio("/dev/gpio/outen");
1881
1882         ctr_mask = ~(1 << type);
1883         out_mask = (1 << type);
1884
1885         write_gpio("/dev/gpio/control", control & ctr_mask);
1886         write_gpio("/dev/gpio/outen", outen | out_mask);
1887
1888         if (act == STOP_LED) {  // stop blinking
1889                 // cprintf("%s: Stop GPIO %d\n", __FUNCTION__, type);
1890                 write_gpio("/dev/gpio/out", out | out_mask);
1891         } else if (act == START_LED) {  // start blinking
1892                 // cprintf("%s: Start GPIO %d\n", __FUNCTION__, type);
1893                 write_gpio("/dev/gpio/out", out & ctr_mask);
1894         }
1895
1896         return 1;
1897 #endif
1898 }
1899
1900 int C_led_4712(int i)
1901 {
1902         if (i == 1)
1903                 return diag_led(DIAG, START_LED);
1904         else
1905                 return diag_led(DIAG, STOP_LED);
1906 }
1907
1908 int C_led(int i)
1909 {
1910         int brand = getRouterBrand();
1911
1912         if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
1913                 return C_led_4702(i);
1914         else if (brand == ROUTER_WRT54G)
1915                 return C_led_4712(i);
1916         else
1917                 return 0;
1918 }
1919
1920 int diag_led(int type, int act)
1921 {
1922         int brand = getRouterBrand();
1923
1924         if (brand == ROUTER_WRT54G || brand == ROUTER_WRT54G3G
1925             || brand == ROUTER_WRT300NV11)
1926                 return diag_led_4712(type, act);
1927         else if (brand == ROUTER_WRT54G1X || brand == ROUTER_LINKSYS_WRT55AG)
1928                 return diag_led_4702(type, act);
1929         else if ((brand == ROUTER_WRTSL54GS
1930                   || brand == ROUTER_WRT310N || brand == ROUTER_WRT350N
1931                   || brand == ROUTER_BUFFALO_WZRG144NH) && type == DIAG)
1932                 return diag_led_4704(type, act);
1933         else {
1934                 if (type == DMZ) {
1935                         if (act == START_LED)
1936                                 return led_control(LED_DMZ, LED_ON);
1937                         if (act == STOP_LED)
1938                                 return led_control(LED_DMZ, LED_OFF);
1939                         return 1;
1940                 }
1941         }
1942         return 0;
1943 }
1944
1945 #ifdef HAVE_MADWIFI
1946 static char *stalist[] = {
1947         "ath0", "ath1", "ath2", "ath3", "ath4", "ath5", "ath6", "ath8", "ath9"
1948 };
1949
1950 char *getWifi(char *ifname)
1951 {
1952         if (!strcmp(ifname, "ath0"))
1953                 return "wifi0";
1954         if (!strcmp(ifname, "ath1"))
1955                 return "wifi1";
1956         if (!strcmp(ifname, "ath2"))
1957                 return "wifi2";
1958         if (!strcmp(ifname, "ath3"))
1959                 return "wifi3";
1960         return NULL;
1961 }
1962
1963 char *getWDSSTA(void)
1964 {
1965
1966         int c = getifcount("wifi");
1967         int i;
1968
1969         for (i = 0; i < c; i++) {
1970                 char mode[32];
1971                 char netmode[32];
1972
1973                 sprintf(mode, "ath%d_mode", i);
1974                 sprintf(netmode, "ath%d_net_mode", i);
1975                 if (nvram_match(mode, "wdssta")
1976                     && !nvram_match(netmode, "disabled")) {
1977                         return stalist[i];
1978                 }
1979
1980         }
1981         return NULL;
1982 }
1983
1984 char *getSTA(void)
1985 {
1986
1987 #ifdef HAVE_WAVESAT
1988         if (nvram_match("ofdm_mode", "sta"))
1989                 return "ofdm";
1990 #endif
1991         int c = getifcount("wifi");
1992         int i;
1993
1994         for (i = 0; i < c; i++) {
1995                 char mode[32];
1996                 char netmode[32];
1997
1998                 sprintf(mode, "ath%d_mode", i);
1999                 sprintf(netmode, "ath%d_net_mode", i);
2000                 if (nvram_match(mode, "sta")
2001                     && !nvram_match(netmode, "disabled")) {
2002                         return stalist[i];
2003                 }
2004
2005         }
2006         return NULL;
2007 }
2008
2009 char *getWET(void)
2010 {
2011 #ifdef HAVE_WAVESAT
2012         if (nvram_match("ofdm_mode", "bridge"))
2013                 return "ofdm";
2014 #endif
2015         int c = getifcount("wifi");
2016         int i;
2017
2018         for (i = 0; i < c; i++) {
2019                 char mode[32];
2020                 char netmode[32];
2021
2022                 sprintf(mode, "ath%d_mode", i);
2023                 sprintf(netmode, "ath%d_net_mode", i);
2024                 if (nvram_match(mode, "wet")
2025                     && !nvram_match(netmode, "disabled")) {
2026                         return stalist[i];
2027                 }
2028
2029         }
2030         return NULL;
2031 }
2032
2033 #elif HAVE_RT2880
2034
2035 char *getSTA()
2036 {
2037         int c = get_wl_instances();
2038         int i;
2039
2040         for (i = 0; i < c; i++) {
2041                 if (nvram_nmatch("sta", "wl%d_mode", i)) {
2042                         if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2043                                 return "ra0";
2044                 }
2045
2046                 if (nvram_nmatch("apsta", "wl%d_mode", i)) {
2047                         if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2048                                 return "apcli0";
2049                 }
2050
2051         }
2052         return NULL;
2053 }
2054
2055 char *getWET()
2056 {
2057         int c = get_wl_instances();
2058         int i;
2059
2060         for (i = 0; i < c; i++) {
2061                 if (!nvram_nmatch("disabled", "wl%d_net_mode", i)
2062                     && nvram_nmatch("wet", "wl%d_mode", i))
2063                         return "ra0";
2064
2065                 if (!nvram_nmatch("disabled", "wl%d_net_mode", i)
2066                     && nvram_nmatch("apstawet", "wl%d_mode", i))
2067                         return "apcli0";
2068
2069         }
2070         return NULL;
2071 }
2072
2073 #else
2074 char *getSTA()
2075 {
2076         int c = get_wl_instances();
2077         int i;
2078
2079         for (i = 0; i < c; i++) {
2080                 if (nvram_nmatch("sta", "wl%d_mode", i)
2081                     || nvram_nmatch("apsta", "wl%d_mode", i)) {
2082                         if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2083                                 return get_wl_instance_name(i);
2084                         // else
2085                         // return nvram_nget ("wl%d_ifname", i);
2086                 }
2087
2088         }
2089         return NULL;
2090 }
2091
2092 char *getWET()
2093 {
2094         int c = get_wl_instances();
2095         int i;
2096
2097         for (i = 0; i < c; i++) {
2098                 if (nvram_nmatch("wet", "wl%d_mode", i)
2099                     || nvram_nmatch("apstawet", "wl%d_mode", i)) {
2100                         if (!nvram_nmatch("disabled", "wl%d_net_mode", i))
2101                                 return get_wl_instance_name(i);
2102                         // else
2103                         // return nvram_nget ("wl%d_ifname", i);
2104
2105                 }
2106
2107         }
2108         return NULL;
2109 }
2110
2111 #endif
2112 // note - broadcast addr returned in ipaddr
2113 void get_broadcast(char *ipaddr, char *netmask)
2114 {
2115         int ip2[4], mask2[4];
2116         unsigned char ip[4], mask[4];
2117
2118         if (!ipaddr || !netmask)
2119                 return;
2120
2121         sscanf(ipaddr, "%d.%d.%d.%d", &ip2[0], &ip2[1], &ip2[2], &ip2[3]);
2122         sscanf(netmask, "%d.%d.%d.%d", &mask2[0], &mask2[1], &mask2[2],
2123                &mask2[3]);
2124         int i = 0;
2125
2126         for (i = 0; i < 4; i++) {
2127                 ip[i] = ip2[i];
2128                 mask[i] = mask2[i];
2129                 // ip[i] = (ip[i] & mask[i]) | !mask[i];
2130                 ip[i] = (ip[i] & mask[i]) | (0xff & ~mask[i]);
2131         }
2132
2133         sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
2134 #ifdef WDS_DEBUG
2135         fprintf(fp, "get_broadcast return %s\n", value);
2136 #endif
2137
2138 }
2139
2140 char *get_wan_face(void)
2141 {
2142         static char localwanface[IFNAMSIZ];
2143
2144         /*
2145          * if (nvram_match ("pptpd_client_enable", "1")) { strncpy (localwanface,
2146          * "ppp0", IFNAMSIZ); return localwanface; }
2147          */
2148         if (nvram_match("wan_proto", "pptp")
2149             || nvram_match("wan_proto", "l2tp")
2150             || nvram_match("wan_proto", "3g")
2151             || nvram_match("wan_proto", "pppoe")) {
2152                 if (nvram_match("pppd_pppifname", ""))
2153                         strncpy(localwanface, "ppp0", IFNAMSIZ);
2154                 else
2155                         strncpy(localwanface, nvram_safe_get("pppd_pppifname"),
2156                                 IFNAMSIZ);
2157         }
2158 #ifndef HAVE_MADWIFI
2159         else if (getSTA()) {
2160                 strcpy(localwanface, getSTA());
2161         }
2162 #else
2163         else if (getSTA()) {
2164                 if (nvram_match("wifi_bonding", "1"))
2165                         strcpy(localwanface, "bond0");
2166                 else
2167                         strcpy(localwanface, getSTA());
2168         }
2169 #endif
2170         else
2171                 strncpy(localwanface, nvram_safe_get("wan_ifname"), IFNAMSIZ);
2172
2173         return localwanface;
2174 }
2175
2176 static int _pidof(const char *name, pid_t ** pids)
2177 {
2178         const char *p;
2179         char *e;
2180         DIR *dir;
2181         struct dirent *de;
2182         pid_t i;
2183         int count;
2184         char buf[256];
2185
2186         count = 0;
2187         *pids = NULL;
2188         if ((p = strchr(name, '/')) != NULL)
2189                 name = p + 1;
2190         if ((dir = opendir("/proc")) != NULL) {
2191                 while ((de = readdir(dir)) != NULL) {
2192                         i = strtol(de->d_name, &e, 10);
2193                         if (*e != 0)
2194                                 continue;
2195                         if (strcmp(name, psname(i, buf, sizeof(buf))) == 0) {
2196                                 if ((*pids =
2197                                      realloc(*pids,
2198                                              sizeof(pid_t) * (count + 1))) ==
2199                                     NULL) {
2200                                         return -1;
2201                                 }
2202                                 (*pids)[count++] = i;
2203                         }
2204                 }
2205         }
2206         closedir(dir);
2207         return count;
2208 }
2209
2210 int pidof(const char *name)
2211 {
2212         pid_t *pids;
2213         pid_t p;
2214
2215         if (_pidof(name, &pids) > 0) {
2216                 p = *pids;
2217                 free(pids);
2218                 return p;
2219         }
2220         return -1;
2221 }
2222
2223 int killall(const char *name, int sig)
2224 {
2225         pid_t *pids;
2226         int i;
2227         int r;
2228
2229         if ((i = _pidof(name, &pids)) > 0) {
2230                 r = 0;
2231                 do {
2232                         r |= kill(pids[--i], sig);
2233                 }
2234                 while (i > 0);
2235                 free(pids);
2236                 return r;
2237         }
2238         return -2;
2239 }
2240
2241 void set_ip_forward(char c)
2242 {
2243         FILE *fp;
2244
2245         if ((fp = fopen("/proc/sys/net/ipv4/ip_forward", "r+"))) {
2246                 fputc(c, fp);
2247                 fclose(fp);
2248         } else {
2249                 perror("/proc/sys/net/ipv4/ip_forward");
2250         }
2251 }
2252
2253 int ifexists(const char *ifname)
2254 {
2255         return getifcount(ifname) > 0 ? 1 : 0;
2256 }
2257
2258 int getifcount(const char *ifprefix)
2259 {
2260         /*
2261          * char devcall[128];
2262          *
2263          * sprintf (devcall, "cat /proc/net/dev|grep \"%s\"|wc -l", ifprefix);
2264          * FILE *in = popen (devcall, "rb"); if (in == NULL) return 0; int count;
2265          * fscanf (in, "%d", &count); pclose (in); return count;
2266          */
2267         char *iflist = malloc(256);
2268
2269         memset(iflist, 0, 256);
2270         int c = getIfList(iflist, ifprefix);
2271
2272         free(iflist);
2273         return c;
2274 }
2275
2276 static void skipline(FILE * in)
2277 {
2278         while (1) {
2279                 int c = getc(in);
2280
2281                 if (c == EOF)
2282                         return;
2283                 if (c == 0x0)
2284                         return;
2285                 if (c == 0xa)
2286                         return;
2287         }
2288 }
2289
2290 /*
2291  * strips trailing char(s) c from string
2292  */
2293 void strtrim_right(char *p, int c)
2294 {
2295         char *end;
2296         int len;
2297
2298         len = strlen(p);
2299         while (*p && len) {
2300                 end = p + len - 1;
2301                 if (c == *end)
2302                         *end = 0;
2303                 else
2304                         break;
2305                 len = strlen(p);
2306         }
2307         return;
2308 }
2309
2310 // returns a physical interfacelist filtered by ifprefix. if ifprefix is
2311 // NULL, all valid interfaces will be returned
2312 int getIfList(char *buffer, const char *ifprefix)
2313 {
2314         FILE *in = fopen("/proc/net/dev", "rb");
2315         char ifname[32];
2316
2317         // skip the first 2 lines
2318         skipline(in);
2319         skipline(in);
2320         int ifcount = 0;
2321         int count = 0;
2322
2323         while (1) {
2324                 int c = getc(in);
2325
2326                 if (c == EOF) {
2327                         if (count)
2328                                 buffer[strlen(buffer) - 1] = 0; // fixup last space
2329                         fclose(in);
2330                         return count;
2331                 }
2332                 if (c == 0) {
2333                         if (count)
2334                                 buffer[strlen(buffer) - 1] = 0; // fixup last space
2335                         fclose(in);
2336                         return count;
2337                 }
2338                 if (c == 0x20)
2339                         continue;
2340                 if (c == ':' || ifcount == 30) {
2341                         ifname[ifcount++] = 0;
2342                         int skip = 0;
2343
2344                         if (ifprefix) {
2345                                 if (strncmp(ifname, ifprefix, strlen(ifprefix))) {
2346                                         skip = 1;
2347                                 }
2348                         } else {
2349                                 if (!strncmp(ifname, "wifi", 4))
2350                                         skip = 1;
2351                                 if (!strncmp(ifname, "ifb", 3))
2352                                         skip = 1;
2353                                 if (!strncmp(ifname, "imq", 3))
2354                                         skip = 1;
2355                                 if (!strncmp(ifname, "etherip", 7))
2356                                         skip = 1;
2357                                 if (!strncmp(ifname, "lo", 2))
2358                                         skip = 1;
2359                                 if (!strncmp(ifname, "teql", 4))
2360                                         skip = 1;
2361                                 if (!strncmp(ifname, "gre", 3))
2362                                         skip = 1;
2363                                 if (!strncmp(ifname, "ppp", 3))
2364                                         skip = 1;
2365                                 if (!strncmp(ifname, "tun", 3))
2366                                         skip = 1;
2367                                 if (!strncmp(ifname, "tap", 3))
2368                                         skip = 1;
2369                         }
2370                         if (!skip) {
2371                                 strcat(buffer, ifname);
2372                                 strcat(buffer, " ");
2373                                 count++;
2374                         }
2375                         skip = 0;
2376                         ifcount = 0;
2377                         memset(ifname, 0, 32);
2378                         skipline(in);
2379                         continue;
2380                 }
2381                 if (ifcount < 30)
2382                         ifname[ifcount++] = c;
2383         }
2384 }
2385
2386 /*
2387  * Example: legal_hwaddr("00:11:22:33:44:aB"); return true;
2388  * legal_hwaddr("00:11:22:33:44:5"); return false;
2389  * legal_hwaddr("00:11:22:33:44:HH"); return false;
2390  */
2391 int sv_valid_hwaddr(char *value)
2392 {
2393         unsigned int hwaddr[6];
2394         int tag = TRUE;
2395         int i, count;
2396
2397         /*
2398          * Check for bad, multicast, broadcast, or null address
2399          */
2400         for (i = 0, count = 0; *(value + i); i++) {
2401                 if (*(value + i) == ':') {
2402                         if ((i + 1) % 3 != 0) {
2403                                 tag = FALSE;
2404                                 break;
2405                         }
2406                         count++;
2407                 } else if (ishexit(*(value + i)))       /* one of 0 1 2 3 4 5 6 7 8 9
2408                                                          * a b c d e f A B C D E F */
2409                         continue;
2410                 else {
2411                         tag = FALSE;
2412                         break;
2413                 }
2414         }
2415
2416         if (!tag || i != 17 || count != 5)      /* must have 17's characters and 5's
2417                                                  * ':' */
2418                 tag = FALSE;
2419         else if (sscanf(value, "%x:%x:%x:%x:%x:%x",
2420                         &hwaddr[0], &hwaddr[1], &hwaddr[2],
2421                         &hwaddr[3], &hwaddr[4], &hwaddr[5]) != 6) {
2422                 tag = FALSE;
2423         } else
2424                 tag = TRUE;
2425 #ifdef WDS_DEBUG
2426         if (tag == FALSE)
2427                 fprintf(fp, "failed valid_hwaddr\n");
2428 #endif
2429
2430         return tag;
2431 }
2432
2433 int led_control(int type, int act)
2434 /*
2435  * type: LED_POWER, LED_DIAG, LED_DMZ, LED_CONNECTED, LED_BRIDGE, LED_VPN,
2436  * LED_SES, LED_SES2, LED_WLAN act: LED_ON, LED_OFF, LED_FLASH
2437  */
2438 {
2439 #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))
2440         return 0;
2441 #else
2442         int use_gpio = 0x0ff;
2443         int gpio_value;
2444         int enable;
2445         int disable;
2446
2447         int power_gpio = 0x0ff;
2448         int diag_gpio = 0x0ff;
2449         int dmz_gpio = 0x0ff;
2450         int connected_gpio = 0x0ff;
2451         int bridge_gpio = 0x0ff;
2452         int vpn_gpio = 0x0ff;
2453         int ses_gpio = 0x0ff;   // use for SES1 (Linksys), AOSS (Buffalo)
2454         int ses2_gpio = 0x0ff;
2455         int wlan_gpio = 0x0ff;  // use this only if wlan led is not controlled by hardware!
2456         int usb_gpio = 0x0ff;
2457         int sec0_gpio = 0x0ff;  // security leds, wrt600n
2458         int sec1_gpio = 0x0ff;
2459         int v1func = 0;
2460
2461         switch (getRouterBrand())       // gpio definitions here: 0xYZ,
2462                 // Y=0:normal, Y=1:inverted, Z:gpio
2463                 // number (f=disabled)
2464         {
2465 #ifndef HAVE_BUFFALO
2466         case ROUTER_ALLNET01:
2467                 connected_gpio = 0x100;
2468                 break;
2469         case ROUTER_BOARD_WP54G:
2470                 diag_gpio = 0x102;
2471                 connected_gpio = 0x107;
2472                 break;
2473         case ROUTER_BOARD_NP28G:
2474                 diag_gpio = 0x102;
2475                 connected_gpio = 0x106;
2476                 break;
2477         case ROUTER_BOARD_GATEWORX:
2478 #ifdef HAVE_WG302V1
2479                 diag_gpio = 0x104;
2480                 wlan_gpio = 0x105;
2481 #elif HAVE_WG302
2482                 diag_gpio = 0x102;
2483                 wlan_gpio = 0x104;
2484 #else
2485                 if (nvram_match("DD_BOARD", "Cambria GW2350")
2486                     || nvram_match("DD_BOARD2", "Cambria GW2350"))
2487                         connected_gpio = 0x105;
2488                 else if (nvram_match("DD_BOARD", "Cambria GW2358-4")
2489                          || nvram_match("DD_BOARD2", "Cambria GW2358-4"))
2490                         connected_gpio = 0x118;
2491                 else
2492                         connected_gpio = 0x003;
2493 #endif
2494                 break;
2495         case ROUTER_BOARD_GATEWORX_SWAP:
2496                 connected_gpio = 0x004;
2497                 break;
2498         case ROUTER_BOARD_STORM:
2499                 connected_gpio = 0x005;
2500                 diag_gpio = 0x003;
2501                 break;
2502         case ROUTER_LINKSYS_WRH54G:
2503                 diag_gpio = 0x101;      // power led blink / off to indicate factory
2504                 // defaults
2505                 break;
2506         case ROUTER_WRT54G:
2507         case ROUTER_WRT54G_V8:
2508                 power_gpio = 0x001;
2509                 dmz_gpio = 0x107;
2510                 connected_gpio = 0x103; // ses orange
2511                 ses_gpio = 0x102;       // ses white
2512                 ses2_gpio = 0x103;      // ses orange
2513                 break;
2514         case ROUTER_WRT54G_V81:
2515                 power_gpio = 0x101;
2516                 dmz_gpio = 0x102;
2517                 connected_gpio = 0x104; // ses orange
2518                 ses_gpio = 0x103;       // ses white
2519                 ses2_gpio = 0x104;      // ses orange
2520                 break;
2521         case ROUTER_WRT54G1X:
2522                 connected_gpio = 0x103;
2523                 v1func = 1;
2524                 break;
2525         case ROUTER_WRT350N:
2526                 connected_gpio = 0x103;
2527                 power_gpio = 0x001;
2528                 ses2_gpio = 0x103;      // ses orange
2529                 sec0_gpio = 0x109;
2530                 usb_gpio = 0x10b;
2531                 break;
2532         case ROUTER_WRT600N:
2533                 power_gpio = 0x102;
2534                 diag_gpio = 0x002;
2535                 usb_gpio = 0x103;
2536                 sec0_gpio = 0x109;
2537                 sec1_gpio = 0x10b;
2538                 break;
2539         case ROUTER_LINKSYS_WRT55AG:
2540                 connected_gpio = 0x103;
2541                 break;
2542         case ROUTER_DLINK_DIR330:
2543                 diag_gpio = 0x106;
2544                 connected_gpio = 0x100;
2545                 usb_gpio = 0x104;
2546                 break;
2547 #endif
2548         case ROUTER_BOARD_WHRG300N:
2549                 diag_gpio = 0x107;
2550                 connected_gpio = 0x109;
2551                 ses_gpio = 0x10e;
2552                 break;
2553         case ROUTER_BUFFALO_WBR54G:
2554                 diag_gpio = 0x107;
2555                 break;
2556         case ROUTER_BUFFALO_WBR2G54S:
2557                 diag_gpio = 0x001;
2558                 ses_gpio = 0x006;
2559                 break;
2560         case ROUTER_BUFFALO_WLA2G54C:
2561                 diag_gpio = 0x104;
2562                 ses_gpio = 0x103;
2563                 break;
2564         case ROUTER_BUFFALO_WLAH_G54:
2565                 diag_gpio = 0x107;
2566                 ses_gpio = 0x106;
2567                 break;
2568         case ROUTER_BUFFALO_WAPM_HP_AM54G54:
2569                 diag_gpio = 0x107;
2570                 ses_gpio = 0x101;
2571                 break;
2572         case ROUTER_BOARD_WHRAG108:
2573                 diag_gpio = 0x107;
2574                 bridge_gpio = 0x104;
2575                 ses_gpio = 0x100;
2576                 break;
2577         case ROUTER_BUFFALO_WHRG54S:
2578         case ROUTER_BUFFALO_WLI_TX4_G54HP:
2579                 diag_gpio = 0x107;     
2580                 if (nvram_match("DD_BOARD", "Buffalo WHR-G125"))
2581                 {
2582                 connected_gpio = 0x101;
2583                 sec0_gpio = 0x106;                     
2584                 }
2585                 else
2586                 {
2587                 bridge_gpio = 0x101;
2588                 ses_gpio = 0x106;
2589                 }
2590                 break;
2591         case ROUTER_BUFFALO_WZRRSG54:
2592                 diag_gpio = 0x107;
2593                 vpn_gpio = 0x101;
2594                 ses_gpio = 0x106;
2595                 break;
2596         case ROUTER_BUFFALO_WZRG300N:
2597                 diag_gpio = 0x107;
2598                 bridge_gpio = 0x101;
2599                 break;
2600         case ROUTER_BUFFALO_WZRG144NH:
2601                 diag_gpio = 0x103;
2602                 bridge_gpio = 0x101;
2603                 ses_gpio = 0x102;
2604                 break;
2605 #ifndef HAVE_BUFFALO
2606 #ifdef HAVE_DIR300
2607         case ROUTER_BOARD_FONERA:
2608                 diag_gpio = 0x003;
2609                 bridge_gpio = 0x004;
2610                 ses_gpio = 0x001;
2611                 break;
2612 #endif
2613 #ifdef HAVE_WRT54G2
2614         case ROUTER_BOARD_FONERA:
2615                 bridge_gpio = 0x004;
2616                 ses_gpio = 0x104;
2617                 diag_gpio = 0x103;
2618                 break;
2619 #endif
2620 #ifdef HAVE_BWRG1000
2621         case ROUTER_BOARD_LS2:
2622                 diag_gpio = 0x007;
2623                 break;
2624 #endif
2625 #ifdef HAVE_DIR400
2626         case ROUTER_BOARD_FONERA2200:
2627                 diag_gpio = 0x003;
2628                 bridge_gpio = 0x004;
2629                 ses_gpio = 0x001;
2630                 break;
2631 #endif
2632 #ifdef HAVE_WRK54G
2633         case ROUTER_BOARD_FONERA:
2634                 diag_gpio = 0x107;
2635                 dmz_gpio = 0x005;
2636                 break;
2637 #endif
2638         case ROUTER_BOARD_TW6600:
2639                 diag_gpio = 0x107;
2640                 bridge_gpio = 0x104;
2641                 ses_gpio = 0x100;
2642                 break;
2643         case ROUTER_MOTOROLA:
2644                 power_gpio = 0x001;
2645                 diag_gpio = 0x101;      // power led blink / off to indicate factory
2646                 // defaults
2647                 break;
2648         case ROUTER_RT210W:
2649                 power_gpio = 0x105;
2650                 diag_gpio = 0x005;      // power led blink / off to indicate factory
2651                 // defaults
2652                 connected_gpio = 0x100;
2653                 wlan_gpio = 0x103;
2654                 break;
2655         case ROUTER_RT480W:
2656         case ROUTER_BELKIN_F5D7230_V2000:
2657         case ROUTER_BELKIN_F5D7231:
2658                 power_gpio = 0x105;
2659                 diag_gpio = 0x005;      // power led blink / off to indicate factory
2660                 // defaults
2661                 connected_gpio = 0x100;
2662                 break;
2663         case ROUTER_MICROSOFT_MN700:
2664                 power_gpio = 0x006;
2665                 diag_gpio = 0x106;      // power led blink / off to indicate factory
2666                 // defaults
2667                 break;
2668         case ROUTER_ASUS_WL500GD:
2669         case ROUTER_ASUS_WL520GUGC:
2670                 diag_gpio = 0x000;      // power led blink / off to indicate factory
2671                 // defaults
2672                 break;
2673         case ROUTER_ASUS_WL500G_PRE:
2674                 power_gpio = 0x101;
2675                 diag_gpio = 0x001;      // power led blink / off to indicate factory
2676                 // defaults
2677                 break;
2678         case ROUTER_ASUS_WL550GE:
2679                 power_gpio = 0x102;
2680                 diag_gpio = 0x002;      // power led blink / off to indicate factory
2681                 // defaults
2682                 break;
2683         case ROUTER_WRT54G3G:
2684         case ROUTER_WRTSL54GS:
2685                 power_gpio = 0x001;
2686                 dmz_gpio = 0x100;
2687                 connected_gpio = 0x107; // ses orange
2688                 ses_gpio = 0x105;       // ses white
2689                 ses2_gpio = 0x107;      // ses orange
2690                 break;
2691         case ROUTER_MOTOROLA_WE800G:
2692         case ROUTER_MOTOROLA_V1:
2693                 diag_gpio = 0x103;
2694                 wlan_gpio = 0x101;
2695                 bridge_gpio = 0x105;
2696                 break;
2697         case ROUTER_DELL_TRUEMOBILE_2300:
2698         case ROUTER_DELL_TRUEMOBILE_2300_V2:
2699                 power_gpio = 0x107;
2700                 diag_gpio = 0x007;      // power led blink / off to indicate factory
2701                 // defaults
2702                 wlan_gpio = 0x106;
2703                 break;
2704         case ROUTER_NETGEAR_WNR834B:
2705                 power_gpio = 0x104;
2706                 diag_gpio = 0x105;
2707                 wlan_gpio = 0x106;
2708                 break;
2709         case ROUTER_SITECOM_WL105B:
2710                 power_gpio = 0x003;
2711                 diag_gpio = 0x103;      // power led blink / off to indicate factory
2712                 // defaults
2713                 wlan_gpio = 0x104;
2714                 break;
2715         case ROUTER_WRT150N:
2716         case ROUTER_WRT300N:
2717                 power_gpio = 0x001;
2718                 diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
2719                 break;
2720         case ROUTER_WRT300NV11:
2721                 ses_gpio = 0x105;
2722                 // diag_gpio = 0x11; //power led blink / off to indicate fac.def.
2723                 break;
2724         case ROUTER_WRT310N:
2725                 connected_gpio = 0x103;
2726                 power_gpio = 0x001;
2727                 diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
2728                 ses2_gpio = 0x103;      // ses orange
2729         case ROUTER_WRT160N:
2730                 power_gpio = 0x001;
2731                 diag_gpio = 0x101;      // power led blink / off to indicate fac.def.
2732                 //
2733                 connected_gpio = 0x103; // ses orange
2734                 ses_gpio = 0x105;       // ses blue
2735                 break;
2736         case ROUTER_ASUS_WL500G:
2737                 power_gpio = 0x100;
2738                 diag_gpio = 0x000;      // power led blink /off to indicate factory
2739                 // defaults
2740                 break;
2741         case ROUTER_ASUS_WL500W:
2742                 power_gpio = 0x105;
2743                 diag_gpio = 0x005;      // power led blink /off to indicate factory
2744                 // defaults
2745                 break;
2746         case ROUTER_LINKSYS_WTR54GS:
2747                 diag_gpio = 0x001;
2748                 break;
2749         case ROUTER_WAP54G_V1:
2750                 diag_gpio = 0x103;
2751                 wlan_gpio = 0x104;      // LINK led
2752                 break;
2753         case ROUTER_WAP54G_V3:
2754                 ses_gpio = 0x10c;
2755                 connected_gpio = 0x006;
2756                 break;
2757         case ROUTER_NETGEAR_WNR834BV2:
2758                 power_gpio = 0x002;
2759                 diag_gpio = 0x003;      // power led amber
2760                 connected_gpio = 0x007; // WAN led green
2761                 break;
2762         case ROUTER_NETGEAR_WNDR3300:
2763                 power_gpio = 0x005;
2764                 diag_gpio = 0x105;      // power led blink /off to indicate factory defaults
2765                 connected_gpio = 0x007; // WAN led green
2766                 break;
2767         case ROUTER_ASKEY_RT220XD:
2768                 wlan_gpio = 0x100;
2769                 dmz_gpio = 0x101;       // not soldered
2770                 break;
2771         case ROUTER_WRT610N:
2772                 power_gpio = 0x001;
2773                 connected_gpio = 0x103; // ses amber
2774                 ses_gpio = 0x109;       // ses blue
2775                 usb_gpio = 0x100;
2776                 break;
2777         case ROUTER_USR_5461:
2778                 usb_gpio = 0x001;
2779                 break;
2780         case ROUTER_NETGEAR_WGR614L:
2781                 // power_gpio = 0x107;       // don't use - resets router
2782                 diag_gpio = 0x006;
2783                 connected_gpio = 0x104;
2784                 break;
2785         case ROUTER_NETGEAR_WG602_V4:
2786                 power_gpio = 0x101;     // trick: make lan led green for 100Mbps
2787                 break;
2788         case ROUTER_BELKIN_F5D7231_V2000:
2789                 connected_gpio = 0x104;
2790                 diag_gpio = 0x001;      // power led blink /off to indicate factory defaults
2791                 break;
2792
2793 #endif
2794         }
2795         if (type == LED_DIAG && v1func == 1) {
2796                 if (act == LED_ON)
2797                         C_led(1);
2798                 else
2799                         C_led(0);
2800         }
2801
2802         switch (type) {
2803         case LED_POWER:
2804                 use_gpio = power_gpio;
2805                 break;
2806         case LED_DIAG:
2807                 use_gpio = diag_gpio;
2808                 break;
2809         case LED_DMZ:
2810                 use_gpio = dmz_gpio;
2811                 break;
2812         case LED_CONNECTED:
2813                 use_gpio = connected_gpio;
2814                 break;
2815         case LED_BRIDGE:
2816                 use_gpio = bridge_gpio;
2817                 break;
2818         case LED_VPN:
2819                 use_gpio = vpn_gpio;
2820                 break;
2821         case LED_SES:
2822                 use_gpio = ses_gpio;
2823                 break;
2824         case LED_SES2:
2825                 use_gpio = ses2_gpio;
2826                 break;
2827         case LED_WLAN:
2828                 use_gpio = wlan_gpio;
2829                 break;
2830         case LED_USB:
2831                 use_gpio = usb_gpio;
2832                 break;
2833         case LED_SEC0:
2834                 use_gpio = sec0_gpio;
2835                 break;
2836         case LED_SEC1:
2837                 use_gpio = sec1_gpio;
2838                 break;
2839         }
2840         if ((use_gpio & 0x0ff) != 0x0ff) {
2841                 gpio_value = use_gpio & 0x0ff;
2842                 enable = (use_gpio & 0x100) == 0 ? 1 : 0;
2843                 disable = (use_gpio & 0x100) == 0 ? 0 : 1;
2844                 switch (act) {
2845                 case LED_ON:
2846                         set_gpio(gpio_value, enable);
2847                         break;
2848                 case LED_OFF:
2849                         set_gpio(gpio_value, disable);
2850                         break;
2851                 case LED_FLASH: // will lit the led for 1 sec.
2852                         set_gpio(gpio_value, enable);
2853                         sleep(1);
2854                         set_gpio(gpio_value, disable);
2855                         break;
2856                 }
2857         }
2858         return 1;
2859
2860 #endif
2861 }
2862
2863 int file_to_buf(char *path, char *buf, int len)
2864 {
2865         FILE *fp;
2866
2867         memset(buf, 0, len);
2868
2869         if ((fp = fopen(path, "r"))) {
2870                 fgets(buf, len, fp);
2871                 fclose(fp);
2872                 return 1;
2873         }
2874
2875         return 0;
2876 }
2877
2878 int ishexit(char c)
2879 {
2880
2881         if (strchr("01234567890abcdefABCDEF", c) != (char *)0)
2882                 return 1;
2883
2884         return 0;
2885 }
2886
2887 int getMTD(char *name)
2888 {
2889         char buf[128];
2890         int device;
2891
2892         sprintf(buf, "cat /proc/mtd|grep \"%s\"", name);
2893         FILE *fp = popen(buf, "rb");
2894
2895         fscanf(fp, "%s", &buf[0]);
2896         device = buf[3] - '0';
2897         pclose(fp);
2898         return device;
2899 }
2900
2901 int insmod(char *module)
2902 {
2903         return eval("insmod", module);
2904 }
2905
2906 void rmmod(char *module)
2907 {
2908         eval("rmmod", module);
2909 }
2910
2911 #include "revision.h"
2912
2913 char *getSoftwareRevision(void)
2914 {
2915         return "" SVN_REVISION "";
2916 }
2917
2918 #ifdef HAVE_OLED
2919 void initlcd()
2920 {
2921
2922 }
2923
2924 void lcdmessage(char *message)
2925 {
2926         eval("oled-print", "DD-WRT v24 sp2", "build:" SVN_REVISION,
2927              "3G/UMTS Router", message);
2928 }
2929
2930 void lcdmessaged(char *dual, char *message)
2931 {
2932
2933 }
2934
2935 #endif
2936
2937 #if 0
2938
2939 static int fd;
2940
2941 void SetEnvironment()
2942 {
2943         system("stty ispeed 2400 < /dev/tts/1");
2944         system("stty raw < /dev/tts/1");
2945 }
2946
2947 int Cmd = 254;                  /* EZIO Command */
2948 int cls = 1;                    /* Clear screen */
2949 void Cls()
2950 {
2951         write(fd, &Cmd, 1);
2952         write(fd, &cls, 1);
2953 }
2954
2955 int init = 0x28;
2956 void Init()
2957 {
2958         write(fd, &Cmd, 1);
2959         write(fd, &init, 1);
2960 }
2961
2962 int stopsend = 0x37;
2963 void StopSend()
2964 {
2965         write(fd, &Cmd, 1);
2966         write(fd, &init, 1);
2967 }
2968
2969 int home = 2;                   /* Home cursor */
2970 void Home()
2971 {
2972         write(fd, &Cmd, 1);
2973         write(fd, &home, 1);
2974 }
2975
2976 int readkey = 6;                /* Read key */
2977 void ReadKey()
2978 {
2979         write(fd, &Cmd, 1);
2980         write(fd, &readkey, 1);
2981 }
2982
2983 int blank = 8;                  /* Blank display */
2984 void Blank()
2985 {
2986         write(fd, &Cmd, 1);
2987         write(fd, &blank, 1);
2988 }
2989
2990 int hide = 12;                  /* Hide cursor & display blanked characters */
2991 void Hide()
2992 {
2993         write(fd, &Cmd, 1);
2994         write(fd, &hide, 1);
2995 }
2996
2997 int turn = 13;                  /* Turn On (blinking block cursor) */
2998 void TurnOn()
2999 {
3000         write(fd, &Cmd, 1);
3001         write(fd, &turn, 1);
3002 }
3003
3004 int show = 14;                  /* Show underline cursor */
3005 void Show()
3006 {
3007         write(fd, &Cmd, 1);
3008         write(fd, &show, 1);
3009 }
3010
3011 int movel = 16;                 /* Move cursor 1 character left */
3012 void MoveL()
3013 {
3014         write(fd, &Cmd, 1);
3015         write(fd, &movel, 1);
3016 }
3017
3018 int mover = 20;                 /* Move cursor 1 character right */
3019 void MoveR()
3020 {
3021         write(fd, &Cmd, 1);
3022         write(fd, &mover, 1);
3023 }
3024
3025 int scl = 24;                   /* Scroll cursor 1 character left */
3026 void ScrollL()
3027 {
3028         write(fd, &Cmd, 1);
3029         write(fd, &scl, 1);
3030 }
3031
3032 int scr = 28;                   /* Scroll cursor 1 character right */
3033 void ScrollR()
3034 {
3035         write(fd, &Cmd, 1);
3036         write(fd, &scr, 1);
3037 }
3038
3039 int setdis = 64;                /* Command */
3040 void SetDis()
3041 {
3042         write(fd, &Cmd, 1);
3043         write(fd, &setdis, 1);
3044
3045 }
3046
3047 int a, b;
3048 void ShowMessage(char *str1, char *str2)
3049 {
3050         char nul[] = "                                       ";
3051
3052         a = strlen(str1);
3053         b = 40 - a;
3054         write(fd, str1, a);
3055         write(fd, nul, b);
3056         write(fd, str2, strlen(str2));
3057 }
3058
3059 void initlcd()
3060 {
3061
3062         fd = open("/dev/tts/1", O_RDWR);
3063
3064                                   /** Open Serial port (COM2) */
3065         if (fd > 0) {
3066                 close(fd);
3067                 SetEnvironment();       /* Set RAW mode */
3068                 fd = open("/dev/tts/1", O_RDWR);
3069                 Init();         /* Initialize EZIO twice */
3070                 Init();
3071
3072                 Cls();          /* Clear screen */
3073         }
3074         close(fd);
3075 }
3076
3077 void lcdmessage(char *message)
3078 {
3079
3080         fd = open("/dev/tts/1", O_RDWR);
3081                                    /** Open Serial port (COM2) */
3082
3083         if (fd > 0) {
3084                 Init();         /* Initialize EZIO twice */
3085                 Init();
3086                 SetDis();
3087                 Cls();
3088                 Home();
3089                 ShowMessage("State", message);
3090                 close(fd);
3091         }
3092 }
3093
3094 void lcdmessaged(char *dual, char *message)
3095 {
3096
3097         fd = open("/dev/tts/1", O_RDWR);
3098
3099                                   /** Open Serial port (COM2) */
3100
3101         if (fd > 0) {
3102                 Init();         /* Initialize EZIO twice */
3103                 Init();
3104                 SetDis();
3105                 Cls();          /* Clear screen */
3106                 Home();
3107                 ShowMessage(dual, message);
3108                 close(fd);
3109         }
3110 }
3111
3112 #endif
3113 static int i64c(int i)
3114 {
3115         i &= 0x3f;
3116         if (i == 0)
3117                 return '.';
3118         if (i == 1)
3119                 return '/';
3120         if (i < 12)
3121                 return ('0' - 2 + i);
3122         if (i < 38)
3123                 return ('A' - 12 + i);
3124         return ('a' - 38 + i);
3125 }
3126
3127 int crypt_make_salt(char *p, int cnt, int x)
3128 {
3129         x += getpid() + time(NULL);
3130         do {
3131                 /*
3132                  * x = (x*1664525 + 1013904223) % 2^32 generator is lame (low-order
3133                  * bit is not "random", etc...), but for our purposes it is good
3134                  * enough
3135                  */
3136                 x = x * 1664525 + 1013904223;
3137                 /*
3138                  * BTW, Park and Miller's "minimal standard generator" is x = x*16807
3139                  * % ((2^31)-1) It has no problem with visibly alternating lowest bit
3140                  * but is also weak in cryptographic sense + needs div, which needs
3141                  * more code (and slower) on many CPUs
3142                  */
3143                 *p++ = i64c(x >> 16);
3144                 *p++ = i64c(x >> 22);
3145         }
3146         while (--cnt);
3147         *p = '\0';
3148         return x;
3149 }
3150
3151 #define MD5_OUT_BUFSIZE 36
3152
3153 char *zencrypt(char *passwd)
3154 {
3155         char salt[sizeof("$N$XXXXXXXX")];       /* "$N$XXXXXXXX" or "XX" */
3156         static char passout[MD5_OUT_BUFSIZE];
3157
3158         strcpy(salt, "$1$");
3159         crypt_make_salt(salt + 3, 4, 0);
3160         return md5_crypt(passout, (unsigned char *)passwd,
3161                          (unsigned char *)salt);
3162 }
Note: See TracBrowser for help on using the browser.