/* *=========================================================================== * ipnet_vrrp_add_addr *=========================================================================== * Description: Adds a virtual router address. * Parameters: netif - The network interface the VRIP will be assigned to. * vrid - The VRID the address will be assigned to. * Returns: 0 = success, <0 = error code. * */ IP_GLOBAL int ipnet_vrrp_add_addr(Ipnet_netif *netif, Ip_u8 vrid, struct Ip_in_addr addr) { Ipnet_vrrp_addr_t *addr_entry; if (ipnet->vrrp_addrs == IP_NULL) { ipnet->vrrp_addrs = ipcom_hash_new((Ipcom_hash_obj_func) ipnet_vrrp_obj_hash, (Ipcom_hash_key_func) ipnet_vrrp_obj_hash, (Ipcom_hash_cmp_func) ipnet_vrrp_hash_cmp); if (ipnet->vrrp_addrs == IP_NULL) return -IP_ERRNO_ENOMEM; } addr_entry = ipnet_vrrp_get_addr_entry(netif, vrid); if (addr_entry == IP_NULL) { addr_entry = ipcom_malloc(sizeof(Ipnet_vrrp_addr_t)); if (addr_entry == IP_NULL) return -IP_ERRNO_ENOMEM; IPNET_IF_LOCK(netif); addr_entry->netif = netif; addr_entry->vrid = vrid; addr_entry->num_addrs = 1; addr_entry->addrs[0] = addr; } else { Ipnet_vrrp_addr_t *a; int i; i = ipnet_vrrp_addr_index(addr_entry, addr); if (i >= 0) return -IP_ERRNO_EEXIST; (void)ipcom_hash_remove(ipnet->vrrp_addrs, addr_entry); a = ipcom_realloc(addr_entry, sizeof(Ipnet_vrrp_addr_t) + addr_entry->num_addrs * sizeof(Ipnet_vrrp_addr_t)); if (a == IP_NULL) return -IP_ERRNO_ENOMEM; a->addrs[a->num_addrs++] = addr; addr_entry = a; } if (ipcom_hash_add(ipnet->vrrp_addrs, addr_entry) != IPCOM_SUCCESS) { ipcom_free(addr_entry); return -IP_ERRNO_ENOMEM; } IPCOM_LOG2(INFO, "VRRP: added address %s on %s", ipcom_inet_ntop(IP_AF_INET, &addr, ipnet->log_buf, sizeof(ipnet->log_buf)), netif->ipcom.name); return 0; }
IP_GLOBAL int ipnet_loopback_if_setup(Ipnet_netif *netif) { int ret = 0; #ifdef IPCOM_USE_INET6 struct Ip_in6_addr lo_addr = IP_IN6ADDR_LOOPBACK_INIT; struct Ipnet_route_add_param param; struct Ipnet_ipv6_key key; struct Ipnet_ipv6_key mask; /* Add ::1 loopback address to interface */ (void)ipnet_ip6_add_addr(netif, &lo_addr, IP_TRUE, 0xffffffff, 0xffffffff, 128); /* All packets matching ff02::/16 with no scope specified must be rejected */ ipcom_memset(&key, 0, sizeof(key)); ipcom_memset(&mask, 0, sizeof(mask)); ipcom_memset(¶m, 0, sizeof(param)); key.addr.in6.addr16[0] = ip_htons(0xff02); ipnet_route_create_mask(&mask.addr, 16); param.domain = IP_AF_INET6; param.key = &key; param.netmask = &mask; param.flags = IPNET_RTF_X_HIDDEN | IPNET_RTF_REJECT | IPNET_RTF_DONE; param.netif = netif; param.vr = netif->vr_index; param.table = IPCOM_ROUTE_TABLE_DEFAULT; ret = ipnet_route_add(¶m); if (ret < 0) IPCOM_LOG2(ERR, "Failed to setup routes on %s in vr %d", netif->ipcom.name, netif->vr_index); #endif /* IPCOM_USE_INET6 */ #ifdef IPCOM_USE_INET /* Add 127.0.0.1 loopback address to interface */ (void)ipnet_ip4_add_addr(netif, ip_htonl(IP_INADDR_LOOPBACK), ip_htonl(0xff000000), IP_TRUE, IPNET_ADDR_TYPE_UNICAST); #endif /* IPCOM_USE_INET */ return ret; }
/* *=========================================================================== * ipcom_egd *=========================================================================== * Description: This process gathers random data by calling ipcom_random_bingo_lotto() * * Applications can access the random data before the full entropy * has been gathered. This will of course mean that the quality of * the random data will not be as good, but in some situations that * may be a better trade-off than no random data at all. * Parameters: * Returns: * */ IP_STATIC IPCOM_PROCESS(ipcom_egd) { Ipcom_egd_hash_ctx md5_ctx; Ipcom_egd_hash_ctx tmp_md5_ctx; Ip_s32 rnd; Ipcom_tmo tmo; #ifdef IPCOM_EGD_DEBUG int i; #endif ipcom_proc_init(); IPCOM_LOG0(DEBUG, "ipcom_egd :: starting"); ipcom_egd_hash_init(&md5_ctx); ipcom_egd_laps = 0; #ifdef IPCOM_EGD_DEBUG ipcom_memset(ipcom_egd_raw_data, 0, sizeof(ipcom_egd_raw_data)); #endif while(ipcom_egd_laps < IPCOM_RANDOM_LAPS) { ipcom_egd_tmo_flag = 0; if(ipcom_tmo_request(&tmo, ipcom_random_tmo_handler, (int*)&ipcom_egd_tmo_flag, 50) != IPCOM_SUCCESS) { IPCOM_LOG0(ERR, "ipcom_egd :: timeout request failed, seed aborted"); goto exit; } rnd = ipcom_random_bingo_lotto(); #ifdef IPCOM_EGD_DEBUG ipcom_egd_raw_data[ipcom_egd_laps] = rnd; #endif ipcom_egd_hash_update(&md5_ctx, (void*) &rnd, sizeof(Ip_u32)); ipcom_memcpy(&tmp_md5_ctx, &md5_ctx, sizeof(Ipcom_egd_hash_ctx)); ipcom_egd_hash_final(ipcom_random_state, &tmp_md5_ctx); ipcom_egd_laps++; ipcom_millisleep(IPCOM_EGD_SLEEP_TIME); } exit: #ifdef IPCOM_EGD_DEBUG for (i=0; i < ipcom_egd_laps; i++) { IPCOM_LOG2(INFO, "ipcom_egd_raw_data[%d] = %d", i, ipcom_egd_raw_data[i]); ipcom_millisleep(100); } #endif IPCOM_LOG0(DEBUG, "ipcom_egd :: terminating"); ipcom_proc_exit(); }
/* *=========================================================================== * ipcom_hash_resize *=========================================================================== * Description: Doubles the size or cuts the size in half. * Parameters: head - The head of the hash table. * increase - Set to IP_TRUE to double the size, IP_FALSE * to half the size. * Returns: IPCOM_SUCCESS or IPCOM_ERR_NO_MEMORY if not enough memory * could be allocated. * */ IP_STATIC Ip_err ipcom_hash_resize(Ipcom_hash *head, Ip_bool increase) { void **old_hash_table; int old_size; int i; Ip_err err; old_hash_table = head->table; old_size = head->size; /* Keep the size odd since that will increase the chance of the high bits of the hash value to affect the low bits which is used as index in the hash table */ if (increase) head->size = (head->size << 1) + 3; else head->size = (head->size >> 1) - 1; head->table = IPCOM_CALLOC_STATIC(head->size, sizeof(*head->table)); if (head->table == IP_NULL) { IPCOM_LOG2(ERR, "ipcom_hash_resize :: ipcom_calloc(%d, %d) failed", head->size, sizeof(*head->table)); head->size = old_size; head->table = old_hash_table; return IPCOM_ERR_NO_MEMORY; } head->elem = 0; for (i = 0; i < old_size; i++) if (old_hash_table[i] != IP_NULL) { err = ipcom_hash_add(head, old_hash_table[i]); ip_assert(err == IPCOM_SUCCESS); (void)err; } IPCOM_FREE_STATIC(old_hash_table); return IPCOM_SUCCESS; }
/* *=========================================================================== * ipnet_vrrp_del_addr *=========================================================================== * Description: Deletes a virtual router address. * Parameters: netif - The network interface the VRIP was assigned to. * vrid - The VRID the address was assigned to. * Returns: 0 = success, <0 = error code. * */ IP_GLOBAL int ipnet_vrrp_del_addr(Ipnet_netif *netif, Ip_u8 vrid, struct Ip_in_addr addr) { Ipnet_vrrp_addr_t *addr_entry; int i; ip_assert(ipnet->vrrp_addrs != IP_NULL); addr_entry = ipnet_vrrp_get_addr_entry(netif, vrid); if (addr_entry == IP_NULL) return -IP_ERRNO_ESRCH; i = ipnet_vrrp_addr_index(addr_entry, addr); if (i < 0) return -IP_ERRNO_ESRCH; IPCOM_LOG2(INFO, "VRRP: deleted address %s on %s", ipcom_inet_ntop(IP_AF_INET, &addr, ipnet->log_buf, sizeof(ipnet->log_buf)), netif->ipcom.name); if (--addr_entry->num_addrs > 0) { for (;i < addr_entry->num_addrs; i++) addr_entry->addrs[i] = addr_entry->addrs[i + 1]; } else { (void)ipcom_hash_remove(ipnet->vrrp_addrs, addr_entry); ipcom_free(addr_entry); if (ipnet->vrrp_addrs->elem == 0) { ipcom_hash_delete(ipnet->vrrp_addrs); ipnet->vrrp_addrs = IP_NULL; } } return 0; }
/* *=========================================================================== * ipnet_nat_proxy_h225_msg *=========================================================================== * Description: Track H.225 packets. * This function handles the H.225/Q.931 call signalling packets. NAT calls * this function after translating the address and port number in the IP and * TCP headers, and when the source or destination port is the H.323 port * registered to NAT during the H.323 ALG registration (the standard port for * H.323 protocol is 1720). The H.225 call signalling protocol is used in H.323 * to establish connection between two end-points. * * This function must look at both an outbound as well as an inbound packet. * H.323 connection can be attempted from local to global endpoint or vice * versa. * * NOTE 1: * The fields in the H.225 message are ASN.1 encoded. However, due to schedule, * constraint, rather than employing an ASN.1 decoder, this function uses a simple * strategy to look for the ip+port address in the H.225 payload by taking advantage * of the fact that the port number always follows immediately after the ip address. * Since the ALG can get the expected ip address from NAT, it can search byte by * byte for this ip address to locate where it is in the H.225 payload.. * * Local host (L) <---------------> NAT <----------------> Global host (G) * * The tuple of IP address and TCP/UDP port number is sometimes called transport * address in some publications, and the same terminology will be used here. * * Case 1: Local (L) endpoint to global (G) endpoint connection * * L starts a TCP connection to G and the H.225 call signaling session starts. * The establishment of this TCP connection is all handled by NAT, so by now, * NAT should have the bind entry for this connection. During the H.225 session, * L will embed its sourceCallSignalAddress (ip/port) and G's transport address * in the H.225 payload to G. Thus, this function must parse for each H.225 * outbound packet, look for L's transport address, and substitute it with the * translated address obtained from NAT. * * In addition, this function must also observe the H.225 inbound packets from G * to look for the H.245 transport address (ip/port) in the connect message from * G. The port number provided by G here will serve as the H.245 port number. * L will use this port number to open the H.245 TCP connection with G. So upon * obtaining the H.245 port number, this function must also register the H.245 * ALG agent to NAT . * * Case 2: Global (G) endpoint to local (L) endpoint connection * * G starts a TCP connection to L via the NAT's H.323 static entry and the H.225 * call signaling session starts. As in case 1, the establishment of this TCP * connection is all handled by NAT, so by now, NAT should have the bind entry * for this connection. During the H.225 session, G will embed its sourceCall- * SignalAddress and L's global transport address in the H.225 payload. So, this * function must examine all inbound H.225 packets and substitute L's global * transport address with its real transport address. * * In addition, this function must also observe the H.225 outbound packets * to look for L's H.245 transport address which is embedded in the connect * message from L to G. The port number embedded in this message will serve as * the H.245 port number. * * G will use this port number to open the H.245 TCP connection with L. So, this * function must also register the H.245 ALG agent to NAT upon obtaining the * H.245 port number. Furthermore, since the H.245 TCP connection will be * started from G to L, this function must create a new TCP bind entry for the * impending H.245 port connection. * * NOTE 2: * TCP sequence adjustment is not required since it is a binary substitution of * IP address and port number in the payload. However, the checksum in the TCP * header must be adjusted when the TCP payload is modified. * * Parameters: appdata - pointer to application data. * applen - pointer to length of application data. * param - pointer to proxy parameters. * Returns: 1 = Packet modified. * 0 = Packet untouched. * -1 = Drop packet. */ IP_STATIC int ipnet_nat_proxy_h225_msg(Ip_u8 *appdata, int applen, Ipnet_nat_proxy_param *param) { Ipnet_nat_proxy_tuple proxy_tuple; Ip_u8 *data, *data_start; Ip_u16 local_port, port; Ip_u32 remote_address, local_address, ip_addr; int data_length, tmp; Ip_bool mod = IP_FALSE; data_length = applen; /* length of TCP payload */ if (data_length <= 0) { /* no payload to look at */ return 0; } /* go to start of TCP payload */ data = appdata; data_start = data; local_address = param->tuple.private_addr; local_port = param->tuple.private_port; remote_address = param->tuple.public_addr; if (param->incoming == IP_FALSE) /* outbound packet */ { /* get the H.225 TCP bind descriptor using L's translated source transport address from the source address in the TCP/IP header. From the bind descriptor, obtain L's real transport address and the session flow (i.e. who starts the connection first) of this connection. */ if (param->inbound == IP_FALSE) /* session started by L */ { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_h225_msg() :: outbound packet, outbound session. " "Look for sourceCallSignalAddress from local host."); while ((data + 6) <= (data_start + data_length)) { ip_addr = IP_GET_NTOHL(data); /* look for L's sourceCallSignalAddress match */ if (ip_addr == local_address) { port = IP_GET_NTOHS(data + 4); if (port == local_port) { /* replace with L's translated sourceCallSignalAdress */ IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h225_msg() :: " "Replace local address and port (0x%08x:%d) in H225 payload.", ip_addr, port); IP_SET_HTONL(data, param->nat_addr); IP_SET_HTONS(data + 4, param->nat_port); data += 6; mod = IP_TRUE; IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h225_msg() :: " "Translated local address and port are (0x%08x:%d)", param->nat_addr, param->nat_port); } else /* port != bind_info.local_transport */ { data++; IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_h225_msg() :: matched local address found, " "but not the port number."); } } else /* ip_addr != bind_info.local_addr */ { data++; } } } else /* session started by G */ { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_h225_msg() :: outbound packet, inbound session. " "Look for H245Address from local host."); while ((data + 6) <= (data_start + data_length)) { ip_addr = IP_GET_NTOHL(data); /* look for L's H245Address port */ if (ip_addr == local_address) { port = IP_GET_NTOHS(data + 4); IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h225_msg() :: " "Found H245Address (0x%08x:%d) in H225 payload.", ip_addr, port); /* register H.245 ALG to NAT */ /* if NAPT, create a H.245 TCP bind entry to prepare for H.245 connection request from G */ ipcom_memset(&proxy_tuple, 0, sizeof(proxy_tuple)); proxy_tuple.protocol = param->tuple.protocol; proxy_tuple.private_addr = local_address; proxy_tuple.private_port = port; proxy_tuple.public_addr = remote_address; tmp = ipnet_nat_proxy_add_mapping(&proxy_tuple, 0, param->mapping, IP_TRUE, /* Use port translation */ IP_TRUE, /* Inbound session */ ipnet_nat_proxy_h245, IP_NULL); if (tmp < 0) { IPCOM_LOG2(ERR, "ipnet_nat_proxy_h225_msg() :: Failed to add mapping for address = 0x%08x, port = %d", local_address, port); } else { IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h225_msg() :: Added mapping for address = 0x%08x, port = %d", local_address, port); } IP_SET_HTONL(data, param->nat_addr); IP_SET_HTONS(data + 4, (Ip_u16)tmp); data += 6; mod = IP_TRUE; IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h225_msg() :: " "Translated local address and port are (0x%08x:%d)", param->nat_addr, tmp); } else /* ip_addr != bind_info.local_addr */ { data++; } }/* while */ } /* else: session started by G */ } else /* inbound packet */ { if (param->inbound == IP_FALSE) /* session started by L */ { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_h225_msg() :: inbound packet, outbound session. " "Look for H245Address from remote host."); while ((data + 6) <= (data_start + data_length)) { ip_addr = IP_GET_NTOHL(data); /* look for G's H245Address match */ if (ip_addr == remote_address) { port = IP_GET_NTOHS(data + 4); IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h225_msg() :: " "H245Address from remote host found (0x%08x:%d).", ip_addr, port); /* register H.245 ALG to NAT */ ipcom_memset(&proxy_tuple, 0, sizeof(proxy_tuple)); proxy_tuple.protocol = param->tuple.protocol; proxy_tuple.public_addr = ip_addr; proxy_tuple.public_port = port; proxy_tuple.private_addr = param->tuple.private_addr; if (ipnet_nat_proxy_add_mapping(&proxy_tuple, 0, param->mapping, IP_TRUE, /* Use port translation */ IP_FALSE, /* Outbound session */ ipnet_nat_proxy_h245, IP_NULL) < 0) { IPCOM_LOG2(ERR, "ipnet_nat_proxy_h225_msg() :: Failed to add mapping for address = 0x%08x, port = %d", remote_address, port); } else { IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h225_msg() :: Added mapping for address = 0x%08x, port = %d", remote_address, port); } } data++; } } else /* session started by G */ { /* search for L's transport address in the H225 payload. If found, translate it to its real transport address. */ IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_h225_msg() :: inbound packet, inbound session." "Translate global transport to its local transport."); while ((data + 6) <= (data_start + data_length)) { ip_addr = IP_GET_NTOHL(data); /* look for L's translated address match */ if (ip_addr == param->nat_addr) { port = IP_GET_NTOHS(data + 4); IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h225_msg() :: " "global ip match found in H.225 payload (0x%08x:%d).", ip_addr, port); if (port == param->nat_port) { IP_SET_HTONL(data, local_address); IP_SET_HTONS(data + 4, local_port); data += 6; mod = IP_TRUE; IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h225_msg() :: " "After translation local_address and port are (0x%08x:%d).", local_address, local_port); } else /* port != bind_info.global_transport */ { data++; } } else /* ip_addr != bind_info.global_addr */ { data++; } } /* while */ } /* else (session started by G) */ } return mod == IP_TRUE ? 1 : 0; }
/* *=========================================================================== * ipnet_nat_proxy_h245_msg *=========================================================================== * Description: Track H.245 packets. * This function handles the H.245 call control packets. NAT calls this function * after translating the address and port number in the IP and TCP headers, and * when the source or destination port is the H.245 port. The H.245 port was * negotiated during the H.225 call signaling session and registered to NAT. * The H.245 call control protocol is used in H.323 to negotiate call parameters * between two end-points. For example, it negotiates the UDP connections for * the open logical channels for RTP and RTCP streams between the two endpoints. * In addition, it also negotiates the TCP connection for the T1.120 session. * * NOTE 1: * The H.245 message is ASN.1 encoded. However, due to resource and schedule * constraint, rather than employing an ASN.1 decoder, this function uses a simple * work-around alternative which appears to work just as well. This work-around * strategy looks for the ip+port address in the H.245 payload by taking advantage * of the fact that the port number always follows immediately after the ip address. * Since the ALG can get the expected ip address from NAT, it can search byte by * byte for this ip address to locate where it is in the H.245 payload. * * Local host (L) <---------------> NAT <----------------> Global host (G) * * The tuple of IP address and TCP/UDP port number is sometimes called transport * address in some publications, and the same terminology will be used here. * * For an outbound packet, L may be sending its transport addresses to G to let * G make TCP/UDP connections to it. Similarly, for an inbound packet, G may be * sending its transport addresses to L to let L make TCP/UDP connections to it. * Since only the L's transport addresses in the payload need to be translated, * it is sufficient to examine only the outbound packets. * * NOTE 2: * TCP sequence adjustment is not required since it is a binary substitution of * IP address and port number in the payload. However, the checksum in the TCP * header must be adjusted when the TCP payload is modified. * * Parameters: appdata - pointer to application data. * applen - pointer to length of application data. * param - pointer to proxy parameters. * Returns: 1 = Packet modified. * 0 = Packet untouched. * -1 = Drop packet. */ IP_STATIC int ipnet_nat_proxy_h245_msg(Ip_u8 *appdata, int applen, Ipnet_nat_proxy_param *param) { Ipnet_nat_proxy_tuple proxy_tuple; Ip_u8 *data, *data_start; Ip_u16 port; Ip_u32 local_address, ip_addr; int data_length; Ip_bool mod = IP_FALSE; if (param->incoming == IP_TRUE) return 0; data_length = applen; /* length of TCP payload */ if (data_length <= 0) { /* no payload to look at */ return 0; } /* go to start of TCP payload */ data = appdata; data_start = data; local_address = param->tuple.private_addr; /* L's local ip */ /* search for L's ip address in the H.245 payload for all possible TCP/UDP connections that may be negotiated. For each one found, create create a static TCP/UDP control block to get the translated transport address. We must do this for all L's ip address found in the H.245 payload since we are not decoding the ASN.1 message thus don't really know which ones will actually be used. A check is made to prevent creation of duplicate bind entries. The ID of each created static entry is recorded so the ALG can delete them when the Netmeeting session is terminated */ while ((data + 6) <= (data_start + data_length)) { ip_addr = IP_GET_NTOHL(data); /* look for L's global address match */ if (ip_addr == local_address) { port = IP_GET_NTOHS(data + 4); if (port > IPNET_NAT_H323_LOWER_EPHEMERAL_PORT_VALUE) { IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h245_msg() :: Local host address found in H245 payload. " "ip = 0x%08x, port = %d", ip_addr, port); /* Do not add a mapping for the TCP T1.120 port here. Should be taken care of by NAT rules */ if (port != IPNET_NAT_T1_120_PORT) { /* create a bind entry for this transport address if it hasn't been created yet */ ipcom_memset(&proxy_tuple, 0, sizeof(proxy_tuple)); proxy_tuple.protocol = IP_IPPROTO_UDP; proxy_tuple.private_addr = local_address; proxy_tuple.private_port = port; proxy_tuple.public_addr = param->tuple.public_addr; if (ipnet_nat_proxy_add_mapping(&proxy_tuple, IPNET_NAT_H323_MEDIA_TIMEOUT, param->mapping, IP_FALSE, /* NAT port = local source port */ IP_TRUE, /* Inbound session */ IP_NULL, IP_NULL) < 0) { IPCOM_LOG2(ERR, "ipnet_nat_proxy_h245_msg() :: Failed to add mapping for address = 0x%08x, port = %d", local_address, port); } else { IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_h245_msg() :: Added mapping for address = 0x%08x, port = %d", local_address, port); } } /* Replace L's local address with its global address in the payload */ IP_SET_HTONL(data, param->nat_addr); data += 6; mod = IP_TRUE; IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_h245_msg() :: " "Translated local address is (0x%08x)", param->nat_addr); } else /* detected port number is not a valid ephemeral port value */ { IPCOM_LOG1(INFO, "ipnet_nat_proxy_h245_msg() :: detected port invalid, ignore! port = %d", port); data++; } } else /* ip_addr != local_address */ { data++; } } /* end while loop */ return mod == IP_TRUE ? 1 : 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; }
/* *=========================================================================== * ipcom_shell_run_extcmd *=========================================================================== * Description: Starts a shell command process and delivers the command arguments * and stdio socket to that process. * Parameters: argc, argv - traditional command arguments * stdio_fd - the standard input, output and error sock * ppid - parent pid * cmd_pid - shell command process id * * Returns: 1 : command process started * 0 : not an external command * -1 : error * */ IP_PUBLIC Ip_err ipcom_shell_run_extcmd(int argc, char **argv, Ip_fd *stdio_fd, Ip_pid_t ppid, Ip_u32 seqno, Ip_pid_t *cmd_pid, int *proc_index) { Ipcom_proc_attr attr; Ipcom_ipc ipc; Ipcom_shellcmd_info *sinfo; Ipcom_shell_cmd *cmd = IP_NULL; Ipcom_shell_cmd *tcmd; Ip_err retval; char procname[40]; Ip_u32 stack = IPCOM_PROC_STACK_DEFAULT; Ip_pid_t pid; pid = ipcom_getpid(); ipcom_sprintf(procname, "ipcom_sc_0x%lx_%d", (Ip_u32)pid, *proc_index); /* Find command and max stack size (since we are reusing the process). */ if (argc > 0) { for (tcmd = IPCOM_LIST_FIRST(&ipcom_shell_cmd_head); tcmd; tcmd = IPCOM_LIST_NEXT(&tcmd->cmd_list)) { stack = (Ip_u32)IP_MAX(stack, tcmd->stack_size); if (cmd == IP_NULL && ipcom_strcmp(tcmd->name, argv[0]) == 0) { cmd = tcmd; if (*cmd_pid != 0) break; } } if (cmd == IP_NULL) return 0; /* Start the shell_cmd process. */ if (*cmd_pid == 0) { ipcom_proc_attr_init(&attr); attr.priority = (Ip_u32)cmd->priority; attr.stacksize = stack; attr.flags |= IPCOM_PROC_FLAG_FP; if (ipcom_proc_acreate(procname, (Ipcom_proc_func)ipcom_shell_cmd, &attr, cmd_pid)) { IPCOM_LOG0(ERR, "ipcom_shell_run_extcmd :: ipcom_proc_acreate() failed"); goto fail; } ip_assert(*cmd_pid != 0); } } else { /* argc == 0 is used to kill the shell_cmd process. */ ip_assert(*cmd_pid != 0); } /* Open IPC with ipcom_shell. */ retval = ipcom_ipc_open(&ipc, procname, -1); if (retval != IPCOM_SUCCESS) { IPCOM_LOG2(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_open(%s) failed, ret = %d", procname, retval); goto fail; } /* Send a message to ipcom_shell. */ sinfo = ipcom_ipc_malloc(sizeof(Ipcom_shellcmd_info)); if (sinfo == IP_NULL) { IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_malloc() failed, ret = %d", retval); goto fail; } /* Fill in IPC info. */ sinfo->argc = argc; if (argc > 0) { sinfo->hook = cmd->hook; sinfo->argv = argv; sinfo->fd = *stdio_fd; sinfo->pid = pid; sinfo->ppid = ppid; sinfo->seqno = seqno; #if IPCOM_USE_FILE != IPCOM_FILE_NONE if (ipcom_getcwd(sinfo->cwd, sizeof(sinfo->cwd)) == IP_NULL) ipcom_memset(sinfo->cwd, 0, sizeof(sinfo->cwd)); else sinfo->cwd[sizeof(sinfo->cwd)-1] = '\0'; #endif sinfo->prio = cmd->priority; } /* Send the IPC info. */ retval = ipcom_ipc_send(&ipc, sinfo); if (retval != IPCOM_SUCCESS) { IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_send() failed, ret = %d", retval); ipcom_ipc_free(sinfo); goto fail; } (void)ipcom_ipc_close(&ipc); #ifdef IP_PORT_OSE5 if (argc > 0) { /* OSE5 has process specific sockets -> donate child fd */ ip_assert(*cmd_pid != 0); retval = (Ip_err)efs_donate_fd(*stdio_fd, *cmd_pid); if (retval != 0) { IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: efs_donate_fd, ret = %d", retval); goto fail; } } #endif /* IP_PORT_OSE5 */ /* Wait for exit message from shell_cmd process. */ retval = ipcom_ipc_receive(IP_NULL, &sinfo, -1); if (retval != IPCOM_SUCCESS) { IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_receive(shell_cmd) failed, ret = %d", retval); goto fail; } ip_assert(argc > 0 || *(Ip_u32 *)sinfo == 1); if (*(Ip_u32 *)sinfo == 1) { *cmd_pid = 0; /* shell command called ipcom_exit(). */ (*proc_index)++; } else { #ifdef IP_PORT_OSE5 *stdio_fd = efs_receive_fd(0); if (*stdio_fd == -1) { IP_PANIC(); goto fail; } #endif #if defined(IP_PORT_OSE) || defined(IP_PORT_OSE5) /* Change child socket owner (A must for OSE to work due to poor ipcom_block impl). */ pid = ipcom_getpid(); if (ipcom_socketioctl(*stdio_fd, IP_SIOCSPGRP, &pid) < 0) { IP_PANIC2(); IPCOM_LOG1(WARNING, "ipcom_shell_run_extcmd :: ipcom_socketioctl(IP_SIOCSPGRP) failed, errno = %d", ipcom_errno); } #endif } ipcom_ipc_free(sinfo); return 1; fail: if (ipcom_ipc_isopen(&ipc)) (void)ipcom_ipc_close(&ipc); return -1; }
/* *=========================================================================== * ipnet_if_mib_init *=========================================================================== * Description: Initializes IF-MIB * Parameters: None * Returns: IPCOM_SUCCESS or IPCOM_ERR_FAILED * */ IP_PUBLIC Ip_err ipnet_if_mib_init(void) { struct Ipsnmp_node_object nodeobj; Ip_s32 ret; /* Assign lock function */ nodeobj.lock = ipnet_if_mib_lock; /* Add node "ifMIB" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.31"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifMIB"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "interfaces" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.2"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "interfaces"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifMIBObjects" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.31.1"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifMIBObjects"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifNumber" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_if_mib_handler_ifNumber; nodeobj.id = "1.3.6.1.2.1.2.1"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifNumber"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_SCALAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifTable" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.2.2"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifTable"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_AGGREGATE; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifEntry" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.2.2.1"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifEntry"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_AGGREGATE; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifIndex" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.1"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifIndex"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifDescr" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_OCTETSTRING; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.2"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifDescr"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifType" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.3"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifType"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifMtu" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.4"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifMtu"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifSpeed" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_GAUGE32; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.5"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifSpeed"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifPhysAddress" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_OCTETSTRING; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.6"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifPhysAddress"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifAdminStatus" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READWRITE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.7"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifAdminStatus"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifOperStatus" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.8"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifOperStatus"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifLastChange" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_TIMETICKS; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.9"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifLastChange"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifInOctets" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.10"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifInOctets"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifInUcastPkts" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.11"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifInUcastPkts"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifInDiscards" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.13"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifInDiscards"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifInErrors" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.14"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifInErrors"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifInUnknownProtos" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.15"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifInUnknownProtos"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifOutOctets" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.16"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifOutOctets"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifOutUcastPkts" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.17"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifOutUcastPkts"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifOutDiscards" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.19"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifOutDiscards"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifOutErrors" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifTable; nodeobj.id = "1.3.6.1.2.1.2.2.1.20"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifOutErrors"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifXTable" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.31.1.1"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifXTable"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_AGGREGATE; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifXEntry" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.31.1.1.1"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifXEntry"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_AGGREGATE; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifName" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_OCTETSTRING; nodeobj.handler = ipnet_if_mib_handler_ifXTable; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.1"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifName"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifInMulticastPkts" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifXTable; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.2"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifInMulticastPkts"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifInBroadcastPkts" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifXTable; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.3"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifInBroadcastPkts"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifOutMulticastPkts" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifXTable; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.4"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifOutMulticastPkts"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifOutBroadcastPkts" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_COUNTER32; nodeobj.handler = ipnet_if_mib_handler_ifXTable; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.5"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifOutBroadcastPkts"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifLinkUpDownTrapEnable" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READWRITE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_if_mib_handler_ifXTable; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.14"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifLinkUpDownTrapEnable"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifHighSpeed" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_GAUGE32; nodeobj.handler = ipnet_if_mib_handler_ifXTable; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.15"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifHighSpeed"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifPromiscuousMode" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READWRITE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_if_mib_handler_ifXTable; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.16"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifPromiscuousMode"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifConnectorPresent" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.17"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifConnectorPresent"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifAlias" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READWRITE; nodeobj.datatype = IPSNMP_DATA_TYPE_OCTETSTRING; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.18"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifAlias"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifCounterDiscontinuityTime" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_TIMETICKS; nodeobj.handler = ipnet_if_mib_handler_ifXTable; nodeobj.id = "1.3.6.1.2.1.31.1.1.1.19"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ifCounterDiscontinuityTime"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ifTableLastChange" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_TIMETICKS; nodeobj.handler = ipsnmp_mib_standard_handler; nodeobj.id = "1.3.6.1.2.1.31.1.5"; nodeobj.instance = &ipnet->mib2.ifTableLastChange; #ifdef IP_DEBUG nodeobj.name = "ifTableLastChange"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_SCALAR; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "linkDown" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.6.3.1.1.5.3"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "linkDown"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_TRAP; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "linkUp" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.6.3.1.1.5.4"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "linkUp"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_TRAP; ret = ipsnmp_add_node(&nodeobj); if (ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } return IPCOM_SUCCESS; }
/***************************************************************************** * * example_parse_base - Parse top-level ISC configuration items * * .IP <tok> * The tokenizer buffer * * RETURNS: * 0 on success * * NOMANUAL */ IP_STATIC Ip_s32 example_parse_base(example_token_buffer_t *tok) { for (;;) { char *token = example_get_token(tok, IP_TRUE); char *value; int ret; /* EOF; We've read the entire file - exit */ if (token == IP_NULL) return 0; /* Check the token and see if we know it */ if (ipcom_strcasecmp(token, "subnet") == 0) { ret = example_parse_subnet(tok); } else if (ipcom_strcasecmp(token, "option") == 0) { ret = example_parse_option(tok, "default"); } else if (ipcom_strcasecmp(token, "default-lease-time") == 0) { value = example_get_token(tok, IP_FALSE); if (!example_check_token(tok, ";", IP_FALSE)) { IPCOM_LOG1(ERR, "DHCPS(%d): lease time specified or ';' missing in default-lease-time directive", tok->curline); return -1; } example_do_command("dhcps config set default default-lease-time %s", value); } else if (ipcom_strcasecmp(token, "max-lease-time") == 0) { value = example_get_token(tok, IP_FALSE); if (!example_check_token(tok, ";", IP_FALSE)) { IPCOM_LOG1(ERR, "DHCPS(%d): lease time specified or ';' missing in max-lease-time directive", tok->curline); return -1; } example_do_command("dhcps config set default max-lease-time %s", value); } else if (ipcom_strcasecmp(token, "authoritative") == 0 || ipcom_strcasecmp(token, "ddns-update-style") == 0 || ipcom_strcasecmp(token, "log-facility") == 0) { /* Unsupported ISC directives * Consume this line */ IPCOM_LOG2(WARNING, "DHCPS(%d): Unhandled directive %s specified", tok->curline, token); example_get_line(tok); } } }
/***************************************************************************** * * example_parse_option - Parse a ISC option string * * .IP <tok> * The tokenizer buffer * * .IP <context> * The context the option resides in * * RETURNS: * 0 on success. * * NOMANUAL */ IP_STATIC Ip_s32 example_parse_option(example_token_buffer_t *tok, const char *context) { /* Retrieve the option name */ char *option = example_get_token(tok, IP_FALSE); if (option == IP_NULL) { IPCOM_LOG1(ERR, "DHCPS(%d): no option name specified", tok->curline); return -1; } if (ipcom_strcasecmp(option, "domain-name-servers") == 0) { /* DNS servers option; retrieve the list of servers and pass it * to our dhcps command */ char *value = example_concatenate_tokens(tok); if (value == IP_NULL) { IPCOM_LOG1(ERR, "DHCPS(%d): No servers specified or lacking ';' in domain-name-servers option", tok->curline); return -1; } example_do_command("dhcps option add %s 5 %s", context, value); ipcom_free(value); } else if (ipcom_strcasecmp(option, "domain-name") == 0) { /* A domain name */ char *value = example_get_token(tok, IP_FALSE); if (!example_check_token(tok, ";", IP_FALSE)) { IPCOM_LOG1(ERR, "DHCPS(%d): No domain name specified or lacking ';' in domain-name option", tok->curline); return -1; } example_do_command("dhcps option add %s 15 %s", context, value); } else if (ipcom_strcasecmp(option, "routers") == 0) { /* One or many routers */ char *value = example_concatenate_tokens(tok); if (value == IP_NULL) { IPCOM_LOG1(ERR, "DHCPS(%d): No servers specified or lacking ';' in routers option", tok->curline); return -1; } example_do_command("dhcps option add %s 3 %s", context, value); ipcom_free(value); } else { /* Unknown or unhandled option */ IPCOM_LOG2(WARNING, "DHCPS(%d): Unknown option %s", tok->curline, option); return -1; } return 0; }
/* *=========================================================================== * ipnet_config_add_route *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_config_add_route(int domain, char *addr, int prefix_len, char *gateway) { char *argv[] = { "route", "add", "-silent", IP_NULL, IP_NULL, IP_NULL, IP_NULL, IP_NULL, IP_NULL, IP_NULL, IP_NULL, IP_NULL, IP_NULL, }; int argc = 4; int max_prefix_len; union Ipnet_addr mask; union Ipnet_addr dst_addr; char dst_str[IP_INET6_ADDRSTRLEN]; char prefix_len_str[4]; int ret; #ifdef IPCOM_USE_INET if (domain == IP_AF_INET) { max_prefix_len = 32; argv[3] = "-inet"; } else #endif /* IPCOM_USE_INET */ #ifdef IPCOM_USE_INET6 if (domain == IP_AF_INET6) { max_prefix_len = 128; argv[3] = "-inet6"; } else #endif /* IPCOM_USE_INET6 */ { /* Unsupported domain */ IPCOM_LOG1(ERR, "unsupported domain: %d", domain); return -IP_ERRNO_EAFNOSUPPORT; } if (prefix_len == -1) /* Host route */ prefix_len = max_prefix_len; if (addr == IP_NULL || gateway == IP_NULL || prefix_len < 0 || prefix_len > max_prefix_len) return -IP_ERRNO_EINVAL; if (ipcom_inet_pton(domain, addr, &dst_addr) != 1) { IPCOM_LOG2(ERR, "invalid %s address format: %s", (domain == IP_AF_INET) ? "inet" : "inet6", addr); return -IP_ERRNO_EINVAL; } /* Apply mask */ ipcom_memset(&mask, 0, sizeof(mask)); ipnet_route_create_mask(&mask, prefix_len); ipnet_route_apply_mask(&dst_addr, &mask, max_prefix_len); (void) ipcom_inet_ntop(domain, &dst_addr, dst_str, sizeof(dst_str)); argv[argc++] = "-static"; if (prefix_len == max_prefix_len) argv[argc++] = "-host"; else { argv[argc++] = "-net"; argv[argc++] = "-prefixlen"; ipcom_sprintf(prefix_len_str, "%d", prefix_len); argv[argc++] = prefix_len_str; } argv[argc++] = dst_str; argv[argc++] = gateway; ret = ipnet_config_cmd_route(argc, argv); if (ret == IP_ERRNO_EEXIST) return 0; return ret; }
/* *=========================================================================== * ipcom_drv_ppp_init *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipcom_drv_ppp_init(Ipcom_drv_ppp_link *plink) { Ipcom_ipc ipc; Ipcom_drv_ppp_ipc *ipcbuf; char procname[IPCOM_PROC_NAME_MAX]; Ip_err retval; Ipcom_proc_attr attr; /* Open driver */ if (ipcom_drv_ppp_open(plink) != 0) goto fail; /* Create driver I/O daemons */ ipcom_proc_attr_init(&attr); attr.priority = IPCOM_PRIORITY_MIN; attr.stacksize = IPCOM_PROC_STACK_SMALL; /* Create and open output daemon */ ipcom_sprintf(procname, "ipcom_drv_%s_output", plink->netif->name); retval = ipcom_proc_acreate(procname, ipcom_drv_ppp_outputd, &attr, IP_NULL); if (retval != IPCOM_SUCCESS) goto fail; retval = ipcom_ipc_open(&plink->out_ipc, procname, -1); if (retval != IPCOM_SUCCESS) goto fail; /* Create and start input daemon */ ipcom_sprintf(procname, "ipcom_drv_%s_input", plink->netif->name); retval = ipcom_proc_acreate(procname, ipcom_drv_ppp_inputd, &attr, IP_NULL); if (retval != IPCOM_SUCCESS) goto fail; /* Open IPC. */ ipcom_sprintf(procname, "ipcom_drv_%s_input", plink->netif->name); retval = ipcom_ipc_open(&ipc, procname, -1); if (retval != IPCOM_SUCCESS) goto fail; /* Create IPC buf */ ipcbuf = ipcom_ipc_malloc(sizeof(Ipcom_drv_ppp_ipc)); if (ipcbuf == IP_NULL) goto fail; ipcbuf->netif = plink->netif; /* Send IPC buf */ retval = ipcom_ipc_send(&ipc, ipcbuf); if (retval != IPCOM_SUCCESS) { (void)ipcom_ipc_close(&ipc); goto fail; } /* Close IPC. */ (void)ipcom_ipc_close(&ipc); /* Success. */ return 0; fail: if (plink->fd != -1) { (void)close(plink->fd); plink->fd = -1; } IPCOM_LOG2(ERR, "ipcom_drv_ppp_init :: failed to open %s for %s", plink->devname, plink->netif->name); return -IP_ERRNO_EINVAL; }
/* *=========================================================================== * ipnet_ip_forward_mib_init *=========================================================================== * Description: Initializes IP-FORWARD-MIB * Parameters: None * Returns: IPCOM_SUCCESS or IPCOM_ERR_FAILED * */ IP_PUBLIC Ip_err ipnet_ip_forward_mib_init(void) { struct Ipsnmp_node_object nodeobj; Ip_s32 ret; /* Assign lock function */ nodeobj.lock = ipnet_ip_forward_mib_lock; /* Add node "ipForward" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipForward"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipForwardConformance" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.5"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipForwardConformance"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipForwardGroups" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.5.1"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipForwardGroups"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipForwardCompliances" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.5.2"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipForwardCompliances"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteNumber" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_GAUGE32; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteNumber; nodeobj.id = "1.3.6.1.2.1.4.24.3"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteNumber"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_SCALAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteTable" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.4"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteTable"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_AGGREGATE; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteEntry" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.4.1"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteEntry"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_AGGREGATE; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteDest" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_IPADDRESS; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.1"; /* nodeobj.instance = IP_NULL; */ nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteDest"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteMask" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_IPADDRESS; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.2"; /* nodeobj.instance = IP_NULL; */ nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteMask"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteTos" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.3"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteTos"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteNextHop" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_IPADDRESS; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.4"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteNextHop"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteIfIndex" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READCREATE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.5"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteIfIndex"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteType" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READCREATE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.6"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteType"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteProto" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.7"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteProto"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteAge" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READONLY; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.8"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteAge"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteInfo" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READCREATE; nodeobj.datatype = IPSNMP_DATA_TYPE_OID; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.9"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteInfo"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteNextHopAS" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READCREATE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.10"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteNextHopAS"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteMetric1" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READCREATE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.11"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteMetric1"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteMetric2" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READCREATE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.12"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteMetric2"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteMetric3" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READCREATE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.13"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteMetric3"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteMetric4" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READCREATE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.14"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteMetric4"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteMetric5" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READCREATE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.15"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteMetric5"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipCidrRouteStatus" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_READCREATE; nodeobj.datatype = IPSNMP_DATA_TYPE_INTEGER; nodeobj.handler = ipnet_ip_forward_mib_handler_ipCidrRouteTable; nodeobj.id = "1.3.6.1.2.1.4.24.4.1.16"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipCidrRouteStatus"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_COLUMNAR; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipForwardMultiPathGroup" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.5.1.2"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipForwardMultiPathGroup"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipForwardCidrRouteGroup" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.5.1.3"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipForwardCidrRouteGroup"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipForwardCompliance" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.5.2.1"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipForwardCompliance"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } /* Add node "ipForwardOldCompliance" to the MIB tree */ nodeobj.access = IPSNMP_NODE_ACCESS_NOACCESS; nodeobj.datatype = IPSNMP_DATA_TYPE_UNSPECIFIED; nodeobj.handler = IP_NULL; nodeobj.id = "1.3.6.1.2.1.4.24.5.2.2"; nodeobj.instance = IP_NULL; #ifdef IP_DEBUG nodeobj.name = "ipForwardOldCompliance"; #endif nodeobj.nodetype = IPSNMP_NODE_TYPE_OTHER; ret = ipsnmp_add_node(&nodeobj); if(ret != 0) { IPCOM_LOG2(ERR, "ipsnmp_add_node() :: failed to add %s (%d)", nodeobj.id, ret); return IPCOM_ERR_FAILED; } return IPCOM_SUCCESS; }
/* *=========================================================================== * ipcom_start_shell *=========================================================================== * Description: Starts a shell process and sets up a TCP connection. The * TCP connection is used to convey stdin and stdout data. The * stdio proxy process and the underlaying shell process is * terminated by closing the socket. If the shell terminates * (e.g. if the user gives the command 'exit') the stdio proxy * will close the TCP connection and terminate. * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipcom_start_shell(Ip_fd *stdio_sock, Ip_fd client_fd) { Ip_fd mother = IP_INVALID_SOCKET; Ip_fd shell_fd = IP_INVALID_SOCKET; Ip_socklen_t addr_len; Ipcom_ipc ipc; Ipcom_shell_info *sinfo; char procname[40]; Ip_err retval; Ipcom_proc_attr attr; Ip_bool ipc_opened = IP_FALSE; Ip_pid_t ppid, shell_pid; Ip_u16 mother_port; static Ip_u32 seqno = 0; struct Ip_addrinfo hints; struct Ip_addrinfo *res = IP_NULL; union Ip_sockaddr_union sa; *stdio_sock = IP_INVALID_SOCKET; sinfo = ipcom_ipc_malloc(sizeof(Ipcom_shell_info)); if (sinfo == IP_NULL) { IPCOM_LOG0(ERR, "ipcom_start_shell :: ipcom_ipc_malloc() failed"); goto exit; } addr_len = sizeof(sinfo->sa_prompt); if (ipcom_getsockname(client_fd, (struct Ip_sockaddr *)&sinfo->sa_prompt, &addr_len) == IP_SOCKERR) { IPCOM_LOG1(ERR, "ipcom_start_shell :: ipcom_getsockname(client_fd) failed, errno = %d", ipcom_errno); goto exit; } /* Get a tcp socket and let the stack pick a port */ ipcom_memset(&hints, 0, sizeof(hints)); hints.ai_family = sinfo->sa_prompt.sa.sa_family; hints.ai_socktype = IP_SOCK_STREAM; if (ipcom_getaddrinfo(IP_NULL, "0", &hints, &res) != 0) { IPCOM_LOG1(ERR, "ipcom_start_shell :: ipcom_getsockname(client_fd) failed, errno = %d", ipcom_errno); goto exit; } mother = ipcom_socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (mother == IP_INVALID_SOCKET) { IPCOM_LOG1(ERR, "ipcom_start_shell :: ipcom_socket(IP_AF_INET) failed, errno = %d", ipcom_errno); goto exit; } if (ipcom_bind(mother, res->ai_addr, res->ai_addrlen) == IP_SOCKERR) { IPCOM_LOG1(ERR, "ipcom_start_shell :: ipcom_bind(IP_AF_INET) failed, errno = %d", ipcom_errno); goto exit; } /* Find out which port was assigned. */ addr_len = sizeof(sa); if (ipcom_getsockname(mother, (struct Ip_sockaddr *)&sa, &addr_len) == IP_SOCKERR) { IPCOM_LOG1(ERR, "ipcom_start_shell :: ipcom_getsockname(IP_AF_INET) failed, errno = %d", ipcom_errno); goto exit; } mother_port = ip_ntohs(sa.sin.sin_port); if (ipcom_listen(mother, 1) == IP_SOCKERR) { IPCOM_LOG1(ERR, "ipcom_start_shell :: ipcom_listen() failed, errno = %d", ipcom_errno); goto exit; } /* Create and start the shell process. */ ipcom_proc_attr_init(&attr); #ifdef IP_PORT_VXWORKS attr.stacksize = IPCOM_PROC_STACK_LARGE; #else attr.priority = IPCOM_PRIORITY_DEFAULT; #endif /* IP_PORT_VXWORKS */ ppid = ipcom_getpid(); ipcom_sprintf(procname, "ipcom_shell_%lx_%lx", (Ip_u32)ppid, ++seqno); if (ipcom_proc_acreate(procname, (Ipcom_proc_func)ipcom_shell, &attr, &shell_pid)) { IPCOM_LOG0(ERR, "ipcom_start_shell :: ipcom_proc_acreate() failed"); goto exit; } /* Open IPC with ipcom_shell. */ retval = ipcom_ipc_open(&ipc, procname, -1); if (retval != IPCOM_SUCCESS) { IPCOM_LOG2(ERR, "ipcom_start_shell :: ipcom_ipc_open(%s) failed, ret = %d", procname, retval); goto exit; } ipc_opened = IP_TRUE; /* Send a message to ipcom_shell. */ sinfo->port = mother_port; sinfo->ppid = ppid; sinfo->seqno = seqno; retval = ipcom_ipc_send(&ipc, sinfo); if (retval != IPCOM_SUCCESS) { IPCOM_LOG1(ERR, "ipcom_start_shell :: ipcom_ipc_send() failed, ret = %d", retval); goto exit; } /* Wait for the shell process to connect */ shell_fd = ipcom_accept(mother, IP_NULL, IP_NULL); exit: if (mother != IP_INVALID_SOCKET) (void)ipcom_socketclose(mother); if (res != IP_NULL) ipcom_freeaddrinfo(res); if (ipc_opened) (void)ipcom_ipc_close(&ipc); else if (sinfo != IP_NULL) ipcom_ipc_free(sinfo); if (shell_fd == IP_INVALID_SOCKET) return IPCOM_ERR_FAILED; else { int enable = IP_TRUE; *stdio_sock = shell_fd; /* Disable Nagle (enable no delay) on this socket since it is an interactive connection */ (void)ipcom_setsockopt(shell_fd, IP_IPPROTO_TCP, IP_TCP_NODELAY, &enable, sizeof(enable)); return IPCOM_SUCCESS; } }