blob: 617b353ff65ba57fb003952c5af3ce39774de2d2 [file] [log] [blame]
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +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
12#include <ip6tables.h>
13#include <linux/netfilter_ipv6/ip6t_mac.h>
14
15/* Function which prints out usage message. */
16static void
17help(void)
18{
19 printf(
20"MAC v%s options:\n"
21" --mac-source [!] XX:XX:XX:XX:XX:XX\n"
22" Match source MAC address\n"
Harald Welte80fe35d2002-05-29 13:08:15 +000023"\n", IPTABLES_VERSION);
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +000024}
25
26static struct option opts[] = {
27 { "mac-source", 1, 0, '1' },
28 {0}
29};
30
31/* Initialize the match. */
32static void
33init(struct ip6t_entry_match *m, unsigned int *nfcache)
34{
35 /* Can't cache this */
36 *nfcache |= NFC_UNKNOWN;
37}
38
39static void
40parse_mac(const char *mac, struct ip6t_mac_info *info)
41{
42 unsigned int i = 0;
43
44 if (strlen(mac) != ETH_ALEN*3-1)
45 exit_error(PARAMETER_PROBLEM, "Bad mac address `%s'", mac);
46
47 for (i = 0; i < ETH_ALEN; i++) {
48 long number;
49 char *end;
50
51 number = strtol(mac + i*3, &end, 16);
52
53 if (end == mac + i*3 + 2
54 && number >= 0
55 && number <= 255)
56 info->srcaddr[i] = number;
57 else
58 exit_error(PARAMETER_PROBLEM,
59 "Bad mac address `%s'", mac);
60 }
61}
62
63/* Function which parses command options; returns true if it
64 ate an option */
65static int
66parse(int c, char **argv, int invert, unsigned int *flags,
67 const struct ip6t_entry *entry,
68 unsigned int *nfcache,
69 struct ip6t_entry_match **match)
70{
71 struct ip6t_mac_info *macinfo = (struct ip6t_mac_info *)(*match)->data;
72
73 switch (c) {
74 case '1':
Harald Welteb77f1da2002-03-14 11:35:58 +000075 check_inverse(optarg, &invert, &optind, 0);
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +000076 parse_mac(argv[optind-1], macinfo);
77 if (invert)
78 macinfo->invert = 1;
79 *flags = 1;
80 break;
81
82 default:
83 return 0;
84 }
85
86 return 1;
87}
88
Dave Zambonini78c57fa2003-06-14 14:27:51 +000089static void print_mac(unsigned char macaddress[ETH_ALEN])
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +000090{
91 unsigned int i;
92
Dave Zambonini78c57fa2003-06-14 14:27:51 +000093 printf("%02X", macaddress[0]);
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +000094 for (i = 1; i < ETH_ALEN; i++)
95 printf(":%02X", macaddress[i]);
96 printf(" ");
97}
98
99/* Final check; must have specified --mac. */
100static void final_check(unsigned int flags)
101{
102 if (!flags)
103 exit_error(PARAMETER_PROBLEM,
104 "You must specify `--mac-source'");
105}
106
107/* Prints out the matchinfo. */
108static void
109print(const struct ip6t_ip6 *ip,
110 const struct ip6t_entry_match *match,
111 int numeric)
112{
113 printf("MAC ");
Dave Zambonini78c57fa2003-06-14 14:27:51 +0000114
115 if (((struct ip6t_mac_info *)match->data)->invert)
116 printf("! ");
117
118 print_mac(((struct ip6t_mac_info *)match->data)->srcaddr);
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000119}
120
121/* Saves the union ip6t_matchinfo in parsable form to stdout. */
122static void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
123{
Dave Zambonini78c57fa2003-06-14 14:27:51 +0000124 if (((struct ip6t_mac_info *)match->data)->invert)
125 printf("! ");
126
Michael Schwendt010491f2002-09-12 07:14:55 +0000127 printf("--mac-source ");
Dave Zambonini78c57fa2003-06-14 14:27:51 +0000128 print_mac(((struct ip6t_mac_info *)match->data)->srcaddr);
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000129}
130
Harald Welte3efb6ea2001-08-06 18:50:21 +0000131static
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000132struct ip6tables_match mac
133= { NULL,
134 "mac",
Harald Welte80fe35d2002-05-29 13:08:15 +0000135 IPTABLES_VERSION,
Jan Rekorajskidc8af0f2001-02-16 15:19:51 +0000136 IP6T_ALIGN(sizeof(struct ip6t_mac_info)),
137 IP6T_ALIGN(sizeof(struct ip6t_mac_info)),
138 &help,
139 &init,
140 &parse,
141 &final_check,
142 &print,
143 &save,
144 opts
145};
146
147void _init(void)
148{
149 register_match6(&mac);
150}