Exemple #1
0
unsigned int
mroute_extract_addr_ether(struct mroute_addr *src,
                          struct mroute_addr *dest,
                          struct mroute_addr *esrc,
                          struct mroute_addr *edest,
                          const struct buffer *buf)
{
    unsigned int ret = 0;
    if (BLEN(buf) >= (int) sizeof(struct openvpn_ethhdr))
    {
        const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR(buf);
        if (src)
        {
            src->type = MR_ADDR_ETHER;
            src->netbits = 0;
            src->len = 6;
            memcpy(src->eth_addr, eth->source, sizeof(dest->eth_addr));
        }
        if (dest)
        {
            dest->type = MR_ADDR_ETHER;
            dest->netbits = 0;
            dest->len = 6;
            memcpy(dest->eth_addr, eth->dest, sizeof(dest->eth_addr));

            /* ethernet broadcast/multicast packet? */
            if (is_mac_mcast_addr(eth->dest))
            {
                ret |= MROUTE_EXTRACT_BCAST;
            }
        }

        ret |= MROUTE_EXTRACT_SUCCEEDED;

#ifdef ENABLE_PF
        if (esrc || edest)
        {
            struct buffer b = *buf;
            if (buf_advance(&b, sizeof(struct openvpn_ethhdr)))
            {
                switch (ntohs(eth->proto))
                {
                    case OPENVPN_ETH_P_IPV4:
                        ret |= (mroute_extract_addr_ip(esrc, edest, &b) << MROUTE_SEC_SHIFT);
                        break;

                    case OPENVPN_ETH_P_ARP:
                        ret |= (mroute_extract_addr_arp(esrc, edest, &b) << MROUTE_SEC_SHIFT);
                        break;
                }
            }
        }
#endif
    }
    return ret;
}
static inline bool
is_mac_mcast_maddr (const struct mroute_addr *addr)
{
  return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER && is_mac_mcast_addr (addr->addr); 
}