IP_PUBLIC int ipcom_cmd_smptest(int argc, char **argv) { Ipcom_getopt opt; int c; struct Ip_addrinfo hints; struct Ip_addrinfo *res; char *hostname = "0.0.0.0"; char *servname = "8484"; int socktype = IP_SOCK_STREAM; int domain = IP_AF_INET; Ipcom_cmd_smptest_t smp_opt; return_client = 0; return_server = 0; verbose = 0; ipcom_memset(&smp_opt, 0, sizeof(smp_opt)); smp_opt.server = 1; smp_opt.ip4 = 1; smp_opt.tcp = 1; smp_opt.num_bytes = 1024; smp_opt.num_sock = 1; smp_opt.port = 8484; ipcom_getopt_clear_r(&opt); while ((c = ipcom_getopt_r(argc, argv, "l:p:s:c6uhv", &opt)) != -1) { switch(c) { case 'c': smp_opt.server = 0; if ( verbose ) ipcom_printf( "client"IP_LF ); break; case '6': smp_opt.ip4 = 0; domain = IP_AF_INET6; hostname = "::"; if ( verbose ) ipcom_printf( "IPv6"IP_LF ); break; case 'u': smp_opt.tcp = 0; socktype = IP_SOCK_DGRAM; if ( verbose ) ipcom_printf( "UDP"IP_LF ); break; case 'l': smp_opt.num_bytes = ipcom_atoi(opt.optarg); if ( verbose ) ipcom_printf( "num bytes: %d"IP_LF, smp_opt.num_bytes ); break; case 'p': servname = opt.optarg; smp_opt.port = ipcom_atoi(opt.optarg); if ( verbose ) ipcom_printf( "port: %s"IP_LF, servname ); break; case 's': smp_opt.num_sock = ipcom_atoi(opt.optarg); if ( smp_opt.num_sock > MAX_TASKS ) smp_opt.num_sock = MAX_TASKS; if ( verbose ) ipcom_printf( "sockets: %d"IP_LF, smp_opt.num_sock ); break; case 'v': verbose = 1; break; case 'h': ipcom_cmd_smptest_print_usage(); return -1; default: ipcom_printf("smptest: unknown option %c"IP_LF, (char)c); ipcom_cmd_smptest_print_usage(); return -1; } } if (opt.optind < argc) hostname = argv[opt.optind]; else { if ( 0 == smp_opt.server ) { if ( smp_opt.ip4 ) hostname = "127.0.0.1"; else hostname = "::1"; } } if ( verbose ) ipcom_printf( "%s : %s"IP_LF, hostname, servname ); ipcom_memset(&hints, 0, sizeof(hints)); hints.ai_socktype = socktype; hints.ai_flags = IP_AI_CANONNAME; hints.ai_family = domain; if (ipcom_getaddrinfo(hostname, servname, &hints, &res) != 0) { ipcom_printf("sockperf: getaddrinfo() failed"IP_LF); goto cleanup; } smp_opt.res = res; if ( smp_opt.server ) smp_opt_server = smp_opt; else smp_opt_client = smp_opt; if ( smp_opt.server == 1 ) { if ( 0 != ipcom_cmd_smptest_server() || 0 != return_server ) { ipcom_printf( "Failure."IP_LF ); goto cleanup; } } else { if ( 0 != ipcom_cmd_smptest_client() || 0 != return_client ) { ipcom_printf( "Failure"IP_LF ); goto cleanup; } } ipcom_printf( "Success." ); /* Success */ cleanup: ipcom_freeaddrinfo( res ); return 0; }
IP_PUBLIC int ipcom_socketpair_tcp(int fd[2]) { int server; union Ip_sockaddr_union sock; Ip_socklen_t socklen; Ip_bool connected = IP_FALSE; int opt; struct Ip_addrinfo hints; struct Ip_addrinfo *res = IP_NULL; fd[0] = fd[1] = server = -1; ipcom_memset(&hints, 0, sizeof(hints)); hints.ai_socktype = IP_SOCK_STREAM; if (ipcom_getaddrinfo(IP_NULL, "0", &hints, &res) != 0) goto failed; /* Server socket */ server = ipcom_socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (server == -1) goto failed; opt = 1; (void)ipcom_setsockopt(server, IP_SOL_SOCKET, IP_SO_REUSEADDR, &opt, sizeof(opt)); if (ipcom_bind(server, res->ai_addr, res->ai_addrlen) != 0) goto failed; if (ipcom_listen(server, 1) != 0) goto failed; socklen = res->ai_addrlen; if (ipcom_getsockname(server, &sock.sa, &socklen) != 0) goto failed; /* Client socket */ fd[1] = ipcom_socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd[1] == -1) goto failed; opt = 1; (void)ipcom_setsockopt(fd[1], IP_SOL_SOCKET, IP_SO_REUSEADDR, &opt, sizeof(opt)); opt = 1; (void)ipcom_socketioctl(fd[1], IP_FIONBIO, &opt); if (ipcom_connect(fd[1], &sock.sa, socklen) == -1) { if (ipcom_errno != IP_ERRNO_EINPROGRESS) goto failed; } else connected = IP_TRUE; /* Spawn socket */ fd[0] = ipcom_accept(server, IP_NULL, IP_NULL); if (fd[0] == -1) goto failed; opt = 1; (void)ipcom_setsockopt(fd[0], IP_SOL_SOCKET, IP_SO_REUSEADDR, &opt, sizeof(opt)); ipcom_socketclose(server); /* Client socket revisited */ if (connected == IP_FALSE) { Ip_fd_set write_set; IP_FD_ZERO(&write_set); IP_FD_SET(fd[1], &write_set); if (ipcom_socketselect(fd[1] + 1, IP_NULL, &write_set, IP_NULL, IP_NULL) != 1) goto failed; } opt = 0; (void)ipcom_socketioctl(fd[1], IP_FIONBIO, &opt); if (res != IP_NULL) ipcom_freeaddrinfo(res); return 0; failed: if (res != IP_NULL) ipcom_freeaddrinfo(res); if (fd[0] != -1) ipcom_socketclose(fd[0]); if (fd[1] != -1) ipcom_socketclose(fd[1]); if (server != -1) ipcom_socketclose(server); return -1; }
/* *=========================================================================== * ipcom_cmd_sockperf *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC int ipcom_cmd_sockperf(int argc, char **argv) { Ipcom_getopt opt; Ipcom_cmd_sockperf_t cmd; int c; struct Ip_addrinfo hints; char *hostname = "0.0.0.0"; char *servname = "7373"; int socktype = IP_SOCK_STREAM; int domain = IP_AF_INET; if (argc < 2) { ipcom_cmd_sockperf_print_usage(); return 0; } ipcom_memset(&cmd, 0, sizeof(cmd)); cmd.buf_len = 8192; cmd.num_buf = 2048; cmd.num_sock = 1; cmd.linger.l_onoff = 1; cmd.linger.l_linger = 3; cmd.sendbuf_size = 32767; cmd.recvbuf_size = 16384; ipcom_getopt_clear_r(&opt); while ((c = ipcom_getopt_r(argc, argv, "6aeL:l:n:Pp:R:rs:T:tu", &opt)) != -1) { switch(c) { case '6': domain = IP_AF_INET6; hostname = "::"; break; case 'a': cmd.accept = IP_TRUE; break; case 'e': cmd.echo = IP_TRUE; break; case 'L': cmd.linger.l_linger = ipcom_atoi(opt.optarg); break; case 'l': cmd.buf_len = ipcom_atoi(opt.optarg); break; case 'n': cmd.num_buf = ipcom_atoi(opt.optarg); break; case 'P': cmd.testpattern = IP_TRUE; break; case 'p': servname = opt.optarg; break; case 'R': cmd.recvbuf_size = ipcom_atoi(opt.optarg); break; case 'r': cmd.receive = IP_TRUE; break; case 's': cmd.num_sock = ipcom_atoi(opt.optarg); break; case 'T': cmd.sendbuf_size = ipcom_atoi(opt.optarg); break; case 't': cmd.transmit = IP_TRUE; break; case 'u': socktype = IP_SOCK_DGRAM; break; default: ipcom_printf("sockperf: unknown option %c"IP_LF, (char)c); return -1; } } if (cmd.testpattern) { if (cmd.buf_len & 0x7) { ipcom_printf("sockperf: the buffert (set with -l) must be a multiple of 8 when " "using a test pattern"IP_LF); goto cleanup; } if (cmd.transmit) { cmd.send_pattern = ipcom_calloc(cmd.num_sock, sizeof(Ip_u32)); if (cmd.send_pattern == IP_NULL) { ipcom_printf("sockperf: out of memory when allocating send pattern"IP_LF); goto cleanup; } } if (cmd.receive) { cmd.recv_pattern = ipcom_calloc(cmd.num_sock, sizeof(Ip_u32)); if (cmd.recv_pattern == IP_NULL) { ipcom_printf("sockperf: out of memory when allocating receive pattern"IP_LF); goto cleanup; } } } if (opt.optind < argc) hostname = argv[opt.optind]; ipcom_memset(&hints, 0, sizeof(hints)); hints.ai_socktype = socktype; hints.ai_flags = IP_AI_CANONNAME; hints.ai_family = domain; if (ipcom_getaddrinfo(hostname, servname, &hints, &cmd.res) != 0) { ipcom_printf("sockperf: getaddrinfo() failed"IP_LF); goto cleanup; } cmd.buf = ipcom_malloc(cmd.buf_len + 1); if (cmd.buf == IP_NULL) { ipcom_printf("sockperf: Failed to allocate %lu bytes" IP_LF, cmd.buf_len); goto cleanup; } cmd.sock_array = ipcom_malloc(cmd.num_sock * sizeof(int)); if (cmd.sock_array == IP_NULL) { ipcom_printf("sockperf: Failed to allocate %lu bytes for sockets" IP_LF, cmd.num_sock * sizeof(int)); goto cleanup; } if (cmd.accept) ipcom_cmd_sockperf_accept(&cmd); else ipcom_cmd_sockperf_connect(&cmd); cleanup: ipcom_free(cmd.send_pattern); ipcom_free(cmd.recv_pattern); ipcom_free(cmd.sock_array); ipcom_free(cmd.buf); ipcom_freeaddrinfo(cmd.res); return 0; }
/* *=========================================================================== * 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; } }