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