/* * 802_3 * * Author: * Chris Vitale csv@bluetail.com * * May 2003 * */ #include #include #include static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *data, unsigned int datalen) { struct ebt_802_3_info *info = (struct ebt_802_3_info *)data; struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb); uint16_t type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type; if (info->bitmask & EBT_802_3_SAP) { if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP)) return EBT_NOMATCH; if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP)) return EBT_NOMATCH; } if (info->bitmask & EBT_802_3_TYPE) { if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE)) return EBT_NOMATCH; if (FWINV(info->type != type, EBT_802_3_TYPE)) return EBT_NOMATCH; } return EBT_MATCH; } static struct ebt_match filter_802_3; static int ebt_802_3_check(const char *tablename, unsigned int hookmask, const struct ebt_entry *e, void *data, unsigned int datalen) { struct ebt_802_3_info *info = (struct ebt_802_3_info *)data; if (datalen < sizeof(struct ebt_802_3_info)) return -EINVAL; if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) return -EINVAL; return 0; } static struct ebt_match filter_802_3 = { .name = EBT_802_3_MATCH, .match = ebt_filter_802_3, .check = ebt_802_3_check, .me = THIS_MODULE, }; static int __init init(void) { return ebt_register_match(&filter_802_3); } static void __exit fini(void) { ebt_unregister_match(&filter_802_3); } module_init(init); module_exit(fini); MODULE_LICENSE("GPL");