/*
 *===========================================================================
 *                    ipnet_netlink_register_ops
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_GLOBAL void
ipnet_rtnetlink_register_family_event(int                             family,
                                      int                             cmd,
                                      Ip_size_t                       maxattr,
                                      Ip_size_t                       min_size,
                                      Ipnet_rtnetlink_do_t            doit,
                                      Ipnet_netlink_dump_t           dumpit)
{
    Ipnet_rtnetlink_table_t   *table;

    /**/
    if (ipnet->rtnetlink_links[family] == IP_NULL)
    {
        ipnet->rtnetlink_links[family] = ipcom_calloc(IP_RTM_NR_MSGTYPES, sizeof(Ipnet_rtnetlink_table_t *));
        ip_assert(ipnet->rtnetlink_links[family] != IP_NULL);
    }

    ip_assert(ipnet->rtnetlink_links[family][cmd - IP_RTM_BASE] == IP_NULL);

    ipnet->rtnetlink_links[family][cmd - IP_RTM_BASE] = ipcom_calloc(1, sizeof(Ipnet_rtnetlink_table_t));

    ip_assert(ipnet->rtnetlink_links[family][cmd - IP_RTM_BASE] != IP_NULL);

    table = ipnet->rtnetlink_links[family][cmd - IP_RTM_BASE];

    table->nl_cmd                       = cmd;
    table->nl_func_table.nl_rta_max     = maxattr;
    table->nl_func_table.nl_size_min    = IP_NLMSG_LENGTH(min_size);
    table->nl_func_table.nl_do          = doit;
    table->nl_func_table.nl_dump        = dumpit;
}
/*
 *===========================================================================
 *                      ipnet_pkt_queue_mbc_configure
 *===========================================================================
 * Description: Configures a queue with new parameters.
 * Parameters:  q - A packet queue.
 *              m - The queue parameters.
 * Returns:     0  = success
 *              <0 = error code
 */
IP_STATIC int
ipnet_pkt_queue_mbc_configure(Ipnet_pkt_queue_mbc *q, struct Ipnet_ifqueue_mbc *m)
{
    Ip_u32 band;

    if (q->number_of_bands)
    {
        IPCOM_LOG0(ERR, "MBC configure: Can only be configured once");
        return -IP_ERRNO_EINVAL;
    }

    if (m->mbc_bands < 2 || m->mbc_bands > IPNET_IFQ_CONTAINER_MAX_COUNT)
    {
        IPCOM_LOG1(ERR,
                   "MBC configure: Number of priority bands must be between 2 and %d",
                   IPNET_IFQ_CONTAINER_MAX_COUNT);
        return -IP_ERRNO_EINVAL;
    }

    if (m->mbc_bands <= m->mbc_default_band)
    {
        IPCOM_LOG1(ERR, "MBC configure: invalid default band, must be [0..%d]",
                   m->mbc_bands - 1);
        return -IP_ERRNO_EINVAL;
    }

    q->bands = ipcom_calloc(m->mbc_bands, sizeof(Ipnet_pkt_queue *));
    if (q->bands == IP_NULL)
    {
        IPCOM_LOG0(CRIT, "MBC configure: out of memory");
        return -IP_ERRNO_ENOMEM;
    }

    q->number_of_bands = m->mbc_bands;
    q->default_band    = m->mbc_default_band;

    for (band = 0; band < q->number_of_bands; band++)
    {
        int                    ret;

        ret = ipnet_pkt_queue_mbc_insert_default_queue(q, band);
        if (ret < 0)
        {
            IPCOM_LOG1(ERR, "MBC configure: Failed to create default queue: %s",
                       ipcom_strerror(-ret));
            return ret;
        }
    }

    return 0;
}
/*
 *===========================================================================
 *                    ipcom_create_ifaddrs_entry
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC struct Ip_ifaddrs *
ipcom_create_ifaddrs_entry(const char                *ifname,
                           struct Ipnet_if_msghdr    *ifm,
                           struct Ipnet_ifa_msghdr   *ifa,
                           struct Ip_sockaddr        **addrs)
{
    /**/
    struct Ip_ifaddrs        *nifa = ipcom_calloc(1, sizeof(*nifa));

    if (nifa == IP_NULL)
        return IP_NULL;

    /* Interface name */
    nifa->ifa_name = ipcom_strdup(ifname);
    if(nifa->ifa_name == IP_NULL)
        goto fail;

    /* Interface flags */
    nifa->ifa_flags = ifm->ifm_flags;

    /* Interface address */
    nifa->ifa_addr = ipcom_malloc(sizeof(union Ip_sockaddr_union));
    if(nifa->ifa_addr == IP_NULL)
        goto fail;

    ipcom_memcpy(nifa->ifa_addr, addrs[IPNET_RTAX_IFA], IPCOM_SA_LEN_GET(addrs[IPNET_RTAX_IFA]));

    nifa->ifa_netmask = ipcom_malloc(sizeof(union Ip_sockaddr_union));
    if(nifa->ifa_netmask == IP_NULL)
        goto fail;

    ipcom_memcpy(nifa->ifa_netmask, addrs[IPNET_RTAX_NETMASK], IPCOM_SA_LEN_GET(addrs[IPNET_RTAX_IFA]));


    if (IP_BIT_ISSET(ifa->ifam_addrs, IPNET_RTA_BRD))
    {
        nifa->ifa_broadaddr = ipcom_malloc(sizeof(union Ip_sockaddr_union));
        if(nifa->ifa_broadaddr == IP_NULL)
            goto fail;

        ipcom_memcpy(nifa->ifa_broadaddr, addrs[IPNET_RTAX_BRD], IPCOM_SA_LEN_GET(addrs[IPNET_RTAX_BRD]));
    }

    return nifa;

