blob: ab2e2259097f909682ff4e6f86ef6b90bb8dfc3e [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
Jan Engelhardt181dead2007-10-04 16:27:07 +000057static void pkttype_help(void)
Harald Welteb5166472001-04-19 16:35:39 +000058{
59 printf(
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020060"pkttype match options:\n"
Jan Engelhardt9b488b92008-06-08 19:11:51 +020061"[!] --pkt-type packettype match packet type\n");
Harald Welteb5166472001-04-19 16:35:39 +000062 print_types();
63}
64
Jan Engelhardt181dead2007-10-04 16:27:07 +000065static const struct option pkttype_opts[] = {
Patrick McHardy500f4832007-09-08 15:59:04 +000066 {"pkt-type", 1, NULL, '1'},
Max Kellermann9ee386a2008-01-29 13:48:05 +000067 { .name = NULL }
Harald Welteb5166472001-04-19 16:35:39 +000068};
69
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +000070static void parse_pkttype(const char *pkttype, struct xt_pkttype_info *info)
Harald Welteb5166472001-04-19 16:35:39 +000071{
72 unsigned int i;
73
74 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
75 {
76 if(strcasecmp(pkttype, supported_types[i].name)==0)
77 {
78 info->pkttype=supported_types[i].pkttype;
79 return;
80 }
81 }
82
83 exit_error(PARAMETER_PROBLEM, "Bad packet type '%s'", pkttype);
84}
85
Jan Engelhardt181dead2007-10-04 16:27:07 +000086static int pkttype_parse(int c, char **argv, int invert, unsigned int *flags,
87 const void *entry, struct xt_entry_match **match)
Harald Welteb5166472001-04-19 16:35:39 +000088{
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +000089 struct xt_pkttype_info *info = (struct xt_pkttype_info *)(*match)->data;
Harald Welteb5166472001-04-19 16:35:39 +000090
91 switch(c)
92 {
93 case '1':
Harald Welteb77f1da2002-03-14 11:35:58 +000094 check_inverse(optarg, &invert, &optind, 0);
Harald Welteb5166472001-04-19 16:35:39 +000095 parse_pkttype(argv[optind-1], info);
96 if(invert)
97 info->invert=1;
98 *flags=1;
99 break;
100
101 default:
102 return 0;
103 }
104
105 return 1;
106}
107
Jan Engelhardt181dead2007-10-04 16:27:07 +0000108static void pkttype_check(unsigned int flags)
Harald Welteb5166472001-04-19 16:35:39 +0000109{
110 if (!flags)
111 exit_error(PARAMETER_PROBLEM, "You must specify `--pkt-type'");
112}
113
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000114static void print_pkttype(struct xt_pkttype_info *info)
Harald Welteb5166472001-04-19 16:35:39 +0000115{
116 unsigned int i;
117
118 for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
119 {
120 if(supported_types[i].pkttype==info->pkttype)
121 {
122 printf("%s ", supported_types[i].name);
123 return;
124 }
125 }
126
127 printf("%d ", info->pkttype); /* in case we didn't find an entry in named-packtes */
128}
129
Jan Engelhardt181dead2007-10-04 16:27:07 +0000130static void pkttype_print(const void *ip, const struct xt_entry_match *match,
131 int numeric)
Harald Welteb5166472001-04-19 16:35:39 +0000132{
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000133 struct xt_pkttype_info *info = (struct xt_pkttype_info *)match->data;
Harald Welteb5166472001-04-19 16:35:39 +0000134
135 printf("PKTTYPE %s= ", info->invert?"!":"");
136 print_pkttype(info);
137}
138
Jan Engelhardt181dead2007-10-04 16:27:07 +0000139static void pkttype_save(const void *ip, const struct xt_entry_match *match)
Harald Welteb5166472001-04-19 16:35:39 +0000140{
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000141 struct xt_pkttype_info *info = (struct xt_pkttype_info *)match->data;
Harald Welteb5166472001-04-19 16:35:39 +0000142
Jan Engelhardtcea9f712008-12-09 15:06:20 +0100143 printf("%s--pkt-type ", info->invert ? "! " : "");
Harald Welteb5166472001-04-19 16:35:39 +0000144 print_pkttype(info);
145}
146
Jan Engelhardt181dead2007-10-04 16:27:07 +0000147static struct xtables_match pkttype_match = {
Jan Engelhardt23545c22008-02-14 04:23:04 +0100148 .family = AF_UNSPEC,
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000149 .name = "pkttype",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200150 .version = XTABLES_VERSION,
Yasuyuki KOZAKAI5fd6ec82007-07-24 07:05:45 +0000151 .size = XT_ALIGN(sizeof(struct xt_pkttype_info)),
152 .userspacesize = XT_ALIGN(sizeof(struct xt_pkttype_info)),
Jan Engelhardt181dead2007-10-04 16:27:07 +0000153 .help = pkttype_help,
154 .parse = pkttype_parse,
155 .final_check = pkttype_check,
156 .print = pkttype_print,
157 .save = pkttype_save,
158 .extra_opts = pkttype_opts,
Harald Welteb5166472001-04-19 16:35:39 +0000159};
160
161void _init(void)
162{
Jan Engelhardt181dead2007-10-04 16:27:07 +0000163 xtables_register_match(&pkttype_match);
Harald Welteb5166472001-04-19 16:35:39 +0000164}