• 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 <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