www.usr.com/support/gpl/USR9108_release1.5.tar.gz
[bcm963xx.git] / userapps / broadcom / cfm / util / system / syscall.c
1 /*****************************************************************************
2 //
3 //  Copyright (c) 2000-2001  Broadcom Corporation
4 //  All Rights Reserved
5 //  No portions of this material may be reproduced in any form without the
6 //  written permission of:
7 //          Broadcom Corporation
8 //          16215 Alton Parkway
9 //          Irvine, California 92619
10 //  All information contained in this document is Broadcom Corporation
11 //  company private, proprietary, and trade secret.
12 //
13 ******************************************************************************
14 //
15 //  Filename:       syscall.c
16 //  Author:         Peter T. Tran
17 //  Creation Date:  12/26/01
18 //
19 ******************************************************************************
20 //  Description:
21 //      It provides system call functions for Linux.
22 //
23 *****************************************************************************/
24
25 /********************** Include Files ***************************************/
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <arpa/inet.h>
30 #include <unistd.h>
31 #include <signal.h>
32 #include <errno.h>
33 #include <pwd.h>
34 #include <crypt.h>
35 #include <time.h>
36 #include <sys/wait.h>
37 #include <sys/socket.h>
38 #include <sys/ioctl.h>
39 #include <sys/types.h>
40 #include <sys/utsname.h>
41 #include <dirent.h>
42 #include <ctype.h>
43 #include <net/if.h>
44 #include <net/route.h>
45 #include <string.h>
46 #include <syslog.h>
47 #include <fcntl.h>
48
49 #include "bcmtypes.h"
50 #ifdef USE_ALL
51 #include "bcmadsl.h"
52 #include "ifcdefs.h"
53 #include "psiapi.h"
54 #include "sysdiag.h"
55 #include "clidefs.h"
56 #include "cliapi.h"
57 #include "adslctlapi.h"
58 #include "secapi.h"
59 #include "dbapi.h"
60 #include "dbobject.h"
61 #include "dbvalid.h"
62 #include "version.h"
63 #ifdef PORT_MIRRORING
64 #include <atm.h>
65 #include "portMirror.h"
66 #include "atmapidrv.h"
67 #endif
68 #endif
69
70 #include "syscall.h"
71 #include "board_api.h"
72 #include "bcmTag.h"
73
74 #define PRIORITY_HIGH    3
75 #define PRIORITY_MEDIUM  2
76 #define PRIORITY_LOW     1
77
78 #ifdef BUILD_STATIC
79 #include "busybox.h"
80 #endif
81
82 extern char **environ;
83 extern char *getIfName(void);
84
85 #define READ_BUF_SIZE        128
86 #define CONNTRACK_MUX        2000
87
88 /* If you change this definition, make sure you change it everywhere */
89 #define UDHCPD_DECLINE "/var/udhcpd.decline"
90
91 #ifdef USE_ALL
92
93 /***************************************************************************
94 // Function Name: bcmSystemNoHang().
95 // Description  : launch shell command in the child process without hang.
96 // Parameters   : command - shell command to launch.
97 // Returns      : status 0 - OK, -1 - ERROR.
98 ****************************************************************************/
99 int bcmSystemNoHang (char *command) {
100    int pid = 0, status = 0, counter = 0, ret = 0;
101
102    if ( command == 0 )
103       return 1;
104
105    pid = fork();
106    if ( pid == -1 )
107       return -1;
108
109    if ( pid == 0 ) {
110       char *argv[4];
111       argv[0] = "sh";
112       argv[1] = "-c";
113       argv[2] = command;
114       argv[3] = 0;
115       execve("/bin/sh", argv, environ);
116       exit(127);
117    }
118
119    do {
120       // check the child is exited or not without hang
121       ret = waitpid(pid, &status, WNOHANG | WUNTRACED);
122       switch ( ret ) {
123          case -1:   // error occurs then return -1
124             return -1;
125          case 0:    // child does not exited yet
126             sleep(1);
127             if ( ++counter > 19 ) {
128 #ifdef BRCM_DEBUG
129                printf("app: child process cannot exits while executing command - %s\n", command);
130 #endif
131                kill(pid, SIGTERM);
132                return -1;
133             }
134             break;
135          default:   // child does exit successfully
136             return status;
137       }
138    } while ( 1 );
139
140    return status;
141 }
142
143 /***************************************************************************
144 // Function Name: bcmCreateDhcpCfg().
145 // Description  : create DHCP server configuration file.
146 // Parameters   : ipAddr - IP address of target.
147 //                mask - subnet mask of target.
148 //                addrStart - start IP address of DHCP server pool.
149 //                addrEnd - end IP address of DHCP server pool.
150 //                dns1 - primary dns.
151 //                dns2 - secondary dns.
152 //                leasedTime - leased time.
153 //                protoInfo - current network protocol.
154 //                enblNat -- is nat enabled?
155 //                enblFirewall -- is firewall enabled?
156 // Returns      : status 0 - OK, -1 - ERROR.
157 ****************************************************************************/
158 int bcmCreateDhcpCfg(char *ipAddr, char *mask,
159                      char *addrStart, char *addrEnd,
160                      char *dns1, char *dns2, int leasedTime,
161                      int protocol, int enblNat, int enblFirewall) {
162    FILE* fs = fopen("/etc/udhcpd.conf", "w");
163
164    if ( fs != NULL ) {
165       // cwu
166       char cmd[128]="";
167       sprintf(cmd, "echo %s > /var/run/ip", addrStart);
168       system(cmd);
169
170       // start IP address
171       sprintf(cmd, "start %s\n", addrStart);
172       fputs(cmd, fs);
173
174       // end IP address
175       sprintf(cmd, "end %s\n", addrEnd);
176       fputs(cmd, fs);
177
178       // interface
179       switch ( protocol ) {
180       case PROTO_PPPOA:
181       case PROTO_PPPOE:
182       case PROTO_MER:
183       case PROTO_IPOA:
184       case PROTO_NONE:
185 #if SUPPORT_ETHWAN
186       case PROTO_IPOWAN:
187 #endif
188          fputs("interface br0\n", fs);
189          break;
190       }
191
192       // If you change the name of this file, make sure you change it
193       // everywhere by searching for UDHCPD_DECLINE macro
194       sprintf(cmd, "decline_file %s\n", UDHCPD_DECLINE);
195       fputs(cmd, fs);
196
197           // lease
198       sprintf(cmd, "option lease %d\n", leasedTime);
199       fputs(cmd, fs);
200       sprintf(cmd, "option min_lease 30\n");
201       fputs(cmd, fs);
202
203       // subnet mask
204       sprintf(cmd, "option subnet %s\n", mask);
205       fputs(cmd, fs);
206
207       // router
208       sprintf(cmd, "option router %s\n", ipAddr);
209       fputs(cmd, fs);
210
211       // use DNS relay only when NAT is enabled
212       if ( enblNat == TRUE ) {
213          // always use DSL router IP address as DNS
214          // for DHCP server since we want local PCs
215          // use DHCP server relay. The real DNS is
216          // stored in /etc/resolv.conf
217          sprintf(cmd, "option dns %s\n", ipAddr);
218          fputs(cmd, fs);
219       } else { // use real DNS when NAT is disabled
220          // primary DNS
221          if ( strcmp(dns1, "0.0.0.0") != 0 )
222             sprintf(cmd, "option dns %s\n", dns1);
223          else
224             sprintf(cmd, "option dns %s\n", ipAddr);
225          fputs(cmd, fs);
226          // secondary DNS
227          if ( strcmp(dns2, "0.0.0.0") != 0 )
228             sprintf(cmd, "option dns %s\n", dns2);
229          else
230             sprintf(cmd, "option dns %s\n", ipAddr);
231          fputs(cmd, fs);
232       }
233
234       fclose(fs);
235       return FILE_OPEN_OK;
236    }
237
238    return FILE_OPEN_ERR;
239 }
240
241 /***************************************************************************
242 // Function Name: bcmCreateIpExtDhcpCfg().
243 // Description  : create DHCP server configuration file for PPP IP Extenstion.
244 // Parameters   : lanAddr - LAN IP address of target.
245 //                mask - subnet mask of target.
246 //                wanAddr - WAN IP address.
247 // Returns      : status 0 - OK, -1 - ERROR.
248 ****************************************************************************/
249 int bcmCreateIpExtDhcpCfg(char *lanAddr, char *mask, char *wanAddr) {
250    char cmd[SYS_CMD_LEN], dns[SYS_CMD_LEN];
251    FILE* fs = fopen("/etc/udhcpd.conf", "w");
252
253    if ( fs != NULL ) {
254        // cwu
255       sprintf(cmd, "echo %s > /var/run/ip", wanAddr);
256       system(cmd);
257
258
259       // start IP address
260       sprintf(cmd, "start %s\n", wanAddr);
261       fputs(cmd, fs);
262
263       // end IP address
264       sprintf(cmd, "end %s\n", wanAddr);
265       fputs(cmd, fs);
266
267       // interface
268       fputs("interface br0\n", fs);
269
270       // lease
271       fputs("option lease 30\n", fs);
272       fputs("option min_lease 30\n", fs);
273
274       // subnet mask
275       sprintf(cmd, "option subnet %s\n", mask);
276       fputs(cmd, fs);
277
278       // router
279       sprintf(cmd, "option router %s\n", wanAddr);
280       fputs(cmd, fs);
281
282       // don't use DNS relay since there is no ip table for
283       // PPP IP extension
284       bcmGetDns(dns);
285       sprintf(cmd, "option dns %s\n", dns);
286       fputs(cmd, fs);
287
288       fclose(fs);
289       return FILE_OPEN_OK;
290    }
291
292    return FILE_OPEN_ERR;
293 }
294
295 /***************************************************************************
296 // Function Name: bcmSetIpExtInfo().
297 // Description  : store wan, gateway, and dns for PPP IP extension.
298 // Parameters   : wan - WAN IP address.
299 //                gateway - default gateway.
300 //                dns - dns.
301 // Returns      : status 0 - OK, -1 - ERROR.
302 ****************************************************************************/
303 int bcmSetIpExtInfo(char *wan, char *gateway, char *dns) {
304    char str[256];
305    FILE* fs = fopen("/var/ipextinfo", "w");
306
307    if ( fs != NULL ) {
308       sprintf(str, "%s %s %s\n", wan, gateway, dns);
309       fputs(str, fs);
310       fclose(fs);
311       return FILE_OPEN_OK;
312    }
313
314    return FILE_OPEN_ERR;
315 }
316
317 /***************************************************************************
318 // Function Name: bcmGetIpExtInfo().
319 // Description  : get wan, gateway, or dns for PPP IP extension.
320 // Parameters   : buf - .
321 //                type - .
322 // Returns      : none.
323 ****************************************************************************/
324 void bcmGetIpExtInfo(char *buf, int type) {
325    FILE* fs;
326    char wan[64], gateway[64], dns[64], str[256];
327
328    if ( buf == NULL ) return;
329
330    buf[0] = '\0';
331    if( bcmGetAdslStatus() == MNTR_STS_OK ) {
332       fs = fopen("/var/ipextinfo", "r");
333       if ( fs != NULL ) {
334          fgets(str, 256, fs);
335          fclose(fs);
336          sscanf(str, "%s %s %s\n", wan, gateway, dns);
337          switch ( type ) {
338          case 0:
339             if( dns[0] >= '0' && dns[0] <= '9' )
340                strcpy(buf, wan);
341             break;
342          case 1:
343             if( dns[0] >= '0' && dns[0] <= '9' )
344                strcpy(buf, gateway);
345             break;
346          case 2:
347             if( dns[0] >= '0' && dns[0] <= '9' )
348                strcpy(buf, dns);
349             break;
350          }
351       }
352    }
353 }
354
355 /***************************************************************************
356 // Function Name: bcmCreateLocalDhcpCfg().
357 // Description  : create DHCP server configuration file with default local.
358 // Parameters   : ipAddr -- default local IP address.
359 //                mask -- default local subnet mask.
360 // Returns      : status 0 - OK, -1 - ERROR.
361 ****************************************************************************/
362 int bcmCreateLocalDhcpCfg(char *ipAddr, char *mask) {
363    FILE* fs = fopen("/etc/udhcpd.conf", "w");
364    char cmd[SYS_CMD_LEN], nextAddr[SYS_CMD_LEN];
365    struct in_addr addr;
366
367    if ( fs != NULL ) {
368       addr.s_addr = inet_addr(ipAddr) + 1;
369       strcpy(nextAddr, inet_ntoa(addr));
370
371       sprintf(cmd, "echo %s > /var/run/ip", nextAddr);
372       system(cmd);
373
374       // start IP address
375       fprintf(fs, "start %s\n", nextAddr);
376
377       // end IP address
378       fprintf(fs, "end %s\n", nextAddr);
379
380       // interface
381       fputs("interface br0\n", fs);
382
383       // lease
384       fputs("option lease 10\n", fs);
385       fputs("option min_lease 10\n", fs);
386
387       // subnet mask
388       fprintf(fs, "option subnet %s\n", mask);
389
390       // router
391       fprintf(fs, "option router %s\n", ipAddr);
392
393       // dns
394       fprintf(fs, "option dns %s\n", ipAddr);
395
396       fclose(fs);
397       return FILE_OPEN_OK;
398    }
399
400    return FILE_OPEN_ERR;
401 }
402
403 /***************************************************************************
404 // Function Name: bcmCreateResolvCfg().
405 // Description  : create resolv configuration file.
406 // Parameters   : dns1 - primary dns.
407 //                dns2 - secondary dns.
408 // Returns      : status 0 - OK, -1 - ERROR.
409 ****************************************************************************/
410 int bcmCreateResolvCfg(char *dns1, char *dns2) {
411    char cmd[SYS_CMD_LEN];
412    FILE* fs = NULL;
413
414    bcmSystemMute("mkdir -p /var/fyi/sys");
415    bcmSystemMute("echo > /var/fyi/sys/dns");
416    fs = fopen("/var/fyi/sys/dns", "w");
417
418    if ( fs != NULL ) {
419       sprintf(cmd, "nameserver %s\n", dns1);
420       fputs(cmd, fs);
421       sprintf(cmd, "nameserver %s\n", dns2);
422       fputs(cmd, fs);
423       fclose(fs);
424       return FILE_OPEN_OK;
425    }
426
427    return FILE_OPEN_ERR;
428 }
429
430 // global ADSL info variable is declared here (in syscall.c)
431 // and is used in syscall.c, sysdiag.c, cgimain.c, and cgists.c
432 ADSL_CONNECTION_INFO glbAdslInfo;
433
434 /***************************************************************************
435 // Function Name: bcmGetAdslStatus().
436 // Description  : get ADSL status.
437 // Parameters   : none
438 // Returns      : 0 - ADSL link Up (OK)
439 //                1 - ADSL link Down
440 //                2 - Other error
441 ****************************************************************************/
442 int bcmGetAdslStatus() {
443    int ret = 0;
444
445    if (BcmAdslCtl_GetConnectionInfo(&glbAdslInfo) != BCMADSL_STATUS_ERROR) {
446       ret = glbAdslInfo.LinkState;
447 //      if ( glbAdslInfo.LinkState == BCM_ADSL_LINK_UP )
448 //         ret = ADSL_LINK_UP;
449 //      else
450 //         ret = ADSL_LINK_DOWN;
451    } else
452       ret = BCMADSL_STATUS_ERROR;
453
454    return ret;
455 }
456
457 /***************************************************************************
458 // Function Name: bcmGetPppStatus().
459 // Description  : get PPP status.
460 // Parameters   : str - buffer to retrieve message
461 //                len - length of buffer
462 // Returns      : 0 - OK
463 //                -1 - ERROR
464 ****************************************************************************/
465 int bcmGetPppStatus(char *str, int len, char *name) {
466    FILE* fs;
467
468    char filePath[100];
469    sprintf(filePath,"/proc/var/fyi/wan/%s/daemonstatus",name);
470    fs = fopen(filePath, "r");
471    if ( fs != NULL ) {
472       fgets(str, len, fs);
473       fclose(fs);
474       return FILE_OPEN_OK;
475    }
476
477    return FILE_OPEN_ERR;
478 }
479
480 /***************************************************************************
481 // Function Name: bcmGetDhcpcStatus().
482 // Description  : get DHCPC status.
483 // Parameters   : str - buffer to retrieve message
484 //                len - length of buffer
485 // Returns      : 0 - OK
486 //                -1 - ERROR
487 ****************************************************************************/
488 int bcmGetDhcpcStatus(char *str, int len) {
489    FILE* fs = fopen("/var/run/dhcpc", "r");
490
491    if ( fs != NULL ) {
492       fgets(str, len, fs);
493       fclose(fs);
494       return FILE_OPEN_OK;
495    }
496
497    return FILE_OPEN_ERR;
498 }
499
500 /***************************************************************************
501 // Function Name: bcmGetSystemStatus().
502 // Description  : get system status.
503 // Parameters   : str - buffer to retrieve message
504 //                len - length of buffer
505 // Returns      : 0 - OK
506 //                -1 - ERROR
507 ****************************************************************************/
508 int bcmGetSystemStatus(char *str, int len) {
509    FILE* fs = fopen("/etc/sysmsg", "r");
510
511    if ( fs != NULL ) {
512       fgets(str, len, fs);
513       fclose(fs);
514       return FILE_OPEN_OK;
515    }
516
517    return FILE_OPEN_ERR;
518 }
519
520 /***************************************************************************
521 // Function Name: bcmSetSystemStatus().
522 // Description  : set system status.
523 // Parameters   : int - system status
524 // Returns      : 0 - OK
525 //                -1 - ERROR
526 ****************************************************************************/
527 int bcmSetSystemStatus(int status) {
528    char cmd[SYS_CMD_LEN];
529    FILE* fs = fopen("/etc/sysmsg", "w");
530
531    if ( fs != NULL ) {
532       sprintf(cmd, "%d\n", status);
533       fputs(cmd, fs);
534       fclose(fs);
535       return FILE_OPEN_OK;
536    }
537
538    return FILE_OPEN_ERR;
539 }
540
541 /***************************************************************************
542 // Function Name: bcmDisplayLed().
543 // Description  : display LED corresponding to WAN link status.
544 // Parameters   : status - WAN link status.
545 // Returns      : none.
546 ****************************************************************************/
547 void bcmDisplayLed(int status) {
548    switch (status) {
549    case MNTR_STS_ADSL_DOWN:
550       /* this means ADSL is DOWN */
551       sysLedCtrl(kLedPPP, kLedStateOff);
552       break;
553    case MNTR_STS_ADSL_TRAINING:
554       /* this means ADSL is TRAINING */
555       sysLedCtrl(kLedPPP, kLedStateOff);
556       break;
557    case MNTR_STS_PPP_AUTH_ERR:
558       //sysLedCtrl(kLedPPP, kLedStateFail);
559       sysLedCtrl(kLedPPP, kLedStateOff);        // USR9108
560       break;
561    case MNTR_STS_PPP_DOWN:
562       /* this means ADSL is UP, but not PPP */
563       //sysLedCtrl(kLedPPP, kLedStateFail);
564       sysLedCtrl(kLedPPP, kLedStateOff);        // USR9108
565       break;
566    case MNTR_STS_OK:
567       /* this means ADSL and PPP are up */
568       // sysLedCtrl(kLedPPP, kLedStateOn);      // USR9108 Not yet!
569       break;
570    }
571 }
572
573 void bcmGetDynamicDnsAddr(char *dns, int primary) {
574    char str[SYS_CMD_LEN];
575    FILE* fs = NULL;
576
577    fs = fopen("/var/fyi/sys/dns", "r");
578    if ( fs != NULL ) {
579       if ( fgets(str, SYS_CMD_LEN, fs) > 0 ) {
580          if (primary)
581             sscanf(str, "nameserver %s\n", dns);
582          else {
583             if ( fgets(str, SYS_CMD_LEN, fs) > 0 ) 
584             sscanf(str, "nameserver %s\n", dns);
585          } /* secondary */
586       }
587       fclose(fs);
588    }
589    else
590       // if cannot find primary dns info then
591       // assign default value which is router IP address
592       bcmGetIfDestAddr("br0", dns);
593 }
594
595 /***************************************************************************
596 // Function Name: bcmGetDns().
597 // Description  : get DSN info.
598 // Parameters   : dns - buffer to retrieve primary dns.
599 // Returns      : none.
600 ****************************************************************************/
601 void bcmGetDns(char *dns) {
602    IFC_DNS_INFO dnsInfo;
603
604    dns[0] = '\0';
605    if ( ((BcmDb_getDnsInfo(&dnsInfo) == DB_GET_OK) && (dnsInfo.dynamic)) ||
606         (BcmDb_getDnsInfo(&dnsInfo) != DB_GET_OK) ) {
607       if (dnsInfo.dynamic) {
608          bcmGetDynamicDnsAddr(dns,BCM_PRIMARY_DNS);
609       }
610    } 
611    else {
612      /* static */
613       if ( dnsInfo.preferredDns.s_addr != INADDR_NONE )
614          strcpy(dns, inet_ntoa(dnsInfo.preferredDns));
615    }
616 }
617
618 /***************************************************************************
619 // Function Name: bcmGetDns2().
620 // Description  : get DSN info.
621 // Parameters   : dns - buffer to retrieve primary dns.
622 // Returns      : none.
623 ****************************************************************************/
624 void bcmGetDns2(char *dns) {
625    IFC_DNS_INFO dnsInfo;
626
627    dns[0] = '\0';
628    if ( ((BcmDb_getDnsInfo(&dnsInfo) == DB_GET_OK) && (dnsInfo.dynamic)) ||
629         (BcmDb_getDnsInfo(&dnsInfo) != DB_GET_OK) ) {
630       if (dnsInfo.dynamic) {
631          bcmGetDynamicDnsAddr(dns, BCM_SECONDARY_DNS);
632       }
633    } 
634    else {
635      /* static */
636       if ( dnsInfo.alternateDns.s_addr != INADDR_NONE )
637          strcpy(dns, inet_ntoa(dnsInfo.alternateDns));
638    }
639 }
640
641 void bcmGetDnsSettings(int *mode, char *primary, char *secondary)
642 {
643    IFC_DNS_INFO dnsInfo;
644    
645    *mode = 1;
646    if (BcmDb_getDnsInfo(&dnsInfo) == DB_GET_OK) {
647       *mode = dnsInfo.dynamic;
648    }
649    bcmGetDns(primary);
650    bcmGetDns2(secondary);
651 }
652
653 /***************************************************************************
654 // Function Name: bcmRestartDnsProbe().
655 // Description  : start DNS probe.
656 // Parameters   : none.
657 // Returns      : none.
658 ****************************************************************************/
659 void bcmRestartDnsProbe(void) {
660    char cmd[CLI_MAX_BUF_SZ];
661
662    // kill the old dnsprobe if it is existed
663    int pid = bcmGetPid("/bin/dnsprobe");
664    if ( pid > 0 ) {
665       sprintf(cmd, "kill -9 %d", pid);
666       bcmSystem(cmd);
667    }
668
669    // start the new dnsprobe
670    bcmSystem("/bin/dnsprobe &");
671 }
672
673 /***************************************************************************
674 // Function Name: bcmConfigDns().
675 // Description  : add or remove DNS info to PSI.
676 // Parameters   : primary and secondary DNS.
677 // Returns      : none.
678 ****************************************************************************/
679 void bcmConfigDns(char *dns1, char *dns2, int dynamic) {
680    char cmd[CLI_MAX_BUF_SZ], addr[CLI_MAX_BUF_SZ], buf[CLI_MAX_BUF_SZ];
681    IFC_DNS_INFO dnsInfo;
682
683    // get local ip address
684    bcmGetIfDestAddr("br0", addr);
685
686    // if user changes from static to auto assgined dns
687    if (dynamic) {
688       if ( BcmDb_getDnsInfo(&dnsInfo) == DB_GET_OK &&
689            bcmIsModuleInserted("iptable_nat") == TRUE ) {
690          strcpy(buf, inet_ntoa(dnsInfo.preferredDns));
691          // del the old rule
692          sprintf(cmd, "iptables -t nat -D PREROUTING -i br0 -d %s -p udp --dport 53 -j DNAT --to %s 2>/dev/null", addr, buf);
693          bcmSystemMute(cmd);
694          // remove old resolve configuration file
695          FILE * fs = fopen("/var/fyi/sys/dns", "r");
696          if ( fs ) {
697              fclose( fs );
698              bcmSystemMute("rm /var/fyi/sys/dns");
699          }
700       }
701    } else {
702       // create the new resolv.conf with new dsn info
703       bcmCreateResolvCfg(dns1, dns2);
704       // get old dns1 info
705       bcmGetDns(buf);
706       if ( buf[0] != '\0' ) {
707          if (strcmp(buf, dns1) != 0) {
708             if ( bcmIsModuleInserted("iptable_nat") == TRUE ) {
709                // del the old rule
710                sprintf(cmd, "iptables -t nat -D PREROUTING -i br0 -d %s -p udp --dport 53 -j DNAT --to %s 2>/dev/null", addr, buf);
711                bcmSystemMute(cmd);
712                // add new DNS Forwarding rule
713                sprintf(cmd, "iptables -t nat -A PREROUTING -i br0 -d %s -p udp --dport 53 -j DNAT --to %s", addr, dns1);
714                bcmSystemMute(cmd);
715                bcmRestartDnsProbe();
716             }
717          }
718       } else {
719          printf("No Existing DNS information from DSL router\n");
720          sprintf(cmd, "iptables -t nat -A PREROUTING -i br0 -d %s -p udp --dport 53 -j DNAT --to %s", addr, dns1);
721          bcmSystemMute(cmd);
722       }
723       // get old dns2 info
724       bcmGetDns2(buf);
725       // if old dns2 differs with new one, restart dnsprobe
726       if (strcmp(buf, dns2) != 0) {
727          if ( bcmIsModuleInserted("iptable_nat") == TRUE )
728             bcmRestartDnsProbe();
729       }
730       dnsInfo.preferredDns.s_addr = inet_addr(dns1);
731       dnsInfo.alternateDns.s_addr = inet_addr(dns2);
732    } /* dynamic to static */
733    dnsInfo.dynamic = dynamic;
734    BcmDb_setDnsInfo(&dnsInfo);
735    BcmPsi_flush();
736 }
737
738 /***************************************************************************
739 // Function Name: bcmRemoveDefaultGatewayByWanIf().
740 // Description  : remove the defaultGateway configuration if it uses the
741 //                removed wan interface.
742 // Parameters   : wanIf - the removed wan interface
743 // Returns      : none
744 ****************************************************************************/
745 void bcmRemoveDefaultGatewayByWanIf(char *wanIf) {
746    char gtwy[IFC_TINY_LEN], ifName[IFC_TINY_LEN];
747    
748    bcmGetDefaultGateway(gtwy, ifName);
749    
750    if ( strcmp(ifName, wanIf) == 0 ) {
751       // remove static default gateway in PSI
752       BcmDb_removeDefaultGatewayInfo();
753       BcmPsi_flush();
754    }
755 }
756
757 /***************************************************************************
758 // Function Name: bcmGetDefaultGateway().
759 // Description  : get default gateway info.
760 // Parameters   : gtwy - buffer to retrieve default gateway.
761 // Returns      : none.
762 ****************************************************************************/
763 void bcmGetDefaultGateway(char *gtwy, char *wanIf) {
764    char str[SYS_CMD_LEN];
765    FILE* fs = NULL;
766    IFC_DEF_GW_INFO defgw;
767    char addr[512], ip[512];
768
769    gtwy[0] = wanIf[0] = '\0';
770    if ( BcmDb_getDefaultGatewayInfo(&defgw) == DB_GET_OK ){
771       if (strcmp(inet_ntoa(defgw.defaultGateway), "0.0.0.0") != 0)
772          strcpy(gtwy, inet_ntoa(defgw.defaultGateway));
773       if (defgw.ifName != NULL)
774          strcpy(wanIf, defgw.ifName);      
775    }
776    else {
777       fs = fopen("/var/fyi/sys/gateway", "r");
778       if ( fs != NULL ) {
779          if ( fgets(str, SYS_CMD_LEN, fs) > 0 ) {
780             sscanf(str, "%s\n", addr);
781             if ( BcmDb_validateIpAddress(addr) == DB_OBJ_VALID_OK ) 
782                strcpy(gtwy, addr);
783             else { // use ifName
784                if (bcmGetIfDestAddr(addr, ip) == BCM_DIAG_PASS)
785                   strcpy(gtwy, ip); 
786             }
787          }
788          fclose(fs);
789       }
790    }
791 }
792
793 /***************************************************************************
794 // Function Name: bcmIsDefaultGatewayExisted().
795 // Description  : Check if the defaultGateway is existed in the route table.
796 // Parameters   : gw and wanIf
797 // Returns      : 1 - Exist. 0 - not Exist
798 ****************************************************************************/
799 int bcmIsDefaultGatewayExisted(char *gw, char *wanIf) {
800    char col[11][32];
801    char line[512];
802    struct in_addr addr;
803    int count = 0;
804    int flag = 0;
805
806    FILE* fsRoute = fopen("/proc/net/route", "r");
807    if ( fsRoute != NULL ) {
808       while ( fgets(line, sizeof(line), fsRoute) ) {
809          // read pass header line
810         if ( count++ < 1 ) continue;
811         sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
812                col[0], col[1], col[2], col[3], col[4], col[5],
813                col[6], col[7], col[8], col[9], col[10]);
814         flag = strtol(col[3], (char**)NULL, 16);
815         if ((flag & (RTF_UP | RTF_GATEWAY)) == (RTF_UP | RTF_GATEWAY)) {
816            if ( wanIf[0] == '\0' || strcmp(wanIf, col[0]) == 0) {
817              addr.s_addr = strtoul(col[2], (char**)NULL, 16);
818              if (strcmp(gw, inet_ntoa(addr)) == 0) {
819                 fclose(fsRoute);
820                 return TRUE;
821              }
822            }
823         }
824       }
825       fclose(fsRoute);
826    }
827
828    return FALSE;
829 }
830
831 /***************************************************************************
832 // Function Name: bcmSetAutoDefaultGateway().
833 // Description  : remove static default gateway in PSI,
834 //                get the default gateway from var/fyi/sys/gateway, and add
835 //                it to the route table.
836 // Parameters   : errMsg -- error message when add default gateway if any.
837 // Returns      : 1 - Exist. 0 - not Exist
838 ****************************************************************************/
839 void bcmSetAutoDefaultGateway(char *errMsg) {
840    char sysDefaultGateway[IFC_TINY_LEN];
841    char cmd[IFC_LARGE_LEN];
842    FILE *fs = NULL;
843    IFC_DEF_GW_INFO defgw;
844
845    // remove static default gateway
846    if ( BcmDb_getDefaultGatewayInfo(&defgw) == DB_GET_OK ) {
847       // remove static default gateway in PSI
848       BcmDb_removeDefaultGatewayInfo();
849       BcmPsi_flush();
850       // create command to delete default gateway in route table
851       sprintf(cmd, "route del default");
852       if (strcmp(inet_ntoa(defgw.defaultGateway), "0.0.0.0") != 0) {
853          strcat(cmd, " gw ");
854          strcat(cmd, inet_ntoa(defgw.defaultGateway));
855       }
856       if (strcmp(defgw.ifName, "") != 0) {
857          strcat(cmd, " dev ");
858          strcat(cmd, defgw.ifName);
859       }
860       strcat(cmd, " 2> /var/gwerr");
861       bcmSystem(cmd);
862       fs = fopen("/var/gwerr", "r");
863       // read gwerr, if there is err then
864       // need to set error message
865       if ( fs != NULL ) {
866          if ( fgets(cmd, IFC_LARGE_LEN, fs) > 0 ) {
867             // remove the last newline character
868             cmd[strlen(cmd) - 1] = '\0';
869             strcpy(errMsg, cmd);
870             bcmSystemMute("cat /var/gwerr");
871          } else
872             errMsg[0] = '\0';
873          fclose(fs);
874          bcmSystemMute("rm /var/gwerr");
875       }
876    }
877
878    //get the default gateway from var/fyi/sys/gateway
879    bcmGetDefaultGateway(sysDefaultGateway, cmd);
880    if ( sysDefaultGateway[0] != '\0' &&
881         bcmIsDefaultGatewayExisted(sysDefaultGateway, "") == FALSE ) {
882       sprintf(cmd, "route add default gw %s 2> /var/gwerr", sysDefaultGateway);
883       bcmSystem(cmd);
884       fs = fopen("/var/gwerr", "r");
885       // read gwerr, if there is err then
886       // need to set the error message
887       if ( fs != NULL ) {
888          if ( fgets(cmd, IFC_LARGE_LEN, fs) > 0 ) {
889             // remove the last newline character
890             cmd[strlen(cmd) - 1] = '\0';
891             strcpy(errMsg, cmd);
892             bcmSystemMute("cat /var/gwerr");
893          } else
894             errMsg[0] = '\0';
895          fclose(fs);
896          bcmSystemMute("rm /var/gwerr");
897       }
898    }
899 }
900
901 /***************************************************************************
902 // Function Name: bcmSetStaticDefaultGateway().
903 // Description  : remove the old, and add the new default gateway.
904 // Parameters   : gw, wanIf, and error message
905 // Returns      : none
906 ****************************************************************************/
907 void bcmSetStaticDefaultGateway(char *gw, char *wanIf, char *errMsg) {
908    int runCmd = FALSE;
909    char cmd[IFC_LARGE_LEN];
910    FILE* fs = NULL;
911    IFC_DEF_GW_INFO defgw;
912
913    // intialize gw if it is empty
914    if ( gw[0] == '\0' )
915       strcpy(gw, "0.0.0.0");
916
917    // if errMsg is NULL then only save configuration
918    // but not execute command to avoid error when
919    // route destination address cannot be reached since
920    // interface device does not created yet
921    if ( errMsg != NULL &&
922         BcmDb_getDefaultGatewayInfo(&defgw) == DB_GET_OK ) {
923       // check if not the same
924       if ( strcmp(defgw.ifName, wanIf) != 0 ||
925            strcmp(inet_ntoa(defgw.defaultGateway), gw) != 0) {
926          // del the previous default route saved in route table
927          sprintf(cmd, "route del default");
928          if ( strcmp(inet_ntoa(defgw.defaultGateway), "0.0.0.0") != 0 ) {
929             strcat(cmd, " gw ");
930             strcat(cmd, inet_ntoa(defgw.defaultGateway));
931          }
932          if ( strcmp(defgw.ifName, "") != 0 ) {
933             strcat(cmd, " dev ");
934             strcat(cmd, defgw.ifName);
935          }
936          strcat(cmd, " 2> /var/gwerr");
937          bcmSystemMute(cmd);
938          fs = fopen("/var/gwerr", "r");
939          // read gwerr, if there is err then
940          // need to set error message
941          if ( fgets(cmd, IFC_LARGE_LEN, fs) > 0 ) {
942             // remove the last newline character
943             cmd[strlen(cmd) - 1] = '\0';
944             strcpy(errMsg, cmd);
945             bcmSystemMute("cat /var/gwerr");
946          } else
947             errMsg[0] = '\0';
948          fclose(fs);
949          bcmSystemMute("rm /var/gwerr");
950       }
951       else
952          return; // same and do nothing
953    }
954
955    // if errMsg is NULL then only save configuration
956    // but not execute command to avoid error when
957    // route destination address cannot be reached since
958    // interface device does not created yet
959    // if this gateway and wanIf is already in the route table,
960    // do not issue route add default command.
961    if ( errMsg != NULL &&
962         bcmIsDefaultGatewayExisted(gw, wanIf) == FALSE ) {
963       strcpy(cmd, "route add default");
964       if ( strcmp(gw, "0.0.0.0") != 0 &&
965            BcmDb_validateIpAddress(gw) == DB_OBJ_VALID_OK ) {
966          strcat(cmd, " gw ");
967          strcat(cmd, gw);
968          runCmd = TRUE;
969       }
970       if (wanIf[0] != '\0') {
971          strcat(cmd, " dev ");
972          strcat(cmd, wanIf);
973          runCmd = TRUE;
974       }
975       if ( runCmd == TRUE ) {
976          strcat(cmd, " 2> /var/gwerr");
977          bcmSystemMute(cmd);
978          fs = fopen("/var/gwerr", "r");
979          // read gwerr, if there is no err then
980          // need to configure default gateway in PSI
981          if ( fgets(cmd, IFC_LARGE_LEN, fs) <= 0 ) {
982             // save the new default gateway info to psi
983             errMsg[0] = '\0';
984          } else {
985             // remove the last newline character
986             cmd[strlen(cmd) - 1] = '\0';
987             strcpy(errMsg, cmd);
988             bcmSystemMute("cat /var/gwerr");
989          }
990          // close gwerr file
991          fclose(fs);
992          bcmSystemMute("rm /var/gwerr");
993       }
994    }
995
996    // save to PSI even when error occurs
997    defgw.enblGwAutoAssign = 0;
998    strcpy(defgw.ifName, wanIf);
999    defgw.defaultGateway.s_addr = inet_addr(gw);
1000    BcmDb_setDefaultGatewayInfo(&defgw);
1001    BcmPsi_flush();
1002 }
1003
1004 //**************************************************************************
1005 // Function Name: getPppoeServiceName
1006 // Description  : get pppoe service name of the specific wan interfaces.
1007 // Parameters   : service -- pppoe service name. (output)
1008 //                ifName -- interface name. (input)
1009 // Returns      : none.
1010 //**************************************************************************
1011 void getPppoeServiceName(char *service, char *ifName) {
1012    char fileName[IFC_LARGE_LEN];
1013    char str[SYS_CMD_LEN];
1014    FILE* fs = NULL;
1015
1016    if (ifName[0] != 0) {
1017       sprintf(fileName, "/proc/var/fyi/wan/%s/servicename", ifName);
1018       fs = fopen(fileName, "r");
1019       if (fs != NULL) {
1020          if (fgets(str, SYS_CMD_LEN, fs) > 0)
1021             sscanf(str, "%s\n", service);
1022          fclose(fs);
1023       }
1024    }
1025 }
1026
1027
1028
1029 /***************************************************************************
1030 // Function Name: setWanLinkStatus().
1031 // Description  : get PPP status.
1032 // Parameters   : up - wan link status
1033 // Returns      : none
1034 //                -1 - ERROR
1035 ****************************************************************************/
1036 void setWanLinkStatus(int up) 
1037 {
1038    FILE * fd = NULL;
1039
1040    if ( up == 1 ) {
1041       if ( (fd = fopen("/var/run/wanup", "a+")) != NULL )
1042          fclose(fd);
1043    } else
1044       unlink("/var/run/wanup");
1045 }
1046
1047 /***************************************************************************
1048 // Function Name: disconnectPPP().
1049 // Description  : if PPPD is alive, disconnet it.
1050 // Returns      : none
1051 ****************************************************************************/
1052 void disconnectPPP(void)
1053 {
1054    int pid = 0;
1055
1056    // If PPP is connected disconnect it first
1057    if ( (pid = bcmGetPid("pppd")) > 0 ) {
1058       setWanLinkStatus(0);
1059       // give PPP some time to disconnect. PPP client checks WAN links status
1060       // every 3 seconds 
1061       sleep(6);
1062    }
1063 }
1064
1065
1066 /***************************************************************************
1067 // Function Name: bcmSocketIfPid().
1068 // Description  : return the socket if pid (== 0 is lan (br0), !=0 is wan)
1069 // Parameters   : none.
1070 // Returns      : pid
1071 ****************************************************************************/
1072 int bcmSocketIfPid(void)
1073 {
1074    char ifName[IFC_SMALL_LEN];
1075    int pid = 0;
1076    char cmd[SYS_CMD_LEN];
1077    FILE *fs = NULL;
1078
1079    // Check this first
1080    strncpy(ifName, getIfName(), IFC_SMALL_LEN - 1);
1081    if (ifName[0] == '\0')
1082       return pid;
1083
1084    sprintf(cmd, "/proc/var/fyi/wan/%s/pid", ifName);
1085    if ((fs = fopen(cmd, "r")) != NULL)
1086    {
1087       fgets(cmd, SYS_CMD_LEN, fs);
1088       pid = atoi(cmd);
1089       fclose(fs);
1090    }
1091
1092    return pid;
1093 }
1094
1095
1096
1097 /***************************************************************************
1098 // Function Name: bcmKillAllApps().
1099 // Description  : kill all available applications.
1100 // Parameters   : none.
1101 // Returns      : none.
1102 ****************************************************************************/
1103 void bcmKillAllApps(void) {
1104    // NOTE: Add the app name before NULL. Order is important
1105    char *apps[]=
1106    {
1107 #ifdef SUPPORT_TR69C
1108       "tr69c",
1109 #endif
1110       "bftpd",
1111       "telnetd",   
1112       "sshd",
1113       "snmp",
1114       "upnp",
1115       "sntp",
1116       "ddnsd",
1117       "reaim",
1118       "klogd",
1119       "syslogd",
1120       "tftpd",
1121       "ripd",
1122       "zebra ",
1123       "pppd",
1124       "dnsprobe",
1125       "dhcpc",
1126       "igmp",      
1127       "cfm",
1128       "ippd",
1129       NULL,
1130    };
1131    char cmd[SYS_CMD_LEN], app[SYS_CMD_LEN], buf[SYS_CMD_LEN];
1132    char pidStr[SYS_CMD_LEN];
1133    int pid = 0;
1134    int i = 0;
1135    FILE *fs;
1136    int socketPid = 0;
1137    int curPid = getpid();
1138    int httpdPid =0;
1139    int inWeb = FALSE;
1140
1141    fs = fopen("/var/run/httpd_pid", "r");
1142    if (fs != NULL)
1143    {
1144       fgets(cmd, SYS_CMD_LEN, fs);
1145       httpdPid = atoi(cmd);
1146       fclose(fs);
1147    }
1148    else
1149    {
1150       printf("Error: httpd pid not found ?\n");
1151       return;
1152    }
1153
1154    bcmSystemMute("ps > /var/pslist");
1155    fs = fopen("/var/pslist", "r");
1156    if (fs == NULL)
1157       return;
1158    bcmSystem("cat /var/pslist");
1159
1160    socketPid = bcmSocketIfPid();
1161
1162    if (socketPid != 0) 
1163    {
1164       // add the default route with the ifc the socket is sitting on
1165       if (strstr(getIfName(), "nas") == NULL &&       // only do it if it is not MER and not ipoa (eth?)
1166          strstr(getIfName(), "eth") == NULL)
1167       {
1168          sprintf(cmd, "route add default dev %s", getIfName());
1169          bcmSystem(cmd);
1170       }
1171       rewind(fs);
1172    }
1173       
1174    if (curPid == httpdPid)
1175       inWeb = TRUE;
1176
1177    bcmSystem("sysinfo");
1178
1179    //printf("curPid=%d, socketPid=%d, htpdPid=%d, inWeb=%d\n", curPid, socketPid, httpdPid, inWeb);
1180    // get app and read thru pslist according to the order of apps
1181    i = 0;
1182    do 
1183    {
1184       strcpy(app, apps[i]);
1185       while (fgets(buf, SYS_CMD_LEN, fs) > 0)  
1186       {
1187          if (strstr(buf, app) != NULL) // found command line with match app name
1188          {  
1189             // find pid string
1190             sscanf(buf, "%s\n", pidStr);
1191             // if not in httpd, must be in telnetd or sshd, just skip the line.
1192             if (!inWeb && ((strstr(buf, "telnetd")) || (strstr(buf, "sshd"))))
1193                break;
1194             pid = atoi(pidStr);
1195             if (pid != curPid && pid != socketPid)
1196             {
1197                printf("kill %s process...\n", app);
1198                sprintf(cmd, "kill -%d %d", 9, pid);
1199                bcmSystem(cmd);
1200             }
1201          }
1202       } 
1203       rewind(fs);    // start pslist over again
1204    } while (apps[++i] != NULL);
1205
1206    fclose(fs);
1207    bcmSystemMute("rm /var/pslist");
1208    bcmRemoveModules(socketPid);
1209 }
1210
1211 // function to support encryption password for login
1212 static int i64c(int i) {
1213     if (i <= 0)
1214         return ('.');
1215     if (i == 1)
1216         return ('/');
1217     if (i >= 2 && i < 12)
1218         return ('0' - 2 + i);
1219     if (i >= 12 && i < 38)
1220         return ('A' - 12 + i);
1221     if (i >= 38 && i < 63)
1222         return ('a' - 38 + i);
1223     return ('z');
1224 }
1225
1226 // function to support encryption password for login
1227 static char *crypt_make_salt(void) {
1228     time_t now;
1229     static unsigned long x;
1230     static char result[3];
1231
1232     time(&now);
1233     x += now + getpid() + clock();
1234     result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
1235     result[1] = i64c(((x >> 12) ^ x) & 077);
1236     result[2] = '\0';
1237     return result;
1238 }
1239
1240 // function to support encryption password for login
1241 static char *pw_encrypt(const char *clear, const char *salt) {
1242     static char cipher[128];
1243     char *cp;
1244
1245 #ifdef CONFIG_FEATURE_SHA1_PASSWORDS
1246     if (strncmp(salt, "$2$", 3) == 0) {
1247         return sha1_crypt(clear);
1248     }
1249 #endif
1250     cp = (char *) crypt(clear, salt);
1251     /* if crypt (a nonstandard crypt) returns a string too large,
1252        truncate it so we don't overrun buffers and hope there is
1253        enough security in what's left */
1254     if (strlen(cp) > sizeof(cipher)-1) {
1255         cp[sizeof(cipher)-1] = 0;
1256     }
1257     strcpy(cipher, cp);
1258     return cipher;
1259 }
1260
1261 /***************************************************************************
1262 // Function Name: bcmCreateLoginCfg().
1263 // Description  : create password file for login using 'admin' or 'support'.
1264 // Parameters   : cp_admin - clear password of 'admin'.
1265 //                cp_support - clear password of 'support'.
1266 //                cp_user - clear password of 'user'.
1267 // Returns      : status 0 - OK, -1 - ERROR.
1268 ****************************************************************************/
1269 int bcmCreateLoginCfg(char *cp_admin, char *cp_support, char *cp_user) {
1270    struct passwd pw;
1271    FILE *fsPwd = NULL, *fsGrp = NULL;
1272
1273    fsPwd = fopen("/etc/passwd", "w");
1274
1275    if ( fsPwd != NULL ) {
1276       // In future, we may change uid of 'admin' and 'support'
1277       // uclibc may have a bug on putpwent in terms of uid,gid setup
1278       pw.pw_name = "admin";
1279       pw.pw_passwd = pw_encrypt(cp_admin, crypt_make_salt());
1280       pw.pw_uid = 0;
1281       pw.pw_gid = 0;
1282       pw.pw_gecos = "Administrator";
1283       pw.pw_dir = "/";
1284       pw.pw_shell = "/bin/sh";
1285       putpwent(&pw, fsPwd);
1286
1287       pw.pw_name = "support";
1288       pw.pw_passwd = pw_encrypt(cp_support, crypt_make_salt());
1289       pw.pw_uid = 0;
1290       pw.pw_gid = 0;
1291       pw.pw_gecos = "Technical Support";
1292       pw.pw_dir = "/";
1293       pw.pw_shell = "/bin/sh";
1294       putpwent(&pw, fsPwd);
1295
1296       pw.pw_name = "user";
1297       pw.pw_passwd = pw_encrypt(cp_user, crypt_make_salt());
1298       pw.pw_uid = 0;
1299       pw.pw_gid = 0;
1300       pw.pw_gecos = "Normal User";
1301       pw.pw_dir = "/";
1302       pw.pw_shell = "/bin/sh";
1303       putpwent(&pw, fsPwd);
1304
1305       pw.pw_name = "nobody";
1306       pw.pw_passwd = pw_encrypt(cp_admin, crypt_make_salt());
1307       pw.pw_uid = 0;
1308       pw.pw_gid = 0;
1309       pw.pw_gecos = "nobody for ftp";
1310       pw.pw_dir = "/";
1311       pw.pw_shell = "/bin/sh";
1312       putpwent(&pw, fsPwd);
1313       fclose(fsPwd);
1314
1315       fsGrp = fopen("/etc/group", "w");
1316       if ( fsGrp != NULL ) {
1317          fprintf(fsGrp, "root::0:root,admin,support,user\n");
1318          fclose(fsGrp);
1319          return FILE_OPEN_OK;
1320       }
1321    }
1322
1323    return FILE_OPEN_ERR;
1324 }
1325
1326 /***************************************************************************
1327 // Function Name: bcmSetIpExtension().
1328 // Description  : store PPP IP extension info to file.
1329 // Parameters   : ipExt - 1:enable, 0:disable.
1330 // Returns      : status 0 - OK, -1 - ERROR.
1331 ****************************************************************************/
1332 int bcmSetIpExtension(int ipExt) {
1333    FILE* fs = fopen("/var/ipextension", "w");
1334
1335    if ( fs != NULL ) {
1336       fprintf(fs, "%d\n", ipExt);
1337       fclose(fs);
1338       return FILE_OPEN_OK;
1339    }
1340
1341    return FILE_OPEN_ERR;
1342 }
1343
1344 /***************************************************************************
1345 // Function Name: bcmGetIpExtension().
1346 // Description  : retrieve PPP IP extension info from file.
1347 // Parameters   : str -- buffer.
1348 //                len -- size of buffer.
1349 // Returns      : status 0 - OK, -1 - ERROR.
1350 ****************************************************************************/
1351 int bcmGetIpExtension(char *str, int len) {
1352    FILE* fs = fopen("/var/ipextension", "r");
1353
1354    if ( fs != NULL ) {
1355       fgets(str, len, fs);
1356       fclose(fs);
1357       return FILE_OPEN_OK;
1358    }
1359
1360    return FILE_OPEN_ERR;
1361 }
1362
1363 /***************************************************************************
1364 // Function Name: bcmGetIfcIndexByName().
1365 // Description  : get interface index by its name.
1366 // Parameters   : ifcIdx -- interface index.
1367 //                ifcName -- interface name.
1368 // Returns      : interface index
1369 ****************************************************************************/
1370 int bcmGetIfcIndexByName(char *ifcName) {
1371    struct ifreq ifr;
1372    int s = 0;
1373
1374    if ( ifcName == NULL ) return -1;
1375
1376    if ( (s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) return -1;
1377
1378    strcpy(ifr.ifr_name, ifcName);
1379    if ( ioctl(s, SIOCGIFINDEX, &ifr) < 0 ) {
1380       close(s);
1381       return 0;
1382    }
1383
1384    close(s);
1385
1386    return ifr.ifr_ifindex;
1387 }
1388
1389 /***************************************************************************
1390 // Function Name: bcmIsValidIfcName.
1391 // Description  : validate the interface name.
1392 // Parameters   : ifcName -- interface name that need to validate.
1393 // Returns      : TRUE or FALSE
1394 ****************************************************************************/
1395 int bcmIsValidIfcName(char *ifcName) {
1396    int ret = FALSE;
1397
1398    if (bcmGetIfcIndexByName(ifcName))
1399       ret = TRUE;
1400    return ret;
1401 }
1402
1403 /***************************************************************************
1404 // Function Name: bcmGetIfcNameById.
1405 // Description  : get interface name by its id (defined in ifcdefs.h).
1406 // Parameters   : ifcId -- interface Id.
1407 //                ifcName -- interface name.
1408 // Returns      : interface name or NULL
1409 ****************************************************************************/
1410 char *bcmGetIfcNameById(int ifcId, char *ifcName) {
1411    if ( ifcName == NULL ) return NULL;
1412
1413    ifcName[0] = '\0';
1414
1415    if ( ifcId >= IFC_ENET_ID && ifcId < IFC_USB_ID )
1416       sprintf(ifcName, "eth%d", ifcId - IFC_ENET_ID);
1417    else if ( ifcId >= IFC_USB_ID && ifcId < IFC_HPNA_ID )
1418 //      strcpy(ifcName, "eth1");
1419       sprintf(ifcName, "usb%d", ifcId - IFC_USB_ID);
1420    else if ( ifcId >= IFC_HPNA_ID && ifcId < IFC_WIRELESS_ID )
1421       sprintf(ifcName, "il%d", ifcId - IFC_HPNA_ID);
1422    else if ( ifcId >= IFC_WIRELESS_ID && ifcId < IFC_WIRELESS_ID + IFC_LAN_MAX ) {
1423       int num = ifcId - IFC_WIRELESS_ID;
1424       if (num == 0) { // multiple ssid support
1425          sprintf(ifcName, "wl0");
1426       }
1427       else {
1428          sprintf(ifcName, "wl0.%d", num); 
1429       }
1430    }
1431
1432    return ifcName;
1433 }
1434
1435 /***************************************************************************
1436 // Function Name: bcmGetIfcNameByIpAddr.
1437 // Description  : get interface name by its IP address.
1438 // Parameters   : ifcIpAddr -- interface IP address.
1439 //                ifcName -- interface name.
1440 // Returns      : interface name or NULL
1441 ****************************************************************************/
1442 char *bcmGetIfcNameByIpAddr(unsigned long ipAddr, char *ifcName) {
1443     char str[SYS_CMD_LEN] = "ifconfig -a > /var/ifcs";
1444     FILE *fs;
1445     char *ret = NULL;
1446
1447     bcmSystemMute(str);
1448     if( (fs = fopen("/var/ifcs", "r")) != NULL ) {
1449         while( fgets(str, sizeof(str), fs) != NULL ) {
1450             if( str[0] >= 'A' && str[0] <= 'z' ) {
1451                 int i;
1452                 char *p;
1453                 char name[16];
1454
1455                 // Copy interface name (br0, eth0, pppoe_0_35, etc.) to local
1456                 // variable.
1457                 for(i = 0, p = str; i<sizeof(name)-1 && *p && *p!=' '; i++, p++)
1458                     name[i] = *p;
1459                 name[i] = '\0';
1460
1461                 // The next line will have the IP address if one is assigned
1462                 // to the current interface.
1463                 if( fgets(str, sizeof(str), fs) != NULL ) {
1464                     if( (p = strstr(str, "inet addr:")) != NULL ) {
1465                         unsigned long addr;
1466
1467                         p += strlen("inet addr:");
1468                         addr = inet_addr(p);
1469
1470                         // if the IP address of the current interfaces matches
1471                         // the supplied IP address, then the interface is found.
1472                         if( addr == ipAddr ) {
1473                             strcpy( ifcName, name );
1474                             ret = ifcName;
1475                             break;
1476                         }
1477                     }
1478                 }
1479             }
1480         }
1481         fclose(fs);
1482         unlink("/var/ifcs");
1483     }
1484
1485     return( ret );
1486 }
1487
1488 /***************************************************************************
1489 // Function Name: bcmSetConnTrackMax.
1490 // Description  : tune the connection track table size.
1491 // Parameters   : none.
1492 // Returns      : none.
1493 ****************************************************************************/
1494 void bcmSetConnTrackMax(void) {
1495    int conntrack_max = CONNTRACK_MUX;
1496    char cmd[SYS_CMD_LEN];
1497    FILE* fs = fopen("/proc/sys/net/ipv4/ip_conntrack_max", "r");
1498
1499    // init ip_conntrack_max
1500    if ( fs == NULL ) // ip_conntrack module is not loaded.
1501       return;    
1502    else {
1503       fgets(cmd, SYS_CMD_LEN, fs);
1504       conntrack_max = atoi(cmd);
1505       fclose(fs);
1506    }
1507    // Code in ip_conntrack_init function of ip_conntrack_core.c in kernel
1508    // has been modified to initialize ip_conntrack_max to be always 0
1509    // when ip_conntrack module is inserted (before NAT or Firewall is enabled).
1510    // This function setting real conntrack_max will be called after NAT or Firewall is enabled.
1511    if ( conntrack_max == 0 )
1512         conntrack_max = CONNTRACK_MUX;
1513    else {   
1514       if ( conntrack_max < CONNTRACK_MUX ) {
1515          conntrack_max *= 2;
1516          if ( conntrack_max > CONNTRACK_MUX )
1517             conntrack_max = CONNTRACK_MUX;
1518       }
1519    }
1520    sprintf(cmd, "echo \"%d\" > /proc/sys/net/ipv4/ip_conntrack_max", conntrack_max);
1521    bcmSystem(cmd);
1522 }
1523
1524 /***************************************************************************
1525 // Function Name: bcmResetConnTrackTable.
1526 // Description  : reset the connection track table.
1527 // Parameters   : none.
1528 // Returns      : none.
1529 ****************************************************************************/
1530 void bcmResetConnTrackTable(void) {
1531    if ( bcmIsModuleInserted("ip_conntrack") == TRUE )
1532       bcmSystem("echo > /proc/net/ip_conntrack");
1533 }
1534
1535 /***************************************************************************
1536 // Function Name: bcmHandleConnTrack.
1537 // Description  : handle the connection track table.
1538 // Parameters   : none.
1539 // Returns      : none.
1540 ****************************************************************************/
1541 void bcmHandleConnTrack(void) {
1542    bcmResetConnTrackTable();
1543    bcmSetConnTrackMax();
1544 }
1545
1546 /***************************************************************************
1547 // Function Name: bcmInsertModules.
1548 // Description  : insert all modules under the given path.
1549 // Parameters   : path -- the given path.
1550 // Returns      : none.
1551 ****************************************************************************/
1552 void bcmInsertModules(char *path) {
1553    struct dirent *entry;
1554    DIR *dir;
1555    char *cp = NULL;
1556
1557    if ( path == NULL ) return;
1558
1559    dir = opendir(path);
1560    if ( dir == NULL ) return;
1561
1562    while ( (entry = readdir(dir)) != NULL )
1563       if ( (cp = strstr(entry->d_name, ".ko")) != NULL ) {
1564          *cp = '\0';
1565          bcmInsertModule(entry->d_name);
1566       }
1567    closedir(dir);
1568 }
1569
1570 /***************************************************************************
1571 // Function Name: bcmInsertModule.
1572 // Description  : insert module with the given name.
1573 // Parameters   : modName -- the given module name.
1574 // Returns      : none.
1575 ****************************************************************************/
1576 void bcmInsertModule(char *modName) {
1577    char cmd[SYS_CMD_LEN], modulepath[SYS_CMD_LEN];
1578    struct utsname kernel;
1579
1580    if (uname(&kernel) == -1)
1581       return;
1582
1583    sprintf(modulepath, "/lib/modules/%s/kernel/net/ipv4/netfilter", kernel.release);
1584
1585    if ( bcmIsModuleInserted(modName) == FALSE ) {
1586       sprintf(cmd, "insmod %s/%s.ko", modulepath,modName);
1587       bcmSystemMute(cmd);
1588    }
1589 }
1590
1591 /***************************************************************************
1592 // Function Name: bcmRemoveIpTableRule().
1593 // Description  : remove IP table rules.
1594 // Parameters   : device -- interface name.
1595 //                table -- IP table name.
1596 //                chain -- IP table chain.
1597 // Returns      : 1 - Success. 0 - Fail
1598 ****************************************************************************/
1599 int bcmRemoveIpTableRule(char *device, char *table, char *chain) {
1600    char col[IP_TBL_COL_MAX][IFC_SMALL_LEN];
1601    char comment[IFC_LARGE_LEN], line[IFC_GIANT_LEN];
1602    int ret = FALSE, count = 0;
1603    FILE* fs = NULL;
1604
1605    if ((access("/bin/iptables",F_OK)) != 0)
1606       return FALSE;
1607
1608    // execute iptables command to create iptable file
1609    sprintf(line, "iptables -t %s -L %s -v --line-numbers > /var/iptable",
1610            table, chain);
1611    bcmSystemMute(line);
1612
1613    fs = fopen("/var/iptable", "r");
1614    if ( fs != NULL ) {
1615       while ( fgets(line, sizeof(line), fs) ) {
1616          // read pass 2 header lines
1617          if ( count++ < 2 ) continue;
1618          sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
1619                 col[IP_TBL_COL_NUM], col[IP_TBL_COL_PKTS], col[IP_TBL_COL_BYTES],
1620                 col[IP_TBL_COL_TARGET], col[IP_TBL_COL_PROT], col[IP_TBL_COL_OPT],
1621                 col[IP_TBL_COL_IN], col[IP_TBL_COL_OUT], col[IP_TBL_COL_SRC],
1622                 col[IP_TBL_COL_DST], comment);
1623          // if chain rule for the given device is found
1624          if ( strcmp(col[IP_TBL_COL_IN], device) == 0 ||
1625               strcmp(col[IP_TBL_COL_OUT], device) == 0 ) {
1626             sprintf(line, "iptables -t %s -D %s %s 2>/dev/null",
1627                     table, chain, col[IP_TBL_COL_NUM]);
1628             bcmSystemMute(line);
1629             ret = TRUE;
1630             break;
1631          }
1632       }
1633       fclose(fs);
1634    }
1635
1636    // codes to remove iptable file is moved to bcmRemoveAllIpTableRules() function
1637
1638    return ret;
1639 }
1640
1641 /***************************************************************************
1642 // Function Name: bcmRemoveAllIpTableRules().
1643 // Description  : remove all IP table rules attach with the given device.
1644 // Parameters   : device -- interface name.
1645 // Returns      : none
1646 ****************************************************************************/
1647 void bcmRemoveAllIpTableRules(char *device) {
1648    FILE* fs = NULL;
1649
1650    if ( bcmIsModuleInserted("iptable_filter") == TRUE ) {
1651       while ( bcmRemoveIpTableRule(device, "filter", "INPUT") == TRUE )
1652          ;
1653
1654       while ( bcmRemoveIpTableRule(device, "filter", "FORWARD") == TRUE )
1655          ;
1656
1657       while ( bcmRemoveIpTableRule(device, "filter", "OUTPUT") == TRUE )
1658          ;
1659    }
1660
1661    if ( bcmIsModuleInserted("iptable_nat") == TRUE ) {
1662       while ( bcmRemoveIpTableRule(device, "nat", "PREROUTING") == TRUE )
1663          ;
1664 /* We should keep the masquerading rules
1665       while ( bcmRemoveIpTableRule(device, "nat", "POSTROUTING") == TRUE )
1666          ;
1667 */
1668
1669       while ( bcmRemoveIpTableRule(device, "nat", "OUTPUT") == TRUE )
1670          ;
1671    }
1672
1673    // remove iptable file
1674    fs = fopen("/var/iptable", "r");
1675    if ( fs != NULL ) {
1676       fclose(fs);
1677       unlink("/var/iptable");
1678    }
1679 }
1680
1681 /***************************************************************************
1682 // Function Name: bcmRemoveRipIpTableRule().
1683 // Description  : remove RIP IP table rules.
1684 // Parameters   : none.
1685 // Returns      : 1 - Success. 0 - Fail
1686 ****************************************************************************/
1687 int bcmRemoveRipIpTableRule(void) {
1688    char col[IP_TBL_COL_MAX][IFC_SMALL_LEN];
1689    char comment[IFC_LARGE_LEN], line[IFC_GIANT_LEN];
1690    int ret = FALSE, count = 0;
1691    FILE* fs = NULL;
1692
1693    if ((access("/bin/iptables",F_OK)) != 0)
1694       return FALSE;
1695
1696    // execute iptables command to create iptable file
1697    sprintf(line, "iptables -L INPUT -v --line-numbers > /var/iptable");
1698    bcmSystemMute(line);
1699
1700    fs = fopen("/var/iptable", "r");
1701    if ( fs != NULL ) {
1702       while ( fgets(line, sizeof(line), fs) ) {
1703          // read pass 2 header lines
1704          if ( count++ < 2 ) continue;
1705          sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
1706                 col[IP_TBL_COL_NUM], col[IP_TBL_COL_PKTS], col[IP_TBL_COL_BYTES],
1707                 col[IP_TBL_COL_TARGET], col[IP_TBL_COL_PROT], col[IP_TBL_COL_OPT],
1708                 col[IP_TBL_COL_IN], col[IP_TBL_COL_OUT], col[IP_TBL_COL_SRC],
1709                 col[IP_TBL_COL_DST], comment);
1710          // if protocol column is "udp" and last colum is "udp dpt:route"
1711          // then delete rule since it is RIP IP tables rule
1712          if ( strcmp(col[IP_TBL_COL_PROT], "udp") == 0 &&
1713               strcmp(comment, "udp dpt:route") == 0 ) {
1714             sprintf(line, "iptables -D INPUT %s 2>/dev/null", col[IP_TBL_COL_NUM]);
1715             bcmSystemMute(line);
1716             ret = TRUE;
1717             break;
1718          }
1719       }
1720       fclose(fs);
1721
1722       // remove iptable file
1723       unlink("/var/iptable");
1724    }
1725
1726    return ret;
1727 }
1728
1729 /***************************************************************************
1730 // Function Name: bcmRemoveUpnpIpTableRule().
1731 // Description  : remove UPnP IP table rules.
1732 // Parameters   : none.
1733 // Returns      : 1 - Success. 0 - Fail
1734 ****************************************************************************/
1735 int bcmRemoveUpnpIpTableRule(void) {
1736    char col[IP_TBL_COL_MAX][IFC_SMALL_LEN];
1737    char comment[IFC_LARGE_LEN], line[IFC_GIANT_LEN];
1738    int ret = FALSE, count = 0;
1739    FILE* fs = NULL;
1740
1741    if ((access("/bin/iptables",F_OK)) != 0)
1742       return FALSE;
1743
1744    // execute iptables command to create iptable file
1745    sprintf(line, "iptables -L OUTPUT -v --line-numbers > /var/iptable");
1746    bcmSystemMute(line);
1747
1748    fs = fopen("/var/iptable", "r");
1749    if ( fs != NULL ) {
1750       while ( fgets(line, sizeof(line), fs) ) {
1751          // read pass 2 header lines
1752          if ( count++ < 2 ) continue;
1753          sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
1754                 col[IP_TBL_COL_NUM], col[IP_TBL_COL_PKTS], col[IP_TBL_COL_BYTES],
1755                 col[IP_TBL_COL_TARGET], col[IP_TBL_COL_PROT], col[IP_TBL_COL_OPT],
1756                 col[IP_TBL_COL_IN], col[IP_TBL_COL_OUT], col[IP_TBL_COL_SRC],
1757                 col[IP_TBL_COL_DST], comment);
1758          // if destination column is "239.255.255.250" and target colum is "DROP"
1759          // then delete rule since it is RIP IP tables rule
1760          if ( strcmp(col[IP_TBL_COL_TARGET], "DROP") == 0 &&
1761               strcmp(col[IP_TBL_COL_DST], UPNP_IP_ADDRESS) == 0 ) {
1762             sprintf(line, "iptables -D OUTPUT %s 2>/dev/null", col[IP_TBL_COL_NUM]);
1763             bcmSystemMute(line);
1764             ret = TRUE;
1765             break;
1766          }
1767       }
1768       fclose(fs);
1769
1770       // remove iptable file
1771       unlink("/var/iptable");
1772    }
1773
1774    return ret;
1775 }
1776
1777 /***************************************************************************
1778 // Function Name: bcmInsertAllUpnpIpTableRules().
1779 // Description  : insert UPnP IP table rules.
1780 // Parameters   : none.
1781 // Returns      : none.
1782 ****************************************************************************/
1783 void bcmInsertAllUpnpIpTableRules(void) {
1784    char interface[IFC_TINY_LEN], cmd[IFC_LARGE_LEN];
1785    WAN_CON_ID wanId;
1786    WAN_CON_INFO wanInfo;
1787
1788    // init wanId to get WAN info from the begining
1789    wanId.vpi = wanId.vci = wanId.conId = 0;
1790    
1791    while ( BcmDb_getWanInfoNext(&wanId, &wanInfo) == DB_WAN_GET_OK ) {
1792       if ( wanInfo.flag.service == FALSE ) continue;
1793       if ( wanInfo.flag.nat == TRUE ) {
1794          // get interface name
1795          BcmDb_getWanInterfaceName(&wanId, wanInfo.protocol, interface);
1796          // If the br0 interface goes down and then comes back up, we do not need to
1797          // restart UPnP. All UPnP object values are obtained from the actual WAN
1798          // interface /dev/bcmadsl0 and /dev/bcmatm0.
1799          if ( bcmGetPid("upnp") <= 0 ) {
1800             sprintf(cmd, "upnp -L %s -W %s -D", "br0", interface);
1801             bcmSystem(cmd);
1802          }
1803          // Stop multicast reports for UPnP on WAN.
1804          sprintf(cmd, "iptables -t filter -I OUTPUT -o %s -d %s -j DROP 2>/dev/null",
1805                  interface, UPNP_IP_ADDRESS);
1806          bcmSystemMute(cmd);
1807       }
1808    }
1809 }
1810
1811 /***************************************************************************
1812 // Function Name: bcmRemoveEbTableRule().
1813 // Description  : remove ebtables rules.
1814 // Parameters   : device -- interface name.
1815 //                table -- ebtables table name.
1816 //                chain -- ebtables table chain.
1817 // Returns      : 1 - Success. 0 - Fail
1818 ****************************************************************************/
1819 int bcmRemoveEbTableRule(char *device, char *table, char *chain) {
1820    char line[IFC_GIANT_LEN];
1821    int ret = FALSE, count = 0, index = 0;
1822    FILE* fs = NULL;
1823
1824    if ((access("/bin/ebtables",F_OK)) != 0)
1825       return FALSE;
1826
1827    // execute iptables command to create iptable file
1828    sprintf(line, "ebtables -t %s -L %s --Ln > /var/ebtable", table, chain);
1829    bcmSystemMute(line);
1830
1831    fs = fopen("/var/ebtable", "r");
1832    if ( fs != NULL ) {
1833       while ( fgets(line, sizeof(line), fs) ) {
1834          // read pass 3 header lines
1835          if ( count++ < 3 ) continue;
1836          // if chain rule for the given device is found
1837          if ( strstr(line, device) != NULL ) {
1838             // get the rule index number
1839             sscanf(line, "%d.", &index);
1840             sprintf(line, "ebtables -t %s -D %s %d 2>/dev/null", table, chain, index);
1841             bcmSystemMute(line);
1842             ret = TRUE;
1843             break;
1844          }
1845       }
1846       fclose(fs);
1847    }
1848
1849    // code to remove ebtable file is moved to bcmRemoveAllEbTableRules() function
1850
1851    return ret;
1852 }
1853
1854 /***************************************************************************
1855 // Function Name: bcmRemoveAllEbTableRules().
1856 // Description  : remove all ebtables rules attach with the given device.
1857 //                Each time, only one rule is removed, hence the rule index changes
1858 //                That's why we need to use while loop to remove all
1859 // Parameters   : device -- interface name.
1860 // Returns      : none
1861 ****************************************************************************/
1862 void bcmRemoveAllEbTableRules(char *device) {
1863 // while ( bcmRemoveEbTableRule(device, "filter", "INPUT") == TRUE )
1864 //         ;
1865
1866    while ( bcmRemoveEbTableRule(device, "filter", "FORWARD") == TRUE )
1867          ;
1868
1869 // while ( bcmRemoveEbTableRule(device, "filter", "OUTPUT") == TRUE )
1870 //         ;
1871
1872    // remove ebtable file
1873    unlink("/var/ebtable");
1874 }
1875
1876
1877 /***************************************************************************
1878 // Function Name: bcmGetDefaultRouteInterfaceName().
1879 // Description  : get interface name that is used for first default route.
1880 // Parameters   : ifcName -- the return interface name, '\0' if not found.
1881 // Returns      : none
1882 ****************************************************************************/
1883 void bcmGetDefaultRouteInterfaceName(char *ifcName) {
1884    char col[11][IFC_SMALL_LEN];
1885    char line[IFC_GIANT_LEN];
1886    int count = 0;
1887
1888    if ( ifcName == NULL ) return;
1889
1890    ifcName[0] = '\0';
1891
1892    FILE* fsRoute = fopen("/proc/net/route", "r");
1893    if ( fsRoute != NULL ) {
1894       while ( fgets(line, sizeof(line), fsRoute) ) {
1895          // read pass header line
1896          if ( count++ < 1 ) continue;
1897          sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
1898                 col[0], col[1], col[2], col[3], col[4], col[5],
1899                 col[6], col[7], col[8], col[9], col[10]);
1900          // if destination && mask are 0 then it's default route
1901          if ( strcmp(col[1], "00000000") == 0 &&
1902               strcmp(col[7], "00000000") == 0 ) {
1903             strcpy(ifcName, col[0]);
1904             break;
1905          }
1906       }
1907       fclose(fsRoute);
1908    }
1909 }
1910
1911 //***************************************************************************
1912 // Function Name: parseStrInfo
1913 // Description  : parse info to get value of the given variable.
1914 // Parameters   : info -- information string.
1915 //                var -- variable string to be searched in info string.
1916 //                val -- value string after variable string to be returned.
1917 //                len -- size of value string.
1918 // Returns      : none.
1919 //***************************************************************************/
1920 void parseStrInfo(char *info, char *var, char *val, int len) {
1921    char *pChar = NULL;
1922    int i = 0;
1923
1924    if ( info == NULL || var == NULL || val == NULL ) return;
1925
1926    pChar = strstr(info, var);
1927    if ( pChar == NULL ) return;
1928
1929    // move pass the variable string in line
1930    pChar += strlen(var);
1931
1932    // Remove spaces from beginning of value string
1933    while ( *pChar != '\0' && isspace((int)*pChar) != 0 )
1934       pChar++;
1935
1936    // get data until end of line, or space char
1937    for ( i = 0;
1938          i < len && *pChar != '\0' &&
1939          isspace((int)*pChar) == 0;
1940          i++, pChar++ )
1941       val[i] = *pChar;
1942
1943    val[i] = '\0';
1944 }
1945
1946 //**************************************************************************
1947 // Function Name: bcmConvertStrToShellStr
1948 // Description  : convert the given string so that each its character is
1949 //                surround by '. If character is ' then it is surround by ".
1950 //                (a#b'c"d => 'a''#''b'"'"'c''"''d')
1951 // Parameters   : str - the given string.
1952 //                buf - the converted string.
1953 // Returns      : none.
1954 //**************************************************************************
1955 void bcmConvertStrToShellStr(char *str, char *buf) {
1956    if ( buf == NULL ) return;
1957
1958    int len = strlen(str);
1959    int i = 0, j = 0;
1960    char escp;
1961
1962    for ( i = 0; i < len; i++ ) { 
1963       if ( isalnum(str[i]) ) 
1964          buf[j++] = str[i];
1965       else { 
1966          buf[j++] = ( escp = (str[i] == '\'' ? '"':'\'') );
1967          buf[j++] = str[i];
1968          buf[j++] = escp;
1969       }
1970    }    
1971    buf[j]  = '\0';
1972 }
1973
1974 //**************************************************************************
1975 // Function Name: bcmProcessMarkStrChars
1976 // Description  : use backslash in front one of the escape codes to process
1977 //                marked string characters.
1978 //                (a'b"c => a\'b\"c)
1979 // Parameters   : str - the string that needs to process its special chars.
1980 // Returns      : none.
1981 //**************************************************************************
1982 void bcmProcessMarkStrChars(char *str) {
1983    if ( str == NULL ) return;
1984    if ( str[0] == '\0' ) return;
1985
1986    char buf[SYS_CMD_LEN];
1987    int len = strlen(str);
1988    int i = 0, j = 0;
1989
1990    for ( i = 0; i < len; i++ ) {
1991       if ( bcmIsMarkStrChar(str[i]) == TRUE )
1992          buf[j++] = '\\';
1993       buf[j++] = str[i];
1994    }
1995
1996    buf[j] = '\0';
1997    strcpy(str, buf);
1998 }
1999
2000 //**************************************************************************
2001 // Function Name: bcmIsMarkStrChar
2002 // Description  : verify the given character is used to mark the begining or
2003 //                ending of string or not.
2004 // Parameters   : c -- the given character.
2005 // Returns      : TRUE or FALSE.
2006 //**************************************************************************
2007 int bcmIsMarkStrChar(char c) {
2008    // need to add '\0' as termination character to speChars[]
2009    char specChars[] = "'\"\\";
2010    int len = strlen(specChars);
2011    int i = 0;
2012    int ret = FALSE;
2013
2014    for ( i = 0; i < len; i++ )
2015       if ( c == specChars[i] )
2016          break;
2017
2018    if ( i < len )
2019       ret = TRUE;
2020
2021    return ret;
2022 }
2023
2024 //**************************************************************************
2025 // Function Name: bcmGetSwVer
2026 // Description  : retrieve software version from global variable
2027 // Parameters   : swVer - buffer to get the software version.
2028 //                size - size of buffer.
2029 // Returns      : none.
2030 //**************************************************************************
2031 void bcmGetSwVer(char *swVer, int size) {
2032    char version[SYS_CMD_LEN], adslPhyVersion[SYS_CMD_LEN];
2033
2034    if ( swVer == NULL ) return;
2035
2036    // get adsl physical version
2037    BcmAdslCtl_GetPhyVersion(adslPhyVersion, SYS_CMD_LEN - 1);
2038    // create software version
2039    sprintf(version, "%s%s", SOFTWARE_VERSION, adslPhyVersion);
2040    strncpy(swVer, version, size);
2041    swVer[size-1] = '\0';
2042 }
2043
2044 // USR9108
2045 //**************************************************************************
2046 // Function Name: bcmGetBuildVer
2047 // Description  : retrieve build version from bcmTag
2048 // Parameters   : swVer - buffer to get the software version.
2049 //                size - size of buffer.
2050 // Returns      : none.
2051 //**************************************************************************
2052 void bcmGetBuildVer(char *swVer, int size) {
2053     int i;
2054     const char verFormat[IFC_SMALL_LEN] = {"0.00L.00.00"};
2055     char* tagVersion = BCM_SIG_2 + 5;
2056
2057     strncpy(swVer, verFormat, size);
2058     for( i=0; i<strlen(verFormat), *tagVersion; i++ ) {
2059         if( swVer[i] != '.' )   // Insert periods into version string   
2060             swVer[i] = *tagVersion++;   // Start from numeric value
2061     }
2062 #if ( 0 )            
2063     if( (size - strlen(swVer)) > 12 )
2064         strcat(swVer, "-Beta 6");
2065 #endif
2066 }
2067
2068 //**************************************************************************
2069 // Function Name: bcmcheck_enable
2070 // Description  : check the appName with ip address against the psi
2071 //                for access mode
2072 // Parameters   : appName - application name in the acl.conf (telnet, ssh, etc.)
2073 //                clntAddr - incoming ip address
2074 // Returns      : access mode - CLI_ACCESS_LOCAL, CLI_REMOTE_LOCAL, CLI_ACCESS_DISABLED
2075 //**************************************************************************
2076 int bcmCheckEnable(char *appName, struct in_addr clntAddr)
2077 {
2078    // is client address in Access Control List ?
2079    if ( BcmScm_isInAccessControlList(inet_ntoa(clntAddr)) == FALSE )
2080       return CLI_ACCESS_DISABLED;
2081
2082    if ( isAccessFromLan(clntAddr) == TRUE ) {
2083       // is enabled from lan ?
2084       if ( BcmScm_isServiceEnabled(appName, CLI_ACCESS_LOCAL) == FALSE )
2085          return CLI_ACCESS_DISABLED;
2086       else
2087          return CLI_ACCESS_LOCAL;
2088    } else {
2089       // is enabled from wan ?
2090       if ( BcmScm_isServiceEnabled(appName, CLI_ACCESS_REMOTE) == FALSE )
2091          return CLI_ACCESS_DISABLED;
2092       else
2093          return CLI_ACCESS_REMOTE;
2094    }
2095 }
2096
2097 int bcmWanEnetQuerySwitch(char *ifName) {
2098    FILE *errFs = NULL;
2099    char cmd[IFC_LARGE_LEN];
2100    char str[IFC_LARGE_LEN];
2101    int  numIfc = 0;
2102
2103    sprintf(cmd, "vconfig query %s 2 2>/var/vcfgerr\n", ifName);
2104    bcmSystem(cmd);
2105    // Check the status of the previous command
2106    errFs = fopen("/var/vcfgerr", "r");
2107    if (errFs != NULL ) {
2108       fgets(str, IFC_LARGE_LEN, errFs);
2109       numIfc = atoi(str);
2110       fclose(errFs);
2111       bcmSystem("rm /var/vcfgerr");
2112    }
2113    return numIfc;
2114 }
2115
2116 #endif // USE_ALL, code below this code can be linked with other apps
2117
2118
2119 //*********** code shared by ftpd and tftpd **********************
2120 //****************************************************************
2121
2122 /***************************************************************************
2123 // Function Name: bcmIsModuleInserted.
2124 // Description  : verify the given module name is already inserted or not.
2125 // Parameters   : modName -- the given module name.
2126 // Returns      : TRUE or FALSE.
2127 ****************************************************************************/
2128 int bcmIsModuleInserted(char *modName) {
2129    int ret = FALSE;
2130    char buf[SYS_CMD_LEN];
2131    FILE* fs = fopen("/proc/modules", "r");
2132
2133    if ( fs != NULL ) {
2134       while ( fgets(buf, SYS_CMD_LEN, fs) > 0 )
2135          if ( strstr(buf, modName) != NULL ) {
2136             ret = TRUE;
2137             break;
2138          }
2139       fclose(fs);
2140    }
2141
2142    return ret;
2143 }
2144
2145
2146 /***************************************************************************
2147 // Function Name: bcmCheckInterfaceUp().
2148 // Description  : check status of interface.
2149 // Parameters   : devname - name of device.
2150 // Returns      : 1 - UP.
2151 //                0 - DOWN.
2152 ****************************************************************************/
2153 int bcmCheckInterfaceUp(char *devname) {
2154    int  skfd;
2155    int  ret;
2156    struct ifreq intf;
2157
2158    if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2159       return 0;
2160    }
2161
2162    strcpy(intf.ifr_name, devname);
2163
2164    // if interface is br0:0 and
2165    // there is no binding IP address then return down
2166    if ( strchr(devname, ':') != NULL ) {
2167       if (ioctl(skfd, SIOCGIFADDR, &intf) < 0) {
2168          close(skfd);
2169          return 0;
2170       }
2171    }
2172
2173    // if interface flag is down then return down
2174    if (ioctl(skfd, SIOCGIFFLAGS, &intf) == -1) {
2175       ret = 0;
2176    } else {
2177       if ( (intf.ifr_flags & IFF_UP) != 0)
2178          ret = 1;
2179       else
2180          ret = 0;
2181    }
2182
2183    close(skfd);
2184
2185    return ret;
2186 }
2187
2188 //If we don't link with busybox, we need this function
2189 #ifndef BUILD_STATIC
2190
2191 static void remove_delimitor( char *s)
2192 {
2193     char *p1, *p2;
2194
2195     p1 = p2 = s;
2196     while ( *p1 != '\0' || *(p1+1) != '\0') {
2197         if (*p1 != '\0') {
2198            *p2 = *p1;
2199            p2++;
2200          }
2201          p1++;
2202     }
2203     *p2='\0';
2204
2205 }
2206 /* find_pid_by_name()
2207  *
2208  *  This finds the pid of the specified process.
2209  *  Currently, it's implemented by rummaging through
2210  *  the proc filesystem.
2211  *
2212  *  Returns a list of all matching PIDs
2213  */
2214 static pid_t* find_pid_by_name( char* pidName)
2215 {
2216         DIR *dir;
2217         struct dirent *next;
2218         pid_t* pidList=NULL;
2219         int i=0;
2220
2221         /*FILE *status */
2222         FILE *cmdline;
2223         char filename[READ_BUF_SIZE];
2224         char buffer[READ_BUF_SIZE];
2225         /* char name[READ_BUF_SIZE]; */
2226                 
2227         dir = opendir("/proc");
2228         if (!dir) {
2229                 printf("cfm:Cannot open /proc");
2230                 return NULL;
2231         }
2232
2233         while ((next = readdir(dir)) != NULL) {
2234                 /* re-initialize buffers */
2235                 memset(filename, 0, sizeof(filename));
2236                 memset(buffer, 0, sizeof(buffer));  
2237
2238                 /* Must skip ".." since that is outside /proc */
2239                 if (strcmp(next->d_name, "..") == 0)
2240                         continue;
2241
2242                 /* If it isn't a number, we don't want it */
2243                 if (!isdigit(*next->d_name))
2244                         continue;
2245
2246                 /* sprintf(filename, "/proc/%s/status", next->d_name); */
2247                 /* read /porc/<pid>/cmdline instead to get full cmd line */
2248                 sprintf(filename, "/proc/%s/cmdline", next->d_name);
2249                 if (! (cmdline = fopen(filename, "r")) ) {
2250                         continue;
2251                 }
2252                 if (fgets(buffer, READ_BUF_SIZE-1, cmdline) == NULL) {
2253                         fclose(cmdline);
2254                         continue;
2255                 }
2256                 fclose(cmdline);
2257
2258                 /* Buffer should contain a string like "Name:   binary_name" */
2259                 /*sscanf(buffer, "%*s %s", name);*/
2260                 /* buffer contains full commandline params separted by '\0' */
2261                 remove_delimitor(buffer);
2262                 if (strstr(buffer, pidName) != NULL) {
2263                         pidList=realloc( pidList, sizeof(pid_t) * (i+2));
2264                         if (!pidList) {
2265                                 printf("cfm: Out of memeory!\n");
2266                                 closedir(dir);
2267                                 return NULL;
2268                         }
2269                         pidList[i++]=strtol(next->d_name, NULL, 0);
2270                 }
2271         }
2272         closedir(dir);
2273
2274         if (pidList)
2275                 pidList[i]=0;
2276         else if ( strcmp(pidName, "init")==0) {
2277                 /* If we found nothing and they were trying to kill "init",
2278                  * guess PID 1 and call it good...  Perhaps we should simply
2279                  * exit if /proc isn't mounted, but this will do for now. */
2280                 pidList=realloc( pidList, sizeof(pid_t));
2281                 if (!pidList) {
2282                         printf("cfm: Out of memeory!\n");
2283                         return NULL;
2284                 }
2285                 pidList[0]=1;
2286         } else {
2287                 pidList=realloc( pidList, sizeof(pid_t));
2288                 if (!pidList) {
2289                         printf("cfm: Out of memeory!\n");
2290                         return NULL;
2291                 }
2292                 pidList[0]=-1;
2293         }
2294         return pidList;
2295 }
2296
2297 #endif
2298
2299 void bcmHidePassword(char *command) {
2300    char *ptr = NULL;
2301    char * begin, *end;
2302    int len = 0;
2303
2304    /* pppd -i .....  -p password */
2305    if ((ptr = strstr(command,"pppd")) != NULL) {
2306      if (!strstr(ptr, "-p")) 
2307         return;
2308      begin = strstr(ptr,"-p") + 3;
2309      end = strchr(begin,' ');
2310      if (end == NULL) 
2311        len = strlen(begin);
2312      else 
2313        len = end - begin;
2314    }
2315
2316    while (len > 0) {
2317       *begin = '*';
2318       begin++; len--;
2319    }
2320 }
2321
2322 /***************************************************************************
2323 // Function Name: bcmSystem().
2324 // Description  : launch shell command in the child process.
2325 // Parameters   : command - shell command to launch.
2326 // Returns      : status 0 - OK, -1 - ERROR.
2327 ****************************************************************************/
2328 int bcmSystemEx (char *command, int printFlag) {
2329    int pid = 0, status = 0;
2330    char *newCommand = NULL;
2331
2332    if ( command == 0 )
2333       return 1;
2334
2335    pid = fork();
2336    if ( pid == -1 )
2337       return -1;
2338
2339    if ( pid == 0 ) {
2340       char *argv[4];
2341       argv[0] = "sh";
2342       argv[1] = "-c";
2343       argv[2] = command;
2344       argv[3] = 0;
2345 #ifdef BRCM_DEBUG
2346       if (printFlag)
2347          printf("app: %s\r\n", command);
2348 #endif
2349       if (printFlag) {
2350         if ((newCommand = strdup(command)) != NULL) {
2351            bcmHidePassword(newCommand);
2352            syslog(LOG_DEBUG, newCommand);
2353            free(newCommand);
2354         }
2355       }
2356       execve("/bin/sh", argv, environ);
2357       exit(127);
2358    }
2359
2360    /* wait for child process return */
2361    do {
2362       if ( waitpid(pid, &status, 0) == -1 ) {
2363          if ( errno != EINTR )
2364             return -1;
2365       } else
2366          return status;
2367    } while ( 1 );
2368
2369    return status;
2370 }
2371
2372
2373 /***************************************************************************
2374 // Function Name: bcmGetPid().
2375 // Description  : get process PID by using process name.
2376 // Parameters   : command - command that launch the process.
2377 // Returns      : process ID number.
2378 ****************************************************************************/
2379 int bcmGetPid(char * command)
2380 {
2381     char cmdline[128], *p1, *p2;
2382     pid_t *pid = NULL;
2383     int ret = 0;
2384
2385     p1 = command;
2386     p2 = cmdline;
2387     while ( *p1 != '\0') {
2388         if (*p1 != ' ') {
2389            *p2 = *p1;
2390            p2++;
2391          }
2392          p1++;
2393     }
2394     *p2='\0';
2395
2396     pid = find_pid_by_name(cmdline);
2397     if ( pid != NULL ) {
2398        ret = (int)(*pid);
2399        free(pid);
2400     }
2401
2402     return ret;
2403 }
2404
2405
2406 /***************************************************************************
2407 // Function Name: bcmGetPidList().
2408 // Description  : get process PID by using process name.
2409 // Parameters   : command - command that launch the process.
2410 // Returns      : process ID list
2411 ****************************************************************************/
2412 int *bcmGetPidList(char * command)
2413 {
2414     char cmdline[128], *p1, *p2;
2415     pid_t *pid = NULL;
2416
2417     p1 = command;
2418     p2 = cmdline;
2419     while ( *p1 != '\0') {
2420         if (*p1 != ' ') {
2421            *p2 = *p1;
2422            p2++;
2423          }
2424          p1++;
2425     }
2426     *p2='\0';
2427
2428     pid = find_pid_by_name(cmdline);
2429
2430     return (int*)pid;
2431 }
2432
2433 /***************************************************************************
2434 // Function Name: bcmGetIntfNameSocket.
2435 // Description  : Return the interface name a socket is bound to
2436 // Parameters   : socketfd: Socket descriptor, intfname: Network interface name
2437 // Returns      : Failed: -1. Succeeded: 0
2438 ****************************************************************************/
2439 int bcmGetIntfNameSocket(int socketfd, char *intfname)
2440 {
2441    int i = 0, fd = 0;
2442    int numifs = 0, bufsize = 0;
2443    struct ifreq *all_ifr = NULL;
2444    struct ifconf ifc;
2445    struct sockaddr local_addr;
2446    socklen_t local_len = sizeof(struct sockaddr_in);
2447
2448    memset(&ifc, 0, sizeof(struct ifconf));
2449    memset(&local_addr, 0, sizeof(struct sockaddr));
2450
2451    if (getsockname(socketfd, &local_addr,&local_len) < 0) {
2452      printf("bcmGetIntfNameSocket: Error in getsockname!\n");
2453      return -1;
2454    }
2455
2456    //printf("bcmGetIntfNameSocket: Session comes from: %s\n",inet_ntoa(((struct sockaddr_in *)&local_addr)->sin_addr));
2457    
2458    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2459      printf("bcmGetIntfNameSocket: Error openning socket when getting socket intface info\n");
2460      return -1;
2461    }
2462
2463    numifs = 16;
2464
2465    bufsize = numifs*sizeof(struct ifreq);
2466    all_ifr = (struct ifreq *)malloc(bufsize);
2467    if (all_ifr == NULL) {
2468       printf("bcmGetIntfNameSocket: out of memory!\n");
2469       close(fd);
2470       return -1;
2471    }
2472
2473    ifc.ifc_len = bufsize;
2474    ifc.ifc_buf = (char *)all_ifr;
2475    if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
2476       printf("bcmGetIntfNameSocket: Error getting interfaces\n");
2477       close(fd);
2478       free(all_ifr);
2479       return -1;
2480    }
2481
2482    numifs = ifc.ifc_len/sizeof(struct ifreq);
2483    //printf("bcmGetIntfNameSocket: numifs=%d\n",numifs);
2484    for (i = 0; i < numifs; i ++) {
2485            //printf("bcmGetIntfNameSocket: intface name=%s\n",all_ifr[i].ifr_name); 
2486            struct in_addr addr1,addr2;
2487            addr1 = ((struct sockaddr_in *)&(local_addr))->sin_addr;
2488            addr2 = ((struct sockaddr_in *)&(all_ifr[i].ifr_addr))->sin_addr;
2489            if (addr1.s_addr == addr2.s_addr) {
2490                 strcpy(intfname, all_ifr[i].ifr_name);
2491                 break;
2492            }
2493    }
2494
2495    close(fd);
2496    free(all_ifr);
2497    return 0;
2498 }
2499
2500
2501 static int getLanInfo(char *lan_ifname, struct in_addr *lan_ip, struct in_addr *lan_subnetmask)
2502 {
2503    int socketfd;
2504    struct ifreq lan;
2505
2506    if ((socketfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2507      printf("app: Error openning socket when getting LAN info\n");
2508      return -1;
2509    }
2510
2511    strcpy(lan.ifr_name,lan_ifname);
2512    if (ioctl(socketfd,SIOCGIFADDR,&lan) < 0) {
2513      printf("app: Error getting LAN IP address\n");
2514      close(socketfd);
2515      return -1;
2516    }
2517    *lan_ip = ((struct sockaddr_in *)&(lan.ifr_addr))->sin_addr;
2518
2519    if (ioctl(socketfd,SIOCGIFNETMASK,&lan) < 0) {
2520      printf("app: Error getting LAN subnet address\n");
2521      close(socketfd);
2522      return -1;
2523    }
2524
2525    *lan_subnetmask = ((struct sockaddr_in *)&(lan.ifr_netmask))->sin_addr;
2526
2527    close(socketfd);
2528    return 0;
2529 }
2530
2531 static int isIpExtension(void)
2532 {
2533    FILE *fp;
2534    int ipextension = 0;
2535
2536    if ((fp=fopen("/var/ipextension","r")) != NULL) {
2537       fscanf(fp,"%d",&ipextension);
2538       fclose(fp);
2539    }
2540
2541    return ipextension;
2542 }
2543
2544 static void getIpExtIp(char *buf)
2545 {
2546    FILE* fs;
2547    char wan[64], gateway[64], dns[64], str[256];
2548
2549    if ( buf == NULL ) return;
2550
2551    buf[0] = '\0';
2552    fs = fopen("/var/ipextinfo", "r");
2553    if ( fs != NULL ) {
2554       fgets(str, 256, fs);
2555       fclose(fs);
2556       sscanf(str, "%s %s %s\n", wan, gateway, dns);
2557       strcpy(buf, wan);
2558    }
2559 }
2560
2561 int isAccessFromLan(struct in_addr clntAddr)
2562 {
2563    int ret = 0;
2564    struct in_addr inAddr, inMask;
2565    char wan[64];
2566
2567    getLanInfo("br0", &inAddr, &inMask);
2568    /* check ip address of support user to see it is in LAN or not */
2569    if ( (clntAddr.s_addr & inMask.s_addr) == (inAddr.s_addr & inMask.s_addr) )
2570       ret = 1;
2571    else {
2572       /* check ip address of support user to see if it is from secondary LAN */
2573       if (bcmCheckInterfaceUp("br0:0")) {
2574          getLanInfo("br0:0", &inAddr, &inMask);
2575          if ( (clntAddr.s_addr & inMask.s_addr) == (inAddr.s_addr & inMask.s_addr) )
2576             ret = 1;
2577       }
2578
2579       /* Last option it must be from WAN side */
2580       if (isIpExtension()) {
2581          getIpExtIp(wan);
2582       if ( clntAddr.s_addr == inet_addr(wan) )
2583          ret = 1;
2584       }
2585    }
2586
2587    return ret;
2588 }
2589
2590 // return 0, ok. return -1 = wrong chip
2591 // used by upload.c and ftpd, tftpd, tftp utilities.
2592 int checkChipId(char *strTagChipId, char *sig2)
2593 {
2594     int tagChipId = 0;
2595         unsigned int chipId = (int) sysGetChipId();
2596     int result = 0;
2597    
2598     if (strstr(sig2, "Firmware"))
2599         return result;      // skip the pre 2_14L02 release, where the signiture_2 is "Firmware version 1.0"
2600
2601     tagChipId = atoi(strTagChipId);
2602
2603         switch (chipId) 
2604         {
2605         case 0x6338:
2606                         if (!(tagChipId == 6338))
2607                 result = -1;
2608             break;
2609         case 0x6345:
2610                         if (!(tagChipId == 6345 || tagChipId == 6335))
2611                 result = -1;
2612             break;
2613                 case 0x6348:
2614                         if (tagChipId != 6348)
2615                 result = -1;
2616             break;
2617         default:
2618                         printf("Chip id %04x not supported.\n", chipId);
2619             result = -1;
2620             break;
2621         }
2622
2623     if (result == -1)
2624             printf("Chip Id error.  Image Chip Id = %d, Board Chip Id = %04x.\n", tagChipId, chipId);
2625
2626     return result;
2627 }
2628
2629 /***************************************************************************
2630 // Function Name: bcmCheckForRedirect(void)
2631 // Description  : check for nat redirect for .
2632 // Parameters   : none
2633 // Returns      : 0 --> tcp port 21, 22, 23, 80 is redirected. -1 --> not redirected
2634 ****************************************************************************/
2635 int bcmCheckForRedirect(void)
2636 {
2637    char col[11][32];
2638    char line[512];
2639    FILE* fs;  
2640    int count = 0;
2641
2642    bcmSystem("iptables -t nat -L > /var/nat_redirect");
2643
2644    fs = fopen("/var/nat_redirect", "r");
2645    if ( fs != NULL ) {
2646       while ( fgets(line, sizeof(line), fs) ) {
2647          // read pass 3 header lines
2648          if ( count++ < 3 )
2649             continue;
2650          sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
2651                col[0], col[1], col[2], col[3], col[4], col[5],
2652                col[6], col[7], col[8], col[9], col[10]);
2653         if ((strcmp(col[0], "REDIRECT") == 0) && (strcmp(col[1], "tcp") == 0) && (strcmp(col[8], "ports") == 0))
2654           if (strcmp(col[9], "80") == 0 || strcmp(col[9], "23") == 0 || strcmp(col[9], "21") == 0 ||
2655               strcmp(col[9], "22") == 0 || strcmp(col[9], "69") == 0) {
2656               return TRUE;
2657           }
2658       }
2659       fclose(fs);
2660    }
2661    unlink("/var/nat_redirect");
2662    return FALSE;
2663 }
2664
2665 /***************************************************************************
2666 // Function Name: bcmRemoveModules(int lanIf)
2667 // Description  : remove not used modules to free memory.
2668 // Parameters   : none
2669 // Returns      : none.
2670 ****************************************************************************/
2671 void bcmRemoveModules(int lanIf)
2672 {
2673    char *modList[]=
2674    {
2675       "bcm_usb",
2676 #ifndef SUPPORT_ETHWAN
2677       "bcm_enet",
2678 #endif
2679       "ipt_state",
2680       "ipt_mark",
2681       "ipt_limit",
2682       "ipt_TCPMSS",
2683       "ipt_REDIRECT",
2684       "ipt_MASQUERADE",
2685       "ipt_MARK",
2686       "ipt_LOG",
2687       "ipt_FTOS",
2688       "ip_nat_tftp",
2689       "ip_nat_irc",
2690       "ip_nat_ftp",
2691       "ip_nat_h323",
2692       "ip_nat_pptp",
2693       "ip_nat_gre",
2694       "ip_nat_rtsp",
2695       "ip_nat_ipsec",
2696       "ip_conntrack_tftp",
2697       "ip_conntrack_irc",
2698       "ip_conntrack_ftp",
2699       "ip_conntrack_h323",
2700       "ip_conntrack_pptp",
2701       "ip_conntrack_gre",
2702       "ip_conntrack_rtsp",
2703       "ip_conntrack_ipsec",
2704       "iptable_mangle",
2705       "iptable_nat",
2706       "ip_conntrack",
2707       "iptable_filter",
2708       "ip_tables",
2709       NULL,
2710    };
2711
2712    char cmd[SYS_CMD_LEN];
2713    int i = 0;
2714    int saveNat = FALSE;
2715
2716    if (lanIf == 0)         // if lan, do not kill bcm_usb and bcm_enet
2717       i = 2;
2718
2719    saveNat = bcmCheckForRedirect();
2720
2721    if (bcmIsModuleInserted("iptable_filter") == TRUE)
2722    {  
2723        strncpy(cmd, "iptables -t filter -F", SYS_CMD_LEN-1);
2724        bcmSystem(cmd);
2725    }
2726    if (bcmIsModuleInserted("iptable_nat") == TRUE)
2727    {  
2728        strncpy(cmd, "iptables -t nat -F", SYS_CMD_LEN-1);
2729        bcmSystem(cmd);
2730    }
2731    if (bcmIsModuleInserted("iptable_mangle") == TRUE)
2732    {  
2733        strncpy(cmd, "iptables -t mangle -F", SYS_CMD_LEN-1);
2734        bcmSystem(cmd);
2735    }
2736
2737    while (modList[i] != NULL)
2738    {
2739       if (bcmIsModuleInserted(modList[i]) == TRUE) 
2740       {
2741          if (!(saveNat && strcmp(modList[i], "iptable_nat") == 0))
2742          {
2743             sprintf(cmd, "rmmod %s", modList[i]);
2744             bcmSystem(cmd);
2745          }
2746       }
2747       i++;
2748    }
2749    printf("\nRemaining modules:\n");
2750    bcmSystemMute("cat /proc/modules");
2751    printf("\nMemory info:\n");
2752    bcmSystemMute("sysinfo");
2753    sleep(1);
2754 }
2755
2756 /***************************************************************************
2757 // Function Name: bcmGetIfcIndexByName().
2758 // Description  : get interface index by its name.
2759 // Parameters   : ifcIdx -- interface index.
2760 //                ifcName -- interface name.
2761 // Returns      : interface index
2762 ****************************************************************************/
2763 int bcmGetIntf(char *ifcName) {
2764    struct ifreq ifr;
2765    int s = 0;
2766
2767    if ( ifcName == NULL ) return -1;
2768
2769    if ( (s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) return -1;
2770    strcpy(ifr.ifr_name, ifcName);
2771    if ( ioctl(s, SIOCGIFINDEX, &ifr) < 0 ) {
2772       close(s);
2773       return 0;
2774    }
2775    close(s);
2776    return ifr.ifr_ifindex;
2777 }
2778
2779 int bcmWaitIntfExists(char *ifName) {
2780    int retry = 0;
2781    int ret;
2782
2783    while (retry < 50) {
2784       if ((ret =bcmGetIntf(ifName)) <= 0) {
2785          usleep(5000);
2786          //printf("not exist,retry %d, ret %d\n",retry,ret);
2787          retry++;
2788       }
2789       else {
2790          return 1;
2791       }
2792    } /* while */
2793    return 0;
2794 }
2795
2796 //**************************************************************************
2797 // Function Name: bcmMacStrToNum
2798 // Description  : convert MAC address from string to array of 6 bytes.
2799 //                Ex: 0a:0b:0c:0d:0e:0f -> 0a0b0c0d0e0f
2800 // Returns      : status.
2801 //**************************************************************************
2802 int bcmMacStrToNum(char *macAddr, char *str) {
2803    char *pToken = NULL, *pLast = NULL;
2804    char *buf;
2805    UINT16 i = 1;
2806    int len;
2807    
2808    if ( macAddr == NULL ) return FALSE;
2809    if ( str == NULL ) return FALSE;
2810
2811    len = strlen(str) + 1;
2812    if (len > 20)
2813      len = 20;
2814    buf = (char*)malloc(len);
2815    memset(buf,0,len);
2816
2817    if ( buf == NULL ) return FALSE;
2818
2819    /* need to copy since strtok_r updates string */
2820    strncpy(buf, str,len-1);
2821
2822    /* Mac address has the following format
2823        xx:xx:xx:xx:xx:xx where x is hex number */
2824    pToken = strtok_r(buf, ":", &pLast);
2825    macAddr[0] = (char) strtol(pToken, (char **)NULL, 16);
2826    for ( i = 1; i < 6; i++ ) {
2827       pToken = strtok_r(NULL, ":", &pLast);
2828       macAddr[i] = (char) strtol(pToken, (char **)NULL, 16);
2829    }
2830
2831    free(buf);
2832
2833    return TRUE;
2834 }
2835
2836 //**************************************************************************
2837 // Function Name: bcmMacNumToStr
2838 // Description  : convert MAC address from array of 6 bytes to string.
2839 //                Ex: 0a0b0c0d0e0f -> 0a:0b:0c:0d:0e:0f
2840 // Returns      : status.
2841 //**************************************************************************
2842 int bcmMacNumToStr(char *macAddr, char *str) {
2843    if ( macAddr == NULL ) return FALSE;
2844    if ( str == NULL ) return FALSE;
2845
2846    sprintf(str, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
2847            (UINT8) macAddr[0], (UINT8) macAddr[1], (UINT8) macAddr[2],
2848            (UINT8) macAddr[3], (UINT8) macAddr[4], (UINT8) macAddr[5]);
2849
2850    return TRUE;
2851 }
2852
2853
2854 #ifdef USE_ALL
2855
2856 #ifdef PORT_MIRRORING
2857 /***************************************************************************
2858  * Function Name: OpenBlaaDD
2859  * Description  : Opens the bcmatm device.
2860  * Returns      : device handle if successsful or -1 if error
2861  ***************************************************************************/
2862 static int OpenBlaaDD( void )
2863 {
2864     int nFd ;
2865         
2866          if( (nFd = open("/dev/bcmatm0", O_RDWR)) < 0 )
2867                  printf( "OpenBlaaDD : open error %d\n", errno );
2868
2869     return( nFd );
2870 } /* OpenBcmAtm */
2871 #endif
2872 #endif
2873
2874 /***************************************************************************
2875 // Function Name: bcmConfigPortMirroring.
2876 // Description  : Configure the Port Mirroring feature dynamically.
2877 // Parameters   : MirrorCfg structure pointer.
2878 // Returns      : Failed: -1. Succeeded: 0
2879 ****************************************************************************/
2880 int bcmConfigPortMirroring (void *pCfg)
2881 {
2882 #ifdef USE_ALL
2883          MirrorCfg *pMirrorCfg = (MirrorCfg *) pCfg ;
2884          int fd ;
2885
2886 #ifdef PORTMIRROR_DEBUG
2887          printf ("ENGDBG:- In BcmConfigPortMirroring \n") ;
2888 #endif
2889
2890          if ((fd = OpenBlaaDD ()) < 0) {
2891                         printf ("Config Port Mirroring Failed \n") ;
2892                         return -1 ;
2893          }
2894
2895    if (ioctl(fd, ATMIOCTL_PORT_MIRRORING, pMirrorCfg) < 0) {
2896
2897       printf("IOCTL to BLAA Drive for Port Mirror CFG failed . Fatal \n") ;
2898       close(fd) ;
2899       return -1 ;
2900    }
2901
2902    close(fd);
2903 #endif
2904    return 0;
2905 }
2906
2907 #ifdef USE_ALL
2908 /***************************************************************************
2909 // Function Name: bcmRemoveTrafficControlRules.
2910 // Description  : remove tc rules for this interface if QoS is enabled.
2911 // Returns      : none.
2912 ****************************************************************************/
2913 void bcmRemoveTrafficControlRules(UINT16 vpi, UINT16 vci, UINT16 conId, UINT8 protocol) {
2914     char ifc[16];
2915     char cmd[SYS_CMD_LEN];
2916
2917     if (protocol != PROTO_PPPOA) {
2918         return;
2919     }
2920
2921     ifc[0] = '\0';
2922     snprintf(ifc, 16, "ppp_%d_%d_%d", vpi, vci, conId);
2923     sprintf(cmd, "tc qdisc del dev %s root", ifc);
2924     bcmSystem(cmd);
2925 }
2926
2927 /***************************************************************************
2928 // Function Name: bcmAddTrafficControlRules.
2929 // Description  : add tc rules for this interface if QoS is enabled.
2930 // Returns      : none.
2931 ****************************************************************************/
2932 void bcmAddTrafficControlRules(UINT16 vpi, UINT16 vci, UINT16 conId, UINT8 protocol) {
2933     char ifc[16];
2934     char cmd[SYS_CMD_LEN];
2935     ADSL_CONNECTION_INFO adslInfo;
2936     int lineRate = 0;
2937
2938     if (protocol != PROTO_PPPOA) {
2939         return;
2940     }
2941
2942     ifc[0] = '\0';
2943     sprintf(ifc, "ppp_%d_%d_%d", vpi, vci, conId);
2944     // Get the actual upstream line rate from the ADSL driver.
2945     BcmAdslCtl_GetConnectionInfo(&adslInfo);
2946     if (adslInfo.LinkState != BCM_ADSL_LINK_UP) {
2947         return;
2948     }
2949     if ( adslInfo.ulInterleavedUpStreamRate != 0 )
2950          lineRate = adslInfo.ulInterleavedUpStreamRate;
2951     else
2952          lineRate = adslInfo.ulFastUpStreamRate;
2953
2954     // Before we do anythng, lets add an ebtable rule at the bottom, that
2955     // marks the packets with low priority mark as default 0x0001.
2956     sprintf(cmd, "ebtables -t broute -A BROUTING -j mark --set-mark 0x0001 -p IPv4");
2957     bcmSystem(cmd);
2958
2959     // Create the root. This also creates the classes 1:1, 1:2 and 1:3
2960     // automatically
2961     sprintf(cmd, "tc qdisc add dev %s root handle 1: htb default 1", ifc);
2962     bcmSystem(cmd);
2963     sprintf(cmd, "tc class add dev %s parent 1: classid 1:1 htb rate %lukbit",
2964             ifc, adslInfo.ulInterleavedUpStreamRate);
2965     bcmSystem(cmd);
2966     sprintf(cmd, "tc qdisc add dev %s parent 1:1 handle 10: prio bands 3 "
2967             "priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", ifc);
2968     bcmSystem(cmd);
2969     // Create the htb's under each class.
2970     sprintf(cmd, "tc qdisc add dev %s parent 10:1 handle 100: pfifo limit 10", ifc);
2971     bcmSystem(cmd);
2972     sprintf(cmd, "tc qdisc add dev %s parent 10:2 handle 200: pfifo limit 10", ifc);
2973     bcmSystem(cmd);
2974     sprintf(cmd, "tc qdisc add dev %s parent 10:3 handle 300: pfifo limit 10", ifc);
2975     bcmSystem(cmd);
2976     // Now add the filters for each sfq using the default handles.
2977     sprintf(cmd, "tc filter add dev %s protocol ip parent 10:0 prio 1 handle %d fw classid 10:1",
2978             ifc, PRIORITY_HIGH);
2979     bcmSystem(cmd);
2980     sprintf(cmd, "tc filter add dev %s protocol ip parent 10:0 prio 1 handle %d fw classid 10:2",
2981             ifc, PRIORITY_MEDIUM);
2982     bcmSystem(cmd);
2983     sprintf(cmd, "tc filter add dev %s protocol ip parent 10:0 prio 1 handle %d fw classid 10:3",
2984             ifc, PRIORITY_LOW);
2985     bcmSystem(cmd);
2986 }
2987 #endif
2988