• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/conntrack-tools/conntrack-tools-1.4.0/extensions/
1/*
2 * (C) 2008 by Krzysztof Piotr Oledzki <ole@ans.pl>
3 *
4 * Based on libct_proto_icmp.c:
5 * (C) 2005-2007 by Pablo Neira Ayuso <pablo@netfilter.org>
6 *     2005 by Harald Welte <laforge@netfilter.org>
7 *
8 *      This program is free software; you can redistribute it and/or modify
9 *      it under the terms of the GNU General Public License as published by
10 *      the Free Software Foundation; either version 2 of the License, or
11 *      (at your option) any later version.
12 *
13 */
14
15#include "conntrack.h"
16
17#include <stdio.h>
18#include <getopt.h>
19#include <stdlib.h>
20#include <netinet/in.h> /* For htons */
21#include <netinet/icmp6.h>
22#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
23
24enum {
25	CT_ICMP_TYPE	= (1 << 0),
26	CT_ICMP_CODE	= (1 << 1),
27	CT_ICMP_ID	= (1 << 2),
28};
29
30static struct option opts[] = {
31	{ "icmpv6-type", 1, 0, '1' },
32	{ "icmpv6-code", 1, 0, '2' },
33	{ "icmpv6-id",  1, 0, '3' },
34	{ 0, 0, 0, 0 },
35};
36
37#define ICMPV6_NUMBER_OF_OPT 4
38
39static const char *icmpv6_optflags[ICMPV6_NUMBER_OF_OPT] = {
40	"icmpv6-type", "icmpv6-code", "icmpv6-id"
41};
42
43static char icmpv6_commands_v_options[NUMBER_OF_CMD][ICMPV6_NUMBER_OF_OPT] =
44/* Well, it's better than "Re: Maradona vs Pele" */
45{
46		/* 1 2 3 */
47/*CT_LIST*/	  {2,2,2},
48/*CT_CREATE*/	  {1,1,2},
49/*CT_UPDATE*/	  {2,2,2},
50/*CT_DELETE*/	  {2,2,2},
51/*CT_GET*/	  {1,1,2},
52/*CT_FLUSH*/	  {0,0,0},
53/*CT_EVENT*/	  {2,2,2},
54/*CT_VERSION*/	  {0,0,0},
55/*CT_HELP*/	  {0,0,0},
56/*EXP_LIST*/	  {0,0,0},
57/*EXP_CREATE*/	  {0,0,0},
58/*EXP_DELETE*/	  {0,0,0},
59/*EXP_GET*/	  {0,0,0},
60/*EXP_FLUSH*/	  {0,0,0},
61/*EXP_EVENT*/	  {0,0,0},
62};
63
64static void help(void)
65{
66	fprintf(stdout, "  --icmpv6-type\t\t\ticmpv6 type\n");
67	fprintf(stdout, "  --icmpv6-code\t\t\ticmpv6 code\n");
68	fprintf(stdout, "  --icmpv6-id\t\t\ticmpv6 id\n");
69}
70
71static int parse(char c,
72		 struct nf_conntrack *ct,
73		 struct nf_conntrack *exptuple,
74		 struct nf_conntrack *mask,
75		 unsigned int *flags)
76{
77	switch(c) {
78		u_int8_t tmp;
79		u_int16_t id;
80		case '1':
81			tmp = atoi(optarg);
82			nfct_set_attr_u8(ct, ATTR_ICMP_TYPE, tmp);
83			nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_ICMPV6);
84			*flags |= CT_ICMP_TYPE;
85			break;
86		case '2':
87			tmp = atoi(optarg);
88			nfct_set_attr_u8(ct, ATTR_ICMP_CODE, tmp);
89			nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_ICMPV6);
90			*flags |= CT_ICMP_CODE;
91			break;
92		case '3':
93			id = htons(atoi(optarg));
94			nfct_set_attr_u16(ct, ATTR_ICMP_ID, id);
95			nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_ICMPV6);
96			*flags |= CT_ICMP_ID;
97			break;
98	}
99	return 1;
100}
101
102static void final_check(unsigned int flags,
103		        unsigned int cmd,
104		        struct nf_conntrack *ct)
105{
106	generic_opt_check(flags, ICMPV6_NUMBER_OF_OPT,
107			  icmpv6_commands_v_options[cmd], icmpv6_optflags,
108			  NULL, 0, NULL);
109}
110
111static struct ctproto_handler icmpv6 = {
112	.name 		= "icmpv6",
113	.protonum	= IPPROTO_ICMPV6,
114	.parse_opts	= parse,
115	.final_check	= final_check,
116	.help		= help,
117	.opts		= opts,
118	.version	= VERSION,
119};
120
121void register_icmpv6(void)
122{
123	register_proto(&icmpv6);
124}
125