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