/*
 *===========================================================================
 *                    ipnet_sysctl_route_add_addr
 *===========================================================================
 * Description: Adds an address in route table format.
 * Parameters:  buf - the buffer to where the address should be written.
 *              domain - the domain this address is part of.
 *              rt_addr - a address or mask from the route table.
 * Returns:     The address to where the next data should be written in
 *              the buffer.
 *
 */
IP_STATIC void *
ipnet_sysctl_route_add_addr(void *buf, int domain, void *rt_addr)
{
    union Ip_sockaddr_union *addr;

    addr = (union Ip_sockaddr_union *) buf;
#ifdef IPCOM_USE_INET
    if (domain == IP_AF_INET)
    {
        struct Ipnet_ipv4_key *key = (struct Ipnet_ipv4_key *) rt_addr;

        ipcom_memset(addr, 0, sizeof(struct Ip_sockaddr_in));
        addr->sin.sin_family = IP_AF_INET;
        IPCOM_SA_LEN_SET(&addr->sin, sizeof(struct Ip_sockaddr_in));
        ipcom_memcpy(&addr->sin.sin_addr, &key->addr, sizeof(addr->sin.sin_addr));
    }
#endif /* IPCOM_USE_INET */
#ifdef IPCOM_USE_INET6
    if (domain == IP_AF_INET6)
    {
        struct Ipnet_ipv6_key *key = (struct Ipnet_ipv6_key *) rt_addr;

        ipcom_memset(addr, 0, sizeof(struct Ip_sockaddr_in6));
        addr->sin6.sin6_family = IP_AF_INET6;
        IPCOM_SA_LEN_SET(&addr->sin6, sizeof(struct Ip_sockaddr_in6));
        ipcom_memcpy(&addr->sin6.sin6_scope_id, &key->scope_id, sizeof(addr->sin6.sin6_scope_id));
        ipcom_memcpy(&addr->sin6.sin6_addr, &key->addr, sizeof(addr->sin6.sin6_addr));
    }
#endif /* IPCOM_USE_INET6 */

    return (Ip_u8 *) buf + IPCOM_SA_LEN_GET(&addr->sa);
}
Example #2
0
/*
 *===========================================================================
 *                    ipcom_heap_sort_downheap
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC void
ipcom_heap_sort_downheap(void *base, Ip_size_t elem_size, int root, int last,
                         Ipcom_heap_sort_cmp_func cmp_func, void *tmp)
{
    int new_r;
    int max_r = last >> 1;

    ipcom_memcpy(tmp,
                 IPCOM_HEAP_SORT_GET_ELEM(base, root, elem_size),
                 elem_size);

    while (root <= max_r)
    {
        new_r = root << 1;
        if (new_r < last
            && cmp_func(IPCOM_HEAP_SORT_GET_ELEM(base, new_r, elem_size),
                        IPCOM_HEAP_SORT_GET_ELEM(base, new_r + 1, elem_size)) < 0)
        {
            new_r++;
        }

        if (cmp_func(tmp, IPCOM_HEAP_SORT_GET_ELEM(base, new_r, elem_size)) >= 0)
            goto done;

        ipcom_memcpy(IPCOM_HEAP_SORT_GET_ELEM(base, root, elem_size),
                     IPCOM_HEAP_SORT_GET_ELEM(base, new_r, elem_size),
                     elem_size);
        root = new_r;
    }

 done:
    ipcom_memcpy(IPCOM_HEAP_SORT_GET_ELEM(base, root, elem_size),
                 tmp,
                 elem_size);
}
/*
 *===========================================================================
 *                    ipdnsc_hostent_convert
 *===========================================================================
 * Description: Converts a AF_INET hostent structure to a AF_INET6 hostent
 *              structure. ipv4 addresses are converted to ipv4 mapped ipv6
 *              addresses
 * Parameters:  he - pointer to the hostent structure to convert
 * Returns:     pointer to the new hostent structure or NULL if failed
 */
IP_STATIC struct Ip_hostent *
ipdnsc_hostent_convert(struct Ip_hostent *he)
{
    struct Ip_hostent *he_new;
    Ip_s32 num_alias, num_addr, i;
    Ip_u8 buf[16];
    Ip_u8 in6addr_mapped[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};


    /* Verify the supplied host entry */
    if (he->h_addrtype != IP_AF_INET || he->h_length != IPDNSC_INADDRSZ)
        return IP_NULL;

    /* Get the number of alias and address entries */
    num_alias = ipdnsc_hostent_alias_count(he);
    num_addr = ipdnsc_hostent_addr_count(he);

    /* Create the new host entry structure */
    he_new = ipdnsc_hostent_create(IP_AF_INET6);

    if (he_new == IP_NULL)
        return IP_NULL;

    /* Allocate memory for and copy the aliases */
    for (i=0; i<(num_alias-1); i++)
    {
        if (ipdnsc_hostent_insert_alias(he_new, he->h_aliases[i]))
        {
            goto err_out;
        }
    }

    /* Allocate memory for and copy the addresses */
    for (i=0; i<(num_addr-1); i++)
    {
        ipcom_memcpy(buf, in6addr_mapped, sizeof(in6addr_mapped));
        ipcom_memcpy(buf+sizeof(in6addr_mapped), he->h_addr_list[i], he->h_length);
        if (ipdnsc_hostent_insert_addr(he_new, (char *)buf))
        {
            goto err_out;
        }
    }

    /* Insert the hostname */
    if (ipdnsc_hostent_insert_name(he_new, he->h_name))
    {
        goto err_out;
    }

    return he_new;

err_out:
    ipdnsc_hostent_free(he_new);
    return IP_NULL;
}
IP_STATIC Ip_size_t
ipcom_create_ifaddrs_inet6(Ip_fd                    fd,
                           const char               *ifname,
                           Ip_u8                    *ifa_first,
                           Ip_size_t                buf_len,
                           struct Ipnet_if_msghdr   *ifm,
                           struct Ip_ifaddrs        ***tail)
{
    struct Ip_in6_aliasreq   ifareq;
    struct Ipnet_ifa_msghdr *ifa;
    struct Ip_sockaddr_in6  *addrs[IPNET_RTAX_MAX];
    Ip_size_t                offset = 0;

