• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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