/*
 *===========================================================================
 *                    ipnet_cmd_qc_parse_bit_string
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC Ip_bool
ipnet_cmd_qc_parse_bit_string(const char *bit_str, Ip_u32 *pattern, Ip_u8 *pattern_len)
{
    char *ctx;
    char *bit;
    char *dup_bit_str = ipcom_strdup(bit_str);

    if (dup_bit_str == IP_NULL)
    {
        ipcom_printf("Failed to duplicate string '%s'"IP_LF, bit_str);
        return IP_FALSE;
    }

    *pattern = 0;
    *pattern_len = 0;
    bit = ipcom_strtok_r(dup_bit_str, ",", &ctx);
    if (bit == IP_NULL)
    {
        ipcom_free(dup_bit_str);
        ipcom_printf("Invalid format of the pattern, must be a comma separated list of 0 and 1"IP_LF);
        return IP_FALSE;
    }

    while (bit != IP_NULL)
    {
        if (ipcom_atoi(bit))
            IP_BIT_SET(*pattern, 1 << *pattern_len);
        ++*pattern_len;
        bit = ipcom_strtok_r(IP_NULL, ",", &ctx);
    }

    ipcom_free(dup_bit_str);
    return IP_TRUE;
}
/*
 *===========================================================================
 *                         ipsecctrl_set
 *===========================================================================
 */
static int
ipsecctrl_set(Argvars *vars)
{
    int     i;
    Ip_tag  tags[3];

    if (vars->argc != 4)
    {
        ipcom_printf("usage: > ipsecctrl set <name> <integer value>"IP_LF);
        return -1;
    }

    for (i = 0; params[i].name != IP_NULL; i++)
        if (ipcom_strcmp(vars->argv[2], params[i].name) == 0)
        {
            tags[0] = params[i].set;
            tags[1] = ipcom_atoi(vars->argv[3]);
            tags[2] = IP_TAG_END;
            ipipsec_conf(tags);
            ipcom_printf("ipsecctrl: %s set to %d"IP_LF, params[i].name, tags[1]);
            return 0;
        }

    ipcom_printf("ipsecctrl set: '%s' not found"IP_LF, vars->argv[2]);
    return -1;
}
/*
 *===========================================================================
 *                      ipnet_cmd_qc_parse_parent
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_cmd_qc_parse_parent(Ipnet_cmd_qc *p)
{
    p->p.ifq.ifq_parent_id = IP_IFQ_ID_NONE;

    if (p->argc < 1)
        return 0;

    if (ipcom_strcmp(*p->argv, "root") == 0)
    {
        ipnet_cmd_qc_next_arg(p);
        return 0;
    }

    if (ipcom_strcmp(*p->argv, "parent") == 0)
    {
        ipnet_cmd_qc_next_arg(p);
        if (p->argc < 1)
        {
            ipcom_printf("Expected [ root | parent <q-id> ]"IP_LF);
            return -1;
        }
        p->p.ifq.ifq_parent_id = ipcom_atoi(*p->argv);
        ipnet_cmd_qc_next_arg(p);
    }
    return 0;
}
/*
 *===========================================================================
 *                    ipcom_sysvar_get_as_int
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_PUBLIC int
ipcom_sysvar_get_as_int(const char *name, int default_value)
{
    char strval[16];
    Ip_size_t strval_len = sizeof(strval);

    if (ipcom_sysvar_get(name, strval, &strval_len) == IP_NULL)
        return default_value;

    return ipcom_atoi(strval);
}
/*
 *===========================================================================
 *                    ipcom_getenv_as_int
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipcom_getenv_as_int(const char *name, int default_value)
{
    char *env;

    env = ipcom_getenv(name);
    if (env != IP_NULL)
        return ipcom_atoi(env);
    else
        return default_value;
}
/*
 *===========================================================================
 *                    ipcom_sysvar_get_conf_as_int
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:      Integer config value stored under 'name' or -1 if not found.
 */
