/*
 *===========================================================================
 *                    ipnet_config_add_inet_addr
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_config_add_inet_addr(Ip_fd fd, char *ifname, char *option)
{
    char *inet_addr;
    char *prefix_len;
    char *argv[] = {
        "ifconfig",
        "-silent",
        IP_NULL,
        "inet",
        "add",
        IP_NULL,
        IP_NULL,
        IP_NULL,
        IP_NULL
    };
    int argc = 5;
    char inet_addr_str[IP_INET_ADDRSTRLEN];
    char inet_prefix_len_str[8];

    argv[2] = ifname;

    inet_addr = ipcom_strtok_r(option, " \t/", &option);
    if (inet_addr == IP_NULL)
    {
        IPCOM_LOG0(ERR, "inet address is missing or format is invalid");
        return -IP_ERRNO_EINVAL;
    }

    if (ipcom_strcmp(inet_addr, "dhcp") == 0)
    {
        struct Ip_ifreq  ifreq;

    use_dhcp:
        ipcom_strcpy(ifreq.ifr_name, ifname);
        ifreq.ifr_ifru.ifru_opt = 1;

		if (ipcom_socketioctl(fd, IP_SIOCXSDHCPRUNNING, &ifreq) < 0)
        {
            IPCOM_LOG1(ERR, "Failed to enable DHCP on %s", ifname);
            return ipcom_errno;
        }
        return 0;
    }

#ifdef IPNET_USE_RARP
    if (ipcom_strcmp(inet_addr, "rarp") == 0)
    {
        struct Ip_ethreq  ethreq;

        ipcom_strcpy(ethreq.ethr_name, ifname);
        ethreq.ethru.rarp = -1;

		if (ipcom_socketioctl(fd, IP_SIOCXETHSRARP, &ethreq) < 0)
        {
            IPCOM_LOG1(ERR, "Failed to enable RARPP on %s", ifname);
            return ipcom_errno;
        }
        return 0;
    }
#endif /* IPNET_USE_RARP */

    if (ipcom_strcmp(inet_addr, "driver") == 0)
    {
        /* Get the IPv4 address to use from the driver */
        struct Ip_ethreq ethreq;

        ipcom_strcpy(ethreq.ethr_name, ifname);
        if (ipcom_socketioctl(fd, IP_SIOCXETHGINET, &ethreq) < 0)
        {
            IPCOM_LOG1(ERR, "Failed to read the IPv4 address from the driver for %s", ifname);
            return ipcom_errno;
        }
        if (ethreq.ethru.inet.addr.s_addr == 0xffffffff)
            goto use_dhcp;
        inet_addr = inet_addr_str;
        (void) ipcom_inet_ntop(IP_AF_INET, &ethreq.ethru.inet.addr,
            inet_addr_str, sizeof(inet_addr_str));

        prefix_len = inet_prefix_len_str;
        ipcom_snprintf(inet_prefix_len_str, sizeof(inet_prefix_len_str), "%d",
            ipcom_mask_to_prefixlen(&ethreq.ethru.inet.mask, 32));
    }
    else
    {
        prefix_len = ipcom_strtok_r(option, " \t/", &option);
        if (prefix_len == IP_NULL)
        {
            IPCOM_LOG0(ERR, "prefix len is missing or format is invalid");
            return -IP_ERRNO_EINVAL;
        }
    }

    argv[argc++] = inet_addr;
    argv[argc++] = "prefixlen";
    argv[argc++] = prefix_len;

    return ipnet_config_cmd_ifconfig(argc, argv);
}
IP_PUBLIC int
ipcom_strerror_r(int errnum, char * buf, Ip_size_t buflen)
{
    char * name;
    int n;

    if (buf == NULL)
        return -1;

#if IP_PORT_VXWORKS >= 60
    name = ipcom_strerror_int_vxworks(errnum);
#else
    name = ipcom_strerror_int(errnum);
#endif

    if (name)
    {
        ipcom_strncpy(buf, name, buflen);
        buf[buflen-1] = '\0';
        n = ipcom_strlen(name);
    }
    else
    {

#ifdef IP_PORT_VXWORKS
        n = ipcom_snprintf(buf, buflen, "errno = %#x", errnum);
#else
        n = ipcom_snprintf(buf, buflen, "Unknown error: %d", 0xffff & errnum);
#endif
    }

    return (n < buflen) ? 0 : IP_ERRNO_ERANGE;
}
/*
 *===========================================================================
 *                    ipnet_cmd_qc_format_rate
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC const char *
ipnet_cmd_qc_format_rate(char *str_num, int str_len, Ip_u32 num)
{
    if (num / 10000000 > 0)
        ipcom_snprintf(str_num, str_len, "%uMbps", (unsigned) (num / 1000000));
    else if (num / 10000 > 0)
        ipcom_snprintf(str_num, str_len, "%ukbps", (unsigned) (num / 1000));
    else
        ipcom_snprintf(str_num, str_len, "%ubps", (unsigned) (num));
    return str_num;
}
/*
 *===========================================================================
 *                    ipcom_sysvar_set_conf
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_PUBLIC Ip_err
ipcom_sysvar_set_conf(const char *name, const char *value, int flags,
                      const char *username, const char *ifname)
{
    char buf[256];

    if (username && *username)
    {
        ipcom_snprintf(buf, sizeof(buf), "ipcom.users.%s.%s", username, name);
        return ipcom_sysvar_set(buf, value, flags);
    }

    if (ifname && *ifname)
    {
        ipcom_snprintf(buf, sizeof(buf), "ipcom.if.%s.%s", ifname, name);
        return ipcom_sysvar_set(buf, value, flags);
    }

    return ipcom_sysvar_set(name, value, flags);
}
/*
 *===========================================================================
 *                    ipcom_unsetenv
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipcom_unsetenv(const char *name)
{
#if IPCOM_USE_ENV == IPCOM_ENV_IPCOM
    Ip_err           retval;
    Ipcom_proc      *proc;
    Ipcom_env_entry *env;

    proc = ipcom_proc_self();
    ip_assert(proc != IP_NULL);

    retval = ipcom_once(&proc->env_once, ipcom_env_init, proc);
    if (retval != IPCOM_SUCCESS)
    {
        IP_PANIC();
        return -1;
    }

    ipcom_mutex_lock(proc->env_mutex);

    env = ipcom_hash_get(proc->env_tree, name);
    if (env != IP_NULL)
        ipcom_env_delete(env, proc->env_tree);

    ipcom_mutex_unlock(proc->env_mutex);

    return 0;

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE && (defined(IP_PORT_OSE) || defined(IP_PORT_OSE5))
    set_env(current_process(), name, NULL);
    return 0;

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE && defined(IP_PORT_VXWORKS)
    {
        char buf[256];
        int  ret;
        ipcom_snprintf(buf, sizeof(buf), "%s=", name);
        ret = (int)putenv(buf);
        return ret == 0 ? 0 : -1;
    }

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE
    return unsetenv(name);

#elif defined(IPCOM_USE_SYSVAR) && IPCOM_VR_MAX == 1
    (void)ipcom_sysvar_unset(name);
    return 0;

#else
    return 0;

#endif /* #if IPCOM_USE_ENV == IPCOM_ENV_IPCOM */
}
/*
 *===========================================================================
 *                    ipcom_sysvar_get_conf
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_PUBLIC char *
ipcom_sysvar_get_conf(const char *name, char *value, Ip_size_t *value_size,
                      const char *username, const char *ifname)
{
    char buf[256];
    Ip_size_t org_value_size;
    char *ret;

    if (value != IP_NULL && value_size == IP_NULL)
    {
        return IP_NULL;
    }

    org_value_size = value_size ? *value_size : 0;

    /* First try user configuration. */
    if (username && *username)
    {
        ipcom_snprintf(buf, sizeof(buf), "ipcom.users.%s.%s", username, name);
        ret = ipcom_sysvar_get(buf, value, value_size);
        if (ret)
            return ret;
        if (value_size && *value_size > org_value_size)
            return IP_NULL;
    }

    /* Second try interface configuration. */
    if (ifname && *ifname)
    {
        ipcom_snprintf(buf, sizeof(buf), "ipcom.if.%s.%s", ifname, name);
        ret = ipcom_sysvar_get(buf, value, value_size);
        if (ret)
            return ret;
        if (value_size && *value_size > org_value_size)
            return IP_NULL;
    }

    /* Third try global configuration. */
    return ipcom_sysvar_get(name, value, value_size);
}
/*
 *===========================================================================
 *                    ipnet_debug_sock_to_str
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_GLOBAL char *
ipnet_debug_sock_to_str(Ipnet_socket *sock, char *str, Ip_size_t str_len)
{
#ifdef IPNET_DEBUG
#ifdef IPCOM_USE_INET6
    char src_str[IP_INET6_ADDRSTRLEN];
    char dst_str[IP_INET6_ADDRSTRLEN];
#else
    char src_str[IP_INET_ADDRSTRLEN];
    char dst_str[IP_INET_ADDRSTRLEN];
#endif
#endif /* IPNET_DEBUG*/

    switch (sock->ipcom.domain)
    {
#ifdef IPCOM_USE_INET
    case IP_AF_INET:
        (void)ipcom_inet_ntop(IP_AF_INET, &sock->ip4->saddr_n, src_str, sizeof(src_str));
        (void)ipcom_inet_ntop(IP_AF_INET, &sock->ip4->daddr_n, dst_str, sizeof(dst_str));
        break;
#endif /* IPCOM_USE_INET */
#ifdef IPCOM_USE_INET6
    case IP_AF_INET6:
        (void)ipcom_inet_ntop(IP_AF_INET6, &sock->ip6->saddr, src_str, sizeof(src_str));
        (void)ipcom_inet_ntop(IP_AF_INET6, &sock->ip6->daddr, dst_str, sizeof(dst_str));
        break;
#endif /* IPCOM_USE_INET6 */
    default:
        src_str[0] = '\0';
        dst_str[0] = '\0';
    }
    ipcom_snprintf(str, str_len, "fd:%d ref:%d, domain:%d proto:%d %s:%d %s:%d",
                   sock->ipcom.fd,
                   ipcom_atomic_get(&sock->ref_count),
                   sock->ipcom.domain,
                   sock->proto,
                   src_str, sock->sport,
                   dst_str, sock->dport);
    return str;
}
/*
 *===========================================================================
 *                    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;
}
Ejemplo n.º 9
0
/*
 *===========================================================================
 *                      ipnet_if_mib_table_search_ifTable
 *===========================================================================
 * Description: Searches ifTable and ifXTable for a matching entry
 * Parameters: id, buf, best, cmd
 * Returns:    The best matching interface or IP_NULL if no match was found,
 *             error code is stored in 'ret' in that case.
 *
 */
