blob: a57e341024823667562673a7d0d8819511aefdbf [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* 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
15static void mac_help(void)
16{
17 printf(
18"mac match options:\n"
19"[!] --mac-source XX:XX:XX:XX:XX:XX\n"
20" Match source MAC address\n");
21}
22
23static const struct option mac_opts[] = {
24 { "mac-source", 1, NULL, '1' },
25 { .name = NULL }
26};
27
28static void
29parse_mac(const char *mac, struct xt_mac_info *info)
30{
31 unsigned int i = 0;
32
33 if (strlen(mac) != ETH_ALEN*3-1)
34 xtables_error(PARAMETER_PROBLEM, "Bad mac address \"%s\"", mac);
35
36 for (i = 0; i < ETH_ALEN; i++) {
37 long number;
38 char *end;
39
40 number = strtol(mac + i*3, &end, 16);
41
42 if (end == mac + i*3 + 2
43 && number >= 0
44 && number <= 255)
45 info->srcaddr[i] = number;
46 else
47 xtables_error(PARAMETER_PROBLEM,
48 "Bad mac address `%s'", mac);
49 }
50}
51
52static int
53mac_parse(int c, char **argv, int invert, unsigned int *flags,
54 const void *entry, struct xt_entry_match **match)
55{
56 struct xt_mac_info *macinfo = (struct xt_mac_info *)(*match)->data;
57
58 switch (c) {
59 case '1':
60 xtables_check_inverse(optarg, &invert, &optind, 0);
61 parse_mac(argv[optind-1], macinfo);
62 if (invert)
63 macinfo->invert = 1;
64 *flags = 1;
65 break;
66
67 default:
68 return 0;
69 }
70
71 return 1;
72}
73
74static void print_mac(const unsigned char macaddress[ETH_ALEN])
75{
76 unsigned int i;
77
78 printf("%02X", macaddress[0]);
79 for (i = 1; i < ETH_ALEN; i++)
80 printf(":%02X", macaddress[i]);
81 printf(" ");
82}
83
84static void mac_check(unsigned int flags)
85{
86 if (!flags)
87 xtables_error(PARAMETER_PROBLEM,
88 "You must specify `--mac-source'");
89}
90
91static void
92mac_print(const void *ip, const struct xt_entry_match *match, int numeric)
93{
94 const struct xt_mac_info *info = (void *)match->data;
95 printf("MAC ");
96
97 if (info->invert)
98 printf("! ");
99
100 print_mac(info->srcaddr);
101}
102
103static void mac_save(const void *ip, const struct xt_entry_match *match)
104{
105 const struct xt_mac_info *info = (void *)match->data;
106
107 if (info->invert)
108 printf("! ");
109
110 printf("--mac-source ");
111 print_mac(info->srcaddr);
112}
113
114static struct xtables_match mac_match = {
115 .family = NFPROTO_IPV4,
116 .name = "mac",
117 .version = XTABLES_VERSION,
118 .size = XT_ALIGN(sizeof(struct xt_mac_info)),
119 .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)),
120 .help = mac_help,
121 .parse = mac_parse,
122 .final_check = mac_check,
123 .print = mac_print,
124 .save = mac_save,
125 .extra_opts = mac_opts,
126};
127
128static struct xtables_match mac_match6 = {
129 .family = NFPROTO_IPV6,
130 .name = "mac",
131 .version = XTABLES_VERSION,
132 .size = XT_ALIGN(sizeof(struct xt_mac_info)),
133 .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)),
134 .help = mac_help,
135 .parse = mac_parse,
136 .final_check = mac_check,
137 .print = mac_print,
138 .save = mac_save,
139 .extra_opts = mac_opts,
140};
141
142void _init(void)
143{
144 xtables_register_match(&mac_match);
145 xtables_register_match(&mac_match6);
146}