IP_PUBLIC int
ipcom_sysvar_get_conf_as_int(const char *name,
                             const char *username, const char *ifname)
{
    char strval[16];
    Ip_size_t strval_len = sizeof(strval);

    if (ipcom_sysvar_get_conf(name, strval, &strval_len,
                              username, ifname) == IP_NULL)
        return -1;

    return ipcom_atoi(strval);
}
/*
 *===========================================================================
 *                      ipnet_cmd_qc_parse_id
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_cmd_qc_parse_id(Ipnet_cmd_qc *p)
{
    p->p.ifq.ifq_id = (p->cmd_op == ipnet_cmd_qc_show_queue
                       ? IP_IFQ_ID_NONE
                       : IP_IFQ_ID_DEFAULT);

    if (p->argc < 2 || ipcom_strcmp(*p->argv, "handle") != 0)
        return 0;

    ipnet_cmd_qc_next_arg(p);
    p->p.ifq.ifq_id = ipcom_atoi(*p->argv);
    ipnet_cmd_qc_next_arg(p);
    return 0;
}
Esempio n. 8
0
/*
 *===========================================================================
 *                    ipcom_sysvar_get_descriptive_int0
 *===========================================================================
 * Description: Returns the value of a specific sysvar as an integer.
 * Parameters:  name - name of the sysvar
 *              default_value - the value that will be loaded into "value"
 *                              if sysvar "name" does not exists.
 *              value - points to the location where the integer will be
 *                      stored
 *              map - mapping from a name to an integer value or IP_NULL
 * Returns:     -1 = sysvar "name" does not exist
 *               0 = value was given by mapping name to integer via "map"
 *               1 = value was given by transforming the string value to
 *                   its corresponding integer value via ipcom_atoi().
 */
