blob: 2d068b8a08eb031b41b8c00a8773cdcaf617f31a [file] [log] [blame]
Maciej Soltysiak60358d72003-01-08 09:14:20 +00001/*
2 * IPv6 Hop Limit matching module
3 * Maciej Soltysiak <solt@dns.toxicfilms.tv>
4 * Based on HW's ttl match
5 * This program is released under the terms of GNU GPL
Stephane Ouellette46525cd2003-05-07 20:08:36 +00006 * Cleanups by Stephane Ouellette <ouellettes@videotron.ca>
Maciej Soltysiak60358d72003-01-08 09:14:20 +00007 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <getopt.h>
13#include <ip6tables.h>
14
15#include <linux/netfilter_ipv6/ip6_tables.h>
16#include <linux/netfilter_ipv6/ip6t_hl.h>
17
18static void help(void)
19{
20 printf(
21"HL match v%s options:\n"
Stephane Ouellette46525cd2003-05-07 20:08:36 +000022" --hl-eq [!] value Match hop limit value\n"
Maciej Soltysiak60358d72003-01-08 09:14:20 +000023" --hl-lt value Match HL < value\n"
24" --hl-gt value Match HL > value\n"
25, IPTABLES_VERSION);
26}
27
28static void init(struct ip6t_entry_match *m, unsigned int *nfcache)
29{
30 /* caching not yet implemented */
31 *nfcache |= NFC_UNKNOWN;
32}
33
34static int parse(int c, char **argv, int invert, unsigned int *flags,
35 const struct ip6t_entry *entry, unsigned int *nfcache,
36 struct ip6t_entry_match **match)
37{
38 struct ip6t_hl_info *info = (struct ip6t_hl_info *) (*match)->data;
39 u_int8_t value;
40
41 check_inverse(optarg, &invert, &optind, 0);
42 value = atoi(argv[optind-1]);
43
44 if (*flags)
45 exit_error(PARAMETER_PROBLEM,
46 "Can't specify HL option twice");
47
48 if (!optarg)
49 exit_error(PARAMETER_PROBLEM,
50 "hl: You must specify a value");
51 switch (c) {
52 case '2':
53 if (invert)
54 info->mode = IP6T_HL_NE;
55 else
56 info->mode = IP6T_HL_EQ;
57
58 /* is 0 allowed? */
59 info->hop_limit = value;
60 *flags = 1;
61
62 break;
63 case '3':
64 if (invert)
65 exit_error(PARAMETER_PROBLEM,
66 "hl: unexpected `!'");
67
68 info->mode = IP6T_HL_LT;
69 info->hop_limit = value;
70 *flags = 1;
71
72 break;
73 case '4':
74 if (invert)
75 exit_error(PARAMETER_PROBLEM,
76 "hl: unexpected `!'");
77
78 info->mode = IP6T_HL_GT;
79 info->hop_limit = value;
80 *flags = 1;
81
82 break;
83 default:
84 return 0;
Maciej Soltysiak60358d72003-01-08 09:14:20 +000085 }
86
87 return 1;
88}
89
90static void final_check(unsigned int flags)
91{
92 if (!flags)
93 exit_error(PARAMETER_PROBLEM,
94 "HL match: You must specify one of "
Stephane Ouellette46525cd2003-05-07 20:08:36 +000095 "`--hl-eq', `--hl-lt', `--hl-gt'");
Maciej Soltysiak60358d72003-01-08 09:14:20 +000096}
97
98static void print(const struct ip6t_ip6 *ip,
99 const struct ip6t_entry_match *match,
100 int numeric)
101{
Stephane Ouellette46525cd2003-05-07 20:08:36 +0000102 static const char *op[] = {
103 [IP6T_HL_EQ] = "==",
104 [IP6T_HL_NE] = "!=",
105 [IP6T_HL_LT] = "<",
106 [IP6T_HL_GT] = ">" };
107
Maciej Soltysiak60358d72003-01-08 09:14:20 +0000108 const struct ip6t_hl_info *info =
109 (struct ip6t_hl_info *) match->data;
110
Stephane Ouellette46525cd2003-05-07 20:08:36 +0000111 printf("HL match HL %s %u ", op[info->mode], info->hop_limit);
Maciej Soltysiak60358d72003-01-08 09:14:20 +0000112}
113
114static void save(const struct ip6t_ip6 *ip,
115 const struct ip6t_entry_match *match)
116{
Stephane Ouellette46525cd2003-05-07 20:08:36 +0000117 static const char *op[] = {
118 [IP6T_HL_EQ] = "eq",
119 [IP6T_HL_NE] = "eq !",
120 [IP6T_HL_LT] = "lt",
121 [IP6T_HL_GT] = "gt" };
122
Maciej Soltysiak60358d72003-01-08 09:14:20 +0000123 const struct ip6t_hl_info *info =
124 (struct ip6t_hl_info *) match->data;
125
Stephane Ouellette46525cd2003-05-07 20:08:36 +0000126 printf("--hl-%s %u ", op[info->mode], info->hop_limit);
Maciej Soltysiak60358d72003-01-08 09:14:20 +0000127}
128
129static struct option opts[] = {
Stephane Ouellette46525cd2003-05-07 20:08:36 +0000130 { .name = "hl", .has_arg = 1, .flag = 0, .val = '2' },
131 { .name = "hl-eq", .has_arg = 1, .flag = 0, .val = '2' },
132 { .name = "hl-lt", .has_arg = 1, .flag = 0, .val = '3' },
133 { .name = "hl-gt", .has_arg = 1, .flag = 0, .val = '4' },
Maciej Soltysiak60358d72003-01-08 09:14:20 +0000134 { 0 }
135};
136
137static
138struct ip6tables_match hl = {
Stephane Ouellette46525cd2003-05-07 20:08:36 +0000139 .name = "hl",
140 .version = IPTABLES_VERSION,
141 .size = IP6T_ALIGN(sizeof(struct ip6t_hl_info)),
142 .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_hl_info)),
143 .help = &help,
144 .init = &init,
145 .parse = &parse,
146 .final_check = &final_check,
147 .print = &print,
148 .save = &save,
149 .extra_opts = opts
Maciej Soltysiak60358d72003-01-08 09:14:20 +0000150};
151
152
153void _init(void)
154{
155 register_match6(&hl);
156}