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_ipv4/ipt_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()
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 help(void)
61 "pkt_type v%s options:\n"
62 " --pkt-type [!] packettype\tmatch packet type\n"
63 "\n", PKTTYPE_VERSION
);
67 static struct option opts
[] = {
68 {"pkt-type", 1, 0, '1'},
72 static void parse_pkttype(const char *pkttype
, struct ipt_pkttype_info
*info
)
76 for (i
= 0; i
< sizeof(supported_types
)/sizeof(struct pkttypes
); i
++)
78 if(strcasecmp(pkttype
, supported_types
[i
].name
)==0)
80 info
->pkttype
=supported_types
[i
].pkttype
;
85 exit_error(PARAMETER_PROBLEM
, "Bad packet type '%s'", pkttype
);
88 static int parse(int c
, char **argv
, int invert
, unsigned int *flags
,
89 const struct ipt_entry
*entry
,
90 unsigned int *nfcache
,
91 struct ipt_entry_match
**match
)
93 struct ipt_pkttype_info
*info
= (struct ipt_pkttype_info
*)(*match
)->data
;
98 check_inverse(optarg
, &invert
, &optind
, 0);
99 parse_pkttype(argv
[optind
-1], info
);
112 static void final_check(unsigned int flags
)
115 exit_error(PARAMETER_PROBLEM
, "You must specify `--pkt-type'");
118 static void print_pkttype(struct ipt_pkttype_info
*info
)
122 for (i
= 0; i
< sizeof(supported_types
)/sizeof(struct pkttypes
); i
++)
124 if(supported_types
[i
].pkttype
==info
->pkttype
)
126 printf("%s ", supported_types
[i
].name
);
131 printf("%d ", info
->pkttype
); /* in case we didn't find an entry in named-packtes */
134 static void print(const struct ipt_ip
*ip
, const struct ipt_entry_match
*match
, int numeric
)
136 struct ipt_pkttype_info
*info
= (struct ipt_pkttype_info
*)match
->data
;
138 printf("PKTTYPE %s= ", info
->invert
?"!":"");
142 static void save(const struct ipt_ip
*ip
, const struct ipt_entry_match
*match
)
144 struct ipt_pkttype_info
*info
= (struct ipt_pkttype_info
*)match
->data
;
146 printf("--pkt-type %s", info
->invert
?"! ":"");
150 static struct iptables_match pkttype
= {
153 .version
= IPTABLES_VERSION
,
154 .size
= IPT_ALIGN(sizeof(struct ipt_pkttype_info
)),
155 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_pkttype_info
)),
158 .final_check
= &final_check
,
166 register_match(&pkttype
);