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"
65 #include "portMirror.h"
66 #include "atmapidrv.h"
71 #include "board_api.h"
74 #define PRIORITY_HIGH 3
75 #define PRIORITY_MEDIUM 2
76 #define PRIORITY_LOW 1
82 extern char **environ;
83 extern char *getIfName(void);
85 #define READ_BUF_SIZE 128
86 #define CONNTRACK_MUX 2000
88 /* If you change this definition, make sure you change it everywhere */
89 #define UDHCPD_DECLINE "/var/udhcpd.decline"
93 /***************************************************************************
94 // Function Name: bcmSystemNoHang().
95 // Description : launch shell command in the child process without hang.
96 // Parameters : command - shell command to launch.
97 // Returns : status 0 - OK, -1 - ERROR.
98 ****************************************************************************/
99 int bcmSystemNoHang (char *command) {
100 int pid = 0, status = 0, counter = 0, ret = 0;
115 execve("/bin/sh", argv, environ);
120 // check the child is exited or not without hang
121 ret = waitpid(pid, &status, WNOHANG | WUNTRACED);
123 case -1: // error occurs then return -1
125 case 0: // child does not exited yet
127 if ( ++counter > 19 ) {
129 printf("app: child process cannot exits while executing command - %s\n", command);
135 default: // child does exit successfully
143 /***************************************************************************
144 // Function Name: bcmCreateDhcpCfg().
145 // Description : create DHCP server configuration file.
146 // Parameters : ipAddr - IP address of target.
147 // mask - subnet mask of target.
148 // addrStart - start IP address of DHCP server pool.
149 // addrEnd - end IP address of DHCP server pool.
150 // dns1 - primary dns.
151 // dns2 - secondary dns.
152 // leasedTime - leased time.
153 // protoInfo - current network protocol.
154 // enblNat -- is nat enabled?
155 // enblFirewall -- is firewall enabled?
156 // Returns : status 0 - OK, -1 - ERROR.
157 ****************************************************************************/
158 int bcmCreateDhcpCfg(char *ipAddr, char *mask,
159 char *addrStart, char *addrEnd,
160 char *dns1, char *dns2, int leasedTime,
161 int protocol, int enblNat, int enblFirewall) {
162 FILE* fs = fopen("/etc/udhcpd.conf", "w");
167 sprintf(cmd, "echo %s > /var/run/ip", addrStart);
171 sprintf(cmd, "start %s\n", addrStart);
175 sprintf(cmd, "end %s\n", addrEnd);
179 switch ( protocol ) {
188 fputs("interface br0\n", fs);
192 // If you change the name of this file, make sure you change it
193 // everywhere by searching for UDHCPD_DECLINE macro
194 sprintf(cmd, "decline_file %s\n", UDHCPD_DECLINE);
198 sprintf(cmd, "option lease %d\n", leasedTime);
200 sprintf(cmd, "option min_lease 30\n");
204 sprintf(cmd, "option subnet %s\n", mask);
208 sprintf(cmd, "option router %s\n", ipAddr);
211 // use DNS relay only when NAT is enabled
212 if ( enblNat == TRUE ) {
213 // always use DSL router IP address as DNS
214 // for DHCP server since we want local PCs
215 // use DHCP server relay. The real DNS is
216 // stored in /etc/resolv.conf
217 sprintf(cmd, "option dns %s\n", ipAddr);
219 } else { // use real DNS when NAT is disabled
221 if ( strcmp(dns1, "0.0.0.0") != 0 )
222 sprintf(cmd, "option dns %s\n", dns1);
224 sprintf(cmd, "option dns %s\n", ipAddr);
227 if ( strcmp(dns2, "0.0.0.0") != 0 )
228 sprintf(cmd, "option dns %s\n", dns2);
230 sprintf(cmd, "option dns %s\n", ipAddr);
238 return FILE_OPEN_ERR;
241 /***************************************************************************
242 // Function Name: bcmCreateIpExtDhcpCfg().
243 // Description : create DHCP server configuration file for PPP IP Extenstion.
244 // Parameters : lanAddr - LAN IP address of target.
245 // mask - subnet mask of target.
246 // wanAddr - WAN IP address.
247 // Returns : status 0 - OK, -1 - ERROR.
248 ****************************************************************************/
249 int bcmCreateIpExtDhcpCfg(char *lanAddr, char *mask, char *wanAddr) {
250 char cmd[SYS_CMD_LEN], dns[SYS_CMD_LEN];
251 FILE* fs = fopen("/etc/udhcpd.conf", "w");
255 sprintf(cmd, "echo %s > /var/run/ip", wanAddr);
260 sprintf(cmd, "start %s\n", wanAddr);
264 sprintf(cmd, "end %s\n", wanAddr);
268 fputs("interface br0\n", fs);
271 fputs("option lease 30\n", fs);
272 fputs("option min_lease 30\n", fs);
275 sprintf(cmd, "option subnet %s\n", mask);
279 sprintf(cmd, "option router %s\n", wanAddr);
282 // don't use DNS relay since there is no ip table for
285 sprintf(cmd, "option dns %s\n", dns);
292 return FILE_OPEN_ERR;
295 /***************************************************************************
296 // Function Name: bcmSetIpExtInfo().
297 // Description : store wan, gateway, and dns for PPP IP extension.
298 // Parameters : wan - WAN IP address.
299 // gateway - default gateway.
301 // Returns : status 0 - OK, -1 - ERROR.
302 ****************************************************************************/
303 int bcmSetIpExtInfo(char *wan, char *gateway, char *dns) {
305 FILE* fs = fopen("/var/ipextinfo", "w");
308 sprintf(str, "%s %s %s\n", wan, gateway, dns);
314 return FILE_OPEN_ERR;
317 /***************************************************************************
318 // Function Name: bcmGetIpExtInfo().
319 // Description : get wan, gateway, or dns for PPP IP extension.
320 // Parameters : buf - .
323 ****************************************************************************/
324 void bcmGetIpExtInfo(char *buf, int type) {
326 char wan[64], gateway[64], dns[64], str[256];
328 if ( buf == NULL ) return;
331 if( bcmGetAdslStatus() == MNTR_STS_OK ) {
332 fs = fopen("/var/ipextinfo", "r");
336 sscanf(str, "%s %s %s\n", wan, gateway, dns);
339 if( dns[0] >= '0' && dns[0] <= '9' )
343 if( dns[0] >= '0' && dns[0] <= '9' )
344 strcpy(buf, gateway);
347 if( dns[0] >= '0' && dns[0] <= '9' )
355 /***************************************************************************
356 // Function Name: bcmCreateLocalDhcpCfg().
357 // Description : create DHCP server configuration file with default local.
358 // Parameters : ipAddr -- default local IP address.
359 // mask -- default local subnet mask.
360 // Returns : status 0 - OK, -1 - ERROR.
361 ****************************************************************************/
362 int bcmCreateLocalDhcpCfg(char *ipAddr, char *mask) {
363 FILE* fs = fopen("/etc/udhcpd.conf", "w");
364 char cmd[SYS_CMD_LEN], nextAddr[SYS_CMD_LEN];
368 addr.s_addr = inet_addr(ipAddr) + 1;
369 strcpy(nextAddr, inet_ntoa(addr));
371 sprintf(cmd, "echo %s > /var/run/ip", nextAddr);
375 fprintf(fs, "start %s\n", nextAddr);
378 fprintf(fs, "end %s\n", nextAddr);
381 fputs("interface br0\n", fs);
384 fputs("option lease 10\n", fs);
385 fputs("option min_lease 10\n", fs);
388 fprintf(fs, "option subnet %s\n", mask);
391 fprintf(fs, "option router %s\n", ipAddr);
394 fprintf(fs, "option dns %s\n", ipAddr);
400 return FILE_OPEN_ERR;
403 /***************************************************************************
404 // Function Name: bcmCreateResolvCfg().
405 // Description : create resolv configuration file.
406 // Parameters : dns1 - primary dns.
407 // dns2 - secondary dns.
408 // Returns : status 0 - OK, -1 - ERROR.
409 ****************************************************************************/
410 int bcmCreateResolvCfg(char *dns1, char *dns2) {
411 char cmd[SYS_CMD_LEN];
414 bcmSystemMute("mkdir -p /var/fyi/sys");
415 bcmSystemMute("echo > /var/fyi/sys/dns");
416 fs = fopen("/var/fyi/sys/dns", "w");
419 sprintf(cmd, "nameserver %s\n", dns1);
421 sprintf(cmd, "nameserver %s\n", dns2);
427 return FILE_OPEN_ERR;
430 // global ADSL info variable is declared here (in syscall.c)
431 // and is used in syscall.c, sysdiag.c, cgimain.c, and cgists.c
432 ADSL_CONNECTION_INFO glbAdslInfo;
434 /***************************************************************************
435 // Function Name: bcmGetAdslStatus().
436 // Description : get ADSL status.
438 // Returns : 0 - ADSL link Up (OK)
439 // 1 - ADSL link Down
441 ****************************************************************************/
442 int bcmGetAdslStatus() {
445 if (BcmAdslCtl_GetConnectionInfo(&glbAdslInfo) != BCMADSL_STATUS_ERROR) {
446 ret = glbAdslInfo.LinkState;
447 // if ( glbAdslInfo.LinkState == BCM_ADSL_LINK_UP )
448 // ret = ADSL_LINK_UP;
450 // ret = ADSL_LINK_DOWN;
452 ret = BCMADSL_STATUS_ERROR;
457 /***************************************************************************
458 // Function Name: bcmGetPppStatus().
459 // Description : get PPP status.
460 // Parameters : str - buffer to retrieve message
461 // len - length of buffer
464 ****************************************************************************/
465 int bcmGetPppStatus(char *str, int len, char *name) {
469 sprintf(filePath,"/proc/var/fyi/wan/%s/daemonstatus",name);
470 fs = fopen(filePath, "r");
477 return FILE_OPEN_ERR;
480 /***************************************************************************
481 // Function Name: bcmGetDhcpcStatus().
482 // Description : get DHCPC status.
483 // Parameters : str - buffer to retrieve message
484 // len - length of buffer
487 ****************************************************************************/
488 int bcmGetDhcpcStatus(char *str, int len) {
489 FILE* fs = fopen("/var/run/dhcpc", "r");
497 return FILE_OPEN_ERR;
500 /***************************************************************************
501 // Function Name: bcmGetSystemStatus().
502 // Description : get system status.
503 // Parameters : str - buffer to retrieve message
504 // len - length of buffer
507 ****************************************************************************/
508 int bcmGetSystemStatus(char *str, int len) {
509 FILE* fs = fopen("/etc/sysmsg", "r");
517 return FILE_OPEN_ERR;
520 /***************************************************************************
521 // Function Name: bcmSetSystemStatus().
522 // Description : set system status.
523 // Parameters : int - system status
526 ****************************************************************************/
527 int bcmSetSystemStatus(int status) {
528 char cmd[SYS_CMD_LEN];
529 FILE* fs = fopen("/etc/sysmsg", "w");
532 sprintf(cmd, "%d\n", status);
538 return FILE_OPEN_ERR;
541 /***************************************************************************
542 // Function Name: bcmDisplayLed().
543 // Description : display LED corresponding to WAN link status.
544 // Parameters : status - WAN link status.
546 ****************************************************************************/
547 void bcmDisplayLed(int status) {
549 case MNTR_STS_ADSL_DOWN:
550 /* this means ADSL is DOWN */
551 sysLedCtrl(kLedPPP, kLedStateOff);
553 case MNTR_STS_ADSL_TRAINING:
554 /* this means ADSL is TRAINING */
555 sysLedCtrl(kLedPPP, kLedStateOff);
557 case MNTR_STS_PPP_AUTH_ERR:
558 //sysLedCtrl(kLedPPP, kLedStateFail);
559 sysLedCtrl(kLedPPP, kLedStateOff); // USR9108
561 case MNTR_STS_PPP_DOWN:
562 /* this means ADSL is UP, but not PPP */
563 //sysLedCtrl(kLedPPP, kLedStateFail);
564 sysLedCtrl(kLedPPP, kLedStateOff); // USR9108
567 /* this means ADSL and PPP are up */
568 // sysLedCtrl(kLedPPP, kLedStateOn); // USR9108 Not yet!
573 void bcmGetDynamicDnsAddr(char *dns, int primary) {
574 char str[SYS_CMD_LEN];
577 fs = fopen("/var/fyi/sys/dns", "r");
579 if ( fgets(str, SYS_CMD_LEN, fs) > 0 ) {
581 sscanf(str, "nameserver %s\n", dns);
583 if ( fgets(str, SYS_CMD_LEN, fs) > 0 )
584 sscanf(str, "nameserver %s\n", dns);
590 // if cannot find primary dns info then
591 // assign default value which is router IP address
592 bcmGetIfDestAddr("br0", dns);
595 /***************************************************************************
596 // Function Name: bcmGetDns().
597 // Description : get DSN info.
598 // Parameters : dns - buffer to retrieve primary dns.
600 ****************************************************************************/
601 void bcmGetDns(char *dns) {
602 IFC_DNS_INFO dnsInfo;
605 if ( ((BcmDb_getDnsInfo(&dnsInfo) == DB_GET_OK) && (dnsInfo.dynamic)) ||
606 (BcmDb_getDnsInfo(&dnsInfo) != DB_GET_OK) ) {
607 if (dnsInfo.dynamic) {
608 bcmGetDynamicDnsAddr(dns,BCM_PRIMARY_DNS);
613 if ( dnsInfo.preferredDns.s_addr != INADDR_NONE )
614 strcpy(dns, inet_ntoa(dnsInfo.preferredDns));
618 /***************************************************************************
619 // Function Name: bcmGetDns2().
620 // Description : get DSN info.
621 // Parameters : dns - buffer to retrieve primary dns.
623 ****************************************************************************/
624 void bcmGetDns2(char *dns) {
625 IFC_DNS_INFO dnsInfo;
628 if ( ((BcmDb_getDnsInfo(&dnsInfo) == DB_GET_OK) && (dnsInfo.dynamic)) ||
629 (BcmDb_getDnsInfo(&dnsInfo) != DB_GET_OK) ) {
630 if (dnsInfo.dynamic) {
631 bcmGetDynamicDnsAddr(dns, BCM_SECONDARY_DNS);
636 if ( dnsInfo.alternateDns.s_addr != INADDR_NONE )
637 strcpy(dns, inet_ntoa(dnsInfo.alternateDns));
641 void bcmGetDnsSettings(int *mode, char *primary, char *secondary)
643 IFC_DNS_INFO dnsInfo;
646 if (BcmDb_getDnsInfo(&dnsInfo) == DB_GET_OK) {
647 *mode = dnsInfo.dynamic;
650 bcmGetDns2(secondary);
653 /***************************************************************************
654 // Function Name: bcmRestartDnsProbe().
655 // Description : start DNS probe.
656 // Parameters : none.
658 ****************************************************************************/
659 void bcmRestartDnsProbe(void) {
660 char cmd[CLI_MAX_BUF_SZ];
662 // kill the old dnsprobe if it is existed
663 int pid = bcmGetPid("/bin/dnsprobe");
665 sprintf(cmd, "kill -9 %d", pid);
669 // start the new dnsprobe
670 bcmSystem("/bin/dnsprobe &");
673 /***************************************************************************
674 // Function Name: bcmConfigDns().
675 // Description : add or remove DNS info to PSI.
676 // Parameters : primary and secondary DNS.
678 ****************************************************************************/
679 void bcmConfigDns(char *dns1, char *dns2, int dynamic) {
680 char cmd[CLI_MAX_BUF_SZ], addr[CLI_MAX_BUF_SZ], buf[CLI_MAX_BUF_SZ];
681 IFC_DNS_INFO dnsInfo;
683 // get local ip address
684 bcmGetIfDestAddr("br0", addr);
686 // if user changes from static to auto assgined dns
688 if ( BcmDb_getDnsInfo(&dnsInfo) == DB_GET_OK &&
689 bcmIsModuleInserted("iptable_nat") == TRUE ) {
690 strcpy(buf, inet_ntoa(dnsInfo.preferredDns));
692 sprintf(cmd, "iptables -t nat -D PREROUTING -i br0 -d %s -p udp --dport 53 -j DNAT --to %s 2>/dev/null", addr, buf);
694 // remove old resolve configuration file
695 FILE * fs = fopen("/var/fyi/sys/dns", "r");
698 bcmSystemMute("rm /var/fyi/sys/dns");
702 // create the new resolv.conf with new dsn info
703 bcmCreateResolvCfg(dns1, dns2);
706 if ( buf[0] != '\0' ) {
707 if (strcmp(buf, dns1) != 0) {
708 if ( bcmIsModuleInserted("iptable_nat") == TRUE ) {
710 sprintf(cmd, "iptables -t nat -D PREROUTING -i br0 -d %s -p udp --dport 53 -j DNAT --to %s 2>/dev/null", addr, buf);
712 // add new DNS Forwarding rule
713 sprintf(cmd, "iptables -t nat -A PREROUTING -i br0 -d %s -p udp --dport 53 -j DNAT --to %s", addr, dns1);
715 bcmRestartDnsProbe();
719 printf("No Existing DNS information from DSL router\n");
720 sprintf(cmd, "iptables -t nat -A PREROUTING -i br0 -d %s -p udp --dport 53 -j DNAT --to %s", addr, dns1);
725 // if old dns2 differs with new one, restart dnsprobe
726 if (strcmp(buf, dns2) != 0) {
727 if ( bcmIsModuleInserted("iptable_nat") == TRUE )
728 bcmRestartDnsProbe();
730 dnsInfo.preferredDns.s_addr = inet_addr(dns1);
731 dnsInfo.alternateDns.s_addr = inet_addr(dns2);
732 } /* dynamic to static */
733 dnsInfo.dynamic = dynamic;
734 BcmDb_setDnsInfo(&dnsInfo);
738 /***************************************************************************
739 // Function Name: bcmRemoveDefaultGatewayByWanIf().
740 // Description : remove the defaultGateway configuration if it uses the
741 // removed wan interface.
742 // Parameters : wanIf - the removed wan interface
744 ****************************************************************************/
745 void bcmRemoveDefaultGatewayByWanIf(char *wanIf) {
746 char gtwy[IFC_TINY_LEN], ifName[IFC_TINY_LEN];
748 bcmGetDefaultGateway(gtwy, ifName);
750 if ( strcmp(ifName, wanIf) == 0 ) {
751 // remove static default gateway in PSI
752 BcmDb_removeDefaultGatewayInfo();
757 /***************************************************************************
758 // Function Name: bcmGetDefaultGateway().
759 // Description : get default gateway info.
760 // Parameters : gtwy - buffer to retrieve default gateway.
762 ****************************************************************************/
763 void bcmGetDefaultGateway(char *gtwy, char *wanIf) {
764 char str[SYS_CMD_LEN];
766 IFC_DEF_GW_INFO defgw;
767 char addr[512], ip[512];
769 gtwy[0] = wanIf[0] = '\0';
770 if ( BcmDb_getDefaultGatewayInfo(&defgw) == DB_GET_OK ){
771 if (strcmp(inet_ntoa(defgw.defaultGateway), "0.0.0.0") != 0)
772 strcpy(gtwy, inet_ntoa(defgw.defaultGateway));
773 if (defgw.ifName != NULL)
774 strcpy(wanIf, defgw.ifName);
777 fs = fopen("/var/fyi/sys/gateway", "r");
779 if ( fgets(str, SYS_CMD_LEN, fs) > 0 ) {
780 sscanf(str, "%s\n", addr);
781 if ( BcmDb_validateIpAddress(addr) == DB_OBJ_VALID_OK )
784 if (bcmGetIfDestAddr(addr, ip) == BCM_DIAG_PASS)
793 /***************************************************************************
794 // Function Name: bcmIsDefaultGatewayExisted().
795 // Description : Check if the defaultGateway is existed in the route table.
796 // Parameters : gw and wanIf
797 // Returns : 1 - Exist. 0 - not Exist
798 ****************************************************************************/
799 int bcmIsDefaultGatewayExisted(char *gw, char *wanIf) {
806 FILE* fsRoute = fopen("/proc/net/route", "r");
807 if ( fsRoute != NULL ) {
808 while ( fgets(line, sizeof(line), fsRoute) ) {
809 // read pass header line
810 if ( count++ < 1 ) continue;
811 sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
812 col[0], col[1], col[2], col[3], col[4], col[5],
813 col[6], col[7], col[8], col[9], col[10]);
814 flag = strtol(col[3], (char**)NULL, 16);
815 if ((flag & (RTF_UP | RTF_GATEWAY)) == (RTF_UP | RTF_GATEWAY)) {
816 if ( wanIf[0] == '\0' || strcmp(wanIf, col[0]) == 0) {
817 addr.s_addr = strtoul(col[2], (char**)NULL, 16);
818 if (strcmp(gw, inet_ntoa(addr)) == 0) {
831 /***************************************************************************
832 // Function Name: bcmSetAutoDefaultGateway().
833 // Description : remove static default gateway in PSI,
834 // get the default gateway from var/fyi/sys/gateway, and add
835 // it to the route table.
836 // Parameters : errMsg -- error message when add default gateway if any.
837 // Returns : 1 - Exist. 0 - not Exist
838 ****************************************************************************/
839 void bcmSetAutoDefaultGateway(char *errMsg) {
840 char sysDefaultGateway[IFC_TINY_LEN];
841 char cmd[IFC_LARGE_LEN];
843 IFC_DEF_GW_INFO defgw;
845 // remove static default gateway
846 if ( BcmDb_getDefaultGatewayInfo(&defgw) == DB_GET_OK ) {
847 // remove static default gateway in PSI
848 BcmDb_removeDefaultGatewayInfo();
850 // create command to delete default gateway in route table
851 sprintf(cmd, "route del default");
852 if (strcmp(inet_ntoa(defgw.defaultGateway), "0.0.0.0") != 0) {
854 strcat(cmd, inet_ntoa(defgw.defaultGateway));
856 if (strcmp(defgw.ifName, "") != 0) {
857 strcat(cmd, " dev ");
858 strcat(cmd, defgw.ifName);
860 strcat(cmd, " 2> /var/gwerr");
862 fs = fopen("/var/gwerr", "r");
863 // read gwerr, if there is err then
864 // need to set error message
866 if ( fgets(cmd, IFC_LARGE_LEN, fs) > 0 ) {
867 // remove the last newline character
868 cmd[strlen(cmd) - 1] = '\0';
870 bcmSystemMute("cat /var/gwerr");
874 bcmSystemMute("rm /var/gwerr");
878 //get the default gateway from var/fyi/sys/gateway
879 bcmGetDefaultGateway(sysDefaultGateway, cmd);
880 if ( sysDefaultGateway[0] != '\0' &&
881 bcmIsDefaultGatewayExisted(sysDefaultGateway, "") == FALSE ) {
882 sprintf(cmd, "route add default gw %s 2> /var/gwerr", sysDefaultGateway);
884 fs = fopen("/var/gwerr", "r");
885 // read gwerr, if there is err then
886 // need to set the error message
888 if ( fgets(cmd, IFC_LARGE_LEN, fs) > 0 ) {
889 // remove the last newline character
890 cmd[strlen(cmd) - 1] = '\0';
892 bcmSystemMute("cat /var/gwerr");
896 bcmSystemMute("rm /var/gwerr");
901 /***************************************************************************
902 // Function Name: bcmSetStaticDefaultGateway().
903 // Description : remove the old, and add the new default gateway.
904 // Parameters : gw, wanIf, and error message
906 ****************************************************************************/
907 void bcmSetStaticDefaultGateway(char *gw, char *wanIf, char *errMsg) {
909 char cmd[IFC_LARGE_LEN];
911 IFC_DEF_GW_INFO defgw;
913 // intialize gw if it is empty
915 strcpy(gw, "0.0.0.0");
917 // if errMsg is NULL then only save configuration
918 // but not execute command to avoid error when
919 // route destination address cannot be reached since
920 // interface device does not created yet
921 if ( errMsg != NULL &&
922 BcmDb_getDefaultGatewayInfo(&defgw) == DB_GET_OK ) {
923 // check if not the same
924 if ( strcmp(defgw.ifName, wanIf) != 0 ||
925 strcmp(inet_ntoa(defgw.defaultGateway), gw) != 0) {
926 // del the previous default route saved in route table
927 sprintf(cmd, "route del default");
928 if ( strcmp(inet_ntoa(defgw.defaultGateway), "0.0.0.0") != 0 ) {
930 strcat(cmd, inet_ntoa(defgw.defaultGateway));
932 if ( strcmp(defgw.ifName, "") != 0 ) {
933 strcat(cmd, " dev ");
934 strcat(cmd, defgw.ifName);
936 strcat(cmd, " 2> /var/gwerr");
938 fs = fopen("/var/gwerr", "r");
939 // read gwerr, if there is err then
940 // need to set error message
941 if ( fgets(cmd, IFC_LARGE_LEN, fs) > 0 ) {
942 // remove the last newline character
943 cmd[strlen(cmd) - 1] = '\0';
945 bcmSystemMute("cat /var/gwerr");
949 bcmSystemMute("rm /var/gwerr");
952 return; // same and do nothing
955 // if errMsg is NULL then only save configuration
956 // but not execute command to avoid error when
957 // route destination address cannot be reached since
958 // interface device does not created yet
959 // if this gateway and wanIf is already in the route table,
960 // do not issue route add default command.
961 if ( errMsg != NULL &&
962 bcmIsDefaultGatewayExisted(gw, wanIf) == FALSE ) {
963 strcpy(cmd, "route add default");
964 if ( strcmp(gw, "0.0.0.0") != 0 &&
965 BcmDb_validateIpAddress(gw) == DB_OBJ_VALID_OK ) {
970 if (wanIf[0] != '\0') {
971 strcat(cmd, " dev ");
975 if ( runCmd == TRUE ) {
976 strcat(cmd, " 2> /var/gwerr");
978 fs = fopen("/var/gwerr", "r");
979 // read gwerr, if there is no err then
980 // need to configure default gateway in PSI
981 if ( fgets(cmd, IFC_LARGE_LEN, fs) <= 0 ) {
982 // save the new default gateway info to psi
985 // remove the last newline character
986 cmd[strlen(cmd) - 1] = '\0';
988 bcmSystemMute("cat /var/gwerr");
992 bcmSystemMute("rm /var/gwerr");
996 // save to PSI even when error occurs
997 defgw.enblGwAutoAssign = 0;
998 strcpy(defgw.ifName, wanIf);
999 defgw.defaultGateway.s_addr = inet_addr(gw);
1000 BcmDb_setDefaultGatewayInfo(&defgw);
1004 //**************************************************************************
1005 // Function Name: getPppoeServiceName
1006 // Description : get pppoe service name of the specific wan interfaces.
1007 // Parameters : service -- pppoe service name. (output)
1008 // ifName -- interface name. (input)
1010 //**************************************************************************
1011 void getPppoeServiceName(char *service, char *ifName) {
1012 char fileName[IFC_LARGE_LEN];
1013 char str[SYS_CMD_LEN];
1016 if (ifName[0] != 0) {
1017 sprintf(fileName, "/proc/var/fyi/wan/%s/servicename", ifName);
1018 fs = fopen(fileName, "r");
1020 if (fgets(str, SYS_CMD_LEN, fs) > 0)
1021 sscanf(str, "%s\n", service);
1029 /***************************************************************************
1030 // Function Name: setWanLinkStatus().
1031 // Description : get PPP status.
1032 // Parameters : up - wan link status
1035 ****************************************************************************/
1036 void setWanLinkStatus(int up)
1041 if ( (fd = fopen("/var/run/wanup", "a+")) != NULL )
1044 unlink("/var/run/wanup");
1047 /***************************************************************************
1048 // Function Name: disconnectPPP().
1049 // Description : if PPPD is alive, disconnet it.
1051 ****************************************************************************/
1052 void disconnectPPP(void)
1056 // If PPP is connected disconnect it first
1057 if ( (pid = bcmGetPid("pppd")) > 0 ) {
1058 setWanLinkStatus(0);
1059 // give PPP some time to disconnect. PPP client checks WAN links status
1066 /***************************************************************************
1067 // Function Name: bcmSocketIfPid().
1068 // Description : return the socket if pid (== 0 is lan (br0), !=0 is wan)
1069 // Parameters : none.
1071 ****************************************************************************/
1072 int bcmSocketIfPid(void)
1074 char ifName[IFC_SMALL_LEN];
1076 char cmd[SYS_CMD_LEN];
1080 strncpy(ifName, getIfName(), IFC_SMALL_LEN - 1);
1081 if (ifName[0] == '\0')
1084 sprintf(cmd, "/proc/var/fyi/wan/%s/pid", ifName);
1085 if ((fs = fopen(cmd, "r")) != NULL)
1087 fgets(cmd, SYS_CMD_LEN, fs);
1097 /***************************************************************************
1098 // Function Name: bcmKillAllApps().
1099 // Description : kill all available applications.
1100 // Parameters : none.
1102 ****************************************************************************/
1103 void bcmKillAllApps(void) {
1104 // NOTE: Add the app name before NULL. Order is important
1107 #ifdef SUPPORT_TR69C
1131 char cmd[SYS_CMD_LEN], app[SYS_CMD_LEN], buf[SYS_CMD_LEN];
1132 char pidStr[SYS_CMD_LEN];
1137 int curPid = getpid();
1141 fs = fopen("/var/run/httpd_pid", "r");
1144 fgets(cmd, SYS_CMD_LEN, fs);
1145 httpdPid = atoi(cmd);
1150 printf("Error: httpd pid not found ?\n");
1154 bcmSystemMute("ps > /var/pslist");
1155 fs = fopen("/var/pslist", "r");
1158 bcmSystem("cat /var/pslist");
1160 socketPid = bcmSocketIfPid();
1164 // add the default route with the ifc the socket is sitting on
1165 if (strstr(getIfName(), "nas") == NULL && // only do it if it is not MER and not ipoa (eth?)
1166 strstr(getIfName(), "eth") == NULL)
1168 sprintf(cmd, "route add default dev %s", getIfName());
1174 if (curPid == httpdPid)
1177 bcmSystem("sysinfo");
1179 //printf("curPid=%d, socketPid=%d, htpdPid=%d, inWeb=%d\n", curPid, socketPid, httpdPid, inWeb);
1180 // get app and read thru pslist according to the order of apps
1184 strcpy(app, apps[i]);
1185 while (fgets(buf, SYS_CMD_LEN, fs) > 0)
1187 if (strstr(buf, app) != NULL) // found command line with match app name
1190 sscanf(buf, "%s\n", pidStr);
1191 // if not in httpd, must be in telnetd or sshd, just skip the line.
1192 if (!inWeb && ((strstr(buf, "telnetd")) || (strstr(buf, "sshd"))))
1195 if (pid != curPid && pid != socketPid)
1197 printf("kill %s process...\n", app);
1198 sprintf(cmd, "kill -%d %d", 9, pid);
1203 rewind(fs); // start pslist over again
1204 } while (apps[++i] != NULL);
1207 bcmSystemMute("rm /var/pslist");
1208 bcmRemoveModules(socketPid);
1211 // function to support encryption password for login
1212 static int i64c(int i) {
1217 if (i >= 2 && i < 12)
1218 return ('0' - 2 + i);
1219 if (i >= 12 && i < 38)
1220 return ('A' - 12 + i);
1221 if (i >= 38 && i < 63)
1222 return ('a' - 38 + i);
1226 // function to support encryption password for login
1227 static char *crypt_make_salt(void) {
1229 static unsigned long x;
1230 static char result[3];
1233 x += now + getpid() + clock();
1234 result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
1235 result[1] = i64c(((x >> 12) ^ x) & 077);
1240 // function to support encryption password for login
1241 static char *pw_encrypt(const char *clear, const char *salt) {
1242 static char cipher[128];
1245 #ifdef CONFIG_FEATURE_SHA1_PASSWORDS
1246 if (strncmp(salt, "$2$", 3) == 0) {
1247 return sha1_crypt(clear);
1250 cp = (char *) crypt(clear, salt);
1251 /* if crypt (a nonstandard crypt) returns a string too large,
1252 truncate it so we don't overrun buffers and hope there is
1253 enough security in what's left */
1254 if (strlen(cp) > sizeof(cipher)-1) {
1255 cp[sizeof(cipher)-1] = 0;
1261 /***************************************************************************
1262 // Function Name: bcmCreateLoginCfg().
1263 // Description : create password file for login using 'admin' or 'support'.
1264 // Parameters : cp_admin - clear password of 'admin'.
1265 // cp_support - clear password of 'support'.
1266 // cp_user - clear password of 'user'.
1267 // Returns : status 0 - OK, -1 - ERROR.
1268 ****************************************************************************/
1269 int bcmCreateLoginCfg(char *cp_admin, char *cp_support, char *cp_user) {
1271 FILE *fsPwd = NULL, *fsGrp = NULL;
1273 fsPwd = fopen("/etc/passwd", "w");
1275 if ( fsPwd != NULL ) {
1276 // In future, we may change uid of 'admin' and 'support'
1277 // uclibc may have a bug on putpwent in terms of uid,gid setup
1278 pw.pw_name = "admin";
1279 pw.pw_passwd = pw_encrypt(cp_admin, crypt_make_salt());
1282 pw.pw_gecos = "Administrator";
1284 pw.pw_shell = "/bin/sh";
1285 putpwent(&pw, fsPwd);
1287 pw.pw_name = "support";
1288 pw.pw_passwd = pw_encrypt(cp_support, crypt_make_salt());
1291 pw.pw_gecos = "Technical Support";
1293 pw.pw_shell = "/bin/sh";
1294 putpwent(&pw, fsPwd);
1296 pw.pw_name = "user";
1297 pw.pw_passwd = pw_encrypt(cp_user, crypt_make_salt());
1300 pw.pw_gecos = "Normal User";
1302 pw.pw_shell = "/bin/sh";
1303 putpwent(&pw, fsPwd);
1305 pw.pw_name = "nobody";
1306 pw.pw_passwd = pw_encrypt(cp_admin, crypt_make_salt());
1309 pw.pw_gecos = "nobody for ftp";
1311 pw.pw_shell = "/bin/sh";
1312 putpwent(&pw, fsPwd);
1315 fsGrp = fopen("/etc/group", "w");
1316 if ( fsGrp != NULL ) {
1317 fprintf(fsGrp, "root::0:root,admin,support,user\n");
1319 return FILE_OPEN_OK;
1323 return FILE_OPEN_ERR;
1326 /***************************************************************************
1327 // Function Name: bcmSetIpExtension().
1328 // Description : store PPP IP extension info to file.
1329 // Parameters : ipExt - 1:enable, 0:disable.
1330 // Returns : status 0 - OK, -1 - ERROR.
1331 ****************************************************************************/
1332 int bcmSetIpExtension(int ipExt) {
1333 FILE* fs = fopen("/var/ipextension", "w");
1336 fprintf(fs, "%d\n", ipExt);
1338 return FILE_OPEN_OK;
1341 return FILE_OPEN_ERR;
1344 /***************************************************************************
1345 // Function Name: bcmGetIpExtension().
1346 // Description : retrieve PPP IP extension info from file.
1347 // Parameters : str -- buffer.
1348 // len -- size of buffer.
1349 // Returns : status 0 - OK, -1 - ERROR.
1350 ****************************************************************************/
1351 int bcmGetIpExtension(char *str, int len) {
1352 FILE* fs = fopen("/var/ipextension", "r");
1355 fgets(str, len, fs);
1357 return FILE_OPEN_OK;
1360 return FILE_OPEN_ERR;
1363 /***************************************************************************
1364 // Function Name: bcmGetIfcIndexByName().
1365 // Description : get interface index by its name.
1366 // Parameters : ifcIdx -- interface index.
1367 // ifcName -- interface name.
1368 // Returns : interface index
1369 ****************************************************************************/
1370 int bcmGetIfcIndexByName(char *ifcName) {
1374 if ( ifcName == NULL ) return -1;
1376 if ( (s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) return -1;
1378 strcpy(ifr.ifr_name, ifcName);
1379 if ( ioctl(s, SIOCGIFINDEX, &ifr) < 0 ) {
1386 return ifr.ifr_ifindex;
1389 /***************************************************************************
1390 // Function Name: bcmIsValidIfcName.
1391 // Description : validate the interface name.
1392 // Parameters : ifcName -- interface name that need to validate.
1393 // Returns : TRUE or FALSE
1394 ****************************************************************************/
1395 int bcmIsValidIfcName(char *ifcName) {
1398 if (bcmGetIfcIndexByName(ifcName))
1403 /***************************************************************************
1404 // Function Name: bcmGetIfcNameById.
1405 // Description : get interface name by its id (defined in ifcdefs.h).
1406 // Parameters : ifcId -- interface Id.
1407 // ifcName -- interface name.
1408 // Returns : interface name or NULL
1409 ****************************************************************************/
1410 char *bcmGetIfcNameById(int ifcId, char *ifcName) {
1411 if ( ifcName == NULL ) return NULL;
1415 if ( ifcId >= IFC_ENET_ID && ifcId < IFC_USB_ID )
1416 sprintf(ifcName, "eth%d", ifcId - IFC_ENET_ID);
1417 else if ( ifcId >= IFC_USB_ID && ifcId < IFC_HPNA_ID )
1418 // strcpy(ifcName, "eth1");
1419 sprintf(ifcName, "usb%d", ifcId - IFC_USB_ID);
1420 else if ( ifcId >= IFC_HPNA_ID && ifcId < IFC_WIRELESS_ID )
1421 sprintf(ifcName, "il%d", ifcId - IFC_HPNA_ID);
1422 else if ( ifcId >= IFC_WIRELESS_ID && ifcId < IFC_WIRELESS_ID + IFC_LAN_MAX ) {
1423 int num = ifcId - IFC_WIRELESS_ID;
1424 if (num == 0) { // multiple ssid support
1425 sprintf(ifcName, "wl0");
1428 sprintf(ifcName, "wl0.%d", num);
1435 /***************************************************************************
1436 // Function Name: bcmGetIfcNameByIpAddr.
1437 // Description : get interface name by its IP address.
1438 // Parameters : ifcIpAddr -- interface IP address.
1439 // ifcName -- interface name.
1440 // Returns : interface name or NULL
1441 ****************************************************************************/
1442 char *bcmGetIfcNameByIpAddr(unsigned long ipAddr, char *ifcName) {
1443 char str[SYS_CMD_LEN] = "ifconfig -a > /var/ifcs";
1448 if( (fs = fopen("/var/ifcs", "r")) != NULL ) {
1449 while( fgets(str, sizeof(str), fs) != NULL ) {
1450 if( str[0] >= 'A' && str[0] <= 'z' ) {
1455 // Copy interface name (br0, eth0, pppoe_0_35, etc.) to local
1457 for(i = 0, p = str; i<sizeof(name)-1 && *p && *p!=' '; i++, p++)
1461 // The next line will have the IP address if one is assigned
1462 // to the current interface.
1463 if( fgets(str, sizeof(str), fs) != NULL ) {
1464 if( (p = strstr(str, "inet addr:")) != NULL ) {
1467 p += strlen("inet addr:");
1468 addr = inet_addr(p);
1470 // if the IP address of the current interfaces matches
1471 // the supplied IP address, then the interface is found.
1472 if( addr == ipAddr ) {
1473 strcpy( ifcName, name );
1482 unlink("/var/ifcs");
1488 /***************************************************************************
1489 // Function Name: bcmSetConnTrackMax.
1490 // Description : tune the connection track table size.
1491 // Parameters : none.
1493 ****************************************************************************/
1494 void bcmSetConnTrackMax(void) {
1495 int conntrack_max = CONNTRACK_MUX;
1496 char cmd[SYS_CMD_LEN];
1497 FILE* fs = fopen("/proc/sys/net/ipv4/ip_conntrack_max", "r");
1499 // init ip_conntrack_max
1500 if ( fs == NULL ) // ip_conntrack module is not loaded.
1503 fgets(cmd, SYS_CMD_LEN, fs);
1504 conntrack_max = atoi(cmd);
1507 // Code in ip_conntrack_init function of ip_conntrack_core.c in kernel
1508 // has been modified to initialize ip_conntrack_max to be always 0
1509 // when ip_conntrack module is inserted (before NAT or Firewall is enabled).
1510 // This function setting real conntrack_max will be called after NAT or Firewall is enabled.
1511 if ( conntrack_max == 0 )
1512 conntrack_max = CONNTRACK_MUX;
1514 if ( conntrack_max < CONNTRACK_MUX ) {
1516 if ( conntrack_max > CONNTRACK_MUX )
1517 conntrack_max = CONNTRACK_MUX;
1520 sprintf(cmd, "echo \"%d\" > /proc/sys/net/ipv4/ip_conntrack_max", conntrack_max);
1524 /***************************************************************************
1525 // Function Name: bcmResetConnTrackTable.
1526 // Description : reset the connection track table.
1527 // Parameters : none.
1529 ****************************************************************************/
1530 void bcmResetConnTrackTable(void) {
1531 if ( bcmIsModuleInserted("ip_conntrack") == TRUE )
1532 bcmSystem("echo > /proc/net/ip_conntrack");
1535 /***************************************************************************
1536 // Function Name: bcmHandleConnTrack.
1537 // Description : handle the connection track table.
1538 // Parameters : none.
1540 ****************************************************************************/
1541 void bcmHandleConnTrack(void) {
1542 bcmResetConnTrackTable();
1543 bcmSetConnTrackMax();
1546 /***************************************************************************
1547 // Function Name: bcmInsertModules.
1548 // Description : insert all modules under the given path.
1549 // Parameters : path -- the given path.
1551 ****************************************************************************/
1552 void bcmInsertModules(char *path) {
1553 struct dirent *entry;
1557 if ( path == NULL ) return;
1559 dir = opendir(path);
1560 if ( dir == NULL ) return;
1562 while ( (entry = readdir(dir)) != NULL )
1563 if ( (cp = strstr(entry->d_name, ".ko")) != NULL ) {
1565 bcmInsertModule(entry->d_name);
1570 /***************************************************************************
1571 // Function Name: bcmInsertModule.
1572 // Description : insert module with the given name.
1573 // Parameters : modName -- the given module name.
1575 ****************************************************************************/
1576 void bcmInsertModule(char *modName) {
1577 char cmd[SYS_CMD_LEN], modulepath[SYS_CMD_LEN];
1578 struct utsname kernel;
1580 if (uname(&kernel) == -1)
1583 sprintf(modulepath, "/lib/modules/%s/kernel/net/ipv4/netfilter", kernel.release);
1585 if ( bcmIsModuleInserted(modName) == FALSE ) {
1586 sprintf(cmd, "insmod %s/%s.ko", modulepath,modName);
1591 /***************************************************************************
1592 // Function Name: bcmRemoveIpTableRule().
1593 // Description : remove IP table rules.
1594 // Parameters : device -- interface name.
1595 // table -- IP table name.
1596 // chain -- IP table chain.
1597 // Returns : 1 - Success. 0 - Fail
1598 ****************************************************************************/
1599 int bcmRemoveIpTableRule(char *device, char *table, char *chain) {
1600 char col[IP_TBL_COL_MAX][IFC_SMALL_LEN];
1601 char comment[IFC_LARGE_LEN], line[IFC_GIANT_LEN];
1602 int ret = FALSE, count = 0;
1605 if ((access("/bin/iptables",F_OK)) != 0)
1608 // execute iptables command to create iptable file
1609 sprintf(line, "iptables -t %s -L %s -v --line-numbers > /var/iptable",
1611 bcmSystemMute(line);
1613 fs = fopen("/var/iptable", "r");
1615 while ( fgets(line, sizeof(line), fs) ) {
1616 // read pass 2 header lines
1617 if ( count++ < 2 ) continue;
1618 sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
1619 col[IP_TBL_COL_NUM], col[IP_TBL_COL_PKTS], col[IP_TBL_COL_BYTES],
1620 col[IP_TBL_COL_TARGET], col[IP_TBL_COL_PROT], col[IP_TBL_COL_OPT],
1621 col[IP_TBL_COL_IN], col[IP_TBL_COL_OUT], col[IP_TBL_COL_SRC],
1622 col[IP_TBL_COL_DST], comment);
1623 // if chain rule for the given device is found
1624 if ( strcmp(col[IP_TBL_COL_IN], device) == 0 ||
1625 strcmp(col[IP_TBL_COL_OUT], device) == 0 ) {
1626 sprintf(line, "iptables -t %s -D %s %s 2>/dev/null",
1627 table, chain, col[IP_TBL_COL_NUM]);
1628 bcmSystemMute(line);
1636 // codes to remove iptable file is moved to bcmRemoveAllIpTableRules() function
1641 /***************************************************************************
1642 // Function Name: bcmRemoveAllIpTableRules().
1643 // Description : remove all IP table rules attach with the given device.
1644 // Parameters : device -- interface name.
1646 ****************************************************************************/
1647 void bcmRemoveAllIpTableRules(char *device) {
1650 if ( bcmIsModuleInserted("iptable_filter") == TRUE ) {
1651 while ( bcmRemoveIpTableRule(device, "filter", "INPUT") == TRUE )
1654 while ( bcmRemoveIpTableRule(device, "filter", "FORWARD") == TRUE )
1657 while ( bcmRemoveIpTableRule(device, "filter", "OUTPUT") == TRUE )
1661 if ( bcmIsModuleInserted("iptable_nat") == TRUE ) {
1662 while ( bcmRemoveIpTableRule(device, "nat", "PREROUTING") == TRUE )
1664 /* We should keep the masquerading rules
1665 while ( bcmRemoveIpTableRule(device, "nat", "POSTROUTING") == TRUE )
1669 while ( bcmRemoveIpTableRule(device, "nat", "OUTPUT") == TRUE )
1673 // remove iptable file
1674 fs = fopen("/var/iptable", "r");
1677 unlink("/var/iptable");
1681 /***************************************************************************
1682 // Function Name: bcmRemoveRipIpTableRule().
1683 // Description : remove RIP IP table rules.
1684 // Parameters : none.
1685 // Returns : 1 - Success. 0 - Fail
1686 ****************************************************************************/
1687 int bcmRemoveRipIpTableRule(void) {
1688 char col[IP_TBL_COL_MAX][IFC_SMALL_LEN];
1689 char comment[IFC_LARGE_LEN], line[IFC_GIANT_LEN];
1690 int ret = FALSE, count = 0;
1693 if ((access("/bin/iptables",F_OK)) != 0)
1696 // execute iptables command to create iptable file
1697 sprintf(line, "iptables -L INPUT -v --line-numbers > /var/iptable");
1698 bcmSystemMute(line);
1700 fs = fopen("/var/iptable", "r");
1702 while ( fgets(line, sizeof(line), fs) ) {
1703 // read pass 2 header lines
1704 if ( count++ < 2 ) continue;
1705 sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
1706 col[IP_TBL_COL_NUM], col[IP_TBL_COL_PKTS], col[IP_TBL_COL_BYTES],
1707 col[IP_TBL_COL_TARGET], col[IP_TBL_COL_PROT], col[IP_TBL_COL_OPT],
1708 col[IP_TBL_COL_IN], col[IP_TBL_COL_OUT], col[IP_TBL_COL_SRC],
1709 col[IP_TBL_COL_DST], comment);
1710 // if protocol column is "udp" and last colum is "udp dpt:route"
1711 // then delete rule since it is RIP IP tables rule
1712 if ( strcmp(col[IP_TBL_COL_PROT], "udp") == 0 &&
1713 strcmp(comment, "udp dpt:route") == 0 ) {
1714 sprintf(line, "iptables -D INPUT %s 2>/dev/null", col[IP_TBL_COL_NUM]);
1715 bcmSystemMute(line);
1722 // remove iptable file
1723 unlink("/var/iptable");
1729 /***************************************************************************
1730 // Function Name: bcmRemoveUpnpIpTableRule().
1731 // Description : remove UPnP IP table rules.
1732 // Parameters : none.
1733 // Returns : 1 - Success. 0 - Fail
1734 ****************************************************************************/
1735 int bcmRemoveUpnpIpTableRule(void) {
1736 char col[IP_TBL_COL_MAX][IFC_SMALL_LEN];
1737 char comment[IFC_LARGE_LEN], line[IFC_GIANT_LEN];
1738 int ret = FALSE, count = 0;
1741 if ((access("/bin/iptables",F_OK)) != 0)
1744 // execute iptables command to create iptable file
1745 sprintf(line, "iptables -L OUTPUT -v --line-numbers > /var/iptable");
1746 bcmSystemMute(line);
1748 fs = fopen("/var/iptable", "r");
1750 while ( fgets(line, sizeof(line), fs) ) {
1751 // read pass 2 header lines
1752 if ( count++ < 2 ) continue;
1753 sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
1754 col[IP_TBL_COL_NUM], col[IP_TBL_COL_PKTS], col[IP_TBL_COL_BYTES],
1755 col[IP_TBL_COL_TARGET], col[IP_TBL_COL_PROT], col[IP_TBL_COL_OPT],
1756 col[IP_TBL_COL_IN], col[IP_TBL_COL_OUT], col[IP_TBL_COL_SRC],
1757 col[IP_TBL_COL_DST], comment);
1758 // if destination column is "239.255.255.250" and target colum is "DROP"
1759 // then delete rule since it is RIP IP tables rule
1760 if ( strcmp(col[IP_TBL_COL_TARGET], "DROP") == 0 &&
1761 strcmp(col[IP_TBL_COL_DST], UPNP_IP_ADDRESS) == 0 ) {
1762 sprintf(line, "iptables -D OUTPUT %s 2>/dev/null", col[IP_TBL_COL_NUM]);
1763 bcmSystemMute(line);
1770 // remove iptable file
1771 unlink("/var/iptable");
1777 /***************************************************************************
1778 // Function Name: bcmInsertAllUpnpIpTableRules().
1779 // Description : insert UPnP IP table rules.
1780 // Parameters : none.
1782 ****************************************************************************/
1783 void bcmInsertAllUpnpIpTableRules(void) {
1784 char interface[IFC_TINY_LEN], cmd[IFC_LARGE_LEN];
1786 WAN_CON_INFO wanInfo;
1788 // init wanId to get WAN info from the begining
1789 wanId.vpi = wanId.vci = wanId.conId = 0;
1791 while ( BcmDb_getWanInfoNext(&wanId, &wanInfo) == DB_WAN_GET_OK ) {
1792 if ( wanInfo.flag.service == FALSE ) continue;
1793 if ( wanInfo.flag.nat == TRUE ) {
1794 // get interface name
1795 BcmDb_getWanInterfaceName(&wanId, wanInfo.protocol, interface);
1796 // If the br0 interface goes down and then comes back up, we do not need to
1797 // restart UPnP. All UPnP object values are obtained from the actual WAN
1798 // interface /dev/bcmadsl0 and /dev/bcmatm0.
1799 if ( bcmGetPid("upnp") <= 0 ) {
1800 sprintf(cmd, "upnp -L %s -W %s -D", "br0", interface);
1803 // Stop multicast reports for UPnP on WAN.
1804 sprintf(cmd, "iptables -t filter -I OUTPUT -o %s -d %s -j DROP 2>/dev/null",
1805 interface, UPNP_IP_ADDRESS);
1811 /***************************************************************************
1812 // Function Name: bcmRemoveEbTableRule().
1813 // Description : remove ebtables rules.
1814 // Parameters : device -- interface name.
1815 // table -- ebtables table name.
1816 // chain -- ebtables table chain.
1817 // Returns : 1 - Success. 0 - Fail
1818 ****************************************************************************/
1819 int bcmRemoveEbTableRule(char *device, char *table, char *chain) {
1820 char line[IFC_GIANT_LEN];
1821 int ret = FALSE, count = 0, index = 0;
1824 if ((access("/bin/ebtables",F_OK)) != 0)
1827 // execute iptables command to create iptable file
1828 sprintf(line, "ebtables -t %s -L %s --Ln > /var/ebtable", table, chain);
1829 bcmSystemMute(line);
1831 fs = fopen("/var/ebtable", "r");
1833 while ( fgets(line, sizeof(line), fs) ) {
1834 // read pass 3 header lines
1835 if ( count++ < 3 ) continue;
1836 // if chain rule for the given device is found
1837 if ( strstr(line, device) != NULL ) {
1838 // get the rule index number
1839 sscanf(line, "%d.", &index);
1840 sprintf(line, "ebtables -t %s -D %s %d 2>/dev/null", table, chain, index);
1841 bcmSystemMute(line);
1849 // code to remove ebtable file is moved to bcmRemoveAllEbTableRules() function
1854 /***************************************************************************
1855 // Function Name: bcmRemoveAllEbTableRules().
1856 // Description : remove all ebtables rules attach with the given device.
1857 // Each time, only one rule is removed, hence the rule index changes
1858 // That's why we need to use while loop to remove all
1859 // Parameters : device -- interface name.
1861 ****************************************************************************/
1862 void bcmRemoveAllEbTableRules(char *device) {
1863 // while ( bcmRemoveEbTableRule(device, "filter", "INPUT") == TRUE )
1866 while ( bcmRemoveEbTableRule(device, "filter", "FORWARD") == TRUE )
1869 // while ( bcmRemoveEbTableRule(device, "filter", "OUTPUT") == TRUE )
1872 // remove ebtable file
1873 unlink("/var/ebtable");
1877 /***************************************************************************
1878 // Function Name: bcmGetDefaultRouteInterfaceName().
1879 // Description : get interface name that is used for first default route.
1880 // Parameters : ifcName -- the return interface name, '\0' if not found.
1882 ****************************************************************************/
1883 void bcmGetDefaultRouteInterfaceName(char *ifcName) {
1884 char col[11][IFC_SMALL_LEN];
1885 char line[IFC_GIANT_LEN];
1888 if ( ifcName == NULL ) return;
1892 FILE* fsRoute = fopen("/proc/net/route", "r");
1893 if ( fsRoute != NULL ) {
1894 while ( fgets(line, sizeof(line), fsRoute) ) {
1895 // read pass header line
1896 if ( count++ < 1 ) continue;
1897 sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
1898 col[0], col[1], col[2], col[3], col[4], col[5],
1899 col[6], col[7], col[8], col[9], col[10]);
1900 // if destination && mask are 0 then it's default route
1901 if ( strcmp(col[1], "00000000") == 0 &&
1902 strcmp(col[7], "00000000") == 0 ) {
1903 strcpy(ifcName, col[0]);
1911 //***************************************************************************
1912 // Function Name: parseStrInfo
1913 // Description : parse info to get value of the given variable.
1914 // Parameters : info -- information string.
1915 // var -- variable string to be searched in info string.
1916 // val -- value string after variable string to be returned.
1917 // len -- size of value string.
1919 //***************************************************************************/
1920 void parseStrInfo(char *info, char *var, char *val, int len) {
1924 if ( info == NULL || var == NULL || val == NULL ) return;
1926 pChar = strstr(info, var);
1927 if ( pChar == NULL ) return;
1929 // move pass the variable string in line
1930 pChar += strlen(var);
1932 // Remove spaces from beginning of value string
1933 while ( *pChar != '\0' && isspace((int)*pChar) != 0 )
1936 // get data until end of line, or space char
1938 i < len && *pChar != '\0' &&
1939 isspace((int)*pChar) == 0;
1946 //**************************************************************************
1947 // Function Name: bcmConvertStrToShellStr
1948 // Description : convert the given string so that each its character is
1949 // surround by '. If character is ' then it is surround by ".
1950 // (a#b'c"d => 'a''#''b'"'"'c''"''d')
1951 // Parameters : str - the given string.
1952 // buf - the converted string.
1954 //**************************************************************************
1955 void bcmConvertStrToShellStr(char *str, char *buf) {
1956 if ( buf == NULL ) return;
1958 int len = strlen(str);
1962 for ( i = 0; i < len; i++ ) {
1963 if ( isalnum(str[i]) )
1966 buf[j++] = ( escp = (str[i] == '\'' ? '"':'\'') );
1974 //**************************************************************************
1975 // Function Name: bcmProcessMarkStrChars
1976 // Description : use backslash in front one of the escape codes to process
1977 // marked string characters.
1978 // (a'b"c => a\'b\"c)
1979 // Parameters : str - the string that needs to process its special chars.
1981 //**************************************************************************
1982 void bcmProcessMarkStrChars(char *str) {
1983 if ( str == NULL ) return;
1984 if ( str[0] == '\0' ) return;
1986 char buf[SYS_CMD_LEN];
1987 int len = strlen(str);
1990 for ( i = 0; i < len; i++ ) {
1991 if ( bcmIsMarkStrChar(str[i]) == TRUE )
2000 //**************************************************************************
2001 // Function Name: bcmIsMarkStrChar
2002 // Description : verify the given character is used to mark the begining or
2003 // ending of string or not.
2004 // Parameters : c -- the given character.
2005 // Returns : TRUE or FALSE.
2006 //**************************************************************************
2007 int bcmIsMarkStrChar(char c) {
2008 // need to add '\0' as termination character to speChars[]
2009 char specChars[] = "'\"\\";
2010 int len = strlen(specChars);
2014 for ( i = 0; i < len; i++ )
2015 if ( c == specChars[i] )
2024 //**************************************************************************
2025 // Function Name: bcmGetSwVer
2026 // Description : retrieve software version from global variable
2027 // Parameters : swVer - buffer to get the software version.
2028 // size - size of buffer.
2030 //**************************************************************************
2031 void bcmGetSwVer(char *swVer, int size) {
2032 char version[SYS_CMD_LEN], adslPhyVersion[SYS_CMD_LEN];
2034 if ( swVer == NULL ) return;
2036 // get adsl physical version
2037 BcmAdslCtl_GetPhyVersion(adslPhyVersion, SYS_CMD_LEN - 1);
2038 // create software version
2039 sprintf(version, "%s%s", SOFTWARE_VERSION, adslPhyVersion);
2040 strncpy(swVer, version, size);
2041 swVer[size-1] = '\0';
2045 //**************************************************************************
2046 // Function Name: bcmGetBuildVer
2047 // Description : retrieve build version from bcmTag
2048 // Parameters : swVer - buffer to get the software version.
2049 // size - size of buffer.
2051 //**************************************************************************
2052 void bcmGetBuildVer(char *swVer, int size) {
2054 const char verFormat[IFC_SMALL_LEN] = {"0.00L.00.00"};
2055 char* tagVersion = BCM_SIG_2 + 5;
2057 strncpy(swVer, verFormat, size);
2058 for( i=0; i<strlen(verFormat), *tagVersion; i++ ) {
2059 if( swVer[i] != '.' ) // Insert periods into version string
2060 swVer[i] = *tagVersion++; // Start from numeric value
2063 if( (size - strlen(swVer)) > 12 )
2064 strcat(swVer, "-Beta 6");
2068 //**************************************************************************
2069 // Function Name: bcmcheck_enable
2070 // Description : check the appName with ip address against the psi
2072 // Parameters : appName - application name in the acl.conf (telnet, ssh, etc.)
2073 // clntAddr - incoming ip address
2074 // Returns : access mode - CLI_ACCESS_LOCAL, CLI_REMOTE_LOCAL, CLI_ACCESS_DISABLED
2075 //**************************************************************************
2076 int bcmCheckEnable(char *appName, struct in_addr clntAddr)
2078 // is client address in Access Control List ?
2079 if ( BcmScm_isInAccessControlList(inet_ntoa(clntAddr)) == FALSE )
2080 return CLI_ACCESS_DISABLED;
2082 if ( isAccessFromLan(clntAddr) == TRUE ) {
2083 // is enabled from lan ?
2084 if ( BcmScm_isServiceEnabled(appName, CLI_ACCESS_LOCAL) == FALSE )
2085 return CLI_ACCESS_DISABLED;
2087 return CLI_ACCESS_LOCAL;
2089 // is enabled from wan ?
2090 if ( BcmScm_isServiceEnabled(appName, CLI_ACCESS_REMOTE) == FALSE )
2091 return CLI_ACCESS_DISABLED;
2093 return CLI_ACCESS_REMOTE;
2097 int bcmWanEnetQuerySwitch(char *ifName) {
2099 char cmd[IFC_LARGE_LEN];
2100 char str[IFC_LARGE_LEN];
2103 sprintf(cmd, "vconfig query %s 2 2>/var/vcfgerr\n", ifName);
2105 // Check the status of the previous command
2106 errFs = fopen("/var/vcfgerr", "r");
2107 if (errFs != NULL ) {
2108 fgets(str, IFC_LARGE_LEN, errFs);
2111 bcmSystem("rm /var/vcfgerr");
2116 #endif // USE_ALL, code below this code can be linked with other apps
2119 //*********** code shared by ftpd and tftpd **********************
2120 //****************************************************************
2122 /***************************************************************************
2123 // Function Name: bcmIsModuleInserted.
2124 // Description : verify the given module name is already inserted or not.
2125 // Parameters : modName -- the given module name.
2126 // Returns : TRUE or FALSE.
2127 ****************************************************************************/
2128 int bcmIsModuleInserted(char *modName) {
2130 char buf[SYS_CMD_LEN];
2131 FILE* fs = fopen("/proc/modules", "r");
2134 while ( fgets(buf, SYS_CMD_LEN, fs) > 0 )
2135 if ( strstr(buf, modName) != NULL ) {
2146 /***************************************************************************
2147 // Function Name: bcmCheckInterfaceUp().
2148 // Description : check status of interface.
2149 // Parameters : devname - name of device.
2150 // Returns : 1 - UP.
2152 ****************************************************************************/
2153 int bcmCheckInterfaceUp(char *devname) {
2158 if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2162 strcpy(intf.ifr_name, devname);
2164 // if interface is br0:0 and
2165 // there is no binding IP address then return down
2166 if ( strchr(devname, ':') != NULL ) {
2167 if (ioctl(skfd, SIOCGIFADDR, &intf) < 0) {
2173 // if interface flag is down then return down
2174 if (ioctl(skfd, SIOCGIFFLAGS, &intf) == -1) {
2177 if ( (intf.ifr_flags & IFF_UP) != 0)
2188 //If we don't link with busybox, we need this function
2189 #ifndef BUILD_STATIC
2191 static void remove_delimitor( char *s)
2196 while ( *p1 != '\0' || *(p1+1) != '\0') {
2206 /* find_pid_by_name()
2208 * This finds the pid of the specified process.
2209 * Currently, it's implemented by rummaging through
2210 * the proc filesystem.
2212 * Returns a list of all matching PIDs
2214 static pid_t* find_pid_by_name( char* pidName)
2217 struct dirent *next;
2218 pid_t* pidList=NULL;
2223 char filename[READ_BUF_SIZE];
2224 char buffer[READ_BUF_SIZE];
2225 /* char name[READ_BUF_SIZE]; */
2227 dir = opendir("/proc");
2229 printf("cfm:Cannot open /proc");
2233 while ((next = readdir(dir)) != NULL) {
2234 /* re-initialize buffers */
2235 memset(filename, 0, sizeof(filename));
2236 memset(buffer, 0, sizeof(buffer));
2238 /* Must skip ".." since that is outside /proc */
2239 if (strcmp(next->d_name, "..") == 0)
2242 /* If it isn't a number, we don't want it */
2243 if (!isdigit(*next->d_name))
2246 /* sprintf(filename, "/proc/%s/status", next->d_name); */
2247 /* read /porc/<pid>/cmdline instead to get full cmd line */
2248 sprintf(filename, "/proc/%s/cmdline", next->d_name);
2249 if (! (cmdline = fopen(filename, "r")) ) {
2252 if (fgets(buffer, READ_BUF_SIZE-1, cmdline) == NULL) {
2258 /* Buffer should contain a string like "Name: binary_name" */
2259 /*sscanf(buffer, "%*s %s", name);*/
2260 /* buffer contains full commandline params separted by '\0' */
2261 remove_delimitor(buffer);
2262 if (strstr(buffer, pidName) != NULL) {
2263 pidList=realloc( pidList, sizeof(pid_t) * (i+2));
2265 printf("cfm: Out of memeory!\n");
2269 pidList[i++]=strtol(next->d_name, NULL, 0);
2276 else if ( strcmp(pidName, "init")==0) {
2277 /* If we found nothing and they were trying to kill "init",
2278 * guess PID 1 and call it good... Perhaps we should simply
2279 * exit if /proc isn't mounted, but this will do for now. */
2280 pidList=realloc( pidList, sizeof(pid_t));
2282 printf("cfm: Out of memeory!\n");
2287 pidList=realloc( pidList, sizeof(pid_t));
2289 printf("cfm: Out of memeory!\n");
2299 void bcmHidePassword(char *command) {
2304 /* pppd -i ..... -p password */
2305 if ((ptr = strstr(command,"pppd")) != NULL) {
2306 if (!strstr(ptr, "-p"))
2308 begin = strstr(ptr,"-p") + 3;
2309 end = strchr(begin,' ');
2311 len = strlen(begin);
2322 /***************************************************************************
2323 // Function Name: bcmSystem().
2324 // Description : launch shell command in the child process.
2325 // Parameters : command - shell command to launch.
2326 // Returns : status 0 - OK, -1 - ERROR.
2327 ****************************************************************************/
2328 int bcmSystemEx (char *command, int printFlag) {
2329 int pid = 0, status = 0;
2330 char *newCommand = NULL;
2347 printf("app: %s\r\n", command);
2350 if ((newCommand = strdup(command)) != NULL) {
2351 bcmHidePassword(newCommand);
2352 syslog(LOG_DEBUG, newCommand);
2356 execve("/bin/sh", argv, environ);
2360 /* wait for child process return */
2362 if ( waitpid(pid, &status, 0) == -1 ) {
2363 if ( errno != EINTR )
2373 /***************************************************************************
2374 // Function Name: bcmGetPid().
2375 // Description : get process PID by using process name.
2376 // Parameters : command - command that launch the process.
2377 // Returns : process ID number.
2378 ****************************************************************************/
2379 int bcmGetPid(char * command)
2381 char cmdline[128], *p1, *p2;
2387 while ( *p1 != '\0') {
2396 pid = find_pid_by_name(cmdline);
2397 if ( pid != NULL ) {
2406 /***************************************************************************
2407 // Function Name: bcmGetPidList().
2408 // Description : get process PID by using process name.
2409 // Parameters : command - command that launch the process.
2410 // Returns : process ID list
2411 ****************************************************************************/
2412 int *bcmGetPidList(char * command)
2414 char cmdline[128], *p1, *p2;
2419 while ( *p1 != '\0') {
2428 pid = find_pid_by_name(cmdline);
2433 /***************************************************************************
2434 // Function Name: bcmGetIntfNameSocket.
2435 // Description : Return the interface name a socket is bound to
2436 // Parameters : socketfd: Socket descriptor, intfname: Network interface name
2437 // Returns : Failed: -1. Succeeded: 0
2438 ****************************************************************************/
2439 int bcmGetIntfNameSocket(int socketfd, char *intfname)
2442 int numifs = 0, bufsize = 0;
2443 struct ifreq *all_ifr = NULL;
2445 struct sockaddr local_addr;
2446 socklen_t local_len = sizeof(struct sockaddr_in);
2448 memset(&ifc, 0, sizeof(struct ifconf));
2449 memset(&local_addr, 0, sizeof(struct sockaddr));
2451 if (getsockname(socketfd, &local_addr,&local_len) < 0) {
2452 printf("bcmGetIntfNameSocket: Error in getsockname!\n");
2456 //printf("bcmGetIntfNameSocket: Session comes from: %s\n",inet_ntoa(((struct sockaddr_in *)&local_addr)->sin_addr));
2458 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2459 printf("bcmGetIntfNameSocket: Error openning socket when getting socket intface info\n");
2465 bufsize = numifs*sizeof(struct ifreq);
2466 all_ifr = (struct ifreq *)malloc(bufsize);
2467 if (all_ifr == NULL) {
2468 printf("bcmGetIntfNameSocket: out of memory!\n");
2473 ifc.ifc_len = bufsize;
2474 ifc.ifc_buf = (char *)all_ifr;
2475 if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
2476 printf("bcmGetIntfNameSocket: Error getting interfaces\n");
2482 numifs = ifc.ifc_len/sizeof(struct ifreq);
2483 //printf("bcmGetIntfNameSocket: numifs=%d\n",numifs);
2484 for (i = 0; i < numifs; i ++) {
2485 //printf("bcmGetIntfNameSocket: intface name=%s\n",all_ifr[i].ifr_name);
2486 struct in_addr addr1,addr2;
2487 addr1 = ((struct sockaddr_in *)&(local_addr))->sin_addr;
2488 addr2 = ((struct sockaddr_in *)&(all_ifr[i].ifr_addr))->sin_addr;
2489 if (addr1.s_addr == addr2.s_addr) {
2490 strcpy(intfname, all_ifr[i].ifr_name);
2501 static int getLanInfo(char *lan_ifname, struct in_addr *lan_ip, struct in_addr *lan_subnetmask)
2506 if ((socketfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2507 printf("app: Error openning socket when getting LAN info\n");
2511 strcpy(lan.ifr_name,lan_ifname);
2512 if (ioctl(socketfd,SIOCGIFADDR,&lan) < 0) {
2513 printf("app: Error getting LAN IP address\n");
2517 *lan_ip = ((struct sockaddr_in *)&(lan.ifr_addr))->sin_addr;
2519 if (ioctl(socketfd,SIOCGIFNETMASK,&lan) < 0) {
2520 printf("app: Error getting LAN subnet address\n");
2525 *lan_subnetmask = ((struct sockaddr_in *)&(lan.ifr_netmask))->sin_addr;
2531 static int isIpExtension(void)
2534 int ipextension = 0;
2536 if ((fp=fopen("/var/ipextension","r")) != NULL) {
2537 fscanf(fp,"%d",&ipextension);
2544 static void getIpExtIp(char *buf)
2547 char wan[64], gateway[64], dns[64], str[256];
2549 if ( buf == NULL ) return;
2552 fs = fopen("/var/ipextinfo", "r");
2554 fgets(str, 256, fs);
2556 sscanf(str, "%s %s %s\n", wan, gateway, dns);
2561 int isAccessFromLan(struct in_addr clntAddr)
2564 struct in_addr inAddr, inMask;
2567 getLanInfo("br0", &inAddr, &inMask);
2568 /* check ip address of support user to see it is in LAN or not */
2569 if ( (clntAddr.s_addr & inMask.s_addr) == (inAddr.s_addr & inMask.s_addr) )
2572 /* check ip address of support user to see if it is from secondary LAN */
2573 if (bcmCheckInterfaceUp("br0:0")) {
2574 getLanInfo("br0:0", &inAddr, &inMask);
2575 if ( (clntAddr.s_addr & inMask.s_addr) == (inAddr.s_addr & inMask.s_addr) )
2579 /* Last option it must be from WAN side */
2580 if (isIpExtension()) {
2582 if ( clntAddr.s_addr == inet_addr(wan) )
2590 // return 0, ok. return -1 = wrong chip
2591 // used by upload.c and ftpd, tftpd, tftp utilities.
2592 int checkChipId(char *strTagChipId, char *sig2)
2595 unsigned int chipId = (int) sysGetChipId();
2598 if (strstr(sig2, "Firmware"))
2599 return result; // skip the pre 2_14L02 release, where the signiture_2 is "Firmware version 1.0"
2601 tagChipId = atoi(strTagChipId);
2606 if (!(tagChipId == 6338))
2610 if (!(tagChipId == 6345 || tagChipId == 6335))
2614 if (tagChipId != 6348)
2618 printf("Chip id %04x not supported.\n", chipId);
2624 printf("Chip Id error. Image Chip Id = %d, Board Chip Id = %04x.\n", tagChipId, chipId);
2629 /***************************************************************************
2630 // Function Name: bcmCheckForRedirect(void)
2631 // Description : check for nat redirect for .
2632 // Parameters : none
2633 // Returns : 0 --> tcp port 21, 22, 23, 80 is redirected. -1 --> not redirected
2634 ****************************************************************************/
2635 int bcmCheckForRedirect(void)
2642 bcmSystem("iptables -t nat -L > /var/nat_redirect");
2644 fs = fopen("/var/nat_redirect", "r");
2646 while ( fgets(line, sizeof(line), fs) ) {
2647 // read pass 3 header lines
2650 sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s",
2651 col[0], col[1], col[2], col[3], col[4], col[5],
2652 col[6], col[7], col[8], col[9], col[10]);
2653 if ((strcmp(col[0], "REDIRECT") == 0) && (strcmp(col[1], "tcp") == 0) && (strcmp(col[8], "ports") == 0))
2654 if (strcmp(col[9], "80") == 0 || strcmp(col[9], "23") == 0 || strcmp(col[9], "21") == 0 ||
2655 strcmp(col[9], "22") == 0 || strcmp(col[9], "69") == 0) {
2661 unlink("/var/nat_redirect");
2665 /***************************************************************************
2666 // Function Name: bcmRemoveModules(int lanIf)
2667 // Description : remove not used modules to free memory.
2668 // Parameters : none
2670 ****************************************************************************/
2671 void bcmRemoveModules(int lanIf)
2676 #ifndef SUPPORT_ETHWAN
2696 "ip_conntrack_tftp",
2699 "ip_conntrack_h323",
2700 "ip_conntrack_pptp",
2702 "ip_conntrack_rtsp",
2703 "ip_conntrack_ipsec",
2712 char cmd[SYS_CMD_LEN];
2714 int saveNat = FALSE;
2716 if (lanIf == 0) // if lan, do not kill bcm_usb and bcm_enet
2719 saveNat = bcmCheckForRedirect();
2721 if (bcmIsModuleInserted("iptable_filter") == TRUE)
2723 strncpy(cmd, "iptables -t filter -F", SYS_CMD_LEN-1);
2726 if (bcmIsModuleInserted("iptable_nat") == TRUE)
2728 strncpy(cmd, "iptables -t nat -F", SYS_CMD_LEN-1);
2731 if (bcmIsModuleInserted("iptable_mangle") == TRUE)
2733 strncpy(cmd, "iptables -t mangle -F", SYS_CMD_LEN-1);
2737 while (modList[i] != NULL)
2739 if (bcmIsModuleInserted(modList[i]) == TRUE)
2741 if (!(saveNat && strcmp(modList[i], "iptable_nat") == 0))
2743 sprintf(cmd, "rmmod %s", modList[i]);
2749 printf("\nRemaining modules:\n");
2750 bcmSystemMute("cat /proc/modules");
2751 printf("\nMemory info:\n");
2752 bcmSystemMute("sysinfo");
2756 /***************************************************************************
2757 // Function Name: bcmGetIfcIndexByName().
2758 // Description : get interface index by its name.
2759 // Parameters : ifcIdx -- interface index.
2760 // ifcName -- interface name.
2761 // Returns : interface index
2762 ****************************************************************************/
2763 int bcmGetIntf(char *ifcName) {
2767 if ( ifcName == NULL ) return -1;
2769 if ( (s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) return -1;
2770 strcpy(ifr.ifr_name, ifcName);
2771 if ( ioctl(s, SIOCGIFINDEX, &ifr) < 0 ) {
2776 return ifr.ifr_ifindex;
2779 int bcmWaitIntfExists(char *ifName) {
2783 while (retry < 50) {
2784 if ((ret =bcmGetIntf(ifName)) <= 0) {
2786 //printf("not exist,retry %d, ret %d\n",retry,ret);
2796 //**************************************************************************
2797 // Function Name: bcmMacStrToNum
2798 // Description : convert MAC address from string to array of 6 bytes.
2799 // Ex: 0a:0b:0c:0d:0e:0f -> 0a0b0c0d0e0f
2800 // Returns : status.
2801 //**************************************************************************
2802 int bcmMacStrToNum(char *macAddr, char *str) {
2803 char *pToken = NULL, *pLast = NULL;
2808 if ( macAddr == NULL ) return FALSE;
2809 if ( str == NULL ) return FALSE;
2811 len = strlen(str) + 1;
2814 buf = (char*)malloc(len);
2817 if ( buf == NULL ) return FALSE;
2819 /* need to copy since strtok_r updates string */
2820 strncpy(buf, str,len-1);
2822 /* Mac address has the following format
2823 xx:xx:xx:xx:xx:xx where x is hex number */
2824 pToken = strtok_r(buf, ":", &pLast);
2825 macAddr[0] = (char) strtol(pToken, (char **)NULL, 16);
2826 for ( i = 1; i < 6; i++ ) {
2827 pToken = strtok_r(NULL, ":", &pLast);
2828 macAddr[i] = (char) strtol(pToken, (char **)NULL, 16);
2836 //**************************************************************************
2837 // Function Name: bcmMacNumToStr
2838 // Description : convert MAC address from array of 6 bytes to string.
2839 // Ex: 0a0b0c0d0e0f -> 0a:0b:0c:0d:0e:0f
2840 // Returns : status.
2841 //**************************************************************************
2842 int bcmMacNumToStr(char *macAddr, char *str) {
2843 if ( macAddr == NULL ) return FALSE;
2844 if ( str == NULL ) return FALSE;
2846 sprintf(str, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
2847 (UINT8) macAddr[0], (UINT8) macAddr[1], (UINT8) macAddr[2],
2848 (UINT8) macAddr[3], (UINT8) macAddr[4], (UINT8) macAddr[5]);
2856 #ifdef PORT_MIRRORING
2857 /***************************************************************************
2858 * Function Name: OpenBlaaDD
2859 * Description : Opens the bcmatm device.
2860 * Returns : device handle if successsful or -1 if error
2861 ***************************************************************************/
2862 static int OpenBlaaDD( void )
2866 if( (nFd = open("/dev/bcmatm0", O_RDWR)) < 0 )
2867 printf( "OpenBlaaDD : open error %d\n", errno );
2874 /***************************************************************************
2875 // Function Name: bcmConfigPortMirroring.
2876 // Description : Configure the Port Mirroring feature dynamically.
2877 // Parameters : MirrorCfg structure pointer.
2878 // Returns : Failed: -1. Succeeded: 0
2879 ****************************************************************************/
2880 int bcmConfigPortMirroring (void *pCfg)
2883 MirrorCfg *pMirrorCfg = (MirrorCfg *) pCfg ;
2886 #ifdef PORTMIRROR_DEBUG
2887 printf ("ENGDBG:- In BcmConfigPortMirroring \n") ;
2890 if ((fd = OpenBlaaDD ()) < 0) {
2891 printf ("Config Port Mirroring Failed \n") ;
2895 if (ioctl(fd, ATMIOCTL_PORT_MIRRORING, pMirrorCfg) < 0) {
2897 printf("IOCTL to BLAA Drive for Port Mirror CFG failed . Fatal \n") ;
2908 /***************************************************************************
2909 // Function Name: bcmRemoveTrafficControlRules.
2910 // Description : remove tc rules for this interface if QoS is enabled.
2912 ****************************************************************************/
2913 void bcmRemoveTrafficControlRules(UINT16 vpi, UINT16 vci, UINT16 conId, UINT8 protocol) {
2915 char cmd[SYS_CMD_LEN];
2917 if (protocol != PROTO_PPPOA) {
2922 snprintf(ifc, 16, "ppp_%d_%d_%d", vpi, vci, conId);
2923 sprintf(cmd, "tc qdisc del dev %s root", ifc);
2927 /***************************************************************************
2928 // Function Name: bcmAddTrafficControlRules.
2929 // Description : add tc rules for this interface if QoS is enabled.
2931 ****************************************************************************/
2932 void bcmAddTrafficControlRules(UINT16 vpi, UINT16 vci, UINT16 conId, UINT8 protocol) {
2934 char cmd[SYS_CMD_LEN];
2935 ADSL_CONNECTION_INFO adslInfo;
2938 if (protocol != PROTO_PPPOA) {
2943 sprintf(ifc, "ppp_%d_%d_%d", vpi, vci, conId);
2944 // Get the actual upstream line rate from the ADSL driver.
2945 BcmAdslCtl_GetConnectionInfo(&adslInfo);
2946 if (adslInfo.LinkState != BCM_ADSL_LINK_UP) {
2949 if ( adslInfo.ulInterleavedUpStreamRate != 0 )
2950 lineRate = adslInfo.ulInterleavedUpStreamRate;
2952 lineRate = adslInfo.ulFastUpStreamRate;
2954 // Before we do anythng, lets add an ebtable rule at the bottom, that
2955 // marks the packets with low priority mark as default 0x0001.
2956 sprintf(cmd, "ebtables -t broute -A BROUTING -j mark --set-mark 0x0001 -p IPv4");
2959 // Create the root. This also creates the classes 1:1, 1:2 and 1:3
2961 sprintf(cmd, "tc qdisc add dev %s root handle 1: htb default 1", ifc);
2963 sprintf(cmd, "tc class add dev %s parent 1: classid 1:1 htb rate %lukbit",
2964 ifc, adslInfo.ulInterleavedUpStreamRate);
2966 sprintf(cmd, "tc qdisc add dev %s parent 1:1 handle 10: prio bands 3 "
2967 "priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", ifc);
2969 // Create the htb's under each class.
2970 sprintf(cmd, "tc qdisc add dev %s parent 10:1 handle 100: pfifo limit 10", ifc);
2972 sprintf(cmd, "tc qdisc add dev %s parent 10:2 handle 200: pfifo limit 10", ifc);
2974 sprintf(cmd, "tc qdisc add dev %s parent 10:3 handle 300: pfifo limit 10", ifc);
2976 // Now add the filters for each sfq using the default handles.
2977 sprintf(cmd, "tc filter add dev %s protocol ip parent 10:0 prio 1 handle %d fw classid 10:1",
2978 ifc, PRIORITY_HIGH);
2980 sprintf(cmd, "tc filter add dev %s protocol ip parent 10:0 prio 1 handle %d fw classid 10:2",
2981 ifc, PRIORITY_MEDIUM);
2983 sprintf(cmd, "tc filter add dev %s protocol ip parent 10:0 prio 1 handle %d fw classid 10:3",