static bool ebt_stp_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct ebt_stp_info *info = par->matchinfo; const struct stp_header *sp; struct stp_header _stph; const u8 header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00}; sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph); if (sp == NULL) return false; /* The stp code only considers these */ if (memcmp(sp, header, sizeof(header))) return false; if ((info->bitmask & EBT_STP_TYPE) && NF_INVF(info, EBT_STP_TYPE, info->type != sp->type)) return false; if (sp->type == BPDU_TYPE_CONFIG && info->bitmask & EBT_STP_CONFIG_MASK) { const struct stp_config_pdu *st; struct stp_config_pdu _stpc; st = skb_header_pointer(skb, sizeof(_stph), sizeof(_stpc), &_stpc); if (st == NULL) return false; return ebt_filter_config(info, st); } return true; }
static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *data, unsigned int datalen) { struct ebt_stp_info *info = (struct ebt_stp_info *)data; struct stp_header _stph, *sp; uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00}; sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph); if (sp == NULL) return EBT_NOMATCH; /* The stp code only considers these */ if (memcmp(sp, header, sizeof(header))) return EBT_NOMATCH; if (info->bitmask & EBT_STP_TYPE && FWINV(info->type != sp->type, EBT_STP_TYPE)) return EBT_NOMATCH; if (sp->type == BPDU_TYPE_CONFIG && info->bitmask & EBT_STP_CONFIG_MASK) { struct stp_config_pdu _stpc, *st; st = skb_header_pointer(skb, sizeof(_stph), sizeof(_stpc), &_stpc); if (st == NULL) return EBT_NOMATCH; return ebt_filter_config(info, st); } return EBT_MATCH; }