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

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

optional serial fixes for gw2358 and gw2350

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