IP_PUBLIC int
ipcom_sysvar_get_descriptive_int0(const char *name,
                                  int default_value,
                                  int *value,
                                  const Ipcom_cmd_int_str_map *map)
{
    char      strval[32];
    Ip_size_t strval_len = sizeof(strval);

    *value = default_value;
    if (ipcom_sysvar_get0(name, strval, &strval_len) == IP_NULL)
        return -1;

    if (map != IP_NULL)
        if (ipcom_cmd_str_to_key2(map, strval, value) == 0)
            return 0;

    *value = ipcom_atoi(strval);
    return 1;
}
/*
 *===========================================================================
 *                    ipnet_cmd_sysctl_ival
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC Ip_bool
ipnet_cmd_sysctl_ival(Ip_bool        set,
                      int            *name,
                      int            namelen,
                      char           **value)
{
    if (set)
    {
        int val = ipcom_atoi(*value);
        return ipnet_cmd_sysctl_set(name, namelen, &val, sizeof(val));
    }
    else
    {
        int ival;
        if (!ipnet_cmd_sysctl_getint(name, namelen, &ival))
            return IP_FALSE;

        /* Create string representation */
        ipcom_snprintf(*value, IPNET_CMD_SYSCTL_VALUE_SIZE, "%d", ival);
    }

    return IP_TRUE;
}
Esempio n. 10
0
/*
 *===========================================================================
 *                    ipcom_cmd_ipd
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_PUBLIC int
ipcom_cmd_ipd(int argc, char **argv)
{
    Ipcom_getopt   opt;
    int            i, c, msgtype;
    Ip_err         err = IPCOM_SUCCESS;
#if IPCOM_VR_MAX > 1
    int            vr = ipcom_proc_vr_get();
    int            vr_new = vr;
#endif

    if (argc < 2)
    {
usage:
        ipcom_fprintf(ip_stderr,
                      "Interpeak daemon (IPD) command, version 1.2"IP_LF
                      "usage:  "IP_LF
                      "   ipd [-V <vr>] list"IP_LF
                      "   ipd [-V <vr>] start <service>"IP_LF
                      "   ipd [-V <vr>] kill <service>"IP_LF
                      "   ipd [-V <vr>] reconfigure <service>"IP_LF
                      "   ipd [-V <vr>] <#> <service>"IP_LF
                      IP_LF);
        return 0;
    }

    ipcom_getopt_clear_r(&opt);
    while ((c = ipcom_getopt_r(argc, argv, "V:", &opt)) != -1)
    {
        switch(c)
        {
        case 'V':
#if IPCOM_VR_MAX > 1
            vr_new = ipcom_atoi(opt.optarg);
#endif
            break;
        default:
            ipcom_printf("ipd: unknown option %c"IP_LF, (char)c);
            return -1;
        }
    }

    if (opt.optind >= argc)
    {
        ipcom_printf("ipd: missing <command> argument"IP_LF);
        goto usage;
    }


    if(ipcom_strcmp(argv[opt.optind], "list") == 0)
    {
#if IPCOM_VR_MAX > 1
        if (vr != vr_new)
            ipcom_proc_vr_set(vr_new);
#endif
        ipcom_printf("Services:"IP_LF);
        for (i = 0; ipcom_ipd_products[i].name != IP_NULL; i++)
        {
            if ((argc - (opt.optind + 1)) > 0)
            {
                int p;
                for (p = opt.optind + 1; p < argc; p++)
                {
                    if (ipcom_strcasecmp(ipcom_ipd_products[i].name, argv[p]) == 0)
                        goto print_service;
                }
                continue;
            }

print_service:
            if (IP_BIT_ISSET(ipcom_ipd_products[i].flags, IPCOM_IPD_FLAG_IPD_START))
            {
#ifdef IP_PORT_OSE5
                if (ipcom_ipd_products[i].start == IP_NULL
                    && ipcom_ipd_isinstalled_ose5(ipcom_ipd_products[i].name) != IPCOM_SUCCESS)
                    continue;
#endif
                err = ipcom_ipd_send(ipcom_ipd_products[i].name, IPCOM_IPD_MSGTYPE_PING);
                ipcom_printf("%-20s %-s"IP_LF,
                             ipcom_ipd_products[i].name,
                             err == IPCOM_SUCCESS ? "started" : "killed");
            }
            else if (ipcom_ipd_products[i].start)
                ipcom_printf("%-20s %-s"IP_LF,
                             ipcom_ipd_products[i].name, "started");

        }
        ipcom_printf(IP_LF);
#if IPCOM_VR_MAX > 1
        if (vr != vr_new)
            ipcom_proc_vr_set(vr);
#endif
        return 0;
    }

    if ((argc - opt.optind) < 2)
    {
        ipcom_printf("ipd: missing <service> argument"IP_LF);
        return -1;
    }

    for (i = 0; ipcom_cmd_ipd_messages[i].name; i++)
        if (ipcom_strcmp(argv[opt.optind], ipcom_cmd_ipd_messages[i].name) == 0)
        {
            msgtype = ipcom_cmd_ipd_messages[i].msgtype;
            goto sendmsg;
        }

    if (*argv[opt.optind] == '-' && ipcom_isdigit(argv[opt.optind][1]))
    {
        /* "UNIX" signal support (using negative numbers) */
        msgtype = -ipcom_atoi(argv[opt.optind] + 1);
        goto sendmsg;
    }

    if (ipcom_isdigit(argv[opt.optind][0]))
    {
        /* positive numbers */
        msgtype = ipcom_atoi(argv[1]);
        goto sendmsg;
    }

    /* unknown command. */
    ipcom_printf ("ipd: unknown command '%s'"IP_LF, argv[opt.optind]);
    return -1;

    /* send msg */
 sendmsg:
#if IPCOM_VR_MAX > 1
    if (vr != vr_new)
        ipcom_proc_vr_set(vr_new);
#endif


    if ((argc - opt.optind) < 3)
        err = ipcom_ipd_send(argv[opt.optind+1], msgtype);
    else
    {
        Ipcom_ipd_msg   *msg;
        int             sz  = ipcom_strlen(argv[opt.optind + 2]) + 1;

        msg = ipcom_calloc(1, sz + sizeof(*msg));
        if (msg != IP_NULL)
        {
            msg->msgtype = msgtype;
            ipcom_memcpy(msg + 1, argv[opt.optind + 2], sz);
            err = ipcom_ipd_sendmsg(argv[opt.optind+1], msg, sz + sizeof(*msg));
            ipcom_free(msg);
        }
    }

    if(err == IPCOM_SUCCESS)
        ipcom_printf("ipd: %s %s ok"IP_LF, argv[opt.optind], argv[opt.optind+1]);
    else
        ipcom_printf("ipd: %s %s failed: %s"IP_LF, argv[opt.optind], argv[opt.optind+1], ipcom_err_string(err));