fail:
    ipcom_ifaddrs_free(nifa);
    return IP_NULL;
}
/*
 *===========================================================================
 *                    ipnet_sock_sockdev_register
 *===========================================================================
 * Description: Registers the IP_AF_SOCKDEV domain.
 * Parameters:
 * Returns:     0 = success, <0 = error code.
 *
 */
IP_GLOBAL int
ipnet_sock_sockdev_register(void)
{
    Ipnet_sock_ops *ops;

    ops = ipcom_calloc(1, sizeof(*ops));
    if (ops == IP_NULL)
    {
        IPCOM_LOG0(CRIT, "Could not register the IP_AF_SOCKDEV domain, out of memory");
        IP_PANIC();
        return -IP_ERRNO_ENOMEM;
    }

    ops->domain     = IP_AF_SOCKDEV;
    ops->type       = IP_SOCK_RAW;
    ops->proto      = -1;
    ops->destroy    = ipnet_sockdev_destroy;
    ops->init       = ipnet_sockdev_init;
    ops->recv       = ipnet_sock_pkt_recv;
    ops->send       = ipnet_sockdev_send;

    return ipnet_sock_register_ops(ops);
}
/*
 *===========================================================================
 *                    ipnet_gre_setup
 *===========================================================================
 * Description: Setup the GRE tunnel.
 * Parameters:  netif - A GRE tunnel interface.
 * Returns:     0 = success, <0 = error code.
 *
 */
IP_GLOBAL int
ipnet_gre_setup(Ipnet_netif *netif)
{
#ifdef IPNET_USE_RFC2890
    Ipnet_gre_t *gre;

    gre = netif->ipcom.pdrv = ipcom_calloc(1, sizeof(Ipnet_gre_t));
    if (gre == IP_NULL)
        goto errout;

    gre->reassembly_queue
        = ipcom_pqueue_new((Ipcom_pqueue_cmp_func) ipnet_gre_seq_cmp,
                           ipcom_pqueue_nop_store_index);

    return 0;
 errout:
    ipnet_gre_destroy(netif);
    IPCOM_LOG0(CRIT, "Failed to create GRE tunnel due to unsifficient memory");
    return -IP_ERRNO_ENOMEM;
#else
    IPCOM_UNUSED_ARG(netif);
    return 0;
#endif /* IPNET_USE_RFC2890 */
}
/*
 *===========================================================================
 *                    ipnet_rtnetlink_parse
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_GLOBAL int
ipnet_rtnetlink_parse(int                 maxattr,
                      struct Ip_rtattr    *attr,
                      Ip_size_t           attrlen,
                      struct Ip_rtattr    ***rtap)
{
    struct Ip_rtattr **rta = IP_NULL;

    if (maxattr == 0)
        attrlen = 0;
    else
    {
        rta = ipcom_calloc(sizeof(struct Ip_rtattr *), maxattr + 1);
        if (!rta)
            return -IP_ERRNO_ENOMEM;
    }

    while (IP_RTA_OK(attr, attrlen))
    {
        Ip_u16 flavor = attr->rta_type;
        if (flavor)
        {
            if (flavor > maxattr)
            {
                ipcom_free(rta);
                return -IP_ERRNO_EINVAL;
            }

            rta[flavor-1] = attr;
        }
        attr = IP_RTA_NEXT(attr, attrlen);
    }

    *rtap = rta;
    return 0;
}
Example #7
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;
}
Example #8
0
/*
 *===========================================================================
 *                    ipnet_sock_tcp_register
 *===========================================================================
 * Description: Registers the TCP protocol for IPv4 and/or IPv6.
 * Parameters:
 * Returns:     0 = success, <0 = error code.
 *
 */