    offset = 0;
    while (offset < buf_len)
    {
        struct Ip_ifaddrs        *nifa;

        ifa = (struct Ipnet_ifa_msghdr *) &ifa_first[offset];
#if defined(IP_PORT_VXWORKS) && !defined(_WRS_KERNEL)
        ipnet_cmd_init_addrs_rtp(ifa + 1, ifa->ifam_addrs, (struct Ip_sockaddr **) addrs);
#else
        ipnet_cmd_init_addrs(ifa + 1, ifa->ifam_addrs, (struct Ip_sockaddr **) addrs);
#endif

        if (ifa->ifam_type != IPNET_RTM_NEWADDR || addrs[IPNET_RTAX_IFA]->sin6_family != IP_AF_INET6)
            break;

        offset += ifa->ifam_msglen;

        ipcom_memset(&ifareq, 0, sizeof(ifareq));
        ipcom_memcpy(ifareq.ifra_name, ifname, IP_IFNAMSIZ);
        ipcom_memcpy(&ifareq.ifra_addr, addrs[IPNET_RTAX_IFA], sizeof(ifareq.ifra_addr));
        (void)ipcom_socketioctl(fd, IP_SIOCXGIFADDR_IN6, &ifareq);

        if (IP_BIT_ISSET(ifareq.ifra_flags, IP_IN6_IFF_ANYCAST))
            continue;

        if (IP_IN6_IS_ADDR_MULTICAST(&addrs[IPNET_RTAX_IFA]->sin6_addr))
            continue;

        nifa = ipcom_create_ifaddrs_entry(ifname, ifm, ifa, (struct Ip_sockaddr **)addrs);
        if (nifa != IP_NULL)
        {
            **tail = nifa;
            *tail  = &nifa->ifa_next;
        }
    }

    return offset;
}
/*
 *===========================================================================
 *                    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;
}
Example #6
0
/*
 *===========================================================================
 *                    ipnet_nat_proxy_sip_callidstr
 *===========================================================================
 * Description: Extract the callid string
 * Parameters:  pdata - pointer to message.
 * Returns:     pointer to allocated buffer with callid string or
 *              IP_NULL if wrong format or out of memory.
 */
IP_STATIC char *
ipnet_nat_proxy_sip_callidstr(char *pmsg)
{
    char *pstart;
    char *pcallid;
    int   i;

    SIP_SKIP_SPACES(pmsg);

    pstart = pmsg;
    for (i = 0; i < 200; i++)
    {
        if (*pmsg != '\r')
            pmsg++;
        else
            break;
    }

    /* in case we have a wrong string format */
    if (i >= 200)
    {
        IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_callidstr() :: ERROR, wrong string format");
        return IP_NULL;
    }

    if ((pcallid = ipcom_malloc((pmsg - pstart) + 1)) == IP_NULL)
        return IP_NULL;

    ipcom_memcpy(pcallid, pstart, pmsg - pstart);
    *(pcallid + (pmsg - pstart)) = 0;

    IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_callidstr() :: callid=%s", pcallid);
    return pcallid;
}
Example #7
0
/*
 *===========================================================================
 *                    ipcom_inet6_rth_reverse
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipcom_inet6_rth_reverse(const void *in, void *out)
{
    Ip_pkt_ip6_rthdr   *rthdr = (Ip_pkt_ip6_rthdr *) in;
    struct Ip_in6_addr  temp_addr;
    struct Ip_in6_addr *addr1;
    struct Ip_in6_addr *addr2;
    int i;
    int segments;

    segments = ipcom_inet6_rth_segments(in);
    if (segments < 0)
        return -1;

    if (in != out)
    {
        ipcom_memcpy(out, in, (rthdr->ip6r_len + 1) * 8);
        return ipcom_inet6_rth_reverse(out, out);
    }

    for (i = 0; i < segments / 2; i++)
    {
        addr1 = ipcom_inet6_rth_getaddr(out, i);
        addr2 = ipcom_inet6_rth_getaddr(out, segments - i - 1);
        IPCOM_INET6_SET_ADDR(&temp_addr, addr1);
        IPCOM_INET6_SET_ADDR(addr1, addr2);
        IPCOM_INET6_SET_ADDR(addr2, &temp_addr);
    }
    return 0;
}
/*
 *===========================================================================
 *                    ipcom_drv_eth_filter_add_mcast_addr
 *===========================================================================
 * Description: Adds a multicast Ethernet address that should be passed
 *              by the filter.
 * Parameters:	filter - A filter to where the address should be added.
 *              eth_mcast_addr - The address to add.
 * Returns:	    0 = success, <0 = error code.
 *
 */
