/* *=========================================================================== * ipcom_ipproto_name *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC char * ipcom_ipproto_name(Ip_u8 protocol) { static char ipprot[10]; switch(protocol) { case 0: return "any"; case IP_IPPROTO_ICMP: return "ICMP"; case IP_IPPROTO_IGMP: return "IGMP"; case IP_IPPROTO_IPIP: return "IPIP"; case IP_IPPROTO_TCP: return "TCP "; case IP_IPPROTO_UDP: return "UDP "; case IP_IPPROTO_IPV6: return "IPV6"; case IP_IPPROTO_RSVP: return "RSVP"; case IP_IPPROTO_GRE: return "GRE "; case IP_IPPROTO_ESP: return "ESP "; case IP_IPPROTO_AH: return "AH "; case IP_IPPROTO_ICMPV6: return "ICMPV6"; case IP_IPPROTO_PIM: return "PIM "; case IP_IPPROTO_RAW: return "RAW "; case IP_IPPROTO_MH: return "MH "; default: break; } ipcom_sprintf(ipprot, "#%ld ", (Ip_s32)protocol); return (char *)ipprot; }
/* *=========================================================================== * ipnet_wlan_if_init *=========================================================================== * Description: WLAN uses the Ethernet interface with a few modifications * Parameters: * Returns: * */ IP_PUBLIC int ipnet_wlan_if_init(Ipnet_netif *netif) { int i; ipnet_eth_if_init(netif); netif->wlan = ipcom_malloc(sizeof(Ipnet_netif_wlan)); if (netif->wlan == IP_NULL) return -IP_ERRNO_ENOMEM; ipcom_memset(netif->wlan, 0, sizeof(Ipnet_netif_wlan)); i = 0; do { ipcom_sprintf(netif->ipcom.name, "wlan%d", i++); } while (ipnet_if_nametonetif(netif->vr_index, netif->ipcom.name) != IP_NULL); /* Setup link functions for WLAN use. */ netif->wlan->eth_link_ioctl = (int (*)(Ipnet_netif *, Ip_u32, void *))netif->link_ioctl; netif->link_ioctl = (Ipnet_link_ioctl)ipnet_wlan_ioctl; return 0; }
/* *=========================================================================== * ipnet_sockdev_init *=========================================================================== * Description: Create and attach application device interface. * Parameters: * Returns: * */ IP_STATIC int ipnet_sockdev_init(Ipnet_socket *s, Ip_bool user_context) { Ipcom_netif *sockdev_if; int ret = -IP_ERRNO_ENOMEM; IPCOM_UNUSED_ARG(user_context); /* Allocate loopback interface */ sockdev_if = ipcom_if_malloc(IP_IFT_SOCKDEV); if (sockdev_if == IP_NULL) goto errout; ipcom_sprintf(sockdev_if->name, "%s%d", IPNET_SOCKDEV_IF_NAME_BASE, s->proto); /* Attach loopback interface */ ret = ipcom_if_attach(sockdev_if); if (ret < 0) goto errout; s->bind_to_ifindex = sockdev_if->ifindex; sockdev_if->plink = s; ret = ipnet_if_link_ioctl((Ipnet_netif *)sockdev_if, IP_SIOCXOPEN, IP_NULL); errout: return ret; }
/* *=========================================================================== * ipcom_setenv_as_int *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC int ipcom_setenv_as_int(const char *name, int value, int rewrite) { char buf[16]; ipcom_sprintf(buf, "%d", value); return ipcom_setenv(name, buf, rewrite); }
static void softbreak(struct Ipcom_cmd_ttcp_data *context, char *expr, unsigned int line) { char buf[256]; context->err_no = ipcom_errno; ipcom_sprintf(buf, "TERROR: %s [line %d] [errno %d]", expr, line, context->err_no); ipcom_perror(buf); }
IP_PUBLIC char * ipcom_strerror(int errnum) { static char buf[128]; char *name; #if defined(IP_PORT_VXWORKS) && IP_PORT_VXWORKS >= 60 name = ipcom_strerror_int_vxworks(errnum); #else name = ipcom_strerror_int(errnum); #endif if (name != IP_NULL) return name; #ifdef IP_PORT_VXWORKS ipcom_sprintf(buf, "errno = %#x", errnum); #else ipcom_sprintf(buf, "Unknown error: %d", 0xffff & errnum); #endif return buf; }
/* *=========================================================================== * ipnet_nat_proxy_sip_payload_parse *=========================================================================== * Description: Parse SIP payload. * Parameters: appdata - pointer to application data. * applen - pointer to length of application data. * growspace - space available to extend application data. * param - pointer to proxy parameters. * newdata - pointer to pointer to new application data. * Returns: IP_TRUE = Packet modified. * IP_FALSE = Packet untouched. */ IP_STATIC Ip_bool ipnet_nat_proxy_sip_payload_parse(Ip_u8 *appdata, int *applen, int growspace, Ipnet_nat_proxy_param *param, Ip_u8 **newdata) { char *psipmsg = (char *)appdata; char *pcallid = IP_NULL; char *pendstr, *pstartstr, *psearch; Ip_bool retcode = IP_FALSE; int pos, sdpdatalen, searchlen, msgtype = 0; char tmpholder[50]; char laddrstr[20]; char gaddrstr[20]; char *pend = (char *)sipbuf + *applen - 1; char *sdplen_start, *sdplen_end, *sdp_end; int newlen, diff; if (param->incoming == IP_TRUE) { /* Incoming message*/ goto parseFalseExit; } if (param->inbound == IP_FALSE) { /* Outbound session */ if ((psipmsg = ipnet_nat_proxy_sip_outboundmsgtypecheck(psipmsg, &msgtype, *applen)) == IP_NULL) return IP_FALSE; /* not the message we're looking for */ } else { /* Inbound session */ if ((psipmsg = ipnet_nat_proxy_sip_inboundmsgtypecheck(psipmsg, &msgtype, *applen)) == IP_NULL) return IP_FALSE; /* not the message we're looking for */ } /* find the call-id field */ if (ipnet_nat_proxy_sip_keyfind(psipmsg, SIP_CALLID_STR, &pos, *applen - (psipmsg - (char *)appdata)) == IP_FALSE) { IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: no callid field"); return IP_FALSE; } /* get callid string */ pcallid = ipnet_nat_proxy_sip_callidstr(psipmsg + pos + SIP_TAG_TO_DATAPOS(SIP_CALLID_STR)); if (pcallid == IP_NULL) { IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: failed to parse callid string"); return IP_FALSE; } if (msgtype == SIP_MSG_TYPE_INVITE) { if (param->inbound == IP_FALSE) { /* Update the mapping timeout */ IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds", IPNET_NAT_SIP_ENTRY_INVITE_TIMEOUT); ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_INVITE_TIMEOUT, param->mapping); } else { /* ALG will not detect the ACK for inbound calls so use the INVITE response to set established timeout */ IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds", IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT); ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT, param->mapping); } } else if (msgtype == SIP_MSG_TYPE_ACK) { /* Update the mapping timeout */ IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds", IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT); ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT, param->mapping); } /* Copy the message to scratch buffer and set pointer */ if (*applen > (int)sizeof(sipbuf)) { IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: message to long"); goto parseFalseExit; } ipcom_memcpy(sipbuf, appdata, *applen); psipmsg = (char *)sipbuf + (psipmsg - (char *)appdata); /* first the via field * For response message, the Via field will not contain the private address. * The localAddrProcess() will check if the address is private. */ laddrstr[0] = gaddrstr[0] = 0; if (ipnet_nat_proxy_sip_keyfind(psipmsg, SIP_VIA_STR, &pos, (pend - psipmsg) + 1) == IP_TRUE) { /* advance to IP/Port string */ psipmsg += (pos + ipcom_strlen(SIP_VIA_STR) + SIP_VIA_FIELD_IPADDR_DIS); IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse via field"); psipmsg = ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_ADDRESS_PORT_STRING, param, &pend); if (psipmsg == IP_NULL) goto parseFalseExit; } /* find the contact field */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTACT_STR, &pos, (pend - psipmsg) + 1) == IP_TRUE) { /* advance to IP/Port string */ psipmsg += (pos + ipcom_strlen(SIP_CONTACT_STR) + SIP_CTAC_FIELD_IPADDR_DIS); IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse contact field"); psipmsg = ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_ADDRESS_PORT_STRING, param, &pend); if (psipmsg == IP_NULL) goto parseFalseExit; } /* exit if there isn't any private info in SIP message header */ if (laddrstr[0] == 0 || gaddrstr[0] == 0) goto parseFalseExit; /* When program reaches here, it indicates at least one place in the * packet should be modified. Use parseFalseExit only if it is an error */ /* find the Content-Type field */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTYPE_STR, &pos, (pend - psipmsg) + 1) == IP_FALSE) goto parseTrueExit; /* advance to start of data field */ psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_CONTYPE_STR)); SIP_SKIP_SPACES(psipmsg); /*check the application/sdp type, if not, exit */ if (!SIP_IS_STRING_SAME(psipmsg, SIP_APPSDP_STR)) goto parseTrueExit; /* find the content length field */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTLEN_STR, &pos, (pend - psipmsg) + 1) == IP_FALSE) goto parseTrueExit; IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse Content-Length field"); /* reach to the content length field, advance to length data */ psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_CONTLEN_STR)); SIP_SKIP_SPACES(psipmsg); sdpdatalen = ipcom_strtol(psipmsg, &pendstr, 10); IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: data length = %d", sdpdatalen); if (sdpdatalen == 0) goto parseTrueExit; /* store start and end of sdp datalength string as well as end of message */ sdplen_start = psipmsg; sdplen_end = pendstr; sdp_end = pend; /* advance to the start of SDP data */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, IP_NULL, &pos, (pend - psipmsg) + 1) == IP_FALSE) { IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: Can't find header end mark"); goto parseTrueExit; } /* start of the SIP data field */ psipmsg += pos; searchlen = sdpdatalen; /* search the local IP address, and replace it with global address */ pstartstr = psipmsg; while (IP_TRUE) { psearch = ipnet_nat_proxy_sip_faststrsearch(laddrstr, ipcom_strlen(laddrstr), pstartstr, searchlen, IP_FALSE); if (psearch != IP_NULL) { IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: Local IP address in SDP: %s", laddrstr); if (ipnet_nat_proxy_sip_modmsg(gaddrstr, ipcom_strlen(gaddrstr), psearch, ipcom_strlen(laddrstr), &pend) < 0) { goto parseFalseExit; } searchlen = searchlen - (psearch + ipcom_strlen(gaddrstr) - pstartstr); pstartstr = psearch + ipcom_strlen(gaddrstr); } else break; } IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: the last search length %d", searchlen); /* search for the audio port */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_AUDIO_STR, &pos, sdpdatalen) == IP_TRUE) { /* advance to the port field */ psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_AUDIO_STR)); SIP_SKIP_SPACES(psipmsg); ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_PORT_STRING, param, &pend); } /* search for the audio control port */ if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_RTCP_STR, &pos, sdpdatalen) == IP_TRUE) { /* advance to the port field */ psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_RTCP_STR)); SIP_SKIP_SPACES(psipmsg); ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_PORT_STRING, param, &pend); } /* adjust the length node */ sdpdatalen += pend - sdp_end; ipcom_sprintf(tmpholder, "%d", sdpdatalen); if (ipnet_nat_proxy_sip_modmsg(tmpholder, ipcom_strlen(tmpholder), sdplen_start, sdplen_end - sdplen_start, &pend) < 0) { goto parseFalseExit; } parseTrueExit: /* Update application data with the modified buffer */ newlen = pend - (char *)sipbuf + 1; diff = newlen - *applen; if (diff > growspace) { /* Must allocate a new buffer */ *newdata = ipcom_malloc(*applen + diff); if (*newdata == IP_NULL) { IPCOM_LOG1(ERR, "ipnet_nat_proxy_sip_payload_parse() :: ipcom_malloc(%d) failed", *applen + diff); goto parseFalseExit; } ipcom_memcpy(*newdata, sipbuf, newlen); } else { /* Let the current buffer grow */ ipcom_memcpy(appdata, sipbuf, newlen); } *applen = newlen; IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_msg() :: the delta length = %d ", diff); retcode = IP_TRUE; parseFalseExit: if (msgtype == SIP_MSG_TYPE_BYE) ipnet_nat_proxy_sip_endmsgprocess(pcallid, param); if (pcallid) ipcom_free(pcallid); return retcode; }
/* *=========================================================================== * 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; }
/* *=========================================================================== * 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; } }
/* *=========================================================================== * 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); }
/* *=========================================================================== * ipcom_err_string *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC char * ipcom_err_string(Ip_err err) { static char errname[20]; /* IPCOM errors */ switch(err) { /* success/failure */ case IPCOM_SUCCESS: return "success"; #ifndef IP_SIZE case IPCOM_ERR_FAILED: return "failed"; /* general failures */ case IPCOM_ERR_NO_MEMORY: return "no memory"; case IPCOM_ERR_NOT_FOUND: return "not found"; case IPCOM_ERR_NOT_SUPPORTED: return "not supported"; case IPCOM_ERR_PERMISSION_DENIED: return "permission denied"; /* 'already' failures */ case IPCOM_ERR_ALREADY_OPEN: return "already open"; case IPCOM_ERR_ALREADY_CLOSED: return "already closed"; case IPCOM_ERR_ALREADY_INSTALLED: return "already installed"; case IPCOM_ERR_ALREADY_STARTED: return "already started"; /* 'not' failures */ case IPCOM_ERR_NOT_OPENED: return "not opened"; case IPCOM_ERR_NOT_CLOSED: return "not closed"; case IPCOM_ERR_NOT_INSTALLED: return "not installed"; case IPCOM_ERR_NOT_STARTED: return "not started"; /* 'invalid' failures */ case IPCOM_ERR_INVALID_ARG: return "invalid argument"; case IPCOM_ERR_INVALID_CONFIG: return "invalid configuration"; case IPCOM_ERR_INVALID_VERSION: return "invalid version"; case IPCOM_ERR_INVALID_ALIGNMENT: return "invalid alignment"; case IPCOM_ERR_INVALID_INTERFACE: return "invalid interface"; /* route failures */ case IPCOM_ERR_NO_ROUTE: return "no route"; case IPCOM_ERR_DEAD_ROUTE: return "dead route"; case IPCOM_ERR_INVALID_ROUTE: return "invalid route"; case IPCOM_ERR_INVALID_MASK: return "invalid mask"; case IPCOM_ERR_INVALID_RTCLIENT: return "invalid rtclient"; /* entries failures */ case IPCOM_ERR_DUPLICATE: return "duplicate entry"; case IPCOM_ERR_LOCKED: return "locked"; case IPCOM_ERR_END: return "end of operation"; case IPCOM_ERR_READONLY: return "readonly entry"; /* tag failures */ case IPCOM_ERR_INVALID_TAG_VALUE: return "invalid tag value"; case IPCOM_ERR_UNSUPPORTED_TAG: return "unsupported tag"; /* packet failures */ case IPCOM_ERR_INVALID_PACKET: return "invalid packet"; case IPCOM_ERR_BAD_PACKET: return "bad packet"; case IPCOM_ERR_IGNORED_PACKET: return "ignored packet"; /* BSD failures */ case IPCOM_ERR_SOCKCALLFAILED: return "socket call failed"; /* 'min/max' failures */ case IPCOM_ERR_REACHED_MIN: return "reached minimum"; case IPCOM_ERR_REACHED_MAX: return "reached maximum"; /* system call failures */ case IPCOM_ERR_TIMEOUT: return "timeout"; case IPCOM_ERR_WOULDBLOCK: return "would block"; case IPCOM_ERR_INTERRUPT: return "operation interrupted"; case IPCOM_ERR_PENDING: return "pending"; /* authentication failures */ case IPCOM_ERR_AUTH_FAILED: return "auth failed"; case IPCOM_ERR_AUTH_UNKNOWN: return "unknown auth user"; #endif /* ifndef IP_SIZE */ default: ipcom_sprintf(errname, "error %d", (int)err); return (char *)errname; } }
/* *=========================================================================== * 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; }
static void ipsecctrl_saTables_print(Argvars *vars, Ip_u8 direction, Ip_u8 protocol, int domain) { Ipipsec_ioctl_sactrl sa_next; Ipipsec_ioctl_sactrl sa_u64; Ip_err retval; int i, num; Ip_tag tags[41]; char table[32]; #ifdef IPCOM_USE_INET6 char str[IP_INET6_ADDRSTRLEN]; #else char str[16]; #endif /* pre-init print stuff. */ ipcom_sprintf(table, "ipsecSa%s%s", protocol == IP_IPPROTO_AH ? "Ah" : "Esp", direction == IPIPSEC_SADIR_INPUT ? "In" : direction == IPIPSEC_SADIR_OUTPUT ? "Out" : "Any"); /* Fill in the info tags. */ tags[0] = IPIPSEC_SACTRLT_GET_SaSelector; tags[2] = IPIPSEC_SACTRLT_GET_SaCreator; tags[4] = IPIPSEC_SACTRLT_GET_Encapsulation; tags[6] = IPIPSEC_SACTRLT_GET_EncAlg; tags[8] = IPIPSEC_SACTRLT_GET_EncKeyLength; tags[10] = IPIPSEC_SACTRLT_GET_AuthAlg; tags[12] = IPIPSEC_SACTRLT_GET_AuthKeyLength; tags[14] = IPIPSEC_SACTRLT_GET_RepWinSize; tags[16] = IPIPSEC_SACTRLT_GET_LimitSeconds; tags[18] = IPIPSEC_SACTRLT_GET_LimitKbytes; tags[20] = IPIPSEC_SACTRLT_GET_AccSeconds; tags[22] = IPIPSEC_SACTRLT_GET_InAccKbytes; tags[24] = IPIPSEC_SACTRLT_GET_DecryptErrors; tags[26] = IPIPSEC_SACTRLT_GET_AuthErrors; tags[28] = IPIPSEC_SACTRLT_GET_ReplayErrors; tags[30] = IPIPSEC_SACTRLT_GET_PolicyErrors; tags[32] = IPIPSEC_SACTRLT_GET_PadErrors; tags[34] = IPIPSEC_SACTRLT_GET_OtherReceiveErrors; tags[36] = IPIPSEC_SACTRLT_GET_OutAccKbytes; tags[38] = IPIPSEC_SACTRLT_GET_OutSendErrors; tags[40] = IP_TAG_END; ipcom_printf(IP_LF"***** %stable ::"IP_LF, table); /* Get and print the SAs in MIB format. */ sa_next.arg.next.spi_n = 0; for (num = 0;;) { ipcom_memcpy(&sa_next.sa, &sa_next.arg.next, sizeof(Ipipsec_sa_handle)); sa_next.arg.next.direction = direction; sa_next.arg.next.protocol = protocol; sa_next.arg.next.domain = (Ip_u8)domain; if (ipcom_socketioctl(vars->fd, IP_SIOCXIPSEC_NEXT_SA, &sa_next) < 0) { ipcom_printf("ipsecctrl: ipcom_socketioctl(NEXT_SA) failed (%s)"IP_LF, ipcom_strerror(ipcom_errno)); return; } if (sa_next.arg.next.spi_n == 0) break; retval = ipipsec_sactrl(&sa_next.arg.next, tags); if (retval != IPCOM_SUCCESS) { ipcom_printf("ipsecctrl: ipipsec_sactrl(info) failed, error = %d"IP_LF, retval); return; } /* SA id */ ipcom_printf(IP_LF"%sEntry #%d:"IP_LF "%sAddresstype = %d"IP_LF "%sAddress = %s"IP_LF "%sSpi = 0x%lx"IP_LF , table, num , table, domain == IP_AF_INET ? 1 : domain == IP_AF_INET6 ? 2 : 3 , table, ipcom_inet_ntop(sa_next.arg.next.domain, &sa_next.arg.next.dst, str, sizeof(str)) , table, ip_ntohl(sa_next.arg.next.spi_n)); /* SA MIB entries */ for (i = 0; tags[i] != IP_TAG_END; i += 2) { switch(tags[i]) { case IPIPSEC_SACTRLT_GET_SaSelector : ipcom_printf("%sSelector = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_SaCreator : ipcom_printf("%sCreator = %s"IP_LF, table, mib_Creator[tags[i+1]]); break; case IPIPSEC_SACTRLT_GET_Encapsulation : ipcom_printf("%sEncapsulation = %s"IP_LF, table, mib_Encapsulation[tags[i+1]]); break; case IPIPSEC_SACTRLT_GET_EncAlg : ipcom_printf("%sEncAlg = %s"IP_LF, table, mib_EncAlg[tags[i+1]]); break; case IPIPSEC_SACTRLT_GET_EncKeyLength : ipcom_printf("%sEncKeyLength = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_AuthAlg : ipcom_printf("%sAuthAlg = %s"IP_LF, table, mib_AuthAlg[tags[i+1]]); break; case IPIPSEC_SACTRLT_GET_AuthKeyLength : ipcom_printf("%sAuthKeyLength = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_RepWinSize : ipcom_printf("%sRepWinSize = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_LimitSeconds : ipcom_printf("%sLimitSeconds = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_LimitKbytes : ipcom_printf("%sLimitKbytes = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_AccSeconds : ipcom_printf("%sAccSeconds = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_InAccKbytes : ipcom_printf("%sInAccKbytes = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_OutAccKbytes : ipcom_printf("%sOutAccKbytes = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_DecryptErrors : ipcom_printf("%sDecryptErrors = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_AuthErrors : ipcom_printf("%sAuthErrors = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_ReplayErrors : ipcom_printf("%sReplayErrors = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_PolicyErrors : ipcom_printf("%sPolicyErrors = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_PadErrors : ipcom_printf("%sPadErrors = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_OtherReceiveErrors : ipcom_printf("%sOtherReceiveErrors = %ld"IP_LF, table, tags[i+1]); break; case IPIPSEC_SACTRLT_GET_OutSendErrors : ipcom_printf("%sOutSendErrors = %ld"IP_LF, table, tags[i+1]); break; default: ipcom_printf("error: unknown tag type '%ld'"IP_LF, tags[i]); break; } } /* for */ ipcom_memcpy(&sa_u64.sa, &sa_next.arg.next, sizeof(Ipipsec_sa_handle)); if (ipcom_socketioctl(vars->fd, IP_SIOCXIPSEC_InUserOctets, &sa_u64) == 0) ipcom_printf("%sInUserOctets = %ld"IP_LF, table, IP_U64_GETLO(sa_u64.arg.u64)); /*lint !e530 */ if (ipcom_socketioctl(vars->fd, IP_SIOCXIPSEC_InUserPackets, &sa_u64) == 0) ipcom_printf("%sInUserPackets = %ld"IP_LF, table, IP_U64_GETLO(sa_u64.arg.u64)); /*lint !e530 */ if (ipcom_socketioctl(vars->fd, IP_SIOCXIPSEC_OutUserOctets, &sa_u64) == 0) ipcom_printf("%sOutUserOctets = %ld"IP_LF, table, IP_U64_GETLO(sa_u64.arg.u64)); /*lint !e530 */ if (ipcom_socketioctl(vars->fd, IP_SIOCXIPSEC_OutUserPackets, &sa_u64) == 0) ipcom_printf("%sOutUserPackets = %ld"IP_LF, table, IP_U64_GETLO(sa_u64.arg.u64)); /*lint !e530 */ } }
/* *=========================================================================== * 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; }
/* *=========================================================================== * 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; }
/* *=========================================================================== * ipcom_cmd_ttcp *=========================================================================== */ int ipcom_cmd_ttcp(int argc, char **argv) { /* Uninitialized variables. */ union Ip_sockaddr_union addrme; char *host = IP_NULL; /* ptr to name of host */ int c; Ip_u32 msec0, msec1, msecd, bpermsec, kbpersec; Ip_fd sockfd = -1; char *buf; /* ptr to dynamic buffer */ char *orgbuf = 0; /* the buffer to free. */ struct Ipcom_cmd_ttcp_data context; /* misc initialized variables. */ #ifdef IPCOM_USE_TCP union Ip_sockaddr_union frominet; Ip_socklen_t fromlen; int one = 1; /* for 4.3 BSD style setsockopt() */ Ip_fd oldfd; /* fd of network socket */ #endif Ip_u32 nbytes = 0; /* bytes on net */ int trans = 1; /* 0=receive, !0=transmit mode. Default transmit! */ /* Configuration variables. */ #if defined(IP_SO_X_VR) int vr = 0; #endif int buflen = 8 * 1024; /* length of buffer */ int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ int bufoffset = 0; /* align buffer to this */ int bufalign = 16; /* modulo this */ int options = 0; /* socket options */ unsigned short port = DEFAULT_PORT; /* TCP port number */ unsigned short meport = 0; /* local port, default 0. */ int sinkmode = 1; /* 0=normal I/O, !0=sink/source mode */ int verbose = 0; /* 0=print basic info, 1=print cpu rate, proc resource usage. */ int sockbufsize = -1; /* Default socket buffer size to use. */ #ifdef IP_TCP_NODELAY int nodelay = 0; /* set TCP_NODELAY socket option. */ #endif int enable = 1; #ifdef TCP_OSERFC2385 char *md5opt = IP_NULL; #endif #ifdef IP_SO_REUSEPORT int reuse_port = 0; #endif #ifdef IPCOM_TTCP_REENTRANT union Ip_sockaddr_union addrhim; #endif int sock_error; int mev = 0; /* Use event logging */ int nend = 5; /* Number of UDP end packets */ #ifdef IPCOM_CMD_TTCP_USE_ZEROCOPY_API int zerocopy = 0; #endif int cpu = -1; #ifdef IPSCTP Ip_bool sctp_type_conflict = IP_FALSE; #endif /* Initialize some static data, default configuration. */ #ifdef IPCOM_USE_TCP int proto = IP_IPPROTO_TCP; int sock_type = IP_SOCK_STREAM; const char *proto_as_str = "TCP"; context.udp = 0; /* Default is TCP. */ #else int proto = IP_IPPROTO_UDP; int sock_type = IP_SOCK_DGRAM; const char *proto_as_str = "UDP"; context.udp = 1; /* Only UDP. */ #endif context.b_flag = 0; context.touchdata = 0; context.numCalls = 0; context.err_no = 0; #ifdef IPCOM_USE_INET context.family = IP_AF_INET; /* default IPv4 */ #else context.family = IP_AF_INET6; /* default IPv6 */ #endif context.addrsize = sizeof(struct Ip_sockaddr_in); (void)ipcom_proc_self(); /* when called from vxworks shell, this prevents a crash */ (void)options; /* Init some more. */ ipcom_memset(&addrhim, 0, sizeof (addrhim)); IPCOM_SA_LEN_SET(&addrhim.sin, sizeof(struct Ip_sockaddr_in)); addrhim.sin.sin_family = IP_AF_INET; ipcom_memset(&addrme, 0, sizeof(addrme)); IPCOM_SA_LEN_SET(&addrme.sin, sizeof(struct Ip_sockaddr_in)); addrme.sin.sin_family = IP_AF_INET; #ifdef IP_PORT_INTEGRITY ipcom_init_libsocket(); #endif if (argc < 2) goto usage; ipcom_getopt_clear(); while ((c = ipcom_getopt(argc, argv, "M:xdrstUuvBDTb:f:l:n:p:A:O:V:RP:me:a:cS")) != -1) { switch (c) { #ifdef TCP_OSERFC2385 case 'M': /* MD5 signature option */ md5opt = ip_optarg; break; #endif #ifdef IPCOM_USE_INET6 case 'x': context.family = IP_AF_INET6; break; #endif case 'm': mev = 1; break; case 'e': nend = ipcom_atoi(ip_optarg); break; case 'B': context.b_flag = 1; break; case 't': trans = 1; break; case 'r': trans = 0; break; #ifdef IP_SO_DEBUG case 'd': options |= IP_SO_DEBUG; break; #endif case 'D': #ifdef IP_TCP_NODELAY nodelay = 1; #else ipcom_fprintf(ip_stderr, "ttcp: -D option ignored: IP_TCP_NODELAY socket option not supported"IP_LF); #endif break; case 'n': nbuf = ipcom_atoi(ip_optarg); break; case 'l': buflen = ipcom_atoi(ip_optarg); break; case 's': #ifdef IPCOM_TTCP_USE_STDIOMODE sinkmode = !sinkmode; #endif break; case 'p': port = (unsigned short)ipcom_atoi(ip_optarg); break; case 'P': meport = (unsigned short)ipcom_atoi(ip_optarg); break; #ifdef IPCOM_CMD_TTCP_USE_ZEROCOPY_API case 'U': zerocopy = 1; /* fall through */ #endif case 'u': proto = IP_IPPROTO_UDP; sock_type = IP_SOCK_DGRAM; proto_as_str = "UDP"; context.udp = 1; break; case 'v': verbose = 1; break; case 'A': bufalign = ipcom_atoi(ip_optarg); break; case 'O': bufoffset = ipcom_atoi(ip_optarg); break; case 'b': #if defined(IP_SO_SNDBUF) || defined(IP_SO_RCVBUF) sockbufsize = ipcom_atoi(ip_optarg); #else ipcom_fprintf(ip_stderr, "ttcp: -b option ignored: IP_SO_SNDBUF/IP_SO_RCVBUF socket options not supported"IP_LF); #endif break; #ifdef IP_SO_REUSEPORT case 'R': reuse_port = 1; break; #endif case 'T': context.touchdata = 1; break; #if defined(IP_SO_X_VR) case 'V': vr = ipcom_atoi(ip_optarg); break; #endif case 'a': cpu = ipcom_atoi(ip_optarg); break; #ifdef IPSCTP case 'c': proto = IP_IPPROTO_SCTP; sock_type = IP_SOCK_STREAM; proto_as_str = "SCTP"; if (IP_TRUE == sctp_type_conflict) { ipcom_fprintf(ip_stderr, "ttcp: c/S conflict in command."IP_LF); goto errorout; } sctp_type_conflict = IP_TRUE; break; case 'S': proto = IP_IPPROTO_SCTP; sock_type = IP_SOCK_SEQPACKET; proto_as_str = "SCTP"; if (IP_TRUE == sctp_type_conflict) { ipcom_fprintf(ip_stderr, "ttcp: c/S conflict in command."IP_LF); goto errorout; } sctp_type_conflict = IP_TRUE; break; #endif default: goto usage; } } #ifndef IP_PORT_LAS if (cpu >= 0) { Ip_cpu_set_t cpuset; if (cpu < 0 || cpu >= IP_CPU_SETSIZE) { ipcom_fprintf(ip_stderr, "ttcp: CPU must be between #0 and #%d"IP_LF, IP_CPU_SETSIZE-1); return -1; } IP_CPU_ZERO(&cpuset); IP_CPU_SET(cpu, &cpuset); if (ipcom_proc_cpu_affinity_set(0, &cpuset) != IPCOM_SUCCESS) { ipcom_fprintf(ip_stderr, "ttcp: Failed to set affinity to CPU #%d"IP_LF, cpu); return -1; } } #endif /* IP_PORT_LAS */ if(trans) { host = argv[ip_optind]; if (host == 0) goto usage; sock_error = ipcom_getsockaddrbyaddrname(context.family, IP_FALSE, host, (struct Ip_sockaddr *)&addrhim); if(sock_error != 0) { ipcom_fprintf(ip_stderr, "ttcp error: ipcom_getsockaddrbyaddrname failed, errno = %d."IP_LF, sock_error); ttcperror(&context, "unknown host"); } addrme.sin.sin_port = ip_htons(meport); addrhim.sin.sin_port = ip_htons(port); /* same port offset for IPv4 and IPv6 */ } else { /* rcvr */ addrme.sin.sin_port = ip_htons(port); } #ifdef IPCOM_USE_INET6 if(context.family == IP_AF_INET6) { context.addrsize = sizeof(struct Ip_sockaddr_in6); IPCOM_SA_LEN_SET(&addrme.sin6, sizeof(struct Ip_sockaddr_in6)); addrme.sin6.sin6_family = IP_AF_INET6; IPCOM_SA_LEN_SET(&addrhim.sin6, sizeof(struct Ip_sockaddr_in6)); addrhim.sin6.sin6_family = IP_AF_INET6; } #endif /* Send more than the sentinel size - UDPMINLEN. */ if(context.udp && buflen <= UDPMINLEN) buflen = UDPMINLEN + 1; /* Align buffer. */ if ((buf = (char *) ipcom_malloc(buflen + bufalign)) == (char *) IP_NULL) ttcperror(&context, "malloc"); else orgbuf = buf; if (bufalign != 0) buf += (bufalign - ((Ip_ptrdiff_t) buf % bufalign) + bufoffset) % bufalign; /* Get a socket. */ if ((sockfd = ipcom_socket(context.family, sock_type, proto)) == ERR) ttcperror(&context,"socket"); if (trans) { if(sockbufsize < 0) { if(context.udp) sockbufsize = DEFAULT_UDP_SNDBUF; else sockbufsize = DEFAULT_TCP_SNDBUF; } ipcom_fprintf(ip_stdout, "ttcp-t: fd=%d, buflen=%d, nbuf=%d, align=%d/%d, port=%d", sockfd, buflen, nbuf, bufalign, bufoffset, (int)port); if (sockbufsize) ipcom_fprintf(ip_stdout, ", sockbufsize=%d", sockbufsize); ipcom_fprintf(ip_stdout, " %s -> %s"IP_LF, proto_as_str, host); } else { if(sockbufsize < 0) { if(context.udp) sockbufsize = DEFAULT_UDP_RCVBUF; else sockbufsize = DEFAULT_TCP_RCVBUF; } ipcom_fprintf(ip_stdout, "ttcp-r: fd=%d, buflen=%d, nbuf=%d, align=%d/%d, port=%d", sockfd, buflen, nbuf, bufalign, bufoffset, (int)port); if (sockbufsize) ipcom_fprintf(ip_stdout, ", sockbufsize=%d", sockbufsize); ipcom_fprintf(ip_stdout, " %s"IP_LF, proto_as_str); } /* Code to open socket is moved to before the printf to get 'sockfd' right. */ mes(trans, "socket"); /* Set REUSE addr */ if(ipcom_setsockopt(sockfd, IP_SOL_SOCKET, IP_SO_REUSEADDR, (char *)&enable, sizeof (int)) == ERR) ttcperror(&context, "setsockopt(IP_SO_REUSEADDR)"); else mes(trans, "setsockopt(IP_SO_REUSEADDR)"); #ifdef IP_SO_REUSEPORT /* Set REUSE port */ if(reuse_port) { if(ipcom_setsockopt(sockfd, IP_SOL_SOCKET, IP_SO_REUSEPORT, (char *)&reuse_port, sizeof (int)) == ERR) ttcperror(&context, "setsockopt(IP_SO_REUSEPORT)"); else mes(trans, "setsockopt(IP_SO_REUSEPORT)"); } #endif #ifdef IPCOM_USE_TCP #ifdef TCP_OSERFC2385 if (!udp && md5opt) { if (ipcom_setsockopt(sockfd, IPPROTO_TCP, TCP_OSERFC2385, md5opt, strlen(md5opt)) == ERR) { ttcperror(&context, "setsockopt(IP_SO_REUSEADDR)"); } else { mes(trans, "setsockopt(IP_SO_REUSEADDR)"); } } #endif #endif /* Set routing table index in socket. */ #if defined(IP_SO_X_VR) if(vr != 0) { if (ipcom_setsockopt(sockfd, IP_SOL_SOCKET, IP_SO_X_VR, (char *)&vr, 4) == ERR) ttcperror(&context, "setsockopt: vr"); else mes(trans, "setsockopt(vr)"); } #endif /* Bind the socket. */ if(ipcom_bind(sockfd, (struct Ip_sockaddr *)&addrme, context.addrsize) == ERR) ttcperror(&context, "bind"); else #ifdef IPCOM_USE_INET6 ipcom_fprintf(ip_stderr, "ttcp%s: bind %s %d"IP_LF, trans ? "-t" : "-r", context.family == IP_AF_INET ? "IPv4" : "IPv6", (int)ip_ntohs(addrme.sin.sin_port)); #else { char tmpbuf[32]; ipcom_sprintf(tmpbuf, "bind %d", ip_ntohs(addrme.sin.sin_port)); mes(trans, tmpbuf); } #endif /* Adjust socker buffer size. */ #if defined(IP_SO_SNDBUF) || defined(IP_SO_RCVBUF) if(sockbufsize) { if (trans) { if (ipcom_setsockopt(sockfd, IP_SOL_SOCKET, IP_SO_SNDBUF, (char *)&sockbufsize, sizeof sockbufsize) == ERR) ttcperror(&context,"setsockopt: sndbuf"); else mes(trans, "setsockopt(sndbuf)"); } else { if (ipcom_setsockopt(sockfd, IP_SOL_SOCKET, IP_SO_RCVBUF, (char *)&sockbufsize, sizeof sockbufsize) == ERR) ttcperror(&context,"setsockopt: rcvbuf"); else mes(trans, "setsockopt(rcvbuf)"); } } #endif /* If TCP we need to connect else accept to remote side. */ #ifdef IPCOM_USE_TCP if (context.udp) { mes(trans, "opened"); } else { /* We are the client if transmitting */ if(trans) { if(options) { if(ipcom_setsockopt(sockfd, IP_SOL_SOCKET, options, (char *)&one, sizeof (one)) == ERR) ttcperror(&context,"setsockopt"); } #ifdef IP_TCP_NODELAY if(nodelay) { if(ipcom_setsockopt(sockfd, IP_IPPROTO_TCP, IP_TCP_NODELAY, (char *)&one, sizeof (one)) == ERR) ttcperror(&context,"setsockopt: nodelay"); mes(trans, "nodelay"); } #endif if(ipcom_connect(sockfd, (struct Ip_sockaddr *)&addrhim, context.addrsize) == ERR) ttcperror(&context,"connect"); else mes(trans, "connect"); } /* Otherwise, we are the TCP server and should listen for the connections. */ else { if(ipcom_listen(sockfd, 0) == ERR) ttcperror(&context,"listen"); else mes(trans, "listen"); if(options) { if(ipcom_setsockopt(sockfd, IP_SOL_SOCKET, options, (char *)&one, sizeof (one)) == ERR) ttcperror(&context,"setsockopt"); } fromlen = context.addrsize; oldfd = sockfd; #ifdef IPSCTP if ((IP_SOCK_SEQPACKET == sock_type) && (IP_IPPROTO_SCTP == proto)) { #define TTCP_SCTP_RCV_BUF_LEN 128 struct Ipsctp_event_subscribe events; union Ip_sockaddr_union local_addr; struct Ipsctp_sndrcvinfo sinfo; Ip_u32 len = 0; char pbuf[TTCP_SCTP_RCV_BUF_LEN]; int flags = 0; int ret = 0; /* set data I/O event flag */ ipcom_memset(&events, 0, sizeof(events)); events.Ipsctp_data_io_event = 1; ret = ipcom_setsockopt(sockfd, IP_IPPROTO_SCTP, IPSCTP_EVENTS, (void *)&events, sizeof(events)); if (ERR == ret) ttcperror(&context, "setsockopt events"); /* get the association identifier */ ipcom_memset(pbuf, 0, TTCP_SCTP_RCV_BUF_LEN); len = sizeof(local_addr); /* Wait for connections */ ret = ipsctp_recvmsg(sockfd, pbuf, TTCP_SCTP_RCV_BUF_LEN, &local_addr.sa, &len, &sinfo, &flags); sockfd = ipsctp_peeloff(sockfd, sinfo.sinfo_assoc_id); if (IP_SOCKERR == sockfd) ttcperror(&context,"peeloff"); } else #endif { if((sockfd = ipcom_accept(sockfd, (struct Ip_sockaddr *)&frominet, &fromlen)) == ERR) ttcperror(&context,"accept"); } { union Ip_sockaddr_union peer; Ip_socklen_t peerlen = context.addrsize; /* Close the mother socket. */ if(ipcom_socketclose(oldfd) == ERR) ttcperror(&context,"close of oldfd."); #if defined(IP_SO_RCVBUF) /* Had to add this code in addition to the above because some stacks don't inherit * the receive buffer size from the server socket. /Lennart Bang Enea Ose Systems 980116. */ if(sockbufsize) { if(ipcom_setsockopt(sockfd, IP_SOL_SOCKET, IP_SO_RCVBUF, (char *)&sockbufsize, sizeof sockbufsize) == ERR) ttcperror(&context,"setsockopt: rcvbuf"); else mes(trans, "setsockopt(rcvbuf)"); } #endif if(ipcom_getpeername(sockfd, (struct Ip_sockaddr *) &peer, &peerlen) == ERR) ttcperror(&context, "getpeername"); #ifdef IPCOM_USE_INET if(context.family == IP_AF_INET) { char addr[16]; ipcom_fprintf(ip_stderr, "ttcp-r: accept from %s"IP_LF, ipcom_inet_ntop(IP_AF_INET, &peer.sin.sin_addr, addr, sizeof(addr))); } #endif #ifdef IPCOM_USE_INET6 if(context.family == IP_AF_INET6) { char addr[40]; ipcom_fprintf(ip_stderr, "ttcp-r: accept from %s"IP_LF, ipcom_inet_ntop(IP_AF_INET6, &peer.sin6.sin6_addr, addr, sizeof(addr))); } #endif } } } #endif /* Begin the TTCP performance test. */ msec0 = get_millisec(); if (mev) { #if defined (IP_PORT_INTEGRITY) #include "ipcom_integrity.h" extern void EventLogOn(void); #if IP_VER < 500 extern void EventLogMask(unsigned int newmask); EventLogMask(~0); #endif EventLogOn(); #endif } if(sinkmode) { register int cnt; /* Transmit side. */ if(trans) { pattern(buf, buflen); if(context.udp) { (void) NWRITE(sockfd, buf, UDPMINLEN, &context); /* rcvr start */ ipcom_millisleep(500); /* arp time */ /* Renew the start time to not include the 500 msec sleep */ msec0 = get_millisec(); } #ifdef IPCOM_CMD_TTCP_USE_ZEROCOPY_API if (zerocopy) { while (nbuf-- && ZERONWRITE(sockfd, buflen, &context) == buflen) nbytes += buflen; } else #endif { while (nbuf-- && NWRITE(sockfd, buf, buflen, &context) == buflen) nbytes += buflen; } if(context.udp) (void) NWRITE(sockfd, buf, UDPMINLEN, &context); /* rcvr end */ } /* Receive side. */ else { if(context.udp) { int going = 0; #ifdef IPCOM_CMD_TTCP_USE_ZEROCOPY_API if (zerocopy) { while ((cnt = ZeroNread(sockfd, &context)) > 0) { if(cnt <= UDPMINLEN) { if(going) break; /* "EOF" */ going = 1; msec0 = get_millisec(); } else { nbytes += cnt; } } } else #endif { while ((cnt = Nread(sockfd, buf, buflen, &context)) > 0) { if(cnt <= UDPMINLEN) { if(going) break; /* "EOF" */ going = 1; msec0 = get_millisec(); } else { nbytes += cnt; } } } } #ifdef IPCOM_USE_TCP else { while ((cnt = Nread(sockfd, buf, buflen, &context)) > 0) { nbytes += cnt; } } #endif } } #ifdef IPCOM_TTCP_USE_STDIOMODE /* non sinkmode. */ else { register int cnt; if(trans) { /* Read from standard input and send to other side. */ while ((cnt = ipcom_fread(buf, buflen, 1, ip_stdin)) > 0 && NWRITE(sockfd, buf, cnt) == cnt) nbytes += cnt; } else { /* Read from network and print on stdout. */ while ((cnt = Nread(sockfd, buf, buflen, &context)) > 0) { ipcom_fwrite(buf, cnt, 1, ip_stdout); nbytes += cnt; } } } #endif if (mev) { #if defined (IP_PORT_INTEGRITY) extern void EventLogOff(void); EventLogOff(); #elif defined (IP_PORT_RTCORE) extern void ip_trace(char *what, char *file, int line, int id, void *data); extern void ip_tracedump(void); ip_trace("[ASSERT]", __FILE__, __LINE__, ipcom_getpid(), IP_NULL); ip_tracedump(); #endif } /* Read the final time and calculate some statistics. */ msec1 = get_millisec(); msecd = msec1 - msec0; if (msecd == 0) msecd = 1; bpermsec = nbytes / msecd; /* Bytes per millisecond. */ kbpersec = nbytes / 128; kbpersec = kbpersec * 125 / msecd; /* kilobyte per sec. */ /* End of test assemble statistice. */ if(context.err_no) { ipcom_fprintf(ip_stdout, "ttcp%s: socket errno: %d."IP_LF, trans ? "-t" : "-r", context.err_no); } if(context.udp && trans) { int j; for (j = 0; j < nend; j++) { ipcom_millisleep(100); /* Let the reading side catch up. */ (void) NWRITE(sockfd, buf, UDPMINLEN, &context); /* rcvr end */ } } /* Print the statistics. */ ipcom_fprintf(ip_stdout, "ttcp%s: %lu bytes in %lu milliseconds = %lu KB/sec, %lu B/msec +++"IP_LF, trans ? "-t" : "-r", nbytes, msecd, kbpersec, bpermsec); ipcom_fprintf(ip_stdout, "ttcp%s: %lu I/O calls, msec/call = %lu, calls/sec = %lu"IP_LF, trans ? "-t" : "-r", context.numCalls, msecd / context.numCalls, 1000 * context.numCalls / msecd); if (verbose) ipcom_fprintf(ip_stdout, "ttcp%s: buffer address %p"IP_LF, trans ? "-t" : "-r", buf); /* Test succeeded, goto errorout to cleanup. */ goto errorout; /* Usage. */ usage: ipcom_fprintf(ip_stderr, "Usage: ttcp -t [-options] host [ < in ]"IP_LF "ttcp -r [-options > out]"IP_LF "Common options:"IP_LF "-x use IPv6 instead of IPv4"IP_LF "-l ## length of bufs read from or written to network (default 8192)"IP_LF #ifdef IPCOM_CMD_TTCP_USE_ZEROCOPY_API "-U use UDP and interpeak zero copy API instead of TCP"IP_LF #endif "-u use UDP (default is TCP)"IP_LF #ifdef IPSCTP "-c use SCTP STREAM type(default is TCP)"IP_LF "-S use SCTP SEQPACKET type(default is TCP)"IP_LF #endif "-p ## port number to send to or listen at (default DEFAULT_PORT)"IP_LF); ipcom_fprintf(ip_stderr, "-s -t: source a pattern to network"IP_LF "-r sink (discard) all data from network"IP_LF "-e ## number of packets to end UDP transmission"IP_LF "-m use event logging (not supported on all platforms)"IP_LF "-A align the start of buffers to this modulus (default 16384)"IP_LF "-O start buffers at this offset from the modulus (default 0)"IP_LF "-v verbose: print more statistics"IP_LF "-d set SO_DEBUG socket option (if supported)"IP_LF); ipcom_fprintf(ip_stderr, "-b ## set socket buffer size (if supported)"IP_LF "Options specific to -t:"IP_LF "-n## number of source bufs written to network (default 2048)"IP_LF "-D don't buffer TCP writes (sets TCP_NODELAY socket option)"IP_LF "Options specific to -r:"IP_LF "-B for -s, only output full blocks as specified by -l (for TAR)"IP_LF "-T \"touch\": access each byte as it's read"IP_LF #if defined(IP_SO_X_VR) "-V virtual router index (if supported)"IP_LF); #endif /* fall through to cleanup...*/ /* Free buffer and close socket if any error. */ errorout: #ifndef IP_PORT_LAS if (cpu >= 0) ipcom_proc_cpu_affinity_clr(0); #endif /* IP_PORT_LAS */ if(orgbuf) ipcom_free(orgbuf); if(sockfd != -1) { if(ipcom_socketclose(sockfd) == ERR) ipcom_fprintf(ip_stderr, "ttcp error: close of sockfd. (line %d, errno %d)."IP_LF, __LINE__, ipcom_errno); } #ifdef IP_PORT_INTEGRITY ipcom_shutdown_libsocket(); #endif return 0; }
/* *=========================================================================== * ipcom_cmd_sockperf_run *=========================================================================== * Description: Sends/receives data. * Parameters: * Returns: */ IP_STATIC void ipcom_cmd_sockperf_run(Ipcom_cmd_sockperf_t *cmd) { struct Ip_timeval tmo = { 0, 0 }; struct Ip_timeval *ptmo; struct Ip_timeval start; struct Ip_timeval stop; Ip_u32 i; Ip_u32 c; int num_ready; Ip_fd *s = cmd->sock_array; Ip_u32 total_bytes_to_send = cmd->num_buf * cmd->buf_len; Ip_u32 finished_sockets = 0; Ip_u32 total_bytes_read = 0; Ip_ssize_t bytes; Ip_fd_set read_set; int send_flags = (cmd->transmit && cmd->receive) ? IP_MSG_DONTWAIT : 0; if (cmd->transmit) ipcom_printf("sockperf-t: send buffer is %u"IP_LF, cmd->sendbuf_size); if (cmd->receive) ipcom_printf("sockperf-r: receive buffer is %u"IP_LF, cmd->sendbuf_size); for (i = 0; i < cmd->num_sock; i++) { int on = 1; if (ipcom_setsockopt(s[i], IP_SOL_SOCKET, IP_SO_REUSEADDR, &on, sizeof(on)) < 0) { ipcom_printf("sockperf-c: setsockopt IP_SO_REUSEADDR failed : %s"IP_LF, ipcom_strerror(ipcom_errno)); return; } if (ipcom_setsockopt(s[i], IP_SOL_SOCKET, IP_SO_SNDBUF, &cmd->sendbuf_size, sizeof(cmd->sendbuf_size)) < 0) { ipcom_printf("sockperf-c: setsockopt IP_SO_SNDBUF failed : %s"IP_LF, ipcom_strerror(ipcom_errno)); return; } if (ipcom_setsockopt(s[i], IP_SOL_SOCKET, IP_SO_RCVBUF, &cmd->recvbuf_size, sizeof(cmd->recvbuf_size)) < 0) { ipcom_printf("sockperf-c: setsockopt IP_SO_SNDBUF failed : %s"IP_LF, ipcom_strerror(ipcom_errno)); return; } } if (cmd->receive) { IP_FD_ZERO(&cmd->read_set); cmd->width = s[0]; IP_FD_SET(s[0], &cmd->read_set); for (i = 1; i < cmd->num_sock; i++) if (s[i] != IP_INVALID_SOCKET) { cmd->width = IP_MAX(cmd->width, s[i]); IP_FD_SET(s[i], &cmd->read_set); } } ipcom_microtime(&start); while ((cmd->transmit && total_bytes_to_send) || (cmd->receive && finished_sockets < cmd->num_sock)) { if (cmd->transmit && total_bytes_to_send) { for (i = 0; i < cmd->num_sock; i++) { if (cmd->testpattern) { /* Test patter is "[B|E|D]xxxxxx ", B = first 8 byte in buffer, E = last 8 bytes, D = all other */ for (c = 0; c < cmd->buf_len; c += 8) ipcom_sprintf(cmd->buf + c, "%c%06ld ", c == 0 ? '>' : (c >= cmd->buf_len - 8 ? '<' : '#'), cmd->send_pattern[i]++ % 1000000); } bytes = ipcom_send(s[i], cmd->buf, IP_MIN(cmd->buf_len, total_bytes_to_send), send_flags); if (bytes < 0 && ipcom_errno == IP_ERRNO_EWOULDBLOCK) (void)ipcom_sleep(0); else { if (bytes < 0) { ipcom_printf("sockperf-t: send failed : %s"IP_LF, ipcom_strerror(ipcom_errno)); return; } total_bytes_to_send -= bytes; } } if (cmd->receive && total_bytes_to_send == 0) for (i = 0; i < cmd->num_sock; i++) if (ipcom_shutdown(s[i], IP_SHUT_WR) < 0) { ipcom_printf("sockperf-t: shutdown failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return; } } if (cmd->receive) { ptmo = IP_NULL; while (finished_sockets < cmd->num_sock) { read_set = cmd->read_set; num_ready = ipcom_socketselect(cmd->width + 1, &read_set, IP_NULL, IP_NULL, ptmo); if (num_ready == 0) break; if (num_ready < 0) { ipcom_printf("sockperf-r: select failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return; } for (i = 0; i < cmd->num_sock; i++) { if (IP_FD_ISSET(s[i], &read_set)) { bytes = ipcom_recv(s[i], cmd->buf, cmd->buf_len, 0); if (bytes < 0) { ipcom_printf("sockperf-r: recv failed: %s"IP_LF, ipcom_strerror(ipcom_errno)); return; } if (cmd->testpattern) { if (cmd->echo) ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, cmd->recv_pattern[i]); for (c = 0; c < (Ip_u32)bytes; c += 8) { if (cmd->buf[c] != '#' && cmd->buf[c] != '>' && cmd->buf[c] != '<') { ipcom_printf("\nsockperf-r: test pattern error, expected B, D or E found %c(%d) offset %ld"IP_LF, cmd->buf[c], (int)cmd->buf[c], c); ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, 0); return; } if (ipcom_atoi(cmd->buf + c + 1) != (int)(cmd->recv_pattern[i]++ % 1000000)) { ipcom_printf("\nsockperf-r: test pattern error, was %d should be %ld offset %ld"IP_LF, ipcom_atoi(cmd->buf + c + 1), (cmd->recv_pattern[i] - 1) % 1000000, c); ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, 0); return; } } } if (bytes > 0) total_bytes_read += bytes; else { finished_sockets++; IP_FD_CLR(s[i], &cmd->read_set); } } } if (cmd->transmit && total_bytes_to_send) ptmo = &tmo; } } } ipcom_microtime(&stop); if (cmd->transmit) ipcom_printf("sockperf-t: %lu bytes sent in %ld ms (%lu kbyte/s)"IP_LF, cmd->num_buf * cmd->buf_len, ipcom_cmd_sockperf_tv_to_msec(&start, &stop), cmd->num_buf * cmd->buf_len / (Ip_u32)ipcom_cmd_sockperf_tv_to_msec(&start, &stop) * 1000 / 1024); if (cmd->receive) ipcom_printf("sockperf-r: %lu bytes read in %ld ms (%lu kbyte/s)"IP_LF, total_bytes_read, ipcom_cmd_sockperf_tv_to_msec(&start, &stop), total_bytes_read / (Ip_u32)ipcom_cmd_sockperf_tv_to_msec(&start, &stop) * 1000 / 1024); }
/* *=========================================================================== * ipwlan_cmd_wlan_en *=========================================================================== * Description: Parses and executes wlan shell commands. * Parameters: 'en' == 0 => Do not print to console, * Returns: 0 on success */ IP_STATIC int ipwlan_cmd_wlan_en(int en, int argc, char **argv) { int i; int j; int k; Ip_fd fd; char *endp; char ssid[32]; Ipcom_iwreq iwreq; unsigned char oid_data[10]; Ip_err ret = IPCOM_SUCCESS; if (argc < 3) { /* To few arguments */ ipwlan_print_usage(en); return ret; } #ifdef IPCOM_USE_INET fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0); #else fd = ipcom_socket(IP_AF_INET6, IP_SOCK_DGRAM, 0); #endif if (fd == IP_SOCKERR) { ipwlan_printf(en, "Error: unable to create command socket"IP_LF); return IPCOM_ERR_FAILED; } /* Verify interface existance */ ipcom_sprintf(iwreq.if_name, "%.*s", IP_IFNAMSIZ - 1, argv[1]); if(ipcom_if_nametoindex(iwreq.if_name) < 1) { ipwlan_printf(en, "Error: Interface '%s' does not exist"IP_LF, iwreq.if_name); goto error; } /* Reset WLAN device */ if (!ipcom_strcmp(argv[2], "reset")) { ipcom_socketioctl(fd, IP_SIOCSIWRESET, &iwreq); goto done; } /* Set/Get mode */ if (!ipcom_strcmp(argv[2], "mode")) { if(argc < 4) { if(ipcom_socketioctl(fd, IP_SIOCGIWMODE, &iwreq) < 0) { goto error; } if(iwreq.u.mode == IP_IW_MODE_INFRA) { i = wlan_mode_client_infra; } else if(iwreq.u.mode == IP_IW_MODE_AUTO) { i = wlan_mode_client_auto; } else if(iwreq.u.mode == IP_IW_MODE_ADHOC) { i = wlan_mode_client_adhoc; } else if(iwreq.u.mode == IP_IW_MODE_MASTER) { i = wlan_mode_ap; } else { i = wlan_mode_unknown; } ipwlan_printf(en, "Current mode is: %s"IP_LF, wlan_mode_text[i]); } else { /* Set mode */ if (!strcmp(argv[3], "client")) { if(argc < 5 || (strcmp(argv[4], "adhoc") && strcmp(argv[4], "auto") && strcmp(argv[4], "infra"))) { ipwlan_printf(en, "prism <interface> mode client [auto|adhoc|infra]"IP_LF); goto done; } iwreq.u.mode = !strcmp(argv[4], "auto") ? IP_IW_MODE_AUTO : (!strcmp(argv[4], "infra") ? IP_IW_MODE_INFRA : IP_IW_MODE_ADHOC); } else if (!strcmp(argv[3], "ap")) { iwreq.u.mode = IP_IW_MODE_MASTER; } else { ipwlan_printf(en, "prism <interface> mode ap"IP_LF); ipwlan_printf(en, "prism <interface> mode client auto|adhoc|infra"IP_LF); goto done; } if (ipcom_socketioctl(fd, IP_SIOCSIWMODE, &iwreq) < 0) { goto error; } } goto done; } /* Get/Set SSID */ if (!ipcom_strcmp(argv[2], "ssid")) { iwreq.u.essid.pointer = ssid; if (argc < 4) { /* Get SSID */ iwreq.u.essid.length = sizeof(ssid); if (ipcom_socketioctl(fd, IP_SIOCGIWESSID, &iwreq) == 0) { if(ssid[0]) { ipwlan_printf(en, "ssid: %s"IP_LF, ssid); } else { ipwlan_printf(en, "-- Not associated --"IP_LF); } goto done; } } else { /* Set SSID */ iwreq.u.essid.length = ipcom_sprintf(ssid, "%.*s", sizeof(ssid) - 1, argv[3]); if (ipcom_socketioctl(fd, IP_SIOCSIWESSID, &iwreq) == 0) { goto done; } } goto error; } /* Get/Set frequency */ if (!ipcom_strcmp(argv[2], "freq")) { if(argc < 4) { /* Get frequency */ if (ipcom_socketioctl(fd, IP_SIOCGIWFREQ, &iwreq) < 0) { goto error; } ipwlan_printf(en, "RF frequency: %d kHz"IP_LF, iwreq.u.freq.m); } else { /* Set frequency */ if (!strcmp(argv[3], "auto")) { iwreq.u.freq.flags = IP_IW_FREQ_AUTO; iwreq.u.freq.m = WLAN_FREQUENCY_BAND; iwreq.u.freq.e = 0; } else { i = ipcom_strtol(argv[3], &endp, 10); if (*endp != '\0') { ipwlan_printf(en, "Error: invalid frequency value, '%s'"IP_LF, argv[3]); goto done; } iwreq.u.freq.flags = IP_IW_FREQ_FIXED; iwreq.u.freq.m = i; iwreq.u.freq.e = 0; if (ipcom_socketioctl(fd, IP_SIOCSIWFREQ, &iwreq) < 0) { goto error; } } } goto done; } /* Get/Set authentication */ if (!ipcom_strcmp(argv[2], "auth")) { if (argc < 4) { /* Get authentication policy */ ipwlan_printf(en, "Cannot get authentication policy. Try device specific shell command"IP_LF); } else { /* Set authentication policy */ if (strcmp(argv[3], "open") && strcmp(argv[3], "shared-key") && strcmp(argv[3], "wpa-psk") && strcmp(argv[3], "wpa") && strcmp(argv[3], "wpa2-psk") && strcmp(argv[3], "wpa2")) { ipwlan_printf(en, "Error: invalid authentication policy, valid policies are 'open', 'shared-key', 'wpa-psk or 'wpa'" IP_LF); goto done; } if(strcmp(argv[3], "open") == 0) iwreq.u.auth_type = IP_IW_AUTH_ALG_OPEN_SYSTEM; else if(strcmp(argv[3], "shared-key") == 0) iwreq.u.auth_type = IP_IW_AUTH_ALG_SHARED_KEY; else if(strcmp(argv[3], "wpa2-psk") == 0) iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA2_PSK; else if(strcmp(argv[3], "wpa2") == 0) iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA2; else if(strcmp(argv[3], "wpa-psk") == 0) iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA_PSK; else iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA; if (ipcom_socketioctl(fd, IP_SIOCSIWAUTHTYPE, &iwreq) < 0) { goto error; } } goto done; } /* Get/Set encryption */ if (!ipcom_strcmp(argv[2], "encr")) { if (argc < 4) { if (ipcom_socketioctl(fd, IP_SIOCGIWENCRTYPE, &iwreq) < 0) { goto error; } for(i = 0; i < (int) (sizeof(ipwlan_encr_policy)/sizeof(ipwlan_encr_policy[0])); i++) { if ((unsigned) ipwlan_encr_policy[i] == iwreq.u.encr_type) { break; } } ipwlan_printf(en, "privacy: %s"IP_LF, wlan_encr_text[i]); } else { /* Set encryption parameters */ if (!strcmp(argv[3], "wep")) { if (argc < 5 || argc > 6) { ipwlan_printf(en, "Usage: wlan <interface> encr wep 1|2|3|4 [<key>]"IP_LF); goto done; } i = ipcom_strtol(argv[4], &endp, 10); if (*endp != '\0' || i < 1 || i > 4) { ipwlan_printf(en, "Error: Invalid index value allowed are 1 to 4" IP_LF); goto done; } if(argc == 6) { if (argv[5][0] == '0' && argv[5][1] == 'x') { if (ipcom_strspn(argv[5] + 2, "012345678ABCDEFabcdef") != ipcom_strlen(argv[5] + 2) || ipcom_strlen(argv[5] + 2) > 32 || (ipcom_strlen(argv[5] + 2) % 2) != 0) /* 32 nibbles => 128 bits */ { ipwlan_printf(en, "Usage: wlan <interface> encr wep <index> 0x<hex key>|<string key>"IP_LF); goto done; } for (j = 0; ipcom_sscanf(argv[5] + 2 + 2 * j, "%2x", &k); j++) { iwreq.u.key.key[j] = (unsigned char)k; } iwreq.u.key.len = j; } else { /* key is a text string */ iwreq.u.key.len = ipcom_sprintf((char *)iwreq.u.key.key, "%.*s", MIN(sizeof(iwreq.u.key.key) - 1, ipcom_strlen(argv[5])), argv[5]); } iwreq.u.key.flags = 0; } else { iwreq.u.key.flags = IP_IW_KEY_FLAG_NOKEY; } iwreq.u.key.type = IP_IW_ENCR_ALG_WEP; iwreq.u.key.index = i - 1; /* Index 1 - 4 */ if (ipcom_socketioctl(fd, IP_SIOCSIWENCRKEY, &iwreq) < 0) { goto error; } iwreq.u.encr_type = IP_IW_ENCR_ALG_WEP; if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else if (!strcmp(argv[3], "none")) { iwreq.u.encr_type = IP_IW_ENCR_ALG_NONE; if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else if (!strcmp(argv[3], "tkip")) { iwreq.u.encr_type = IP_IW_ENCR_ALG_TKIP; if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else if (!strcmp(argv[3], "ccmp")) { iwreq.u.encr_type = IP_IW_ENCR_ALG_CCMP; if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0) { goto error; } } else { goto error; } } goto done; } /* Commit changes */ if (!ipcom_strcmp(argv[2], "commit")) { if (ipcom_socketioctl(fd, IP_SIOCSIWCOMMIT, &iwreq) < 0) { goto error; } goto done; } /* Get link quality */ if (!ipcom_strcmp(argv[2], "quality")) { ipcom_socketioctl(fd, IP_SIOCGIWAP, &iwreq); ipcom_memcpy(oid_data, iwreq.u.addr.sa_data, 6); ipcom_memcpy(iwreq.u.quality.bssid, oid_data, 6); if (ipcom_socketioctl(fd, IP_SIOCGIWQUALITY, &iwreq) < 0) { goto error; } ipwlan_printf(en, "\r\nLink quality\r\n============\r\n"); ipwlan_printf(en, "RSSI: % 3d dBm\r\n", (int)iwreq.u.quality.level); ipwlan_printf(en, "Rate: % 3d Mbps\r\n", (unsigned int)iwreq.u.quality.qual); goto done; } error: ipwlan_printf(en, "Error: command %s failed"IP_LF, argv[2]); ret = IPCOM_ERR_FAILED; done: (void)ipcom_socketclose(fd); return ret; }
/* *=========================================================================== * ipcom_shell_print_prompt *=========================================================================== * Description: Print shell prompt. * Parameters: * Returns: 0 = success, <0 = error code. * */ IP_STATIC int ipcom_shell_print_prompt(char *prompt_template, char *prompt_addr, int *promptlen, Ip_pid_t ppid, Ip_u32 seqno) { int baselen; int ret = 0; int buflen = 0; char *buf; #if IPCOM_USE_FILE != IPCOM_FILE_NONE char *cwd; char *base; char cwdbuf[128]; #endif buf = ipcom_malloc(IPCOM_STDIO_BUFSIZE); if (buf == IP_NULL) return -1; for (; *prompt_template != '\0'; ++prompt_template) { ip_assert(buflen < (int)IPCOM_STDIO_BUFSIZE - 1); if (*prompt_template != '\\') { /* 'Normal' character */ buf[buflen++] = *prompt_template; } else { /* New special character*/ switch (*++prompt_template) { case 'w': /* Print current working directory */ case 'W': #if IPCOM_USE_FILE != IPCOM_FILE_NONE /* Print basename of the current workning directory */ cwd = ipcom_getcwd(cwdbuf, sizeof(cwdbuf)); if (cwd == IP_NULL) { IPCOM_LOG0(DEBUG, "ipcom_shell_print_prompt :: ipcom_getcwd() failed"); break; } if (*prompt_template == 'w') base = cwd; else { base = ipcom_strrchr(cwd, '/'); if (base != IP_NULL && base != cwd) base++; else { base = ipcom_strrchr(cwd, '\\'); if (base == IP_NULL) base = cwd; else base++; } } baselen = ipcom_strlen(base); ipcom_memcpy(buf + buflen, base, baselen); buflen += baselen; #endif break; case 'p': /* Print the shell process name */ { char procname[40]; ipcom_sprintf(procname, "ipcom_shell_%lx_%lx", (Ip_u32)ppid, seqno); baselen = ipcom_strlen(procname); ipcom_memcpy(buf + buflen, procname, baselen); buflen += baselen; } break; case 'P': /* Print the shell process pid */ { char pid[14]; ipcom_sprintf(pid, "0x%lx", ipcom_getpid()); baselen = ipcom_strlen(pid); ipcom_memcpy(buf + buflen, pid, baselen); buflen += baselen; } break; case 'i': /* Print the IP address */ if (*prompt_addr) { baselen = ipcom_strlen(prompt_addr); ipcom_memcpy(buf + buflen, prompt_addr, baselen); buflen += baselen; } break; #if IPCOM_USE_ENV != IPCOM_ENV_NONE case 'V': { char vrbuf[16]; baselen = ipcom_sprintf(vrbuf, "%d", ipcom_proc_vr_get()); ipcom_memcpy(buf + buflen, vrbuf, baselen); buflen += baselen; } break; #endif default: /* Unknown code. */ IPCOM_LOG1(DEBUG, "ipcom_shell_print_prompt :: unknown code: %c", *prompt_template); buf[buflen++] = '\\'; buf[buflen++] = '\\'; buf[buflen++] = *prompt_template; break; } } } if (buflen > 0) { buf[buflen] = '\0'; if (promptlen != IP_NULL) *promptlen = ipcom_strlen(buf); ipcom_printf(buf); } ipcom_free(buf); if (ret < 0) IPCOM_LOG0(WARNING, "ipcom_shell_print_prompt :: ipcom_printf() failed"); return ret; }