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

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

clean Asus detection: still don't know who deleted boardnum variable?

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