IP_PUBLIC int
ipcom_drv_eth_filter_add_mcast_addr(Ipcom_drv_eth_filter *filter,
                                    Ip_u8 eth_mcast_addr[IPCOM_DRV_ETH_ADDR_SIZE])
{
    int i;
    int insert = -1;

    for (i = IPCOM_DRV_ETH_MAX_MULTIADDR - 1; i >= 0 ; i--)
    {
        if (filter->ref[i] == 0)
            insert = i;
        else
        {
            if (ipcom_memcmp(eth_mcast_addr, filter->mcast_addr[i], IPCOM_DRV_ETH_ADDR_SIZE) == 0)
            {
                filter->ref[i]++;
                return 0;
            }
        }
    }

    if (insert < 0)
        /* Cannot join any more Ethernet multicast addresses */
        return -IP_ERRNO_ENOSPC;

    /* Add this multicast address */
    filter->ref[insert] = 1;
    ipcom_memcpy(filter->mcast_addr[insert], eth_mcast_addr, IPCOM_DRV_ETH_ADDR_SIZE);
    return 0;
}
Example #9
0
/*
 *===========================================================================
 *                    ipnet_nat_proxy_sip_modmsg
 *===========================================================================
 * Description: Modify message and adjust length
 * Parameters:  newdata    - pointer to new data
 *              newlen     - length of new data
 *              olddata    - pointer to old data
 *              oldlen     - length of old data
 *              ppend      - pointer to pointer to last byte of message
 * Returns:     0  = ok
 *              -1 = message too long
 */
IP_STATIC int
ipnet_nat_proxy_sip_modmsg(char *newdata, int newlen,
                           char *olddata, int oldlen,
                           char **ppend)
{
    char *pmax  = (char *)sipbuf + sizeof(sipbuf) - 1;
    int diff    = newlen - oldlen;
    int movelen = (*ppend  + 1) - (olddata + oldlen);

    ip_assert(movelen >= 0);
    if (pmax - *ppend < diff)
    {
        IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_modmsg() :: message to long");
        return -1;
    }

    /* Make space for new data */
    ipcom_memmove(olddata + newlen, olddata + oldlen, movelen);
    *ppend += diff;

    /* Copy in new data */
    ipcom_memcpy(olddata, newdata, newlen);

    return 0;
}
/*
 *===========================================================================
 *                    ipcom_drv_eth_filter_set_unicast_addr
 *===========================================================================
 * Description: Sets the unicast address of the local interface.
 * Parameters:	filter - The current filter for this interface.
 *              eth_unicast_addr - The unicast address for this node.
 * Returns:
 *
 */
IP_PUBLIC void
ipcom_drv_eth_filter_set_unicast_addr(Ipcom_drv_eth_filter *filter,
                                      Ip_u8 eth_unicast_addr[IPCOM_DRV_ETH_ADDR_SIZE])
{
    ipcom_memcpy(filter->unicast_addr,
                 eth_unicast_addr,
                 IPCOM_DRV_ETH_ADDR_SIZE);
}
Example #11
0
/*
 *===========================================================================
 *                    ipcom_buffer_put
 *===========================================================================
 * Description: Appends data to the buffer, expanding it if necessary.
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC Ip_err
ipcom_buffer_put(Ipcom_buffer *buffer, const Ip_u8 *data, Ip_u32 len)
{
    Ip_u8 *cp;
    if(ipcom_buffer_append_space(buffer, &cp, len))
        return IPCOM_ERR_FAILED;

    ipcom_memcpy(cp, data, len);

    return IPCOM_SUCCESS;
}
Example #12
0
/*
 *===========================================================================
 *                    ipcom_buffer_get
 *===========================================================================
 * Description: Gets data from the beginning of the buffer.
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC Ip_err
ipcom_buffer_get(Ipcom_buffer *buffer, Ip_u8 *buf, Ip_u32 len)
{
    ip_assert(len <= (buffer->end - buffer->offset));

    if(len > (buffer->end - buffer->offset))
        return IPCOM_ERR_FAILED;

    ipcom_memcpy(buf, buffer->buf + buffer->offset, len);
    buffer->offset += len;
    return IPCOM_SUCCESS;
}
IP_STATIC void *
ipnet_sysctl_if_add_ip4_addr(void *buf, Ip_u32 addr_n)
{
    struct Ip_sockaddr_in *in = (struct Ip_sockaddr_in *) buf;

    ipcom_memset(in, 0, sizeof(struct Ip_sockaddr_in));
    in->sin_family = IP_AF_INET;
    IPCOM_SA_LEN_SET(in, sizeof(struct Ip_sockaddr_in));
    ipcom_memcpy(&in->sin_addr, &addr_n, sizeof(in->sin_addr));

    return in + 1;
}
/*
 *===========================================================================
 *                    ipcom_egd
 *===========================================================================
 * Description: This process gathers random data by calling ipcom_random_bingo_lotto()
 *
 *              Applications can access the random data before the full entropy
 *              has been gathered. This will of course mean that the quality of
 *              the random data will not be as good, but in some situations that
 *              may be a better trade-off than no random data at all.
 * Parameters:
 * Returns:
 *
 */