IP_GLOBAL int
ipnet_sock_tcp_register(void)
{
    Ipnet_sock_tcp_ops *ops;
    int domains[] = {
#ifdef IPCOM_USE_INET
        IP_AF_INET,
#endif
#ifdef IPCOM_USE_INET6
        IP_AF_INET6,
#endif
    };
    int       protos[] = { 0, IP_IPPROTO_TCP };
    Ip_size_t p, d;
    int       ret;

    for (d = 0; d < sizeof(domains) / sizeof(domains[0]); d++)
        for (p = 0; p < sizeof(protos) / sizeof(protos[0]); p++)
        {
            ops = ipcom_calloc(1, sizeof(*ops));
            if (ops == IP_NULL)
            {
                IPCOM_LOG0(CRIT, "Could not register the TCP protocol, out of memory");
                IP_PANIC();
                return -IP_ERRNO_ENOMEM;
            }

            switch (domains[d])
            {
#ifdef IPCOM_USE_INET
            case IP_AF_INET:
                ipnet_sock_ip4_get_ops(&ops->inet);
                break;
#endif
#ifdef IPCOM_USE_INET6
            case IP_AF_INET6:
                ipnet_sock_ip6_get_ops(&ops->inet);
                break;
#endif
            default:
                break;
            }

            ops->network_bind                = ops->inet.network_bind;
            ops->inet.network_bind           = ipnet_sock_tcp_bind;

            ops->network_init                = ops->inet.sock.init;
            ops->inet.sock.init              = ipnet_sock_tcp_init;
            ops->network_destroy             = ops->inet.sock.destroy;
            ops->inet.sock.destroy           = ipnet_sock_tcp_destroy;
            ops->network_connect             = ops->inet.sock.connect;
            ops->inet.sock.connect           = ipnet_sock_tcp_connect;

            ops->inet.sock.type              = IP_SOCK_STREAM;
            ops->inet.sock.proto             = protos[p];
            ops->inet.sock.allow_async_send  = IP_TRUE;
            ops->inet.sock.accept            = iptcp_accept;
            ops->inet.sock.close             = iptcp_close;
            ops->inet.sock.listen            = iptcp_listen;
            ops->inet.sock.usr_recv          = ipnet_usr_sock_tcp_recv;
            ops->inet.sock.pkts_from_iov     = ipnet_usr_sock_tcp_pkts_from_iov;
            ops->inet.sock.send              = iptcp_send;
            ops->inet.sock.shutdown          = iptcp_shutdown;
            ops->inet.sock.getopt            = iptcp_getsockopt;
            ops->inet.sock.setopt            = iptcp_setsockopt;
            ops->inet.sock.ioctl             = iptcp_ioctl;
            ops->inet.sock.hdr_space        += IPTCP_TCP_HDR_SIZE;
            ops->inet.sock.extra_sock_space += sizeof(Iptcp_tcb);

            ret = ipnet_sock_register_ops(&ops->inet.sock);
            if (ret < 0)
                return ret;
        }
    return 0;
}
Example #9
0
/*
 *===========================================================================
 *                    ipcom_shellalias_remove
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipcom_shellalias_set(char   *name,
                     char   *cmd)
{
    struct Ipcom_shellalias_alias *alias;

    if (ipcom_strcmp(name, "alias") == 0 ||
        ipcom_strcmp(name, "unalias") == 0)
        return -IPCOM_ERR_INVALID_ARG;

    /* Remove any old references */
    ipcom_shellalias_remove(name);

    /* Allocate a new alias structure */
    alias = ipcom_calloc(1, sizeof(*alias));

    /* Could we allocate? */
    if (alias != IP_NULL)
    {
        Ip_err  retval;
        int     argc;
        char    **argv = IP_NULL;

        /* Allocate the name */
        alias->name = ipcom_strdup(name);
        if (alias->name == IP_NULL)
            goto fail;

        /* Allocate the command */
        alias->cmd  = ipcom_strdup(cmd);
        if (alias->cmd == IP_NULL)
            goto fail;

        /* Parse the string */
        retval = ipcom_parse_argstr(alias->cmd, (int *)&argc, &argv);
        switch(retval)
        {
        case IPCOM_SUCCESS:
            break;

        case IPCOM_ERR_INVALID_ARG:
            ipcom_printf("Unmatched string delimiters"IP_LF);
            goto fail;

        case IPCOM_ERR_FAILED:
        default:
            goto fail;
        }

        /* Store */
        alias->argv = argv;
        alias->argc = argc;

        /* Link the alias into the major list */
        ipcom_list_insert_first(&ipcom_shellalias_head, &alias->next);

        /* Success */
        return IPCOM_SUCCESS;
    }

    /* No memory */
    return -IP_ERRNO_ENOMEM;

