2 * Shared library add-on to iptables to match
3 * packets by their type (BROADCAST, UNICAST, MULTICAST).
5 * Michal Ludvig <michal@logix.cz>
12 #if defined(__GLIBC__) && __GLIBC__ == 2
13 #include <net/ethernet.h>
15 #include <linux/if_ether.h>
18 #include <linux/if_packet.h>
19 #include <linux/netfilter/xt_pkttype.h>
21 #define PKTTYPE_VERSION "0.1"
25 unsigned char pkttype;
26 unsigned char printhelp;
30 static const struct pkttypes supported_types[] = {
31 {"unicast", PACKET_HOST, 1, "to us"},
32 {"broadcast", PACKET_BROADCAST, 1, "to all"},
33 {"multicast", PACKET_MULTICAST, 1, "to group"},
35 {"otherhost", PACKET_OTHERHOST, 1, "to someone else"},
36 {"outgoing", PACKET_OUTGOING, 1, "outgoing of any type"},
39 {"bcast", PACKET_BROADCAST, 0, NULL},
40 {"mcast", PACKET_MULTICAST, 0, NULL},
41 {"host", PACKET_HOST, 0, NULL}
44 static void print_types(void)
48 printf("Valid packet types:\n");
49 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
51 if(supported_types[i].printhelp == 1)
52 printf("\t%-14s\t\t%s\n", supported_types[i].name, supported_types[i].help);
57 /* Function which prints out usage message. */
58 static void pkttype_help(void)
61 "pkttype match options:\n"
62 "[!] --pkt-type packettype match packet type\n");
66 static const struct option pkttype_opts[] = {
67 {"pkt-type", 1, NULL, '1'},
71 static void parse_pkttype(const char *pkttype, struct xt_pkttype_info *info)
75 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
77 if(strcasecmp(pkttype, supported_types[i].name)==0)
79 info->pkttype=supported_types[i].pkttype;
84 exit_error(PARAMETER_PROBLEM, "Bad packet type '%s'", pkttype);
87 static int pkttype_parse(int c, char **argv, int invert, unsigned int *flags,
88 const void *entry, struct xt_entry_match **match)
90 struct xt_pkttype_info *info = (struct xt_pkttype_info *)(*match)->data;
95 check_inverse(optarg, &invert, &optind, 0);
96 parse_pkttype(argv[optind-1], info);
109 static void pkttype_check(unsigned int flags)
112 exit_error(PARAMETER_PROBLEM, "You must specify `--pkt-type'");
115 static void print_pkttype(struct xt_pkttype_info *info)
119 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
121 if(supported_types[i].pkttype==info->pkttype)
123 printf("%s ", supported_types[i].name);
128 printf("%d ", info->pkttype); /* in case we didn't find an entry in named-packtes */
131 static void pkttype_print(const void *ip, const struct xt_entry_match *match,
134 struct xt_pkttype_info *info = (struct xt_pkttype_info *)match->data;
136 printf("PKTTYPE %s= ", info->invert?"!":"");
140 static void pkttype_save(const void *ip, const struct xt_entry_match *match)
142 struct xt_pkttype_info *info = (struct xt_pkttype_info *)match->data;
144 printf("--pkt-type %s", info->invert?"! ":"");
148 static struct xtables_match pkttype_match = {
151 .version = XTABLES_VERSION,
152 .size = XT_ALIGN(sizeof(struct xt_pkttype_info)),
153 .userspacesize = XT_ALIGN(sizeof(struct xt_pkttype_info)),
154 .help = pkttype_help,
155 .parse = pkttype_parse,
156 .final_check = pkttype_check,
157 .print = pkttype_print,
158 .save = pkttype_save,
159 .extra_opts = pkttype_opts,
164 xtables_register_match(&pkttype_match);