IP_STATIC
IPCOM_PROCESS(ipcom_egd)
{
    Ipcom_egd_hash_ctx md5_ctx;
    Ipcom_egd_hash_ctx tmp_md5_ctx;
    Ip_s32 rnd;
    Ipcom_tmo tmo;
#ifdef IPCOM_EGD_DEBUG
    int i;
#endif

    ipcom_proc_init();

    IPCOM_LOG0(DEBUG, "ipcom_egd :: starting");

    ipcom_egd_hash_init(&md5_ctx);
    ipcom_egd_laps = 0;
#ifdef IPCOM_EGD_DEBUG
    ipcom_memset(ipcom_egd_raw_data, 0, sizeof(ipcom_egd_raw_data));
#endif

    while(ipcom_egd_laps < IPCOM_RANDOM_LAPS)
    {
        ipcom_egd_tmo_flag = 0;
        if(ipcom_tmo_request(&tmo, ipcom_random_tmo_handler, (int*)&ipcom_egd_tmo_flag, 50) != IPCOM_SUCCESS)
        {
            IPCOM_LOG0(ERR, "ipcom_egd :: timeout request failed, seed aborted");
            goto exit;
        }
        rnd = ipcom_random_bingo_lotto();
#ifdef IPCOM_EGD_DEBUG
        ipcom_egd_raw_data[ipcom_egd_laps] = rnd;
#endif
        ipcom_egd_hash_update(&md5_ctx, (void*) &rnd, sizeof(Ip_u32));
        ipcom_memcpy(&tmp_md5_ctx, &md5_ctx, sizeof(Ipcom_egd_hash_ctx));
        ipcom_egd_hash_final(ipcom_random_state, &tmp_md5_ctx);
        ipcom_egd_laps++;
        ipcom_millisleep(IPCOM_EGD_SLEEP_TIME);
    }

 exit:
#ifdef IPCOM_EGD_DEBUG
    for (i=0; i < ipcom_egd_laps; i++)
    {
        IPCOM_LOG2(INFO, "ipcom_egd_raw_data[%d] = %d", i, ipcom_egd_raw_data[i]);
        ipcom_millisleep(100);
    }
#endif
    IPCOM_LOG0(DEBUG, "ipcom_egd :: terminating");

    ipcom_proc_exit();
}
/*
 *===========================================================================
 *                    ipcom_env_create
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_STATIC Ipcom_env_entry *
ipcom_env_create(const char *name, const char *value)
{
    Ip_size_t        name_length;
    Ip_size_t        value_length;
    Ipcom_env_entry *env;

    /* Create environment variable */
    name_length = ipcom_strlen(name) + 1;
    value_length = ipcom_strlen(value) + 1;
    env = ipcom_malloc(sizeof(Ipcom_env_entry) + name_length + value_length);
    if(env == IP_NULL)
        return IP_NULL;

    /* Init environment variable */
    env->name  = (const char *)env + sizeof(Ipcom_env_entry);
    ipcom_memcpy((void *)env->name, name, name_length);
    env->value = env->name + name_length;
    ipcom_memcpy((void *)env->value, value, value_length);

    return env;
}
/*
 *===========================================================================
 *                    ipcom_random_get
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC void
ipcom_random_get(Ip_u8 *buf)
{
    Ipcom_egd_hash_ctx ctx;
    static Ip_u32 counter = 0;

    counter++;
    ipcom_egd_hash_init(&ctx);
    ipcom_egd_hash_update(&ctx, ipcom_random_state, sizeof(ipcom_random_state));
    ipcom_egd_hash_update(&ctx, (void*) &counter, sizeof(counter));
    ipcom_egd_hash_final(ipcom_random_state, &ctx);

    ipcom_memcpy(buf, ipcom_random_state, sizeof(ipcom_random_state));
}
Example #17
0
IP_PUBLIC void
ipcom_heap_sort(void *base, Ip_size_t num_members, Ip_size_t elem_size,
                Ipcom_heap_sort_cmp_func cmp_func, void *tmp)
{
    int i;

    for (i = num_members >> 1; i >= 1; i--)
        ipcom_heap_sort_downheap(base, elem_size, i, num_members, cmp_func, tmp);

    for (i = num_members; i > 1; i--)
    {
        ipcom_memcpy(tmp,
                     IPCOM_HEAP_SORT_GET_ELEM(base, i, elem_size),
                     elem_size);
        ipcom_memcpy(IPCOM_HEAP_SORT_GET_ELEM(base, i, elem_size),
                     IPCOM_HEAP_SORT_GET_ELEM(base, 1, elem_size),
                     elem_size);
        ipcom_memcpy(IPCOM_HEAP_SORT_GET_ELEM(base, 1, elem_size),
                     tmp,
                     elem_size);
        ipcom_heap_sort_downheap(base, elem_size, 1, i - 1, cmp_func, tmp);
    }
}
Example #18
0
/*
 *===========================================================================
 *                    ipcom_inet6_rth_add
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipcom_inet6_rth_add(void *bp, const struct Ip_in6_addr *addr)
{
    Ip_pkt_ip6_rthdr0  *rthdr = (Ip_pkt_ip6_rthdr0 *) bp;
    struct Ip_in6_addr *rtaddr;

    if (rthdr->ip6r0_type != IP_IPV6_RTHDR_TYPE_0)
        return -1;

    rtaddr = (struct Ip_in6_addr *) (rthdr + 1);
    ipcom_memcpy(&rtaddr[rthdr->ip6r0_segleft], addr, sizeof(struct Ip_in6_addr));
    ++rthdr->ip6r0_segleft;
    rthdr->ip6r0_len += sizeof(struct Ip_in6_addr) / 8;

    return 0;
}
/*
 *===========================================================================
 *                   ipnet_rtnetlink_rta_sz_put
 *===========================================================================
 * Description: Add a NETLINK route attribute to a NETLINK message.
 * Parameters:  nlh      - Current NLMSG
 *              sz       - Total size
 *              attrtype - Attribute type
 *              attrlen  - Lenght of attribute
 *              data     - Attribute data
 *
 * Returns:
 *
 */
IP_GLOBAL void *
ipnet_rtnetlink_rta_sz_put(Ipnet_netlink_mem_t *mem, int attrtype, int attrlen, IP_CONST void *data)
{
    struct Ip_rtattr *rta = ipnet_netlink_sz_put(mem, IP_NULL, IP_RTA_LENGTH(attrlen));

    if (!rta)
        return IP_NULL;

    rta->rta_type = (Ip_u16) attrtype;
    rta->rta_len  = (Ip_u16) IP_RTA_LENGTH (attrlen);

    if (data)
        ipcom_memcpy(IP_RTA_DATA(rta), data, attrlen);

    return rta;
}
/*
 *===========================================================================
 *                    ipcom_egd_random
 *===========================================================================
 * Description: This function will return the required number of random data,
 *              regardless of the seed state. A caller that requires high quality
 *              random data should check the random seed state first by calling
 *              ipcom_egd_random_seed_state().
 * Parameters:  rand_size:
 *                  the number of random bytes requested.
 *              buf:
 *                  the buffer to store the random data in.
 * Returns:
 */
