xt_pkttype.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* (C) 1999-2001 Michal Ludvig <michal@logix.cz>
  3. */
  4. #include <linux/module.h>
  5. #include <linux/skbuff.h>
  6. #include <linux/if_ether.h>
  7. #include <linux/if_packet.h>
  8. #include <linux/in.h>
  9. #include <linux/ip.h>
  10. #include <linux/ipv6.h>
  11. #include <linux/netfilter/xt_pkttype.h>
  12. #include <linux/netfilter/x_tables.h>
  13. MODULE_LICENSE("GPL");
  14. MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>");
  15. MODULE_DESCRIPTION("Xtables: link layer packet type match");
  16. MODULE_ALIAS("ipt_pkttype");
  17. MODULE_ALIAS("ip6t_pkttype");
  18. static bool
  19. pkttype_mt(const struct sk_buff *skb, struct xt_action_param *par)
  20. {
  21. const struct xt_pkttype_info *info = par->matchinfo;
  22. u_int8_t type;
  23. if (skb->pkt_type != PACKET_LOOPBACK)
  24. type = skb->pkt_type;
  25. else if (xt_family(par) == NFPROTO_IPV4 &&
  26. ipv4_is_multicast(ip_hdr(skb)->daddr))
  27. type = PACKET_MULTICAST;
  28. else if (xt_family(par) == NFPROTO_IPV6)
  29. type = PACKET_MULTICAST;
  30. else
  31. type = PACKET_BROADCAST;
  32. return (type == info->pkttype) ^ info->invert;
  33. }
  34. static struct xt_match pkttype_mt_reg __read_mostly = {
  35. .name = "pkttype",
  36. .revision = 0,
  37. .family = NFPROTO_UNSPEC,
  38. .match = pkttype_mt,
  39. .matchsize = sizeof(struct xt_pkttype_info),
  40. .me = THIS_MODULE,
  41. };
  42. static int __init pkttype_mt_init(void)
  43. {
  44. return xt_register_match(&pkttype_mt_reg);
  45. }
  46. static void __exit pkttype_mt_exit(void)
  47. {
  48. xt_unregister_match(&pkttype_mt_reg);
  49. }
  50. module_init(pkttype_mt_init);
  51. module_exit(pkttype_mt_exit);