/*
 *===========================================================================
 *                    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);
}
/*
 *===========================================================================
 *                  ipnet_pkt_queue_mbc_insert_default_queue
 *===========================================================================
 * Description: Inserts a FIFO queue in the MBC.
 * Parameters:  pq - Pointer to where the new FIFO should be stored.
 *              netif - The interface the queue belongs to.
 * Returns:     0  = success
 *              <0 = error code
 *
 */
IP_STATIC int
ipnet_pkt_queue_mbc_insert_default_queue(Ipnet_pkt_queue_mbc *q, int band)
{
    struct Ipnet_ifqueue fifo;

    ipcom_strcpy(fifo.ifq_name, q->hdr.netif->ipcom.name);
    ipcom_strcpy(fifo.ifq_type, "fifo");
    if (q->bands[band] == IP_NULL)
        fifo.ifq_id = IP_IFQ_ID_NONE;
    else
        fifo.ifq_id = q->bands[band]->id;
    fifo.ifq_parent_id            = q->hdr.id;
    fifo.ifq_data.fifo.fifo_limit = IPNET_PKT_QUEUE_DEFAULT_FIFO_SIZE;
    return ipnet_pkt_queue_new(&fifo, q->hdr.netif, &q->bands[band]);
}
/*
 *===========================================================================
 *                    ipdnsc_hostent_insert_name
 *===========================================================================
 * Description: Inserts a host name in a hostent structure
 * Parameters:  he - pointer to the hostent structure
 *              name - the name to insert
 * Returns:     0 for OK, -1 for fail.
 */
IP_GLOBAL Ip_s32
ipdnsc_hostent_insert_name(struct Ip_hostent *he, char *name)
{
    if (he == IP_NULL)
        return -1;

    if (ipcom_strlen(name) > (IPDNSC_MAXNAME-1))
        return -1;

    /* Free the memory for the current name if any */
    if (he != IP_NULL && he->h_name != IP_NULL)
    {
        ipcom_free(he->h_name);
    }
    /* Allocate storage for the host name */
    he->h_name = ipcom_malloc(ipcom_strlen(name)+1);
    if (he->h_name == IP_NULL)
    {
        return -1;
    }
    /* Copy the host name */
    ipcom_strcpy(he->h_name, name);

    return 0;

}
/*
 *===========================================================================
 *                      ipnet_cmd_qc_del_queue
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_cmd_qc_del_queue(Ipnet_cmd_qc *p)
{
    ipcom_strcpy(p->p.ifq.ifq_type, "none");
    if (ipcom_socketioctl(p->fd, IPNET_SIOCSIFQUEUE, &p->p.ifq) < 0)
    {
        ipcom_printf("Failed to delete the queue: %s"IP_LF, ipcom_strerror(ipcom_errno));
        return -1;
    }
    return 0;
}
IP_PUBLIC char *
ipcom_strdup(const char *s1)
{
    char *s2;

    s2 = ipcom_malloc(ipcom_strlen(s1) + 1);
    if(s2 == IP_NULL)
        return IP_NULL;

    ipcom_strcpy(s2, s1);
    return s2;
}
/*
 *===========================================================================
 *                    ipnet_nat_proxy_dns_ptr_name
 *===========================================================================
 * Description: Convert an Internet address to a domain name.
 * Parameters:  buf    - buffer to store the domain name in.
 *              buflen - length of domain name buffer.
 *              addr   - pointer to Internet address.
 *              family - address family.
 *              zone   - top level domain.
 * Returns:     The length of the domain name or -1 if failed.
 */
