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

Last change on this file since 11885 was 11885, checked in by eko, 4 years ago

security leds for wrt600n ....

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