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 52static int 53snprintf_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 } 99err_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 119static int 120snprintf_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 179static int 180snprintf_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 239int __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