blob: f4128c0180ac45d9505af83644ce47f0f7fcc9e2 [file] [log] [blame]
Marc Bouchere6869a82000-03-20 06:03:29 +00001/* 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
Yasuyuki KOZAKAIba2d8912007-07-24 07:09:51 +000012#include <xtables.h>
13#include <linux/netfilter/xt_mac.h>
Marc Bouchere6869a82000-03-20 06:03:29 +000014
Jan Engelhardt181dead2007-10-04 16:27:07 +000015static void mac_help(void)
Marc Bouchere6869a82000-03-20 06:03:29 +000016{
17 printf(
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020018"mac match options:\n"
Jan Engelhardt96727922008-08-13 14:42:41 +020019"[!] --mac-source XX:XX:XX:XX:XX:XX\n"
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020020" Match source MAC address\n");
Marc Bouchere6869a82000-03-20 06:03:29 +000021}
22
Jan Engelhardt181dead2007-10-04 16:27:07 +000023static const struct option mac_opts[] = {
Patrick McHardy500f4832007-09-08 15:59:04 +000024 { "mac-source", 1, NULL, '1' },
Max Kellermann9ee386a2008-01-29 13:48:05 +000025 { .name = NULL }
Marc Bouchere6869a82000-03-20 06:03:29 +000026};
27
Marc Bouchere6869a82000-03-20 06:03:29 +000028static void
Yasuyuki KOZAKAIba2d8912007-07-24 07:09:51 +000029parse_mac(const char *mac, struct xt_mac_info *info)
Marc Bouchere6869a82000-03-20 06:03:29 +000030{
31 unsigned int i = 0;
32
33 if (strlen(mac) != ETH_ALEN*3-1)
34 exit_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 exit_error(PARAMETER_PROBLEM,
48 "Bad mac address `%s'", mac);
49 }
50}
51
Marc Bouchere6869a82000-03-20 06:03:29 +000052static int
Jan Engelhardt181dead2007-10-04 16:27:07 +000053mac_parse(int c, char **argv, int invert, unsigned int *flags,
54 const void *entry, struct xt_entry_match **match)
Marc Bouchere6869a82000-03-20 06:03:29 +000055{
Yasuyuki KOZAKAIba2d8912007-07-24 07:09:51 +000056 struct xt_mac_info *macinfo = (struct xt_mac_info *)(*match)->data;
Marc Bouchere6869a82000-03-20 06:03:29 +000057
58 switch (c) {
59 case '1':
Harald Welteb77f1da2002-03-14 11:35:58 +000060 check_inverse(optarg, &invert, &optind, 0);
Marc Bouchere6869a82000-03-20 06:03:29 +000061 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
Jan Engelhardt161143d2008-09-01 14:18:01 +020074static void print_mac(const unsigned char macaddress[ETH_ALEN])
Marc Bouchere6869a82000-03-20 06:03:29 +000075{
76 unsigned int i;
77
Dave Zambonini78c57fa2003-06-14 14:27:51 +000078 printf("%02X", macaddress[0]);
Marc Bouchere6869a82000-03-20 06:03:29 +000079 for (i = 1; i < ETH_ALEN; i++)
80 printf(":%02X", macaddress[i]);
81 printf(" ");
82}
83
Jan Engelhardt181dead2007-10-04 16:27:07 +000084static void mac_check(unsigned int flags)
Marc Bouchere6869a82000-03-20 06:03:29 +000085{
86 if (!flags)
87 exit_error(PARAMETER_PROBLEM,
88 "You must specify `--mac-source'");
89}
90
Marc Bouchere6869a82000-03-20 06:03:29 +000091static void
Jan Engelhardt181dead2007-10-04 16:27:07 +000092mac_print(const void *ip, const struct xt_entry_match *match, int numeric)
Marc Bouchere6869a82000-03-20 06:03:29 +000093{
Jan Engelhardt161143d2008-09-01 14:18:01 +020094 const struct xt_mac_info *info = (void *)match->data;
Marc Bouchere6869a82000-03-20 06:03:29 +000095 printf("MAC ");
Dave Zambonini78c57fa2003-06-14 14:27:51 +000096
Jan Engelhardt161143d2008-09-01 14:18:01 +020097 if (info->invert)
Dave Zambonini78c57fa2003-06-14 14:27:51 +000098 printf("! ");
99
Jan Engelhardt161143d2008-09-01 14:18:01 +0200100 print_mac(info->srcaddr);
Marc Bouchere6869a82000-03-20 06:03:29 +0000101}
102
Jan Engelhardt181dead2007-10-04 16:27:07 +0000103static void mac_save(const void *ip, const struct xt_entry_match *match)
Marc Bouchere6869a82000-03-20 06:03:29 +0000104{
Jan Engelhardt161143d2008-09-01 14:18:01 +0200105 const struct xt_mac_info *info = (void *)match->data;
106
107 if (info->invert)
Dave Zambonini78c57fa2003-06-14 14:27:51 +0000108 printf("! ");
109
Michael Schwendt010491f2002-09-12 07:14:55 +0000110 printf("--mac-source ");
Jan Engelhardt161143d2008-09-01 14:18:01 +0200111 print_mac(info->srcaddr);
Marc Bouchere6869a82000-03-20 06:03:29 +0000112}
113
Jan Engelhardt181dead2007-10-04 16:27:07 +0000114static struct xtables_match mac_match = {
Jan Engelhardt03d99482008-11-18 12:27:54 +0100115 .family = NFPROTO_IPV4,
Pablo Neira8caee8b2004-12-28 13:11:59 +0000116 .name = "mac",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200117 .version = XTABLES_VERSION,
Yasuyuki KOZAKAIba2d8912007-07-24 07:09:51 +0000118 .size = XT_ALIGN(sizeof(struct xt_mac_info)),
119 .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)),
Jan Engelhardt181dead2007-10-04 16:27:07 +0000120 .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,
Yasuyuki KOZAKAIba2d8912007-07-24 07:09:51 +0000126};
127
Jan Engelhardt181dead2007-10-04 16:27:07 +0000128static struct xtables_match mac_match6 = {
Jan Engelhardt03d99482008-11-18 12:27:54 +0100129 .family = NFPROTO_IPV6,
Yasuyuki KOZAKAIba2d8912007-07-24 07:09:51 +0000130 .name = "mac",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200131 .version = XTABLES_VERSION,
Yasuyuki KOZAKAIba2d8912007-07-24 07:09:51 +0000132 .size = XT_ALIGN(sizeof(struct xt_mac_info)),
133 .userspacesize = XT_ALIGN(sizeof(struct xt_mac_info)),
Jan Engelhardt181dead2007-10-04 16:27:07 +0000134 .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,
Marc Bouchere6869a82000-03-20 06:03:29 +0000140};
141
142void _init(void)
143{
Jan Engelhardt181dead2007-10-04 16:27:07 +0000144 xtables_register_match(&mac_match);
145 xtables_register_match(&mac_match6);
Marc Bouchere6869a82000-03-20 06:03:29 +0000146}