/*
 *===========================================================================
 *                    ipcom_hash_for_each
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC void
ipcom_hash_for_each(Ipcom_hash *head, Ipcom_hash_foreach_cb_func cb_func, void *data)
{
    unsigned  i;
    unsigned  x;
    void    **elems;

    if (head->elem == 0)
        return;

    elems = IPCOM_MALLOC_DYNAMIC(head->elem * sizeof(void*)); /*lint !e647 */
    if (elems == IP_NULL)
    {
        IP_PANIC();
        return;
    }

    for (i = 0, x = 0; i < head->size; i++)
        if (head->table[i] != IP_NULL)
            elems[x++] = head->table[i];

    ip_assert(x == head->elem);
    for (i = 0; i < x; i++)
        cb_func(elems[i], data);

    IPCOM_FREE_DYNAMIC(elems);
}
/*
 *===========================================================================
 *                    ipcom_clearenv
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipcom_clearenv(void)
{
#if IPCOM_USE_ENV == IPCOM_ENV_IPCOM
    Ip_err      retval;
    Ipcom_proc *proc;

    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_proc_clearenv(proc);
    return 0;

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE && (defined(IP_PORT_OSE) || defined(IP_PORT_OSE5))
    /*!! Are all environment variables cleaned up by OS automatically? */
    return 0;

#elif defined(IPCOM_USE_SYSVAR) && IPCOM_VR_MAX == 1
    /*! Hmmmm */
    return -1;

#else
    return -1;

#endif /* #if IPCOM_USE_ENV == IPCOM_ENV_IPCOM */
}
/*
 *===========================================================================
 *                    ipcom_drv_ppp_exit
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int /*D!!*/
ipcom_drv_ppp_exit(Ipcom_drv_ppp_link *plink)
{
    Ipcom_drv_ppp_ipc   *ipcbuf;
    int  fd;

    fd = plink->fd;
    if (fd != -1)
    {
        plink->fd = -1;  /* will make input daemon exit */
        (void)close(fd);
    }

    /* Kill output daemon */
    ipcbuf = ipcom_ipc_malloc(sizeof(Ipcom_drv_ppp_ipc));
    if (ipcbuf == IP_NULL)
    {
        IP_PANIC();
        return 0;
    }
    ipcbuf->netif = plink->netif;
    ipcbuf->pkt = IP_NULL;

    /* Send IPC buf to output task */
    (void)ipcom_ipc_send(&plink->out_ipc, ipcbuf);
    (void)ipcom_ipc_close(&plink->out_ipc);

    return 0;
}
/*
 *===========================================================================
 *                    ipcom_proc_copyenv
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_GLOBAL void
ipcom_proc_copyenv(Ipcom_proc *proc_c)
{
    Ipcom_proc         *proc_p;
    Ip_err              retval;

    proc_p = ipcom_proc_self();
    ip_assert(proc_p != IP_NULL);
    ip_assert(proc_c != IP_NULL);

    if (proc_p->env_tree == IP_NULL)
        /* Parent process has no environment variables */
        return;

    /* Create child environment semaphore and tree */
    retval = ipcom_once(&proc_c->env_once, ipcom_env_init, proc_c);
    if (retval != IPCOM_SUCCESS)
    {
        IP_PANIC();
        return;
    }

    ipcom_mutex_lock(proc_p->env_mutex);

    ipcom_hash_for_each(proc_p->env_tree,
                        (Ipcom_hash_foreach_cb_func) ipcom_env_clone,
                        proc_c->env_tree);

    ipcom_mutex_unlock(proc_p->env_mutex);
}
Пример #5
0
/*********************************************************************
*
*       IP_OS_AddTickHook()
*
*  Function description
*    Add tick hook. This is a function which is called from the tick handler, typically because the driver's
*    interrupt handler is not called via it's own hardware ISR. (We poll 1000 times per second)
*
*  Context
*    Function is called from a task, not an ISR
*/
void IP_OS_AddTickHook(void (* pfHook)(void)) {
#if OS_VERSION >= 36000
  static OS_TICK_HOOK _cb;
  OS_AddTickHook(&_cb, pfHook);
#else
  IP_PANIC("IP_OS_AddTickHook() requires an OS version >= 3.60");      // This requires a newer version of the OS.
#endif
}
/*
 *===========================================================================
 *                    ipcom_getenv
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC char *
ipcom_getenv(const char *name)
{
#if IPCOM_USE_ENV == IPCOM_ENV_IPCOM
    Ip_err           retval;
    Ipcom_proc      *proc;
    Ipcom_env_entry *env;
    char            *value = IP_NULL;

    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 IP_NULL;
    }

    ipcom_mutex_lock(proc->env_mutex);

    env = ipcom_hash_get(proc->env_tree, name);
    if (env != IP_NULL)
        value = (char *)env->value;

    ipcom_mutex_unlock(proc->env_mutex);

    return value;

#elif IPCOM_USE_ENV == IPCOM_ENV_NATIVE && (defined(IP_PORT_OSE) || defined(IP_PORT_OSE5))
    char *env;
    static char buf[256];

    env = get_env(current_process(), name);
    if (env != IP_NULL)
    {
        ipcom_strncpy(buf, env, sizeof(buf));
        free_buf((union SIGNAL **)&env);
        return (char *)buf;
    }
    return IP_NULL;

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

#elif defined(IPCOM_USE_SYSVAR) && IPCOM_VR_MAX == 1
    static char buf[256];
    Ip_size_t  buf_size = sizeof(buf);

    return ipcom_sysvar_get(name, buf, &buf_size);

#else
    return IP_NULL;

#endif /* #if IPCOM_USE_ENV == IPCOM_ENV_IPCOM */
}
/*
 *===========================================================================
 *                    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 */
}
Пример #8
0
IP_PUBLIC void
ipcom_abort(void)
{
    IP_PANIC();

#if defined(IP_PORT_OSE5)
    efs_abort(__FILE__, __LINE__);
#elif defined(IP_PORT_RTCORE)
    ipcom_proc_exit();
#elif !defined(IP_PORT_ITRON) && \
    (!defined(IP_PORT_INTEGRITY) || !defined(INT_178B))
    abort();
#endif
}
/*
 *===========================================================================
 *                    ipnet_config_run_boot_cmd
 *===========================================================================
 * Description: Configures one route entry.
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_config_run_boot_cmd(const char *conf)
{
    char *option_org;
    char *option;
    char *argv[20];
    char *arg;
    int   argc = 0;
    int   ret = -IP_ERRNO_EINVAL;

    option_org = option = ipcom_strdup(conf);
    if (option == IP_NULL)
        return -IP_ERRNO_ENOMEM;

    while (IP_NULL != (arg = ipcom_strtok_r(option, " \t", &option)))
    {
        if (argc == 1)
            argv[argc++] = "-silent";
        argv[argc++] = arg;

        if (argc >= (int) (sizeof(argv) / sizeof(*argv)))
        {
            IPCOM_LOG1(ERR, "Too many arguments in command %s", conf);
            IP_PANIC();
        }
    }
    argv[argc] = IP_NULL;

    if (argc > 2)
    {
        if (ipcom_strcmp(argv[0], "route") == 0)
            ret = ipnet_config_cmd_route(argc, argv);
        else if (ipcom_strcmp(argv[0], "ifconfig") == 0)
            ret = ipnet_config_cmd_ifconfig(argc, argv);
        else if (ipcom_strcmp(argv[0], "qc") == 0)
            ret = ipnet_config_cmd_qc(argc, argv);
#if defined(IPNET_USE_NAT) && !defined(IP_PORT_LKM) && !defined(IP_PORT_VXWORKS)
        else if (ipcom_strcmp(argv[0], "nat") == 0)
            ret = ipnet_cmd_nat(argc, argv);
#endif
    }

    ipcom_free(option_org);
    return ret;
}
/*
 *===========================================================================
 *                    ipnet_config_add_gateway
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_config_add_gateway(Ip_fd fd, char *ifname, char *option)
{
    char gw_str[IP_INET_ADDRSTRLEN];
    char *gw;

    gw = ipcom_strtok_r(option, " \t", &option);
    if (gw == IP_NULL)
    {
        IPCOM_LOG1(ERR,
                   "Wrong gateway format specified for interface %s, must be 'gateway <driver|gw_address>",
                   ifname);
        IP_PANIC();
        return -IP_ERRNO_EINVAL;
    }

    if (ipcom_strcmp(gw, "driver") == 0)
    {
        /* Get the IPv4 gateway 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 gateway address "
                       "from the driver for %s", ifname);
            return ipcom_errno;
        }
        if (ethreq.ethru.inet.gateway.s_addr == 0xffffffff)
            return 0; /* using dhcp, ignore gateway */
        if (ethreq.ethru.inet.gateway.s_addr == 0)
        {
            IPCOM_LOG1(NOTICE, "No IPv4 gateway address set in driver for %s", ifname);
            return 0;
        }

        (void) ipcom_inet_ntop(IP_AF_INET, &ethreq.ethru.inet.gateway,
                               gw_str, sizeof(gw_str));
        gw = gw_str;
    }

    return ipnet_config_add_route(IP_AF_INET, "0.0.0.0", 0, gw);
}
Пример #11
0
/*
 *===========================================================================
 *                    ipcom_hash_can_move_obj
 *===========================================================================
 * Description:   Returns if the object with the specified ideal index can
 *                be move to the specified new index.
 * Parameters:    ideal_index - The index the object would have the table had
 *                no collisions.
 *                new_index - The new index this object would be moved to.
 *                size - The size of the current hash array.
 * Returns:       IP_TRUE if the object can be moved.
 *
 */