IP_STATIC void
ipcom_egd_random(Ip_u8 *buf, Ip_s32 rand_size)
{
    Ip_u8 tmp_buf[sizeof(ipcom_random_state)];

    while(rand_size >= (Ip_s32) sizeof(ipcom_random_state))
    {
        ipcom_random_get(buf);
        buf += sizeof(ipcom_random_state);
        rand_size -= sizeof(ipcom_random_state);
    }

    if(rand_size > 0)
    {
        ipcom_random_get(tmp_buf);
        ipcom_memcpy(buf, tmp_buf, rand_size);
    }
}
IP_STATIC int
ipnet_cmd_qc_show_children(Ipnet_cmd_qc *p, struct Ipnet_ifqueue_container *container)
{
    int i;
    int ret = 0;
    struct Ipnet_ifqueue_container c;

    ipcom_memcpy(&c, container, sizeof(c));
    p->recurse_level++;

    p->p.ifq.ifq_parent_id = p->p.ifq.ifq_id;
    for (i = 0; ret == 0 && i < c.child_count; i++)
    {
        p->p.ifq.ifq_id = c.child_ids[i];
        ret = ipnet_cmd_qc_show_queue(p);
    }

    p->recurse_level--;
    return ret;
}
/*
 *===========================================================================
 *                    ipdnsc_hostent_insert_addr
 *===========================================================================
 * Description: Inserts an address in a hostent structure
 * Parameters:  he - pointer to the hostent structure
 *              addr - the addr to insert
 * Returns:     0 for OK, -1 for fail.
 */
IP_GLOBAL Ip_s32
ipdnsc_hostent_insert_addr(struct Ip_hostent *he, char *addr)
{
    Ip_s32 num_addr, i=0;
    char **tmp;

    /* Find out the current number of addresses */
    num_addr = ipdnsc_hostent_addr_count(he);

    /* Allocate memory for the another address list entry */
    tmp = ipcom_realloc(he->h_addr_list, (num_addr+1) * sizeof(char *));
    if(tmp == IP_NULL)
        return -1;
    he->h_addr_list = tmp;

    /* Allocate memory for the address */
    he->h_addr_list[num_addr-1] = ipcom_malloc(he->h_length);
    if (he->h_addr_list[num_addr-1] == IP_NULL)
    {
        /* We have to free to whole list here */
        while (he->h_addr_list[i] != IP_NULL)
        {
		    ipcom_free(he->h_addr_list[i]);
            i++;
        }
        /* Free the address list */
	    ipcom_free(he->h_addr_list);
        he->h_addr_list = IP_NULL;
        return -1;
    }

    /* Set the address */
    ipcom_memcpy(he->h_addr_list[num_addr-1], addr, he->h_length);

    /* Null terminate the list */
    he->h_addr_list[num_addr] = IP_NULL;

    return 0;

}
Example #23
0
/*
 *===========================================================================
 *                    ipcom_cmd_sockperf_echo_buf
 *===========================================================================
 * Description: Prints the contents of the buffer.
 * Parameters:  buf - The buffer to print.
 *              size - The size of 'buf'
 *              pattern_id - The pattern number the buffer should start at.
 * Returns:
 */
IP_STATIC void
ipcom_cmd_sockperf_echo_buf(char *buf, int size, int pattern_id)
{
    char pbuf[9];
    int  i;

    if (size == 0)
    {
        ipcom_printf(IP_LF);
        return;
    }

    pbuf[8] = '\0';
    for (i = 0; i < size; i += 8)
    {
        ipcom_memcpy(pbuf, buf + i, 8);
        if ((pattern_id % 16) == 0)
            ipcom_printf("%04d  ", i);
        if ((++pattern_id % 16) == 0)
            pbuf[7] = '\n';
        ipcom_printf(pbuf);
    }
}
Example #24
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_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();
}
/*
 *===========================================================================
 *                    ipnet_sysctl_route_dump_cb
 *===========================================================================
 * Description: Checks if this entry should be added and adds it if it should.
 * Parameters:  rt - the route entry to add
 *              data - callback data.
 * Returns:     IP_FALSE (the entry should never be deleted).
 *
 */
