static bool ebt_among_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct ebt_among_info *info = par->matchinfo; const char *dmac, *smac; const struct ebt_mac_wormhash *wh_dst, *wh_src; __be32 dip = 0, sip = 0; wh_dst = ebt_among_wh_dst(info); wh_src = ebt_among_wh_src(info); if (wh_src) { smac = eth_hdr(skb)->h_source; if (get_ip_src(skb, &sip)) { return false; } if (!(info->bitmask & EBT_AMONG_SRC_NEG)) { /* we match only if it contains */ if (!ebt_mac_wormhash_contains(wh_src, smac, sip)) { return false; } } else { /* we match only if it DOES NOT contain */ if (ebt_mac_wormhash_contains(wh_src, smac, sip)) { return false; } } } if (wh_dst) { dmac = eth_hdr(skb)->h_dest; if (get_ip_dst(skb, &dip)) { return false; } if (!(info->bitmask & EBT_AMONG_DST_NEG)) { /* we match only if it contains */ if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip)) { return false; } } else { /* we match only if it DOES NOT contain */ if (ebt_mac_wormhash_contains(wh_dst, dmac, dip)) { return false; } } } return true; }
static int ebt_filter_among(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *data, unsigned int datalen) { const struct ebt_among_info *info = data; const char *dmac, *smac; const struct ebt_mac_wormhash *wh_dst, *wh_src; __be32 dip = 0, sip = 0; wh_dst = ebt_among_wh_dst(info); wh_src = ebt_among_wh_src(info); if (wh_src) { smac = eth_hdr(skb)->h_source; if (get_ip_src(skb, &sip)) return EBT_NOMATCH; if (!(info->bitmask & EBT_AMONG_SRC_NEG)) { /* we match only if it contains */ if (!ebt_mac_wormhash_contains(wh_src, smac, sip)) return EBT_NOMATCH; } else { /* we match only if it DOES NOT contain */ if (ebt_mac_wormhash_contains(wh_src, smac, sip)) return EBT_NOMATCH; } } if (wh_dst) { dmac = eth_hdr(skb)->h_dest; if (get_ip_dst(skb, &dip)) return EBT_NOMATCH; if (!(info->bitmask & EBT_AMONG_DST_NEG)) { /* we match only if it contains */ if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip)) return EBT_NOMATCH; } else { /* we match only if it DOES NOT contain */ if (ebt_mac_wormhash_contains(wh_dst, dmac, dip)) return EBT_NOMATCH; } } return EBT_MATCH; }
static int ebt_target_idnat(struct sk_buff **pskb, unsigned int hooknr, const struct net_device *in, const struct net_device *out, const void *data, unsigned int datalen) { struct ebt_inat_info *info = (struct ebt_inat_info *)data; uint32_t ip; int index; struct ebt_inat_tuple *tuple; if (!get_ip_dst(*pskb, &ip)) { return info->target; } if ((ip & __constant_htonl(0xffffff00)) != info->ip_subnet) { return info->target; } index = ((unsigned char*)&ip)[3]; tuple = &info->a[index]; if (!tuple->enabled) { return info->target; } memcpy(((**pskb).mac.ethernet)->h_dest, tuple->mac, ETH_ALEN * sizeof(unsigned char)); if ((**pskb).mac.ethernet->h_proto == __constant_htons(ETH_P_ARP)) { memcpy( (**pskb).nh.raw + sizeof(struct arphdr) + (**pskb).nh.arph->ar_hln + (**pskb).nh.arph->ar_pln, tuple->mac, ETH_ALEN); } return tuple->target; }