10 #include "internal/internal.h"
12 static int __snprintf_l3protocol(
char *buf,
14 const struct nf_conntrack *ct)
16 return (snprintf(buf, len,
"%-8s %u ",
17 l3proto2str[ct->head.orig.l3protonum] == NULL ?
18 "unknown" : l3proto2str[ct->head.orig.l3protonum],
19 ct->head.orig.l3protonum));
22 int __snprintf_protocol(
char *buf,
24 const struct nf_conntrack *ct)
26 return (snprintf(buf, len,
"%-8s %u ",
27 proto2str[ct->head.orig.protonum] == NULL ?
28 "unknown" : proto2str[ct->head.orig.protonum],
29 ct->head.orig.protonum));
32 static int __snprintf_timeout(
char *buf,
34 const struct nf_conntrack *ct)
36 return snprintf(buf, len,
"%u ", ct->timeout);
39 static int __snprintf_protoinfo(
char *buf,
41 const struct nf_conntrack *ct)
43 return snprintf(buf, len,
"%s ",
44 ct->protoinfo.tcp.state < TCP_CONNTRACK_MAX ?
45 states[ct->protoinfo.tcp.state] :
46 states[TCP_CONNTRACK_NONE]);
49 static int __snprintf_protoinfo_sctp(
char *buf,
51 const struct nf_conntrack *ct)
53 return snprintf(buf, len,
"%s ",
54 ct->protoinfo.sctp.state < SCTP_CONNTRACK_MAX ?
55 sctp_states[ct->protoinfo.sctp.state] :
56 sctp_states[SCTP_CONNTRACK_NONE]);
59 static int __snprintf_protoinfo_dccp(
char *buf,
61 const struct nf_conntrack *ct)
63 return snprintf(buf, len,
"%s ",
64 ct->protoinfo.dccp.state < DCCP_CONNTRACK_MAX ?
65 sctp_states[ct->protoinfo.dccp.state] :
66 sctp_states[DCCP_CONNTRACK_NONE]);
69 static int __snprintf_address_ipv4(
char *buf,
71 const struct __nfct_tuple *tuple,
75 int ret, size = 0, offset = 0;
76 struct in_addr src = { .s_addr = tuple->src.v4 };
77 struct in_addr dst = { .s_addr = tuple->dst.v4 };
79 ret = snprintf(buf, len,
"%s=%s ", src_tag, inet_ntoa(src));
80 BUFFER_SIZE(ret, size, len, offset);
82 ret = snprintf(buf+offset, len,
"%s=%s ", dst_tag, inet_ntoa(dst));
83 BUFFER_SIZE(ret, size, len, offset);
88 static int __snprintf_address_ipv6(
char *buf,
90 const struct __nfct_tuple *tuple,
94 int ret, size = 0, offset = 0;
97 char tmp[INET6_ADDRSTRLEN];
99 memcpy(&src, &tuple->src.v6,
sizeof(
struct in6_addr));
100 memcpy(&dst, &tuple->dst.v6,
sizeof(
struct in6_addr));
102 if (!inet_ntop(AF_INET6, &src, tmp,
sizeof(tmp)))
105 ret = snprintf(buf, len,
"%s=%s ", src_tag, tmp);
106 BUFFER_SIZE(ret, size, len, offset);
108 if (!inet_ntop(AF_INET6, &dst, tmp,
sizeof(tmp)))
111 ret = snprintf(buf+offset, len-size,
"%s=%s ", dst_tag, tmp);
112 BUFFER_SIZE(ret, size, len, offset);
117 int __snprintf_address(
char *buf,
119 const struct __nfct_tuple *tuple,
125 switch (tuple->l3protonum) {
127 size = __snprintf_address_ipv4(buf, len, tuple,
131 size = __snprintf_address_ipv6(buf, len, tuple,
139 int __snprintf_proto(
char *buf,
141 const struct __nfct_tuple *tuple)
145 switch(tuple->protonum) {
148 case IPPROTO_UDPLITE:
151 return snprintf(buf, len,
"sport=%u dport=%u ",
152 ntohs(tuple->l4src.tcp.port),
153 ntohs(tuple->l4dst.tcp.port));
156 return snprintf(buf, len,
"srckey=0x%x dstkey=0x%x ",
157 ntohs(tuple->l4src.all),
158 ntohs(tuple->l4dst.all));
164 return (snprintf(buf, len,
"type=%d code=%d id=%d ",
165 tuple->l4dst.icmp.type,
166 tuple->l4dst.icmp.code,
167 ntohs(tuple->l4src.icmp.id)));
175 __snprintf_tuple_zone(
char *buf,
unsigned int len,
const char *pfx,
176 const struct __nfct_tuple *tuple)
178 return (snprintf(buf, len,
"zone-%s=%u ", pfx, tuple->zone));
181 static int __snprintf_status_assured(
char *buf,
183 const struct nf_conntrack *ct)
187 if (ct->status & IPS_ASSURED)
188 size = snprintf(buf, len,
"[ASSURED] ");
193 static int __snprintf_status_not_seen_reply(
char *buf,
195 const struct nf_conntrack *ct)
199 if (!(ct->status & IPS_SEEN_REPLY))
200 size = snprintf(buf, len,
"[UNREPLIED] ");
205 static int __snprintf_counters(
char *buf,
207 const struct nf_conntrack *ct,
210 return (snprintf(buf, len,
"packets=%llu bytes=%llu ",
211 (
unsigned long long) ct->counters[dir].packets,
212 (
unsigned long long) ct->counters[dir].bytes));
216 __snprintf_mark(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
218 return (snprintf(buf, len,
"mark=%u ", ct->mark));
222 __snprintf_secmark(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
224 return (snprintf(buf, len,
"secmark=%u ", ct->secmark));
228 __snprintf_use(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
230 return (snprintf(buf, len,
"use=%u ", ct->use));
234 __snprintf_id(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
236 return (snprintf(buf, len,
"id=%u ", ct->id));
240 __snprintf_zone(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
242 return (snprintf(buf, len,
"zone=%u ", ct->zone));
246 __snprintf_secctx(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
248 return (snprintf(buf, len,
"secctx=%s ", ct->secctx));
252 __snprintf_timestamp_start(
char *buf,
unsigned int len,
253 const struct nf_conntrack *ct)
255 time_t start = (time_t)(ct->timestamp.start / NSEC_PER_SEC);
256 char *tmp = ctime(&start);
259 tmp[strlen(tmp)-1] =
'\0';
260 return (snprintf(buf, len,
"[start=%s] ", tmp));
264 __snprintf_timestamp_stop(
char *buf,
unsigned int len,
265 const struct nf_conntrack *ct)
267 time_t stop = (time_t)(ct->timestamp.stop / NSEC_PER_SEC);
268 char *tmp = ctime(&stop);
271 tmp[strlen(tmp)-1] =
'\0';
272 return (snprintf(buf, len,
"[stop=%s] ", tmp));
276 __snprintf_timestamp_delta(
char *buf,
unsigned int len,
277 const struct nf_conntrack *ct)
279 time_t delta_time, stop;
281 if (ct->timestamp.stop == 0)
284 stop = (time_t)(ct->timestamp.stop / NSEC_PER_SEC);
286 delta_time = stop - (time_t)(ct->timestamp.start / NSEC_PER_SEC);
288 return (snprintf(buf, len,
"delta-time=%llu ",
289 (
unsigned long long)delta_time));
293 __snprintf_helper_name(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
295 return (snprintf(buf, len,
"helper=%s ", ct->helper_name));
299 __snprintf_connlabels(
char *buf,
unsigned int len,
301 const struct nfct_bitmask *b,
const char *fmt)
304 int ret, size = 0, offset = 0;
306 max = nfct_bitmask_maxbit(b);
307 for (i = 0; i <= max && len; i++) {
309 if (!nfct_bitmask_test_bit(b, i))
312 if (!name || strcmp(name,
"") == 0)
315 ret = snprintf(buf + offset, len, fmt, name);
316 BUFFER_SIZE(ret, size, len, offset);
322 __snprintf_clabels(
char *buf,
unsigned int len,
325 const struct nfct_bitmask *b =
nfct_get_attr(ct, ATTR_CONNLABELS);
326 int ret, size = 0, offset = 0;
331 ret = snprintf(buf, len,
"labels=");
332 BUFFER_SIZE(ret, size, len, offset);
334 ret = __snprintf_connlabels(buf + offset, len, map, b,
"%s,");
336 BUFFER_SIZE(ret, size, len, offset);
340 ret = snprintf(buf + offset, len,
" ");
341 BUFFER_SIZE(ret, size, len, offset);
346 int __snprintf_conntrack_default(
char *buf,
348 const struct nf_conntrack *ct,
349 unsigned int msg_type,
353 int ret = 0, size = 0, offset = 0;
357 ret = snprintf(buf, len,
"%9s ",
"[NEW]");
360 ret = snprintf(buf, len,
"%9s ",
"[UPDATE]");
363 ret = snprintf(buf, len,
"%9s ",
"[DESTROY]");
369 BUFFER_SIZE(ret, size, len, offset);
371 if (flags & NFCT_OF_SHOW_LAYER3) {
372 ret = __snprintf_l3protocol(buf+offset, len, ct);
373 BUFFER_SIZE(ret, size, len, offset);
376 ret = __snprintf_protocol(buf+offset, len, ct);
377 BUFFER_SIZE(ret, size, len, offset);
379 if (test_bit(ATTR_TIMEOUT, ct->head.set)) {
380 ret = __snprintf_timeout(buf+offset, len, ct);
381 BUFFER_SIZE(ret, size, len, offset);
384 if (test_bit(ATTR_TCP_STATE, ct->head.set)) {
385 ret = __snprintf_protoinfo(buf+offset, len, ct);
386 BUFFER_SIZE(ret, size, len, offset);
389 if (test_bit(ATTR_SCTP_STATE, ct->head.set)) {
390 ret = __snprintf_protoinfo_sctp(buf+offset, len, ct);
391 BUFFER_SIZE(ret, size, len, offset);
394 if (test_bit(ATTR_DCCP_STATE, ct->head.set)) {
395 ret = __snprintf_protoinfo_dccp(buf+offset, len, ct);
396 BUFFER_SIZE(ret, size, len, offset);
399 ret = __snprintf_address(buf+offset, len, &ct->head.orig,
401 BUFFER_SIZE(ret, size, len, offset);
403 ret = __snprintf_proto(buf+offset, len, &ct->head.orig);
404 BUFFER_SIZE(ret, size, len, offset);
406 if (test_bit(ATTR_ORIG_ZONE, ct->head.set)) {
407 ret = __snprintf_tuple_zone(buf+offset, len,
"orig", &ct->head.orig);
408 BUFFER_SIZE(ret, size, len, offset);
411 if (test_bit(ATTR_ORIG_COUNTER_PACKETS, ct->head.set) &&
412 test_bit(ATTR_ORIG_COUNTER_BYTES, ct->head.set)) {
413 ret = __snprintf_counters(buf+offset, len, ct, __DIR_ORIG);
414 BUFFER_SIZE(ret, size, len, offset);
417 if (test_bit(ATTR_STATUS, ct->head.set)) {
418 ret = __snprintf_status_not_seen_reply(buf+offset, len, ct);
419 BUFFER_SIZE(ret, size, len, offset);
422 ret = __snprintf_address(buf+offset, len, &ct->repl,
424 BUFFER_SIZE(ret, size, len, offset);
426 ret = __snprintf_proto(buf+offset, len, &ct->repl);
427 BUFFER_SIZE(ret, size, len, offset);
429 if (test_bit(ATTR_REPL_ZONE, ct->head.set)) {
430 ret = __snprintf_tuple_zone(buf+offset, len,
"reply", &ct->repl);
431 BUFFER_SIZE(ret, size, len, offset);
434 if (test_bit(ATTR_REPL_COUNTER_PACKETS, ct->head.set) &&
435 test_bit(ATTR_REPL_COUNTER_BYTES, ct->head.set)) {
436 ret = __snprintf_counters(buf+offset, len, ct, __DIR_REPL);
437 BUFFER_SIZE(ret, size, len, offset);
440 if (test_bit(ATTR_STATUS, ct->head.set)) {
441 ret = __snprintf_status_assured(buf+offset, len, ct);
442 BUFFER_SIZE(ret, size, len, offset);
445 if (test_bit(ATTR_MARK, ct->head.set)) {
446 ret = __snprintf_mark(buf+offset, len, ct);
447 BUFFER_SIZE(ret, size, len, offset);
450 if (test_bit(ATTR_SECMARK, ct->head.set)) {
451 ret = __snprintf_secmark(buf+offset, len, ct);
452 BUFFER_SIZE(ret, size, len, offset);
455 if (test_bit(ATTR_SECCTX, ct->head.set)) {
456 ret = __snprintf_secctx(buf+offset, len, ct);
457 BUFFER_SIZE(ret, size, len, offset);
460 if (test_bit(ATTR_ZONE, ct->head.set)) {
461 ret = __snprintf_zone(buf+offset, len, ct);
462 BUFFER_SIZE(ret, size, len, offset);
465 if (test_bit(ATTR_TIMESTAMP_START, ct->head.set)) {
466 ret = __snprintf_timestamp_delta(buf+offset, len, ct);
467 BUFFER_SIZE(ret, size, len, offset);
469 if (flags & NFCT_OF_TIMESTAMP) {
470 if (test_bit(ATTR_TIMESTAMP_START, ct->head.set)) {
471 ret = __snprintf_timestamp_start(buf+offset, len, ct);
472 BUFFER_SIZE(ret, size, len, offset);
474 if (test_bit(ATTR_TIMESTAMP_STOP, ct->head.set)) {
475 ret = __snprintf_timestamp_stop(buf+offset, len, ct);
476 BUFFER_SIZE(ret, size, len, offset);
480 if (test_bit(ATTR_HELPER_NAME, ct->head.set)) {
481 ret = __snprintf_helper_name(buf+offset, len, ct);
482 BUFFER_SIZE(ret, size, len, offset);
485 if (test_bit(ATTR_USE, ct->head.set)) {
486 ret = __snprintf_use(buf+offset, len, ct);
487 BUFFER_SIZE(ret, size, len, offset);
490 if (flags & NFCT_OF_ID && test_bit(ATTR_ID, ct->head.set)) {
491 ret = __snprintf_id(buf+offset, len, ct);
492 BUFFER_SIZE(ret, size, len, offset);
495 if (map && test_bit(ATTR_CONNLABELS, ct->head.set)) {
496 ret = __snprintf_clabels(buf+offset, len, ct, map);
497 BUFFER_SIZE(ret, size, len, offset);
const char * nfct_labelmap_get_name(struct nfct_labelmap *m, unsigned int bit)
const void * nfct_get_attr(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)