IP_STATIC int
ipnet_nat_proxy_dns_ptr_name(Ip_u8 *buf, int buflen, Ip_u8 *addr, int family, Ip_u8 *zone)
{
    int i, j, second, zonelen;
    Ip_u8 tmp;

    zonelen = ipcom_strlen((char *)zone) + 1;
    i = 0;
    if (family == IP_AF_INET)
    {
        /* Reverse ipv4 address */
        for (j=3; j>=0; j--)
        {
            second = 0;

            /* possible hundreds digit */
            tmp = addr[j] / 100;
            if (tmp)
            {
                if (buflen - i < 1)
                    return -1;                  /* Too small buffer */
                buf[i++] = '0' + tmp;
                second = 1;
            }
            tmp = addr[j] % 100;

            /* possible tens digit */
            if ((tmp / 10) || second)
            {
                if (buflen - i < 1)
                    return -1;                  /* Too small buffer */
                buf[i++] = '0' + tmp / 10;
            }

            /* always print ones digit */
            if (buflen - i < 2)
                return -1;                      /* Too small buffer */
            buf[i++] = '0' + tmp % 10;
            buf[i++] = '.';
        }

        /* Append the zone */
        if (buflen - i < zonelen)
            return -1;                          /* Too small buffer */
        ipcom_strcpy((char *)&buf[i], (char *)zone);
        i += zonelen;
    }
    return i;
}
Beispiel #7
0
int get_ip( char * ifname)
{ 
	struct Ip_ifreq ifr;
	int fd;
	int addr;
	
	        fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
	
	ipcom_memset(&ifr,0,sizeof(ifr));
	ipcom_strcpy(ifr.ifr_name, ifname); 
	if (ipcom_socketioctl(fd, IP_SIOCGIFADDR, &ifr) != IP_SOCKERR)
	{ 
		addr =((struct Ip_sockaddr_in *)&ifr.ip_ifr_addr)->sin_addr.s_addr;
		
	return addr;
	}
}
Beispiel #8
0
/*
 *===========================================================================
 *                       ipppp_work_alloc
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC struct Ipppp_action_work *
ipppp_work_alloc(Ipcom_netif *netif, int action, void *data)
{
    struct Ipppp_action_work *work;

    work = ipcom_malloc(sizeof(*work));
    if (work)
    {
        ipcom_strcpy(work->ifname, netif->name);
        work->ifindex    = netif->ifindex;
        work->link_index = netif->link_index;
        work->action     = action;
        work->data       = data;
    }

    return work;
}
/*
 *===========================================================================
 *                      ipnet_cmd_qc_parse_dev
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_cmd_qc_parse_dev(Ipnet_cmd_qc *p)
{
    if (p->argc < 2 || ipcom_strcmp(*p->argv, "dev") != 0)
    {
        ipcom_printf("expected 'dev <if>'" IP_LF);
        return -IP_ERRNO_EINVAL;
    }
    ipnet_cmd_qc_next_arg(p);
    if (ipcom_if_nametoindex(*p->argv) == 0)
    {
        ipcom_printf("'%s' is not a valid interface name" IP_LF, *p->argv);
        return -IP_ERRNO_EINVAL;

    }
    ipcom_strcpy(p->p.ifq.ifq_name, *p->argv);
    ipnet_cmd_qc_next_arg(p);
    return 0;
}
/*
 *===========================================================================
 *                    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);
}
/*
 *===========================================================================
 *                      ipnet_cmd_qc_parse_queue_type
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_cmd_qc_parse_queue_type(Ipnet_cmd_qc *p)
{
    Ipnet_cmd_qc_type_handler *h;

    if (p->argc < 1)
    {
        ipcom_printf("no queue type specified" IP_LF);
        return -IP_ERRNO_EINVAL;
    }

    ipcom_strcpy(p->p.ifq.ifq_type, *p->argv);
    ipnet_cmd_qc_next_arg(p);
    h = ipnet_cmd_qc_get_type_handler(p->p.ifq.ifq_type);
    if (h)
        return h->add(p);

    return -IP_ERRNO_EINVAL;
}
/*
 *===========================================================================
 *                    ipdnsc_hostent_insert_alias
 *===========================================================================
 * Description: Inserts an alias name in a hostent structure
 * Parameters:  he - pointer to the hostent structure
 *              name - the name to insert
 * Returns:     0 for OK, -1 for fail.
 */
IP_GLOBAL Ip_s32
ipdnsc_hostent_insert_alias(struct Ip_hostent *he, char *name)
{
    Ip_s32 num_alias, i=0;
    char **tmp;

    if (ipcom_strlen(name) > (IPDNSC_MAXNAME-1))
        return -1;

    /* Find out the current number of aliases */
    num_alias = ipdnsc_hostent_alias_count(he);

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

    /* Allocate memory for the alias */
    he->h_aliases[num_alias-1] = ipcom_malloc(ipcom_strlen(name)+1);
    if (he->h_aliases[num_alias-1] == IP_NULL)
    {
        /* We have to free to whole list here */
        while (he->h_aliases[i] != IP_NULL)
        {
		    ipcom_free(he->h_aliases[i]);
            i++;
        }
        /* Free the alias list */
	    ipcom_free(he->h_aliases);
        he->h_aliases = IP_NULL;
        return -1;
    }

    /* Set the alias */
    ipcom_strcpy(he->h_aliases[num_alias-1], name);

    /* Null terminate the list */
    he->h_aliases[num_alias] = IP_NULL;

    return 0;

}
/*
 *===========================================================================
 *                    ipnet_loopback_attach
 *===========================================================================
 * Description: Create and attach a loopback interface.
 * Parameters:
 * Returns:     0 = success, <0 = error code.
 *
 */
