Sapan says vnet_tun is obsolete.
[iptables.git] / extensions / libxt_mac.c
1 /* Shared library add-on to iptables to add MAC address support. */
2 #include <stdio.h>
3 #include <netdb.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <getopt.h>
7 #if defined(__GLIBC__) && __GLIBC__ == 2
8 #include <net/ethernet.h>
9 #else
10 #include <linux/if_ether.h>
11 #endif
12 #include <xtables.h>
13 #include <linux/netfilter/xt_mac.h>
14
15 /* Function which prints out usage message. */
16 static void mac_help(void)
17 {
18         printf(
19 "mac match options:\n"
20 " --mac-source [!] XX:XX:XX:XX:XX:XX\n"
21 "                               Match source MAC address\n");
22 }
23
24 static const struct option mac_opts[] = {
25         { "mac-source", 1, NULL, '1' },
26         { .name = NULL }
27 };
28
29 static void
30 parse_mac(const char *mac, struct xt_mac_info *info)
31 {
32         unsigned int i = 0;
33
34         if (strlen(mac) != ETH_ALEN*3-1)
35                 exit_error(PARAMETER_PROBLEM, "Bad mac address `%s'", mac);
36
37         for (i = 0; i < ETH_ALEN; i++) {
38                 long number;
39                 char *end;
40
41                 number = strtol(mac + i*3, &end, 16);
42
43                 if (end == mac + i*3 + 2
44                     && number >= 0
45                     && number <= 255)
46                         info->srcaddr[i] = number;
47                 else
48                         exit_error(PARAMETER_PROBLEM,
49                                    "Bad mac address `%s'", mac);
50         }
51 }
52
53 /* Function which parses command options; returns true if it
54    ate an option */
55 static int
56 mac_parse(int c, char **argv, int invert, unsigned int *flags,
57           const void *entry, struct xt_entry_match **match)
58 {
59         struct xt_mac_info *macinfo = (struct xt_mac_info *)(*match)->data;
60
61         switch (c) {
62         case '1':
63                 check_inverse(optarg, &invert, &optind, 0);
64                 parse_mac(argv[optind-1], macinfo);
65                 if (invert)
66                         macinfo->invert = 1;
67                 *flags = 1;
68                 break;
69
70         default:
71                 return 0;
72         }
73
74         return 1;
75 }
76
77 static void print_mac(unsigned char macaddress[ETH_ALEN])
78 {
79         unsigned int i;
80
81         printf("%02X", macaddress[0]);
82         for (i = 1; i < ETH_ALEN; i++)
83                 printf(":%02X", macaddress[i]);
84         printf(" ");
85 }
86
87 /* Final check; must have specified --mac. */
88 static void mac_check(unsigned int flags)
89 {
90         if (!flags)
91                 exit_error(PARAMETER_PROBLEM,
92                            "You must specify `--mac-source'");
93 }
94
95 /* Prints out the matchinfo. */
96 static void
97 mac_print(const void *ip, const struct xt_entry_match *match, int numeric)
98 {
99         printf("MAC ");
100
101         if (((struct xt_mac_info *)match->data)->invert)
102                 printf("! ");
103         
104         print_mac(((struct xt_mac_info *)match->data)->srcaddr);
105 }
106
107 /* Saves the union ipt_matchinfo in parsable form to stdout. */
108 static void mac_save(const void *ip, const struct xt_entry_match *match)
109 {
110         if (((struct xt_mac_info *)match->data)->invert)
111                 printf("! ");
112
113         printf("--mac-source ");
114         print_mac(((struct xt_mac_info *)match->data)->srcaddr);
115 }
116
117 static struct xtables_match mac_match = {
118         .family         = AF_INET,
119         .name           = "mac",
120         .version        = XTABLES_VERSION,
121         .size           = XT_ALIGN(sizeof(struct xt_mac_info)),
122         .userspacesize  = XT_ALIGN(sizeof(struct xt_mac_info)),
123         .help           = mac_help,
124         .parse          = mac_parse,
125         .final_check    = mac_check,
126         .print          = mac_print,
127         .save           = mac_save,
128         .extra_opts     = mac_opts,
129 };
130
131 static struct xtables_match mac_match6 = {
132         .family         = AF_INET6,
133         .name           = "mac",
134         .version        = XTABLES_VERSION,
135         .size           = XT_ALIGN(sizeof(struct xt_mac_info)),
136         .userspacesize  = XT_ALIGN(sizeof(struct xt_mac_info)),
137         .help           = mac_help,
138         .parse          = mac_parse,
139         .final_check    = mac_check,
140         .print          = mac_print,
141         .save           = mac_save,
142         .extra_opts     = mac_opts,
143 };
144
145 void _init(void)
146 {
147         xtables_register_match(&mac_match);
148         xtables_register_match(&mac_match6);
149 }