blob: cbb78be4ab64522e0abb7a6343421e318054a244 [file] [log] [blame]
Harald Welteb5166472001-04-19 16:35:39 +00001/*
2 * Shared library add-on to iptables to match
3 * packets by their type (BROADCAST, UNICAST, MULTICAST).
4 *
5 * Michal Ludvig <michal@logix.cz>
6 */
7#include <stdio.h>
8#include <netdb.h>
9#include <string.h>
10#include <stdlib.h>
11#include <getopt.h>
12#if defined(__GLIBC__) && __GLIBC__ == 2
13#include <net/ethernet.h>
14#else
15#include <linux/if_ether.h>
16#endif
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +000017#include <xtables.h>
Harald Welteb5166472001-04-19 16:35:39 +000018#include <linux/if_packet.h>
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +000019#include <linux/netfilter/xt_pkttype.h>
Harald Welteb5166472001-04-19 16:35:39 +000020
21#define PKTTYPE_VERSION "0.1"
22
23struct pkttypes {
24 const char *name;
25 unsigned char pkttype;
26 unsigned char printhelp;
27 const char *help;
28};
29
30static const struct pkttypes supported_types[] = {
Harald Welteef225432002-08-07 09:54:45 +000031 {"unicast", PACKET_HOST, 1, "to us"},
Harald Welteb5166472001-04-19 16:35:39 +000032 {"broadcast", PACKET_BROADCAST, 1, "to all"},
33 {"multicast", PACKET_MULTICAST, 1, "to group"},
34/*
35 {"otherhost", PACKET_OTHERHOST, 1, "to someone else"},
36 {"outgoing", PACKET_OUTGOING, 1, "outgoing of any type"},
37*/
38 /* aliases */
39 {"bcast", PACKET_BROADCAST, 0, NULL},
40 {"mcast", PACKET_MULTICAST, 0, NULL},
Harald Welteef225432002-08-07 09:54:45 +000041 {"host", PACKET_HOST, 0, NULL}
Harald Welteb5166472001-04-19 16:35:39 +000042};
43
Patrick McHardy500f4832007-09-08 15:59:04 +000044static void print_types(void)
Harald Welteb5166472001-04-19 16:35:39 +000045{
46 unsigned int i;
47
48 printf("Valid packet types:\n");
49 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
50 {
51 if(supported_types[i].printhelp == 1)
52 printf("\t%-14s\t\t%s\n", supported_types[i].name, supported_types[i].help);
53 }
54 printf("\n");
55}
56
57/* Function which prints out usage message. */
58static void help(void)
59{
60 printf(
61"pkt_type v%s options:\n"
62" --pkt-type [!] packettype\tmatch packet type\n"
63"\n", PKTTYPE_VERSION);
64 print_types();
65}
66
Jan Engelhardt661f1122007-07-30 14:46:51 +000067static const struct option opts[] = {
Patrick McHardy500f4832007-09-08 15:59:04 +000068 {"pkt-type", 1, NULL, '1'},
69 { }
Harald Welteb5166472001-04-19 16:35:39 +000070};
71
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +000072static void parse_pkttype(const char *pkttype, struct xt_pkttype_info *info)
Harald Welteb5166472001-04-19 16:35:39 +000073{
74 unsigned int i;
75
76 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
77 {
78 if(strcasecmp(pkttype, supported_types[i].name)==0)
79 {
80 info->pkttype=supported_types[i].pkttype;
81 return;
82 }
83 }
84
85 exit_error(PARAMETER_PROBLEM, "Bad packet type '%s'", pkttype);
86}
87
88static int parse(int c, char **argv, int invert, unsigned int *flags,
Yasuyuki KOZAKAIc0a9ab92007-07-24 06:02:05 +000089 const void *entry,
Yasuyuki KOZAKAI193df8e2007-07-24 05:57:28 +000090 struct xt_entry_match **match)
Harald Welteb5166472001-04-19 16:35:39 +000091{
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +000092 struct xt_pkttype_info *info = (struct xt_pkttype_info *)(*match)->data;
Harald Welteb5166472001-04-19 16:35:39 +000093
94 switch(c)
95 {
96 case '1':
Harald Welteb77f1da2002-03-14 11:35:58 +000097 check_inverse(optarg, &invert, &optind, 0);
Harald Welteb5166472001-04-19 16:35:39 +000098 parse_pkttype(argv[optind-1], info);
99 if(invert)
100 info->invert=1;
101 *flags=1;
102 break;
103
104 default:
105 return 0;
106 }
107
108 return 1;
109}
110
111static void final_check(unsigned int flags)
112{
113 if (!flags)
114 exit_error(PARAMETER_PROBLEM, "You must specify `--pkt-type'");
115}
116
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000117static void print_pkttype(struct xt_pkttype_info *info)
Harald Welteb5166472001-04-19 16:35:39 +0000118{
119 unsigned int i;
120
121 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
122 {
123 if(supported_types[i].pkttype==info->pkttype)
124 {
125 printf("%s ", supported_types[i].name);
126 return;
127 }
128 }
129
130 printf("%d ", info->pkttype); /* in case we didn't find an entry in named-packtes */
131}
132
Yasuyuki KOZAKAIc0a9ab92007-07-24 06:02:05 +0000133static void print(const void *ip, const struct xt_entry_match *match, int numeric)
Harald Welteb5166472001-04-19 16:35:39 +0000134{
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000135 struct xt_pkttype_info *info = (struct xt_pkttype_info *)match->data;
Harald Welteb5166472001-04-19 16:35:39 +0000136
137 printf("PKTTYPE %s= ", info->invert?"!":"");
138 print_pkttype(info);
139}
140
Yasuyuki KOZAKAIc0a9ab92007-07-24 06:02:05 +0000141static void save(const void *ip, const struct xt_entry_match *match)
Harald Welteb5166472001-04-19 16:35:39 +0000142{
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000143 struct xt_pkttype_info *info = (struct xt_pkttype_info *)match->data;
Harald Welteb5166472001-04-19 16:35:39 +0000144
145 printf("--pkt-type %s", info->invert?"! ":"");
146 print_pkttype(info);
147}
148
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000149static struct xtables_match pkttype = {
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000150 .family = AF_INET,
Pablo Neira8caee8b2004-12-28 13:11:59 +0000151 .name = "pkttype",
152 .version = IPTABLES_VERSION,
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000153 .size = XT_ALIGN(sizeof(struct xt_pkttype_info)),
154 .userspacesize = XT_ALIGN(sizeof(struct xt_pkttype_info)),
155 .help = &help,
156 .parse = &parse,
157 .final_check = &final_check,
158 .print = &print,
159 .save = &save,
160 .extra_opts = opts
161};
162
163static struct xtables_match pkttype6 = {
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000164 .family = AF_INET6,
165 .name = "pkttype",
166 .version = IPTABLES_VERSION,
167 .size = XT_ALIGN(sizeof(struct xt_pkttype_info)),
168 .userspacesize = XT_ALIGN(sizeof(struct xt_pkttype_info)),
Pablo Neira8caee8b2004-12-28 13:11:59 +0000169 .help = &help,
Pablo Neira8caee8b2004-12-28 13:11:59 +0000170 .parse = &parse,
171 .final_check = &final_check,
172 .print = &print,
173 .save = &save,
174 .extra_opts = opts
Harald Welteb5166472001-04-19 16:35:39 +0000175};
176
177void _init(void)
178{
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000179 xtables_register_match(&pkttype);
180 xtables_register_match(&pkttype6);
Harald Welteb5166472001-04-19 16:35:39 +0000181}