IP_STATIC Ipnet_netif *
ipnet_if_mib_table_search_ifTable(char *id,
                                  char *buf,
                                  char *best,
                                  Ip_s32 cmd,
                                  Ip_s32 *error_code)
{
    Ip_u32       bestindex = 0;
    Ip_u32       ifIndex;
    Ip_u32      *ifindexes;
    unsigned     ifTable_num_entries;
    unsigned     i;

    ifindexes = ipnet_if_get_index_array(IPCOM_VR_ANY, 0, &ifTable_num_entries);
    if (ifindexes == IP_NULL)
    {
        *error_code = IPSNMP_ERROR_GENERROR;
        return IP_NULL;
    }

    for (i = 0; i < ifTable_num_entries; i++)
    {
        Ip_s32 lex, len = 0;

        buf[0] = '\0';

        ifIndex = ifindexes[i];

        if (ipcom_snprintf(&buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "%d.", (int)ifIndex) < 0)
        {
            *error_code = IPSNMP_ERROR_GENERROR;
            ipcom_free(ifindexes);
            return IP_NULL;
        }
        len = ipcom_strlen(buf);
        if (len)
            buf[len - 1] = '\0';

        lex = ipsnmp_util_lexcmp_oid(buf, id);
        if (cmd == IPSNMP_MIB_COMMAND_NEXT)
        {
            if (lex > 0)
            {
                if (bestindex == 0 || ipsnmp_util_lexcmp_oid(buf, best) < 0)
                {
                    ipcom_strcpy(best, buf);
                    bestindex = ifIndex;
                }
            }
        }
        else
        {
            if (lex == 0)
            {
                ipcom_strcpy(best, buf);
                bestindex = ifIndex;
                break;
            }
        }
    }

    if (bestindex == 0)
        *error_code = IPSNMP_ERROR_NOSUCHNAME;
    ipcom_free(ifindexes);
    return ipnet_if_indextonetif(IPCOM_VR_ANY, bestindex);
}
/*
 *===========================================================================
 *                      ipnet_ip_mib_cb_ipCidrRouteTable
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC Ip_bool
ipnet_ip_mib_cb_ipCidrRouteTable(Ipnet_route_entry *rt, Ipsnmp_route_walk *rwp)
{
    Ip_s32 tmp, lex, len = 0;

    /* Early exit if exact match was found previously */
    if(rwp->bestrt != IP_NULL &&
        (rwp->cmd == IPSNMP_MIB_COMMAND_GET
        || rwp->cmd == IPSNMP_MIB_COMMAND_TEST
        || rwp->cmd == IPSNMP_MIB_COMMAND_SET))
        goto exit;

    if(rt->netif == IP_NULL)
        goto exit;

    /* Do not use hidden entries */
    if(IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_X_HIDDEN))
        goto exit;

    /* Route must be usable */
    if(IP_BIT_ISFALSE(rt->hdr.flags, IPNET_RTF_UP))
        goto exit;

    /* Do not use link layer entries */
    if(IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_LLINFO))
        goto exit;

    /* Do not use loopback entries */
    if (IP_BIT_ISSET(rt->netif->ipcom.flags, IP_IFF_LOOPBACK))
        goto exit;

    ip_assert(rt->hdr.key != IP_NULL);

    /* Do not use multicast entries */
    if(IP_IN_CLASSD(*(Ip_u32 *)rt->hdr.key))
        goto exit;

    /* Do not use broadcast entries */
    if(ip_ntohl(*(Ip_u32 *)rt->hdr.key) == IP_INADDR_BROADCAST)
        goto exit;

    if(rwp->count_only == IP_TRUE)
    {
        count++;
        goto exit;
    }

    rwp->buf[0] = '\0';
    /* ipCidrRouteDest */
    if(ipcom_inet_ntop(IP_AF_INET, rt->hdr.key, &rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len) == IP_NULL)
        goto exit;
    len = ipcom_strlen(rwp->buf);
    if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, ".") < 0)
        goto exit;
    len = ipcom_strlen(rwp->buf);

    /* ipCidrRouteMask */
    if(rt->hdr.mask == IP_NULL)
    {
        if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "255.255.255.255") < 0)
            goto exit;
    }
    else
    {
        if(ipcom_inet_ntop(IP_AF_INET, rt->hdr.mask, &rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len) == IP_NULL)
            goto exit;
    }
    len = ipcom_strlen(rwp->buf);
    if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, ".") < 0)
        goto exit;
    len = ipcom_strlen(rwp->buf);

    /* ipCidrRouteTos */
    tmp = 0;
    if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "%d.", (int)tmp) < 0)
        goto exit;
    len = ipcom_strlen(rwp->buf);

    /* ipCidrRouteNextHop */
    if(IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_GATEWAY))
    {
        struct Ip_sockaddr_in *sa;

        ip_assert(rt->gateway != IP_NULL);
        sa = (struct Ip_sockaddr_in *)rt->gateway;
        if(ipcom_inet_ntop(IP_AF_INET, &sa->sin_addr.s_addr, &rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID - len) == IP_NULL)
            goto exit;
    }
    else
    {
        if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "0.0.0.0") < 0)
            goto exit;
    }
    len = ipcom_strlen(rwp->buf);
    if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, ".") < 0)
        goto exit;
    len = ipcom_strlen(rwp->buf);
    if(len)
        rwp->buf[len-1] = '\0';

    lex = ipsnmp_util_lexcmp_oid(rwp->buf, rwp->id);
    if(rwp->cmd == IPSNMP_MIB_COMMAND_NEXT)
    {
        if(lex > 0)
        {
            if(rwp->bestrt == IP_NULL || ipsnmp_util_lexcmp_oid(rwp->buf, rwp->best) < 0)
            {
                ipcom_strcpy(rwp->best, rwp->buf);
                rwp->bestrt = rt;
            }
        }
    }
    else
    {
        if(lex == 0)
        {
            ipcom_strcpy(rwp->best, rwp->buf);
            rwp->bestrt = rt;
        }
    }

