• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  */
9 
10 #include "internal/internal.h"
11 
12 /*
13  * XML output sample:
14  *
15  * <flow type="new">
16  *	<layer3 protonum="2" protoname="IPv4">
17  *		<expected>
18  *			<src>192.168.0.2</src>
19  *			<dst>192.168.1.2</dst>
20  *		</expected>
21  *		<mask>
22  *			<src>255.255.255.255</src>
23  *			<dst>255.255.255.255</dst>
24  *		</mask>
25  *		<master>
26  *			<src>192.168.0.2</src>
27  *			<dst>192.168.1.2</dst>
28  *		</master>
29  *	</layer3>
30  *	<layer4 protonum="6" protoname="tcp">
31  *		<expected>
32  *			<sport>0</sport>
33  *			<dport>41739</dport>
34  *		</expected>
35  *		<mask>
36  *			<sport>0</sport>
37  *			<dport>65535</dport>
38  *		</mask>
39  *		<master>
40  *			<sport>36390</sport>
41  *			<dport>21</dport>
42  *		</master>
43  *	</layer4>
44  *	<meta>
45  *		<helper-name>ftp</helper-name>
46  *		<timeout>300</timeout>
47  *		<zone>0</zone>
48  *	</meta>
49  * </flow>
50  */
51 
52 static int
snprintf_expect_meta_xml(char * buf,size_t len,const struct nf_expect * exp,unsigned int flags)53 snprintf_expect_meta_xml(char *buf, size_t len,
54 			 const struct nf_expect *exp, unsigned int flags)
55 {
56 	int ret;
57 	unsigned int size = 0, offset = 0;
58 
59 	ret = snprintf(buf, len, "<meta>");
60 	BUFFER_SIZE(ret, size, len, offset);
61 
62 	if (test_bit(ATTR_EXP_HELPER_NAME, exp->set)) {
63 		ret = snprintf(buf+offset, len,
64 				"<helper-name>%s</helper-name>",
65 				exp->helper_name);
66 		BUFFER_SIZE(ret, size, len, offset);
67 	}
68 	if (test_bit(ATTR_EXP_TIMEOUT, exp->set)) {
69 		ret = snprintf(buf+offset, len, "<timeout>%u</timeout>",
70 				exp->timeout);
71 		BUFFER_SIZE(ret, size, len, offset);
72 	}
73 	if (test_bit(ATTR_EXP_CLASS, exp->set)) {
74 		ret = snprintf(buf+offset, len, "<class>%u</class>",
75 				exp->class);
76 		BUFFER_SIZE(ret, size, len, offset);
77 	}
78 	if (test_bit(ATTR_EXP_ZONE, exp->set)) {
79 		ret = snprintf(buf+offset, len, "<zone>%u</zone>", exp->zone);
80 		BUFFER_SIZE(ret, size, len, offset);
81 	}
82         if (flags & NFCT_OF_TIME) {
83                 time_t t;
84                 struct tm tm;
85 
86                 t = time(NULL);
87                 if (localtime_r(&t, &tm) == NULL)
88                         goto err_out;
89 
90                 ret = snprintf(buf+offset, len, "<when>");
91                 BUFFER_SIZE(ret, size, len, offset);
92 
93                 ret = __snprintf_localtime_xml(buf+offset, len, &tm);
94                 BUFFER_SIZE(ret, size, len, offset);
95 
96                 ret = snprintf(buf+offset, len, "</when>");
97                 BUFFER_SIZE(ret, size, len, offset);
98         }
99 err_out:
100 	if (exp->flags & NF_CT_EXPECT_PERMANENT) {
101 		ret = snprintf(buf+offset, len, "<permanent/>");
102 		BUFFER_SIZE(ret, size, len, offset);
103 	}
104 	if (exp->flags & NF_CT_EXPECT_INACTIVE) {
105 		ret = snprintf(buf+offset, len, "<inactive/>");
106 		BUFFER_SIZE(ret, size, len, offset);
107 	}
108 	if (exp->flags & NF_CT_EXPECT_USERSPACE) {
109 		ret = snprintf(buf+offset, len, "<userspace/>");
110 		BUFFER_SIZE(ret, size, len, offset);
111 	}
112 
113 	ret = snprintf(buf+offset, len, "</meta>");
114 	BUFFER_SIZE(ret, size, len, offset);
115 
116 	return size;
117 }
118 
119 static int
snprintf_expect_layer3_xml(char * buf,size_t len,const struct nf_expect * exp)120 snprintf_expect_layer3_xml(char *buf, size_t len, const struct nf_expect *exp)
121 {
122 	int ret;
123 	unsigned int size = 0, offset = 0;
124 
125         ret = snprintf(buf+offset, len,
126                        "<layer3 protonum=\"%d\" protoname=\"%s\">",
127 			exp->expected.orig.l3protonum,
128 			__l3proto2str(exp->expected.orig.l3protonum));
129         BUFFER_SIZE(ret, size, len, offset);
130 
131         ret = snprintf(buf+offset, len, "<expected>");
132         BUFFER_SIZE(ret, size, len, offset);
133 
134         ret = __snprintf_addr_xml(buf+offset, len, &exp->expected.orig,
135 				__ADDR_SRC);
136         BUFFER_SIZE(ret, size, len, offset);
137 
138         ret = __snprintf_addr_xml(buf+offset, len, &exp->expected.orig,
139 				__ADDR_DST);
140         BUFFER_SIZE(ret, size, len, offset);
141 
142         ret = snprintf(buf+offset, len, "</expected>");
143         BUFFER_SIZE(ret, size, len, offset);
144 
145         ret = snprintf(buf+offset, len, "<mask>");
146         BUFFER_SIZE(ret, size, len, offset);
147 
148         ret = __snprintf_addr_xml(buf+offset, len, &exp->mask.orig,
149 				__ADDR_SRC);
150         BUFFER_SIZE(ret, size, len, offset);
151 
152         ret = __snprintf_addr_xml(buf+offset, len, &exp->mask.orig,
153 				__ADDR_DST);
154         BUFFER_SIZE(ret, size, len, offset);
155 
156         ret = snprintf(buf+offset, len, "</mask>");
157         BUFFER_SIZE(ret, size, len, offset);
158 
159         ret = snprintf(buf+offset, len, "<master>");
160         BUFFER_SIZE(ret, size, len, offset);
161 
162         ret = __snprintf_addr_xml(buf+offset, len, &exp->master.orig,
163 				__ADDR_SRC);
164         BUFFER_SIZE(ret, size, len, offset);
165 
166         ret = __snprintf_addr_xml(buf+offset, len, &exp->master.orig,
167 				__ADDR_DST);
168         BUFFER_SIZE(ret, size, len, offset);
169 
170         ret = snprintf(buf+offset, len, "</master>");
171         BUFFER_SIZE(ret, size, len, offset);
172 
173         ret = snprintf(buf+offset, len, "</layer3>");
174         BUFFER_SIZE(ret, size, len, offset);
175 
176 	return size;
177 }
178 
179 static int
snprintf_expect_layer4_xml(char * buf,size_t len,const struct nf_expect * exp)180 snprintf_expect_layer4_xml(char *buf, size_t len, const struct nf_expect *exp)
181 {
182 	int ret;
183 	unsigned int size = 0, offset = 0;
184 
185         ret = snprintf(buf+offset, len,
186                        "<layer4 protonum=\"%d\" protoname=\"%s\">",
187 			exp->expected.orig.protonum,
188 			__proto2str(exp->expected.orig.protonum));
189         BUFFER_SIZE(ret, size, len, offset);
190 
191         ret = snprintf(buf+offset, len, "<expected>");
192         BUFFER_SIZE(ret, size, len, offset);
193 
194 	ret = __snprintf_proto_xml(buf+offset, len, &exp->expected.orig,
195 				__ADDR_SRC);
196         BUFFER_SIZE(ret, size, len, offset);
197 
198 	ret = __snprintf_proto_xml(buf+offset, len, &exp->expected.orig,
199 				__ADDR_DST);
200         BUFFER_SIZE(ret, size, len, offset);
201 
202         ret = snprintf(buf+offset, len, "</expected>");
203         BUFFER_SIZE(ret, size, len, offset);
204 
205         ret = snprintf(buf+offset, len, "<mask>");
206         BUFFER_SIZE(ret, size, len, offset);
207 
208 	ret = __snprintf_proto_xml(buf+offset, len, &exp->mask.orig,
209 				__ADDR_SRC);
210         BUFFER_SIZE(ret, size, len, offset);
211 
212 	ret = __snprintf_proto_xml(buf+offset, len, &exp->mask.orig,
213 				__ADDR_DST);
214         BUFFER_SIZE(ret, size, len, offset);
215 
216         ret = snprintf(buf+offset, len, "</mask>");
217         BUFFER_SIZE(ret, size, len, offset);
218 
219         ret = snprintf(buf+offset, len, "<master>");
220         BUFFER_SIZE(ret, size, len, offset);
221 
222 	ret = __snprintf_proto_xml(buf+offset, len, &exp->master.orig,
223 				__ADDR_SRC);
224         BUFFER_SIZE(ret, size, len, offset);
225 
226 	ret = __snprintf_proto_xml(buf+offset, len, &exp->master.orig,
227 				__ADDR_DST);
228         BUFFER_SIZE(ret, size, len, offset);
229 
230         ret = snprintf(buf+offset, len, "</master>");
231         BUFFER_SIZE(ret, size, len, offset);
232 
233 	ret = snprintf(buf+offset, len, "</layer4>");
234         BUFFER_SIZE(ret, size, len, offset)
235 
236 	return size;
237 }
238 
__snprintf_expect_xml(char * buf,unsigned int len,const struct nf_expect * exp,unsigned int msg_type,unsigned int flags)239 int __snprintf_expect_xml(char *buf, unsigned int len,
240 			  const struct nf_expect *exp,
241 			  unsigned int msg_type, unsigned int flags)
242 {
243 	int ret = 0, size = 0, offset = 0;
244 
245 	switch(msg_type) {
246 		case NFCT_T_NEW:
247 			ret = snprintf(buf, len, "<flow type=\"new\">");
248 			break;
249 		case NFCT_T_UPDATE:
250 			ret = snprintf(buf, len, "<flow type=\"update\">");
251 			break;
252 		case NFCT_T_DESTROY:
253 			ret = snprintf(buf, len, "<flow type=\"destroy\">");
254 			break;
255 		default:
256 			ret = snprintf(buf, len, "<flow>");
257 			break;
258 	}
259 	BUFFER_SIZE(ret, size, len, offset);
260 
261 	ret = snprintf_expect_layer3_xml(buf+offset, len, exp);
262 	BUFFER_SIZE(ret, size, len, offset);
263 
264 	ret = snprintf_expect_layer4_xml(buf+offset, len, exp);
265 	BUFFER_SIZE(ret, size, len, offset);
266 
267 	ret = snprintf_expect_meta_xml(buf+offset, len, exp, flags);
268 	BUFFER_SIZE(ret, size, len, offset);
269 
270 	ret = snprintf(buf+offset, len, "</flow>");
271 	BUFFER_SIZE(ret, size, len, offset);
272 
273 	return size;
274 }
275