IP_GLOBAL int
ipnet_loopback_attach(Ip_u16 vr, char *name)
{
    Ipcom_netif *loopback_if;
    int          ret;

    /* Allocate loopback interface */
    loopback_if = ipcom_if_malloc(IP_IFT_LOOP);
    if (loopback_if == IP_NULL)
        return -IP_ERRNO_ENOMEM;
    ((Ipnet_netif *)loopback_if)->vr_index = vr;

    ipcom_strcpy(loopback_if->name, name);

    /* Attach loopback interface */
    ret = ipnet_sys_if_attach(loopback_if);
    if (ret < 0)
      return ret;

    /* Success. */
    return 0;
}
/*
 *===========================================================================
 *                    ipnet_nat_proxy_sip_localaddrprocess
 *===========================================================================
 * Description: Process the private transport address
 * Parameters:  pmsgstr    - pointer to message
 *              pipaddrstr - pointer to buffer for the local address string
 *              pgaddrstr  - pointer to buffer for the gloab address string
 *              pcallid    - pointer to the call id string
 *              type       - type of search
 *              ppend      - pointer to pointer to last byte of message
 * Returns:     The next character position after the parsed string or
 *	            IP_NULL if parse fails
 */
IP_STATIC char *
ipnet_nat_proxy_sip_localaddrprocess(char *pmsgstr,
                                     char *pipaddrstr,
                                     char *pgaddrstr,
                                     char *pcallid,
                                     int  type,
                                     Ipnet_nat_proxy_param *param,
                                     char **ppend)
{
    int localport, newport;
    int len, diff;
    Ip_u32 ipaddr;
    char *pstart;
    char tmpholder[30];
    Ipnet_nat_proxy_tuple proxy_tuple;

    (void)pcallid;
    SIP_SKIP_SPACES(pmsgstr);

    pstart = pmsgstr;
    pmsgstr = ipnet_nat_proxy_sip_addrportstrparse(pmsgstr, &ipaddr, &localport, type);

    if (pmsgstr == IP_NULL)
        return IP_NULL;

    if (!localport)
        localport = SIP_DEFAULT_PORT;

    if (type == SIP_ADDRESS_PORT_STRING)
    {
        ipaddr = ip_htonl(ipaddr);
        (void)ipcom_inet_ntop(IP_AF_INET, &ipaddr, pipaddrstr, 16);
        ipaddr = ip_ntohl(ipaddr);
    }
    else  /* PORT string only */
    {
        ipaddr = ipcom_inet_addr(pipaddrstr);
        ipaddr = ip_ntohl(ipaddr);
    }

    /* make sure it is the private address, otherwise no translation */

    if (ipaddr != param->tuple.private_addr)
        return pmsgstr;

    /* create a bind entry for this transport address if it hasn't been created yet */
    if (param->tuple.private_port != localport)
    {
        ipcom_memset(&proxy_tuple, 0, sizeof(proxy_tuple));
        proxy_tuple.protocol     = IP_IPPROTO_UDP;
        proxy_tuple.private_addr = ipaddr;
        proxy_tuple.private_port = localport;
        newport = ipnet_nat_proxy_add_mapping(&proxy_tuple,
                                              IPNET_NAT_SIP_ENTRY_MEDIA_TIMEOUT,
                                              param->mapping,
                                              IP_FALSE,         /* Use port translation */
                                              IP_TRUE,          /* Inbound session */
                                              IP_NULL,
                                              IP_NULL);

        if (newport < 0)
        {
            IPCOM_LOG2(ERR, "ipnet_nat_proxy_sip_localaddrprocess() :: Failed to add mapping for address = 0x%08x, port = %d",
                       ipaddr, localport);
        }
        else
        {
            IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_sip_localaddrprocess() :: Added mapping for address = 0x%08x, port = %d",
                       ipaddr, localport);
        }
    }
    else
    {
        newport = param->nat_port;
        IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_sip_localaddrprocess() :: Mapping already existed for address = 0x%08x, port = %d",
                   ipaddr, localport);
    }

    /* compose the new modified string */

    len = 0;
    if (type == SIP_ADDRESS_PORT_STRING)
    {
        ipaddr = ip_htonl(param->nat_addr);
        (void)ipcom_inet_ntop(IP_AF_INET, &ipaddr, tmpholder, 16);
        ipcom_strcpy(pgaddrstr, tmpholder);
        len = ipcom_strlen(tmpholder);
        tmpholder[len++]= ':';
    }
    ipcom_sprintf(tmpholder + len, "%d", newport);

    IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_localaddrprocess() new str: %s", tmpholder);


    if (ipnet_nat_proxy_sip_modmsg(tmpholder, ipcom_strlen(tmpholder),
                                   pstart, pmsgstr - pstart, ppend) < 0)
    {
        return IP_NULL;
    }

    diff = ipcom_strlen(tmpholder) - (pmsgstr - pstart);
    return pmsgstr + diff;
}
IP_PUBLIC Ip_err
ipcom_sysvar_ext_setv(const Ipcom_sysvar_ext entries[], int flags)
{
    /* !!TODO: make atomic */
    int i;
    int len = 0;
    int  param_len = 0;
    char *sysvar_name = IP_NULL;
    char *sysvar_param = IP_NULL;
    char *conf = IP_NULL;
    char *last = IP_NULL;
    char *value = IP_NULL;
    char *ifparam = IP_NULL;
    Ip_err err = IPCOM_SUCCESS;

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

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

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

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

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

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

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

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

done:
    ipcom_free(sysvar_name);
    if (sysvar_param)
        ipcom_free(sysvar_param);
    return err;
}
/*
 *===========================================================================
 *                      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;
}
/*
 *===========================================================================
 *                         ipsecctrl_flows
 *===========================================================================
 */
