libnetfilter_conntrack  1.0.6
expect/snprintf_xml.c
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
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
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
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 
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 }