1 /* ebt_pkttype
2 *
3 * Authors:
4 * Bart De Schuymer <bdschuym@pandora.be>
5 *
6 * April, 2003
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <getopt.h>
13 #include <netdb.h>
14 #include <xtables.h>
15 #include <linux/if_packet.h>
16 #include <linux/netfilter_bridge/ebt_pkttype.h>
17
18 static const char *classes[] = {
19 "host",
20 "broadcast",
21 "multicast",
22 "otherhost",
23 "outgoing",
24 "loopback",
25 "fastroute",
26 };
27
28 static const struct option brpkttype_opts[] =
29 {
30 { "pkttype-type" , required_argument, 0, '1' },
31 { 0 }
32 };
33
brpkttype_print_help(void)34 static void brpkttype_print_help(void)
35 {
36 printf(
37 "pkttype options:\n"
38 "--pkttype-type [!] type: class the packet belongs to\n"
39 "Possible values: broadcast, multicast, host, otherhost, or any other byte value (which would be pretty useless).\n");
40 }
41
42
brpkttype_parse(int c,char ** argv,int invert,unsigned int * flags,const void * entry,struct xt_entry_match ** match)43 static int brpkttype_parse(int c, char **argv, int invert, unsigned int *flags,
44 const void *entry, struct xt_entry_match **match)
45 {
46 struct ebt_pkttype_info *ptinfo = (struct ebt_pkttype_info *)(*match)->data;
47 char *end;
48 long int i;
49
50 switch (c) {
51 case '1':
52 if (invert)
53 ptinfo->invert = 1;
54 i = strtol(optarg, &end, 16);
55 if (*end != '\0') {
56 for (i = 0; i < ARRAY_SIZE(classes); i++) {
57 if (!strcasecmp(optarg, classes[i]))
58 break;
59 }
60 if (i >= ARRAY_SIZE(classes))
61 xtables_error(PARAMETER_PROBLEM, "Could not parse class '%s'", optarg);
62 }
63 if (i < 0 || i > 255)
64 xtables_error(PARAMETER_PROBLEM, "Problem with specified pkttype class");
65 ptinfo->pkt_type = (uint8_t)i;
66 break;
67 default:
68 return 0;
69 }
70 return 1;
71 }
72
73
brpkttype_print(const void * ip,const struct xt_entry_match * match,int numeric)74 static void brpkttype_print(const void *ip, const struct xt_entry_match *match, int numeric)
75 {
76 struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data;
77
78 printf("--pkttype-type %s", pt->invert ? "! " : "");
79
80 if (pt->pkt_type < ARRAY_SIZE(classes))
81 printf("%s ", classes[pt->pkt_type]);
82 else
83 printf("%d ", pt->pkt_type);
84 }
85
brpkttype_xlate(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)86 static int brpkttype_xlate(struct xt_xlate *xl,
87 const struct xt_xlate_mt_params *params)
88 {
89 const struct ebt_pkttype_info *info = (const void*)params->match->data;
90
91 xt_xlate_add(xl, "meta pkttype %s", info->invert ? "!= " : "");
92
93 if (info->pkt_type < 3)
94 xt_xlate_add(xl, "%s ", classes[info->pkt_type]);
95 else if (info->pkt_type == 3)
96 xt_xlate_add(xl, "other ");
97 else
98 xt_xlate_add(xl, "%d ", info->pkt_type);
99
100 return 1;
101 }
102
103 static struct xtables_match brpkttype_match = {
104 .name = "pkttype",
105 .version = XTABLES_VERSION,
106 .family = NFPROTO_BRIDGE,
107 .size = XT_ALIGN(sizeof(struct ebt_pkttype_info)),
108 .userspacesize = XT_ALIGN(sizeof(struct ebt_pkttype_info)),
109 .help = brpkttype_print_help,
110 .parse = brpkttype_parse,
111 .print = brpkttype_print,
112 .xlate = brpkttype_xlate,
113 .extra_opts = brpkttype_opts,
114 };
115
_init(void)116 void _init(void)
117 {
118 xtables_register_match(&brpkttype_match);
119 }
120