www.usr.com/support/gpl/USR9107_release.1.4.tar.gz
[bcm963xx.git] / userapps / opensource / ebtables / extensions / ebt_pkttype.c
1 /*
2  *  ebtables ebt_pkttype
3  *
4  *  Authors:
5  *   Bart De Schuymer <bdschuym@pandora.be>
6  *
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <getopt.h>
13 #include <netdb.h>
14 #include "../include/ebtables_u.h"
15 #include <linux/if_packet.h>
16 #include <linux/netfilter_bridge/ebt_pkttype.h>
17
18 char *classes[] =
19 {
20         "host",
21         "broadcast",
22         "multicast",
23         "otherhost",
24         "outgoing",
25         "loopback",
26         "fastroute",
27         "\0"
28 };
29
30 static struct option opts[] =
31 {
32         { "pkttype-type"        , required_argument, 0, '1' },
33         { 0 }
34 };
35
36 static void print_help()
37 {
38         printf(
39 "pkttype options:\n"
40 "--pkttype-type    [!] type: class the packet belongs to\n"
41 "Possible values: broadcast, multicast, host, otherhost any byte value.\n");
42 }
43
44 static void init(struct ebt_entry_match *match)
45 {
46         struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data;
47
48         pt->invert = 0;
49 }
50
51 static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
52    unsigned int *flags, struct ebt_entry_match **match)
53 {
54         struct ebt_pkttype_info *ptinfo = (struct ebt_pkttype_info *)(*match)->data;
55         char *end;
56         long int i;
57
58         switch (c) {
59         case '1':
60                 check_option(flags, 1);
61                 if (check_inverse(optarg))
62                         ptinfo->invert = 1;
63                 if (optind > argc)
64                         print_error("Missing pkttype class specification");
65
66                 i = strtol(argv[optind - 1], &end, 16);
67                 if (*end != '\0') {
68                         int j = 0;
69                         i = -1;
70                         while (classes[j][0])
71                                 if (!strcasecmp(argv[optind - 1], classes[j++])) {
72                                         i = j - 1;
73                                         break;
74                                 }
75                 }
76                 if (i < 0 || i > 255)
77                         print_error("Problem with specified pkttype class");
78                 ptinfo->pkt_type = (uint8_t)i;
79
80                 break;
81         default:
82                 return 0;
83         }
84         return 1;
85 }
86
87 static void final_check(const struct ebt_u_entry *entry,
88    const struct ebt_entry_match *match, const char *name,
89    unsigned int hookmask, unsigned int time)
90 {
91 }
92
93 static void print(const struct ebt_u_entry *entry,
94    const struct ebt_entry_match *match)
95 {
96         struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data;
97         int i = 0;
98
99         printf("--pkttype-type %s", pt->invert ? "! " : "");
100         while (classes[i++][0]);
101         if (pt->pkt_type < i - 1)
102                 printf("%s ", classes[pt->pkt_type]);
103         else
104                 printf("%d ", pt->pkt_type);
105 }
106
107 static int compare(const struct ebt_entry_match *m1,
108    const struct ebt_entry_match *m2)
109 {
110         struct ebt_pkttype_info *pt1 = (struct ebt_pkttype_info *)m1->data;
111         struct ebt_pkttype_info *pt2 = (struct ebt_pkttype_info *)m2->data;
112
113         if (pt1->invert != pt2->invert ||
114             pt1->pkt_type != pt2->pkt_type)
115                 return 0;
116         return 1;
117 }
118
119 static struct ebt_u_match pkttype_match =
120 {
121         .name           = EBT_PKTTYPE_MATCH,
122         .size           = sizeof(struct ebt_pkttype_info),
123         .help           = print_help,
124         .init           = init,
125         .parse          = parse,
126         .final_check    = final_check,
127         .print          = print,
128         .compare        = compare,
129         .extra_ops      = opts,
130 };
131
132 static void _init(void) __attribute((constructor));
133 static void _init(void)
134 {
135         register_match(&pkttype_match);
136 }