/*
 *===========================================================================
 *                    ipcom_drv_eth_filter_add_mcast_addr
 *===========================================================================
 * Description: Adds a multicast Ethernet address that should be passed
 *              by the filter.
 * Parameters:	filter - A filter to where the address should be added.
 *              eth_mcast_addr - The address to add.
 * Returns:	    0 = success, <0 = error code.
 *
 */
IP_PUBLIC int
ipcom_drv_eth_filter_add_mcast_addr(Ipcom_drv_eth_filter *filter,
                                    Ip_u8 eth_mcast_addr[IPCOM_DRV_ETH_ADDR_SIZE])
{
    int i;
    int insert = -1;

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

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

    /* Add this multicast address */
    filter->ref[insert] = 1;
    ipcom_memcpy(filter->mcast_addr[insert], eth_mcast_addr, IPCOM_DRV_ETH_ADDR_SIZE);
    return 0;
}
示例#2
0
/*
 *===========================================================================
 *                    ipnet_nat_proxy_sip_keyfind
 *===========================================================================
 * Description: Find a string in a structured message.
 *              This routine searches a string in a structured message.
 *              It assumes the searched string always starts at the beginning
 *              of each line of data terminated by \r\n characters. A message
 *              should be terminated by \r\n preceded by the line terminator
 *              \r\n.
 * Parameters:  pdata     - pointer to message.
 *              pstr      - key to look for.
 *              ppos      - found string position relative to pdata.
 *              searchlen - searchlen.
 * Returns:     IP_TRUE  = found key.
 *              IP_FALSE = key not found.
 */
IP_STATIC Ip_bool
ipnet_nat_proxy_sip_keyfind(char *pdata,
                            char *pstr,
                            int  *ppos,
                            int  searchlen)
{
    char *pstart = pdata;
    int        i = 0;

    if (!searchlen)
        searchlen = 1000;  /* max default search length */

    while (IP_TRUE)
    {
        if (pstr)
        {
            /* skip all space */
            while (*pdata == ' ')
                pdata++;

            if (ipcom_memcmp(pdata, pstr, ipcom_strlen(pstr)) == 0)
                break;
        }

        /* advance to next line */
        for (i = 0; i < (searchlen - 1); i++)
        {
            if (pdata[i] == '\r')
                if (pdata[i+1] == '\n')
                    break;
        }

        if (i >= (searchlen - 1))
        {
            IPCOM_LOG1(ERR, "ipnet_nat_proxy_sip_keyfind() :: single message exceeds max len: %d", searchlen);
            *ppos = searchlen;  /* reaches the end */
            return IP_FALSE;
        }

        pdata += i + 2;
        searchlen -= (i + 2);

        if ((pdata[0] == '\r' && pdata[1] == '\n') || (searchlen <= 0))
        {
            /* reach the end mark \r\n\r\n */
            if (searchlen)
                pdata += 2;

            *ppos = pdata - pstart;

            return (pstr ? IP_FALSE : IP_TRUE);
        }
    }

    *ppos = pdata - pstart;
    return IP_TRUE;
}
/*
 *===========================================================================
 *                    ipcom_drv_eth_filter_pkt_to_me
 *===========================================================================
 * Description: Returns if this packet was sent to this node.
 * Parameters:	filter - The current filter for this interface.
 *              frame - An Ethernet frame.
 * Returns:	    IP_TRUE if this packet was sent to this node.
 *
 */
IP_PUBLIC Ip_bool
ipcom_drv_eth_filter_pkt_to_me(Ipcom_drv_eth_filter *filter,
                               Ipcom_eth_hdr *frame)
{
    int  i;

    if (filter->promisc)
        /* Driver in software-promiscuous mode, accept all packets. */
        return IP_TRUE;

    if (frame->dst[0] == 0xFF)
        /* Ethernet broadcast is always accepted */
        return IP_TRUE;

    if (IP_BIT_ISFALSE(frame->dst[0], 0x01))
    {
        /* Unicast packet */
        if (ipcom_memcmp(filter->unicast_addr, frame->dst, IPCOM_DRV_ETH_ADDR_SIZE) != 0)
            /* Not my MAC address */
            return IP_FALSE;
#ifdef IPCOM_USE_INET
        if (filter->in_block_addr.s_addr
            && ip_ntohs(frame->type) == 0x0800
            && ipcom_memcmp(&filter->in_block_addr, &frame->data[16], 4) == 0) /*lint !e416 !e420 */
            return IP_FALSE;
#endif
        return IP_TRUE;
    }

    /* Check multicast groups */
    for (i = 0; i < IPCOM_DRV_ETH_MAX_MULTIADDR; i++)
        if (filter->ref[i] != 0
            && ipcom_memcmp(filter->mcast_addr[i],
                            frame->dst,
                            IPCOM_DRV_ETH_ADDR_SIZE) == 0)
            return IP_TRUE;

    /* This multicast frame was not sent to this interface */
    return IP_FALSE;
}
/*
 *===========================================================================
 *                    ipcom_drv_eth_filter_remove_mcast_addr
 *===========================================================================
 * Description: Removes a multicast Ethernet address that should be passed
 *              by the filter.
 * Parameters:	filter - A filter from where the address should be removed.
 *              eth_mcast_addr - The address to remove.
 * Returns:	    0 = success, <0 = error code.
 *
 */
IP_PUBLIC int
ipcom_drv_eth_filter_remove_mcast_addr(Ipcom_drv_eth_filter *filter,
                                       Ip_u8 eth_mcast_addr[IPCOM_DRV_ETH_ADDR_SIZE])
{
    int i;

    for (i = 0; i < IPCOM_DRV_ETH_MAX_MULTIADDR; i++)
    {
        if (filter->ref[i] != 0
            && ipcom_memcmp(eth_mcast_addr, filter->mcast_addr[i], IPCOM_DRV_ETH_ADDR_SIZE) == 0)
        {
            /* Address found */
            if (--filter->ref[i] == 0)
                /* Last reference, remove the address */
                ipcom_memset(filter->mcast_addr[i], 0, IPCOM_DRV_ETH_ADDR_SIZE);
            return 0;
        }
    }
    /* Unknown address */
    return -IP_ERRNO_EADDRNOTAVAIL;
}
/*
 *===========================================================================
 *                         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;
}