/* *=========================================================================== * ipnet_config_add_inet_addr *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_config_add_inet_addr(Ip_fd fd, char *ifname, char *option) { char *inet_addr; char *prefix_len; char *argv[] = { "ifconfig", "-silent", IP_NULL, "inet", "add", IP_NULL, IP_NULL, IP_NULL, IP_NULL }; int argc = 5; char inet_addr_str[IP_INET_ADDRSTRLEN]; char inet_prefix_len_str[8]; argv[2] = ifname; inet_addr = ipcom_strtok_r(option, " \t/", &option); if (inet_addr == IP_NULL) { IPCOM_LOG0(ERR, "inet address is missing or format is invalid"); return -IP_ERRNO_EINVAL; } if (ipcom_strcmp(inet_addr, "dhcp") == 0) { struct Ip_ifreq ifreq; use_dhcp: ipcom_strcpy(ifreq.ifr_name, ifname); ifreq.ifr_ifru.ifru_opt = 1; if (ipcom_socketioctl(fd, IP_SIOCXSDHCPRUNNING, &ifreq) < 0) { IPCOM_LOG1(ERR, "Failed to enable DHCP on %s", ifname); return ipcom_errno; } return 0; } #ifdef IPNET_USE_RARP if (ipcom_strcmp(inet_addr, "rarp") == 0) { struct Ip_ethreq ethreq; ipcom_strcpy(ethreq.ethr_name, ifname); ethreq.ethru.rarp = -1; if (ipcom_socketioctl(fd, IP_SIOCXETHSRARP, ðreq) < 0) { IPCOM_LOG1(ERR, "Failed to enable RARPP on %s", ifname); return ipcom_errno; } return 0; } #endif /* IPNET_USE_RARP */ if (ipcom_strcmp(inet_addr, "driver") == 0) { /* Get the IPv4 address to use from the driver */ struct Ip_ethreq ethreq; ipcom_strcpy(ethreq.ethr_name, ifname); if (ipcom_socketioctl(fd, IP_SIOCXETHGINET, ðreq) < 0) { IPCOM_LOG1(ERR, "Failed to read the IPv4 address from the driver for %s", ifname); return ipcom_errno; } if (ethreq.ethru.inet.addr.s_addr == 0xffffffff) goto use_dhcp; inet_addr = inet_addr_str; (void) ipcom_inet_ntop(IP_AF_INET, ðreq.ethru.inet.addr, inet_addr_str, sizeof(inet_addr_str)); prefix_len = inet_prefix_len_str; ipcom_snprintf(inet_prefix_len_str, sizeof(inet_prefix_len_str), "%d", ipcom_mask_to_prefixlen(ðreq.ethru.inet.mask, 32)); } else { prefix_len = ipcom_strtok_r(option, " \t/", &option); if (prefix_len == IP_NULL) { IPCOM_LOG0(ERR, "prefix len is missing or format is invalid"); return -IP_ERRNO_EINVAL; } } argv[argc++] = inet_addr; argv[argc++] = "prefixlen"; argv[argc++] = prefix_len; return ipnet_config_cmd_ifconfig(argc, argv); }
/* *=========================================================================== * ipnet_pkt_queue_mbc_insert_default_queue *=========================================================================== * Description: Inserts a FIFO queue in the MBC. * Parameters: pq - Pointer to where the new FIFO should be stored. * netif - The interface the queue belongs to. * Returns: 0 = success * <0 = error code * */ IP_STATIC int ipnet_pkt_queue_mbc_insert_default_queue(Ipnet_pkt_queue_mbc *q, int band) { struct Ipnet_ifqueue fifo; ipcom_strcpy(fifo.ifq_name, q->hdr.netif->ipcom.name); ipcom_strcpy(fifo.ifq_type, "fifo"); if (q->bands[band] == IP_NULL) fifo.ifq_id = IP_IFQ_ID_NONE; else fifo.ifq_id = q->bands[band]->id; fifo.ifq_parent_id = q->hdr.id; fifo.ifq_data.fifo.fifo_limit = IPNET_PKT_QUEUE_DEFAULT_FIFO_SIZE; return ipnet_pkt_queue_new(&fifo, q->hdr.netif, &q->bands[band]); }
/* *=========================================================================== * 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; }
/* *=========================================================================== * ipnet_cmd_qc_del_queue *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_cmd_qc_del_queue(Ipnet_cmd_qc *p) { ipcom_strcpy(p->p.ifq.ifq_type, "none"); if (ipcom_socketioctl(p->fd, IPNET_SIOCSIFQUEUE, &p->p.ifq) < 0) { ipcom_printf("Failed to delete the queue: %s"IP_LF, ipcom_strerror(ipcom_errno)); return -1; } 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; }
/* *=========================================================================== * 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; }
int get_ip( char * ifname) { struct Ip_ifreq ifr; int fd; int addr; fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0); ipcom_memset(&ifr,0,sizeof(ifr)); ipcom_strcpy(ifr.ifr_name, ifname); if (ipcom_socketioctl(fd, IP_SIOCGIFADDR, &ifr) != IP_SOCKERR) { addr =((struct Ip_sockaddr_in *)&ifr.ip_ifr_addr)->sin_addr.s_addr; return addr; } }
/* *=========================================================================== * ipppp_work_alloc *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC struct Ipppp_action_work * ipppp_work_alloc(Ipcom_netif *netif, int action, void *data) { struct Ipppp_action_work *work; work = ipcom_malloc(sizeof(*work)); if (work) { ipcom_strcpy(work->ifname, netif->name); work->ifindex = netif->ifindex; work->link_index = netif->link_index; work->action = action; work->data = data; } return work; }
/* *=========================================================================== * ipnet_cmd_qc_parse_dev *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_cmd_qc_parse_dev(Ipnet_cmd_qc *p) { if (p->argc < 2 || ipcom_strcmp(*p->argv, "dev") != 0) { ipcom_printf("expected 'dev <if>'" IP_LF); return -IP_ERRNO_EINVAL; } ipnet_cmd_qc_next_arg(p); if (ipcom_if_nametoindex(*p->argv) == 0) { ipcom_printf("'%s' is not a valid interface name" IP_LF, *p->argv); return -IP_ERRNO_EINVAL; } ipcom_strcpy(p->p.ifq.ifq_name, *p->argv); ipnet_cmd_qc_next_arg(p); return 0; }
/* *=========================================================================== * ipnet_config_add_gateway *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_config_add_gateway(Ip_fd fd, char *ifname, char *option) { char gw_str[IP_INET_ADDRSTRLEN]; char *gw; gw = ipcom_strtok_r(option, " \t", &option); if (gw == IP_NULL) { IPCOM_LOG1(ERR, "Wrong gateway format specified for interface %s, must be 'gateway <driver|gw_address>", ifname); IP_PANIC(); return -IP_ERRNO_EINVAL; } if (ipcom_strcmp(gw, "driver") == 0) { /* Get the IPv4 gateway address to use from the driver */ struct Ip_ethreq ethreq; ipcom_strcpy(ethreq.ethr_name, ifname); if (ipcom_socketioctl(fd, IP_SIOCXETHGINET, ðreq) < 0) { IPCOM_LOG1(ERR, "Failed to read the IPv4 gateway address " "from the driver for %s", ifname); return ipcom_errno; } if (ethreq.ethru.inet.gateway.s_addr == 0xffffffff) return 0; /* using dhcp, ignore gateway */ if (ethreq.ethru.inet.gateway.s_addr == 0) { IPCOM_LOG1(NOTICE, "No IPv4 gateway address set in driver for %s", ifname); return 0; } (void) ipcom_inet_ntop(IP_AF_INET, ðreq.ethru.inet.gateway, gw_str, sizeof(gw_str)); gw = gw_str; } return ipnet_config_add_route(IP_AF_INET, "0.0.0.0", 0, gw); }
/* *=========================================================================== * ipnet_cmd_qc_parse_queue_type *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_cmd_qc_parse_queue_type(Ipnet_cmd_qc *p) { Ipnet_cmd_qc_type_handler *h; if (p->argc < 1) { ipcom_printf("no queue type specified" IP_LF); return -IP_ERRNO_EINVAL; } ipcom_strcpy(p->p.ifq.ifq_type, *p->argv); ipnet_cmd_qc_next_arg(p); h = ipnet_cmd_qc_get_type_handler(p->p.ifq.ifq_type); if (h) return h->add(p); return -IP_ERRNO_EINVAL; }
/* *=========================================================================== * 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; }
/* *=========================================================================== * ipnet_loopback_attach *=========================================================================== * Description: Create and attach a loopback interface. * Parameters: * Returns: 0 = success, <0 = error code. * */ IP_GLOBAL int ipnet_loopback_attach(Ip_u16 vr, char *name) { Ipcom_netif *loopback_if; int ret; /* Allocate loopback interface */ loopback_if = ipcom_if_malloc(IP_IFT_LOOP); if (loopback_if == IP_NULL) return -IP_ERRNO_ENOMEM; ((Ipnet_netif *)loopback_if)->vr_index = vr; ipcom_strcpy(loopback_if->name, name); /* Attach loopback interface */ ret = ipnet_sys_if_attach(loopback_if); if (ret < 0) return ret; /* Success. */ return 0; }
/* *=========================================================================== * 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; }
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; }
/* *=========================================================================== * 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; }
/* *=========================================================================== * ipsecctrl_flows *=========================================================================== */ static int ipsecctrl_flows(Argvars *vars) { Ipipsec_ctrl_selector sel; char srcport[32], dstport[32]; int num = 0; char str[IP_INET6_ADDRSTRLEN]; char str2[IP_INET6_ADDRSTRLEN+1]; ipcom_printf("Flows:"IP_LF); sel.Index = 0; /* get first selector. */ /* Get and print the Selectors in MIB format. */ for (;;) { /* Get first/next Selector */ if (ipcom_socketioctl(vars->fd, IP_SIOCXIPSEC_SELECTOR, &sel) < 0) { ipcom_printf("ipsecctrl: ipcom_socketioctl(SELECTOR) failed (%s)"IP_LF, ipcom_strerror(ipcom_errno)); return -1; } if (sel.Index == 0) break; /* Print selector aka flow: */ num++; ipcom_printf("[%ld] :: %s ", sel.Index, FLOW_TYPE(sel.flowtype)); if (sel.flowpri != 0) ipcom_printf("pri=%d ", (signed char)sel.flowpri); /* source */ if (sel.LocalPort != sel.LocalMaxPort) ipcom_sprintf(srcport, "%d-%d", (int)ip_ntohs(sel.LocalPort), (int)ip_ntohs(sel.LocalMaxPort)); else if (sel.LocalPort == 0) ipcom_strcpy(srcport, "any"); else ipcom_sprintf(srcport, "%d", (int)ip_ntohs(sel.LocalPort)); if (ipcom_memcmp(&sel.LocalId, &sel.LocalMaxId, sizeof(union Ip_in_addr_union))) ipcom_sprintf(str2, "-%s", ipcom_inet_ntop(sel.domain, &sel.LocalMaxId, str, sizeof(str))); else *str2 = '\0'; ipcom_printf("src=%s%s/%d:%s ", ipcom_inet_ntop(sel.domain, &sel.LocalId, str, sizeof(str)), str2, ipipsec_addrmasklen(sel.domain, (Ip_u8 *)&sel.local_mask), srcport); /* destination */ if (sel.RemotePort != sel.RemoteMaxPort) ipcom_sprintf(dstport, "%d-%d", (int)ip_ntohs(sel.RemotePort), (int)ip_ntohs(sel.RemoteMaxPort)); else if (sel.RemotePort == 0) ipcom_strcpy(dstport, "any"); else ipcom_sprintf(dstport, "%d", (int)ip_ntohs(sel.RemotePort)); if (ipcom_memcmp(&sel.RemoteId, &sel.RemoteMaxId, sizeof(union Ip_in_addr_union))) ipcom_sprintf(str2, "-%s", ipcom_inet_ntop(sel.domain, &sel.RemoteMaxId, str, sizeof(str))); else *str2 = '\0'; ipcom_printf("dst=%s%s/%d:%s ", ipcom_inet_ntop(sel.domain, &sel.RemoteId, str, sizeof(str)), str2, ipipsec_addrmasklen(sel.domain, (Ip_u8 *)&sel.remote_mask), dstport); ipcom_printf("%s", ipcom_ipproto_name(sel.Protocol)); switch (sel.Protocol) { case IP_IPPROTO_ICMP: case IP_IPPROTO_ICMPV6: if (sel.ports[0] || sel.ports[1]) ipcom_printf(" type=%d code=%d", sel.ports[0], sel.ports[1]); break; case IP_IPPROTO_MH: if (sel.ports[0]) ipcom_printf(" type=%d", sel.ports[0]); break; default: break; } /* Print SA */ if (sel.sa.domain) { if (sel.sa.domain == IPIPSEC_AF_BYPASS) ipcom_printf(" %s SA: %s", sel.direction == IPIPSEC_SADIR_INPUT ? "<-" : sel.direction == IPIPSEC_SADIR_OUTPUT ? "->" : "--", IPSECSATYPENAME(sel.sa.satype)); else ipcom_printf(" %s SA: %s spi=0x%lx src=%s dst=%s", sel.direction == IPIPSEC_SADIR_INPUT ? "<-" : sel.direction == IPIPSEC_SADIR_OUTPUT ? "->" : "--", IPSECSATYPENAME(sel.sa.satype), ip_ntohl(sel.sa.spi_n), ipcom_inet_ntop(sel.sa.domain, &sel.sa.src, str, sizeof(str)), ipcom_inet_ntop(sel.sa.domain, &sel.sa.dst, str2, sizeof(str2))); } else ipcom_printf(" %s SA: none", sel.direction == IPIPSEC_SADIR_INPUT ? "<-" : sel.direction == IPIPSEC_SADIR_OUTPUT ? "->" : "--"); ipcom_printf(IP_LF); } ipcom_printf("Total of %d flows."IP_LF, num); return 0; }
/* *=========================================================================== * 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; }
/* *=========================================================================== * 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); }
/* *=========================================================================== * ipnet_config_add_inet6_addr *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_config_add_inet6_addr(Ip_fd fd, char *ifname, char *option) { char *opt; char *inet6_addr; char *prefix_len; char *argv[] = { "ifconfig", "-silent", IP_NULL, "inet6", "add", IP_NULL, IP_NULL, IP_NULL, IP_NULL, IP_NULL, IP_NULL }; int argc = 6; char inet6_addr_str[IP_INET6_ADDRSTRLEN]; char prefixlen_str[4]; argv[2] = ifname; for (;;) { /* Parse options */ opt = ipcom_strtok_r(option, " \t/", &option); if (opt == IP_NULL) { IPCOM_LOG0(ERR, "too few arguments"); return -IP_ERRNO_EINVAL; } if (ipcom_strcmp(opt, "tentative") == 0) argv[argc++] = opt; else break; } inet6_addr = opt; if (ipcom_strcmp(inet6_addr, "driver") == 0) { /* Get the IPv6 address to use from the driver */ struct Ip_ethreq ethreq; ipcom_strcpy(ethreq.ethr_name, ifname); if (ipcom_socketioctl(fd, IP_SIOCXETHGINET6, ðreq) < 0) { IPCOM_LOG1(ERR, "Failed to read the IPv6 address from the driver for %s", ifname); return ipcom_errno; } inet6_addr = inet6_addr_str; (void) ipcom_inet_ntop(IP_AF_INET6, ðreq.ethru.inet6.addr, inet6_addr_str, sizeof(inet6_addr_str)); ipcom_sprintf(prefixlen_str, "%u", ethreq.ethru.inet6.prefixlen); prefix_len = prefixlen_str; } else { prefix_len = ipcom_strtok_r(option, " \t/", &option); if (prefix_len == IP_NULL) { IPCOM_LOG0(ERR, "prefix len is missing or format is invalid"); return -IP_ERRNO_EINVAL; } } argv[5] = inet6_addr; argv[argc++] = "prefixlen"; argv[argc++] = prefix_len; return ipnet_config_cmd_ifconfig(argc, argv); }