/* *=========================================================================== * ipnet_cmd_qc_parse_port_range *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_cmd_qc_parse_port_range(const char *str, Ip_u16 *lo_port, Ip_u16 *hi_port) { char *end; if (*str != '-') *lo_port = (Ip_u16) ipcom_strtol(str, &end, 10); else { *lo_port = 0; end = (char *) str + 1; } if (end == IP_NULL || ipcom_strlen(end) == 0) *hi_port = *lo_port; else { if (*end == '-') end++; if (ipcom_strlen(end) == 0) *hi_port = 0xffff; else *hi_port = (Ip_u16) ipcom_strtol(end, &end, 10); } if (*hi_port < *lo_port) return -IP_ERRNO_EINVAL; return 0; }
/* *=========================================================================== * ipdnsc_hostent_insert_name *=========================================================================== * Description: Inserts a host name in a hostent structure * Parameters: he - pointer to the hostent structure * name - the name to insert * Returns: 0 for OK, -1 for fail. */ IP_GLOBAL Ip_s32 ipdnsc_hostent_insert_name(struct Ip_hostent *he, char *name) { if (he == IP_NULL) return -1; if (ipcom_strlen(name) > (IPDNSC_MAXNAME-1)) return -1; /* Free the memory for the current name if any */ if (he != IP_NULL && he->h_name != IP_NULL) { ipcom_free(he->h_name); } /* Allocate storage for the host name */ he->h_name = ipcom_malloc(ipcom_strlen(name)+1); if (he->h_name == IP_NULL) { return -1; } /* Copy the host name */ ipcom_strcpy(he->h_name, name); return 0; }
IP_PUBLIC int ipcom_strerror_r(int errnum, char * buf, Ip_size_t buflen) { char * name; int n; if (buf == NULL) return -1; #if IP_PORT_VXWORKS >= 60 name = ipcom_strerror_int_vxworks(errnum); #else name = ipcom_strerror_int(errnum); #endif if (name) { ipcom_strncpy(buf, name, buflen); buf[buflen-1] = '\0'; n = ipcom_strlen(name); } else { #ifdef IP_PORT_VXWORKS n = ipcom_snprintf(buf, buflen, "errno = %#x", errnum); #else n = ipcom_snprintf(buf, buflen, "Unknown error: %d", 0xffff & errnum); #endif } return (n < buflen) ? 0 : IP_ERRNO_ERANGE; }
/* *=========================================================================== * ipnet_cmd_qc_parse_rate *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_bool ipnet_cmd_qc_parse_rate(const char *str_rate, Ip_u32 *rate) { char *end; *rate = (Ip_u32) ipcom_strtol(str_rate, &end, 10); if (end && ipcom_strlen(end) > 0) { if (ipcom_strcmp(end, "kbps") == 0) *rate *= 1000; else if (ipcom_strcmp(end, "Mbps") == 0) *rate *= 1000000; else if (ipcom_strcmp(end, "kbit") == 0) *rate *= 1000 / 8; else if (ipcom_strcmp(end, "Mbit") == 0) *rate *= 1000000 / 8; else if (ipcom_strcmp(end, "bit") == 0) *rate /= 8; else if (ipcom_strcmp(end, "bps") == 0) ; else { ipcom_printf("'%s' is an unsupported rate suffix"IP_LF, end); return IP_FALSE; } } return IP_TRUE; }
/* *=========================================================================== * ipnet_cmd_qc_parse_number *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_bool ipnet_cmd_qc_parse_number(const char *str_num, Ip_u32 *num) { char *end; long lnum; lnum = ipcom_strtol(str_num, &end, 10); if (lnum < 0) *num = 0; else *num = (Ip_u32) lnum; if (end && ipcom_strlen(end) > 0) { if (ipcom_strcmp(end, "k") == 0 || ipcom_strcmp(end, "kb") == 0) *num *= 1000; else if (ipcom_strcmp(end, "M") == 0 || ipcom_strcmp(end, "Mb") == 0) *num *= 1000000; else { ipcom_printf("'%s' is an unsupported number suffix"IP_LF, str_num); return IP_FALSE; } } return IP_TRUE; }
/* *=========================================================================== * ipnet_nat_proxy_sip_keyfind *=========================================================================== * Description: Find a string in a structured message. * This routine searches a string in a structured message. * It assumes the searched string always starts at the beginning * of each line of data terminated by \r\n characters. A message * should be terminated by \r\n preceded by the line terminator * \r\n. * Parameters: pdata - pointer to message. * pstr - key to look for. * ppos - found string position relative to pdata. * searchlen - searchlen. * Returns: IP_TRUE = found key. * IP_FALSE = key not found. */ IP_STATIC Ip_bool ipnet_nat_proxy_sip_keyfind(char *pdata, char *pstr, int *ppos, int searchlen) { char *pstart = pdata; int i = 0; if (!searchlen) searchlen = 1000; /* max default search length */ while (IP_TRUE) { if (pstr) { /* skip all space */ while (*pdata == ' ') pdata++; if (ipcom_memcmp(pdata, pstr, ipcom_strlen(pstr)) == 0) break; } /* advance to next line */ for (i = 0; i < (searchlen - 1); i++) { if (pdata[i] == '\r') if (pdata[i+1] == '\n') break; } if (i >= (searchlen - 1)) { IPCOM_LOG1(ERR, "ipnet_nat_proxy_sip_keyfind() :: single message exceeds max len: %d", searchlen); *ppos = searchlen; /* reaches the end */ return IP_FALSE; } pdata += i + 2; searchlen -= (i + 2); if ((pdata[0] == '\r' && pdata[1] == '\n') || (searchlen <= 0)) { /* reach the end mark \r\n\r\n */ if (searchlen) pdata += 2; *ppos = pdata - pstart; return (pstr ? IP_FALSE : IP_TRUE); } } *ppos = pdata - pstart; return IP_TRUE; }
/* *=========================================================================== * ipdnsc_hostent_insert_alias *=========================================================================== * Description: Inserts an alias name in a hostent structure * Parameters: he - pointer to the hostent structure * name - the name to insert * Returns: 0 for OK, -1 for fail. */ IP_GLOBAL Ip_s32 ipdnsc_hostent_insert_alias(struct Ip_hostent *he, char *name) { Ip_s32 num_alias, i=0; char **tmp; if (ipcom_strlen(name) > (IPDNSC_MAXNAME-1)) return -1; /* Find out the current number of aliases */ num_alias = ipdnsc_hostent_alias_count(he); /* Allocate memory for the another alias list entry */ tmp = ipcom_realloc(he->h_aliases, (num_alias+1) * sizeof(char *)); if(tmp == IP_NULL) return -1; he->h_aliases = tmp; /* Allocate memory for the alias */ he->h_aliases[num_alias-1] = ipcom_malloc(ipcom_strlen(name)+1); if (he->h_aliases[num_alias-1] == IP_NULL) { /* We have to free to whole list here */ while (he->h_aliases[i] != IP_NULL) { ipcom_free(he->h_aliases[i]); i++; } /* Free the alias list */ ipcom_free(he->h_aliases); he->h_aliases = IP_NULL; return -1; } /* Set the alias */ ipcom_strcpy(he->h_aliases[num_alias-1], name); /* Null terminate the list */ he->h_aliases[num_alias] = IP_NULL; return 0; }
/* *=========================================================================== * netsysctlname2oid *=========================================================================== * Description: * Parameters: ctl - * name - * pNewName - * nameLen - * Returns: * */ IP_PUBLIC int netsysctlname2oid(Ipnet_cmd_sysctl *ctl, char* name, int* pNewName, int* nameLen) { #ifdef IPCOM_USE_INET int i; if(ctl == IP_NULL) { ctl = ipnet_sysctl_inet_table; pNewName[(*nameLen)++] = IP_IPPROTO_IP; } /* if you want to support trunk node, pls change this function */ while (ctl->comp != IP_NULL) { if (IP_BIT_ISSET(ctl->argument, IPNET_CMD_SYSCTL_NETIF_NO)) { if (ipcom_strcasecmp(name, ctl->comp) == 0) { for (i = 0; ctl->ctl[i] != -1; i++); pNewName[(*nameLen)++] = ctl->ctl[i ? i-1 : i]; } } /* Do the netifs */ if (IP_BIT_ISSET(ctl->argument, IPNET_CMD_SYSCTL_NETIF_YES)) { /* Dump the arguments */ char **argv = ipnet_cmd_sysctl_dump_netif(); if (argv) { for (i = 0; argv[i] != IP_NULL; i++) { if(ipcom_strcasecmp(name, argv[i])==0) { name += ipcom_strlen(argv[i]) + 1; pNewName[(*nameLen)++] = i; netsysctlname2oid(ipnet_sysctl_inet_table, name, pNewName, nameLen); } ipcom_free(argv[i]); } ipcom_free(argv); } } ctl++; } #endif return 0; }
IP_PUBLIC char * ipcom_strdup(const char *s1) { char *s2; s2 = ipcom_malloc(ipcom_strlen(s1) + 1); if(s2 == IP_NULL) return IP_NULL; ipcom_strcpy(s2, s1); return s2; }
/* *=========================================================================== * ipcom_env_create *=========================================================================== * Description: * Parameters: * Returns: */ IP_STATIC Ipcom_env_entry * ipcom_env_create(const char *name, const char *value) { Ip_size_t name_length; Ip_size_t value_length; Ipcom_env_entry *env; /* Create environment variable */ name_length = ipcom_strlen(name) + 1; value_length = ipcom_strlen(value) + 1; env = ipcom_malloc(sizeof(Ipcom_env_entry) + name_length + value_length); if(env == IP_NULL) return IP_NULL; /* Init environment variable */ env->name = (const char *)env + sizeof(Ipcom_env_entry); ipcom_memcpy((void *)env->name, name, name_length); env->value = env->name + name_length; ipcom_memcpy((void *)env->value, value, value_length); return env; }
/* *=========================================================================== * ipnet_nat_proxy_dns_ptr_name *=========================================================================== * Description: Convert an Internet address to a domain name. * Parameters: buf - buffer to store the domain name in. * buflen - length of domain name buffer. * addr - pointer to Internet address. * family - address family. * zone - top level domain. * Returns: The length of the domain name or -1 if failed. */ IP_STATIC int ipnet_nat_proxy_dns_ptr_name(Ip_u8 *buf, int buflen, Ip_u8 *addr, int family, Ip_u8 *zone) { int i, j, second, zonelen; Ip_u8 tmp; zonelen = ipcom_strlen((char *)zone) + 1; i = 0; if (family == IP_AF_INET) { /* Reverse ipv4 address */ for (j=3; j>=0; j--) { second = 0; /* possible hundreds digit */ tmp = addr[j] / 100; if (tmp) { if (buflen - i < 1) return -1; /* Too small buffer */ buf[i++] = '0' + tmp; second = 1; } tmp = addr[j] % 100; /* possible tens digit */ if ((tmp / 10) || second) { if (buflen - i < 1) return -1; /* Too small buffer */ buf[i++] = '0' + tmp / 10; } /* always print ones digit */ if (buflen - i < 2) return -1; /* Too small buffer */ buf[i++] = '0' + tmp % 10; buf[i++] = '.'; } /* Append the zone */ if (buflen - i < zonelen) return -1; /* Too small buffer */ ipcom_strcpy((char *)&buf[i], (char *)zone); i += zonelen; } return i; }
/* *=========================================================================== * ipcom_sysvar_unset *=========================================================================== * Description: * Parameters: * Returns: */ IP_PUBLIC Ip_err ipcom_sysvar_unset(const char *name) { Ipcom_sysvar_entry *sysvar; Ip_err retval; Ip_size_t namelen; Ipcom_sysvar_tree *tree; retval = ipcom_once(&ipcom_sysvar_once, ipcom_sysvar_init, IP_NULL); if (retval != IPCOM_SUCCESS) return retval; namelen = ipcom_strlen(name); if (name[namelen-1] == '*') return ipcom_sysvar_for_each(name, ipcom_sysvar_unset_cb, IP_NULL); IPCOM_CODE_LOCK(); tree = ipcom_sysvar_tree_get(-1); if (tree == IP_NULL) { retval = IPCOM_ERR_NO_MEMORY; goto leave; } retval = IPCOM_ERR_NOT_FOUND; sysvar = ipcom_hash_get(tree->sysvars, name); if (sysvar) { if(IP_BIT_ISSET(sysvar->flags, IPCOM_SYSVAR_FLAG_READONLY)) retval = IPCOM_ERR_READONLY; else { ipcom_sysvar_release(tree, sysvar); retval = IPCOM_SUCCESS; } } leave: ipcom_sysvar_tree_done(tree); IPCOM_CODE_UNLOCK(); return retval; }
/***************************************************************************** * * example_get_line - Fetch the next available line into the tokenizer buffer * * .IP <tok> * The tokenizer buffer * * RETURNS: * IP_TRUE on success, IP_FALSE if we're at EOF. * * NOMANUAL */ IP_STATIC Ip_bool example_get_line(example_token_buffer_t *tok) { char *line; char *t; restart: /* Already EOF */ if (tok->eof) return IP_FALSE; /* Get next */ line = ipcom_strtok_r(tok->lines, "\r\n", &tok->llines); tok->curline++; tok->lines = IP_NULL; /* No more lines? */ if (line == IP_NULL) { tok->eof = IP_TRUE; return IP_FALSE; } /* Discard comments */ t = ipcom_strchr(line, '#'); if (t) *t = '\0'; /* Empty line; restart */ if (ipcom_strlen(line) == 0) goto restart; /* Set the tokens; discard any stored values */ tok->tokens = line; tok->spec = IP_NULL; return IP_TRUE; }
/* *=========================================================================== * ipnet_if_mib_table_search_ifTable *=========================================================================== * Description: Searches ifTable and ifXTable for a matching entry * Parameters: id, buf, best, cmd * Returns: The best matching interface or IP_NULL if no match was found, * error code is stored in 'ret' in that case. * */ IP_STATIC Ipnet_netif * ipnet_if_mib_table_search_ifTable(char *id, char *buf, char *best, Ip_s32 cmd, Ip_s32 *error_code) { Ip_u32 bestindex = 0; Ip_u32 ifIndex; Ip_u32 *ifindexes; unsigned ifTable_num_entries; unsigned i; ifindexes = ipnet_if_get_index_array(IPCOM_VR_ANY, 0, &ifTable_num_entries); if (ifindexes == IP_NULL) { *error_code = IPSNMP_ERROR_GENERROR; return IP_NULL; } for (i = 0; i < ifTable_num_entries; i++) { Ip_s32 lex, len = 0; buf[0] = '\0'; ifIndex = ifindexes[i]; if (ipcom_snprintf(&buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "%d.", (int)ifIndex) < 0) { *error_code = IPSNMP_ERROR_GENERROR; ipcom_free(ifindexes); return IP_NULL; } len = ipcom_strlen(buf); if (len) buf[len - 1] = '\0'; lex = ipsnmp_util_lexcmp_oid(buf, id); if (cmd == IPSNMP_MIB_COMMAND_NEXT) { if (lex > 0) { if (bestindex == 0 || ipsnmp_util_lexcmp_oid(buf, best) < 0) { ipcom_strcpy(best, buf); bestindex = ifIndex; } } } else { if (lex == 0) { ipcom_strcpy(best, buf); bestindex = ifIndex; break; } } } if (bestindex == 0) *error_code = IPSNMP_ERROR_NOSUCHNAME; ipcom_free(ifindexes); return ipnet_if_indextonetif(IPCOM_VR_ANY, bestindex); }
/* *=========================================================================== * ipcom_sysvar_getvr *=========================================================================== * Description: * Parameters: * Returns: */ IP_GLOBAL char * ipcom_sysvar_getvr(const char *name, char *value, Ip_size_t *value_size, Ip_bool usr, int vr) { Ipcom_sysvar_entry *sysvar; Ip_size_t value_length; char *ret_value = IP_NULL; Ip_err retval; Ipcom_sysvar_tree *tree; if (name == IP_NULL) return IP_NULL; retval = ipcom_once(&ipcom_sysvar_once, ipcom_sysvar_init, IP_NULL); if (retval != IPCOM_SUCCESS) { IP_PANIC(); return IP_NULL; } IPCOM_CODE_LOCK(); tree = ipcom_sysvar_tree_get(vr); if (tree == IP_NULL) goto leave; sysvar = ipcom_hash_get(tree->sysvars, name); if (sysvar) { if (value == IP_NULL) { #ifdef IP_PORT_OSE5 if (usr) ret_value = ipcom_strdup_usr(sysvar->value); else #else (void)usr; #endif ret_value = ipcom_strdup(sysvar->value); } else { value_length = ipcom_strlen(sysvar->value) + 1; if (value_length > *value_size) { ret_value = IP_NULL; *value_size = value_length; } else { ret_value = value; ipcom_memcpy(ret_value, sysvar->value, value_length); *value_size = value_length - 1; } } } #ifdef IP_PORT_OSE5 else { ret_value = ipcom_sysvar_get_ose5(name, value, value_size); } #endif /* IP_PORT_OSE5 */ leave: ipcom_sysvar_tree_done(tree); IPCOM_CODE_UNLOCK(); return ret_value; }
/* *=========================================================================== * ipcom_sysvar_set_internal *=========================================================================== * Description: * Parameters: * Returns: */ IP_GLOBAL Ip_err ipcom_sysvar_set_tree(const char *name, const char *value, int flags, Ipcom_sysvar_tree *tree) { Ip_size_t name_length; Ip_size_t value_length; Ipcom_sysvar_entry *sysvar; Ip_err retval = IPCOM_SUCCESS; /* Check for duplicate. */ sysvar = ipcom_hash_get(tree->sysvars, name); if (sysvar) { if (IP_BIT_ISSET(sysvar->flags, IPCOM_SYSVAR_FLAG_READONLY)) { retval = IPCOM_ERR_READONLY; goto leave; } else if (IP_BIT_ISFALSE(flags, IPCOM_SYSVAR_FLAG_OVERWRITE)) { retval = IPCOM_ERR_DUPLICATE; goto leave; } else { flags |= sysvar->flags & IPCOM_SYSVAR_FLAG_KERNEL; ipcom_hash_remove(tree->sysvars, sysvar); ipcom_free(sysvar); goto set; } } /* No current entry found and not allowed to create a new entry. */ if(IP_BIT_ISSET(flags, IPCOM_SYSVAR_FLAG_NOCREATE)) { retval = IPCOM_ERR_FAILED; goto leave; } /* Add the new sysvar. */ set: name_length = ipcom_strlen(name) + 1; value_length = ipcom_strlen(value) + 1; sysvar = ipcom_malloc(sizeof(Ipcom_sysvar_entry) + name_length + value_length); if(sysvar == IP_NULL) { retval = IPCOM_ERR_NO_MEMORY; goto leave; } sysvar->refcount = 1; sysvar->flags = flags; if (IP_BIT_ISFALSE(flags, IPCOM_SYSVAR_FLAG_INIT)) { tree->modified = IP_TRUE; sysvar->flags |= IPCOM_SYSVAR_FLAG_MODIFIED; } sysvar->name = (const char *)sysvar + sizeof(Ipcom_sysvar_entry); ipcom_memcpy((void *)sysvar->name, name, name_length); sysvar->value = sysvar->name + name_length; ipcom_memcpy((void *)sysvar->value, value, value_length); retval = ipcom_hash_add(tree->sysvars, sysvar); leave: return retval; /*lint !e429 Custodial pointer 'sysvar' has not been freed or returned */ }
/* *=========================================================================== * ipnet_nat_proxy_sip_payload_parse *=========================================================================== * Description: Parse SIP payload. * Parameters: appdata - pointer to application data. * applen - pointer to length of application data. * growspace - space available to extend application data. * param - pointer to proxy parameters. * newdata - pointer to pointer to new application data. * Returns: IP_TRUE = Packet modified. * IP_FALSE = Packet untouched. */ IP_STATIC Ip_bool ipnet_nat_proxy_sip_payload_parse(Ip_u8 *appdata, int *applen, int growspace, Ipnet_nat_proxy_param *param, Ip_u8 **newdata) { char *psipmsg = (char *)appdata; char *pcallid = IP_NULL; char *pendstr, *pstartstr, *psearch; Ip_bool retcode = IP_FALSE; int pos, sdpdatalen, searchlen, msgtype = 0; char tmpholder[50]; char laddrstr[20]; char gaddrstr[20]; char *pend = (char *)sipbuf + *applen - 1; char *sdplen_start, *sdplen_end, *sdp_end; int newlen, diff; if (param->incoming == IP_TRUE) { /* Incoming message*/ goto parseFalseExit; } if (param->inbound == IP_FALSE) { /* Outbound session */ if ((psipmsg = ipnet_nat_proxy_sip_outboundmsgtypecheck(psipmsg, &msgtype, *applen)) == IP_NULL) return IP_FALSE; /* not the message we're looking for */ } else { /* Inbound session */ if ((psipmsg = ipnet_nat_proxy_sip_inboundmsgtypecheck(psipmsg, &msgtype, *applen)) == IP_NULL) return IP_FALSE; /* not the message we're looking for */ } /* find the call-id field */ if (ipnet_nat_proxy_sip_keyfind(psipmsg, SIP_CALLID_STR, &pos, *applen - (psipmsg - (char *)appdata)) == IP_FALSE) { IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: no callid field"); return IP_FALSE; } /* get callid string */ pcallid = ipnet_nat_proxy_sip_callidstr(psipmsg + pos + SIP_TAG_TO_DATAPOS(SIP_CALLID_STR)); if (pcallid == IP_NULL) { IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: failed to parse callid string"); return IP_FALSE; } if (msgtype == SIP_MSG_TYPE_INVITE) { if (param->inbound == IP_FALSE) { /* Update the mapping timeout */ IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds", IPNET_NAT_SIP_ENTRY_INVITE_TIMEOUT); ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_INVITE_TIMEOUT, param->mapping); } else { /* ALG will not detect the ACK for inbound calls so use the INVITE response to set established timeout */ IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds", IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT); ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT, param->mapping); } } else if (msgtype == SIP_MSG_TYPE_ACK) { /* Update the mapping timeout */ IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds", IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT); ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT, param->mapping); } /* Copy the message to scratch buffer and set pointer */ if (*applen > (int)sizeof(sipbuf)) { IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: message to long"); goto parseFalseExit; } ipcom_memcpy(sipbuf, appdata, *applen); psipmsg = (char *)sipbuf + (psipmsg - (char *)appdata); /* first the via field * For response message, the Via field will not contain the private address. * The localAddrProcess() will check if the address is private. */ laddrstr[0] = gaddrstr[0] = 0; if (ipnet_nat_proxy_sip_keyfind(psipmsg, SIP_VIA_STR, &pos, (pend - psipmsg) + 1) == IP_TRUE) { /* advance to IP/Port string */ psipmsg += (pos + ipcom_strlen(SIP_VIA_STR) + SIP_VIA_FIELD_IPADDR_DIS); IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse via field"); psipmsg = ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_ADDRESS_PORT_STRING, param, &pend); if (psipmsg == IP_NULL) goto parseFalseExit; } /* find the contact field */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTACT_STR, &pos, (pend - psipmsg) + 1) == IP_TRUE) { /* advance to IP/Port string */ psipmsg += (pos + ipcom_strlen(SIP_CONTACT_STR) + SIP_CTAC_FIELD_IPADDR_DIS); IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse contact field"); psipmsg = ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_ADDRESS_PORT_STRING, param, &pend); if (psipmsg == IP_NULL) goto parseFalseExit; } /* exit if there isn't any private info in SIP message header */ if (laddrstr[0] == 0 || gaddrstr[0] == 0) goto parseFalseExit; /* When program reaches here, it indicates at least one place in the * packet should be modified. Use parseFalseExit only if it is an error */ /* find the Content-Type field */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTYPE_STR, &pos, (pend - psipmsg) + 1) == IP_FALSE) goto parseTrueExit; /* advance to start of data field */ psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_CONTYPE_STR)); SIP_SKIP_SPACES(psipmsg); /*check the application/sdp type, if not, exit */ if (!SIP_IS_STRING_SAME(psipmsg, SIP_APPSDP_STR)) goto parseTrueExit; /* find the content length field */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTLEN_STR, &pos, (pend - psipmsg) + 1) == IP_FALSE) goto parseTrueExit; IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse Content-Length field"); /* reach to the content length field, advance to length data */ psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_CONTLEN_STR)); SIP_SKIP_SPACES(psipmsg); sdpdatalen = ipcom_strtol(psipmsg, &pendstr, 10); IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: data length = %d", sdpdatalen); if (sdpdatalen == 0) goto parseTrueExit; /* store start and end of sdp datalength string as well as end of message */ sdplen_start = psipmsg; sdplen_end = pendstr; sdp_end = pend; /* advance to the start of SDP data */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, IP_NULL, &pos, (pend - psipmsg) + 1) == IP_FALSE) { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: Can't find header end mark"); goto parseTrueExit; } /* start of the SIP data field */ psipmsg += pos; searchlen = sdpdatalen; /* search the local IP address, and replace it with global address */ pstartstr = psipmsg; while (IP_TRUE) { psearch = ipnet_nat_proxy_sip_faststrsearch(laddrstr, ipcom_strlen(laddrstr), pstartstr, searchlen, IP_FALSE); if (psearch != IP_NULL) { IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: Local IP address in SDP: %s", laddrstr); if (ipnet_nat_proxy_sip_modmsg(gaddrstr, ipcom_strlen(gaddrstr), psearch, ipcom_strlen(laddrstr), &pend) < 0) { goto parseFalseExit; } searchlen = searchlen - (psearch + ipcom_strlen(gaddrstr) - pstartstr); pstartstr = psearch + ipcom_strlen(gaddrstr); } else break; } IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: the last search length %d", searchlen); /* search for the audio port */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_AUDIO_STR, &pos, sdpdatalen) == IP_TRUE) { /* advance to the port field */ psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_AUDIO_STR)); SIP_SKIP_SPACES(psipmsg); ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_PORT_STRING, param, &pend); } /* search for the audio control port */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_RTCP_STR, &pos, sdpdatalen) == IP_TRUE) { /* advance to the port field */ psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_RTCP_STR)); SIP_SKIP_SPACES(psipmsg); ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_PORT_STRING, param, &pend); } /* adjust the length node */ sdpdatalen += pend - sdp_end; ipcom_sprintf(tmpholder, "%d", sdpdatalen); if (ipnet_nat_proxy_sip_modmsg(tmpholder, ipcom_strlen(tmpholder), sdplen_start, sdplen_end - sdplen_start, &pend) < 0) { goto parseFalseExit; } parseTrueExit: /* Update application data with the modified buffer */ newlen = pend - (char *)sipbuf + 1; diff = newlen - *applen; if (diff > growspace) { /* Must allocate a new buffer */ *newdata = ipcom_malloc(*applen + diff); if (*newdata == IP_NULL) { IPCOM_LOG1(ERR, "ipnet_nat_proxy_sip_payload_parse() :: ipcom_malloc(%d) failed", *applen + diff); goto parseFalseExit; } ipcom_memcpy(*newdata, sipbuf, newlen); } else { /* Let the current buffer grow */ ipcom_memcpy(appdata, sipbuf, newlen); } *applen = newlen; IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_msg() :: the delta length = %d ", diff); retcode = IP_TRUE; parseFalseExit: if (msgtype == SIP_MSG_TYPE_BYE) ipnet_nat_proxy_sip_endmsgprocess(pcallid, param); if (pcallid) ipcom_free(pcallid); return retcode; }
/* *=========================================================================== * ipcom_sysvar_hash_key *=========================================================================== * Description: * Parameters: * Returns: */ IP_STATIC unsigned ipcom_sysvar_hash_key(const char *key) { return ipcom_hash_update(key, ipcom_strlen(key), 0); }
/* *=========================================================================== * ipnet_nat_proxy_sip_inboundmsgtypecheck *=========================================================================== * Description: Find the type of inbound SIP message * Parameters: psipmsg - pointer to buffer message * ptype - pointer to buffer for returned status * Returns: Pointer to message after the type or IP_NULL * if type not found. */ IP_STATIC char * ipnet_nat_proxy_sip_inboundmsgtypecheck(char *psipmsg, int *ptype, int searchlen) { int pos; /* check if the first 3 char is "SIP" */ if (SIP_IS_STRING_SAME(psipmsg, SIP_SIP_STR)) { /* yes, it is, check if it is status code 200 */ psipmsg += 8; if (SIP_IS_STRING_SAME(psipmsg, SIP_200_OK_STR)) { /* this is the status 200 OK message */ psipmsg += ipcom_strlen(SIP_200_OK_STR); *ptype = SIP_MSG_TYPE_STATUS; /* check if the INVITE or BYE code */ if (ipnet_nat_proxy_sip_keyfind(psipmsg, SIP_CSEQ_STR, &pos, searchlen) == IP_TRUE) { char * pbye; pbye = psipmsg + pos + SIP_TAG_TO_DATAPOS(SIP_CSEQ_STR); SIP_SKIP_SPACES(pbye); /* skip the number field */ while (*pbye != ' ') pbye++; SIP_SKIP_SPACES(pbye); if (SIP_IS_STRING_SAME (pbye, SIP_INVITE_STR)) { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_inboundmsgtypecheck() :: STATUS(INVITE) message"); *ptype = SIP_MSG_TYPE_INVITE; } else if (SIP_IS_STRING_SAME (pbye, SIP_BYE_STR)) { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_inboundmsgtypecheck() :: STATUS(BYE) message"); *ptype = SIP_MSG_TYPE_BYE; } else if (SIP_IS_STRING_SAME (pbye, SIP_CANCEL_STR)) { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_inboundmsgtypecheck() :: STATUS(BYE) message"); *ptype = SIP_MSG_TYPE_BYE; } } return psipmsg; } return IP_NULL; } if (SIP_IS_STRING_SAME(psipmsg, SIP_BYE_STR)) { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_inboundmsgtypecheck() :: BYE message"); psipmsg += ipcom_strlen(SIP_BYE_STR); *ptype = SIP_MSG_TYPE_BYE; return psipmsg; } else if (SIP_IS_STRING_SAME(psipmsg, SIP_MESSAGE_STR)) { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_inboundmsgtypecheck() :: MESSAGE message"); psipmsg += ipcom_strlen(SIP_MESSAGE_STR); *ptype = SIP_MSG_TYPE_MESSAGE; return psipmsg; } return IP_NULL; /* not the SIP messages we want */ }
/* *=========================================================================== * ipnet_nat_proxy_sip_localaddrprocess *=========================================================================== * Description: Process the private transport address * Parameters: pmsgstr - pointer to message * pipaddrstr - pointer to buffer for the local address string * pgaddrstr - pointer to buffer for the gloab address string * pcallid - pointer to the call id string * type - type of search * ppend - pointer to pointer to last byte of message * Returns: The next character position after the parsed string or * IP_NULL if parse fails */ IP_STATIC char * ipnet_nat_proxy_sip_localaddrprocess(char *pmsgstr, char *pipaddrstr, char *pgaddrstr, char *pcallid, int type, Ipnet_nat_proxy_param *param, char **ppend) { int localport, newport; int len, diff; Ip_u32 ipaddr; char *pstart; char tmpholder[30]; Ipnet_nat_proxy_tuple proxy_tuple; (void)pcallid; SIP_SKIP_SPACES(pmsgstr); pstart = pmsgstr; pmsgstr = ipnet_nat_proxy_sip_addrportstrparse(pmsgstr, &ipaddr, &localport, type); if (pmsgstr == IP_NULL) return IP_NULL; if (!localport) localport = SIP_DEFAULT_PORT; if (type == SIP_ADDRESS_PORT_STRING) { ipaddr = ip_htonl(ipaddr); (void)ipcom_inet_ntop(IP_AF_INET, &ipaddr, pipaddrstr, 16); ipaddr = ip_ntohl(ipaddr); } else /* PORT string only */ { ipaddr = ipcom_inet_addr(pipaddrstr); ipaddr = ip_ntohl(ipaddr); } /* make sure it is the private address, otherwise no translation */ if (ipaddr != param->tuple.private_addr) return pmsgstr; /* create a bind entry for this transport address if it hasn't been created yet */ if (param->tuple.private_port != localport) { ipcom_memset(&proxy_tuple, 0, sizeof(proxy_tuple)); proxy_tuple.protocol = IP_IPPROTO_UDP; proxy_tuple.private_addr = ipaddr; proxy_tuple.private_port = localport; newport = ipnet_nat_proxy_add_mapping(&proxy_tuple, IPNET_NAT_SIP_ENTRY_MEDIA_TIMEOUT, param->mapping, IP_FALSE, /* Use port translation */ IP_TRUE, /* Inbound session */ IP_NULL, IP_NULL); if (newport < 0) { IPCOM_LOG2(ERR, "ipnet_nat_proxy_sip_localaddrprocess() :: Failed to add mapping for address = 0x%08x, port = %d", ipaddr, localport); } else { IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_sip_localaddrprocess() :: Added mapping for address = 0x%08x, port = %d", ipaddr, localport); } } else { newport = param->nat_port; IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_sip_localaddrprocess() :: Mapping already existed for address = 0x%08x, port = %d", ipaddr, localport); } /* compose the new modified string */ len = 0; if (type == SIP_ADDRESS_PORT_STRING) { ipaddr = ip_htonl(param->nat_addr); (void)ipcom_inet_ntop(IP_AF_INET, &ipaddr, tmpholder, 16); ipcom_strcpy(pgaddrstr, tmpholder); len = ipcom_strlen(tmpholder); tmpholder[len++]= ':'; } ipcom_sprintf(tmpholder + len, "%d", newport); IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_localaddrprocess() new str: %s", tmpholder); if (ipnet_nat_proxy_sip_modmsg(tmpholder, ipcom_strlen(tmpholder), pstart, pmsgstr - pstart, ppend) < 0) { return IP_NULL; } diff = ipcom_strlen(tmpholder) - (pmsgstr - pstart); return pmsgstr + diff; }
/* *=========================================================================== * ipnet_if_mib_handler_ifTable *=========================================================================== * Description: MIB handler for variables in ifTable * Parameters: See file 'ipsnmp.h' * Returns: IPSNMP_ERROR_XXX * */ IP_STATIC Ip_s32 ipnet_if_mib_handler_ifTable(Ip_s32 cmd, char *id, Ipsnmp_varbind *vb, Ip_s32 magic, struct Ipsnmp_node_object *nodeobj) { Ip_s32 lid, ret = -1; Ipnet_netif *best_netif; Ip_s32 ifAdminStatus = 0; char *iid; char *buf = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID); char *best = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID); struct Ip_ifreq ifreq; Ip_fd fd; if (buf == IP_NULL || best == IP_NULL) { ret = IPSNMP_ERROR_GENERROR; goto exit; } lid = ipsnmp_util_last_subid(nodeobj->id); ip_assert(lid >= 1 && lid <= 20); ip_assert(lid != 12 && lid != 18); best_netif = ipnet_if_mib_table_search_ifTable(id, buf, best, cmd, &ret); if (best_netif == IP_NULL) goto exit; if (cmd == IPSNMP_MIB_COMMAND_GET || cmd == IPSNMP_MIB_COMMAND_NEXT) { iid = ipsnmp_create_iid_direct(nodeobj->id, best); if (iid == IP_NULL) { ret = IPSNMP_ERROR_GENERROR; goto exit; } switch(lid) { case 1: /* ifIndex */ ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.ifindex); break; case 2: /* ifDescr */ ret = ipsnmp_util_put_octetstring(magic, iid, (Ip_u8 *)best_netif->ipcom.name, ipcom_strlen(best_netif->ipcom.name)); break; case 3: /* ifType */ ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.type); break; case 4: /* ifMtu */ ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.mtu); break; case 5: /* ifSpeed */ if (best_netif->ipcom.type == IP_IFT_PPP) ret = ipsnmp_util_put_gauge32(magic, iid, IPCOM_DRV_PPP_BAUDRATE); else ret = ipsnmp_util_put_gauge32(magic, iid, 100000000); break; case 6: /* ifPhysAddr */ ret = ipsnmp_util_put_octetstring(magic, iid, best_netif->ipcom.link_addr, best_netif->ipcom.link_addr_size); break; case 7: /* ifAdminStatus */ if (IP_BIT_ISSET(best_netif->ipcom.flags, IP_IFF_UP)) ret = ipsnmp_util_put_integer(magic, iid, 1); else ret = ipsnmp_util_put_integer(magic, iid, 2); break; case 8: /* ifOperStatus */ if (IP_BIT_ISSET(best_netif->ipcom.flags, IP_IFF_UP)) ret = ipsnmp_util_put_integer(magic, iid, 1); else ret = ipsnmp_util_put_integer(magic, iid, 2); break; case 9: /* ifLastChange */ ret = ipsnmp_util_put_timeticks(magic, iid, best_netif->ipcom.mib2.ifLastChange); break; case 10: /* ifInOctets */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInOctets); break; case 11: /* ifInUcastPkts */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInUcastPkts); break; case 13: /* ifInDiscards */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInDiscards); break; case 14: /* ifInErrors */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInErrors); break; case 15: /* ifInUnknownProtos */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInUnknownProtos); break; case 16: /* ifOutOctets */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutOctets); break; case 17: /* ifOutUcastPkts */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutUcastPkts); break; case 19: /* ifOutDiscards */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutDiscards); break; case 20: /* ifOutErrors */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutErrors); break; default: IP_PANIC(); ret = IPSNMP_ERROR_GENERROR; break; } ipcom_free(iid); } if (cmd == IPSNMP_MIB_COMMAND_TEST || cmd == IPSNMP_MIB_COMMAND_SET) { switch(lid) { case 7: /* ifAdminStatus */ ret = ipsnmp_util_get_integer(vb, &ifAdminStatus); if (ret == IPSNMP_ERROR_NOERROR) { if (ifAdminStatus != 1 && ifAdminStatus != 2) { ret = IPSNMP_ERROR_WRONGVALUE; } } if (ret == IPSNMP_ERROR_NOERROR && cmd == IPSNMP_MIB_COMMAND_SET) { fd = ipnet_do_socket(IP_AF_INET, IP_SOCK_DGRAM, IP_IPPROTO_UDP, IP_FALSE); if(fd != IP_INVALID_SOCKET) { /* Change interface status */ ipcom_memset(&ifreq, 0, sizeof(struct Ip_ifreq)); ipcom_strcpy(ifreq.ifr_name, best_netif->ipcom.name); if (ipnet_sys_socketioctl(fd, IP_SIOCGIFFLAGS, &ifreq) < 0) { IPCOM_LOG1(ERR, "Failed to get interface flags: %s", ipcom_strerror(ipcom_errno)); ret = IPSNMP_ERROR_GENERROR; } if (ifAdminStatus == 1) IP_BIT_SET(ifreq.ip_ifr_flags, IP_IFF_UP); else IP_BIT_CLR(ifreq.ip_ifr_flags, IP_IFF_UP); if (ipnet_sys_socketioctl(fd, IP_SIOCSIFFLAGS, &ifreq) < 0) { IPCOM_LOG1(ERR, "Failed to set interface flags: %s", ipcom_strerror(ipcom_errno)); ret = IPSNMP_ERROR_GENERROR; } ipnet_sys_socketclose(fd); } else { IPCOM_LOG0(ERR, "Failed to create socket for ioctl call"); ret = IPSNMP_ERROR_GENERROR; } } break; default: IP_PANIC(); ret = IPSNMP_ERROR_GENERROR; break; } } exit: if (buf != IP_NULL) ipcom_free(buf); if (best != IP_NULL) ipcom_free(best); return ret; }
/* *=========================================================================== * ipwlan_cmd_wlan_en *=========================================================================== * Description: Parses and executes wlan shell commands. * Parameters: 'en' == 0 => Do not print to console, * Returns: 0 on success */ IP_STATIC int ipwlan_cmd_wlan_en(int en, int argc, char **argv) { int i; int j; int k; Ip_fd fd; char *endp; char ssid[32]; Ipcom_iwreq iwreq; unsigned char oid_data[10]; Ip_err ret = IPCOM_SUCCESS; if (argc < 3) { /* To few arguments */ ipwlan_print_usage(en); return ret; } #ifdef IPCOM_USE_INET fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0); #else fd = ipcom_socket(IP_AF_INET6, IP_SOCK_DGRAM, 0); #endif if (fd == IP_SOCKERR) { ipwlan_printf(en, "Error: unable to create command socket"IP_LF); return IPCOM_ERR_FAILED; } /* Verify interface existance */ ipcom_sprintf(iwreq.if_name, "%.*s", IP_IFNAMSIZ - 1, argv[1]); if(ipcom_if_nametoindex(iwreq.if_name) < 1) { ipwlan_printf(en, "Error: Interface '%s' does not exist"IP_LF, iwreq.if_name); goto error; } /* Reset WLAN device */ if (!ipcom_strcmp(argv[2], "reset")) { ipcom_socketioctl(fd, IP_SIOCSIWRESET, &iwreq); goto done; } /* Set/Get mode */ if (!ipcom_strcmp(argv[2], "mode")) { if(argc < 4) { if(ipcom_socketioctl(fd, IP_SIOCGIWMODE, &iwreq) < 0) { goto error; } if(iwreq.u.mode == IP_IW_MODE_INFRA) { i = wlan_mode_client_infra; } else if(iwreq.u.mode == IP_IW_MODE_AUTO) { i = wlan_mode_client_auto; } else if(iwreq.u.mode == IP_IW_MODE_ADHOC) { i = wlan_mode_client_adhoc; } else if(iwreq.u.mode == IP_IW_MODE_MASTER) { i = wlan_mode_ap; } else { i = wlan_mode_unknown; } ipwlan_printf(en, "Current mode is: %s"IP_LF, wlan_mode_text[i]); } else { /* Set mode */ if (!strcmp(argv[3], "client")) { if(argc < 5 || (strcmp(argv[4], "adhoc") && strcmp(argv[4], "auto") && strcmp(argv[4], "infra"))) { ipwlan_printf(en, "prism <interface> mode client [auto|adhoc|infra]"IP_LF); goto done; } iwreq.u.mode = !strcmp(argv[4], "auto") ? IP_IW_MODE_AUTO : (!strcmp(argv[4], "infra") ? IP_IW_MODE_INFRA : IP_IW_MODE_ADHOC); } else if (!strcmp(argv[3], "ap")) { iwreq.u.mode = IP_IW_MODE_MASTER; } else { ipwlan_printf(en, "prism <interface> mode ap"IP_LF); ipwlan_printf(en, "prism <interface> mode client auto|adhoc|infra"IP_LF); goto done; } if (ipcom_socketioctl(fd, IP_SIOCSIWMODE, &iwreq) < 0) { goto error; } } goto done; } /* Get/Set SSID */ if (!ipcom_strcmp(argv[2], "ssid")) { iwreq.u.essid.pointer = ssid; if (argc < 4) { /* Get SSID */ iwreq.u.essid.length = sizeof(ssid); if (ipcom_socketioctl(fd, IP_SIOCGIWESSID, &iwreq) == 0) { if(ssid[0]) { ipwlan_printf(en, "ssid: %s"IP_LF, ssid); } else { ipwlan_printf(en, "-- Not associated --"IP_LF); } goto done; } } else { /* Set SSID */ iwreq.u.essid.length = ipcom_sprintf(ssid, "%.*s", sizeof(ssid) - 1, argv[3]); if (ipcom_socketioctl(fd, IP_SIOCSIWESSID, &iwreq) == 0) { goto done; } } goto error; } /* Get/Set frequency */ if (!ipcom_strcmp(argv[2], "freq")) { if(argc < 4) { /* Get frequency */ if (ipcom_socketioctl(fd, IP_SIOCGIWFREQ, &iwreq) < 0) { goto error; } ipwlan_printf(en, "RF frequency: %d kHz"IP_LF, iwreq.u.freq.m); } else { /* Set frequency */ if (!strcmp(argv[3], "auto")) { iwreq.u.freq.flags = IP_IW_FREQ_AUTO; iwreq.u.freq.m = WLAN_FREQUENCY_BAND; iwreq.u.freq.e = 0; } else { i = ipcom_strtol(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid frequency value, '%s'"IP_LF, argv[3]); goto done; } iwreq.u.freq.flags = IP_IW_FREQ_FIXED; iwreq.u.freq.m = i; iwreq.u.freq.e = 0; if (ipcom_socketioctl(fd, IP_SIOCSIWFREQ, &iwreq) < 0) { goto error; } } } goto done; } /* Get/Set authentication */ if (!ipcom_strcmp(argv[2], "auth")) { if (argc < 4) { /* Get authentication policy */ ipwlan_printf(en, "Cannot get authentication policy. Try device specific shell command"IP_LF); } else { /* Set authentication policy */ if (strcmp(argv[3], "open") && strcmp(argv[3], "shared-key") && strcmp(argv[3], "wpa-psk") && strcmp(argv[3], "wpa") && strcmp(argv[3], "wpa2-psk") && strcmp(argv[3], "wpa2")) { ipwlan_printf(en, "Error: invalid authentication policy, valid policies are 'open', 'shared-key', 'wpa-psk or 'wpa'" IP_LF); goto done; } if(strcmp(argv[3], "open") == 0) iwreq.u.auth_type = IP_IW_AUTH_ALG_OPEN_SYSTEM; else if(strcmp(argv[3], "shared-key") == 0) iwreq.u.auth_type = IP_IW_AUTH_ALG_SHARED_KEY; else if(strcmp(argv[3], "wpa2-psk") == 0) iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA2_PSK; else if(strcmp(argv[3], "wpa2") == 0) iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA2; else if(strcmp(argv[3], "wpa-psk") == 0) iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA_PSK; else iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA; if (ipcom_socketioctl(fd, IP_SIOCSIWAUTHTYPE, &iwreq) < 0) { goto error; } } goto done; } /* Get/Set encryption */ if (!ipcom_strcmp(argv[2], "encr")) { if (argc < 4) { if (ipcom_socketioctl(fd, IP_SIOCGIWENCRTYPE, &iwreq) < 0) { goto error; } for(i = 0; i < (int) (sizeof(ipwlan_encr_policy)/sizeof(ipwlan_encr_policy[0])); i++) { if ((unsigned) ipwlan_encr_policy[i] == iwreq.u.encr_type) { break; } } ipwlan_printf(en, "privacy: %s"IP_LF, wlan_encr_text[i]); } else { /* Set encryption parameters */ if (!strcmp(argv[3], "wep")) { if (argc < 5 || argc > 6) { ipwlan_printf(en, "Usage: wlan <interface> encr wep 1|2|3|4 [<key>]"IP_LF); goto done; } i = ipcom_strtol(argv[4], &endp, 10); if (*endp != '\0' || i < 1 || i > 4) { ipwlan_printf(en, "Error: Invalid index value allowed are 1 to 4" IP_LF); goto done; } if(argc == 6) { if (argv[5][0] == '0' && argv[5][1] == 'x') { if (ipcom_strspn(argv[5] + 2, "012345678ABCDEFabcdef") != ipcom_strlen(argv[5] + 2) || ipcom_strlen(argv[5] + 2) > 32 || (ipcom_strlen(argv[5] + 2) % 2) != 0) /* 32 nibbles => 128 bits */ { ipwlan_printf(en, "Usage: wlan <interface> encr wep <index> 0x<hex key>|<string key>"IP_LF); goto done; } for (j = 0; ipcom_sscanf(argv[5] + 2 + 2 * j, "%2x", &k); j++) { iwreq.u.key.key[j] = (unsigned char)k; } iwreq.u.key.len = j; } else { /* key is a text string */ iwreq.u.key.len = ipcom_sprintf((char *)iwreq.u.key.key, "%.*s", MIN(sizeof(iwreq.u.key.key) - 1, ipcom_strlen(argv[5])), argv[5]); } iwreq.u.key.flags = 0; } else { iwreq.u.key.flags = IP_IW_KEY_FLAG_NOKEY; } iwreq.u.key.type = IP_IW_ENCR_ALG_WEP; iwreq.u.key.index = i - 1; /* Index 1 - 4 */ if (ipcom_socketioctl(fd, IP_SIOCSIWENCRKEY, &iwreq) < 0) { goto error; } iwreq.u.encr_type = IP_IW_ENCR_ALG_WEP; if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else if (!strcmp(argv[3], "none")) { iwreq.u.encr_type = IP_IW_ENCR_ALG_NONE; if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else if (!strcmp(argv[3], "tkip")) { iwreq.u.encr_type = IP_IW_ENCR_ALG_TKIP; if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else if (!strcmp(argv[3], "ccmp")) { iwreq.u.encr_type = IP_IW_ENCR_ALG_CCMP; if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else { goto error; } } goto done; } /* Commit changes */ if (!ipcom_strcmp(argv[2], "commit")) { if (ipcom_socketioctl(fd, IP_SIOCSIWCOMMIT, &iwreq) < 0) { goto error; } goto done; } /* Get link quality */ if (!ipcom_strcmp(argv[2], "quality")) { ipcom_socketioctl(fd, IP_SIOCGIWAP, &iwreq); ipcom_memcpy(oid_data, iwreq.u.addr.sa_data, 6); ipcom_memcpy(iwreq.u.quality.bssid, oid_data, 6); if (ipcom_socketioctl(fd, IP_SIOCGIWQUALITY, &iwreq) < 0) { goto error; } ipwlan_printf(en, "\r\nLink quality\r\n============\r\n"); ipwlan_printf(en, "RSSI: % 3d dBm\r\n", (int)iwreq.u.quality.level); ipwlan_printf(en, "Rate: % 3d Mbps\r\n", (unsigned int)iwreq.u.quality.qual); goto done; } error: ipwlan_printf(en, "Error: command %s failed"IP_LF, argv[2]); ret = IPCOM_ERR_FAILED; done: (void)ipcom_socketclose(fd); return ret; }
/* *=========================================================================== * ipcom_sysvar_for_each *=========================================================================== * Description: * Parameters: * Returns: */ IP_PUBLIC Ip_err ipcom_sysvar_for_each(const char *name, Ipcom_sysvar_for_each cb_func, void *cookie) { Ipcom_sysvar_entry *sysvar; Ipcom_sysvar_tree *tree; Ip_size_t namelen = 0; Ip_err retval; Ipcom_pqueue *pq; retval = ipcom_once(&ipcom_sysvar_once, ipcom_sysvar_init, IP_NULL); if (retval != IPCOM_SUCCESS) return retval; if (name) { namelen = ipcom_strlen(name); if (name[namelen-1] == '*') namelen--; /* ignore trailing wildcard sign */ } pq = ipcom_pqueue_new((Ipcom_pqueue_cmp_func)ipcom_sysvar_pqueue_cmp, ipcom_pqueue_nop_store_index); if (pq == IP_NULL) return IPCOM_ERR_NO_MEMORY; IPCOM_CODE_LOCK(); tree = ipcom_sysvar_tree_get(-1); if (tree == IP_NULL) { ipcom_pqueue_delete(pq); IPCOM_CODE_UNLOCK(); return IPCOM_ERR_NO_MEMORY; } /* Add all sysvars to the priority queue so they can be extracted sorted in lexicographical order */ ipcom_hash_for_each(tree->sysvars, (Ipcom_hash_foreach_cb_func)ipcom_sysvar_pqueue_insert_cb, pq); while (IP_NULL != (sysvar = ipcom_pqueue_remove_next(pq))) { if (name == IP_NULL || ipcom_strncmp(sysvar->name, name, namelen) == 0) { IPCOM_CODE_UNLOCK(); (void)cb_func(sysvar->name, sysvar->value, sysvar->flags, cookie); IPCOM_CODE_LOCK(); } ipcom_sysvar_release(tree, sysvar); } ipcom_pqueue_delete(pq); ipcom_sysvar_tree_done(tree); IPCOM_CODE_UNLOCK(); #ifdef IP_PORT_OSE5_DISABLED return ipcom_sysvar_for_each_ose5(name, cb_func, cookie); #else return IPCOM_SUCCESS; #endif }
/* *=========================================================================== * ipnet_nat_proxy_dns_parse_questions *=========================================================================== * Description: Parses and modifies DNS questions in a DNS packet. * Parameters: buf - pointer to buffer with the DNS questions. * buflen - length of buffer with DNS questions. * offset - offset in the buffer where the DNS questions begin. * newlen - pointer to the length of the message if modified. * dns_hdr - pointer to the DNS protocol header. * param - pointer to NAT proxy parameters. * Returns: The number of bytes parsed or -1 if failed. */ IP_STATIC Ip_s32 ipnet_nat_proxy_dns_parse_questions(Ip_u8 *buf, int buflen, int offset, int *newlen, Ipnet_nat_dns_hdr *dns_hdr, Ipnet_nat_proxy_param *param) { int i, j, k, count, origoffset, numq, numa, request; Ip_u16 type, cla, flags; Ip_u8 addr[4]; Ipnet_nat_dns_transaction *trans; int newbuflen = sizeof(dnsbuf); Ip_u8 c, *zone; numq = IP_GET_NTOHS(&dns_hdr->no_ques); if (numq != 1) { IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: supports only one question per message"); return -1; } numa = IP_GET_NTOHS(&dns_hdr->no_answ); flags = IP_GET_NTOHS(&dns_hdr->flags); request = (flags & IPNET_NAT_DNS_QR_FLAG) != 0 ? 0 : 1; origoffset = offset; for (i=0; i<numq; i++) { /* Get the name */ count = ipnet_nat_proxy_dns_decode_name(buf, buflen, offset, dnsname, sizeof(dnsname)); if (count < 0) { IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: could not decode dns name"); return -1; } /* Copy the name */ if (newbuflen - *newlen < count) { IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: no space left in modified buffer"); return -1; } ipcom_memcpy(&dnsbuf[*newlen], buf+offset, count); *newlen += count; offset += count; /* Check space for type and class */ if (buflen - offset < 4) { IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: message too short to parse question"); return -1; } /* Get the type */ type = (Ip_u16)(IP_GET_NTOHS(buf+offset)); switch(type) { case IPNET_NAT_DNS_QTYPE_AAAA: if (request) { trans = ipnet_nat_proxy_dns_add_transaction(IPNET_NAT_DNS_QTYPE_A, dns_hdr, param, IP_NULL); if (trans == IP_NULL) { IPCOM_LOG0(ERR, "ipnet_nat_proxy_dns_parse_questions() :: could not add transaction to list"); return -1; } else { IPCOM_LOG4(DEBUG, "ipnet_nat_proxy_dns_parse_questions() :: added transaction:" "id=%d port=%d addr=0x%08x type=%d", trans->id, trans->srcport, trans->dstaddr, trans->type); } type = IPNET_NAT_DNS_QTYPE_A; /* Change type to A */ } break; case IPNET_NAT_DNS_QTYPE_A: if (!request) { trans = ipnet_nat_proxy_dns_find_transaction(IPNET_NAT_DNS_QTYPE_A, dns_hdr, param); if (trans != IP_NULL) { IPCOM_LOG4(DEBUG, "ipnet_nat_proxy_dns_parse_questions() :: found transaction:" "id=%d port=%d addr=0x%08x type=%d", trans->id, trans->srcport, trans->dstaddr, trans->type); ipnet_nat_proxy_dns_remove_transaction(trans); } else { return -1; } type = IPNET_NAT_DNS_QTYPE_AAAA; /* Change type back to AAAA */ } break; case IPNET_NAT_DNS_QTYPE_PTR: if (request) { zone = (Ip_u8 *)ipcom_strstr((char *)dnsname, "ip6.int"); if (zone == IP_NULL) zone = (Ip_u8 *)ipcom_strstr((char *)dnsname, "ip6.arpa"); if (zone == IP_NULL) { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_dns_parse_questions() :: unhandled zone in PTR request"); return -1; } /* Extract IPv4 part */ if (ipcom_strlen((char *)dnsname) != 64 + ipcom_strlen((char *)zone)) { IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: invalid name in PTR request"); return -1; } k=0; for (j=3; j>=0; j--) { c = ipcom_tolower(dnsname[k]); c = c > '9' ? c - 'a' + 10 : c - '0'; addr[j] = c; k += 2; c = ipcom_tolower(dnsname[k]); c = c > '9' ? c - 'a' + 10 : c - '0'; c <<= 4; addr[j] += c; k += 2; } trans = ipnet_nat_proxy_dns_add_transaction(IPNET_NAT_DNS_QTYPE_PTR, dns_hdr, param, dnsname); if (trans == IP_NULL) { IPCOM_LOG0(ERR, "ipnet_nat_proxy_dns_parse_questions() :: could not add transaction to list"); return -1; } else { IPCOM_LOG4(DEBUG, "ipnet_nat_proxy_dns_parse_questions() :: added transaction:" "id=%d port=%d addr=0x%08x type=%d", trans->id, trans->srcport, trans->dstaddr, trans->type); } /* Convert address to PTR name */ if (ipnet_nat_proxy_dns_ptr_name(dnsname, sizeof(dnsname), addr, IP_AF_INET, (Ip_u8 *)"in-addr.arpa") < 0) { ipnet_nat_proxy_dns_remove_transaction(trans); IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: could not encode PTR name"); return -1; } *newlen -= count; /* Move index back to before the name */ count = ipnet_nat_proxy_dns_encode_name(dnsbuf, newbuflen, *newlen, dnsname); if (count < 0) { ipnet_nat_proxy_dns_remove_transaction(trans); IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: could not encode dns name"); return -1; } *newlen += count; } else { trans = ipnet_nat_proxy_dns_find_transaction(IPNET_NAT_DNS_QTYPE_PTR, dns_hdr, param); if (trans != IP_NULL) { IPCOM_LOG4(DEBUG, "ipnet_nat_proxy_dns_parse_questions() :: found transaction:" "id=%d port=%d addr=0x%08x type=%d", trans->id, trans->srcport, trans->dstaddr, trans->type); *newlen -= count; /* Move index back to before the name */ count = ipnet_nat_proxy_dns_encode_name(dnsbuf, newbuflen, *newlen, trans->ptrname); if (count < 0) { ipnet_nat_proxy_dns_remove_transaction(trans); IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: could not encode dns name"); return -1; } *newlen += count; if (numa == 0) { /* Remove the transaction if there are no answers */ ipnet_nat_proxy_dns_remove_transaction(trans); } } else { return -1; } } break; default: return -1; } /* Copy the type */ if (newbuflen - *newlen < 2) { IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: no space left in modified buffer"); return -1; } IP_SET_HTONS(&dnsbuf[*newlen], type); *newlen += 2; offset += 2; /* Get the class */ cla = (Ip_u16)(IP_GET_NTOHS(buf+offset)); if (cla != IPNET_NAT_DNS_QCLASS_INET) { IPCOM_LOG1(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: unhandled class: %d", cla); return -1; } /* Copy the class */ if (newbuflen - *newlen < 2) { IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: no space left in modified buffer"); return -1; } IP_SET_HTONS(&dnsbuf[*newlen], cla); *newlen += 2; offset += 2; } return offset - origoffset; }
/* *=========================================================================== * ipnet_if_mib_handler_ifXTable *=========================================================================== * Description: MIB handler for variables in ifXTable * Parameters: See file 'ipsnmp.h' * Returns: IPSNMP_ERROR_XXX * */ IP_STATIC Ip_s32 ipnet_if_mib_handler_ifXTable(Ip_s32 cmd, char *id, Ipsnmp_varbind *vb, Ip_s32 magic, struct Ipsnmp_node_object *nodeobj) { Ip_s32 lid, ret = -1; Ip_s32 ifLinkUpDownTrapEnable = 0; char *iid; char *buf = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID); char *best = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID); Ipnet_netif *best_netif; if (buf == IP_NULL || best == IP_NULL) { ret = IPSNMP_ERROR_GENERROR; goto exit; } lid = ipsnmp_util_last_subid(nodeobj->id); ip_assert((lid >= 1 && lid <= 5) || (lid >= 14 && lid <= 19)); best_netif = ipnet_if_mib_table_search_ifTable(id, buf, best, cmd, &ret); if (best_netif == IP_NULL) goto exit; if (cmd == IPSNMP_MIB_COMMAND_GET || cmd == IPSNMP_MIB_COMMAND_NEXT) { iid = ipsnmp_create_iid_direct(nodeobj->id, best); if (iid == IP_NULL) { ret = IPSNMP_ERROR_GENERROR; goto exit; } switch(lid) { case 1: /* ifName */ ret = ipsnmp_util_put_octetstring(magic, iid, (Ip_u8 *)best_netif->ipcom.name, ipcom_strlen(best_netif->ipcom.name)); break; case 2: /* ifInMulticastPkts */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInMulticastPkts); break; case 3: /* ifInBroadcastPkts */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInBroadcastPkts); break; case 4: /* ifOutMulticastPkts */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutMulticastPkts); break; case 5: /* ifOutBroadcastPkts */ ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutBroadcastPkts); break; case 14: /* ifLinkUpDownTrapEnable */ if (best_netif->ipcom.mib2.ifLinkUpDownTrapEnable == 0) best_netif->ipcom.mib2.ifLinkUpDownTrapEnable = 1; ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.mib2.ifLinkUpDownTrapEnable); break; case 15: /* ifHighSpeed */ if (best_netif->ipcom.type == IP_IFT_PPP) ret = ipsnmp_util_put_gauge32(magic, iid, 0); else ret = ipsnmp_util_put_gauge32(magic, iid, 100); break; case 16: /* ifPromiscuousMode */ if (IP_BIT_ISSET(best_netif->ipcom.flags, IP_IFF_PROMISC)) ret = ipsnmp_util_put_integer(magic, iid, 1); else ret = ipsnmp_util_put_integer(magic, iid, 2); break; case 17: /* ifConnectorPresent */ ret = ipsnmp_util_put_integer(magic, iid, 2); break; case 18: /* ifAlias */ ret = ipsnmp_util_put_octetstring(magic, iid, IP_NULL, 0); break; case 19: /* ifCounterDiscontinuityTime */ ret = ipsnmp_util_put_timeticks(magic, iid, 0); break; default: IP_PANIC(); ret = IPSNMP_ERROR_GENERROR; break; } ipcom_free(iid); } if (cmd == IPSNMP_MIB_COMMAND_TEST || cmd == IPSNMP_MIB_COMMAND_SET) { switch(lid) { case 14: /* ifLinkUpDownTrapEnable */ ret = ipsnmp_util_get_integer(vb, &ifLinkUpDownTrapEnable); if (ret == IPSNMP_ERROR_NOERROR) { if (ifLinkUpDownTrapEnable != 1 && ifLinkUpDownTrapEnable != 2) { ret = IPSNMP_ERROR_WRONGVALUE; } } if (ret == IPSNMP_ERROR_NOERROR && cmd == IPSNMP_MIB_COMMAND_SET) { best_netif->ipcom.mib2.ifLinkUpDownTrapEnable = ifLinkUpDownTrapEnable; } break; case 16: /* ifPromiscuousMode */ case 18: /* ifAlias */ ret = IPSNMP_ERROR_NOSUCHNAME; break; default: IP_PANIC(); ret = IPSNMP_ERROR_GENERROR; break; } } exit: if (buf != IP_NULL) ipcom_free(buf); if (best != IP_NULL) ipcom_free(best); return ret; }
/* *=========================================================================== * ipcom_shell_print_prompt *=========================================================================== * Description: Print shell prompt. * Parameters: * Returns: 0 = success, <0 = error code. * */ IP_STATIC int ipcom_shell_print_prompt(char *prompt_template, char *prompt_addr, int *promptlen, Ip_pid_t ppid, Ip_u32 seqno) { int baselen; int ret = 0; int buflen = 0; char *buf; #if IPCOM_USE_FILE != IPCOM_FILE_NONE char *cwd; char *base; char cwdbuf[128]; #endif buf = ipcom_malloc(IPCOM_STDIO_BUFSIZE); if (buf == IP_NULL) return -1; for (; *prompt_template != '\0'; ++prompt_template) { ip_assert(buflen < (int)IPCOM_STDIO_BUFSIZE - 1); if (*prompt_template != '\\') { /* 'Normal' character */ buf[buflen++] = *prompt_template; } else { /* New special character*/ switch (*++prompt_template) { case 'w': /* Print current working directory */ case 'W': #if IPCOM_USE_FILE != IPCOM_FILE_NONE /* Print basename of the current workning directory */ cwd = ipcom_getcwd(cwdbuf, sizeof(cwdbuf)); if (cwd == IP_NULL) { IPCOM_LOG0(DEBUG, "ipcom_shell_print_prompt :: ipcom_getcwd() failed"); break; } if (*prompt_template == 'w') base = cwd; else { base = ipcom_strrchr(cwd, '/'); if (base != IP_NULL && base != cwd) base++; else { base = ipcom_strrchr(cwd, '\\'); if (base == IP_NULL) base = cwd; else base++; } } baselen = ipcom_strlen(base); ipcom_memcpy(buf + buflen, base, baselen); buflen += baselen; #endif break; case 'p': /* Print the shell process name */ { char procname[40]; ipcom_sprintf(procname, "ipcom_shell_%lx_%lx", (Ip_u32)ppid, seqno); baselen = ipcom_strlen(procname); ipcom_memcpy(buf + buflen, procname, baselen); buflen += baselen; } break; case 'P': /* Print the shell process pid */ { char pid[14]; ipcom_sprintf(pid, "0x%lx", ipcom_getpid()); baselen = ipcom_strlen(pid); ipcom_memcpy(buf + buflen, pid, baselen); buflen += baselen; } break; case 'i': /* Print the IP address */ if (*prompt_addr) { baselen = ipcom_strlen(prompt_addr); ipcom_memcpy(buf + buflen, prompt_addr, baselen); buflen += baselen; } break; #if IPCOM_USE_ENV != IPCOM_ENV_NONE case 'V': { char vrbuf[16]; baselen = ipcom_sprintf(vrbuf, "%d", ipcom_proc_vr_get()); ipcom_memcpy(buf + buflen, vrbuf, baselen); buflen += baselen; } break; #endif default: /* Unknown code. */ IPCOM_LOG1(DEBUG, "ipcom_shell_print_prompt :: unknown code: %c", *prompt_template); buf[buflen++] = '\\'; buf[buflen++] = '\\'; buf[buflen++] = *prompt_template; break; } } } if (buflen > 0) { buf[buflen] = '\0'; if (promptlen != IP_NULL) *promptlen = ipcom_strlen(buf); ipcom_printf(buf); } ipcom_free(buf); if (ret < 0) IPCOM_LOG0(WARNING, "ipcom_shell_print_prompt :: ipcom_printf() failed"); return ret; }
IP_PUBLIC Ip_err ipcom_sysvar_ext_setv(const Ipcom_sysvar_ext entries[], int flags) { /* !!TODO: make atomic */ int i; int len = 0; int param_len = 0; char *sysvar_name = IP_NULL; char *sysvar_param = IP_NULL; char *conf = IP_NULL; char *last = IP_NULL; char *value = IP_NULL; char *ifparam = IP_NULL; Ip_err err = IPCOM_SUCCESS; sysvar_name = ipcom_calloc(1, sizeof(char) * 256); if (sysvar_name == IP_NULL) return IPCOM_ERR_NO_MEMORY; for (i = 0; ; i++) { /* * The syntax {IP_NULL,IP_NULL,IP_NULL} terminates the configuration * array. Otherwise, <name1> and/or <name2> must be specified. */ if ((entries[i].name1 == IP_NULL) && (entries[i].name2 == IP_NULL)) { err = (entries[i].param == IP_NULL) ? IPCOM_SUCCESS : IPCOM_ERR_INVALID_CONFIG; goto done; } /* * The expected string should contain <ifparam>=<value>. If the * separator is not found, assume the string does not contain * any valid configuration values. */ if (entries[i].param == IP_NULL || ipcom_strchr(entries[i].param, '=') == IP_NULL) continue; len = ipcom_strlen(entries[i].param); if ((len > param_len) || (sysvar_param == IP_NULL)) { if (sysvar_param) ipcom_free(sysvar_param); /* free previously allocated mem */ param_len = len; sysvar_param = ipcom_calloc(1, param_len+1); if (sysvar_param == IP_NULL) { ipcom_free(sysvar_name); return IPCOM_ERR_NO_MEMORY; } } else ipcom_memset(sysvar_param, 0, param_len+1); ipcom_strcpy(sysvar_param, entries[i].param); /* * Expected format: <ifparam1>=<value1>;<ifparam2>=<value2>;... */ conf = ipcom_strtok_r(sysvar_param, IPCOM_IFPARAM_LIST_DELIMITER, &last); if (conf == IP_NULL) { err = IPCOM_ERR_INVALID_CONFIG; goto done; } do { /* Expected format: <ifparam>=<value> */ ifparam = ipcom_strtok_r(conf, IPCOM_IFPARAM_DELIMITER, &value); if ((ifparam == IP_NULL) || (value == IP_NULL)) { err = IPCOM_ERR_INVALID_CONFIG; goto done; } ipcom_memset(sysvar_name, 0, sizeof(sysvar_name)); if (entries[i].name1 != IP_NULL) { ipcom_strcpy(sysvar_name, entries[i].name1); ipcom_strcat(sysvar_name, "."); } ipcom_strcat(sysvar_name, ifparam); if (entries[i].name2 != IP_NULL) { ipcom_strcat(sysvar_name, "."); ipcom_strcat(sysvar_name, entries[i].name2); } err = ipcom_sysvar_set(sysvar_name, value, flags); if (err == IPCOM_ERR_DUPLICATE) err = IPCOM_SUCCESS; else if (err != IPCOM_SUCCESS) goto done; } while (IP_NULL != (conf = ipcom_strtok_r(IP_NULL, IPCOM_IFPARAM_LIST_DELIMITER, &last))); } done: ipcom_free(sysvar_name); if (sysvar_param) ipcom_free(sysvar_param); return err; }
/* *=========================================================================== * ipcom_cmd_ipd *=========================================================================== * Description: * Parameters: * Returns: */ IP_PUBLIC int ipcom_cmd_ipd(int argc, char **argv) { Ipcom_getopt opt; int i, c, msgtype; Ip_err err = IPCOM_SUCCESS; #if IPCOM_VR_MAX > 1 int vr = ipcom_proc_vr_get(); int vr_new = vr; #endif if (argc < 2) { usage: ipcom_fprintf(ip_stderr, "Interpeak daemon (IPD) command, version 1.2"IP_LF "usage: "IP_LF " ipd [-V <vr>] list"IP_LF " ipd [-V <vr>] start <service>"IP_LF " ipd [-V <vr>] kill <service>"IP_LF " ipd [-V <vr>] reconfigure <service>"IP_LF " ipd [-V <vr>] <#> <service>"IP_LF IP_LF); return 0; } ipcom_getopt_clear_r(&opt); while ((c = ipcom_getopt_r(argc, argv, "V:", &opt)) != -1) { switch(c) { case 'V': #if IPCOM_VR_MAX > 1 vr_new = ipcom_atoi(opt.optarg); #endif break; default: ipcom_printf("ipd: unknown option %c"IP_LF, (char)c); return -1; } } if (opt.optind >= argc) { ipcom_printf("ipd: missing <command> argument"IP_LF); goto usage; } if(ipcom_strcmp(argv[opt.optind], "list") == 0) { #if IPCOM_VR_MAX > 1 if (vr != vr_new) ipcom_proc_vr_set(vr_new); #endif ipcom_printf("Services:"IP_LF); for (i = 0; ipcom_ipd_products[i].name != IP_NULL; i++) { if ((argc - (opt.optind + 1)) > 0) { int p; for (p = opt.optind + 1; p < argc; p++) { if (ipcom_strcasecmp(ipcom_ipd_products[i].name, argv[p]) == 0) goto print_service; } continue; } print_service: if (IP_BIT_ISSET(ipcom_ipd_products[i].flags, IPCOM_IPD_FLAG_IPD_START)) { #ifdef IP_PORT_OSE5 if (ipcom_ipd_products[i].start == IP_NULL && ipcom_ipd_isinstalled_ose5(ipcom_ipd_products[i].name) != IPCOM_SUCCESS) continue; #endif err = ipcom_ipd_send(ipcom_ipd_products[i].name, IPCOM_IPD_MSGTYPE_PING); ipcom_printf("%-20s %-s"IP_LF, ipcom_ipd_products[i].name, err == IPCOM_SUCCESS ? "started" : "killed"); } else if (ipcom_ipd_products[i].start) ipcom_printf("%-20s %-s"IP_LF, ipcom_ipd_products[i].name, "started"); } ipcom_printf(IP_LF); #if IPCOM_VR_MAX > 1 if (vr != vr_new) ipcom_proc_vr_set(vr); #endif return 0; } if ((argc - opt.optind) < 2) { ipcom_printf("ipd: missing <service> argument"IP_LF); return -1; } for (i = 0; ipcom_cmd_ipd_messages[i].name; i++) if (ipcom_strcmp(argv[opt.optind], ipcom_cmd_ipd_messages[i].name) == 0) { msgtype = ipcom_cmd_ipd_messages[i].msgtype; goto sendmsg; } if (*argv[opt.optind] == '-' && ipcom_isdigit(argv[opt.optind][1])) { /* "UNIX" signal support (using negative numbers) */ msgtype = -ipcom_atoi(argv[opt.optind] + 1); goto sendmsg; } if (ipcom_isdigit(argv[opt.optind][0])) { /* positive numbers */ msgtype = ipcom_atoi(argv[1]); goto sendmsg; } /* unknown command. */ ipcom_printf ("ipd: unknown command '%s'"IP_LF, argv[opt.optind]); return -1; /* send msg */ sendmsg: #if IPCOM_VR_MAX > 1 if (vr != vr_new) ipcom_proc_vr_set(vr_new); #endif if ((argc - opt.optind) < 3) err = ipcom_ipd_send(argv[opt.optind+1], msgtype); else { Ipcom_ipd_msg *msg; int sz = ipcom_strlen(argv[opt.optind + 2]) + 1; msg = ipcom_calloc(1, sz + sizeof(*msg)); if (msg != IP_NULL) { msg->msgtype = msgtype; ipcom_memcpy(msg + 1, argv[opt.optind + 2], sz); err = ipcom_ipd_sendmsg(argv[opt.optind+1], msg, sz + sizeof(*msg)); ipcom_free(msg); } } if(err == IPCOM_SUCCESS) ipcom_printf("ipd: %s %s ok"IP_LF, argv[opt.optind], argv[opt.optind+1]); else ipcom_printf("ipd: %s %s failed: %s"IP_LF, argv[opt.optind], argv[opt.optind+1], ipcom_err_string(err)); #if IPCOM_VR_MAX > 1 if (vr != vr_new) ipcom_proc_vr_set(vr); #endif return 0; }
/* *=========================================================================== * ipnet_ip_mib_cb_ipCidrRouteTable *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_bool ipnet_ip_mib_cb_ipCidrRouteTable(Ipnet_route_entry *rt, Ipsnmp_route_walk *rwp) { Ip_s32 tmp, lex, len = 0; /* Early exit if exact match was found previously */ if(rwp->bestrt != IP_NULL && (rwp->cmd == IPSNMP_MIB_COMMAND_GET || rwp->cmd == IPSNMP_MIB_COMMAND_TEST || rwp->cmd == IPSNMP_MIB_COMMAND_SET)) goto exit; if(rt->netif == IP_NULL) goto exit; /* Do not use hidden entries */ if(IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_X_HIDDEN)) goto exit; /* Route must be usable */ if(IP_BIT_ISFALSE(rt->hdr.flags, IPNET_RTF_UP)) goto exit; /* Do not use link layer entries */ if(IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_LLINFO)) goto exit; /* Do not use loopback entries */ if (IP_BIT_ISSET(rt->netif->ipcom.flags, IP_IFF_LOOPBACK)) goto exit; ip_assert(rt->hdr.key != IP_NULL); /* Do not use multicast entries */ if(IP_IN_CLASSD(*(Ip_u32 *)rt->hdr.key)) goto exit; /* Do not use broadcast entries */ if(ip_ntohl(*(Ip_u32 *)rt->hdr.key) == IP_INADDR_BROADCAST) goto exit; if(rwp->count_only == IP_TRUE) { count++; goto exit; } rwp->buf[0] = '\0'; /* ipCidrRouteDest */ if(ipcom_inet_ntop(IP_AF_INET, rt->hdr.key, &rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len) == IP_NULL) goto exit; len = ipcom_strlen(rwp->buf); if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, ".") < 0) goto exit; len = ipcom_strlen(rwp->buf); /* ipCidrRouteMask */ if(rt->hdr.mask == IP_NULL) { if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "255.255.255.255") < 0) goto exit; } else { if(ipcom_inet_ntop(IP_AF_INET, rt->hdr.mask, &rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len) == IP_NULL) goto exit; } len = ipcom_strlen(rwp->buf); if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, ".") < 0) goto exit; len = ipcom_strlen(rwp->buf); /* ipCidrRouteTos */ tmp = 0; if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "%d.", (int)tmp) < 0) goto exit; len = ipcom_strlen(rwp->buf); /* ipCidrRouteNextHop */ if(IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_GATEWAY)) { struct Ip_sockaddr_in *sa; ip_assert(rt->gateway != IP_NULL); sa = (struct Ip_sockaddr_in *)rt->gateway; if(ipcom_inet_ntop(IP_AF_INET, &sa->sin_addr.s_addr, &rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID - len) == IP_NULL) goto exit; } else { if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "0.0.0.0") < 0) goto exit; } len = ipcom_strlen(rwp->buf); if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, ".") < 0) goto exit; len = ipcom_strlen(rwp->buf); if(len) rwp->buf[len-1] = '\0'; lex = ipsnmp_util_lexcmp_oid(rwp->buf, rwp->id); if(rwp->cmd == IPSNMP_MIB_COMMAND_NEXT) { if(lex > 0) { if(rwp->bestrt == IP_NULL || ipsnmp_util_lexcmp_oid(rwp->buf, rwp->best) < 0) { ipcom_strcpy(rwp->best, rwp->buf); rwp->bestrt = rt; } } } else { if(lex == 0) { ipcom_strcpy(rwp->best, rwp->buf); rwp->bestrt = rt; } } exit: /* Do not delete the entry */ return IP_FALSE; }