• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <getopt.h>
5 #include <iptables.h>
6 
7 #include <linux/netfilter_ipv4/ip_tables.h>
8 #include <linux/netfilter/xt_NFLOG.h>
9 
10 enum {
11 	NFLOG_GROUP	= 0x1,
12 	NFLOG_PREFIX	= 0x2,
13 	NFLOG_RANGE	= 0x4,
14 	NFLOG_THRESHOLD	= 0x8,
15 };
16 
17 static struct option opts[] = {
18 	{ "nflog-group",     1, 0, NFLOG_GROUP },
19 	{ "nflog-prefix",    1, 0, NFLOG_PREFIX },
20 	{ "nflog-range",     1, 0, NFLOG_RANGE },
21 	{ "nflog-threshold", 1, 0, NFLOG_THRESHOLD },
22 };
23 
help(void)24 static void help(void)
25 {
26 	printf("NFLOG v%s options:\n"
27 	       " --nflog-group NUM		NETLINK group used for logging\n"
28 	       " --nflog-range NUM		Number of byte to copy\n"
29 	       " --nflog-threshold NUM		Message threshold of in-kernel queue\n"
30 	       " --nflog-prefix STRING		Prefix string for log messages\n\n",
31 	       IPTABLES_VERSION);
32 }
33 
init(struct xt_entry_target * t,unsigned int * nfcache)34 static void init(struct xt_entry_target *t, unsigned int *nfcache)
35 {
36 	struct xt_nflog_info *info = (struct xt_nflog_info *)t->data;
37 
38 	info->group	= XT_NFLOG_DEFAULT_GROUP;
39 	info->threshold	= XT_NFLOG_DEFAULT_THRESHOLD;
40 }
41 
parse(int c,char ** argv,int invert,unsigned int * flags,const struct ipt_entry * entry,struct xt_entry_target ** target)42 static int parse(int c, char **argv, int invert, unsigned int *flags,
43 		 const struct ipt_entry *entry,
44 		 struct xt_entry_target **target)
45 {
46 	struct xt_nflog_info *info = (struct xt_nflog_info *)(*target)->data;
47 	int n;
48 
49 	switch (c) {
50 	case NFLOG_GROUP:
51 		if (*flags & NFLOG_GROUP)
52 			exit_error(PARAMETER_PROBLEM,
53 				   "Can't specify --nflog-group twice");
54 		if (check_inverse(optarg, &invert, NULL, 0))
55 			exit_error(PARAMETER_PROBLEM,
56 				   "Unexpected `!' after --nflog-group");
57 
58 		n = atoi(optarg);
59 		if (n < 1 || n > 32)
60 			exit_error(PARAMETER_PROBLEM,
61 				   "--nflog-group has to be between 1 and 32");
62 		info->group = 1 << (n - 1);
63 		break;
64 	case NFLOG_PREFIX:
65 		if (*flags & NFLOG_PREFIX)
66 			exit_error(PARAMETER_PROBLEM,
67 				   "Can't specify --nflog-prefix twice");
68 		if (check_inverse(optarg, &invert, NULL, 0))
69 			exit_error(PARAMETER_PROBLEM,
70 				   "Unexpected `!' after --nflog-prefix");
71 
72 		n = strlen(optarg);
73 		if (n == 0)
74 			exit_error(PARAMETER_PROBLEM,
75 				   "No prefix specified for --nflog-prefix");
76 		if (n >= sizeof(info->prefix))
77 			exit_error(PARAMETER_PROBLEM,
78 				   "--nflog-prefix too long, max %Zu characters",
79 				   sizeof(info->prefix) - 1);
80 		if (n != strlen(strtok(optarg, "\n")))
81 			exit_error(PARAMETER_PROBLEM,
82 				   "Newlines are not allowed in --nflog-prefix");
83 		strcpy(info->prefix, optarg);
84 		break;
85 	case NFLOG_RANGE:
86 		if (*flags & NFLOG_RANGE)
87 			exit_error(PARAMETER_PROBLEM,
88 				   "Can't specify --nflog-range twice");
89 		n = atoi(optarg);
90 		if (n < 0)
91 			exit_error(PARAMETER_PROBLEM,
92 				   "Invalid --nflog-range, must be >= 0");
93 		info->len = n;
94 		break;
95 	case NFLOG_THRESHOLD:
96 		if (*flags & NFLOG_THRESHOLD)
97 			exit_error(PARAMETER_PROBLEM,
98 				   "Can't specify --nflog-threshold twice");
99 		n = atoi(optarg);
100 		if (n < 1)
101 			exit_error(PARAMETER_PROBLEM,
102 				   "Invalid --nflog-threshold, must be >= 1");
103 		info->threshold = n;
104 		break;
105 	default:
106 		return 0;
107 	}
108 	*flags |= c;
109 	return 1;
110 }
111 
final_check(unsigned int flags)112 static void final_check(unsigned int flags)
113 {
114 	return;
115 }
116 
nflog_print(const struct xt_nflog_info * info,char * prefix)117 static void nflog_print(const struct xt_nflog_info *info, char *prefix)
118 {
119 	if (info->prefix[0] != '\0')
120 		printf("%snflog-prefix \"%s\" ", prefix, info->prefix);
121 	if (info->group != XT_NFLOG_DEFAULT_GROUP)
122 		printf("%snflog-group %u ", prefix, ffs(info->group));
123 	if (info->len)
124 		printf("%snflog-range %u ", prefix, info->len);
125 	if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD)
126 		printf("%snflog-threshold %u ", prefix, info->threshold);
127 }
128 
print(const struct ipt_ip * ip,const struct xt_entry_target * target,int numeric)129 static void print(const struct ipt_ip *ip, const struct xt_entry_target *target,
130 		  int numeric)
131 {
132 	const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data;
133 
134 	nflog_print(info, "");
135 }
136 
save(const struct ipt_ip * ip,const struct xt_entry_target * target)137 static void save(const struct ipt_ip *ip, const struct xt_entry_target *target)
138 {
139 	const struct xt_nflog_info *info = (struct xt_nflog_info *)target->data;
140 
141 	nflog_print(info, "--");
142 }
143 
144 static struct iptables_target nflog = {
145 	.name		= "NFLOG",
146 	.version	= IPTABLES_VERSION,
147 	.size		= XT_ALIGN(sizeof(struct xt_nflog_info)),
148 	.userspacesize	= XT_ALIGN(sizeof(struct xt_nflog_info)),
149 	.help		= help,
150 	.init		= init,
151 	.parse		= parse,
152 	.final_check	= final_check,
153 	.print		= print,
154 	.save		= save,
155 	.extra_opts	= opts,
156 };
157 
ipt_NFLOG_init(void)158 void ipt_NFLOG_init(void)
159 {
160 	register_target(&nflog);
161 }
162