| /* |
| * ffcontrol.c: Fast Forward Control |
| * |
| * Copyright (C) 2007 Mindspeed Technologies, Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #include "cmm.h" |
| |
| #include <sys/ioctl.h> |
| #include <net/if.h> |
| #include <sys/socket.h> |
| #include <string.h> |
| #include <signal.h> |
| #include <ctype.h> |
| |
| #include <bits/sockaddr.h> |
| #include <asm/types.h> |
| #include <linux/netlink.h> |
| #include <linux/rtnetlink.h> |
| |
| #include "ffbridge.h" |
| #include "pppoe.h" |
| #include "cmmd.h" |
| #include "fpp.h" |
| |
| struct denyRuleList * denyRules = NULL; |
| struct asymFFRuleList * asymFFRules = NULL; |
| #ifdef WIFI_ENABLE |
| struct wifi_ff_entry glbl_wifi_ff_ifs[MAX_WIFI_FF_IFS]; |
| #endif |
| |
| /***************************************************************** |
| * cmmFcIsLocal() |
| * |
| * |
| ******************************************************************/ |
| static int cmmFcIsLocal(FCI_CLIENT *fci_handle, struct nf_conntrack *ct, struct flow *flow_orig, struct RtEntry **rtEntryOrig) |
| { |
| char saddr_buf[INET6_ADDRSTRLEN], daddr_buf[INET6_ADDRSTRLEN]; |
| int iif; |
| |
| /* Filter local->outside connections, iif = 0 because packets doesn't go through pre-routing hook */ |
| iif = nfct_get_attr_u32(ct, ATTR_ORIG_COMCERTO_FP_IIF); |
| if (!iif) |
| goto local; |
| |
| /* Filter local->local connections */ |
| if (iif == LO_IFINDEX) |
| goto local; |
| |
| if (!*rtEntryOrig) |
| { |
| *rtEntryOrig = __cmmRouteGet(flow_orig); |
| if (!*rtEntryOrig) |
| goto local; |
| } |
| |
| if ((*rtEntryOrig)->type != RTN_UNICAST) |
| goto local; |
| |
| return 0; |
| |
| local: |
| if (*rtEntryOrig) |
| { |
| ____cmmRouteDeregister(*rtEntryOrig, "originator"); |
| *rtEntryOrig = NULL; |
| } |
| |
| cmm_print(DEBUG_WARNING, "%s: conntrack local dst:%s src:%s\n", __func__, |
| inet_ntop(flow_orig->family, flow_orig->sAddr, saddr_buf, INET6_ADDRSTRLEN), |
| inet_ntop(flow_orig->family, flow_orig->dAddr, daddr_buf, INET6_ADDRSTRLEN)); |
| |
| return 1; |
| } |
| |
| /***************************************************************** |
| * cmmIsConntrack4Allowed() |
| * |
| * |
| ******************************************************************/ |
| #define MULTICAST(x) (((x) & htonl(0xf0000000)) == htonl(0xe0000000)) |
| int cmmFcIsConntrack4Allowed(FCI_CLIENT *fci_handle, struct nf_conntrack *ct, struct RtEntry **rtEntryOrig) |
| { |
| struct denyRuleList * temp; |
| denyRule_t tempRule; |
| unsigned int sAddr, dAddr; |
| struct flow flow_orig; |
| char saddr_buf[INET_ADDRSTRLEN], raddr_buf[INET_ADDRSTRLEN]; |
| |
| sAddr = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC); |
| dAddr = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC); |
| |
| /* Multicast connections are not forwarded */ |
| if (MULTICAST(dAddr)) { |
| cmm_print(DEBUG_WARNING, "%s: conntrack multicast dst:%s:%x src:%s:%x\n", __func__, |
| inet_ntop(AF_INET, &sAddr, saddr_buf, sizeof(saddr_buf)),sAddr, |
| inet_ntop(AF_INET, &dAddr, raddr_buf, sizeof(raddr_buf)),dAddr); |
| goto refused; |
| } |
| |
| flow_orig.family = AF_INET; |
| flow_orig.sAddr = &sAddr; |
| flow_orig.dAddr = &dAddr; |
| flow_orig.iifindex = nfct_get_attr_u32(ct, ATTR_ORIG_COMCERTO_FP_IFINDEX); |
| flow_orig.fwmark = nfct_get_attr_u32(ct, ATTR_ORIG_COMCERTO_FP_MARK); |
| |
| if (cmmFcIsLocal(fci_handle, ct, &flow_orig, rtEntryOrig)) { |
| cmm_print(DEBUG_INFO, "%s: local connection refused\n", __func__); |
| goto refused; |
| } |
| |
| /*Go through each rule to see if it is allowed*/ |
| for(temp = denyRules ; temp != NULL ; temp = temp->next) |
| { |
| for(tempRule = temp->rule ; tempRule != NULL ; tempRule = tempRule->next) |
| { |
| unsigned int temp = 0; |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| unsigned int temp_shift = tempRule->value; |
| #endif |
| |
| const void *ret = nfct_get_attr(ct, tempRule->type); |
| if(ret == NULL) { //If ret==NULL it means we are not able to get the informations we need from the conntrack, check next rule (default is accept) |
| cmm_print(DEBUG_ERROR, "%s: can't get infos from conntrack, connection refused\n", __func__); |
| break; |
| } |
| |
| memcpy(&temp, ret, tempRule->width); |
| temp &= tempRule->mask; |
| |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| // bytes shift only in case of short type and big endian |
| if ( tempRule->width == 2) { |
| temp_shift = tempRule->value << 16; |
| } |
| #endif |
| |
| |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, temp_shift, tempRule->mask, tempRule->width); |
| if (memcmp(&temp, &temp_shift, tempRule->width)) { |
| #else |
| cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, tempRule->value, tempRule->mask, tempRule->width); |
| if (memcmp(&temp, &tempRule->value, tempRule->width)) { |
| #endif |
| cmm_print(DEBUG_INFO, "%s: rule does not match\n", __func__); |
| break; |
| } else { |
| cmm_print(DEBUG_INFO, "%s: rule's attribute matched, check next one(s)\n", __func__); |
| } |
| } |
| |
| /* |
| * We reach the end of the list meaning all the values matched |
| * So the conntrack is not allowed to be FastForwarded |
| */ |
| if(tempRule == NULL) |
| { |
| cmm_print(DEBUG_INFO, "%s: conntrack refused by rules\n", __func__); |
| goto refused; |
| } |
| |
| cmm_print(DEBUG_INFO, "%s: check next deny rule\n", __func__); |
| } |
| |
| cmm_print(DEBUG_INFO, "%s: conntrack accepted\n", __func__); |
| |
| return 1; |
| |
| refused: |
| return 0; |
| } |
| |
| /***************************************************************** |
| * cmmIsConntrack6Allowed() |
| * |
| * |
| ******************************************************************/ |
| int cmmFcIsConntrack6Allowed(FCI_CLIENT *fci_handle, struct nf_conntrack * ct, struct RtEntry **rtEntryOrig) |
| { |
| struct denyRuleList * temp; |
| denyRule_t tempRule; |
| struct flow flow_orig; |
| const unsigned int *Saddr, *SaddrReply; |
| |
| /*Local connections are not Fast Forwarded*/ |
| Saddr = nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC); |
| SaddrReply = nfct_get_attr(ct, ATTR_REPL_IPV6_SRC); |
| |
| if ((SaddrReply[0] & ntohl(0xff000000)) == ntohl(0xff000000)) |
| { |
| goto refused; |
| } |
| |
| flow_orig.family = AF_INET6; |
| flow_orig.sAddr = Saddr; |
| flow_orig.dAddr = SaddrReply; |
| flow_orig.iifindex = nfct_get_attr_u32(ct, ATTR_ORIG_COMCERTO_FP_IFINDEX); |
| flow_orig.fwmark = nfct_get_attr_u32(ct, ATTR_ORIG_COMCERTO_FP_MARK); |
| |
| if (cmmFcIsLocal(fci_handle, ct, &flow_orig, rtEntryOrig)) { |
| cmm_print(DEBUG_INFO, "%s: local connection refused\n", __func__); |
| goto refused; |
| } |
| |
| /*Go through each rule to see if it is allowed*/ |
| for(temp = denyRules ; temp != NULL ; temp = temp->next) |
| { |
| for(tempRule = temp->rule ; tempRule != NULL ; tempRule = tempRule->next) |
| { |
| unsigned int temp = 0; |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| unsigned int temp_shift = tempRule->value; |
| #endif |
| struct in6_addr *valueIpV6Ret, valueIpV6Tmp ; |
| |
| |
| if ((tempRule->type == ATTR_ORIG_IPV6_SRC )|| (tempRule->type == ATTR_ORIG_IPV6_DST ) |
| || (tempRule->type == ATTR_REPL_IPV6_SRC ) || (tempRule->type == ATTR_REPL_IPV6_DST )) { |
| |
| valueIpV6Ret = (struct in6_addr *)nfct_get_attr(ct, tempRule->type); |
| if(valueIpV6Ret == NULL) {//If ret==NULL it means we are not able to get the informations we need from the conntrack, check next rule (default is accept) |
| cmm_print(DEBUG_ERROR, "%s: can't get infos from conntrack, jumps to next rule\n", __func__); |
| break; |
| } |
| |
| if(16 != tempRule->width) {//width of IPv6 address should be of 16 bytes |
| cmm_print(DEBUG_ERROR, "%s: Incorrect width in the rule, jumps to next rule\n", __func__); |
| break; |
| } |
| |
| memcpy(&valueIpV6Tmp.s6_addr[0], &valueIpV6Ret->s6_addr[0], tempRule->width); |
| |
| if (memcmp(&valueIpV6Tmp.s6_addr[0], &tempRule->valueIpV6.s6_addr[0], tempRule->width)) { |
| cmm_print(DEBUG_INFO, "%s: rule does not match\n", __func__); |
| break; |
| } else { |
| cmm_print(DEBUG_INFO, "%s: rule's attribute matched, check next one(s)\n", __func__); |
| } |
| } |
| else { |
| const void *ret = nfct_get_attr(ct, tempRule->type); |
| if(ret == NULL) {//If ret==NULL it means we are not able to get the informations we need from the conntrack, check next rule (default is accept) |
| cmm_print(DEBUG_ERROR, "%s: can't get infos from conntrack, jumps to next rule\n", __func__); |
| break; |
| } |
| |
| memcpy(&temp, ret, tempRule->width); |
| temp &= tempRule->mask; |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| // bytes shift only in case of short type and big endian |
| if ( tempRule->width == 2) { |
| temp_shift = tempRule->value << 16; |
| } |
| #endif |
| |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, temp_shift, tempRule->mask, tempRule->width); |
| if (memcmp(&temp, &temp_shift, tempRule->width)) { |
| #else |
| cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, tempRule->value, tempRule->mask, tempRule->width); |
| if (memcmp(&temp, &tempRule->value, tempRule->width)) { |
| #endif |
| cmm_print(DEBUG_INFO, "%s: rule does not match\n", __func__); |
| break; |
| } else { |
| cmm_print(DEBUG_INFO, "%s: rule's attribute matched, check next one(s)\n", __func__); |
| } |
| } |
| } |
| |
| /* |
| * We reach the end of the list meaning all the values matched |
| * So the conntrack is not allowed to be FastForwarded |
| */ |
| if(tempRule == NULL) |
| { |
| cmm_print(DEBUG_INFO, "%s: conntrack refused by rules\n", __func__); |
| goto refused; |
| } |
| |
| cmm_print(DEBUG_INFO, "%s: check next deny rule\n", __func__); |
| } |
| |
| cmm_print(DEBUG_INFO, "%s: conntrack accepted\n", __func__); |
| |
| return 1; |
| |
| refused: |
| return 0; |
| } |
| |
| /***************************************************************** |
| * cmmFcStop |
| * |
| * |
| ******************************************************************/ |
| int cmmFcStop(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| cli_print(cli, "Killing cmm ...\n"); |
| |
| kill(0, SIGTERM); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmFcActivate |
| * |
| * |
| ******************************************************************/ |
| int cmmFcActivate(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| int val; |
| int family; |
| |
| if (argc < 1) |
| goto usage; |
| |
| //Check if it is a digit. atoi() returns 0 if not digit |
| if(! isdigit(*argv[0])) |
| goto usage; |
| |
| val = atoi(argv[0]); |
| if (globalConf.enable != val) |
| { |
| if (val == 0) |
| { |
| /*Reset Forward Engine*/ |
| cmmFeReset(globalConf.cli.fci_handle); |
| globalConf.enable = val; |
| } |
| else if (val == 1) |
| { |
| /*Reset Forward Engine*/ |
| cmmFeReset(globalConf.cli.fci_handle); |
| globalConf.enable = val; |
| |
| /*Get already existing ipv4 conntrack*/ |
| family = AF_INET; |
| if (nfct_query(globalConf.ct.catch_handle, NFCT_Q_DUMP, (void *) &family) < 0) |
| cmm_print(DEBUG_ERROR, "%s: nfct_query(NFCT_Q_DUMP) %s\n", __func__, strerror(errno)); |
| |
| /*Get already existing ipv6 conntrack*/ |
| family = AF_INET6; |
| if (nfct_query(globalConf.ct.catch_handle, NFCT_Q_DUMP, (void *) &family) < 0) |
| cmm_print(DEBUG_ERROR, "%s: nfct_query(NFCT_Q_DUMP) %s\n", __func__, strerror(errno)); |
| } |
| else |
| goto usage; |
| } |
| |
| return CLI_OK; |
| |
| usage: |
| cli_print(cli, "Usage: activate <0 1>"); |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmFcDesactivate |
| * |
| * |
| ******************************************************************/ |
| int cmmFcActivateShow(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| cli_print(cli, "%d", globalConf.enable); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmFcDesactivate |
| * |
| * |
| ******************************************************************/ |
| int cmmFcDebug(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| int val; |
| int flag = 0; |
| |
| if (argc < 2) |
| goto usage; |
| |
| if (strncmp(argv[0], "command", strlen(argv[0])) == 0) |
| flag = DEBUG_COMMAND; |
| else if (strncmp(argv[0], "error", strlen(argv[0])) == 0) |
| flag = DEBUG_ERROR; |
| else if (strncmp(argv[0], "warning", strlen(argv[0])) == 0) |
| flag = DEBUG_WARNING; |
| else if (strncmp(argv[0], "info", strlen(argv[0])) == 0) |
| flag = DEBUG_INFO; |
| else |
| goto usage; |
| |
| //Check if it is a digit. atoi() returns 0 if not digit |
| if(! isdigit(*argv[1])) |
| goto usage; |
| |
| val = atoi(argv[1]); |
| if (val == 0) |
| globalConf.debug_level &= ~flag; |
| else if (val == 1) |
| globalConf.debug_level |= flag; |
| else |
| goto usage; |
| |
| return CLI_OK; |
| |
| usage: |
| cli_print(cli, "Usage: set debug <command error warning info> <0 1>"); |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmFcDebugShow |
| * |
| * |
| ******************************************************************/ |
| int cmmFcDebugShow(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| cli_print(cli, "command:\t%s", (globalConf.debug_level & DEBUG_COMMAND) ? "printed": "not printed"); |
| cli_print(cli, "error: \t%s", (globalConf.debug_level & DEBUG_ERROR) ? "printed": "not printed"); |
| cli_print(cli, "warning:\t%s", (globalConf.debug_level & DEBUG_WARNING) ? "printed": "not printed"); |
| cli_print(cli, "info: \t%s", (globalConf.debug_level & DEBUG_INFO) ? "printed": "not printed"); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmFcAsymFFRuleAddAtrribut() |
| * |
| * |
| ******************************************************************/ |
| asymFFRule_t cmmFcAsymFFRuleAddAttribut(asymFFRule_t rule, int attributType, int attributValue, char *attrStrValue, int attributWidth, int mask) |
| { |
| asymFFRule_t temp; |
| |
| temp = (asymFFRule_t) malloc(sizeof(asymFFRule)); |
| if (temp ==NULL) |
| return rule; |
| |
| temp->next = rule; |
| temp->type = attributType; |
| temp->value = attributValue; |
| strcpy(temp->strValue,attrStrValue); |
| temp->width = attributWidth; |
| temp->mask = mask; |
| |
| return temp; |
| } |
| |
| /***************************************************************** |
| * cmmFcAsymFFListAddRule() |
| * |
| * |
| ******************************************************************/ |
| struct asymFFRuleList * cmmFcAsymFFListAddRule(struct asymFFRuleList *list, char * ruleName, asymFFRule_t rule) |
| { |
| struct asymFFRuleList * temp; |
| |
| temp = (struct asymFFRuleList *) malloc(sizeof(struct asymFFRuleList)); |
| if (temp == NULL) |
| return list; |
| |
| temp->next = list; |
| temp->rule = rule; |
| strncpy(temp->name, ruleName, sizeof(temp->name)); |
| |
| return temp; |
| } |
| |
| /***************************************************************** |
| * cmmFcAsymFFRulesShow() |
| * |
| * Print rules on CLI |
| ******************************************************************/ |
| int cmmFcAsymFFRulesShow(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| struct asymFFRuleList *rulesList; |
| struct asymFFRule *rule; |
| |
| for(rulesList = asymFFRules ; rulesList != NULL ; rulesList = rulesList->next) |
| { |
| cli_print(cli, "\n%s:", rulesList->name); |
| for(rule = rulesList->rule ; rule != NULL ; rule = rule->next) |
| { |
| switch(rule->type) |
| { |
| case ATTR_ORIG_PORT_SRC: |
| cli_print(cli, "\t%s: %d mask %x", ATTR_ORIG_PORT_SRC_STR, ntohs(rule->value), rule->mask); |
| break; |
| |
| case ATTR_ORIG_PORT_DST: |
| cli_print(cli, "\t%s: %d mask %x", ATTR_ORIG_PORT_DST_STR, ntohs(rule->value), rule->mask); |
| break; |
| |
| case ATTR_ORIG_L4PROTO: |
| if (rule->value == IPPROTO_TCP) |
| cli_print(cli, "\t%s: tcp (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask); |
| else if (rule->value == IPPROTO_UDP) |
| cli_print(cli, "\t%s: udp (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask); |
| else if (rule->value == IPPROTO_IPIP) |
| cli_print(cli, "\t%s: ipip (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask); |
| else |
| cli_print(cli, "\t%s: unknown (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask); |
| break; |
| |
| case ATTR_L3PROTO: |
| if (rule->value == AF_INET) |
| cli_print(cli, "\t%s: ipv4 (%d) mask %x", ATTR_L3_PROTO_STR, rule->value, rule->mask); |
| else if (rule->value == AF_INET6) |
| cli_print(cli, "\t%s: ipv6 (%d) mask %x", ATTR_L3_PROTO_STR, rule->value, rule->mask); |
| |
| break; |
| case ATTR_ORIG_COMCERTO_FP_IIF: |
| cli_print(cli, "\tinterface: %s", rule->strValue); |
| break; |
| default: |
| cli_print(cli, "\tERROR"); |
| } |
| } |
| } |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmFcIsConntrackAsymFastForwarded() |
| * |
| * |
| ******************************************************************/ |
| int cmmFcIsConntrackAsymFastForwarded(struct nf_conntrack *ct) |
| { |
| struct asymFFRuleList * temp; |
| asymFFRule_t tempRule; |
| int iif; |
| struct interface *itf; |
| |
| /*Go through each rule to see if it is allowed*/ |
| for(temp = asymFFRules ; temp != NULL ; temp = temp->next) |
| { |
| for(tempRule = temp->rule ; tempRule != NULL ; tempRule = tempRule->next) |
| { |
| unsigned int temp = 0; |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| unsigned int temp_shift = tempRule->value; |
| #endif |
| |
| const void *ret = nfct_get_attr(ct, tempRule->type); |
| if(ret == NULL) { //If ret==NULL it means we are not able to get the informations we need from the conntrack, check next rule (default is accept) |
| cmm_print(DEBUG_ERROR, "%s: can't get infos from conntrack, connection refused\n", __func__); |
| break; |
| } |
| |
| if(tempRule->type == ATTR_ORIG_COMCERTO_FP_IIF) |
| { |
| memcpy(&iif, ret, tempRule->width); |
| itf = __itf_find(iif); |
| if (!itf) { |
| cmm_print(DEBUG_ERROR, "%s: can't get inteface details from conntrack\n", __func__); |
| goto out; |
| } |
| if(!strcmp(itf->ifname,tempRule->strValue)) { |
| cmm_print(DEBUG_INFO, "%s: interface attribute matched, check next atribute\n", __func__); |
| } |
| else { |
| cmm_print(DEBUG_INFO, "%s: rule does not match\n", __func__); |
| break; |
| } |
| } |
| else { |
| memcpy(&temp, ret, tempRule->width); |
| temp &= tempRule->mask; |
| |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| // bytes shift only in case of short type and big endian |
| if ( tempRule->width == 2) { |
| temp_shift = tempRule->value << 16; |
| } |
| #endif |
| |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, temp_shift, tempRule->mask, tempRule->width); |
| if (memcmp(&temp, &temp_shift, tempRule->width)) { |
| #else |
| cmm_print(DEBUG_INFO, "%s: ct attr %x - rule value %x rule mask %x rule width %x\n", __func__, temp, tempRule->value, tempRule->mask, tempRule->width); |
| if (memcmp(&temp, &tempRule->value, tempRule->width)) { |
| #endif |
| cmm_print(DEBUG_INFO, "%s: rule does not match\n", __func__); |
| break; |
| } else { |
| cmm_print(DEBUG_INFO, "%s: rule's attribute matched, check next one(s)\n", __func__); |
| } |
| } |
| } |
| |
| /* |
| * We reach the end of the list meaning all the values matched |
| * So the conntrack should be asymmetrically FastForwarded |
| */ |
| if(tempRule == NULL) |
| { |
| cmm_print(DEBUG_INFO, "%s: conntrack should be asym forwarded as per rules\n", __func__); |
| goto asym_forward; |
| } |
| |
| cmm_print(DEBUG_INFO, "%s: check next Asym Fastpath rule\n", __func__); |
| } |
| |
| //cmm_print(DEBUG_INFO, "%s: conntrack accepted\n", __func__); |
| out: |
| return 0; |
| |
| asym_forward: |
| return 1; |
| } |
| |
| |
| /***************************************************************** |
| * cmmFcRuleAddAtrribut() |
| * |
| * |
| ******************************************************************/ |
| denyRule_t cmmFcRuleAddAttribut(denyRule_t rule, int attributType, int attributValue, int attributWidth, int mask, const u_int8_t *attrValIpV6) |
| { |
| denyRule_t temp; |
| |
| if ( (attributWidth == 16) && (attrValIpV6 == NULL) ) |
| return rule; |
| |
| |
| temp = (denyRule_t) malloc(sizeof(denyRule)); |
| if (temp ==NULL) |
| return rule; |
| |
| temp->next = rule; |
| temp->type = attributType; |
| temp->value = attributValue; |
| temp->width = attributWidth; |
| temp->mask = mask; |
| |
| if (attributWidth == 16) |
| memcpy(&temp->valueIpV6.s6_addr[0], attrValIpV6, attributWidth) ; |
| |
| return temp; |
| } |
| |
| /***************************************************************** |
| * cmmFcListAddRule() |
| * |
| * |
| ******************************************************************/ |
| struct denyRuleList * cmmFcListAddRule(struct denyRuleList *list, char * ruleName, denyRule_t rule) |
| { |
| struct denyRuleList * temp; |
| |
| temp = (struct denyRuleList *) malloc(sizeof(struct denyRuleList)); |
| if (temp == NULL) |
| return list; |
| |
| temp->next = list; |
| temp->rule = rule; |
| strncpy(temp->name, ruleName, sizeof(temp->name)); |
| |
| return temp; |
| } |
| |
| /***************************************************************** |
| * cmmFcRulesShow() |
| * |
| * Print rules on CLI |
| ******************************************************************/ |
| int cmmFcRulesShow(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| struct denyRuleList *rulesList; |
| struct denyRule *rule; |
| char *ipv4Address; |
| struct in_addr tmp; |
| char ipv6Address[INET6_ADDRSTRLEN]; |
| |
| |
| for(rulesList = denyRules ; rulesList != NULL ; rulesList = rulesList->next) |
| { |
| cli_print(cli, "\n%s:", rulesList->name); |
| for(rule = rulesList->rule ; rule != NULL ; rule = rule->next) |
| { |
| switch(rule->type) |
| { |
| case ATTR_ORIG_PORT_SRC: |
| cli_print(cli, "\t%s: %d mask %x", ATTR_ORIG_PORT_SRC_STR, ntohs(rule->value), rule->mask); |
| break; |
| |
| case ATTR_ORIG_PORT_DST: |
| cli_print(cli, "\t%s: %d mask %x", ATTR_ORIG_PORT_DST_STR, ntohs(rule->value), rule->mask); |
| break; |
| |
| case ATTR_REPL_PORT_SRC: |
| cli_print(cli, "\t%s: %d mask %x", ATTR_REPL_PORT_SRC_STR, ntohs(rule->value), rule->mask); |
| break; |
| |
| case ATTR_REPL_PORT_DST: |
| cli_print(cli, "\t%s: %d mask %x", ATTR_REPL_PORT_DST_STR, ntohs(rule->value), rule->mask); |
| break; |
| |
| case ATTR_MARK: |
| cli_print(cli, "\t%s: %d mask %x", ATTR_MARK_STR, rule->value, rule->mask); |
| break; |
| |
| case ATTR_ORIG_IPV4_SRC: |
| tmp.s_addr = (unsigned int)rule->value ; |
| ipv4Address = inet_ntoa(tmp) ; |
| if (ipv4Address == NULL){ |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address"); |
| break; |
| } |
| cli_print(cli, "\t%s: %s mask %x", ATTR_ORIG_IPV4_SRC_STR, ipv4Address, rule->mask); |
| break; |
| |
| case ATTR_ORIG_IPV4_DST: |
| tmp.s_addr = (unsigned int)rule->value ; |
| ipv4Address = inet_ntoa(tmp) ; |
| if (ipv4Address == NULL){ |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address"); |
| break; |
| } |
| cli_print(cli, "\t%s: %s mask %x", ATTR_ORIG_IPV4_DST_STR, ipv4Address, rule->mask); |
| break; |
| |
| case ATTR_REPL_IPV4_SRC: |
| tmp.s_addr = (unsigned int)rule->value ; |
| ipv4Address = inet_ntoa(tmp) ; |
| if (ipv4Address == NULL){ |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address"); |
| break; |
| } |
| cli_print(cli, "\t%s: %s mask %x", ATTR_REPL_IPV4_SRC_STR, ipv4Address, rule->mask); |
| break; |
| |
| case ATTR_REPL_IPV4_DST: |
| tmp.s_addr = (unsigned int)rule->value ; |
| ipv4Address = inet_ntoa(tmp) ; |
| if (ipv4Address == NULL){ |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address"); |
| break; |
| } |
| cli_print(cli, "\t%s: %s mask %x", ATTR_REPL_IPV4_DST_STR, ipv4Address, rule->mask); |
| break; |
| |
| case ATTR_ORIG_IPV6_SRC: |
| if (! inet_ntop(AF_INET6, ((struct in6_addr *)&(rule->valueIpV6)), ipv6Address, INET6_ADDRSTRLEN)){ |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address"); |
| break; |
| } |
| cli_print(cli, "\t%s: %s mask %x", ATTR_ORIG_IPV6_SRC_STR, ipv6Address, rule->mask); |
| break; |
| |
| case ATTR_ORIG_IPV6_DST: |
| if (! inet_ntop(AF_INET6, ((struct in6_addr *)&(rule->valueIpV6)), ipv6Address, INET6_ADDRSTRLEN)){ |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address"); |
| break; |
| } |
| cli_print(cli, "\t%s: %s mask %x", ATTR_ORIG_IPV4_DST_STR, ipv6Address, rule->mask); |
| break; |
| |
| case ATTR_REPL_IPV6_SRC: |
| if (! inet_ntop(AF_INET6, ((struct in6_addr *)&(rule->valueIpV6)), ipv6Address, INET6_ADDRSTRLEN)){ |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address"); |
| break; |
| } |
| cli_print(cli, "\t%s: %s mask %x", ATTR_REPL_IPV4_SRC_STR, ipv6Address, rule->mask); |
| break; |
| |
| case ATTR_REPL_IPV6_DST: |
| if (! inet_ntop(AF_INET6, ((struct in6_addr *)&(rule->valueIpV6)), ipv6Address, INET6_ADDRSTRLEN)){ |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing rule IPv4 address"); |
| break; |
| } |
| cli_print(cli, "\t%s: %s mask %x", ATTR_REPL_IPV4_DST_STR, ipv6Address, rule->mask); |
| break; |
| |
| case ATTR_ORIG_L4PROTO: |
| case ATTR_REPL_L4PROTO: |
| if (rule->value == IPPROTO_TCP) |
| cli_print(cli, "\t%s: tcp (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask); |
| else if (rule->value == IPPROTO_UDP) |
| cli_print(cli, "\t%s: udp (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask); |
| else if (rule->value == IPPROTO_IPIP) |
| cli_print(cli, "\t%s: ipip (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask); |
| else |
| cli_print(cli, "\t%s: unknown (%d) mask %x", ATTR_PROTO_STR, rule->value, rule->mask); |
| |
| case ATTR_L3PROTO: |
| if (rule->value == AF_INET) |
| cli_print(cli, "\t%s: ipv4 (%d) mask %x", ATTR_L3_PROTO_STR, rule->value, rule->mask); |
| else if (rule->value == AF_INET6) |
| cli_print(cli, "\t%s: ipv6 (%d) mask %x", ATTR_L3_PROTO_STR, rule->value, rule->mask); |
| |
| break; |
| default: |
| cli_print(cli, "\tERROR"); |
| } |
| } |
| } |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmFcParser() |
| * |
| * Returns 0 if the parser succeed |
| * |
| ******************************************************************/ |
| int cmmFcParser(char *confFilePath) |
| { |
| FILE * fp; |
| char buf[150], buf1[30], buf2[30], buf3[50], buf4[30], buf5[30], tempName[30], tempName1[30]; |
| denyRule_t rule = NULL; |
| denyRule_t copy_rule = NULL; |
| denyRule_t head_rule = NULL; |
| asymFFRule_t aff_rule = NULL; |
| int asymff_config = 0; |
| char attrSValue[IFNAMSIZ+1]={0}; |
| int check_port_is_last_option = 0; |
| int check_ipv4_is_last_option = 0; |
| int check_ipv6_is_last_option = 0; |
| int vlan_config = 0, log_config = 0, tun_config = 0; |
| unsigned int attrType, attrValue, ret = 0, number; |
| u_int8_t *attrValueV6 = NULL ; |
| int attrWidth; |
| unsigned int mask; |
| #ifdef WIFI_ENABLE |
| struct wifi_ff_entry *wifi_if = NULL; |
| int ii; |
| int wifi_config = 0; |
| #endif |
| |
| fp = fopen(confFilePath , "r"); |
| if(fp == NULL) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error opening %s\n", confFilePath); |
| return -1; |
| } |
| |
| #ifdef WIFI_ENABLE |
| memset( glbl_wifi_ff_ifs, 0, sizeof(struct wifi_ff_entry) * MAX_WIFI_FF_IFS ); |
| #endif |
| |
| tempName[0] = '\0'; |
| tempName1[0] = '\0'; |
| while(fgets(buf, sizeof(buf), fp)) |
| { |
| number = sscanf(buf, "%29s%29s%49s%29s%29s", buf1, buf2, buf3, buf4, buf5); /* leave 1 byte for '\0' */ |
| |
| // Check if it is a comment line |
| if (buf1[0] == '#') |
| continue; |
| |
| if (number == -1) |
| continue; |
| |
| else if (number == 2) |
| { |
| if((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "vlan") == 0)) |
| { |
| vlan_config = 1; |
| log_config = 0; |
| #ifdef WIFI_ENABLE |
| wifi_config = 0; |
| #endif |
| asymff_config = 0; |
| tun_config = 0; |
| check_port_is_last_option = 1; |
| continue; |
| } |
| if((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "logging") == 0)) |
| { |
| log_config = 1; |
| vlan_config = 0; |
| #ifdef WIFI_ENABLE |
| wifi_config = 0; |
| #endif |
| asymff_config = 0; |
| tun_config = 0; |
| check_port_is_last_option = 0; |
| continue; |
| } |
| #ifdef WIFI_ENABLE |
| if((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "wifi_fastforward") == 0)) |
| { |
| log_config = 0; |
| vlan_config = 0; |
| #ifdef WIFI_ENABLE |
| wifi_config = 1; |
| #endif |
| asymff_config = 0; |
| tun_config = 0; |
| check_port_is_last_option = 0; |
| |
| /* Get Free WiFi fastforward entry */ |
| for( ii = 0; ii < MAX_WIFI_FF_IFS; ii++ ) |
| { |
| if (!glbl_wifi_ff_ifs[ii].used) |
| { |
| wifi_if = &glbl_wifi_ff_ifs[ii]; |
| glbl_wifi_ff_ifs[ii].used = 1; |
| glbl_wifi_ff_ifs[ii].vapid = ii; |
| break; |
| } |
| } |
| |
| if( ii == MAX_WIFI_FF_IFS ) |
| wifi_if = NULL; |
| cmm_print(DEBUG_ERROR, "cmmFcParser: WiFi interface parsed \n"); |
| |
| continue; |
| } |
| #endif |
| |
| if((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "tun") == 0)) |
| { |
| log_config = 0; |
| vlan_config = 0; |
| #ifdef WIFI_ENABLE |
| wifi_config = 0; |
| #endif |
| tun_config = 1; |
| check_port_is_last_option = 0; |
| continue; |
| |
| } |
| |
| goto fail_parsing; |
| } |
| else if ((number != 3) && (number != 5)) |
| { |
| fail_parsing: |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\n Number of parameter per line must be 3\n"); |
| ret = -1; |
| break; |
| } |
| else |
| { |
| // Scan options |
| if ((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "fastforward") == 0)) |
| { |
| if(rule && strlen(tempName)) |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| strncpy(tempName, buf3, 20); |
| rule = NULL; |
| check_port_is_last_option = 0; |
| vlan_config = 0; |
| log_config = 0; |
| #ifdef WIFI_ENABLE |
| wifi_config = 0; |
| #endif |
| asymff_config = 0; |
| } |
| else if ((strcasecmp(buf1, "config") == 0) && (strcasecmp(buf2, "asym_fastforward") == 0)) |
| { |
| if(aff_rule && strlen(tempName1)) |
| asymFFRules = cmmFcAsymFFListAddRule(asymFFRules, tempName1, aff_rule); |
| |
| strncpy(tempName1, buf3, 20); |
| aff_rule = NULL; |
| check_port_is_last_option = 0; |
| vlan_config = 0; |
| log_config = 0; |
| #ifdef WIFI_ENABLE |
| wifi_config = 0; |
| #endif |
| asymff_config = 1; |
| } |
| else if(strcasecmp(buf1, "option") == 0) |
| { |
| if (vlan_config) |
| { |
| if (strcasecmp(buf2, "policy") == 0) |
| { |
| if (strcasecmp(buf3,"allow") == 0) |
| { |
| globalConf.vlan_policy = ALLOW; |
| continue; |
| } |
| if (strcasecmp(buf3,"prohibit") == 0) |
| { |
| globalConf.vlan_policy = PROHIBIT; |
| continue; |
| } |
| if (strcasecmp(buf3,"manual") == 0) |
| { |
| globalConf.vlan_policy = MANUAL; |
| continue; |
| } |
| } |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nLine: \"%s\"\n", buf); |
| ret = -1; |
| break; |
| } |
| else if (check_port_is_last_option) { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\noption \"port\" must be in last position in options list\n"); |
| ret = -1; |
| break; |
| } |
| |
| if (log_config) |
| { |
| if (strcasecmp(buf2, "file") == 0) |
| { |
| if (strcmp(buf3, "-") == 0) |
| { |
| /* Don't include DEBUG_STDERR if logFile is stdout */ |
| globalConf.log_level &= ~DEBUG_STDERR; |
| globalConf.logFile = stdout; |
| } |
| else |
| { |
| globalConf.log_level |= DEBUG_STDERR; |
| globalConf.logFile = fopen(buf3 , "a"); |
| } |
| if (globalConf.logFile) |
| { |
| pthread_mutex_init(&globalConf.logMutex, NULL); |
| setlinebuf(globalConf.logFile); |
| } |
| else |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Opening logfile %s returned error %s.\n", buf3, strerror(errno)); |
| continue; |
| } |
| else if (strcasecmp(buf2, "command") == 0) |
| { |
| if (atoi(buf3) == 1) |
| globalConf.log_level |= DEBUG_COMMAND; |
| continue; |
| } |
| else if (strcasecmp(buf2, "error") == 0) |
| { |
| if (atoi(buf3) == 1) |
| globalConf.log_level |= DEBUG_ERROR; |
| continue; |
| } |
| else if (strcasecmp(buf2, "warning") == 0) |
| { |
| if (atoi(buf3) == 1) |
| globalConf.log_level |= DEBUG_WARNING; |
| continue; |
| } |
| else if (strcasecmp(buf2, "info") == 0) |
| { |
| if (atoi(buf3) == 1) |
| globalConf.log_level |= DEBUG_INFO; |
| continue; |
| } |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nUnknown attribut name: %s\n", buf2); |
| ret = -1; |
| break; |
| } |
| |
| if(tun_config) |
| { |
| if(strcasecmp(buf2, "proto") == 0) |
| { |
| if(strcasecmp(buf3, "IPIP") == 0) |
| { |
| globalConf.tun_proto = IPPROTO_IPIP; |
| globalConf.tun_family = AF_INET6; |
| continue; |
| } |
| break; |
| } |
| break; |
| } |
| |
| |
| #ifdef WIFI_ENABLE |
| if(wifi_config) |
| { |
| if (strcasecmp(buf2, "ifname") == 0) |
| { |
| if (wifi_if) |
| { |
| strcpy(wifi_if->ifname, buf3); |
| } |
| cmm_print(DEBUG_ERROR, "cmmFcParser: WiFi name: %s \n", wifi_if->ifname); |
| |
| continue; |
| } |
| else if (strcasecmp(buf2, "direct_path_rx") == 0) |
| { |
| if (wifi_if) |
| wifi_if->direct_path_rx = atoi(buf3); |
| |
| continue; |
| } |
| |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nUnknown attribut name: %s\n", buf2); |
| ret = -1; |
| break; |
| } |
| #endif |
| if(asymff_config) |
| { |
| if(strcmp(buf2, "orig_src_port") == 0) |
| { |
| attrType = ATTR_ORIG_PORT_SRC; |
| attrValue = atoi(buf3); |
| attrSValue[0] = '\0'; |
| attrWidth = sizeof(unsigned short); |
| if ((attrValue < 1) || (attrValue> 65535)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribute value: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = ntohs(attrValue); |
| |
| mask = 0x0000FFFF; |
| |
| aff_rule = cmmFcAsymFFRuleAddAttribut(aff_rule, attrType, attrValue, attrSValue, attrWidth, mask); |
| } |
| else if(strcmp(buf2, "orig_dst_port") == 0) |
| { |
| attrType = ATTR_ORIG_PORT_DST; |
| attrValue = atoi(buf3); |
| attrSValue[0] = '\0'; |
| attrWidth = sizeof(unsigned short); |
| if ((attrValue < 1) || (attrValue> 65535)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribute value: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = ntohs(attrValue); |
| mask = 0x0000FFFF; |
| |
| aff_rule = cmmFcAsymFFRuleAddAttribut(aff_rule, attrType, attrValue, attrSValue, attrWidth, mask); |
| } |
| else if(strcmp(buf2, "l3proto") == 0) |
| { |
| if(strcmp(buf3, "ipv4") == 0) { |
| attrValue = AF_INET /*ETH_P_IP*/; |
| attrSValue[0] = '\0'; |
| attrType = ATTR_L3PROTO; |
| attrWidth = sizeof(unsigned char); |
| mask = 0x000000FF; |
| } |
| else if(strcmp(buf3, "ipv6") == 0) { |
| attrValue = AF_INET6 /*ETH_P_IPV6*/; |
| attrSValue[0] = '\0'; |
| attrType = ATTR_L3PROTO; |
| attrWidth = sizeof(unsigned char); |
| mask = 0x000000FF; |
| } |
| else { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribute value: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| aff_rule = cmmFcAsymFFRuleAddAttribut(aff_rule, attrType, attrValue, attrSValue, attrWidth, mask); |
| } |
| else if(strcmp(buf2, "l4proto") == 0) |
| { |
| if(strcmp(buf3, "tcp") == 0) { |
| attrValue = IPPROTO_TCP; |
| attrSValue[0] = '\0'; |
| attrType = ATTR_ORIG_L4PROTO; |
| attrWidth = sizeof(unsigned char); |
| mask = 0x000000FF; |
| } |
| else if(strcmp(buf3, "udp") == 0) { |
| attrValue = IPPROTO_UDP; |
| attrSValue[0] = '\0'; |
| attrType = ATTR_ORIG_L4PROTO; |
| attrWidth = sizeof(unsigned char); |
| mask = 0x000000FF; |
| } |
| else { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribute value: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| aff_rule = cmmFcAsymFFRuleAddAttribut(aff_rule, attrType, attrValue, attrSValue, attrWidth, mask); |
| } |
| else if (strcasecmp(buf2, "interface") == 0) |
| { |
| attrValue = 0; |
| strcpy(attrSValue,buf3); |
| attrType = ATTR_ORIG_COMCERTO_FP_IIF; |
| attrWidth = sizeof(int); |
| mask = 0x000000FF; |
| aff_rule = cmmFcAsymFFRuleAddAttribut(aff_rule, attrType, attrValue, attrSValue, attrWidth, mask); |
| } |
| continue; |
| } |
| |
| |
| if (check_ipv4_is_last_option) { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\noption \"ip_v4_addr\" must be in last position in options list\n"); |
| ret = -1; |
| break; |
| } |
| |
| if (check_ipv6_is_last_option) { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\noption \"ip_v6_addr\" must be in last position in options list\n"); |
| ret = -1; |
| break; |
| } |
| |
| // Scan options |
| if(strcmp(buf2, "orig_src_port") == 0) |
| { |
| attrType = ATTR_ORIG_PORT_SRC; |
| attrValue = atoi(buf3); |
| attrWidth = sizeof(unsigned short); |
| if ((attrValue < 1) || (attrValue> 65535)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = ntohs(attrValue); |
| |
| mask = 0x0000FFFF; |
| |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| |
| |
| } |
| else if(strcmp(buf2, "orig_dst_port") == 0) |
| { |
| attrType = ATTR_ORIG_PORT_DST; |
| attrValue = atoi(buf3); |
| attrWidth = sizeof(unsigned short); |
| if ((attrValue < 1) || (attrValue> 65535)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = ntohs(attrValue); |
| mask = 0x0000FFFF; |
| |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "repl_src_port") == 0) |
| { |
| attrType = ATTR_REPL_PORT_SRC; |
| attrValue = atoi(buf3); |
| attrWidth = sizeof(unsigned short); |
| if ((attrValue < 1) || (attrValue> 65535)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = ntohs(attrValue); |
| mask = 0x0000FFFF; |
| |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "repl_dst_port") == 0) |
| { |
| attrType = ATTR_REPL_PORT_DST; |
| attrValue = atoi(buf3); |
| attrWidth = sizeof(unsigned short); |
| if ((attrValue < 1) || (attrValue> 65535)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = ntohs(attrValue); |
| mask = 0x0000FFFF; |
| |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "mark") == 0) |
| { |
| attrType = ATTR_MARK; |
| attrValue = atoi(buf3); |
| attrWidth = sizeof(unsigned int); |
| if(strcmp(buf4, "mask") == 0) |
| mask = atoi(buf5); |
| else |
| { |
| mask = 0xFFFFFFFF; |
| } |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "proto") == 0) |
| { |
| |
| if(strcmp(buf3, "tcp") == 0) { |
| attrValue = IPPROTO_TCP; |
| |
| attrType = ATTR_ORIG_L4PROTO; |
| attrWidth = sizeof(unsigned char); |
| mask = 0x000000FF; |
| } |
| else if(strcmp(buf3, "udp") == 0) { |
| attrValue = IPPROTO_UDP; |
| |
| attrType = ATTR_ORIG_L4PROTO; |
| attrWidth = sizeof(unsigned char); |
| mask = 0x000000FF; |
| } |
| else if(strcmp(buf3, "ipv4") == 0) { |
| attrValue = AF_INET /*ETH_P_IP*/; |
| |
| attrType = ATTR_L3PROTO; |
| attrWidth = sizeof(unsigned char); |
| mask = 0x000000FF; |
| } |
| else if(strcmp(buf3, "ipv6") == 0) { |
| attrValue = AF_INET6 /*ETH_P_IPV6*/; |
| |
| attrType = ATTR_L3PROTO; |
| attrWidth = sizeof(unsigned char); |
| mask = 0x000000FF; |
| } |
| else { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| /*attrType = ATTR_ORIG_L4PROTO; |
| attrWidth = sizeof(unsigned char); |
| mask = 0x000000FF;*/ |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| |
| else if(strcmp(buf2, "port") == 0) |
| { |
| attrValue = atoi(buf3); |
| attrWidth = sizeof(unsigned short); |
| if ((attrValue < 1) || (attrValue> 65535)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = ntohs(attrValue); |
| head_rule = rule; |
| // Port option. It is like 4 differents rules |
| attrType = ATTR_ORIG_PORT_SRC; |
| mask = 0x0000FFFF; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| copy_rule = head_rule; |
| rule = NULL; |
| while(copy_rule) { |
| rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL); |
| copy_rule = copy_rule->next; |
| } |
| attrType = ATTR_ORIG_PORT_DST; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| copy_rule = head_rule; |
| rule = NULL; |
| while(copy_rule) { |
| rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL); |
| copy_rule = copy_rule->next; |
| } |
| attrType = ATTR_REPL_PORT_SRC; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| // The last one will be added to the list later |
| copy_rule = head_rule; |
| rule = NULL; |
| while(copy_rule) { |
| rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL); |
| copy_rule = copy_rule->next; |
| } |
| attrType = ATTR_REPL_PORT_DST; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| |
| check_port_is_last_option = 1; |
| } |
| else if(strcmp(buf2, "orig_src_ipv4") == 0) |
| { |
| struct in_addr addr; |
| |
| if (!inet_aton(buf3, &addr)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = addr.s_addr; |
| |
| attrWidth = sizeof(unsigned int); |
| attrType = ATTR_ORIG_IPV4_SRC; |
| mask = 0xFFFFFFFF; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "orig_dst_ipv4") == 0) |
| { |
| struct in_addr addr; |
| |
| if (!inet_aton(buf3, &addr)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = addr.s_addr; |
| |
| attrWidth = sizeof(unsigned int); |
| attrType = ATTR_ORIG_IPV4_DST; |
| mask = 0xFFFFFFFF; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "reply_src_ipv4") == 0) |
| { |
| struct in_addr addr; |
| |
| if (!inet_aton(buf3, &addr)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = addr.s_addr; |
| |
| attrWidth = sizeof(unsigned int); |
| attrType = ATTR_REPL_IPV4_SRC; |
| mask = 0xFFFFFFFF; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "reply_dst_ipv4") == 0) |
| { |
| |
| struct in_addr addr; |
| |
| if (!inet_aton(buf3, &addr)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = addr.s_addr; |
| |
| attrWidth = sizeof(unsigned int); |
| attrType = ATTR_REPL_IPV4_DST; |
| mask = 0xFFFFFFFF; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "ip_v4_addr") == 0) |
| { |
| struct in_addr addr; |
| |
| if (!inet_aton(buf3, &addr)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValue = addr.s_addr; |
| attrWidth = sizeof(unsigned int); |
| mask = 0xFFFFFFFF; |
| |
| // this option is like 4 differents rules |
| head_rule = rule; |
| |
| attrType = ATTR_ORIG_IPV4_SRC; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| copy_rule = head_rule; |
| rule = NULL; |
| while(copy_rule) { |
| rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL); |
| copy_rule = copy_rule->next; |
| } |
| attrType = ATTR_ORIG_IPV4_DST; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| copy_rule = head_rule; |
| rule = NULL; |
| while(copy_rule) { |
| rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL); |
| copy_rule = copy_rule->next; |
| } |
| attrType = ATTR_REPL_IPV4_SRC; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| copy_rule = head_rule; |
| rule = NULL; |
| while(copy_rule) { |
| rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL); |
| copy_rule = copy_rule->next; |
| } |
| attrType = ATTR_REPL_IPV4_DST; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| // The last one will be added to the list later |
| |
| check_ipv4_is_last_option = 1; |
| } |
| else if(strcmp(buf2, "orig_src_ipv6") == 0) |
| { |
| struct in6_addr addr; |
| |
| if (!inet_pton(AF_INET6, buf3, &addr)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValueV6 = addr.s6_addr; |
| attrValue = 0; |
| |
| attrWidth = 16; |
| attrType = ATTR_ORIG_IPV6_SRC; |
| mask = 0xFFFFFFFF; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "orig_dst_ipv6") == 0) |
| { |
| struct in6_addr addr; |
| |
| if (!inet_pton(AF_INET6, buf3, &addr)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValueV6 = addr.s6_addr; |
| attrValue = 0; |
| |
| attrWidth = 16; |
| attrType = ATTR_ORIG_IPV6_DST; |
| mask = 0xFFFFFFFF; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "reply_src_ipv6") == 0) |
| { |
| struct in6_addr addr; |
| |
| if (!inet_pton(AF_INET6, buf3, &addr)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValueV6 = addr.s6_addr; |
| attrValue = 0; |
| |
| attrWidth = 16; |
| attrType = ATTR_REPL_IPV6_SRC; |
| mask = 0xFFFFFFFF; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "reply_dst_ipv6") == 0) |
| { |
| struct in6_addr addr; |
| |
| if (!inet_pton(AF_INET6, buf3, &addr)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValueV6 = addr.s6_addr; |
| attrValue = 0; |
| |
| attrWidth = 16; |
| attrType = ATTR_REPL_IPV6_DST; |
| mask = 0xFFFFFFFF; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| } |
| else if(strcmp(buf2, "ip_v6_addr") == 0) |
| { |
| struct in6_addr addr; |
| |
| if (!inet_pton(AF_INET6, buf3, &addr)) |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nBad attribut value IP Address: %s\n", buf3); |
| ret = -1; |
| break; |
| } |
| attrValueV6 = addr.s6_addr; |
| attrValue = 0; |
| attrWidth = 16; |
| mask = 0xFFFFFFFF; |
| |
| // this option is like 4 differents rules |
| head_rule = rule; |
| |
| attrType = ATTR_ORIG_IPV6_SRC; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| copy_rule = head_rule; |
| rule = NULL; |
| while(copy_rule) { |
| rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL); |
| copy_rule = copy_rule->next; |
| } |
| attrType = ATTR_ORIG_IPV6_DST; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| copy_rule = head_rule; |
| rule = NULL; |
| while(copy_rule) { |
| rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL); |
| copy_rule = copy_rule->next; |
| } |
| attrType = ATTR_REPL_IPV6_SRC; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| copy_rule = head_rule; |
| rule = NULL; |
| while(copy_rule) { |
| rule = cmmFcRuleAddAttribut(rule, copy_rule->type, copy_rule->value, copy_rule->width, copy_rule->mask, NULL); |
| copy_rule = copy_rule->next; |
| } |
| attrType = ATTR_REPL_IPV6_DST; |
| rule = cmmFcRuleAddAttribut(rule, attrType, attrValue, attrWidth, mask, attrValueV6); |
| // The last one will be added to the list later |
| |
| check_ipv6_is_last_option = 1; |
| } |
| else |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\nUnknown attribut name: %s\n", buf2); |
| ret = -1; |
| break; |
| } |
| } |
| else |
| { |
| cmm_print(DEBUG_CRIT, "cmmFcParser: Error parsing configuration file.\n The string is %s\nThe expected string is: config fastforward <rule_name> or option <attribut_name> <attribut_value>\n", buf); |
| // TODO: Some memory to free when we enter in that case |
| ret = -1; |
| break; |
| } |
| } |
| } |
| if(aff_rule && strlen(tempName1)) |
| asymFFRules = cmmFcAsymFFListAddRule(asymFFRules, tempName1, aff_rule); |
| |
| if(rule && strlen(tempName)) |
| denyRules = cmmFcListAddRule(denyRules, tempName, rule); |
| |
| fclose(fp); |
| return ret; |
| } |
| |
| /***************************************************************** |
| * cmmRxCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmRxCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmRxSetProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmStatCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmStatCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmStatSetProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmm4rdIdConvCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmm4rdIdConvCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call tunnel 4rd id conversion set process function*/ |
| cmm4rdIdConvSetProcess(argv, 0, argc, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| |
| /***************************************************************** |
| * cmmDPDSaQueryCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmDPDSaQueryCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmDPDSaQuerySetProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| #ifdef C2000_DPI |
| /***************************************************************** |
| * cmmDPIEnableCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmDPIEnableCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmDPIFlagSetProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| #endif |
| |
| /***************************************************************** |
| * cmmAsymFFEnableCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmAsymFFEnableCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmAsymFFSetProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmShowRxCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmShowRxCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmRxShowProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmShowStatCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmShowStatCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Stat process function*/ |
| cmmStatShowProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| |
| /***************************************************************** |
| * cmmQueryRxCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmQueryRxCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmRxQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| |
| /***************************************************************** |
| * cmmQueryRtCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmQueryRtCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmRtQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmQueryCtCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmQueryCtCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmCtQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmQueryMacVlanCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmQueryMacVlanCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call MacVlan process function*/ |
| cmmMacVlanQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * * cmmQueryV6CtCmd |
| * * |
| * * |
| * ******************************************************************/ |
| static int cmmQueryV6CtCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmCt6QueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| |
| |
| /***************************************************************** |
| * cmmQueryPPPoECmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmQueryPPPoECmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call PPPoE process function*/ |
| cmmPPPoEQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| |
| /***************************************************************** |
| * * cmmQueryVlanCmd |
| * * |
| * * |
| * ******************************************************************/ |
| static int cmmQueryVlanCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Vlan process function*/ |
| cmmVlanQuery(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * * * cmmQueryMc4Cmd |
| * * * |
| * * * |
| * * ******************************************************************/ |
| static int cmmQueryMc4Cmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Multicast IPV4 process function*/ |
| cmmMc4QueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * * * * cmmQueryMc6Cmd |
| * * * * |
| * * * * |
| * * * ******************************************************************/ |
| static int cmmQueryMc6Cmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Multicast IPV4 process function*/ |
| cmmMc6QueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| |
| /***************************************************************** |
| * * * * * cmmQueryQmCmd |
| * * * * * |
| * * * * * |
| * * * * ******************************************************************/ |
| static int cmmQueryQmCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Multicast IPV4 process function*/ |
| cmmQmQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| |
| /***************************************************************** |
| * * * * * * cmmQueryQmCmd |
| * * * * * * |
| * * * * * * |
| * * * * * ******************************************************************/ |
| static int cmmQmExptRateQueryCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Multicast IPV4 process function*/ |
| cmmQmExptRateQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * * * cmmSaQueryCmd |
| * * * |
| * * * |
| * * ******************************************************************/ |
| static int cmmSaQueryCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Sa Query process function*/ |
| cmmSAQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| |
| |
| /***************************************************************** |
| * cmmQueryNatptCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmQueryNatptCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call NATPT process function*/ |
| cmmNATPTQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| #ifdef AUTO_BRIDGE |
| /***************************************************************** |
| * cmmQueryL2FlowCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmQueryL2FlowCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call L2Flow query function*/ |
| cmmL2FlowQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| #endif |
| /***************************************************************** |
| * cmmQosCmds |
| * |
| * |
| ******************************************************************/ |
| static int cmmQmCmds(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call QM process function*/ |
| cmmQmSetProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmMc4Cmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmMc4Cmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmMc4SetProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| /***************************************************************** |
| * cmmMc6Cmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmMc6Cmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RX process function*/ |
| cmmMc6SetProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmMspMem |
| * |
| * |
| ******************************************************************/ |
| static int cmmMspMem(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Memory DIsplay function */ |
| prfMspMS( globalConf.cli.daemon_handle,argc, argv); |
| |
| return CLI_OK; |
| } |
| /***************************************************************** |
| * cmmMspMem |
| * |
| * |
| ******************************************************************/ |
| static int cmmMspMemW(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Memory DIsplay function */ |
| prfMspMSW( globalConf.cli.daemon_handle,argc, argv); |
| |
| return CLI_OK; |
| } |
| /***************************************************************** |
| * cmmMspMem |
| ******************************************************************/ |
| static int cmmMspCT(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Memory DIsplay function */ |
| prfMspCT(globalConf.cli.daemon_handle,argc, argv ); |
| return CLI_OK; |
| } |
| |
| /* |
| ** Performance mesaurement and tracing |
| */ |
| /* Busy CPU */ |
| static int cmmPTBusyCPU(struct cli_def * cli, char *command, char *argv[], int argc) { |
| prfPTBusyCPU( globalConf.cli.daemon_handle,argc, argv); |
| return CLI_OK; |
| } |
| /* Tracing/profiling */ |
| static int cmmPTsetmask(struct cli_def * cli, char *command, char *argv[], int argc) { |
| prfPTsetmask( globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| static int cmmPTstart(struct cli_def * cli, char *command, char *argv[], int argc) { |
| prfPTstart(globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| static int cmmPTswitch(struct cli_def * cli, char *command, char *argv[], int argc) { |
| prfPTswitch(globalConf.cli.daemon_handle, argc,argv); |
| return CLI_OK; |
| } |
| |
| static int cmmPTshow(struct cli_def * cli, char *command, char *argv[], int argc) { |
| prfPTshow(globalConf.cli.daemon_handle, argc,argv); |
| return CLI_OK; |
| } |
| |
| static int cmmPTstatus(struct cli_def * cli, char *command, char *argv[], int argc) { |
| prfStatus(globalConf.cli.daemon_handle,argc, argv); |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmVlan commands |
| * |
| * |
| ******************************************************************/ |
| static int cmmVlanCliAdd(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| /*Call vlan process function*/ |
| vlanAddProcess(globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| |
| static int cmmVlanCliDelete(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| /*Call vlan process function*/ |
| vlanDeleteProcess(globalConf.cli.daemon_handle, argc, argv); |
| |
| return CLI_OK; |
| } |
| |
| |
| /***************************************************************** |
| * cmmPktCap commands |
| * |
| * |
| ******************************************************************/ |
| static int cmmPktCapSlice(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| |
| PktCapSliceProcess(globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| |
| static int cmmPktCapStat(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| PktCapStatProcess(globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| |
| |
| static int cmmPktCapFilter(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| PktCapFilterProcess(globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| |
| |
| static int cmmPktCapQuery(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| PktCapQueryProcess(cli , globalConf.cli.daemon_handle); |
| return CLI_OK; |
| } |
| |
| |
| /***************************************************************** |
| * cmmIcc commands |
| * |
| * |
| ******************************************************************/ |
| static int cmmIccReset(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| |
| IccReset(globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| |
| static int cmmIccThreshold(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| IccThreshold(globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| |
| |
| static int cmmIccAdd(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| IccAdd(globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| |
| |
| static int cmmIccDelete(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| IccDelete(globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| |
| |
| static int cmmIccQuery(struct cli_def *cli, char *command, char *argv[], int argc) |
| { |
| IccQuery(globalConf.cli.daemon_handle, argc, argv); |
| return CLI_OK; |
| } |
| |
| |
| static int cmmQueryTnlCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| cmmTnlQueryProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| |
| |
| /***************************************************************** |
| * cmmSetTimeoutCLI |
| ******************************************************************/ |
| static int cmmSetTimeoutCLI(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| timeoutSet(globalConf.cli.daemon_handle, argv, argc); |
| return CLI_OK; |
| } |
| |
| static int cmmSetRouteCLI(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| cmmRouteSetProcess(argv, 0, globalConf.cli.daemon_handle); |
| return CLI_OK; |
| } |
| |
| static int cmmFFControlCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| cmmFFControlProcess(argv, 0, globalConf.cli.daemon_handle); |
| return CLI_OK; |
| } |
| |
| static int cmmIpv4Cmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| cmmCtChangeProcess4(argv, 0, globalConf.cli.daemon_handle); |
| return CLI_OK; |
| } |
| |
| static int cmmIpv6Cmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| cmmCtChangeProcess6(argv, 0, globalConf.cli.daemon_handle); |
| return CLI_OK; |
| } |
| |
| int cmmFFControlProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle) |
| { |
| int cpt = tabStart; |
| cmmd_ff_ctrl_cmd_t cmd; |
| char rcvBuffer[256]; |
| char enable; |
| int rc; |
| |
| if(!keywords[cpt]) |
| goto usage; |
| |
| if(strcasecmp(keywords[cpt], "enable") == 0) |
| enable = 1; |
| else if (strcasecmp(keywords[cpt], "disable") == 0) |
| enable = 0; |
| else |
| goto usage; |
| |
| cmd.enable = enable; |
| |
| // Send message to forward engine |
| cmm_print(DEBUG_COMMAND, "Send CMD_CMMTD_IPV4_FF_CONTROL cmd to daemon len=%d\n",sizeof(cmmd_ff_ctrl_cmd_t)); |
| rc = cmmSendToDaemon(daemon_handle, CMMD_CMD_IPV4_FF_CONTROL, (unsigned short *) &cmd, sizeof(cmmd_ff_ctrl_cmd_t), rcvBuffer); |
| if (rc != 2) /* we expect 2 bytes in response */ |
| { |
| cmm_print(DEBUG_STDERR, "CMD_CMMTD_IPV4_FF_CONTROL unexpected response length %d\n", rc); |
| return -1; |
| } |
| else if ((((u_int16_t*)rcvBuffer)[0]) != CMMD_ERR_OK) |
| { |
| cmm_print(DEBUG_STDERR, "Error %d received from CMM Deamon for CMD_CMMTD_IPV4_FF_CONTROL\n", ((u_int16_t*)rcvBuffer)[0]); |
| return -1; |
| } |
| |
| return 0; |
| usage: |
| cmm_print(DEBUG_ERROR, "Usage: set ff <enable disable>\n"); |
| return -1; |
| } |
| |
| int cmmIPsecSetProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle) |
| { |
| int cpt = tabStart; |
| fpp_ipsec_cmd_t cmd; |
| char rcvBuffer[256]; |
| char enable; |
| |
| if(!keywords[cpt]) |
| goto usage; |
| |
| else if(strcasecmp(keywords[cpt], "pre-frag") == 0) |
| { |
| if(!keywords[++cpt]) |
| goto usage; |
| |
| if(strcasecmp(keywords[cpt], "enable") == 0) |
| enable = 1; |
| else if (strcasecmp(keywords[cpt], "disable") == 0) |
| enable = 0; |
| else |
| goto usage; |
| |
| cmd.pre_frag_en = enable; |
| |
| // Send message to forward engine |
| cmm_print(DEBUG_COMMAND, "Send CMD_IPSEC_FRAG_CFG cmd to daemon len=%d\n",sizeof(fpp_ipsec_cmd_t)); |
| if(cmmSendToDaemon(daemon_handle, FPP_CMD_IPSEC_FRAG_CFG, (unsigned short *) &cmd, sizeof(fpp_ipsec_cmd_t), rcvBuffer) == 4) |
| { |
| if ( ((unsigned short *)rcvBuffer)[0] != 0) { |
| cmm_print(DEBUG_STDERR, "Error %d while sending message to daemon\n", ((unsigned short *)rcvBuffer)[0]); |
| return ((unsigned short *)rcvBuffer)[0]; |
| } |
| } |
| return 0; |
| } |
| usage: |
| cmm_print(DEBUG_ERROR, "Usage: set ipsec pre-frag <enable disable>\n"); |
| return -1; |
| } |
| |
| int cmmExptCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call exception path process function*/ |
| cmmExptSetProcess(argv, 0, globalConf.cli.daemon_handle); |
| return CLI_OK; |
| } |
| |
| int cmmRtpCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call RTP process function*/ |
| cmmRTPSetProcess(argv, 0, globalConf.cli.daemon_handle); |
| return CLI_OK; |
| } |
| |
| int cmmSocketCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call Socket process function*/ |
| cmmSocketSetProcess(argv, 0, globalConf.cli.daemon_handle); |
| return CLI_OK; |
| } |
| |
| int cmmNatptCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call NAT-PT process function*/ |
| cmmNATPTSetProcess(argv, 0, globalConf.cli.daemon_handle); |
| return CLI_OK; |
| } |
| |
| int cmmAltConfCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call AltConf process function*/ |
| cmmAltConfClient(argc, argv, 0, globalConf.cli.daemon_handle); |
| return CLI_OK; |
| } |
| |
| static void cliCallback(struct cli_def *cliHandle, char *format) |
| { |
| if (format[0] && cliHandle->client) |
| fprintf(cliHandle->client, "%s\r\n", format); |
| } |
| |
| /***************************************************************** |
| * cmmBridgeControlCmd |
| * |
| * |
| ******************************************************************/ |
| static int cmmBridgeControlCmd(struct cli_def * cli, char *command, char *argv[], int argc) |
| { |
| /*Call L2Flow query function*/ |
| cmmBridgeControlProcess(argv, 0, globalConf.cli.daemon_handle); |
| |
| return CLI_OK; |
| } |
| |
| /***************************************************************** |
| * cmmCliThread() |
| * |
| * |
| * |
| ******************************************************************/ |
| static void *cmmCliThread(void *data) |
| { |
| struct cmm_cli *ctx = data; |
| |
| cmm_print(DEBUG_INFO, "%s: pid %d\n", __func__, getpid()); |
| |
| while (1) |
| { |
| ctx->sock2 = accept(ctx->sock, NULL, 0); |
| if (ctx->sock2 < 0) |
| { |
| cmm_print(DEBUG_ERROR, "%s: accept() %s\n", __func__, strerror(errno)); |
| break; |
| } |
| |
| cli_loop(ctx->handle, ctx->sock2); |
| cmm_print(DEBUG_INFO, "%s: cli_loop exiting\n", __func__); |
| |
| close(ctx->sock2); |
| } |
| |
| cmm_print(DEBUG_INFO, "%s: exiting\n", __func__); |
| |
| kill (0, SIGTERM); |
| pthread_exit(NULL); |
| |
| return NULL; |
| } |
| |
| |
| /***************************************************************** |
| * cmmCliInit() |
| * |
| * |
| * |
| ******************************************************************/ |
| int cmmCliInit(struct cmm_cli *ctx) |
| { |
| struct sockaddr_in serveraddr; |
| struct cli_command *c; |
| int on; |
| |
| cmm_print(DEBUG_INFO, "%s\n", __func__); |
| |
| ctx->fci_handle = fci_open(FCILIB_FF_TYPE, 0); |
| if (!ctx->fci_handle) |
| { |
| cmm_print(DEBUG_ERROR, "%s: fci_open() failed, %s\n", __func__, strerror(errno)); |
| goto err0; |
| } |
| |
| #ifdef NEW_IPC |
| ctx->daemon_handle = cmm_open(); |
| if (!ctx->daemon_handle) |
| { |
| cmm_print(DEBUG_ERROR, "%s: cmm_open() failed, %s\n", __func__, strerror(errno)); |
| goto err1; |
| } |
| #else |
| ctx->daemon_handle = globalConf.cmmPid; |
| #endif |
| ctx->handle = cli_init(); |
| if (!ctx->handle) |
| { |
| cmm_print(DEBUG_ERROR, "%s: cli_init() failed\n", __func__); |
| goto err2; |
| } |
| |
| cli_set_hostname(ctx->handle, "cmm"); |
| cli_set_banner(ctx->handle, "Welcome to the Fast Forward Contrack module monitor CLI"); |
| cli_print_callback(ctx->handle, cliCallback); |
| |
| cli_allow_user(ctx->handle, "admin", "admin"); |
| |
| c = cli_register_command(ctx->handle, NULL, "show", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| { |
| cli_register_command(ctx->handle, c, "connections", cmmCtShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of fast forwarded connections"); |
| cli_register_command(ctx->handle, c, "fpp_route", cmmFPPRtShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the fpp route entries used by the fast forwarded connections"); |
| cli_register_command(ctx->handle, c, "route", cmmRtShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the route entries used by the fast forwarded connections"); |
| cli_register_command(ctx->handle, c, "neighbor", cmmNeighShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the neighbor entries used by the fast forwarded connections"); |
| cli_register_command(ctx->handle, c, "rules", cmmFcRulesShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of non fast forwardable connections"); |
| cli_register_command(ctx->handle, c, "debug_level", cmmFcDebugShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the debug level"); |
| cli_register_command(ctx->handle, c, "activate", cmmFcActivateShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show if cmm is activated or not"); |
| cli_register_command(ctx->handle, c, "pppoe", cmmPPPoELocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the pppoe entries used by the fast forwarded connections"); |
| cli_register_command(ctx->handle, c, "vlan", cmmVlanLocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the vlan entries programmmed"); |
| cli_register_command(ctx->handle, c, "macvlan", cmmMacVlanLocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the macvlan entries programmmed"); |
| cli_register_command(ctx->handle, c, "rx", cmmShowRxCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show ICC, Bridge status"); |
| cli_register_command(ctx->handle, c, "stat", cmmShowStatCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show Statistics"); |
| cli_register_command(ctx->handle, c, "sa_query_timer", cmmSaQueryTimerShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the DPD SA query timer configuration"); |
| cli_register_command(ctx->handle, c, "sec-connections", cmmFlowLocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the local table of secure connections"); |
| cli_register_command(ctx->handle, c, "relay", cmmRelayLocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show pppoe relay entries used by the fast forwarded connections"); |
| cli_register_command(ctx->handle, c, "mc6", cmmMc6Show, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of V6 multicat listeners"); |
| cli_register_command(ctx->handle, c, "mc4", cmmMc4Show, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of V4 multicat listeners"); |
| #ifdef C2000_DPI |
| cli_register_command(ctx->handle, c, "dpi", cmmDPIEnableShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the DPI flag status"); |
| #endif |
| cli_register_command(ctx->handle, c, "asym_fastforward", cmmAsymFFEnableShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the Asymmetric fast forward status"); |
| cli_register_command(ctx->handle, c, "asym_ff_rules", cmmFcAsymFFRulesShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of asymmetric fast forwardable connections"); |
| } |
| |
| c = cli_register_command(ctx->handle, NULL, "query", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| { |
| cli_register_command(ctx->handle, c, "pppoe", cmmQueryPPPoECmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query PPPoE entries on FPP"); |
| cli_register_command(ctx->handle, c, "rx", cmmQueryRxCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Bridge entries on FPP"); |
| cli_register_command(ctx->handle, c, "route", cmmQueryRtCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Route entries on FPP"); |
| cli_register_command(ctx->handle, c, "connections", cmmQueryCtCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Connection entries on FPP"); |
| cli_register_command(ctx->handle, c, "macvlan", cmmQueryMacVlanCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Macvlan interfaces on FPP"); |
| cli_register_command(ctx->handle, c, "v6connections", cmmQueryV6CtCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query IPV6Connection entries on FPP"); |
| cli_register_command(ctx->handle, c, "vlan", cmmQueryVlanCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query VLAN entries on FPP"); |
| cli_register_command(ctx->handle, c, "mc4", cmmQueryMc4Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Multicast IPV4 entries on FPP"); |
| cli_register_command(ctx->handle, c, "mc6", cmmQueryMc6Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Multicast IPV6 entries on FPP"); |
| cli_register_command(ctx->handle, c, "qm", cmmQueryQmCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query QOS configuration on FPP"); |
| cli_register_command(ctx->handle, c, "qmexptrate", cmmQmExptRateQueryCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query Exception rate configured on FPP"); |
| cli_register_command(ctx->handle, c, "sa", cmmSaQueryCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query for SA details"); |
| cli_register_command(ctx->handle, c, "natpt", cmmQueryNatptCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query NAT-PT connections"); |
| cli_register_command(ctx->handle, c, "pktcapture", cmmPktCapQuery, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query packet capture config parameters"); |
| cli_register_command(ctx->handle, c, "tunnels",cmmQueryTnlCmd , PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query tunnel parameters"); |
| #ifdef AUTO_BRIDGE |
| cli_register_command(ctx->handle, c, "l2flows", cmmQueryL2FlowCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Query L2Flows entries on FPP"); |
| #endif |
| } |
| |
| // cli_register_command(ctx->handle, pshow, "eth_icc", cmmEthIccShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the pppoe entries used by the fast forwarded connections"); |
| c = cli_register_command(ctx->handle, NULL, "set", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| { |
| cli_register_command(ctx->handle, c, "activate", cmmFcActivate, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Activate or desactivate fast forwarding"); |
| cli_register_command(ctx->handle, c, "debug", cmmFcDebug, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Debug level"); |
| cli_register_command(ctx->handle, c, "rx", cmmRxCmd, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Manage RX module (ICC, Bridge ...)"); |
| cli_register_command(ctx->handle, c, "qm", cmmQmCmds, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Manage QM module (QOS, Rate Limiting ...)"); |
| cli_register_command(ctx->handle, c, "mc6", cmmMc6Cmd, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Manage MC6 module (IpV6 multicast)"); |
| cli_register_command(ctx->handle, c, "mc4", cmmMc4Cmd, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Manage MC4 module (IPv4 multicast)"); |
| cli_register_command(ctx->handle, c, "timeout", cmmSetTimeoutCLI, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Set UDP/TCP/IPIP timeout value in FPP"); |
| cli_register_command(ctx->handle, c, "route", cmmSetRouteCLI, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Set Extended Route"); |
| cli_register_command(ctx->handle, c, "ff", cmmFFControlCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enable or disable fast forward"); |
| cli_register_command(ctx->handle, c, "stat", cmmStatCmd, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Manage Statistics (PPPoE, Bridge ...)"); |
| cli_register_command(ctx->handle, c, "expt_queue", cmmExptCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage Exception Path Queuing"); |
| cli_register_command(ctx->handle, c, "socket", cmmSocketCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage Socket module"); |
| cli_register_command(ctx->handle, c, "rtp", cmmRtpCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage RTP-relay module"); |
| cli_register_command(ctx->handle, c, "natpt", cmmNatptCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage NAT-PT module"); |
| cli_register_command(ctx->handle, c, "sa_query_timer", cmmDPDSaQueryCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enable or disable SA query timer"); |
| cli_register_command(ctx->handle, c, "config", cmmAltConfCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage Alternate Configuration module"); |
| cli_register_command(ctx->handle, c, "bridge", cmmBridgeControlCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Manage automatic bridging"); |
| #ifdef C2000_DPI |
| cli_register_command(ctx->handle, c, "dpi", cmmDPIEnableCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enable or disable Global DPI flag"); |
| #endif |
| cli_register_command(ctx->handle, c, "asym_fastforward", cmmAsymFFEnableCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enable or disable Asymmetric Fast forward"); |
| cli_register_command(ctx->handle, c, "4rd-id-conversion", cmm4rdIdConvCmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enable or disable 4rd Ipv4 header ID conversion"); |
| } |
| |
| c = cli_register_command(ctx->handle, NULL, "ipv4", cmmIpv4Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| cli_register_command(ctx->handle, c, "update", cmmIpv4Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Update IPv4 Connection"); |
| |
| c = cli_register_command(ctx->handle, NULL, "ipv6", cmmIpv6Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| cli_register_command(ctx->handle, c, "update", cmmIpv6Cmd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Update IPv6 Connection"); |
| |
| cli_register_command(ctx->handle, NULL, "stop", cmmFcStop, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Kill cmm"); |
| |
| c = cli_register_command(ctx->handle, NULL, "prf",NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| { |
| cli_register_command(ctx->handle, c, "busycpu",cmmPTBusyCPU, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Measure available CPU cycles"); |
| cli_register_command(ctx->handle, c, "status", cmmPTstatus, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show status of profiling/CPU measurement"); |
| c = cli_register_command(ctx->handle, c, "trace", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| { |
| cli_register_command(ctx->handle, c, "setmask", cmmPTsetmask, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Set module mask"); |
| cli_register_command(ctx->handle, c, "start", cmmPTstart, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Start trace"); |
| cli_register_command(ctx->handle, c, "switch", cmmPTswitch, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Stop or switch trace and show inactive trace"); |
| cli_register_command(ctx->handle, c, "showtrace", cmmPTshow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show inactive trace"); |
| } |
| } |
| |
| c = cli_register_command(ctx->handle, NULL, "mspmem",NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| { |
| cli_register_command(ctx->handle, c, "ct", cmmMspCT, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the table of fast forwarded connections"); |
| cli_register_command(ctx->handle, c, "bytes", cmmMspMem, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show msp memory in host order"); |
| cli_register_command(ctx->handle, c, "words", cmmMspMemW, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show msp memory in network order"); |
| } |
| |
| c = cli_register_command(ctx->handle, NULL, "vlan",NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| { |
| cli_register_command(ctx->handle, c, "add", cmmVlanCliAdd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Register vlan entry with fpp"); |
| cli_register_command(ctx->handle, c, "delete", cmmVlanCliDelete, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Deregister vlan with fpp"); |
| cli_register_command(ctx->handle, c, "show", cmmVlanLocalShow, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Deregister vlan with fpp"); |
| } |
| |
| c = cli_register_command(ctx->handle, NULL, "pktcapture", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| { |
| cli_register_command(ctx->handle, c, "slice", cmmPktCapSlice, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, |
| "Register packet capture size with fpp"); |
| cli_register_command(ctx->handle, c, "status", cmmPktCapStat, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, |
| "Enable/disable packet capture on LAN/WAN with fpp"); |
| cli_register_command(ctx->handle, c, "filter", cmmPktCapFilter, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, |
| "Register first-level-filter string for LAN/WAN with fpp"); |
| } |
| |
| c = cli_register_command(ctx->handle, NULL, "icc", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, ""); |
| if (c) |
| { |
| cli_register_command(ctx->handle, c, "reset", cmmIccReset, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, |
| "Reset ICC"); |
| cli_register_command(ctx->handle, c, "threshold", cmmIccThreshold, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, |
| "Set ICC threshold values"); |
| cli_register_command(ctx->handle, c, "add", cmmIccAdd, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, |
| "Add ICC table entry"); |
| cli_register_command(ctx->handle, c, "delete", cmmIccDelete, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, |
| "Delete ICC table entry"); |
| cli_register_command(ctx->handle, c, "query", cmmIccQuery, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, |
| "Query ICC table values"); |
| } |
| |
| |
| ctx->sock = socket(AF_INET, SOCK_STREAM, 0); |
| if (ctx->sock < 0) |
| { |
| cmm_print(DEBUG_ERROR, "%s: socket() %s\n", __func__, strerror(errno)); |
| goto err3; |
| } |
| |
| on = 1; |
| setsockopt(ctx->sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); |
| |
| memset(&serveraddr, 0, sizeof(serveraddr)); |
| serveraddr.sin_family = AF_INET; |
| serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); |
| serveraddr.sin_port = htons(2103); |
| if (bind(ctx->sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) |
| { |
| cmm_print(DEBUG_ERROR, "%s: bind() %s\n", __func__, strerror(errno)); |
| goto err4; |
| } |
| |
| if (listen(ctx->sock, 1) < 0) |
| { |
| cmm_print(DEBUG_ERROR, "%s: listen() %s\n", __func__, strerror(errno)); |
| goto err4; |
| } |
| |
| if (pthread_create(&ctx->pthread, NULL, cmmCliThread, ctx) < 0) |
| { |
| cmm_print(DEBUG_CRIT, "%s: pthread_create() failed, %s\n", __func__, strerror(errno)); |
| goto err4; |
| } |
| |
| return 0; |
| |
| err4: |
| close(ctx->sock); |
| |
| err3: |
| cli_done(ctx->handle); |
| |
| err2: |
| #ifdef NEW_IPC |
| cmm_close(ctx->daemon_handle); |
| |
| err1: |
| #endif |
| fci_close(ctx->fci_handle); |
| |
| err0: |
| return -1; |
| } |
| |
| |
| void cmmCliExit(struct cmm_cli *ctx) |
| { |
| cmm_print(DEBUG_INFO, "%s\n", __func__); |
| |
| #if defined(__UCLIBC__) |
| /* workaround uclibc pthread_cancel() bug, force thread to exit */ |
| close(ctx->sock); |
| close(ctx->sock2); |
| #endif |
| pthread_cancel(ctx->pthread); |
| |
| pthread_join(ctx->pthread, NULL); |
| |
| #if !defined(__UCLIBC__) |
| close(ctx->sock); |
| close(ctx->sock2); |
| #endif |
| |
| cli_done(ctx->handle); |
| ctx->handle = 0; |
| |
| #ifdef NEW_IPC |
| cmm_close(ctx->daemon_handle); |
| #endif |
| |
| fci_close(ctx->fci_handle); |
| |
| cmm_print(DEBUG_INFO, "%s: exiting\n", __func__); |
| } |