IP_STATIC Ip_bool
ipcom_hash_can_move_obj(unsigned ideal_index, unsigned new_index, unsigned size)
{
    int half_size = size >> 1;

#if IPCOM_HASH_HIGH_WATER_MARK > 50
    /* NOTE: this algorithm will break if IPCOM_HASH_HIGH_WATER_MARK
       is 50 or higher */
    IP_PANIC();
#endif

    if (IP_ABS((int) (ideal_index - new_index)) > half_size)
    {
        ideal_index = (ideal_index + half_size) % size;
        new_index = (new_index + half_size) % size;
    }

    return ideal_index <= new_index;
}
Пример #12
0
IP_STATIC Ip_err
ipcom_sysvar_setvr(const char *name, const char *value, int flags, int vr)
{
    Ip_err retval;
    Ipcom_sysvar_tree   *tree;


    if (value == IP_NULL)
        return IPCOM_SUCCESS;  /* simply ignore it silently */

#ifdef IP_PORT_OSE5
    if (IP_BIT_ISFALSE(flags, IPCOM_SYSVAR_FLAG_OVERWRITE))
    {
        Ip_size_t test_size = 1;
        char test[1];

        if (ipcom_sysvar_get_ose5(name, test, &test_size) || test_size > 1)
            return IPCOM_ERR_DUPLICATE;
    }
#endif /* IP_PORT_OSE5 */


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

    IPCOM_CODE_LOCK();

    tree = ipcom_sysvar_tree_get(vr);
    if (tree == IP_NULL)
        retval = IPCOM_ERR_NO_MEMORY;
    else
        retval =  ipcom_sysvar_set_tree(name, value, flags, tree);
    ipcom_sysvar_tree_done(tree);

    IPCOM_CODE_UNLOCK();

    return retval;
}
Пример #13
0
/*
 *===========================================================================
 *                       ipppp_work_schedule
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipppp_work_schedule(struct Ipppp_action_work *work)
{
    if (ipcom_once(&ipppp_work_once,
                   ipppp_work_init,
                   IP_NULL)
        != IPCOM_SUCCESS)
    {
        IP_PANIC();
        return -1;
    }


    ipcom_mutex_lock(ipppp_work_lock);
    ipcom_list_insert_last(&ipppp_work_queue, &work->list);
    ipcom_mutex_unlock(ipppp_work_lock);

    ipcom_sem_post(ipppp_work_sem);
    return 0;
}
/*
 *===========================================================================
 *                    ipcom_usr_create
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_PUBLIC Ip_err
ipcom_usr_create(void)
{
    Ip_err   err;

    /*!!RACE CONDITION*/
    if (ipcom_usr_created)
        return IPCOM_SUCCESS;
    ipcom_usr_created = IP_TRUE;

    err = ipcom_mutex_create(&ipcom_once_mutex);
    if (err != IPCOM_SUCCESS)
        goto fail;

    /****** SUCCESS *****/
    return err;


    /****** Create fail *****/
 fail:
    IP_PANIC();
    return err;
}
/*
 *===========================================================================
 *                    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);
}
IP_GLOBAL IP_CONST char *
ipnet_nd_state_to_string(int state)
{
    switch (state)
    {
    case IPNET_ND_UNINITIALIZED:
        return "UNINITIALIZED";
    case IPNET_ND_INCOMPLETE:
        return "INCOMPLETE";
    case IPNET_ND_REACHABLE:
        return "REACHABLE";
    case IPNET_ND_STALE:
        return "STALE";
    case IPNET_ND_DELAY:
        return "DELAY";
    case IPNET_ND_PROBE:
        return "PROBE";
    case IPNET_ND_PROXY:
        return "PROXY";
    default:
        IP_PANIC();
        return "Unknown ND state";
    }
}
Пример #17
0
/*
 *===========================================================================
 *                    ipcom_once
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_PUBLIC Ip_err
ipcom_once(Ipcom_once_t *once, Ip_err (*init)(void *param), void *param)
{
    Ip_err           ret = IPCOM_SUCCESS;
    int              old_state;
    Ipcom_wait_queue wq;

    if (once->state == IPCOM_ONCE_STATE_DONE)
        return IPCOM_SUCCESS;

    /* Enter the once monitor */
    ip_assert(ipcom_once_mutex != IPCOM_MUTEX_INVALID);
    ipcom_mutex_lock(ipcom_once_mutex);

    /* Check state */
    switch (old_state = once->state)
    {
    case IPCOM_ONCE_STATE_UNINITIALIZED:
        /* First call, will do the init */
        ipcom_wait_queue_init(&wq);
        once->wq    = &wq;
        once->state = IPCOM_ONCE_STATE_RUNNING;
        break;
    case IPCOM_ONCE_STATE_RUNNING:
        /* Sleep until the init() function has been run */
        ret = ipcom_wait_queue_add_current_proc(once->wq,
                                                IPC_TIMEOUT_INFINITE,
                                                ipcom_mutex_unlock,
                                                ipcom_mutex_lock,
                                                ipcom_once_mutex);
        break;
    case IPCOM_ONCE_STATE_DONE:
        break;
    default:
        IP_PANIC();
        break;
    }

    /* Exit the once monitor */
    ipcom_mutex_unlock(ipcom_once_mutex);

    if (old_state == IPCOM_ONCE_STATE_UNINITIALIZED)
    {
        /* Do init call */
        ret = init(param);

        /* Enter the once monitor again */
        ipcom_mutex_lock(ipcom_once_mutex);

        /* Update the state to done */
        once->state = IPCOM_ONCE_STATE_DONE;

        /* All pending processes are unlinked from the wait-queue by
           this call, so it is safe to set once->wq to IP_NULL */
        ipcom_wait_queue_wakeup_all_procs(once->wq);
        once->wq = IP_NULL;

        /* Exit the once monitor */
        ipcom_mutex_unlock(ipcom_once_mutex);
    }

    return ret;
}
Пример #18
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;
}
/*
 *===========================================================================
 *                    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 */
}
Пример #20
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;
}
/*
 *===========================================================================
 *                      ipnet_ip_forward_mib_handler_ipCidrRouteTable
 *===========================================================================
 * Description: MIB handler for ipCidrRouteDest
 * Parameters: See file 'ipsnmp.h'
 * Returns: IPSNMP_ERROR_XXX
 *
 */