#if IPCOM_VR_MAX > 1
    if (vr != vr_new)
        ipcom_proc_vr_set(vr);
#endif
    return 0;
}
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;
}
/*
 *===========================================================================
 *                         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;
}
Esempio n. 13
0
/*
 *===========================================================================
 *                    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;
}
Esempio n. 14
0
/*
 *===========================================================================
 *                    ipcom_cmd_sockperf_run
 *===========================================================================
 * Description: Sends/receives data.
 * Parameters:
 * Returns:
 */
IP_STATIC void
ipcom_cmd_sockperf_run(Ipcom_cmd_sockperf_t *cmd)
{
    struct Ip_timeval  tmo = { 0, 0 };
    struct Ip_timeval *ptmo;
    struct Ip_timeval  start;
    struct Ip_timeval  stop;
    Ip_u32             i;
    Ip_u32             c;
    int                num_ready;
    Ip_fd             *s = cmd->sock_array;
    Ip_u32             total_bytes_to_send = cmd->num_buf * cmd->buf_len;
    Ip_u32             finished_sockets = 0;
    Ip_u32             total_bytes_read = 0;
    Ip_ssize_t         bytes;
    Ip_fd_set          read_set;
    int                send_flags = (cmd->transmit && cmd->receive) ? IP_MSG_DONTWAIT : 0;

    if (cmd->transmit)
        ipcom_printf("sockperf-t: send buffer is %u"IP_LF, cmd->sendbuf_size);
    if (cmd->receive)
        ipcom_printf("sockperf-r: receive buffer is %u"IP_LF, cmd->sendbuf_size);
    for (i = 0; i < cmd->num_sock; i++)
    {
        int on = 1;

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

        if (ipcom_setsockopt(s[i],
                             IP_SOL_SOCKET,
                             IP_SO_SNDBUF,
                             &cmd->sendbuf_size,
                             sizeof(cmd->sendbuf_size)) < 0)
        {
            ipcom_printf("sockperf-c: setsockopt IP_SO_SNDBUF failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            return;
        }

        if (ipcom_setsockopt(s[i],
                             IP_SOL_SOCKET,
                             IP_SO_RCVBUF,
                             &cmd->recvbuf_size,
                             sizeof(cmd->recvbuf_size)) < 0)
        {
            ipcom_printf("sockperf-c: setsockopt IP_SO_SNDBUF failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            return;
        }
    }


    if (cmd->receive)
    {
        IP_FD_ZERO(&cmd->read_set);
        cmd->width = s[0];
        IP_FD_SET(s[0], &cmd->read_set);
        for (i = 1; i < cmd->num_sock; i++)
            if (s[i] != IP_INVALID_SOCKET)
            {
                cmd->width = IP_MAX(cmd->width, s[i]);
                IP_FD_SET(s[i], &cmd->read_set);
            }
    }

    ipcom_microtime(&start);
    while ((cmd->transmit && total_bytes_to_send)
           || (cmd->receive && finished_sockets < cmd->num_sock))
    {
        if (cmd->transmit && total_bytes_to_send)
        {
            for (i = 0; i < cmd->num_sock; i++)
            {
                if (cmd->testpattern)
                {
                    /* Test patter is "[B|E|D]xxxxxx ", B = first 8 byte in buffer, E = last 8 bytes, D = all other */
                    for (c = 0; c < cmd->buf_len; c += 8)
                        ipcom_sprintf(cmd->buf + c, "%c%06ld ",
                                      c == 0 ? '>' : (c >= cmd->buf_len - 8 ? '<' : '#'),
                                      cmd->send_pattern[i]++ % 1000000);
                }

                bytes = ipcom_send(s[i],
                                   cmd->buf,
                                   IP_MIN(cmd->buf_len, total_bytes_to_send),
                                   send_flags);
                if (bytes < 0 && ipcom_errno == IP_ERRNO_EWOULDBLOCK)
                    (void)ipcom_sleep(0);
                else
                {
                    if (bytes < 0)
                    {
                        ipcom_printf("sockperf-t: send failed : %s"IP_LF,
                                     ipcom_strerror(ipcom_errno));
                        return;
                    }
                    total_bytes_to_send -= bytes;
                }
            }

            if (cmd->receive && total_bytes_to_send == 0)
                for (i = 0; i < cmd->num_sock; i++)
                    if (ipcom_shutdown(s[i], IP_SHUT_WR) < 0)
                    {
                        ipcom_printf("sockperf-t: shutdown failed: %s"IP_LF,
                                     ipcom_strerror(ipcom_errno));
                        return;
                    }
        }

        if (cmd->receive)
        {
            ptmo = IP_NULL;
            while (finished_sockets < cmd->num_sock)
            {
                read_set = cmd->read_set;
                num_ready = ipcom_socketselect(cmd->width + 1, &read_set, IP_NULL, IP_NULL, ptmo);

                if (num_ready == 0)
                    break;

                if (num_ready < 0)
                {
                    ipcom_printf("sockperf-r: select failed: %s"IP_LF,
                                 ipcom_strerror(ipcom_errno));
                    return;
                }

                for (i = 0; i < cmd->num_sock; i++)
                {
                    if (IP_FD_ISSET(s[i], &read_set))
                    {
                        bytes = ipcom_recv(s[i], cmd->buf, cmd->buf_len, 0);
                        if (bytes < 0)
                        {
                            ipcom_printf("sockperf-r: recv failed: %s"IP_LF,
                                         ipcom_strerror(ipcom_errno));
                            return;
                        }

                        if (cmd->testpattern)
                        {
                            if (cmd->echo)
                                ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, cmd->recv_pattern[i]);
                            for (c = 0; c < (Ip_u32)bytes; c += 8)
                            {
                                if (cmd->buf[c] != '#' && cmd->buf[c] != '>' && cmd->buf[c] != '<')
                                {
                                    ipcom_printf("\nsockperf-r: test pattern error, expected B, D or E found %c(%d) offset %ld"IP_LF,
                                                 cmd->buf[c], (int)cmd->buf[c], c);
                                    ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, 0);
                                    return;
                                }

                                if (ipcom_atoi(cmd->buf + c + 1) != (int)(cmd->recv_pattern[i]++ % 1000000))
                                {
                                    ipcom_printf("\nsockperf-r: test pattern error, was %d should be %ld offset %ld"IP_LF,
                                                 ipcom_atoi(cmd->buf + c + 1), (cmd->recv_pattern[i] - 1) % 1000000, c);
                                    ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, 0);
                                    return;
                                }
                            }
                        }

                        if (bytes > 0)
                            total_bytes_read += bytes;
                        else
                        {
                            finished_sockets++;
                            IP_FD_CLR(s[i], &cmd->read_set);
                        }
                    }
                }

                if (cmd->transmit && total_bytes_to_send)
                    ptmo = &tmo;
            }
        }
    }
    ipcom_microtime(&stop);

    if (cmd->transmit)
        ipcom_printf("sockperf-t: %lu bytes sent in %ld ms (%lu kbyte/s)"IP_LF,
                     cmd->num_buf * cmd->buf_len,
                     ipcom_cmd_sockperf_tv_to_msec(&start, &stop),
                     cmd->num_buf * cmd->buf_len / (Ip_u32)ipcom_cmd_sockperf_tv_to_msec(&start, &stop) * 1000 / 1024);
    if (cmd->receive)
        ipcom_printf("sockperf-r: %lu bytes read in %ld ms (%lu kbyte/s)"IP_LF,
                     total_bytes_read,
                     ipcom_cmd_sockperf_tv_to_msec(&start, &stop),
                     total_bytes_read / (Ip_u32)ipcom_cmd_sockperf_tv_to_msec(&start, &stop) * 1000 / 1024);

}
/*
 *===========================================================================
 *                      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;
}