IP_STATIC Ip_bool
ipnet_sysctl_route_dump_cb(Ipnet_route_entry *rt, Ipnet_sysctl_route_data *data)
{
    struct Ipnet_rt_msghdr *rt_msg;
    Ip_u16                  len;

    if (rt->next)
        (void)ipnet_sysctl_route_dump_cb(rt->next, data);

    if (rt->narrow)
        (void) ipnet_sysctl_route_dump_cb(rt->narrow, data);

    if ((rt->hdr.flags & data->flags) != data->flags)
        return IP_FALSE;

    /* Do not list the 255.255.255.255, 224.0.0.0/4 or IPv6 multicast routes. */
    if (IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_X_MCAST_RO | IPNET_RTF_X_BCAST_RO | IPNET_RTF_X_HIDDEN))
          return IP_FALSE;

    len = ipnet_sysctl_route_dump_elem_len(rt);
    data->bytes_written += len;

    if (data->bytes_written > data->buf_len)
    {
        /* Buffer to small */
        if (data->buf != IP_NULL)
            data->soerrno = -IP_ERRNO_ENOMEM;
        return IP_FALSE;
    }

    rt_msg = (struct Ipnet_rt_msghdr *) data->buf;
    data->buf = (Ip_u8 *) data->buf + sizeof(struct Ipnet_rt_msghdr);

    ipcom_memset(rt_msg, 0, sizeof(struct Ipnet_rt_msghdr));
    rt_msg->rtm_msglen  = len;
    rt_msg->rtm_version = IPNET_RTM_VERSION;
    rt_msg->rtm_type    = IPNET_RTM_GET;
    rt_msg->rtm_index   = rt->netif ? rt->netif->ipcom.ifindex : 0;
    rt_msg->rtm_table   = data->table;
    rt_msg->rtm_flags   = rt->hdr.flags;
    rt_msg->rtm_use     = rt->use;
    rt_msg->rtm_rmx     = rt->metrics;

    /* add destination address */
    IP_BIT_SET(rt_msg->rtm_addrs, IPNET_RTA_DST);
    data->buf = ipnet_sysctl_route_add_addr(data->buf, IPNET_ROUTE_GET_FAMILY(rt->head), rt->hdr.key);

    if (rt->gateway)
    {
        IP_BIT_SET(rt_msg->rtm_addrs, IPNET_RTA_GATEWAY);
        ipcom_memcpy(data->buf, rt->gateway, IPCOM_SA_LEN_GET(rt->gateway));
        data->buf = (Ip_u8 *) data->buf + IPCOM_SA_LEN_GET(rt->gateway);
    }
    else if (IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_CLONING))
    {
        struct Ip_sockaddr_dl  *dl = data->buf;
        IP_BIT_SET(rt_msg->rtm_addrs, IPNET_RTA_GATEWAY);
        ipcom_memset(data->buf, 0, sizeof(struct Ip_sockaddr_dl));
        IPCOM_SA_LEN_SET(dl, sizeof(struct Ip_sockaddr_dl));
        dl->sdl_family = IP_AF_LINK;
        ip_assert(rt->netif != IP_NULL);
        if (rt->netif != IP_NULL)
        {
            dl->sdl_index  = (Ip_u16)rt->netif->ipcom.ifindex;
            dl->sdl_type   = (Ip_u8)rt->netif->ipcom.type;
        }
        data->buf = (Ip_u8 *) data->buf + sizeof(struct Ip_sockaddr_dl);
    }

    if (rt->hdr.mask)
    {
        /* add destination mask */
        IP_BIT_SET(rt_msg->rtm_addrs, IPNET_RTA_NETMASK);
        data->buf = ipnet_sysctl_route_add_addr(data->buf, IPNET_ROUTE_GET_FAMILY(rt->head), rt->hdr.mask);
    }

    ip_assert((Ip_u16)((Ip_ptrdiff_t) data->buf - (Ip_ptrdiff_t) rt_msg) == len);

    return IP_FALSE;
}
Example #28
0
/*
 *===========================================================================
 *                    ipcom_sysvar_set_internal
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_GLOBAL Ip_err
ipcom_sysvar_set_tree(const char *name, const char *value, int flags, Ipcom_sysvar_tree *tree)
{
    Ip_size_t           name_length;
    Ip_size_t           value_length;
    Ipcom_sysvar_entry  *sysvar;
    Ip_err              retval = IPCOM_SUCCESS;

    /* Check for duplicate. */
    sysvar = ipcom_hash_get(tree->sysvars, name);
    if (sysvar)
    {
        if (IP_BIT_ISSET(sysvar->flags, IPCOM_SYSVAR_FLAG_READONLY))
        {
            retval = IPCOM_ERR_READONLY;
            goto leave;
        }
        else if (IP_BIT_ISFALSE(flags, IPCOM_SYSVAR_FLAG_OVERWRITE))
        {
            retval = IPCOM_ERR_DUPLICATE;
            goto leave;
        }
        else
        {
            flags |= sysvar->flags & IPCOM_SYSVAR_FLAG_KERNEL;
            ipcom_hash_remove(tree->sysvars, sysvar);
            ipcom_free(sysvar);
            goto set;
        }
    }

    /* No current entry found and not allowed to create a new entry. */
    if(IP_BIT_ISSET(flags, IPCOM_SYSVAR_FLAG_NOCREATE))
    {
        retval = IPCOM_ERR_FAILED;
        goto leave;
    }

    /* Add the new sysvar. */
 set:
     name_length = ipcom_strlen(name) + 1;
     value_length = ipcom_strlen(value) + 1;
     sysvar = ipcom_malloc(sizeof(Ipcom_sysvar_entry) + name_length + value_length);

     if(sysvar == IP_NULL)
     {
         retval = IPCOM_ERR_NO_MEMORY;
         goto leave;
     }

     sysvar->refcount = 1;
     sysvar->flags    = flags;
     if (IP_BIT_ISFALSE(flags, IPCOM_SYSVAR_FLAG_INIT))
     {
         tree->modified = IP_TRUE;
         sysvar->flags |= IPCOM_SYSVAR_FLAG_MODIFIED;
     }
     sysvar->name     = (const char *)sysvar + sizeof(Ipcom_sysvar_entry);
     ipcom_memcpy((void *)sysvar->name, name, name_length);
     sysvar->value    = sysvar->name + name_length;
     ipcom_memcpy((void *)sysvar->value, value, value_length);

     retval = ipcom_hash_add(tree->sysvars, sysvar);

 leave:
    return retval; /*lint !e429 Custodial pointer 'sysvar' has not been freed or returned */
}
Example #29
0
/*
 *===========================================================================
 *                    ipcom_sysvar_getvr
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_GLOBAL char *
ipcom_sysvar_getvr(const char *name, char *value, Ip_size_t *value_size, Ip_bool usr, int vr)
{
    Ipcom_sysvar_entry  *sysvar;
    Ip_size_t           value_length;
    char                *ret_value = IP_NULL;
    Ip_err              retval;
    Ipcom_sysvar_tree   *tree;

    if (name == IP_NULL)
        return IP_NULL;

    retval = ipcom_once(&ipcom_sysvar_once, ipcom_sysvar_init, IP_NULL);
    if (retval != IPCOM_SUCCESS)
    {
        IP_PANIC();
        return IP_NULL;
    }

    IPCOM_CODE_LOCK();

    tree = ipcom_sysvar_tree_get(vr);
    if (tree == IP_NULL)
        goto leave;

    sysvar = ipcom_hash_get(tree->sysvars, name);
    if (sysvar)
    {
        if (value == IP_NULL)
        {
#ifdef IP_PORT_OSE5
            if (usr)
                ret_value = ipcom_strdup_usr(sysvar->value);
            else
#else
                (void)usr;
#endif
                ret_value = ipcom_strdup(sysvar->value);
        }
        else
        {
            value_length = ipcom_strlen(sysvar->value) + 1;
            if (value_length > *value_size)
            {
                ret_value = IP_NULL;
                *value_size = value_length;
            }
            else
            {
                ret_value = value;
                ipcom_memcpy(ret_value, sysvar->value, value_length);
                *value_size = value_length - 1;
            }
        }
    }
#ifdef IP_PORT_OSE5
    else
    {
        ret_value = ipcom_sysvar_get_ose5(name, value, value_size);
    }
#endif /* IP_PORT_OSE5 */

 leave:
    ipcom_sysvar_tree_done(tree);
    IPCOM_CODE_UNLOCK();
    return ret_value;
}
Example #30
0
/*
 *===========================================================================
 *                    ipnet_nat_proxy_sip_payload_parse
 *===========================================================================
 * Description: Parse SIP payload.
 * Parameters:  appdata   - pointer to application data.
 *              applen    - pointer to length of application data.
 *              growspace - space available to extend application data.
 *              param     - pointer to proxy parameters.
 *              newdata   - pointer to pointer to new application data.
 * Returns:     IP_TRUE  = Packet modified.
 *              IP_FALSE = Packet untouched.
 */