IP_STATIC Ip_s32
ipnet_ip_forward_mib_handler_ipCidrRouteTable(Ip_s32 cmd,
                                              char *id,
                                              Ipsnmp_varbind *vb,
                                              Ip_s32 magic,
                                              struct Ipsnmp_node_object *nodeobj)
{
    Ip_s32 lid, bestindex, ret = -1;
    char *iid;
    char *buf = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID);
    char *best = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID);

    if(buf == IP_NULL || best == IP_NULL)
    {
        ret = IPSNMP_ERROR_GENERROR;
        goto exit;
    }

    lid = ipsnmp_util_last_subid(nodeobj->id);
    ip_assert(lid >= 1 && lid <= 16);
    bestindex = ipnet_ip_forward_mib_table_search_ipCidrRouteTable(id, buf, best, cmd);
    if(bestindex == -2)
    {
        ret = IPSNMP_ERROR_GENERROR;
        goto exit;
    }
    else if(bestindex == -1)
    {
        ret = IPSNMP_ERROR_NOSUCHNAME;
        goto exit;
    }

    if(cmd == IPSNMP_MIB_COMMAND_GET || cmd == IPSNMP_MIB_COMMAND_NEXT)
    {
        iid = ipsnmp_create_iid_direct(nodeobj->id, best);
        if(iid == IP_NULL)
        {
            ret = IPSNMP_ERROR_GENERROR;
            goto exit;
        }

        ip_assert(routewalk.bestrt != IP_NULL);
        switch(lid)
        {
            case 1: /* ipCidrRouteDest */
                ret = ipsnmp_util_put_ipaddress(magic, iid, ip_ntohl(*(Ip_u32 *)routewalk.bestrt->hdr.key));
                break;
            case 2: /* ipCidrRouteMask */
                if(routewalk.bestrt->hdr.mask != IP_NULL)
                    ret = ipsnmp_util_put_ipaddress(magic, iid, ip_ntohl(*(Ip_u32 *)routewalk.bestrt->hdr.mask));
                else
                    ret = ipsnmp_util_put_ipaddress(magic, iid, 0xffffffff);
                break;
            case 3: /* ipCidrRouteTos */
                ret = ipsnmp_util_put_integer(magic, iid, 0);
                break;
            case 4: /* ipCidrRouteNextHop */
                if(IP_BIT_ISSET(routewalk.bestrt->hdr.flags, IPNET_RTF_GATEWAY))
                {
                    struct Ip_sockaddr_in *sa = (struct Ip_sockaddr_in *)routewalk.bestrt->gateway;
                    ret = ipsnmp_util_put_ipaddress(magic, iid, ip_ntohl(sa->sin_addr.s_addr));
                }
                else
                    ret = ipsnmp_util_put_ipaddress(magic, iid, 0);
                break;
            case 5: /* ipCidrRouteIfIndex */
                ret = ipsnmp_util_put_integer(magic, iid, routewalk.bestrt->netif->ipcom.ifindex);
                break;
            case 6: /* ipCidrRouteType */
                if(IP_BIT_ISSET(routewalk.bestrt->hdr.flags, IPNET_RTF_GATEWAY))
                    ret = ipsnmp_util_put_integer(magic, iid, 4);   /* remote */
                else
                    ret = ipsnmp_util_put_integer(magic, iid, 3);   /* local */
                break;
            case 7: /* ipCidrRouteProto */
                ret = ipsnmp_util_put_integer(magic, iid, 2);   /* local */
                break;
            case 8: /* ipCidrRouteAge */
                ret = ipsnmp_util_put_integer(magic, iid, 0);
                break;
            case 9: /* ipCidrRouteInfo */
                ret = ipsnmp_util_put_oid(magic, iid, "0.0");
                break;
            case 10: /* ipCidrRouteNextHopAS */
                ret = ipsnmp_util_put_integer(magic, iid, 0);
                break;
            case 11: /* ipCidrRouteMetric1 */
                ret = ipsnmp_util_put_integer(magic, iid, -1);
                break;
            case 12: /* ipCidrRouteMetric2 */
                ret = ipsnmp_util_put_integer(magic, iid, -1);
                break;
            case 13: /* ipCidrRouteMetric3 */
                ret = ipsnmp_util_put_integer(magic, iid, -1);
                break;
            case 14: /* ipCidrRouteMetric4 */
                ret = ipsnmp_util_put_integer(magic, iid, -1);
                break;
            case 15: /* ipCidrRouteMetric5 */
                ret = ipsnmp_util_put_integer(magic, iid, -1);
                break;
            case 16: /* ipCidrRouteStatus */
                ret = ipsnmp_util_put_integer(magic, iid, 1);   /* active */
                break;
            default:
                IP_PANIC();
                ret = IPSNMP_ERROR_GENERROR;
                break;
        }

        ipcom_free(iid);
    }

    if(cmd == IPSNMP_MIB_COMMAND_TEST || cmd == IPSNMP_MIB_COMMAND_SET)
    {
        (void)vb;
        switch(lid)
        {
            case 5: /* ipCidrRouteIfIndex */
            case 6: /* ipCidrRouteType */
            case 9: /* ipCidrRouteInfo */
            case 10: /* ipCidrRouteNextHopAS */
            case 11: /* ipCidrRouteMetric1 */
            case 12: /* ipCidrRouteMetric2 */
            case 13: /* ipCidrRouteMetric3 */
            case 14: /* ipCidrRouteMetric4 */
            case 15: /* ipCidrRouteMetric5 */
            case 16: /* ipCidrRouteStatus */
                ret = IPSNMP_ERROR_NOSUCHNAME;
                break;
            default:
                IP_PANIC();
                ret = IPSNMP_ERROR_GENERROR;
                break;
        }
    }