exit:
    /* Do not delete the entry */
    return IP_FALSE;
}
/*
 *===========================================================================
 *                    ipcom_setenv
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipcom_setenv(const char *name, const char *value, int rewrite)
{
#if IPCOM_USE_ENV == IPCOM_ENV_IPCOM
    Ip_err           retval;
    Ipcom_proc      *proc;
    Ipcom_env_entry *env;

    proc = ipcom_proc_self();
    ip_assert(proc != IP_NULL);

    retval = ipcom_once(&proc->env_once, ipcom_env_init, proc);
    if (retval != IPCOM_SUCCESS)
    {
        IP_PANIC();
        return -1;
    }

    ipcom_mutex_lock(proc->env_mutex);

    /* Check for duplicate. */
    env = ipcom_hash_get(proc->env_tree, name);
    if (env != IP_NULL)
    {
        if (rewrite == 0)
            goto leave;
        ipcom_env_delete(env, proc->env_tree);
    }

    /* Create environment variable. */
    env = ipcom_env_create(name, value);
    if (env == IP_NULL)
    {
        ipcom_mutex_unlock(proc->env_mutex);
        return -1;
    }
    (void)ipcom_hash_add(proc->env_tree, env);

 leave:
    ipcom_mutex_unlock(proc->env_mutex);
    return 0;

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE && (defined(IP_PORT_OSE) || defined(IP_PORT_OSE5))
    (void)rewrite;

    set_env(current_process(), name, value);
    return 0;

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE && defined(IP_PORT_VXWORKS)
    char buf[256];
    int  ret;

    (void)rewrite;

    ipcom_snprintf(buf, sizeof(buf), "%s=%s", name, value);
    ret = (int)putenv(buf);
    return ret == 0 ? 0 : -1;

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE
    return setenv(name, value, rewrite);

#elif defined(IPCOM_USE_SYSVAR) && IPCOM_VR_MAX == 1
    (void)ipcom_sysvar_set(name, value, rewrite ? IPCOM_SYSVAR_FLAG_OVERWRITE : 0);
    return 0;

#else
    (void)name;
    (void)value;
    (void)rewrite;
    return -1;

#endif /* #if IPCOM_USE_ENV == IPCOM_ENV_IPCOM */
}