fail:
    /* Did we manage to allocate the name? */
    if (alias->name != IP_NULL)
        ipcom_free(alias->name);

    /* Free the stored command */
    if (alias->cmd != IP_NULL)
        ipcom_free(alias->cmd);

    /* Free the vector */
    if (alias->argv != IP_NULL)
        ipcom_free(alias->argv);

    /* Free the structure */
    ipcom_free(alias);
    return -IP_ERRNO_ENOMEM;
}
Example #10
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;
}
Example #11
0
/*
 *===========================================================================
 *                    ipnet_sock_udp_register
 *===========================================================================
 * Description: Registers the UDP protocol for IPv4 and/or IPv6.
 * Parameters:
 * Returns:     0 = success, <0 = error code.
 *
 */
IP_GLOBAL int
ipnet_sock_udp_register(void)
{
    Ipnet_sock_udp_ops *ops;
    int domains[] = {
#ifdef IPCOM_USE_INET
        IP_AF_INET,
#endif
#ifdef IPCOM_USE_INET6
        IP_AF_INET6,
#endif
    };
    int       protos[] = { 0, IP_IPPROTO_UDP };
    Ip_size_t d, p;
    int       ret;

    for (d = 0; d < sizeof(domains) / sizeof(domains[0]); d++)
        for (p = 0; p < sizeof(protos) / sizeof(protos[0]); p++)
        {
            ops = ipcom_calloc(1, sizeof(*ops));
            if (ops == IP_NULL)
            {
                IPCOM_LOG0(CRIT, "Could not register the UDP protocol, out of memory");
                IP_PANIC();
                return -IP_ERRNO_ENOMEM;
            }

            switch (domains[d])
            {
#ifdef IPCOM_USE_INET
            case IP_AF_INET:
                ipnet_sock_ip4_get_ops(&ops->inet);
                break;
#endif
#ifdef IPCOM_USE_INET6
            case IP_AF_INET6:
                ipnet_sock_ip6_get_ops(&ops->inet);
                break;
#endif
            default:
                break;
            }

            ops->network_bind          = ops->inet.network_bind;
            ops->inet.network_bind     = ipnet_sock_udp_bind;

            ops->network_init          = ops->inet.sock.init;
            ops->network_connect       = ops->inet.sock.connect;
            ops->inet.sock.init        = ipnet_sock_udp_init;
            ops->inet.sock.connect     = ipnet_sock_udp_connect;

            ops->inet.sock.type        = IP_SOCK_DGRAM;
            ops->inet.sock.proto       = protos[p];
            ops->inet.sock.allow_async_send = IP_TRUE;
            ops->inet.sock.usr_recv    = ipnet_usr_sock_recvmsg;
            ops->inet.sock.send        = ipnet_sock_udp_send;
            ops->inet.sock.hdr_space  += IPNET_UDP_HDR_SIZE;

            ret = ipnet_sock_register_ops(&ops->inet.sock);
            if (ret < 0)
                return ret;
        }
    return 0;
}
IP_PUBLIC Ip_err
ipcom_sysvar_ext_setv(const Ipcom_sysvar_ext entries[], int flags)
{
    /* !!TODO: make atomic */
    int i;
    int len = 0;
    int  param_len = 0;
    char *sysvar_name = IP_NULL;
    char *sysvar_param = IP_NULL;
    char *conf = IP_NULL;
    char *last = IP_NULL;
    char *value = IP_NULL;
    char *ifparam = IP_NULL;
    Ip_err err = IPCOM_SUCCESS;

    sysvar_name = ipcom_calloc(1, sizeof(char) * 256);
    if (sysvar_name == IP_NULL)
        return IPCOM_ERR_NO_MEMORY;

    for (i = 0; ; i++)
    {
        /*
         * The syntax {IP_NULL,IP_NULL,IP_NULL} terminates the configuration
         * array. Otherwise, <name1> and/or <name2> must be specified.
         */
        if ((entries[i].name1 == IP_NULL) && (entries[i].name2 == IP_NULL))
        {
            err = (entries[i].param == IP_NULL) ? IPCOM_SUCCESS :
                  IPCOM_ERR_INVALID_CONFIG;
            goto done;
        }

        /*
         * The expected string should contain <ifparam>=<value>. If the
         * separator is not found, assume the string does not contain
         * any valid configuration values.
         */
        if (entries[i].param == IP_NULL ||
            ipcom_strchr(entries[i].param, '=') == IP_NULL)
            continue;

        len = ipcom_strlen(entries[i].param);
        if ((len > param_len) || (sysvar_param == IP_NULL))
        {
            if (sysvar_param)
                ipcom_free(sysvar_param);  /* free previously allocated mem */
            param_len = len;
            sysvar_param = ipcom_calloc(1, param_len+1);
            if (sysvar_param == IP_NULL)
            {
                ipcom_free(sysvar_name);
                return IPCOM_ERR_NO_MEMORY;
            }
        }
        else
            ipcom_memset(sysvar_param, 0, param_len+1);

        ipcom_strcpy(sysvar_param, entries[i].param);

        /*
         * Expected format: <ifparam1>=<value1>;<ifparam2>=<value2>;...
         */
        conf = ipcom_strtok_r(sysvar_param,
                              IPCOM_IFPARAM_LIST_DELIMITER, &last);
        if (conf == IP_NULL)
        {
            err = IPCOM_ERR_INVALID_CONFIG;
            goto done;
        }

        do {
            /* Expected format: <ifparam>=<value> */
            ifparam = ipcom_strtok_r(conf, IPCOM_IFPARAM_DELIMITER, &value);
            if ((ifparam == IP_NULL) || (value == IP_NULL))
            {
                err = IPCOM_ERR_INVALID_CONFIG;
                goto done;
            }

            ipcom_memset(sysvar_name, 0, sizeof(sysvar_name));
            if (entries[i].name1 != IP_NULL)
            {
                ipcom_strcpy(sysvar_name, entries[i].name1);
                ipcom_strcat(sysvar_name, ".");
            }
            ipcom_strcat(sysvar_name, ifparam);
            if (entries[i].name2 != IP_NULL)
            {
                ipcom_strcat(sysvar_name, ".");
                ipcom_strcat(sysvar_name, entries[i].name2);
            }
            err = ipcom_sysvar_set(sysvar_name, value, flags);
            if (err == IPCOM_ERR_DUPLICATE)
                err = IPCOM_SUCCESS;
            else if (err != IPCOM_SUCCESS)
                goto done;
        } while (IP_NULL != (conf = ipcom_strtok_r(IP_NULL,
                                                   IPCOM_IFPARAM_LIST_DELIMITER, &last)));
    }

done:
    ipcom_free(sysvar_name);
    if (sysvar_param)
        ipcom_free(sysvar_param);
    return err;
}