exit:
    if(buf != IP_NULL)
        ipcom_free(buf);
    if(best != IP_NULL)
        ipcom_free(best);
    return ret;
}
Пример #22
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;
}
Пример #23
0
/*
 *===========================================================================
 *                    ipcom_shell_run_extcmd
 *===========================================================================
 * Description: Starts a shell command process and delivers the command arguments
 *              and stdio socket to that process.
 * Parameters:  argc, argv - traditional command arguments
 *              stdio_fd - the standard input, output and error sock
 *              ppid - parent pid
 *              cmd_pid - shell command process id
 *
 * Returns:          1 : command process started
 *                   0 : not an external command
 *                  -1 : error
 *
 */
IP_PUBLIC Ip_err
ipcom_shell_run_extcmd(int argc, char **argv, Ip_fd *stdio_fd, Ip_pid_t ppid, Ip_u32 seqno, Ip_pid_t *cmd_pid, int *proc_index)
{
    Ipcom_proc_attr  attr;
    Ipcom_ipc        ipc;
    Ipcom_shellcmd_info  *sinfo;
    Ipcom_shell_cmd   *cmd = IP_NULL;
    Ipcom_shell_cmd   *tcmd;
    Ip_err retval;
    char procname[40];
    Ip_u32    stack = IPCOM_PROC_STACK_DEFAULT;
    Ip_pid_t  pid;

    pid = ipcom_getpid();
    ipcom_sprintf(procname, "ipcom_sc_0x%lx_%d", (Ip_u32)pid, *proc_index);

    /* Find command and max stack size (since we are reusing the process). */
    if (argc > 0)
    {
        for (tcmd = IPCOM_LIST_FIRST(&ipcom_shell_cmd_head); tcmd; tcmd = IPCOM_LIST_NEXT(&tcmd->cmd_list))
        {
            stack = (Ip_u32)IP_MAX(stack, tcmd->stack_size);
            if (cmd == IP_NULL && ipcom_strcmp(tcmd->name, argv[0]) == 0)
            {
                cmd = tcmd;
                if (*cmd_pid != 0)
                    break;
            }
        }
        if (cmd == IP_NULL)
            return 0;

        /* Start the shell_cmd process. */
        if (*cmd_pid == 0)
        {
            ipcom_proc_attr_init(&attr);
            attr.priority  = (Ip_u32)cmd->priority;
            attr.stacksize = stack;
            attr.flags |= IPCOM_PROC_FLAG_FP;
            if (ipcom_proc_acreate(procname, (Ipcom_proc_func)ipcom_shell_cmd, &attr, cmd_pid))
            {
                IPCOM_LOG0(ERR, "ipcom_shell_run_extcmd :: ipcom_proc_acreate() failed");
                goto fail;
            }
            ip_assert(*cmd_pid != 0);
        }
    }
    else
    {
        /* argc == 0 is used to kill the shell_cmd process. */
        ip_assert(*cmd_pid != 0);
    }

    /* Open IPC with ipcom_shell. */
    retval = ipcom_ipc_open(&ipc, procname, -1);
    if (retval != IPCOM_SUCCESS)
    {
        IPCOM_LOG2(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_open(%s) failed, ret = %d", procname, retval);
        goto fail;
    }

    /* Send a message to ipcom_shell. */
    sinfo = ipcom_ipc_malloc(sizeof(Ipcom_shellcmd_info));
    if (sinfo == IP_NULL)
    {
        IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_malloc() failed, ret = %d", retval);
        goto fail;
    }

    /* Fill in IPC info. */
    sinfo->argc = argc;
    if (argc > 0)
    {
        sinfo->hook  = cmd->hook;
        sinfo->argv  = argv;
        sinfo->fd    = *stdio_fd;
        sinfo->pid   = pid;
        sinfo->ppid  = ppid;
        sinfo->seqno = seqno;
#if IPCOM_USE_FILE != IPCOM_FILE_NONE
        if (ipcom_getcwd(sinfo->cwd, sizeof(sinfo->cwd)) == IP_NULL)
            ipcom_memset(sinfo->cwd, 0, sizeof(sinfo->cwd));
        else
            sinfo->cwd[sizeof(sinfo->cwd)-1] = '\0';
#endif
        sinfo->prio = cmd->priority;
    }

    /* Send the IPC info. */
    retval = ipcom_ipc_send(&ipc, sinfo);
    if (retval != IPCOM_SUCCESS)
    {
        IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_send() failed, ret = %d", retval);
        ipcom_ipc_free(sinfo);
        goto fail;
     }

    (void)ipcom_ipc_close(&ipc);

#ifdef IP_PORT_OSE5
    if (argc > 0)
    {
        /* OSE5 has process specific sockets -> donate child fd */
        ip_assert(*cmd_pid != 0);
        retval = (Ip_err)efs_donate_fd(*stdio_fd, *cmd_pid);
        if (retval != 0)
        {
            IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: efs_donate_fd, ret = %d", retval);
            goto fail;
        }
    }
#endif /* IP_PORT_OSE5 */

    /* Wait for exit message from shell_cmd process. */
    retval = ipcom_ipc_receive(IP_NULL, &sinfo, -1);
    if (retval != IPCOM_SUCCESS)
    {
        IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_receive(shell_cmd) failed, ret = %d", retval);
        goto fail;
    }
    ip_assert(argc > 0 || *(Ip_u32 *)sinfo == 1);
    if (*(Ip_u32 *)sinfo == 1)
    {
        *cmd_pid = 0;  /* shell command called ipcom_exit(). */
        (*proc_index)++;
    }
    else
    {
#ifdef IP_PORT_OSE5
        *stdio_fd = efs_receive_fd(0);
        if (*stdio_fd == -1)
        {
            IP_PANIC();
            goto fail;
        }
#endif
#if defined(IP_PORT_OSE) || defined(IP_PORT_OSE5)
        /* Change child socket owner (A must for OSE to work due to poor ipcom_block impl). */
        pid = ipcom_getpid();
        if (ipcom_socketioctl(*stdio_fd, IP_SIOCSPGRP, &pid) < 0)
        {
            IP_PANIC2();
            IPCOM_LOG1(WARNING, "ipcom_shell_run_extcmd :: ipcom_socketioctl(IP_SIOCSPGRP) failed, errno = %d", ipcom_errno);
        }
#endif

    }
    ipcom_ipc_free(sinfo);

    return 1;

 fail:
    if (ipcom_ipc_isopen(&ipc))
        (void)ipcom_ipc_close(&ipc);
    return -1;
}
Пример #24
0
/*
 *===========================================================================
 *                      ipnet_if_mib_handler_ifXTable
 *===========================================================================
 * Description: MIB handler for variables in ifXTable
 * Parameters: See file 'ipsnmp.h'
 * Returns: IPSNMP_ERROR_XXX
 *
 */
IP_STATIC Ip_s32
ipnet_if_mib_handler_ifXTable(Ip_s32 cmd,
                              char *id,
                              Ipsnmp_varbind *vb,
                              Ip_s32 magic,
                              struct Ipsnmp_node_object *nodeobj)
{
    Ip_s32       lid, ret = -1;
    Ip_s32       ifLinkUpDownTrapEnable = 0;
    char        *iid;
    char        *buf = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID);
    char        *best = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID);
    Ipnet_netif *best_netif;

    if (buf == IP_NULL || best == IP_NULL)
    {
        ret = IPSNMP_ERROR_GENERROR;
        goto exit;
    }

    lid = ipsnmp_util_last_subid(nodeobj->id);
    ip_assert((lid >= 1 && lid <= 5) || (lid >= 14 && lid <= 19));
    best_netif = ipnet_if_mib_table_search_ifTable(id, buf, best, cmd, &ret);
    if (best_netif == IP_NULL)
        goto exit;

    if (cmd == IPSNMP_MIB_COMMAND_GET || cmd == IPSNMP_MIB_COMMAND_NEXT)
    {
        iid = ipsnmp_create_iid_direct(nodeobj->id, best);
        if (iid == IP_NULL)
        {
            ret = IPSNMP_ERROR_GENERROR;
            goto exit;
        }

        switch(lid)
        {
            case 1: /* ifName */
                ret = ipsnmp_util_put_octetstring(magic, iid, (Ip_u8 *)best_netif->ipcom.name, ipcom_strlen(best_netif->ipcom.name));
                break;
            case 2: /* ifInMulticastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInMulticastPkts);
                break;
            case 3: /* ifInBroadcastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInBroadcastPkts);
                break;
            case 4: /* ifOutMulticastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutMulticastPkts);
                break;
            case 5: /* ifOutBroadcastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutBroadcastPkts);
                break;
            case 14: /* ifLinkUpDownTrapEnable */
                if (best_netif->ipcom.mib2.ifLinkUpDownTrapEnable == 0)
                    best_netif->ipcom.mib2.ifLinkUpDownTrapEnable = 1;
                ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.mib2.ifLinkUpDownTrapEnable);
                break;
            case 15: /* ifHighSpeed */
                if (best_netif->ipcom.type == IP_IFT_PPP)
                    ret = ipsnmp_util_put_gauge32(magic, iid, 0);
                else
                    ret = ipsnmp_util_put_gauge32(magic, iid, 100);
                break;
            case 16: /* ifPromiscuousMode */
                if (IP_BIT_ISSET(best_netif->ipcom.flags, IP_IFF_PROMISC))
                    ret = ipsnmp_util_put_integer(magic, iid, 1);
                else
                    ret = ipsnmp_util_put_integer(magic, iid, 2);
                break;
            case 17: /* ifConnectorPresent */
                ret = ipsnmp_util_put_integer(magic, iid, 2);
                break;
            case 18: /* ifAlias */
                ret = ipsnmp_util_put_octetstring(magic, iid, IP_NULL, 0);
                break;
            case 19: /* ifCounterDiscontinuityTime */
                ret = ipsnmp_util_put_timeticks(magic, iid, 0);
                break;
            default:
                IP_PANIC();
                ret = IPSNMP_ERROR_GENERROR;
                break;
        }

        ipcom_free(iid);
    }

    if (cmd == IPSNMP_MIB_COMMAND_TEST || cmd == IPSNMP_MIB_COMMAND_SET)
    {
        switch(lid)
        {
            case 14: /* ifLinkUpDownTrapEnable */
                ret = ipsnmp_util_get_integer(vb, &ifLinkUpDownTrapEnable);
                if (ret == IPSNMP_ERROR_NOERROR)
                {
                    if (ifLinkUpDownTrapEnable != 1 && ifLinkUpDownTrapEnable != 2)
                    {
                        ret = IPSNMP_ERROR_WRONGVALUE;
                    }
                }

                if (ret == IPSNMP_ERROR_NOERROR && cmd == IPSNMP_MIB_COMMAND_SET)
                {
                    best_netif->ipcom.mib2.ifLinkUpDownTrapEnable = ifLinkUpDownTrapEnable;
                }
                break;
            case 16: /* ifPromiscuousMode */
            case 18: /* ifAlias */
                ret = IPSNMP_ERROR_NOSUCHNAME;
                break;
            default:
                IP_PANIC();
                ret = IPSNMP_ERROR_GENERROR;
                break;
        }
    }

