示例#1
0
/*
 *===========================================================================
 *                    ipcom_cmd_sockperf_connect
 *===========================================================================
 * Description: Active open of socket(s)
 * Parameters:
 * Returns:
 */
IP_STATIC void
ipcom_cmd_sockperf_connect(Ipcom_cmd_sockperf_t *cmd)
{
    Ip_fd            *s = cmd->sock_array;
    Ip_u32            created_sockets;
    struct Ip_timeval start;
    struct Ip_timeval stop;

    ipcom_printf("sockperf-c: connecting to %s[%d]"IP_LF,
                 cmd->res->ai_canonname,
                 ip_ntohs(((struct Ip_sockaddr_in *)cmd->res->ai_addr)->sin_port));
    ipcom_microtime(&start);
    for (created_sockets = 0; created_sockets < cmd->num_sock; created_sockets++)
    {
        s[created_sockets] = ipcom_socket(cmd->res->ai_family,
                                          cmd->res->ai_socktype,
                                          cmd->res->ai_protocol);
        if (s[created_sockets] == IP_SOCKERR)
        {
            ipcom_printf("sockperf-c: Failed to create socket: %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            created_sockets--;
            goto cleanup;
        }

        if (ipcom_setsockopt(s[created_sockets],
                             IP_SOL_SOCKET,
                             IP_SO_LINGER,
                             &cmd->linger,
                             sizeof(cmd->linger)) < 0)
        {
            ipcom_printf("sockperf-c: setsockopt SO_LINGER failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            goto cleanup;
        }

        if (ipcom_connect(s[created_sockets], cmd->res->ai_addr, cmd->res->ai_addrlen) < 0)
        {
            ipcom_printf("sockperf-c: Failed to connect: %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            goto cleanup;
        }
    }
    ipcom_microtime(&stop);
    ipcom_printf("sockperf-t: %ld sockets connected in %ld ms"IP_LF,
                 created_sockets,
                 ipcom_cmd_sockperf_tv_to_msec(&start, &stop));

    ipcom_cmd_sockperf_run(cmd);

 cleanup:
    while (created_sockets > 0)
        (void)ipcom_socketclose(s[created_sockets--]);
}
示例#2
0
int get_ip( char * ifname)
{ 
	struct Ip_ifreq ifr;
	int fd;
	int addr;
	
	        fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
	
	ipcom_memset(&ifr,0,sizeof(ifr));
	ipcom_strcpy(ifr.ifr_name, ifname); 
	if (ipcom_socketioctl(fd, IP_SIOCGIFADDR, &ifr) != IP_SOCKERR)
	{ 
		addr =((struct Ip_sockaddr_in *)&ifr.ip_ifr_addr)->sin_addr.s_addr;
		
	return addr;
	}
}
/*
 *===========================================================================
 *                    ipipsec_cmd_ipsecctrl
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipipsec_cmd_ipsecctrl(int argc, char **argv)
{
    Argvars   vars;
    int       ret;

    if (argc < 2)
        goto usage;

    vars.fd = ipcom_socket(IP_PF_KEY, IP_SOCK_RAW, PF_KEY_V2);
    if (vars.fd < 0)
    {
        ipcom_printf("ipsecctrl: ipcom_socket() failed (%s)"IP_LF,
                     ipcom_strerror(ipcom_errno));
        return -1;
    }

    vars.argc = argc;
    vars.argv = argv;

    ret = ipsecctrl_run_command(argv[1], &vars);
    ipcom_socketclose(vars.fd);

    if (ret == 0)
        return 0;

 usage:
    ipcom_printf(
                 "IPsec control command, version 2.0"IP_LF
                 "Copyright (c) 2000-2009, Interpeak AB <www.interpeak.com>"IP_LF
                 "usage: ipsecctrl <command>"IP_LF
                 "   Commands:"IP_LF
                 "\tflows\t\t  list all IPsec output flows"IP_LF
                 "\tsa\t\t  list all kernel Security Associations"IP_LF
                 "\tmib\t\t  print IPSec monitor MIB"IP_LF
                 "\tget\t\t  get IPSec configuration values"IP_LF
                 "\tset <name> <val>  set IPSec configuration values"IP_LF
                 );

    return 0;
}
示例#4
0
int vlan_check(int ifindex, char * parent)
{
    struct Ip_ifreq   ifreq;
    struct Ip_vlanreq vlanreq;
    
    int fd;
        fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
        
    ipcom_memset(&vlanreq, 0, sizeof(struct Ip_vlanreq));
    ifreq.ip_ifr_data = &vlanreq;
    if (ipcom_if_indextoname(ifindex, ifreq.ifr_name) == IP_NULL
        || ipcom_socketioctl(fd, IP_SIOCGETVLAN, &ifreq) < 0)
        return 0;

    if(ipcom_strcmp(parent,vlanreq.vlr_parent) == 0)
    { 
        	return 1;
        }
    else
    	return -1; 
    
}
IP_STATIC
IPCOM_PROCESS( ipcom_cmd_smptest_client_spawn )
{
    union
    {
        struct Ip_sockaddr          sa;
#ifdef IPCOM_USE_INET6
        struct Ip_sockaddr_in6      sin6;
#endif
        struct Ip_sockaddr_storage  ss;
        struct Ip_sockaddr_in       sin;
    } addr;
    Ip_fd socket;
    unsigned char *buf = 0;
    int portadd = spawn_number_client++;
    int opt_val = 1;
    int sec = SECONDS_CLIENT;
    int send = 0;
    int num_sends = 0;
    unsigned long num_bytes = 0;

    ipcom_proc_init();

    ipcom_memset( &addr.ss, 0, sizeof( addr.ss ) );
    ipcom_memcpy( &addr.sa, smp_opt_client.res->ai_addr, smp_opt_client.res->ai_addrlen );

    socket = ipcom_socket( smp_opt_client.res->ai_family, smp_opt_client.res->ai_socktype, smp_opt_client.res->ai_protocol );
    if (socket == IP_SOCKERR)
    {
        ipcom_printf("Failed to create socket for thread %d: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno));
        return_client = 1;
        ipcom_sem_post( sem_wait_client );
        return;
    }

    if ( 0 != ipcom_setsockopt(socket, IP_SOL_SOCKET, IP_SO_REUSEPORT, &opt_val, sizeof (opt_val)) )
    {
        ipcom_printf("ipcom_setsockopt failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
        return_client = 1;
        ipcom_sem_post( sem_wait_client );
        return;
    }

    if ( 0 != ipcom_socketioctl( socket, IP_X_SIOCSINTR, &sec ) )
    {
        ipcom_printf("ipcom_socketioctl failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
        return_client = 1;
        ipcom_sem_post( sem_wait_client );
        return;
    }

    addr.sin.sin_port = ip_htons( smp_opt_client.port + portadd );   /* port is in the same place for IPv4 and IPv6 */
    if ( smp_opt_client.tcp )
    {
        if ( 0 != ipcom_connect( socket, &addr.sa, smp_opt_client.res->ai_addrlen ) )
        {
            ipcom_printf("Thread %d failed to connect: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno));
            return_client = 1;
            ipcom_sem_post( sem_wait_client );
            return;
        }
        if ( verbose )
            ipcom_printf("Thread %d connected to port %d"IP_LF, portadd, smp_opt_client.port + portadd );
    }

    buf = ipcom_malloc( smp_opt_client.num_bytes );
    while ( 1 )
    {
        if ( smp_opt_client.tcp )
            send = ipcom_send( socket, buf, smp_opt_client.num_bytes, 0);
        else
            send = ipcom_sendto( socket, buf, smp_opt_client.num_bytes, 0, &addr.sa, smp_opt_client.res->ai_addrlen );

        if ( send > 0 )
           num_bytes += send;
        num_sends++;
        if ( send == 0 )
        {
           ipcom_printf( "Error: Disconnected"IP_LF );
           return_client = 1;
           break;
        }
        else if ( send < 0 )
        {
            if ( ipcom_errno == IP_ERRNO_EINTR )
            {
                if ( verbose )
                {
                    ipcom_printf("Thread %d done."IP_LF, portadd );
                    ipcom_printf("  Sends: %d"IP_LF, num_sends );
                    ipcom_printf("  MB/s:  %f"IP_LF, ((float)(num_bytes)/(1024.0f*1024.0f) )/5.0f );
                }
                break;
            }
            return_client = 1;
            ipcom_printf("Error on thread %d: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno));
            break;
        }
    }

    if ( verbose )
    {
        if ( spawn_number_client != smp_opt_client.num_sock )
        {
            ipcom_printf("Error. Only %d client-sockets seemed to work."IP_LF, spawn_number_client );
        }
    }

    ipcom_socketclose( socket );

    ipcom_free( buf );
    if ( 0 == ipcom_atomic_sub_and_return( &num_wait_client, 1 ) )
        ipcom_sem_post( sem_wait_client );

    ipcom_proc_exit();
}
IP_STATIC
IPCOM_PROCESS( ipcom_cmd_smptest_server_spawn )
{
    union
    {
        struct Ip_sockaddr          sa;
#ifdef IPCOM_USE_INET6
        struct Ip_sockaddr_in6      sin6;
#endif
        struct Ip_sockaddr_storage  ss;
        struct Ip_sockaddr_in       sin;
    } addr;

    Ip_fd  listen_socket;
    Ip_fd  connect_sock = 0;
    int    opt_val = 1;
    int    portadd = spawn_number_server++;
    int    bytes = 0;
    int    sec = SECONDS_CLIENT + SECONDS_SERVER;
    unsigned char *buf = 0;
    int    num_recives = 0;
    unsigned long num_bytes = 0;
    struct Ip_sockaddr from;
    struct Ip_linger   linger;
    Ip_socklen_t       from_length = 0;
    int     retry_count = 0;

    ipcom_proc_init();

    ipcom_memset( &addr.ss, 0, sizeof( addr.ss ) );
    ipcom_memcpy( &addr.sa, smp_opt_server.res->ai_addr, smp_opt_server.res->ai_addrlen );

    linger.l_onoff  = 1;
    linger.l_linger = 2;

    listen_socket = ipcom_socket( smp_opt_server.res->ai_family, smp_opt_server.res->ai_socktype, smp_opt_server.res->ai_protocol );
    if (listen_socket == IP_SOCKERR)
    {
        ipcom_printf("Failed to create socket: %s"IP_LF, ipcom_strerror(ipcom_errno));
        return_server = 1;
        ipcom_sem_post( sem_wait_server );
        return;
    }

    if ( 0 != ipcom_setsockopt(listen_socket, IP_SOL_SOCKET, IP_SO_REUSEPORT, &opt_val, sizeof (opt_val)) )
    {
        ipcom_printf("ipcom_setsockopt failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
        return_server = 1;
        ipcom_sem_post( sem_wait_server );
        return;
    }

    addr.sin.sin_port = ip_htons( smp_opt_server.port + portadd );   /* port is in the same place for IPv4 and IPv6 */
    if ( 0 != ipcom_bind( listen_socket, &addr.sa, sizeof( addr.ss ) ) )
    {
        ipcom_printf("Failed to bind: %s"IP_LF, ipcom_strerror(ipcom_errno));
        return_server = 1;
        ipcom_sem_post( sem_wait_server );
        return;
    }

    buf = ipcom_malloc( smp_opt_server.num_bytes );

    if ( smp_opt_server.tcp )
    {
        if ( -1 == ipcom_listen( listen_socket, 0 ) )
        {
            ipcom_printf("Listen failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
            return_server = 1;
            ipcom_sem_post( sem_wait_server );
            return;
        }
        if ( verbose )
            ipcom_printf("Thread %d listens to %s:%d"IP_LF, portadd, smp_opt_server.res->ai_canonname, ip_ntohs( addr.sin.sin_port ) );
    }

    if ( 0 == ipcom_atomic_sub_and_return( &listen_wait, 1 ) )
    {
        /* Send to the test-server or write to stdout? */
        if ( server_out >= 0 )
        {
            char ready[] = "Ready.";
            ipcom_socketwrite(server_out, ready, 8 );
        }
        else
            ipcom_printf("Ready."IP_LF );
    }

    if ( 0 != ipcom_socketioctl( listen_socket, IP_X_SIOCSINTR, &sec ) )
    {
        ipcom_printf("ipcom_socketioctl failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
        return_server = 1;
        ipcom_sem_post( sem_wait_server );
        return;
    }

    if ( smp_opt_server.tcp )
    {
retry:
        connect_sock = ipcom_accept( listen_socket, IP_NULL, 0 );
        if ( -1 == connect_sock )
        {
            if ( ipcom_errno == IP_ERRNO_EINTR )
            {
                if ( verbose )
                {
                    if ( ++retry_count < 5 )
                    {
                        ipcom_printf("Accept failed for thread %d: %s.. Retrying."IP_LF, portadd, ipcom_strerror(ipcom_errno));
                        goto retry;
                    }
                }
            }
            ipcom_printf("Accept failed for thread %d: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno));
            return_server = 1;
            ipcom_socketclose( listen_socket );
            ipcom_sem_post( sem_wait_server );
            return;
        }

        if ( 0 != ipcom_socketioctl( connect_sock, IP_X_SIOCSINTR, &sec ) )
        {
            ipcom_printf("ipcom_socketioctl failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
            return_server = 1;
            ipcom_sem_post( sem_wait_server );
            return;
        }

        if ( 0 != ipcom_setsockopt( connect_sock, IP_SOL_SOCKET, IP_SO_LINGER, &linger, sizeof (linger)) )
        {
            ipcom_printf("ipcom_setsockopt failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
            return_server = 1;
            ipcom_sem_post( sem_wait_server );
            return;
        }
    }

    while ( 1 )
    {
        num_recives++;
        if ( smp_opt_server.tcp )
            bytes = ipcom_recv( connect_sock, buf, smp_opt_server.num_bytes, 0);
        else
        {
            bytes = ipcom_recvfrom( listen_socket, buf, smp_opt_server.num_bytes, 0, &from, &from_length );
            if ( num_recives == 1 && 0 == smp_opt_server.tcp )
            {
                sec = SECONDS_CLIENT+2+portadd;
                if ( 0 != ipcom_socketioctl( listen_socket, IP_X_SIOCSINTR, &sec ) )
                {
                    ipcom_printf("ipcom_socketioctl failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
                    return_server = 1;
                    ipcom_sem_post( sem_wait_server );
                    return;
                }
            }
        }

        if ( bytes > 0 )
            num_bytes += bytes;
        if (bytes == 0)
        {
            if ( verbose )
            {
                ipcom_printf("Thread %d done."IP_LF, portadd );
                ipcom_printf("  Recives: %d"IP_LF, num_recives );
                ipcom_printf("  MB/s:    %f"IP_LF, ((float)(num_bytes)/(1024.0f*1024.0f) )/5.0f );
            }
            break;
        }
        else if (bytes < 0)
        {
            if ( ipcom_errno == IP_ERRNO_EINTR )
            {
                if ( smp_opt_server.tcp )
                {
                    return_server = 1;
                    ipcom_printf("Error! Out of time!"IP_LF );
                    break;
                }
                else
                {
                    if ( verbose )
                    {
                        ipcom_printf("Thread %d done."IP_LF, portadd );
                        ipcom_printf("  Recives: %d"IP_LF, num_recives );
                        ipcom_printf("  MB/s:    %f"IP_LF, ((float)(num_bytes)/(1024.0f*1024.0f) )/5.0f );
                    }
                    break;
                }
            }
            else if ( bytes == IP_SOCKERR )    /* Connection reset by peer */
            {
            }

            return_server = 1;
            ipcom_printf("recv failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
            return;
        }
    }

    if ( verbose )
    {
        if ( spawn_number_server != smp_opt_server.num_sock )
        {
            ipcom_printf("Error. Only %d server-sockets seemed to work."IP_LF, spawn_number_server );
        }
    }

    if ( smp_opt_server.tcp )
        ipcom_shutdown( connect_sock, IP_SHUT_RDWR );

    ipcom_free( buf );
    ipcom_socketclose( listen_socket );

    if ( 0 == ipcom_atomic_sub_and_return( &num_wait_server, 1 ) )
        ipcom_sem_post( sem_wait_server );

    if ( smp_opt_server.tcp )
        ipcom_socketclose( connect_sock );

    ipcom_proc_exit();
}
/*
 *===========================================================================
 *                    ipl2tps
 *===========================================================================
 * Description: 
 * Parameters:  
 * Returns:     
 *
 */
IP_STATIC
IPCOM_PROCESS(ipl2tps)
{
    Ip_fd                   ipd_fd = IP_INVALID_SOCKET;
    Ip_bool                 ipd_init = 0;
#ifdef IPPPP_USE_PPPL2TP
    Ip_fd                   ipl2tp_ppp_ipc_recv_fd = IP_INVALID_SOCKET;
#endif

    ipcom_proc_init();

#ifdef IPPPP_USE_PPPL2TP
    if ((ipl2tp_ppp_ipc_recv_fd = ipppp_pppl2tp_pkt_que_open()) == IP_INVALID_SOCKET)
    {
        ipcom_printf("Cannot allocate data packet output socket, errno: %d"IP_LF, ipcom_errno);
        goto leave;
    }
#endif

    /* Get socket */
    if ((udp_fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, IP_IPPROTO_UDP)) < 0)
    {
        ipcom_printf("Cannot allocate socket, errno: %d"IP_LF,
                     ipcom_errno);
        goto leave;
    }
    else
    {
        union Ip_sockaddr_union uaddr;

        /* Bind to L2TP port */
        ipcom_memset(&uaddr, 0, sizeof(uaddr));

        uaddr.sin.sin_family        = IP_AF_INET;
        uaddr.sin.sin_addr.s_addr   = IP_INADDR_ANY;
        uaddr.sin.sin_port          = ip_htons(IPL2TP_PORT_NUMBER);
        uaddr.sin.sin_len           = sizeof(struct Ip_sockaddr_in);
        if (ipcom_bind(udp_fd, &uaddr.sa, sizeof(struct Ip_sockaddr_in)) < 0)
        {
            ipcom_printf("Cannot bind socket, errno: %d"IP_LF,
                         ipcom_errno);
            ipcom_socketclose(udp_fd);
            goto leave;
        }
    }

    /* Get socket */
    if ((ip_fd = ipcom_socket(IP_AF_INET, IP_SOCK_RAW, IP_IPPROTO_L2TP)) < 0)
    {
        ipcom_printf("Cannot allocate socket, errno: %d"IP_LF,
                     ipcom_errno);
        ipcom_socketclose(udp_fd);
        goto leave;
    }


    /* Init IPD */
    if (ipd_init == 0 &&
        ipcom_ipd_init("ipl2tp", IPCOM_SUCCESS, &ipd_fd) != IPCOM_SUCCESS)
    {
        ipcom_printf("Cannot initialize ipd: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        goto leave;
    }

    ipd_init = 1;

    /* Enter read loop (never return) */
    for (;;)
    {
        Ip_fd_set                   fds;            
        Ipl2tp_example_fd_entry_t   *fd;
        int                         fd_max;
        struct Ip_timeval           tv;
        int                         ret;

        IP_FD_ZERO(&fds);

        IP_FD_SET(udp_fd, &fds);
        IP_FD_SET(ip_fd, &fds);
        IP_FD_SET(ipd_fd, &fds);
        fd_max = IP_MAX(udp_fd, ip_fd);
        fd_max = IP_MAX(fd_max, ipd_fd);

#ifdef IPPPP_USE_PPPL2TP
        IP_FD_SET(ipl2tp_ppp_ipc_recv_fd, &fds); 
        fd_max = IP_MAX(fd_max, ipl2tp_ppp_ipc_recv_fd);
#endif

        fd = IPCOM_LIST_FIRST(&ipl2tp_example_fds);
        while (fd != IP_NULL)
        {
            Ipl2tp_example_fd_entry_t   *nfd = IPCOM_LIST_NEXT(&fd->next);
            if (fd->data != IP_NULL)
            {
                IP_FD_SET(fd->fd, &fds);
                fd_max = IP_MAX(fd_max, fd->fd);
            }
            else
            {
                ipcom_list_remove(&fd->next);
                ipcom_socketclose(fd->fd);
                ipcom_free(fd);
            }

            fd = nfd;
        }

        tv.tv_sec   = 0;
        tv.tv_usec  = 10000;
        if ((ret = ipcom_socketselect(fd_max + 1, &fds, IP_NULL, IP_NULL, &tv)) > 0)
        {
            union Ip_sockaddr_union uaddr;
            int                     length;
            Ip_u8                   *buffer;

            if (IP_FD_ISSET(ipd_fd, &fds))
            {
                int event;

                event = ipcom_ipd_input(ipd_fd);
                if (event == IPCOM_IPD_EVENT_RECONFIGURE)
                    goto leave;
            }


#ifdef IPPPP_USE_PPPL2TP
            if (IP_FD_ISSET(ipl2tp_ppp_ipc_recv_fd, &fds))
            {
                Ipppp_pppl2tp_pkt_que_entry que_entry;
                Ipcom_netif *netif;
                Ipcom_pkt *pkt;
                char addrstr[IP_INET_ADDRSTRLEN];

                /* Read message and feed it to L2TP main input */
                if (ipppp_pppl2tp_pkt_que_recv(&que_entry, &uaddr) == IPCOM_SUCCESS)
                {
                    if ((que_entry.netif == IP_NULL) ||
                        (que_entry.pkt == IP_NULL))
                    {
                        ipcom_printf("ipl2tps: L2TPv2 pkt from %s:%d contains null ptr(s)."IP_LF,
                            ipcom_inet_ntop(IP_AF_INET, &uaddr.sin.sin_addr, addrstr, sizeof(addrstr)),
                            ipcom_ntohs(uaddr.sin.sin_port));
                    }
                    else
                    {
                        pkt = que_entry.pkt;
                        netif = que_entry.netif;
                        ipppp_pppl2tp_output(netif, pkt);
                    }
                }
                else
                    ipcom_printf("ipl2tps: PPP pkt recv failed."IP_LF);
            }
#endif /* IPPPP_USE_PPPL2TP */

            if (IP_FD_ISSET(udp_fd, &fds))
            {
                /* Read message and feed it to L2TP main input */
                if ((length = ipl2tp_l2tp_read(udp_fd, &buffer, &uaddr)) > 0)
                {
                    ipl2tp_api_l2tp_input(buffer, 
                                          buffer + HEADER_SPACE,
                                          (Ip_u16)length, 
                                          &uaddr, 
                                          IPL2TP_ATTR_TRANSPORT_UDP);

                    /* Free buffer if not in PPP output queue */
                    if (ipl2tp_buffer_free)
                    {
                        ipl2tp_cache_free(buffer);
                    }
                }
            }

            if (IP_FD_ISSET(ip_fd, &fds))
            {
                /* Read message and feed it to L2TP main input */
                if ((length = ipl2tp_l2tp_read(ip_fd, &buffer, &uaddr)) > 0)
                {
                    /* Remove the IP header before invoking */
                    ipl2tp_api_l2tp_input(buffer, 
                                          buffer + HEADER_SPACE + 20,
                                          (Ip_u16)(length - 20), 
                                          &uaddr, 
                                          IPL2TP_ATTR_TRANSPORT_IP);

                    /* Free buffer if not in PPP output queue */
                    if (ipl2tp_buffer_free)
                    {
                        ipl2tp_cache_free(buffer);
                    }
                }
            }

            fd = IPCOM_LIST_FIRST(&ipl2tp_example_fds);
            while (fd != IP_NULL)
            {
                Ipl2tp_example_fd_entry_t   *nfd = IPCOM_LIST_NEXT(&fd->next);
                if (fd->data!= IP_NULL && IP_FD_ISSET(fd->fd, &fds))
                {
                    /* Read message and feed it to L2TP main input */
                    if ((length = ipl2tp_l2tp_read(fd->fd, &buffer, &uaddr)) > 0)
                    {
                        if (fd->data != IP_NULL)
                        {
                            (*fd->data) (fd,
                                         buffer, 
                                         buffer + HEADER_SPACE, 
                                         length);
                        }

                        /* Free buffer if not in PPP output queue */
                        if (ipl2tp_buffer_free)
                        {
                            ipl2tp_cache_free(buffer);
                        }
                    }
                }

                fd = nfd;
            }
        }
        else if (ret < 0)
        {
            ipcom_printf("select error"IP_LF);
        }        
    }

leave:
    /* Have to call ipd init if not done yet */
    if (ipd_init == 0 &&
        ipcom_ipd_init("ipl2tp", IPCOM_ERR_FAILED, &ipd_fd) == IPCOM_SUCCESS)
    {
        ipd_init = 1;
    }
    if (ipd_init != 0)
    {
        (void)ipcom_ipd_exit("ipl2tp", ipd_fd);
    }

    ipcom_proc_exit();
}
/*
 *===========================================================================
 *                         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_waitif
 *===========================================================================
 * Description: Wait for interface to get an IP address assigned.
 * Parameters:  ifindex - Index of the interface to wait for.
 *                        0 = any interface except loopback.
 *              domain - The address domain.
 * Returns:     0 = success, -1 = error, and sets errno.
 *
 */
IP_PUBLIC int
ipcom_waitif(int ifindex, int domain)
{
    struct Ipnet_rs_msghdr rtmsg;
    struct Ip_timeval stop;
    struct Ip_timeval tv;
    Ip_fd fd = IP_INVALID_SOCKET;
    int ret = -1;

    /* Check domain */
    if (domain != IP_AF_INET
#ifdef IPCOM_USE_INET6
        && domain != IP_AF_INET6
#endif /* IPCOM_USE_INET6 */
       )
    {
        IPCOM_LOG1(ERR, "ipcom_waitif :: invalid domain: %d", domain);
        ipcom_errno_set(IP_ERRNO_EINVAL);
        goto leave;
    }

    /* Get routing socket */
    fd = ipcom_socket(IP_AF_ROUTE, IP_SOCK_RAW, 0);
    if (fd == IP_INVALID_SOCKET)
    {
        IPCOM_LOG1(ERR, "ipcom_waitif :: ipcom_socket(ROUTE, RAW) failed, errno = %d", ipcom_errno);
        goto leave;
    }

    /* Get stop time */
    ipcom_microtime(&tv);
    stop.tv_sec = tv.tv_sec + IPNET_WAITIF_TIMEOUT;

    /* Loop and wait for address */
    for (;;)
    {
        Ip_ssize_t length;

        /* Check if address available */
        if (ifindex == 0)
        {
            int i;

            /* Any if will do */
            for (i = 2; i < IPNET_WAITIF_MAXIF; i++)
            {
                if (ipcom_waitif_gifaddr(fd, i, domain) == 0)
                {
                    ret = 0;
                    goto leave;
                }
            }
        }
        else if (ipcom_waitif_gifaddr(fd, ifindex, domain) == 0)
        {
            ret = 0;
            goto leave;
        }

again:
        /* Get timeout time */
        ipcom_microtime(&tv);
        tv.tv_sec = stop.tv_sec - tv.tv_sec;
        tv.tv_usec = 0;
        if (tv.tv_sec <= 0)
        {
            ipcom_errno_set(IP_ERRNO_ETIMEDOUT);
            goto leave;
        }

        /* Set receive timeout */
        if (ipcom_setsockopt(fd, IP_SOL_SOCKET, IP_SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
        {
            IPCOM_LOG1(ERR, "ipcom_waitif :: ipcom_setsockopt(RCVTIMEO) failed, errno = %d", ipcom_errno);
            goto leave;
        }

        /* Read routing message headers only (truncated read). */
        length = ipcom_recv(fd, &rtmsg, sizeof(rtmsg), 0);
        if (length == IP_SOCKERR)
        {
            if (ipcom_errno != IP_ERRNO_ETIMEDOUT && ipcom_errno != IP_ERRNO_EWOULDBLOCK)
            {
                IPCOM_LOG1(ERR, "ipcom_waitif :: ipcom_recv() failed, errno = %d", ipcom_errno);
            }

            goto leave;
        }

        /* Only bother about newaddr */
        if (rtmsg.type != IPNET_RTM_NEWADDR)
        {
            goto again;
        }
    }

leave:
    if (fd != IP_INVALID_SOCKET)
    {
        ipcom_socketclose(fd);
    }

    return ret;
}
/*
 *===========================================================================
 *                    ipcom_getifaddrs
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipcom_getifaddrs(struct Ip_ifaddrs **ifa)
{
    int                     name[6];
    Ip_u8                   *if_data;
    Ip_size_t               if_data_len;
    Ip_size_t               if_data_offset;
    struct Ipnet_if_msghdr  *ifm;
    struct Ip_ifaddrs       **tail  = ifa;
    struct Ip_sockaddr_dl   *dl;
    struct Ipnet_rt_msghdr  *rtm;
    Ip_fd                   fd = IP_INVALID_SOCKET;
    char                    ifname[IP_IFNAMSIZ];
    Ip_size_t               if_name_len;

    if(ifa == IP_NULL)
        return -1;
    *ifa = IP_NULL;


    name[0] = IP_CTL_NET;
    name[1] = IP_AF_ROUTE;
    name[2] = 0;    /* Always 0 */
    name[3] = 0;
    name[4] = IP_NET_RT_IFLIST;
    name[5] = 0;

redo_alloc:
    if (ipcom_sysctl(name, 6, IP_NULL, &if_data_len, IP_NULL, 0) < 0)
    {
        IPCOM_LOG1(ERR, "ipcom_getifaddrs() :: ipcom_sysctl(%d) failed!"IP_LF, ipcom_errno);
        return -1;
    }

    if_data = ipcom_malloc(if_data_len);
    if (if_data == IP_NULL)
    {
        IPCOM_LOG1(ERR, "ipcom_getifaddrs() :: ipcom_malloc(%d) failed!"IP_LF, if_data_len);
        return -1;
    }

    if (ipcom_sysctl(name, 6, if_data, &if_data_len, IP_NULL, 0) < 0)
    {
        if (ipcom_errno == IP_ERRNO_ENOMEM)
        {
            ipcom_free(if_data);
            goto redo_alloc;
        }

        IPCOM_LOG1(ERR, "ipcom_getifaddrs() :: ipcom_sysctl(%d) failed!"IP_LF, ipcom_errno);
        goto cleanup;
    }

#if defined(IPCOM_USE_INET)
    fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, IP_IPPROTO_UDP);
#elif defined(IPCOM_USE_INET6)
    fd = ipcom_socket(IP_AF_INET6, IP_SOCK_DGRAM, IP_IPPROTO_UDP);
#endif
    if (fd == IP_INVALID_SOCKET)
        goto cleanup;

    if_data_offset = 0;
    while (if_data_len > if_data_offset + sizeof(struct Ipnet_if_msghdr))
    {
        ifm = (struct Ipnet_if_msghdr *) &if_data[if_data_offset];
        if_data_offset += ifm->ifm_msglen;
        rtm = (struct Ipnet_rt_msghdr *)(void *)ifm;
        switch (rtm->rtm_type) {
			case IPNET_RTM_IFINFO:
				if (ifm->ifm_addrs & IPNET_RTA_IFP) {
					dl = (struct Ip_sockaddr_dl *)(void *)(ifm + 1);
					ipcom_memset(ifname,0,IP_IFNAMSIZ);
					ipcom_memcpy(ifname, dl->sdl_data,(Ip_size_t)dl->sdl_nlen);
					break; /* Got the name! */
				}
			default:
				continue; /* No name, continue */
        }        
        
#ifdef IPCOM_USE_INET
        if_data_offset += ipcom_create_ifaddrs_inet(fd,
                                                    ifname,
                                                    &if_data[if_data_offset],
                                                    if_data_len - if_data_offset,
                                                    ifm,
                                                    &tail);
#endif /* IPCOM_USE_INET */
#ifdef IPCOM_USE_INET6
        if_data_offset += ipcom_create_ifaddrs_inet6(fd,
                                                     ifname,
                                                     &if_data[if_data_offset],
                                                     if_data_len - if_data_offset,
                                                     ifm,
                                                     &tail);
#endif /* IPCOM_USE_INET6 */


    }

cleanup:
    if (fd != IP_INVALID_SOCKET)
        ipcom_socketclose(fd);
    ipcom_free(if_data);
    return 0;
}
示例#11
0
/*
 *===========================================================================
 *                    ipcom_cmd_sockperf_accept
 *===========================================================================
 * Description: Passive open of socket(s).
 * Parameters:
 * Returns:
 */
IP_STATIC void
ipcom_cmd_sockperf_accept(Ipcom_cmd_sockperf_t *cmd)
{
    Ip_fd            *s = cmd->sock_array;
    int               listen_sock;
    Ip_u32            accepted_sockets = 0;
    struct Ip_timeval start;
    struct Ip_timeval stop;
    int               on = 1;

    listen_sock = ipcom_socket(cmd->res->ai_family,
                               cmd->res->ai_socktype,
                               cmd->res->ai_protocol);

    if (listen_sock == IP_SOCKERR)
    {
        ipcom_printf("sockperf-a: Failed to create socket: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        goto cleanup;
    }


    if (ipcom_setsockopt(listen_sock,
                         IP_SOL_SOCKET,
                         IP_SO_REUSEADDR,
                         &on,
                         sizeof(on)) < 0)
    {
        ipcom_printf("sockperf-a: setsockopt IP_SO_REUSEADDR failed : %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        return;
    }

    if (ipcom_bind(listen_sock, cmd->res->ai_addr, cmd->res->ai_addrlen) < 0)
    {
        ipcom_printf("sockperf-a: Failed to bind: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        goto cleanup;
    }

    if (ipcom_listen(listen_sock, cmd->num_sock) < 0)
    {
        ipcom_printf("sockperf-a: Failed to listen: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        goto cleanup;
    }

    ipcom_printf("sockperf-a: listen on %s[%d]"IP_LF,
                 cmd->res->ai_canonname,
                 ip_ntohs(((struct Ip_sockaddr_in *)cmd->res->ai_addr)->sin_port));

    IP_FD_ZERO(&cmd->read_set);
    IP_FD_SET(listen_sock, &cmd->read_set);
    if (ipcom_socketselect(listen_sock + 1, &cmd->read_set, IP_NULL, IP_NULL, IP_NULL) != 1)
    {
        ipcom_printf("sockperf-a: Select failed for listen socket: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        goto cleanup;
    }

    ipcom_microtime(&start);
    for (;accepted_sockets < cmd->num_sock; accepted_sockets++)
    {
        s[accepted_sockets] = ipcom_accept(listen_sock, IP_NULL, IP_NULL);
        if (s[accepted_sockets] == IP_SOCKERR)
        {
            ipcom_printf("sockperf-a: Failed to create socket: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
            goto cleanup;
        }
        if (ipcom_setsockopt(s[accepted_sockets],
                             IP_SOL_SOCKET,
                             IP_SO_LINGER,
                             &cmd->linger,
                             sizeof(cmd->linger)) < 0)
        {
            ipcom_printf("sockperf-a: setsockopt SO_LINGER failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            goto cleanup;
        }
    }
    ipcom_microtime(&stop);
    ipcom_printf("sockperf-a: %ld sockets accepted in %ld ms"IP_LF,
                 accepted_sockets,
                 ipcom_cmd_sockperf_tv_to_msec(&start, &stop));

    ipcom_cmd_sockperf_run(cmd);

 cleanup:
    if (listen_sock >= 0)
        (void)ipcom_socketclose(listen_sock);
    while (accepted_sockets-- > 0)
        (void)ipcom_socketclose(s[accepted_sockets]);
}
/*
 *===========================================================================
 *                      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;
}
/*
 *===========================================================================
 *                    ipnet_boot_config
 *===========================================================================
 * Description: Adds the initial configuration to the stack.
 * Parameters:
 * Returns:
 *
 */
IP_GLOBAL int
ipnet_boot_config()
{
    const char *key;
    const char *ifname = IP_NULL;
    int         begin_index;
    int         end_index;
    int         err = 0;
    Ip_fd       fd;

#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)
    {
        IP_PANIC2();
        err = -ipcom_errno;
        goto leave;
    }

    /* Configure interfaces. */
    begin_index = 0;
    while (ipnet_conf_interfaces[begin_index] != IP_NULL)
    {
        end_index = begin_index;
        while (ipnet_conf_interfaces[end_index] != IP_NULL)
        {
            key = ipcom_strstr((const char *)ipnet_conf_interfaces[end_index], "ifname");
            if (key != IP_NULL)
            {
                ifname = key + 6;
                while(*ifname && (*ifname == ' ' || *ifname == '\t'))
                    ifname++;
            }
            end_index++;
        }
        ip_assert(ifname != IP_NULL);
        err = ipnet_config_interface(fd,
                                     (char *)ifname,
                                     (char **) &ipnet_conf_interfaces[begin_index],
                                     end_index - begin_index,
                                     1);
        if (err >= 0)
        {
            /* Run all pending ioctls since the addresses are not added until that is done
               which means that adding of gateway will fail since it cannot be reached */
            err = ipnet_config_interface(fd,
                                         (char *)ifname,
                                         (char **) &ipnet_conf_interfaces[begin_index],
                                         end_index - begin_index,
                                         2);
        }
#if defined (WRS_IPNET)
        if (err >= 0 && ipnet_qc_unif_config_hook != IP_NULL)
        {
	    err = ipnet_qc_unif_config_hook (ifname);
        }
#endif /* defined (WRS_IPNET) */
        if (err < 0)
        {
            IP_PANIC2();
            goto leave;
        }
        begin_index = end_index + 1;
    }

    /* Run boot configuration commands. */
    for (begin_index = 0; ipnet_conf_boot_cmd[begin_index] != IP_NULL; begin_index++)
    {
        err = ipnet_config_run_boot_cmd(ipnet_conf_boot_cmd[begin_index]);
        if (err < 0)
        {
            IPCOM_LOG1(ERR, "Configuration failed to run '%s'", ipnet_conf_boot_cmd[begin_index]);
            IP_PANIC2();
            goto leave;
        }
    }

 leave:
    if (fd != IP_INVALID_SOCKET)
        (void)ipcom_socketclose(fd);
    return err;
}
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_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_cmd_qc
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipnet_cmd_qc(int argc, char **argv)
{
    Ipnet_cmd_qc cmd;
    int          ret;

    ipcom_memset(&cmd, 0, sizeof(cmd));
    cmd.argc = argc;
    cmd.argv = argv;
    ipnet_cmd_qc_next_arg(&cmd);

#ifdef IPCOM_USE_INET
    cmd.fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
#else
    cmd.fd = ipcom_socket(IP_AF_INET6, IP_SOCK_DGRAM, 0);
#endif
    if (cmd.fd == IP_SOCKERR)
    {
        IP_PANIC2();
        goto errout;
    }

    if (cmd.argc == 0)
    {
        ipnet_cmd_qc_print_usage();
        goto errout;
    }

    do
    {
        ret = 0;
        if (ipcom_strcmp(*cmd.argv, "-V") == 0)
        {
            int val;

            ipnet_cmd_qc_next_arg(&cmd);
            if (cmd.argc == 0)
            {
                ipnet_cmd_qc_print_usage();
                goto errout;
            }

            val = ipcom_atoi(*cmd.argv);
            ipnet_cmd_qc_next_arg(&cmd);

            ret = ipcom_setsockopt(cmd.fd, IP_SOL_SOCKET, IP_SO_X_VR, &val, sizeof(val));
            if (ret < 0)
            {
                ipcom_printf("ipcom_setsockopt() IP_SO_X_VR ");
                goto errout;
            }
            ret = 1;
        }

        if (ipcom_strcmp(*cmd.argv, "-silent") == 0)
        {
            cmd.silent = IP_TRUE;
            ipnet_cmd_qc_next_arg(&cmd);
            ret = 1;
        }
    } while (ret);

    if (ipnet_cmd_qc_parse_op(&cmd) < 0)
        goto errout;
    if (ipnet_cmd_qc_parse_dev(&cmd) < 0)
        goto errout;
    if (ipnet_cmd_qc_parse_parent(&cmd) < 0)
        goto errout;
    if (ipnet_cmd_qc_parse_id(&cmd) < 0)
        goto errout;

    ret = cmd.cmd_op(&cmd);
 leave:
    if (cmd.fd != IP_INVALID_SOCKET)
        (void)ipcom_socketclose(cmd.fd);
    return ret;

 errout:
    ret = -1;
    goto leave;
}