IP_STATIC Ip_bool
ipnet_nat_proxy_sip_payload_parse(Ip_u8 *appdata,
                                  int   *applen,
                                  int    growspace,
                                  Ipnet_nat_proxy_param *param,
                                  Ip_u8 **newdata)

{
    char    *psipmsg = (char *)appdata;
    char    *pcallid = IP_NULL;
    char    *pendstr, *pstartstr, *psearch;
    Ip_bool  retcode = IP_FALSE;
    int      pos, sdpdatalen, searchlen, msgtype = 0;
    char     tmpholder[50];
    char     laddrstr[20];
    char     gaddrstr[20];
    char    *pend = (char *)sipbuf + *applen - 1;
    char    *sdplen_start, *sdplen_end, *sdp_end;
    int      newlen, diff;

    if (param->incoming == IP_TRUE)
    {
        /* Incoming message*/
        goto parseFalseExit;
    }

    if (param->inbound == IP_FALSE)
    {
        /* Outbound session */
        if ((psipmsg = ipnet_nat_proxy_sip_outboundmsgtypecheck(psipmsg, &msgtype, *applen)) == IP_NULL)
            return IP_FALSE;   /* not the message we're looking for */
    }
    else
    {
        /* Inbound session */
        if ((psipmsg = ipnet_nat_proxy_sip_inboundmsgtypecheck(psipmsg, &msgtype, *applen)) == IP_NULL)
            return IP_FALSE;   /* not the message we're looking for */
    }

    /* find the call-id field */
    if (ipnet_nat_proxy_sip_keyfind(psipmsg, SIP_CALLID_STR, &pos, *applen - (psipmsg - (char *)appdata)) == IP_FALSE)
    {
        IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: no callid field");
        return IP_FALSE;
    }

    /* get callid string */
    pcallid = ipnet_nat_proxy_sip_callidstr(psipmsg + pos + SIP_TAG_TO_DATAPOS(SIP_CALLID_STR));
    if (pcallid == IP_NULL)
    {
        IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: failed to parse callid string");
        return IP_FALSE;
    }

    if (msgtype == SIP_MSG_TYPE_INVITE)
    {
        if (param->inbound == IP_FALSE)
        {
            /* Update the mapping timeout */
            IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds",
                       IPNET_NAT_SIP_ENTRY_INVITE_TIMEOUT);
            ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_INVITE_TIMEOUT, param->mapping);
        }
        else
        {
            /* ALG will not detect the ACK for inbound calls so use the INVITE response to set established timeout */
            IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds",
                       IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT);
            ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT, param->mapping);
        }
    }
    else if (msgtype == SIP_MSG_TYPE_ACK)
    {
        /* Update the mapping timeout */
        IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds",
                   IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT);
        ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT, param->mapping);
    }

    /* Copy the message to scratch buffer and set pointer */
    if (*applen > (int)sizeof(sipbuf))
    {
        IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: message to long");
        goto parseFalseExit;
    }
    ipcom_memcpy(sipbuf, appdata, *applen);
    psipmsg = (char *)sipbuf + (psipmsg - (char *)appdata);

    /* first the via field
     * For response message, the Via field will not contain the private address.
     * The localAddrProcess() will check if the address is private.
     */

    laddrstr[0] = gaddrstr[0] = 0;
    if (ipnet_nat_proxy_sip_keyfind(psipmsg, SIP_VIA_STR, &pos, (pend - psipmsg) + 1) == IP_TRUE)
	{
        /* advance to IP/Port string */

        psipmsg += (pos + ipcom_strlen(SIP_VIA_STR) + SIP_VIA_FIELD_IPADDR_DIS);

        IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse via field");

        psipmsg = ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid,
                                                       SIP_ADDRESS_PORT_STRING, param, &pend);

        if (psipmsg == IP_NULL)
            goto parseFalseExit;

    }

    /* find the contact field */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTACT_STR, &pos, (pend - psipmsg) + 1) == IP_TRUE)
    {
        /* advance to IP/Port string */

        psipmsg += (pos + ipcom_strlen(SIP_CONTACT_STR) + SIP_CTAC_FIELD_IPADDR_DIS);

        IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse contact field");

        psipmsg = ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid,
                                                       SIP_ADDRESS_PORT_STRING, param, &pend);

        if (psipmsg == IP_NULL)
            goto parseFalseExit;
    }

    /* exit if there isn't any private info in SIP message header */

    if (laddrstr[0] == 0 || gaddrstr[0] == 0)
        goto parseFalseExit;

    /* When program reaches here, it indicates at least one place in the
     * packet should be modified. Use parseFalseExit only if it is an error
     */

    /* find the Content-Type field */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTYPE_STR, &pos, (pend - psipmsg) + 1) == IP_FALSE)
        goto parseTrueExit;

    /* advance to start of data field */

    psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_CONTYPE_STR));

    SIP_SKIP_SPACES(psipmsg);

    /*check the application/sdp type, if not, exit */

    if (!SIP_IS_STRING_SAME(psipmsg, SIP_APPSDP_STR))
        goto parseTrueExit;

    /* find the content length field */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTLEN_STR, &pos, (pend - psipmsg) + 1) == IP_FALSE)
        goto parseTrueExit;

    IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse Content-Length field");

    /* reach to the content length field, advance to length data */

    psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_CONTLEN_STR));

    SIP_SKIP_SPACES(psipmsg);

    sdpdatalen = ipcom_strtol(psipmsg, &pendstr, 10);

    IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: data length = %d", sdpdatalen);

    if (sdpdatalen == 0)
        goto parseTrueExit;

    /* store start and end of sdp datalength string as well as end of message */
    sdplen_start = psipmsg;
    sdplen_end   = pendstr;
    sdp_end      = pend;

    /* advance to the start of SDP data */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, IP_NULL, &pos, (pend - psipmsg) + 1) == IP_FALSE)
    {
        IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: Can't find header end mark");
        goto parseTrueExit;
    }

    /* start of the SIP data field */

    psipmsg += pos;
    searchlen = sdpdatalen;

    /* search the local IP address, and replace it with global address */

    pstartstr = psipmsg;
    while (IP_TRUE)
    {
        psearch = ipnet_nat_proxy_sip_faststrsearch(laddrstr, ipcom_strlen(laddrstr),
                                                    pstartstr, searchlen, IP_FALSE);
        if (psearch != IP_NULL)
        {
            IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: Local IP address in SDP: %s", laddrstr);

            if (ipnet_nat_proxy_sip_modmsg(gaddrstr, ipcom_strlen(gaddrstr),
                                           psearch, ipcom_strlen(laddrstr), &pend) < 0)
            {
                goto parseFalseExit;
            }

            searchlen = searchlen - (psearch + ipcom_strlen(gaddrstr) - pstartstr);
            pstartstr = psearch + ipcom_strlen(gaddrstr);
        }
        else
            break;
    }

    IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: the last search length %d", searchlen);

    /* search for the audio port */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_AUDIO_STR, &pos, sdpdatalen) == IP_TRUE)
    {
        /* advance to the port field */

        psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_AUDIO_STR));

        SIP_SKIP_SPACES(psipmsg);
        ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_PORT_STRING, param, &pend);
    }

    /* search for the audio control port */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_RTCP_STR, &pos, sdpdatalen) == IP_TRUE)
	{
        /* advance to the port field */

        psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_RTCP_STR));

        SIP_SKIP_SPACES(psipmsg);
        ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_PORT_STRING, param, &pend);
    }

    /* adjust the length node */

    sdpdatalen += pend - sdp_end;
    ipcom_sprintf(tmpholder, "%d", sdpdatalen);
    if (ipnet_nat_proxy_sip_modmsg(tmpholder, ipcom_strlen(tmpholder),
                                   sdplen_start, sdplen_end - sdplen_start, &pend) < 0)
    {
        goto parseFalseExit;
    }

parseTrueExit:
    /* Update application data with the modified buffer */
    newlen = pend - (char *)sipbuf + 1;
    diff = newlen - *applen;
    if (diff > growspace)
    {
        /* Must allocate a new buffer */
        *newdata = ipcom_malloc(*applen + diff);
        if (*newdata == IP_NULL)
        {
            IPCOM_LOG1(ERR, "ipnet_nat_proxy_sip_payload_parse() :: ipcom_malloc(%d) failed",
                            *applen + diff);
            goto parseFalseExit;
        }
        ipcom_memcpy(*newdata, sipbuf, newlen);
    }
    else
    {
        /* Let the current buffer grow */
        ipcom_memcpy(appdata, sipbuf, newlen);
    }
    *applen = newlen;
    IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_msg() :: the delta length = %d ", diff);
    retcode = IP_TRUE;

parseFalseExit:
    if (msgtype == SIP_MSG_TYPE_BYE)
        ipnet_nat_proxy_sip_endmsgprocess(pcallid, param);
    if (pcallid)
        ipcom_free(pcallid);
    return retcode;
}