Home | History | Annotate | Download | only in expect
      1 /*
      2  * (C) 2005-2011 by Pablo Neira Ayuso <pablo (at) 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 }
    275