Sapan says vnet_tun is obsolete.
[iptables.git] / extensions / libxt_pkttype.c
1 /* 
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
17 #include <xtables.h>
18 #include <linux/if_packet.h>
19 #include <linux/netfilter/xt_pkttype.h>
20
21 #define PKTTYPE_VERSION "0.1"
22
23 struct pkttypes {
24         const char *name;
25         unsigned char pkttype;
26         unsigned char printhelp;
27         const char *help;
28 };
29
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"},
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},
41         {"host", PACKET_HOST, 0, NULL}
42 };
43
44 static void print_types(void)
45 {
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. */
58 static void pkttype_help(void)
59 {
60         printf(
61 "pkttype match options:\n"
62 "[!] --pkt-type packettype    match packet type\n");
63         print_types();
64 }
65
66 static const struct option pkttype_opts[] = {
67         {"pkt-type", 1, NULL, '1'},
68         { .name = NULL }
69 };
70
71 static void parse_pkttype(const char *pkttype, struct xt_pkttype_info *info)
72 {
73         unsigned int    i;
74         
75         for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
76         {
77                 if(strcasecmp(pkttype, supported_types[i].name)==0)
78                 {
79                         info->pkttype=supported_types[i].pkttype;
80                         return;
81                 }
82         }
83         
84         exit_error(PARAMETER_PROBLEM, "Bad packet type '%s'", pkttype);
85 }
86
87 static int pkttype_parse(int c, char **argv, int invert, unsigned int *flags,
88                          const void *entry, struct xt_entry_match **match)
89 {
90         struct xt_pkttype_info *info = (struct xt_pkttype_info *)(*match)->data;
91         
92         switch(c)
93         {
94                 case '1':
95                         check_inverse(optarg, &invert, &optind, 0);
96                         parse_pkttype(argv[optind-1], info);
97                         if(invert)
98                                 info->invert=1;
99                         *flags=1;
100                         break;
101
102                 default: 
103                         return 0;
104         }
105
106         return 1;
107 }
108
109 static void pkttype_check(unsigned int flags)
110 {
111         if (!flags)
112                 exit_error(PARAMETER_PROBLEM, "You must specify `--pkt-type'");
113 }
114
115 static void print_pkttype(struct xt_pkttype_info *info)
116 {
117         unsigned int    i;
118         
119         for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
120         {
121                 if(supported_types[i].pkttype==info->pkttype)
122                 {
123                         printf("%s ", supported_types[i].name);
124                         return;
125                 }
126         }
127
128         printf("%d ", info->pkttype);   /* in case we didn't find an entry in named-packtes */
129 }
130
131 static void pkttype_print(const void *ip, const struct xt_entry_match *match,
132                           int numeric)
133 {
134         struct xt_pkttype_info *info = (struct xt_pkttype_info *)match->data;
135         
136         printf("PKTTYPE %s= ", info->invert?"!":"");
137         print_pkttype(info);
138 }
139
140 static void pkttype_save(const void *ip, const struct xt_entry_match *match)
141 {
142         struct xt_pkttype_info *info = (struct xt_pkttype_info *)match->data;
143         
144         printf("--pkt-type %s", info->invert?"! ":"");
145         print_pkttype(info);
146 }
147
148 static struct xtables_match pkttype_match = {
149         .family         = AF_UNSPEC,
150         .name           = "pkttype",
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,
160 };
161
162 void _init(void)
163 {
164         xtables_register_match(&pkttype_match);
165 }