static int
ipsecctrl_flows(Argvars *vars)
{
    Ipipsec_ctrl_selector   sel;
    char   srcport[32], dstport[32];
    int    num = 0;
    char   str[IP_INET6_ADDRSTRLEN];
    char   str2[IP_INET6_ADDRSTRLEN+1];

    ipcom_printf("Flows:"IP_LF);

    sel.Index = 0;  /* get first selector. */

    /* Get and print the Selectors in MIB format. */
    for (;;)
    {
        /* Get first/next Selector */
        if (ipcom_socketioctl(vars->fd, IP_SIOCXIPSEC_SELECTOR, &sel) < 0)
        {
            ipcom_printf("ipsecctrl: ipcom_socketioctl(SELECTOR) failed (%s)"IP_LF,
                         ipcom_strerror(ipcom_errno));
            return -1;
        }

        if (sel.Index == 0)
            break;

        /* Print selector aka flow: */
        num++;
        ipcom_printf("[%ld] :: %s ", sel.Index, FLOW_TYPE(sel.flowtype));

        if (sel.flowpri != 0)
            ipcom_printf("pri=%d ", (signed char)sel.flowpri);

        /* source */
        if (sel.LocalPort != sel.LocalMaxPort)
            ipcom_sprintf(srcport, "%d-%d",
                          (int)ip_ntohs(sel.LocalPort), (int)ip_ntohs(sel.LocalMaxPort));
        else if (sel.LocalPort == 0)
            ipcom_strcpy(srcport, "any");
        else
            ipcom_sprintf(srcport, "%d", (int)ip_ntohs(sel.LocalPort));
        if (ipcom_memcmp(&sel.LocalId, &sel.LocalMaxId, sizeof(union Ip_in_addr_union)))
            ipcom_sprintf(str2, "-%s",
                          ipcom_inet_ntop(sel.domain, &sel.LocalMaxId, str, sizeof(str)));
        else
            *str2 = '\0';
        ipcom_printf("src=%s%s/%d:%s ",
                     ipcom_inet_ntop(sel.domain, &sel.LocalId, str, sizeof(str)),
                     str2,
                     ipipsec_addrmasklen(sel.domain, (Ip_u8 *)&sel.local_mask),
                     srcport);

        /* destination */
        if (sel.RemotePort != sel.RemoteMaxPort)
            ipcom_sprintf(dstport, "%d-%d",
                          (int)ip_ntohs(sel.RemotePort), (int)ip_ntohs(sel.RemoteMaxPort));
        else if (sel.RemotePort == 0)
            ipcom_strcpy(dstport, "any");
        else
            ipcom_sprintf(dstport, "%d", (int)ip_ntohs(sel.RemotePort));
        if (ipcom_memcmp(&sel.RemoteId, &sel.RemoteMaxId, sizeof(union Ip_in_addr_union)))
            ipcom_sprintf(str2, "-%s",
                          ipcom_inet_ntop(sel.domain, &sel.RemoteMaxId, str, sizeof(str)));
        else
            *str2 = '\0';
        ipcom_printf("dst=%s%s/%d:%s ",
                     ipcom_inet_ntop(sel.domain, &sel.RemoteId, str, sizeof(str)),
                     str2,
                     ipipsec_addrmasklen(sel.domain, (Ip_u8 *)&sel.remote_mask),
                     dstport);

        ipcom_printf("%s", ipcom_ipproto_name(sel.Protocol));
        switch (sel.Protocol)
        {
        case IP_IPPROTO_ICMP:
        case IP_IPPROTO_ICMPV6:
            if (sel.ports[0] || sel.ports[1])
                ipcom_printf(" type=%d code=%d", sel.ports[0], sel.ports[1]);
            break;
        case IP_IPPROTO_MH:
            if (sel.ports[0])
                ipcom_printf(" type=%d", sel.ports[0]);
            break;
        default:
            break;
        }

        /* Print SA */
        if (sel.sa.domain)
        {
            if (sel.sa.domain == IPIPSEC_AF_BYPASS)
                ipcom_printf(" %s SA: %s",
                             sel.direction == IPIPSEC_SADIR_INPUT ? "<-" :
                             sel.direction == IPIPSEC_SADIR_OUTPUT ? "->" : "--",
                             IPSECSATYPENAME(sel.sa.satype));
            else
                ipcom_printf(" %s SA: %s spi=0x%lx src=%s dst=%s",
                             sel.direction == IPIPSEC_SADIR_INPUT ? "<-" :
                             sel.direction == IPIPSEC_SADIR_OUTPUT ? "->" : "--",
                             IPSECSATYPENAME(sel.sa.satype),
                             ip_ntohl(sel.sa.spi_n),
                             ipcom_inet_ntop(sel.sa.domain, &sel.sa.src, str, sizeof(str)),
                             ipcom_inet_ntop(sel.sa.domain, &sel.sa.dst, str2, sizeof(str2)));
        }
        else
            ipcom_printf(" %s SA: none",
                         sel.direction == IPIPSEC_SADIR_INPUT ? "<-" :
                         sel.direction == IPIPSEC_SADIR_OUTPUT ? "->" : "--");
        ipcom_printf(IP_LF);
    }
    ipcom_printf("Total of %d flows."IP_LF, num);

    return 0;
}
Beispiel #18
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;
}
Beispiel #19
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_config_add_inet6_addr
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_config_add_inet6_addr(Ip_fd fd, char *ifname, char *option)
{
    char *opt;
    char *inet6_addr;
    char *prefix_len;
    char *argv[] = {
        "ifconfig",
        "-silent",
        IP_NULL,
        "inet6",
        "add",
        IP_NULL,
        IP_NULL,
        IP_NULL,
        IP_NULL,
        IP_NULL,
        IP_NULL
    };
    int argc = 6;
    char inet6_addr_str[IP_INET6_ADDRSTRLEN];
    char prefixlen_str[4];

    argv[2] = ifname;

    for (;;)
    {
        /* Parse options */
        opt = ipcom_strtok_r(option, " \t/", &option);
        if (opt == IP_NULL)
        {
            IPCOM_LOG0(ERR, "too few arguments");
            return -IP_ERRNO_EINVAL;
        }
        if (ipcom_strcmp(opt, "tentative") == 0)
            argv[argc++] = opt;
        else
            break;
    }

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

        ipcom_strcpy(ethreq.ethr_name, ifname);
        if (ipcom_socketioctl(fd, IP_SIOCXETHGINET6, &ethreq) < 0)
        {
            IPCOM_LOG1(ERR, "Failed to read the IPv6 address from the driver for %s", ifname);
            return ipcom_errno;
        }
        inet6_addr = inet6_addr_str;
        (void) ipcom_inet_ntop(IP_AF_INET6, &ethreq.ethru.inet6.addr,
                               inet6_addr_str, sizeof(inet6_addr_str));

        ipcom_sprintf(prefixlen_str, "%u", ethreq.ethru.inet6.prefixlen);
        prefix_len = prefixlen_str;
    }
    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[5] = inet6_addr;
    argv[argc++] = "prefixlen";
    argv[argc++] = prefix_len;

    return ipnet_config_cmd_ifconfig(argc, argv);
}