1 /*****************************************************************************
3 // Copyright (c) 2000-2001 Broadcom Corporation
5 // No portions of this material may be reproduced in any form without the
6 // written permission of:
7 // Broadcom Corporation
9 // Irvine, California 92619
10 // All information contained in this document is Broadcom Corporation
11 // company private, proprietary, and trade secret.
13 ******************************************************************************
15 // Filename: syscall.c
16 // Author: Peter T. Tran
17 // Creation Date: 12/26/01
19 ******************************************************************************
21 // It provides system call functions for Linux.
23 *****************************************************************************/
25 /********************** Include Files ***************************************/
29 #include <arpa/inet.h>
37 #include <sys/socket.h>
38 #include <sys/ioctl.h>
39 #include <sys/types.h>
40 #include <sys/utsname.h>
44 #include <net/route.h>
57 #include "adslctlapi.h"
58 #if defined(SUPPORT_VDSL)
59 #include "vdslctlapi.h"
68 #include "portMirror.h"
69 #include "atmapidrv.h"
70 #endif /* PORT_MIRRORING */
76 #include "board_api.h"
79 #define PRIORITY_HIGH 3
80 #define PRIORITY_MEDIUM 2
81 #define PRIORITY_LOW 1
88 #define IFC_LARGE_LEN 264
91 extern char **environ;
92 extern char *getIfName(void);
94 extern char glbErrMsg[IFC_LARGE_LEN];
95 #define READ_BUF_SIZE 128
96 #define CONNTRACK_MUX 2000
98 /* If you change this definition, make sure you change it everywhere */
99 #define UDHCPD_DECLINE "/var/udhcpd.decline"
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;
125 execve("/bin/sh", argv, environ);
130 // check the child is exited or not without hang
131 ret = waitpid(pid, &status, WNOHANG | WUNTRACED);
133 case -1: // error occurs then return -1
135 case 0: // child does not exited yet
137 if ( ++counter > 20000 ) {
139 printf("app: child process cannot exits while executing command - %s\n", command);
145 default: // child does exit successfully
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");
177 sprintf(cmd, "echo %s > /var/run/ip", addrStart);
181 sprintf(cmd, "start %s\n", addrStart);
185 sprintf(cmd, "end %s\n", addrEnd);
189 switch ( protocol ) {
198 fputs("interface br0\n", fs);
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);
208 sprintf(cmd, "option lease %d\n", leasedTime);
210 sprintf(cmd, "option min_lease 30\n");
214 sprintf(cmd, "option subnet %s\n", mask);
218 sprintf(cmd, "option router %s\n", ipAddr);
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);
229 } else { // use real DNS when NAT is disabled
231 if ( strcmp(dns1, "0.0.0.0") != 0 )
232 sprintf(cmd, "option dns %s\n", dns1);
234 sprintf(cmd, "option dns %s\n", ipAddr);
237 if ( strcmp(dns2, "0.0.0.0") != 0 )
238 sprintf(cmd, "option dns %s\n", dns2);
240 sprintf(cmd, "option dns %s\n", ipAddr);
248 return FILE_OPEN_ERR;
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");
265 sprintf(cmd, "echo %s > /var/run/ip", wanAddr);
270 sprintf(cmd, "start %s\n", wanAddr);
274 sprintf(cmd, "end %s\n", wanAddr);
278 fputs("interface br0\n", fs);
281 fputs("option lease 30\n", fs);
282 fputs("option min_lease 30\n", fs);
285 sprintf(cmd, "option subnet %s\n", mask);
289 sprintf(cmd, "option router %s\n", wanAddr);
292 // don't use DNS relay since there is no ip table for
295 sprintf(cmd, "option dns %s\n", dns);
302 return FILE_OPEN_ERR;
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.
311 // Returns : status 0 - OK, -1 - ERROR.
312 ****************************************************************************/
313 int bcmSetIpExtInfo(char *wan, char *gateway, char *dns) {
315 FILE* fs = fopen("/var/ipextinfo", "w");
318 sprintf(str, "%s %s %s\n", wan, gateway, dns);
324 return FILE_OPEN_ERR;
327 /***************************************************************************
328 // Function Name: bcmGetIpExtInfo().
329 // Description : get wan, gateway, or dns for PPP IP extension.
330 // Parameters : buf - .
333 ****************************************************************************/
334 void bcmGetIpExtInfo(char *buf, int type) {
336 char wan[64], gateway[64], dns[64], str[256];
338 if ( buf == NULL ) return;
341 if( bcmGetAdslStatus() == MNTR_STS_OK ) {
342 fs = fopen("/var/ipextinfo", "r");
346 sscanf(str, "%s %s %s\n", wan, gateway, dns);
349 if( dns[0] >= '0' && dns[0] <= '9' )
353 if( dns[0] >= '0' && dns[0] <= '9' )
354 strcpy(buf, gateway);
357 if( dns[0] >= '0' && dns[0] <= '9' )
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];
378 addr.s_addr = inet_addr(ipAddr) + 1;
379 strcpy(nextAddr, inet_ntoa(addr));
381 sprintf(cmd, "echo %s > /var/run/ip", nextAddr);
385 fprintf(fs, "start %s\n", nextAddr);
388 fprintf(fs, "end %s\n", nextAddr);
391 fputs("interface br0\n", fs);
394 fputs("option lease 10\n", fs);
395 fputs("option min_lease 10\n", fs);
398 fprintf(fs, "option subnet %s\n", mask);
401 fprintf(fs, "option router %s\n", ipAddr);
404 fprintf(fs, "option dns %s\n", ipAddr);
410 return FILE_OPEN_ERR;
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];
424 bcmSystemMute("mkdir -p /var/fyi/sys");
425 bcmSystemMute("echo > /var/fyi/sys/dns");
426 fs = fopen("/var/fyi/sys/dns", "w");
429 sprintf(cmd, "nameserver %s\n", dns1);
431 sprintf(cmd, "nameserver %s\n", dns2);
437 return FILE_OPEN_ERR;
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;
447 /***************************************************************************
448 // Function Name: bcmGetXdslStatus().
449 // Description : get ADSL or VDSL status, depending on which link is up
451 // Returns : Link satus as in BCMXDSL_STATUS
452 ****************************************************************************/
453 int bcmGetXdslStatus()
455 BCMXDSL_STATUS ret = BCM_XDSL_LINK_DOWN;
458 sts = BcmAdslCtl_GetConnectionInfo(&glbAdslInfo);
459 if( sts == BCMADSL_STATUS_SUCCESS )
460 ret = glbAdslInfo.LinkState;
462 #if defined(SUPPORT_VDSL)
463 if((sts == BCMADSL_STATUS_ERROR) || ( glbAdslInfo.LinkState == BCM_XDSL_LINK_DOWN))
465 sts = BcmVdslCtl_GetConnectionInfo(&glbVdslInfo, glbErrMsg);
466 if( sts == BCMADSL_STATUS_SUCCESS )
467 ret = glbVdslInfo.LinkState;
474 /***************************************************************************
475 // Function Name: bcmGetAdslStatus().
476 // Description : get ADSL status.
478 // Returns : 0 - ADSL link Up (OK)
479 // 1 - ADSL link Down
481 ****************************************************************************/
482 int bcmGetAdslStatus() {
485 if (BcmAdslCtl_GetConnectionInfo(&glbAdslInfo) != BCMADSL_STATUS_ERROR) {
486 ret = glbAdslInfo.LinkState;
488 ret = BCMADSL_STATUS_ERROR;
493 #if defined(SUPPORT_VDSL)
494 /***************************************************************************
495 // Function Name: bcmGetVdslStatus().
496 // Description : get VDSL status.
498 // Returns : 0 - VDSL link Up (OK)
499 // 1 - VDSL link Down
501 ****************************************************************************/
502 int bcmGetVdslStatus() {
503 return((BcmVdslCtl_GetConnectionInfo(&glbVdslInfo, glbErrMsg) != BCMADSL_STATUS_ERROR) ?
504 glbVdslInfo.LinkState : BCMADSL_STATUS_ERROR);
508 /***************************************************************************
509 // Function Name: bcmGetPppStatus().
510 // Description : get PPP status.
511 // Parameters : str - buffer to retrieve message
512 // len - length of buffer
515 ****************************************************************************/
516 int bcmGetPppStatus(char *str, int len, char *name) {
520 sprintf(filePath,"/proc/var/fyi/wan/%s/daemonstatus",name);
521 fs = fopen(filePath, "r");
528 return FILE_OPEN_ERR;
531 /***************************************************************************
532 // Function Name: bcmGetDhcpcStatus().
533 // Description : get DHCPC status.
534 // Parameters : str - buffer to retrieve message
535 // len - length of buffer
538 ****************************************************************************/
539 int bcmGetDhcpcStatus(char *str, int len) {
540 FILE* fs = fopen("/var/run/dhcpc", "r");
548 return FILE_OPEN_ERR;
551 /***************************************************************************
552 // Function Name: bcmGetSystemStatus().
553 // Description : get system status.
554 // Parameters : str - buffer to retrieve message
555 // len - length of buffer
558 ****************************************************************************/
559 int bcmGetSystemStatus(char *str, int len) {
560 FILE* fs = fopen("/etc/sysmsg", "r");
568 return FILE_OPEN_ERR;
571 /***************************************************************************
572 // Function Name: bcmSetSystemStatus().
573 // Description : set system status.
574 // Parameters : int - system status
577 ****************************************************************************/
578 int bcmSetSystemStatus(int status) {
579 char cmd[SYS_CMD_LEN];
580 FILE* fs = fopen("/etc/sysmsg", "w");
583 sprintf(cmd, "%d\n", status);
589 return FILE_OPEN_ERR;
592 /***************************************************************************
593 // Function Name: bcmDisplayLed().
594 // Description : display LED corresponding to WAN link status.
595 // Parameters : status - WAN link status.
597 ****************************************************************************/
598 void bcmDisplayLed(int status) {
600 case MNTR_STS_ADSL_DOWN:
601 /* this means ADSL is DOWN */
602 sysLedCtrl(kLedPPP, kLedStateOff);
604 case MNTR_STS_ADSL_TRAINING:
605 /* this means ADSL is TRAINING */
606 sysLedCtrl(kLedPPP, kLedStateOff);
608 case MNTR_STS_PPP_AUTH_ERR:
609 //sysLedCtrl(kLedPPP, kLedStateFail);
610 sysLedCtrl(kLedPPP, kLedStateOff); // USR9108
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); */
620 /* this means ADSL and PPP are up */
621 // sysLedCtrl(kLedPPP, kLedStateOn); // USR9108 Not yet!
626 void bcmGetDynamicDnsAddr(char *dns, int primary) {
627 char str[SYS_CMD_LEN];
630 fs = fopen("/var/fyi/sys/dns", "r");
632 if ( fgets(str, SYS_CMD_LEN, fs) > 0 ) {
634 sscanf(str, "nameserver %s\n", dns);
636 if ( fgets(str, SYS_CMD_LEN, fs) > 0 )
637 sscanf(str, "nameserver %s\n", dns);
643 // if cannot find primary dns info then
644 // assign default value which is router IP address
645 bcmGetIfDestAddr("br0", dns);
648 /***************************************************************************
649 // Function Name: bcmGetDns().
650 // Description : get DSN info.
651 // Parameters : dns - buffer to retrieve primary dns.
653 ****************************************************************************/
654 void bcmGetDns(char *dns) {
655 IFC_DNS_INFO dnsInfo;
656 int sts = BcmDb_getDnsInfo(&dnsInfo);
659 if ( sts == DB_GET_OK ) {
660 if ( dnsInfo.dynamic == TRUE )
661 bcmGetDynamicDnsAddr(dns,BCM_PRIMARY_DNS);
663 if ( dnsInfo.preferredDns.s_addr != INADDR_NONE )
664 strcpy(dns, inet_ntoa(dnsInfo.preferredDns));
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);
672 /***************************************************************************
673 // Function Name: bcmGetDns2().
674 // Description : get DSN info.
675 // Parameters : dns - buffer to retrieve primary dns.
677 ****************************************************************************/
678 void bcmGetDns2(char *dns) {
679 IFC_DNS_INFO dnsInfo;
680 int sts = BcmDb_getDnsInfo(&dnsInfo);
683 if ( sts == DB_GET_OK ) {
684 if ( dnsInfo.dynamic == TRUE )
685 bcmGetDynamicDnsAddr(dns,BCM_SECONDARY_DNS);
687 if ( dnsInfo.alternateDns.s_addr != INADDR_NONE )
688 strcpy(dns, inet_ntoa(dnsInfo.alternateDns));
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);
696 void bcmGetDnsSettings(int *mode, char *primary, char *secondary)
698 IFC_DNS_INFO dnsInfo;
701 if (BcmDb_getDnsInfo(&dnsInfo) == DB_GET_OK) {
702 *mode = dnsInfo.dynamic;
705 bcmGetDns2(secondary);
708 /***************************************************************************
709 // Function Name: bcmRestartDnsProbe().
710 // Description : start DNS probe.
711 // Parameters : none.
713 ****************************************************************************/
714 void bcmRestartDnsProbe(void) {
715 char cmd[CLI_MAX_BUF_SZ];
717 // kill the old dnsprobe if it is existed
718 int pid = bcmGetPid("/bin/dnsprobe");
720 sprintf(cmd, "kill -9 %d", pid);
724 // start the new dnsprobe
725 bcmSystem("/bin/dnsprobe &");
728 /***************************************************************************
729 // Function Name: bcmConfigDns().
730 // Description : add or remove DNS info to PSI.
731 // Parameters : primary and secondary DNS.
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);
740 // get local ip address
741 bcmGetIfDestAddr("br0", addr);
743 // if user changes from static to auto assgined dns
745 if ( sts == DB_GET_OK &&
746 bcmIsModuleInserted("iptable_nat") == TRUE ) {
747 strcpy(buf, inet_ntoa(dnsInfo.preferredDns));
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);
751 // remove old resolve configuration file
752 FILE * fs = fopen("/var/fyi/sys/dns", "r");
755 bcmSystemMute("rm /var/fyi/sys/dns");
759 // create the new resolv.conf with new dsn info
760 bcmCreateResolvCfg(dns1, dns2);
763 if ( buf[0] != '\0' ) {
764 if (strcmp(buf, dns1) != 0) {
765 if ( bcmIsModuleInserted("iptable_nat") == TRUE ) {
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);
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);
772 bcmRestartDnsProbe();
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);
782 // if old dns2 differs with new one, restart dnsprobe
783 if (strcmp(buf, dns2) != 0) {
784 if ( bcmIsModuleInserted("iptable_nat") == TRUE )
785 bcmRestartDnsProbe();
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);
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
800 ****************************************************************************/
801 void bcmRemoveDefaultGatewayByWanIf(char *wanIf) {
802 char gtwy[IFC_TINY_LEN], ifName[IFC_TINY_LEN];
804 bcmGetDefaultGateway(gtwy, ifName);
806 if ( strcmp(ifName, wanIf) == 0 ) {
807 // remove static default gateway in PSI
808 BcmDb_removeDefaultGatewayInfo();
813 /***************************************************************************
814 // Function Name: bcmGetDefaultGateway().
815 // Description : get default gateway info.
816 // Parameters : gtwy - buffer to retrieve default gateway.
818 ****************************************************************************/
819 void bcmGetDefaultGateway(char *gtwy, char *wanIf) {
820 char str[SYS_CMD_LEN];
822 IFC_DEF_GW_INFO defgw;
823 char addr[512], ip[512];
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);
833 fs = fopen("/var/fyi/sys/gateway", "r");
835 if ( fgets(str, SYS_CMD_LEN, fs) > 0 ) {
836 sscanf(str, "%s\n", addr);
837 if ( BcmDb_validateIpAddress(addr) == DB_OBJ_VALID_OK )
840 if (bcmGetIfDestAddr(addr, ip) == BCM_DIAG_PASS)
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) {
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) {
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];
899 IFC_DEF_GW_INFO defgw;
901 // USR9109/9113 Just in case if something was wrong.
904 // remove static default gateway
905 if ( BcmDb_getDefaultGatewayInfo(&defgw) == DB_GET_OK ) {
906 // remove static default gateway in PSI
907 BcmDb_removeDefaultGatewayInfo();
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) {
913 strcat(cmd, inet_ntoa(defgw.defaultGateway));
915 if (strcmp(defgw.ifName, "") != 0) {
916 strcat(cmd, " dev ");
917 strcat(cmd, defgw.ifName);
919 strcat(cmd, " 2> /var/gwerr");
921 fs = fopen("/var/gwerr", "r");
922 // read gwerr, if there is err then
923 // need to set error message
925 if ( fgets(cmd, IFC_LARGE_LEN, fs) > 0 ) {
926 // remove the last newline character
927 cmd[strlen(cmd) - 1] = '\0';
929 bcmSystemMute("cat /var/gwerr");
933 bcmSystemMute("rm /var/gwerr");
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);
943 fs = fopen("/var/gwerr", "r");
944 // read gwerr, if there is err then
945 // need to set the error message
947 if ( fgets(cmd, IFC_LARGE_LEN, fs) > 0 ) {
948 // remove the last newline character
949 cmd[strlen(cmd) - 1] = '\0';
951 bcmSystemMute("cat /var/gwerr");
955 bcmSystemMute("rm /var/gwerr");
960 /***************************************************************************
961 // Function Name: bcmSetStaticDefaultGateway().
962 // Description : remove the old, and add the new default gateway.
963 // Parameters : gw, wanIf, and error message
965 ****************************************************************************/
966 void bcmSetStaticDefaultGateway(char *gw, char *wanIf, char *errMsg) {
968 char cmd[IFC_LARGE_LEN];
970 IFC_DEF_GW_INFO defgw;
972 // intialize gw if it is empty
974 strcpy(gw, "0.0.0.0");
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 ) {
989 strcat(cmd, inet_ntoa(defgw.defaultGateway));
991 if ( strcmp(defgw.ifName, "") != 0 ) {
992 strcat(cmd, " dev ");
993 strcat(cmd, defgw.ifName);
995 strcat(cmd, " 2> /var/gwerr");
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");
1008 bcmSystemMute("rm /var/gwerr");
1011 return; // same and do nothing
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 ");
1029 if (wanIf[0] != '\0') {
1030 strcat(cmd, " dev ");
1034 if ( runCmd == TRUE ) {
1035 strcat(cmd, " 2> /var/gwerr");
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
1044 // remove the last newline character
1045 cmd[strlen(cmd) - 1] = '\0';
1046 strcpy(errMsg, cmd);
1047 bcmSystemMute("cat /var/gwerr");
1051 bcmSystemMute("rm /var/gwerr");
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);
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)
1069 //**************************************************************************
1070 void getPppoeServiceName(char *service, char *ifName) {
1071 char fileName[IFC_LARGE_LEN];
1072 char str[SYS_CMD_LEN];
1075 if (ifName[0] != 0) {
1076 sprintf(fileName, "/proc/var/fyi/wan/%s/servicename", ifName);
1077 fs = fopen(fileName, "r");
1079 if (fgets(str, SYS_CMD_LEN, fs) > 0)
1080 sscanf(str, "%s\n", service);
1088 /***************************************************************************
1089 // Function Name: setWanLinkStatus().
1090 // Description : get PPP status.
1091 // Parameters : up - wan link status
1094 ****************************************************************************/
1095 void setWanLinkStatus(int up)
1100 if ( (fd = fopen("/var/run/wanup", "a+")) != NULL )
1103 unlink("/var/run/wanup");
1106 /***************************************************************************
1107 // Function Name: disconnectPPP().
1108 // Description : if PPPD is alive, disconnet it.
1110 ****************************************************************************/
1111 void disconnectPPP(void)
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
1125 /***************************************************************************
1126 // Function Name: bcmSocketIfPid().
1127 // Description : return the socket if pid (== 0 is lan (br0), !=0 is wan)
1128 // Parameters : none.
1130 ****************************************************************************/
1131 int bcmSocketIfPid(void)
1133 char ifName[IFC_SMALL_LEN];
1135 char cmd[SYS_CMD_LEN];
1139 strncpy(ifName, getIfName(), IFC_SMALL_LEN - 1);
1140 if (ifName[0] == '\0')
1143 sprintf(cmd, "/proc/var/fyi/wan/%s/pid", ifName);
1144 if ((fs = fopen(cmd, "r")) != NULL)
1146 fgets(cmd, SYS_CMD_LEN, fs);
1156 /***************************************************************************
1157 // Function Name: bcmKillAllApps().
1158 // Description : kill all available applications.
1159 // Parameters : none.
1161 ****************************************************************************/
1162 void bcmKillAllApps(void) {
1163 // NOTE: Add the app name before NULL. Order is important
1166 #ifdef SUPPORT_TR69C
1190 char cmd[SYS_CMD_LEN], app[SYS_CMD_LEN], buf[SYS_CMD_LEN];
1191 char pidStr[SYS_CMD_LEN];
1196 int curPid = getpid();
1200 fs = fopen("/var/run/httpd_pid", "r");
1203 fgets(cmd, SYS_CMD_LEN, fs);
1204 httpdPid = atoi(cmd);
1209 printf("Error: httpd pid not found ?\n");
1213 bcmSystemMute("ps > /var/pslist");
1214 fs = fopen("/var/pslist", "r");
1217 bcmSystem("cat /var/pslist");
1219 socketPid = bcmSocketIfPid();
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)
1227 sprintf(cmd, "route add default dev %s", getIfName());
1233 if (curPid == httpdPid)
1236 bcmSystem("sysinfo");
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
1243 strcpy(app, apps[i]);
1244 while (fgets(buf, SYS_CMD_LEN, fs) > 0)
1246 if (strstr(buf, app) != NULL) // found command line with match app name
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"))))
1254 if (pid != curPid && pid != socketPid)
1256 printf("kill %s process...\n", app);
1257 sprintf(cmd, "kill -%d %d", 9, pid);
1262 rewind(fs); // start pslist over again
1263 } while (apps[++i] != NULL);
1266 bcmSystemMute("rm /var/pslist");
1267 bcmRemoveModules(socketPid);
1270 // function to support encryption password for login
1271 static int i64c(int i) {
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);
1285 // function to support encryption password for login
1286 static char *crypt_make_salt(void) {
1288 static unsigned long x;
1289 static char result[3];
1292 x += now + getpid() + clock();
1293 result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
1294 result[1] = i64c(((x >> 12) ^ x) & 077);
1299 // function to support encryption password for login
1300 static char *pw_encrypt(const char *clear, const char *salt) {
1301 static char cipher[128];
1304 #ifdef CONFIG_FEATURE_SHA1_PASSWORDS
1305 if (strncmp(salt, "$2$", 3) == 0) {
1306 return sha1_crypt(clear);
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;
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) {
1330 FILE *fsPwd = NULL, *fsGrp = NULL;
1332 fsPwd = fopen("/etc/passwd", "w");
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());
1341 pw.pw_gecos = "Administrator";
1343 pw.pw_shell = "/bin/sh";
1344 putpwent(&pw, fsPwd);
1346 pw.pw_name = "support";
1347 pw.pw_passwd = pw_encrypt(cp_support, crypt_make_salt());
1350 pw.pw_gecos = "Technical Support";
1352 pw.pw_shell = "/bin/sh";
1353 putpwent(&pw, fsPwd);
1355 pw.pw_name = "user";
1356 pw.pw_passwd = pw_encrypt(cp_user, crypt_make_salt());
1359 pw.pw_gecos = "Normal User";
1361 pw.pw_shell = "/bin/sh";
1362 putpwent(&pw, fsPwd);
1364 pw.pw_name = "nobody";
1365 pw.pw_passwd = pw_encrypt(cp_admin, crypt_make_salt());
1368 pw.pw_gecos = "nobody for ftp";
1370 pw.pw_shell = "/bin/sh";
1371 putpwent(&pw, fsPwd);
1374 fsGrp = fopen("/etc/group", "w");
1375 if ( fsGrp != NULL ) {
1376 fprintf(fsGrp, "root::0:root,admin,support,user\n");
1378 return FILE_OPEN_OK;
1382 return FILE_OPEN_ERR;
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");
1395 fprintf(fs, "%d\n", ipExt);
1397 return FILE_OPEN_OK;
1400 return FILE_OPEN_ERR;
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");
1414 fgets(str, len, fs);
1416 return FILE_OPEN_OK;
1419 return FILE_OPEN_ERR;
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) {
1433 if ( ifcName == NULL ) return -1;
1435 if ( (s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) return -1;
1437 strcpy(ifr.ifr_name, ifcName);
1438 if ( ioctl(s, SIOCGIFINDEX, &ifr) < 0 ) {
1445 return ifr.ifr_ifindex;
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) {
1457 if (bcmGetIfcIndexByName(ifcName))
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;
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");
1486 sprintf(ifcName, "wl0.%d", num);
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);
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";
1510 if( (fs = fopen("/var/ifcs", "r")) != NULL ) {
1511 while( fgets(str, sizeof(str), fs) != NULL ) {
1512 if( str[0] >= 'A' && str[0] <= 'z' ) {
1517 // Copy interface name (br0, eth0, pppoe_0_35, etc.) to local
1519 for(i = 0, p = str; i<sizeof(name)-1 && *p && *p!=' '; i++, p++)
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 ) {
1529 p += strlen("inet addr:");
1530 addr = inet_addr(p);
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 );
1544 unlink("/var/ifcs");
1550 /***************************************************************************
1551 // Function Name: bcmSetConnTrackMax.
1552 // Description : tune the connection track table size.
1553 // Parameters : 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");
1561 // init ip_conntrack_max
1562 if ( fs == NULL ) // ip_conntrack module is not loaded.
1565 fgets(cmd, SYS_CMD_LEN, fs);
1566 conntrack_max = atoi(cmd);
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;
1576 if ( conntrack_max < CONNTRACK_MUX ) {
1578 if ( conntrack_max > CONNTRACK_MUX )
1579 conntrack_max = CONNTRACK_MUX;
1582 sprintf(cmd, "echo \"%d\" > /proc/sys/net/ipv4/ip_conntrack_max", conntrack_max);
1586 /***************************************************************************
1587 // Function Name: bcmResetConnTrackTable.
1588 // Description : reset the connection track table.
1589 // Parameters : none.
1591 ****************************************************************************/
1592 void bcmResetConnTrackTable(void) {
1593 if ( bcmIsModuleInserted("ip_conntrack") == TRUE )
1594 bcmSystem("echo > /proc/net/ip_conntrack");
1597 /***************************************************************************
1598 // Function Name: bcmHandleConnTrack.
1599 // Description : handle the connection track table.
1600 // Parameters : none.
1602 ****************************************************************************/
1603 void bcmHandleConnTrack(void) {
1604 bcmResetConnTrackTable();
1605 bcmSetConnTrackMax();
1608 /***************************************************************************
1609 // Function Name: bcmInsertModules.
1610 // Description : insert all modules under the given path.
1611 // Parameters : path -- the given path.
1613 ****************************************************************************/
1614 void bcmInsertModules(char *path) {
1615 struct dirent *entry;
1619 if ( path == NULL ) return;
1621 dir = opendir(path);
1622 if ( dir == NULL ) return;
1624 while ( (entry = readdir(dir)) != NULL )
1625 if ( (cp = strstr(entry->d_name, ".ko")) != NULL ) {
1627 bcmInsertModule(entry->d_name);
1632 /***************************************************************************
1633 // Function Name: bcmInsertModule.
1634 // Description : insert module with the given name.
1635 // Parameters : modName -- the given module name.
1637 ****************************************************************************/
1638 void bcmInsertModule(char *modName) {
1639 char cmd[SYS_CMD_LEN], modulepath[SYS_CMD_LEN];
1640 struct utsname kernel;
1642 if (uname(&kernel) == -1)
1645 sprintf(modulepath, "/lib/modules/%s/kernel/net/ipv4/netfilter", kernel.release);
1647 if ( bcmIsModuleInserted(modName) == FALSE ) {
1648 sprintf(cmd, "insmod %s/%s.ko", modulepath,modName);
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;
1667 if ((access("/bin/iptables",F_OK)) != 0)
1670 // execute iptables command to create iptable file
1671 sprintf(line, "iptables -t %s -L %s -v --line-numbers > /var/iptable",
1673 bcmSystemNoHang(line);
1675 fs = fopen("/var/iptable", "r");
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);
1698 // codes to remove iptable file is moved to bcmRemoveAllIpTableRules() function
1703 /***************************************************************************
1704 // Function Name: bcmRemoveAllIpTableRules().
1705 // Description : remove all IP table rules attach with the given device.
1706 // Parameters : device -- interface name.
1708 ****************************************************************************/
1709 void bcmRemoveAllIpTableRules(char *device) {
1712 if ( bcmIsModuleInserted("iptable_filter") == TRUE ) {
1713 while ( bcmRemoveIpTableRule(device, "filter", "INPUT") == TRUE )
1716 while ( bcmRemoveIpTableRule(device, "filter", "FORWARD") == TRUE )
1719 while ( bcmRemoveIpTableRule(device, "filter", "OUTPUT") == TRUE )
1723 if ( bcmIsModuleInserted("iptable_nat") == TRUE ) {
1724 while ( bcmRemoveIpTableRule(device, "nat", "PREROUTING") == TRUE )
1726 /* We should keep the masquerading rules
1727 while ( bcmRemoveIpTableRule(device, "nat", "POSTROUTING") == TRUE )
1731 while ( bcmRemoveIpTableRule(device, "nat", "OUTPUT") == TRUE )
1735 // remove iptable file
1736 fs = fopen("/var/iptable", "r");
1739 unlink("/var/iptable");
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;
1755 if ((access("/bin/iptables",F_OK)) != 0)
1758 // execute iptables command to create iptable file
1759 sprintf(line, "iptables -L INPUT -v --line-numbers > /var/iptable");
1760 bcmSystemMute(line);
1762 fs = fopen("/var/iptable", "r");
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);
1784 // remove iptable file
1785 unlink("/var/iptable");
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;
1803 if ((access("/bin/iptables",F_OK)) != 0)
1806 // execute iptables command to create iptable file
1807 sprintf(line, "iptables -L OUTPUT -v --line-numbers > /var/iptable");
1808 bcmSystemMute(line);
1810 fs = fopen("/var/iptable", "r");
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);
1832 // remove iptable file
1833 unlink("/var/iptable");
1839 /***************************************************************************
1840 // Function Name: bcmInsertAllUpnpIpTableRules().
1841 // Description : insert UPnP IP table rules.
1842 // Parameters : none.
1844 ****************************************************************************/
1845 void bcmInsertAllUpnpIpTableRules(void) {
1846 char interface[IFC_TINY_LEN], cmd[IFC_LARGE_LEN];
1848 WAN_CON_INFO wanInfo;
1850 // init wanId to get WAN info from the begining
1851 wanId.vpi = wanId.vci = wanId.conId = 0;
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);
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);
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;
1886 if ((access("/bin/ebtables",F_OK)) != 0)
1889 // execute iptables command to create iptable file
1890 sprintf(line, "ebtables -t %s -L %s --Ln > /var/ebtable", table, chain);
1891 bcmSystemMute(line);
1893 fs = fopen("/var/ebtable", "r");
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);
1911 // code to remove ebtable file is moved to bcmRemoveAllEbTableRules() function
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.
1923 ****************************************************************************/
1924 void bcmRemoveAllEbTableRules(char *device) {
1925 // while ( bcmRemoveEbTableRule(device, "filter", "INPUT") == TRUE )
1928 while ( bcmRemoveEbTableRule(device, "filter", "FORWARD") == TRUE )
1931 // while ( bcmRemoveEbTableRule(device, "filter", "OUTPUT") == TRUE )
1934 // remove ebtable file
1935 unlink("/var/ebtable");
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.
1944 ****************************************************************************/
1945 void bcmGetDefaultRouteInterfaceName(char *ifcName) {
1946 char col[11][IFC_SMALL_LEN];
1947 char line[IFC_GIANT_LEN];
1950 if ( ifcName == NULL ) return;
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]);
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.
1981 //***************************************************************************/
1982 void parseStrInfo(char *info, char *var, char *val, int len) {
1986 if ( info == NULL || var == NULL || val == NULL ) return;
1988 pChar = strstr(info, var);
1989 if ( pChar == NULL ) return;
1991 // move pass the variable string in line
1992 pChar += strlen(var);
1994 // Remove spaces from beginning of value string
1995 while ( *pChar != '\0' && isspace((int)*pChar) != 0 )
1998 // get data until end of line, or space char
2000 i < len && *pChar != '\0' &&
2001 isspace((int)*pChar) == 0;
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.
2016 //**************************************************************************
2017 void bcmConvertStrToShellStr(char *str, char *buf) {
2018 if ( buf == NULL ) return;
2020 int len = strlen(str);
2024 for ( i = 0; i < len; i++ ) {
2025 if ( isalnum(str[i]) )
2028 buf[j++] = ( escp = (str[i] == '\'' ? '"':'\'') );
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.
2043 //**************************************************************************
2044 void bcmProcessMarkStrChars(char *str) {
2045 if ( str == NULL ) return;
2046 if ( str[0] == '\0' ) return;
2048 char buf[SYS_CMD_LEN];
2049 int len = strlen(str);
2052 for ( i = 0; i < len; i++ ) {
2053 if ( bcmIsMarkStrChar(str[i]) == TRUE )
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);
2076 for ( i = 0; i < len; i++ )
2077 if ( c == specChars[i] )
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.
2094 //**************************************************************************
2095 void bcmSetVdslSwVer(char *swVer)
2097 if ( swVer == NULL ) return;
2099 if ( strlen(swVer) < SYS_CMD_LEN - 1 )
2100 strcpy(glbVdslSwVer, swVer);
2102 strncpy(glbVdslSwVer, swVer, SYS_CMD_LEN - 2);
2103 glbVdslSwVer[SYS_CMD_LEN - 1] = '\0';
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.
2114 //**************************************************************************
2115 void bcmGetSwVer(char *swVer, int size) {
2116 char version[SYS_CMD_LEN], adslPhyVersion[SYS_CMD_LEN];
2118 if ( swVer == NULL ) return;
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);
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.
2134 //**************************************************************************
2135 void bcmGetBuildVer(char *swVer, int size) {
2137 const char verFormat[IFC_SMALL_LEN] = {"0.00L.00.00"};
2138 char* tagVersion = BCM_SIG_2 + 5;
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
2146 if( (size - strlen(swVer)) > 12 )
2147 strcat(swVer, "-Beta 6");
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.
2158 //**************************************************************************
2159 void bcmGetVdslSwVer(char *swVer, int size) {
2160 if ( swVer == NULL ) return;
2162 if ( strlen(glbVdslSwVer) < size - 1 )
2163 strcpy(swVer, glbVdslSwVer);
2165 strncpy(swVer, glbVdslSwVer, size - 2);
2166 swVer[size - 1] = '\0';
2171 //**************************************************************************
2172 // Function Name: bcmcheck_enable
2173 // Description : check the appName with ip address against the psi
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)
2181 // is client address in Access Control List ?
2182 if ( BcmScm_isInAccessControlList(inet_ntoa(clntAddr)) == FALSE )
2183 return CLI_ACCESS_DISABLED;
2185 if ( isAccessFromLan(clntAddr) == TRUE ) {
2186 // is enabled from lan ?
2187 if ( BcmScm_isServiceEnabled(appName, CLI_ACCESS_LOCAL) == FALSE )
2188 return CLI_ACCESS_DISABLED;
2190 return CLI_ACCESS_LOCAL;
2192 // is enabled from wan ?
2193 if ( BcmScm_isServiceEnabled(appName, CLI_ACCESS_REMOTE) == FALSE )
2194 return CLI_ACCESS_DISABLED;
2196 return CLI_ACCESS_REMOTE;
2200 int bcmWanEnetQuerySwitch(char *ifName) {
2202 char cmd[IFC_LARGE_LEN];
2203 char str[IFC_LARGE_LEN];
2206 sprintf(cmd, "vconfig query %s 2 2>/var/vcfgerr\n", ifName);
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);
2214 bcmSystem("rm /var/vcfgerr");
2219 #endif // USE_ALL, code below this code can be linked with other apps
2222 //*********** code shared by ftpd and tftpd **********************
2223 //****************************************************************
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) {
2233 char buf[SYS_CMD_LEN];
2234 FILE* fs = fopen("/proc/modules", "r");
2237 while ( fgets(buf, SYS_CMD_LEN, fs) > 0 )
2238 if ( strstr(buf, modName) != NULL ) {
2249 /***************************************************************************
2250 // Function Name: bcmCheckInterfaceUp().
2251 // Description : check status of interface.
2252 // Parameters : devname - name of device.
2253 // Returns : 1 - UP.
2255 ****************************************************************************/
2256 int bcmCheckInterfaceUp(char *devname) {
2261 if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2265 strcpy(intf.ifr_name, devname);
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) {
2276 // if interface flag is down then return down
2277 if (ioctl(skfd, SIOCGIFFLAGS, &intf) == -1) {
2280 if ( (intf.ifr_flags & IFF_UP) != 0)
2291 //If we don't link with busybox, we need this function
2292 #ifndef BUILD_STATIC
2294 static void remove_delimitor( char *s)
2299 while ( *p1 != '\0' || *(p1+1) != '\0') {
2309 /* find_pid_by_name()
2311 * This finds the pid of the specified process.
2312 * Currently, it's implemented by rummaging through
2313 * the proc filesystem.
2315 * Returns a list of all matching PIDs
2317 static pid_t* find_pid_by_name( char* pidName)
2320 struct dirent *next;
2321 pid_t* pidList=NULL;
2326 char filename[READ_BUF_SIZE];
2327 char buffer[READ_BUF_SIZE];
2328 /* char name[READ_BUF_SIZE]; */
2330 dir = opendir("/proc");
2332 printf("cfm:Cannot open /proc");
2336 while ((next = readdir(dir)) != NULL) {
2337 /* re-initialize buffers */
2338 memset(filename, 0, sizeof(filename));
2339 memset(buffer, 0, sizeof(buffer));
2341 /* Must skip ".." since that is outside /proc */
2342 if (strcmp(next->d_name, "..") == 0)
2345 /* If it isn't a number, we don't want it */
2346 if (!isdigit(*next->d_name))
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")) ) {
2355 if (fgets(buffer, READ_BUF_SIZE-1, cmdline) == NULL) {
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));
2368 printf("cfm: Out of memeory!\n");
2372 pidList[i++]=strtol(next->d_name, NULL, 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));
2385 printf("cfm: Out of memeory!\n");
2390 pidList=realloc( pidList, sizeof(pid_t));
2392 printf("cfm: Out of memeory!\n");
2402 void bcmHidePassword(char *command) {
2407 /* pppd -i ..... -p password */
2408 if ((ptr = strstr(command,"pppd")) != NULL) {
2409 if (!strstr(ptr, "-p"))
2411 begin = strstr(ptr,"-p") + 3;
2412 end = strchr(begin,' ');
2414 len = strlen(begin);
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;
2450 printf("app: %s\r\n", command);
2453 if ((newCommand = strdup(command)) != NULL) {
2454 bcmHidePassword(newCommand);
2455 syslog(LOG_DEBUG, newCommand);
2459 execve("/bin/sh", argv, environ);
2463 /* wait for child process return */
2465 if ( waitpid(pid, &status, 0) == -1 ) {
2466 if ( errno != EINTR )
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)
2484 char cmdline[128], *p1, *p2;
2490 while ( *p1 != '\0') {
2499 pid = find_pid_by_name(cmdline);
2500 if ( pid != NULL ) {
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)
2517 char cmdline[128], *p1, *p2;
2522 while ( *p1 != '\0') {
2531 pid = find_pid_by_name(cmdline);
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)
2545 int numifs = 0, bufsize = 0;
2546 struct ifreq *all_ifr = NULL;
2548 struct sockaddr local_addr;
2549 socklen_t local_len = sizeof(struct sockaddr_in);
2551 memset(&ifc, 0, sizeof(struct ifconf));
2552 memset(&local_addr, 0, sizeof(struct sockaddr));
2554 if (getsockname(socketfd, &local_addr,&local_len) < 0) {
2555 printf("bcmGetIntfNameSocket: Error in getsockname!\n");
2559 //printf("bcmGetIntfNameSocket: Session comes from: %s\n",inet_ntoa(((struct sockaddr_in *)&local_addr)->sin_addr));
2561 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2562 printf("bcmGetIntfNameSocket: Error openning socket when getting socket intface info\n");
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");
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");
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);
2604 static int getLanInfo(char *lan_ifname, struct in_addr *lan_ip, struct in_addr *lan_subnetmask)
2609 if ((socketfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2610 printf("app: Error openning socket when getting LAN info\n");
2614 strcpy(lan.ifr_name,lan_ifname);
2615 if (ioctl(socketfd,SIOCGIFADDR,&lan) < 0) {
2616 printf("app: Error getting LAN IP address\n");
2620 *lan_ip = ((struct sockaddr_in *)&(lan.ifr_addr))->sin_addr;
2622 if (ioctl(socketfd,SIOCGIFNETMASK,&lan) < 0) {
2623 printf("app: Error getting LAN subnet address\n");
2628 *lan_subnetmask = ((struct sockaddr_in *)&(lan.ifr_netmask))->sin_addr;
2634 static int isIpExtension(void)
2637 int ipextension = 0;
2639 if ((fp=fopen("/var/ipextension","r")) != NULL) {
2640 fscanf(fp,"%d",&ipextension);
2647 static void getIpExtIp(char *buf)
2650 char wan[64], gateway[64], dns[64], str[256];
2652 if ( buf == NULL ) return;
2655 fs = fopen("/var/ipextinfo", "r");
2657 fgets(str, 256, fs);
2659 sscanf(str, "%s %s %s\n", wan, gateway, dns);
2664 int isAccessFromLan(struct in_addr clntAddr)
2667 struct in_addr inAddr, inMask;
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) )
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) )
2682 /* Last option it must be from WAN side */
2683 if (isIpExtension()) {
2685 if ( clntAddr.s_addr == inet_addr(wan) )
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)
2698 unsigned int chipId = (int) sysGetChipId();
2701 tagChipId = strtol(strTagChipId, NULL, 16);
2703 if (tagChipId == chipId)
2706 printf("Chip Id error. Image Chip Id = %04x, Board Chip Id = %04x.\n", tagChipId, chipId);
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)
2726 if (bcmIsModuleInserted("iptable_nat") == FALSE)
2729 bcmSystem("iptables -t nat -L > /var/nat_redirect");
2731 fs = fopen("/var/nat_redirect", "r");
2733 while ( fgets(line, sizeof(line), fs) ) {
2734 // read pass 3 header lines
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) {
2748 unlink("/var/nat_redirect");
2752 /***************************************************************************
2753 // Function Name: bcmRemoveModules(int lanIf)
2754 // Description : remove not used modules to free memory.
2755 // Parameters : none
2757 ****************************************************************************/
2758 void bcmRemoveModules(int lanIf)
2781 "ip_conntrack_tftp",
2784 "ip_conntrack_h323",
2785 "ip_conntrack_pptp",
2787 "ip_conntrack_rtsp",
2788 "ip_conntrack_ipsec",
2797 char cmd[SYS_CMD_LEN];
2799 int saveNat = FALSE;
2801 if (lanIf == 0) // if lan, do not kill bcm_usb and bcm_enet
2803 else // if in ipow mode, leave bcm_enet out
2805 FILE *fs = fopen("/proc/var/fyi/wan/eth0/pid", "r");
2813 saveNat = bcmCheckForRedirect();
2814 if (bcmIsModuleInserted("iptable_filter") == TRUE)
2816 strncpy(cmd, "iptables -t filter -F", SYS_CMD_LEN-1);
2819 if (bcmIsModuleInserted("iptable_nat") == TRUE)
2821 strncpy(cmd, "iptables -t nat -F", SYS_CMD_LEN-1);
2824 if (bcmIsModuleInserted("iptable_mangle") == TRUE)
2826 strncpy(cmd, "iptables -t mangle -F", SYS_CMD_LEN-1);
2830 while (modList[i] != NULL)
2832 if (bcmIsModuleInserted(modList[i]) == TRUE)
2834 if (!(saveNat && strcmp(modList[i], "iptable_nat") == 0))
2836 sprintf(cmd, "rmmod %s", modList[i]);
2842 printf("\nRemaining modules:\n");
2843 bcmSystemMute("cat /proc/modules");
2844 printf("\nMemory info:\n");
2845 bcmSystemMute("sysinfo");
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) {
2860 if ( ifcName == NULL ) return -1;
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 ) {
2869 return ifr.ifr_ifindex;
2872 int bcmWaitIntfExists(char *ifName) {
2876 while (retry < 50) {
2877 if ((ret =bcmGetIntf(ifName)) <= 0) {
2879 //printf("not exist,retry %d, ret %d\n",retry,ret);
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;
2901 if ( macAddr == NULL ) return FALSE;
2902 if ( str == NULL ) return FALSE;
2904 len = strlen(str) + 1;
2907 buf = (char*)malloc(len);
2910 if ( buf == NULL ) return FALSE;
2912 /* need to copy since strtok_r updates string */
2913 strncpy(buf, str,len-1);
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);
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;
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]);
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 )
2959 if( (nFd = open("/dev/bcmatm0", O_RDWR)) < 0 )
2960 printf( "OpenBlaaDD : open error %d\n", errno );
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)
2976 MirrorCfg *pMirrorCfg = (MirrorCfg *) pCfg ;
2979 #ifdef PORTMIRROR_DEBUG
2980 printf ("ENGDBG:- In BcmConfigPortMirroring \n") ;
2983 if ((fd = OpenBlaaDD ()) < 0) {
2984 printf ("Config Port Mirroring Failed \n") ;
2988 if (ioctl(fd, ATMIOCTL_PORT_MIRRORING, pMirrorCfg) < 0) {
2990 printf("IOCTL to BLAA Drive for Port Mirror CFG failed . Fatal \n") ;
3001 /***************************************************************************
3002 // Function Name: bcmRemoveTrafficControlRules.
3003 // Description : remove tc rules for this interface if QoS is enabled.
3005 ****************************************************************************/
3006 void bcmRemoveTrafficControlRules(UINT16 vpi, UINT16 vci, UINT16 conId, UINT8 protocol) {
3008 char cmd[SYS_CMD_LEN];
3010 if (protocol != PROTO_PPPOA) {
3015 snprintf(ifc, 16, "ppp_%d_%d_%d", vpi, vci, conId);
3016 sprintf(cmd, "tc qdisc del dev %s root", ifc);
3020 /***************************************************************************
3021 // Function Name: bcmAddTrafficControlRules.
3022 // Description : add tc rules for this interface if QoS is enabled.
3024 ****************************************************************************/
3025 void bcmAddTrafficControlRules(UINT16 vpi, UINT16 vci, UINT16 conId, UINT8 protocol) {
3027 char cmd[SYS_CMD_LEN];
3028 ADSL_CONNECTION_INFO adslInfo;
3031 if (protocol != PROTO_PPPOA) {
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) {
3042 if ( adslInfo.ulInterleavedUpStreamRate != 0 )
3043 lineRate = adslInfo.ulInterleavedUpStreamRate;
3045 lineRate = adslInfo.ulFastUpStreamRate;
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);
3052 // Create the root. This also creates the classes 1:1, 1:2 and 1:3
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",
3078 bcmSystemNoHang(cmd);
3081 /* this function stores device into procfs file for other processes to access */
3082 void bcmStoreDeviceInfoToProcFile(void)
3086 PBcmCfm_DevInfoCfg_t pDevInfo = NULL;
3088 bcmSystemMute("mkdir -p /var/fyi/sys");
3089 bcmSystemMute("echo > /var/fyi/sys/info");
3090 fs = fopen("/var/fyi/sys/info", "w+");
3093 /* SerialNumber %s */
3094 /* ProductClass %s */
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);