From bd9578d2dc1bf4ed587e0158b8f3c0753fd18f29 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Thu, 7 Jun 2007 15:37:44 +0000 Subject: fix nfct_snprintf behaviour if the buffer passed is too small (similar to C99 convention) --- src/conntrack/api.c | 5 +- src/conntrack/snprintf.c | 3 +- src/conntrack/snprintf_default.c | 95 +++++++------------------- src/conntrack/snprintf_xml.c | 142 ++++++++++----------------------------- 4 files changed, 62 insertions(+), 183 deletions(-) (limited to 'src/conntrack') diff --git a/src/conntrack/api.c b/src/conntrack/api.c index 9f14188..2d90818 100644 --- a/src/conntrack/api.c +++ b/src/conntrack/api.c @@ -605,8 +605,9 @@ int nfct_catch(struct nfct_handle *h) * - NFCT_O_LAYER: include layer 3 information in the output, this is * *only* required by NFCT_O_DEFAULT. * - * On error, -1 is returned and errno is set appropiately. Otherwise, - * 0 is returned. + * This function returns the size of the information that _would_ have been + * written to the buffer, even if there was no room for it. Thus, the + * behaviour is similar to snprintf. */ int nfct_snprintf(char *buf, unsigned int size, diff --git a/src/conntrack/snprintf.c b/src/conntrack/snprintf.c index 0c500b7..bcaf2db 100644 --- a/src/conntrack/snprintf.c +++ b/src/conntrack/snprintf.c @@ -29,8 +29,7 @@ int __snprintf_conntrack(char *buf, } /* NULL terminated string */ - if (snprintf(buf+size, len-size, "\0") == -1) - return -1; + buf[size+1 > len ? len-1 : size] = '\0'; return size; } diff --git a/src/conntrack/snprintf_default.c b/src/conntrack/snprintf_default.c index 054a4fc..78c0c64 100644 --- a/src/conntrack/snprintf_default.c +++ b/src/conntrack/snprintf_default.c @@ -70,19 +70,15 @@ int __snprintf_address_ipv4(char *buf, unsigned int len, const struct __nfct_tuple *tuple) { - int ret, size; + int ret, size = 0; struct in_addr src = { .s_addr = tuple->src.v4 }; struct in_addr dst = { .s_addr = tuple->dst.v4 }; ret = snprintf(buf, len, "src=%s ", inet_ntoa(src)); - if (ret == -1) - return -1; - size = ret; + BUFFER_SIZE(ret, size, len); - ret = snprintf(buf+size, len-size, "dst=%s ", inet_ntoa(dst)); - if (ret == -1) - return -1; - size += ret; + ret = snprintf(buf+size, len, "dst=%s ", inet_ntoa(dst)); + BUFFER_SIZE(ret, size, len); return size; } @@ -91,7 +87,7 @@ int __snprintf_address_ipv6(char *buf, unsigned int len, const struct __nfct_tuple *tuple) { - int size; + int ret, size = 0; struct in6_addr src; struct in6_addr dst; char tmp[INET6_ADDRSTRLEN]; @@ -102,12 +98,14 @@ int __snprintf_address_ipv6(char *buf, if (!inet_ntop(AF_INET6, &src, tmp, sizeof(tmp))) return -1; - size = snprintf(buf, len, "src=%s ", tmp); + ret = snprintf(buf, len, "src=%s ", tmp); + BUFFER_SIZE(ret, size, len); if (!inet_ntop(AF_INET6, &dst, tmp, sizeof(tmp))) return -1; - size += snprintf(buf+size, len-size, "dst=%s ", tmp); + ret = snprintf(buf+size, len-size, "dst=%s ", tmp); + BUFFER_SIZE(ret, size, len); return size; } @@ -228,113 +226,68 @@ int __snprintf_conntrack_default(char *buf, break; } - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); if (flags & NFCT_OF_SHOW_LAYER3) { ret = __snprintf_l3protocol(buf+size, remain, ct); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); } ret = __snprintf_protocol(buf+size, remain, ct); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); if (test_bit(ATTR_TIMEOUT, ct->set)) { ret = __snprintf_timeout(buf+size, remain, ct); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); } if (test_bit(ATTR_TCP_STATE, ct->set)) { ret = __snprintf_protoinfo(buf+size, remain, ct); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); } ret = __snprintf_address(buf+size, remain, &ct->tuple[__DIR_ORIG]); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); ret = __snprintf_proto(buf+size, remain, &ct->tuple[__DIR_ORIG]); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); if (test_bit(ATTR_ORIG_COUNTER_PACKETS, ct->set) && test_bit(ATTR_ORIG_COUNTER_BYTES, ct->set)) { ret = __snprintf_counters(buf+size, remain, ct, __DIR_ORIG); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); } if (test_bit(ATTR_STATUS, ct->set)) { ret = __snprintf_status_not_seen_reply(buf+size, remain, ct); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); } ret = __snprintf_address(buf+size, remain, &ct->tuple[__DIR_REPL]); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); ret = __snprintf_proto(buf+size, remain, &ct->tuple[__DIR_REPL]); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); if (test_bit(ATTR_REPL_COUNTER_PACKETS, ct->set) && test_bit(ATTR_REPL_COUNTER_BYTES, ct->set)) { ret = __snprintf_counters(buf+size, remain, ct, __DIR_REPL); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); } if (test_bit(ATTR_STATUS, ct->set)) { ret = __snprintf_status_assured(buf+size, remain, ct); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); } if (test_bit(ATTR_MARK, ct->set)) { ret = __snprintf_mark(buf+size, remain, ct); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); } if (test_bit(ATTR_USE, ct->set)) { ret = __snprintf_use(buf+size, remain, ct); - if (ret == -1) - return -1; - size += ret; - remain -= ret; + BUFFER_SIZE(ret, size, remain); } /* Delete the last blank space */ diff --git a/src/conntrack/snprintf_xml.c b/src/conntrack/snprintf_xml.c index 669d3e8..892c85b 100644 --- a/src/conntrack/snprintf_xml.c +++ b/src/conntrack/snprintf_xml.c @@ -67,12 +67,6 @@ enum { __ADDR_DST, }; -static void buffer_size(int ret, unsigned int *size, unsigned int *len) -{ - *size += ret; - *len -= ret; -} - static char *__proto2str(u_int8_t protonum) { return proto2str[protonum] ? proto2str[protonum] : "unknown"; @@ -123,45 +117,33 @@ static int __snprintf_addr_xml(char *buf, switch(type) { case __ADDR_SRC: ret = snprintf(buf, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); break; case __ADDR_DST: ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); break; } switch (tuple->l3protonum) { case AF_INET: ret = __snprintf_ipv4_xml(buf+size, len, tuple, type); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); break; case AF_INET6: ret = __snprintf_ipv6_xml(buf+size, len, tuple, type); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); break; } switch(type) { case __ADDR_SRC: ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); break; case __ADDR_DST: ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); break; } @@ -183,15 +165,11 @@ static int __snprintf_proto_xml(char *buf, if (type == __ADDR_SRC) { ret = snprintf(buf, len, "%u", ntohs(tuple->l4src.tcp.port)); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); } else { ret = snprintf(buf, len, "%u", ntohs(tuple->l4dst.tcp.port)); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); } break; } @@ -209,15 +187,11 @@ static int __snprintf_counters_xml(char *buf, ret = snprintf(buf, len, "%llu", ct->counters[type].packets); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = snprintf(buf+size, len, "%llu", ct->counters[type].bytes); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); return size; } @@ -233,76 +207,50 @@ static int __snprintf_tuple_xml(char *buf, ret = snprintf(buf, len, "", dir == __DIR_ORIG ? "original" : "reply"); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = snprintf(buf+size, len, "", tuple->l3protonum, __l3proto2str(tuple->l3protonum)); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = __snprintf_addr_xml(buf+size, len, tuple, __DIR_ORIG); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = __snprintf_addr_xml(buf+size, len, tuple, __DIR_REPL); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = snprintf(buf+size, len, "", tuple->protonum, __proto2str(tuple->protonum)); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = __snprintf_proto_xml(buf+size, len, tuple, __DIR_ORIG); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = __snprintf_proto_xml(buf+size, len, tuple, __DIR_REPL); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); if (test_bit(ATTR_ORIG_COUNTER_PACKETS, ct->set) && test_bit(ATTR_ORIG_COUNTER_BYTES, ct->set)) { ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = __snprintf_counters_xml(buf+size, len, ct, dir); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); } ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); return size; } @@ -331,19 +279,13 @@ int __snprintf_conntrack_xml(char *buf, break; } - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = __snprintf_tuple_xml(buf+size, len, ct, __DIR_ORIG); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); ret = __snprintf_tuple_xml(buf+size, len, ct, __DIR_REPL); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); if (test_bit(ATTR_TIMEOUT, ct->set) || test_bit(ATTR_MARK, ct->set) || @@ -351,47 +293,35 @@ int __snprintf_conntrack_xml(char *buf, test_bit(ATTR_STATUS, ct->set)) { ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); } if (test_bit(ATTR_TIMEOUT, ct->set)) { ret = snprintf(buf+size, len, "%u", ct->timeout); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); } if (test_bit(ATTR_MARK, ct->set)) { ret = snprintf(buf+size, len, "%u", ct->mark); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); } if (test_bit(ATTR_USE, ct->set)) { ret = snprintf(buf+size, len, "%u", ct->use); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); } if (test_bit(ATTR_STATUS, ct->set) && ct->status & IPS_ASSURED) { ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); } if (test_bit(ATTR_STATUS, ct->set) && !(ct->status & IPS_SEEN_REPLY)) { ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); } if (test_bit(ATTR_TIMEOUT, ct->set) || @@ -399,15 +329,11 @@ int __snprintf_conntrack_xml(char *buf, test_bit(ATTR_USE, ct->set) || test_bit(ATTR_STATUS, ct->set)) { ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); } ret = snprintf(buf+size, len, ""); - if (ret == -1) - return -1; - buffer_size(ret, &size, &len); + BUFFER_SIZE(ret, size, len); return size; } -- cgit v1.2.3