exit:
    if (buf != IP_NULL)
        ipcom_free(buf);
    if (best != IP_NULL)
        ipcom_free(best);
    return ret;
}
Пример #25
0
/*
 *===========================================================================
 *                      ipnet_if_mib_handler_ifTable
 *===========================================================================
 * Description: MIB handler for variables in ifTable
 * Parameters: See file 'ipsnmp.h'
 * Returns: IPSNMP_ERROR_XXX
 *
 */
IP_STATIC Ip_s32
ipnet_if_mib_handler_ifTable(Ip_s32 cmd,
                             char *id,
                             Ipsnmp_varbind *vb,
                             Ip_s32 magic,
                             struct Ipsnmp_node_object *nodeobj)
{
    Ip_s32          lid, ret = -1;
    Ipnet_netif    *best_netif;
    Ip_s32          ifAdminStatus = 0;
    char           *iid;
    char           *buf = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID);
    char           *best = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID);
    struct Ip_ifreq ifreq;
    Ip_fd           fd;

    if (buf == IP_NULL || best == IP_NULL)
    {
        ret = IPSNMP_ERROR_GENERROR;
        goto exit;
    }

    lid = ipsnmp_util_last_subid(nodeobj->id);
    ip_assert(lid >= 1 && lid <= 20);
    ip_assert(lid != 12 && lid != 18);
    best_netif = ipnet_if_mib_table_search_ifTable(id, buf, best, cmd, &ret);
    if (best_netif == IP_NULL)
        goto exit;

    if (cmd == IPSNMP_MIB_COMMAND_GET || cmd == IPSNMP_MIB_COMMAND_NEXT)
    {
        iid = ipsnmp_create_iid_direct(nodeobj->id, best);
        if (iid == IP_NULL)
        {
            ret = IPSNMP_ERROR_GENERROR;
            goto exit;
        }

        switch(lid)
        {
            case 1: /* ifIndex */
                ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.ifindex);
                break;
            case 2: /* ifDescr */
                ret = ipsnmp_util_put_octetstring(magic, iid, (Ip_u8 *)best_netif->ipcom.name, ipcom_strlen(best_netif->ipcom.name));
                break;
            case 3: /* ifType */
                ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.type);
                break;
            case 4: /* ifMtu */
                ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.mtu);
                break;
            case 5: /* ifSpeed */
                if (best_netif->ipcom.type == IP_IFT_PPP)
                    ret = ipsnmp_util_put_gauge32(magic, iid, IPCOM_DRV_PPP_BAUDRATE);
                else
                    ret = ipsnmp_util_put_gauge32(magic, iid, 100000000);
                break;
            case 6: /* ifPhysAddr */
                ret = ipsnmp_util_put_octetstring(magic, iid, best_netif->ipcom.link_addr, best_netif->ipcom.link_addr_size);
                break;
            case 7: /* ifAdminStatus */
                if (IP_BIT_ISSET(best_netif->ipcom.flags, IP_IFF_UP))
                    ret = ipsnmp_util_put_integer(magic, iid, 1);
                else
                    ret = ipsnmp_util_put_integer(magic, iid, 2);
                break;
            case 8: /* ifOperStatus */
                if (IP_BIT_ISSET(best_netif->ipcom.flags, IP_IFF_UP))
                    ret = ipsnmp_util_put_integer(magic, iid, 1);
                else
                    ret = ipsnmp_util_put_integer(magic, iid, 2);
                break;
            case 9: /* ifLastChange */
                ret = ipsnmp_util_put_timeticks(magic, iid, best_netif->ipcom.mib2.ifLastChange);
                break;
            case 10: /* ifInOctets */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInOctets);
                break;
            case 11: /* ifInUcastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInUcastPkts);
                break;
            case 13: /* ifInDiscards */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInDiscards);
                break;
            case 14: /* ifInErrors */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInErrors);
                break;
            case 15: /* ifInUnknownProtos */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInUnknownProtos);
                break;
            case 16: /* ifOutOctets */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutOctets);
                break;
            case 17: /* ifOutUcastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutUcastPkts);
                break;
            case 19: /* ifOutDiscards */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutDiscards);
                break;
            case 20: /* ifOutErrors */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutErrors);
                break;
            default:
                IP_PANIC();
                ret = IPSNMP_ERROR_GENERROR;
                break;
        }

        ipcom_free(iid);
    }

    if (cmd == IPSNMP_MIB_COMMAND_TEST || cmd == IPSNMP_MIB_COMMAND_SET)
    {
        switch(lid)
        {
            case 7: /* ifAdminStatus */
                ret = ipsnmp_util_get_integer(vb, &ifAdminStatus);
                if (ret == IPSNMP_ERROR_NOERROR)
                {
                    if (ifAdminStatus != 1 && ifAdminStatus != 2)
                    {
                        ret = IPSNMP_ERROR_WRONGVALUE;
                    }
                }

                if (ret == IPSNMP_ERROR_NOERROR && cmd == IPSNMP_MIB_COMMAND_SET)
                {
                    fd = ipnet_do_socket(IP_AF_INET, IP_SOCK_DGRAM, IP_IPPROTO_UDP, IP_FALSE);
                    if(fd != IP_INVALID_SOCKET)
                    {
                        /* Change interface status */
                        ipcom_memset(&ifreq, 0, sizeof(struct Ip_ifreq));
                        ipcom_strcpy(ifreq.ifr_name, best_netif->ipcom.name);
                        if (ipnet_sys_socketioctl(fd, IP_SIOCGIFFLAGS, &ifreq) < 0)
                        {
                            IPCOM_LOG1(ERR, "Failed to get interface flags: %s", ipcom_strerror(ipcom_errno));
                            ret = IPSNMP_ERROR_GENERROR;
                        }
                        if (ifAdminStatus == 1)
                            IP_BIT_SET(ifreq.ip_ifr_flags, IP_IFF_UP);
                        else
                            IP_BIT_CLR(ifreq.ip_ifr_flags, IP_IFF_UP);
                        if (ipnet_sys_socketioctl(fd, IP_SIOCSIFFLAGS, &ifreq) < 0)
                        {
                            IPCOM_LOG1(ERR, "Failed to set interface flags: %s", ipcom_strerror(ipcom_errno));
                            ret = IPSNMP_ERROR_GENERROR;
                        }
                        ipnet_sys_socketclose(fd);
                    }
                    else
                    {
                        IPCOM_LOG0(ERR, "Failed to create socket for ioctl call");
                        ret = IPSNMP_ERROR_GENERROR;
                    }
                }
                break;
            default:
                IP_PANIC();
                ret = IPSNMP_ERROR_GENERROR;
                break;
        }
    }

