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

Last change on this file since 11969 was 11969, checked in by BrainSlayer, 4 years ago

optional serial fixes for gw2358 and gw2350

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