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