exit:
    if (buf != IP_NULL)
        ipcom_free(buf);
    if (best != IP_NULL)
        ipcom_free(best);
    return ret;
}
Пример #26
0
/*
 *===========================================================================
 *                    ipnet_rtnetlink_route_foreach_vr
 *===========================================================================
 * Description: Hash table foreach callback. Called once for each virtual
 *              router that exists in the system.
 * Parameters:  rtab  - route table
 *              param - callback parameters.
 * Returns:     -
 *
 */
IP_STATIC void
ipnet_rtnetlink_route_foreach_vr_family(Ipcom_route *rtab, Ipnet_rtnetlink_route_family_t *param)
{
    int                new_offs = 0;
    Ip_ptrdiff_t       table    = IPNET_ROUTE_GET_TABLE(rtab);
    Ip_u16             vr       = IPNET_ROUTE_GET_VR(rtab);
    Ipnet_route_entry  *rt      = IP_NULL;

    /* This traversal is already aborted */
    if (param->state.aborted)
        return;

    /* Only handle rtabs of selected address family */
    if (IPNET_ROUTE_GET_FAMILY(rtab) != param->family)
        return;

    /* Check if specific VR shall be dumped */
    if (IP_BIT_ISFALSE(param->nlmsg->nlmsg_flags, IP_NLM_F_VR_UNSPEC) && (param->mem->vr != IPCOM_VR_ANY) && (param->mem->vr != vr))
        return;

    /*
     * If this is a trailer message buffer, make sure it
     * starts dumping where the last message ended
     */
    if (param->state.cont)
    {
        Ipnet_route_entry  *rtt = (Ipnet_route_entry*)(*param->state.rt);

        /* Verify current state */
        if (*param->state.vr != vr || *param->state.table != table)
            return;

        if (rtt != IP_NULL)
        {
            rt = ipnet_route_first_entry(IPNET_ROUTE_GET_FAMILY(rtab),
                                         vr,
                                         table);
            while (rt != IP_NULL)
            {
                if (rt == rtt)
                    break;
                rt = ipnet_route_next_entry(rt);
            }
        }
    }


    /* Reset the continue variable; we're on the move again */
    param->state.cont = 0;

    /* Get first unless we've found one to continue from */
    if (rt == IP_NULL)
        rt = ipnet_route_first_entry(IPNET_ROUTE_GET_FAMILY(rtab),
                                     vr,
                                     table);

    /* */
    while (rt)
    {
        /* Do not dump the 255.255.255.255, 224.0.0.0/4 or IPv6 multicast routes. */
        /* Do not dump routes that are part of multipath routes either */
        if (IP_BIT_ISFALSE(rt->hdr.flags, IPNET_RTF_X_MCAST_RO | IPNET_RTF_X_BCAST_RO | IPNET_RTF_X_HIDDEN)
            && (rt->prev == IP_NULL))
        {
#ifdef IPCOM_USE_INET
            if (param->family == IP_AF_INET)
            {
                new_offs = ipnet_rtnetlink_ip4_route_fill_info (param->mem,
                                                                rt,
                                                                param->nlmsg->nlmsg_seq,
                                                                IP_RTM_NEWROUTE,
                                                                IP_NLM_F_MULTI);
            }
            else
#endif
#ifdef IPCOM_USE_INET6
            if (param->family == IP_AF_INET6)
            {
                new_offs = ipnet_rtnetlink_ip6_route_fill_info (param->mem,
                                                                rt,
                                                                param->nlmsg->nlmsg_seq,
                                                                IP_RTM_NEWROUTE,
                                                                IP_NLM_F_MULTI);
            }
            else
#endif
            {
                IP_PANIC();
            }

            if (new_offs < 0)
                goto aborted;
        }

        rt = ipnet_route_next_entry(rt);

        /* */
        if (rt && new_offs)
            goto aborted;
    }

    return;

aborted:
    param->state.aborted = 1;
    *param->state.rt     = (Ip_ptrdiff_t)rt;
    *param->state.table  = (Ip_ptrdiff_t)table;
    *param->state.vr     = (Ip_ptrdiff_t)vr;
}
/*
 *===========================================================================
 *                    ipnet_config_interface
 *===========================================================================
 * Description: Configures one interface if it exists and is UP.
 * Parameters:  fd - A socket descriptor
 *              ifname - The name of the interface to configure
 *              conf - The configuration to apply to the interface
 *              conf_len - Number of valid entries in the "conf" array
 *              pass - First pass (1) will add all addresses
 *                     second pass (2) will add other things like gateways
 * Returns:     0 = success
 *             <0 = error code
 *
 */
