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

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

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

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

    ipcom_free(dup_bit_str);
    return IP_TRUE;
}
/*
 *===========================================================================
 *                    ipcom_drv_ppp_if_init
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_PUBLIC int
ipcom_drv_ppp_if_init(const char *ifname, const char *devname, int unit)
{
    Ipcom_netif         *netif;
    Ipcom_pdrv_ppp      *pdrv;
    Ipcom_drv_ppp_link  *plink;

    /* Allocate memory for the network interface structure */
    netif  = ipcom_if_malloc(IP_IFT_PPP);
    if (netif == IP_NULL)
        return IPCOM_ERR_FAILED;

    /* Set up the driver downcall function pointers */
    netif->drv_ioctl  = ipcom_drv_ppp_ioctl;
    netif->drv_output = ipcom_drv_ppp_output;

    /* Set interface name */
    ipcom_strncpy(netif->name, ifname, sizeof(netif->name) - 1);

    /* Allocate and init memory for the driver structure */
    pdrv = ipcom_malloc(sizeof(*pdrv));
    if (pdrv == IP_NULL)
        goto fail;
    ipcom_memset(pdrv, 0, sizeof(*pdrv));
    netif->pdrv = pdrv;
    plink = &pdrv->plink[unit];
    if (devname == IP_NULL)
    {
        char value[64];
        Ip_size_t value_size = sizeof(value);
        devname = ipcom_sysvar_get_conf("devname", value, &value_size,
                                        IP_NULL, ifname);
    }
    if (devname != IP_NULL)
        plink->devname = ipcom_strdup(devname);
    plink->sv[0] = plink->sv[1] = -1;

    /* Initialize PPP link */
    plink->index    = unit;
    plink->netif    = netif;
    plink->out_q_nr = 0;
    plink->fd       = -1;
    plink->baudrate = ipcom_sysvar_get_conf_as_int("ipppp.baudrate", IP_NULL, netif->name);
    if (plink->baudrate <= 0)
        plink->baudrate = IPCOM_DRV_PPP_BAUDRATE;

    /* Attach the interface. */
    if (ipcom_if_attach(netif) < 0)
        goto fail;

    /* Success. */
    return IPCOM_SUCCESS;

 fail:
    if (pdrv != IP_NULL)
        ipcom_free(pdrv);
    ipcom_if_free(netif);
    return IPCOM_ERR_FAILED;
}
/*
 *===========================================================================
 *                    ipcom_create_ifaddrs_entry
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC struct Ip_ifaddrs *
ipcom_create_ifaddrs_entry(const char                *ifname,
                           struct Ipnet_if_msghdr    *ifm,
                           struct Ipnet_ifa_msghdr   *ifa,
                           struct Ip_sockaddr        **addrs)
{
    /**/
    struct Ip_ifaddrs        *nifa = ipcom_calloc(1, sizeof(*nifa));

    if (nifa == IP_NULL)
        return IP_NULL;

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

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

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

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

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

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


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

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

    return nifa;

fail:
    ipcom_ifaddrs_free(nifa);
    return IP_NULL;
}
/*
 *===========================================================================
 *                    ipnet_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;
}
Exemple #5
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;
}
/*
 *===========================================================================
 *                    ipcom_shellalias_remove
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipcom_shellalias_set(char   *name,
                     char   *cmd)
{
    struct Ipcom_shellalias_alias *alias;

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

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

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

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

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

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

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

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

        case IPCOM_ERR_FAILED:
        default:
            goto fail;
        }

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

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

        /* Success */
        return IPCOM_SUCCESS;
    }

    /* No memory */
    return -IP_ERRNO_ENOMEM;

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

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

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

    /* Free the structure */
    ipcom_free(alias);
    return -IP_ERRNO_ENOMEM;
}
/*
 *===========================================================================
 *                    ipnet_cmd_sysctl_do
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:     0 on success, -1 on syntax error. > 0 unknown key
 *
 */
IP_STATIC int
ipnet_cmd_sysctl_do(Ip_bool         set,
                    const char      *var)
{
    char                    *dupval = ipcom_strdup(var);
    char                    *tok;
    char                    *ntok;
    char                    *last;
    char                    *value      = IP_NULL;
    char                    *names[12];
    int                     nameslen    = 0;
    int                     name[12];
    int                     namelen     = 0;
    const Ipnet_cmd_sysctl  *current    = ipnet_sysctl_base_table;
    const Ipnet_cmd_sysctl  *ctl        = IP_NULL;
    int                     err         = -1;
    const char              *netif      = IP_NULL;
    int                     argbit      = IPNET_CMD_SYSCTL_NETIF_NO;

    if (set)
    {
        tok = ipcom_strtok_r(dupval, "=", &last);
        if (tok == IP_NULL)
            goto done;
        value = ipcom_strtok_r(IP_NULL, "=", &last);
        if (value == IP_NULL)
            goto done;
    }

    err = 1;
    tok = ipcom_strtok_r(dupval, ".", &last);
    while (tok != IP_NULL)
    {
        ntok = ipcom_strtok_r(IP_NULL, ".", &last);
        ctl = current;

        /* */
        while (ctl->comp != IP_NULL)
        {
            if (IP_BIT_ISSET(ctl->argument, argbit))
            {
                if (ipnet_cmd_sysctl_strcmp(ctl, tok, name, &namelen, names, &nameslen) == IP_TRUE)
                {
                    if (ctl->type == IPNET_CMD_SYSCTL_TYPE_TRUNK)
                    {
                        current = ctl->ntable;
                        break;
                    }
                    else
                    {
                        /* EOL */
                        if (ntok)
                            goto done;

                        /* Check any cached netif's */
                        if (netif)
                        {
                            name[namelen++] = ipcom_if_nametoindex(netif);
                            netif = IP_NULL;
                        }

                        /* We're done */
                        if (ipnet_cmd_sysctl_exec(ctl, set, name, namelen, names, nameslen, value))
                            err = 0;

                        /**/
                        goto done;
                    }
                }
            }

            ctl++;
        }

        /* We've failed */
        if (ctl->comp == IP_NULL)
        {
            /* Check interface */
            if (argbit == IPNET_CMD_SYSCTL_NETIF_NO && ipcom_if_nametoindex(tok) != 0)
            {
                netif               = tok;
                names[nameslen++]   = tok;
                argbit = IPNET_CMD_SYSCTL_NETIF_YES;
            }
            else
            {
                ipcom_printf("sysctl: Failed to parse subkey %s"IP_LF, tok);
                goto done;
            }
        }
        else
        {
            argbit  = IPNET_CMD_SYSCTL_NETIF_NO;
            netif   = IP_NULL;
        }

        /* Store next */
        tok     = ntok;
    }

    /* Do dump */
    if (set == IP_FALSE)
    {
        ipnet_cmd_sysctl_print_ctl(current,
                                   name,
                                   namelen,
                                   names,
                                   nameslen,
                                   IP_NULL);
        err = 0;
    }

done:
    ipcom_free(dupval);
    return err;
}
/*
 *===========================================================================
 *                    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;
}