IP_STATIC int
ipnet_config_interface(Ip_fd fd, char *ifname, char *conf[], int conf_len, int pass)
{
    char *option;
    char *option_org;
    char *token;
    int   i;
    int   err;

    ip_assert(pass == 1 || pass == 2);

    if (ipcom_if_nametoindex(ifname) == 0)
    {
        /* Interface does not exist */
        IPCOM_LOG1(INFO, "%s not attached - skipping", ifname);
        return 0;
    }

    if (0 > (err = ipnet_config_bring_up_if(ifname)))
    {
        IPCOM_LOG1(INFO, "Failed to bring UP %s", ifname);
        return 0;
    }

    for (i = 0; i < conf_len; i++)
    {
        option_org = option = ipcom_strdup(conf[i]);
        if (option == IP_NULL)
            return -IP_ERRNO_ENOMEM;

        token = ipcom_strtok_r(option, " \t/", &option);

        if (token == IP_NULL || ipcom_strcmp(token, "ifname") == 0)
        {
            /* Ignore */
            err = 0;
        }
#ifdef IPCOM_USE_INET
        else if (ipcom_strcmp(token, "inet") == 0)
        {
            if (pass == 1)
                err = ipnet_config_add_inet_addr(fd, ifname, option);
        }
        else if (ipcom_strcmp(token, "gateway") == 0)
        {
            if (pass == 2)
                err = ipnet_config_add_gateway(fd, ifname, option);
        }
#else
        else if (ipcom_strcmp(token, "inet") == 0
                 || ipcom_strcmp(token, "gateway") == 0)
            IP_NOOP;
#endif /* IPCOM_USE_INET */
#ifdef IPCOM_USE_INET6
        else if (ipcom_strcmp(token, "inet6") == 0)
        {
            if (pass == 1)
                err = ipnet_config_add_inet6_addr(fd, ifname, option);
        }
        else if (ipcom_strcmp(token, "gateway6") == 0)
        {
            if (pass == 2)
                err = ipnet_config_add_gateway6(ifname, option);
        }
#else
        else if (ipcom_strcmp(token, "inet6") == 0
                 || ipcom_strcmp(token, "gateway6") == 0)
            IP_NOOP;
#endif /* IPCOM_USE_INET6 */
        else if (ipcom_strcmp(token, "devname") != 0)
            /* Invalid configuration */
            err = -IP_ERRNO_EINVAL;

        ipcom_free(option_org);
        if (err != 0)
        {
            if (err < 0)
                err = -err;
            IPCOM_LOG4(ERR, "failed on '%s' when configuring %s: %s (%d)",
                conf[i], ifname, ipcom_strerror(err), err);
            IP_PANIC();
            break;
        }
    }

    return err;
}