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_OFFLOAD)
188 size = snprintf(buf, len,
"[OFFLOAD] ");
189 else if (ct->status & IPS_ASSURED)
190 size = snprintf(buf, len,
"[ASSURED] ");
195 static int __snprintf_status_not_seen_reply(
char *buf,
197 const struct nf_conntrack *ct)
201 if (!(ct->status & IPS_SEEN_REPLY))
202 size = snprintf(buf, len,
"[UNREPLIED] ");
207 static int __snprintf_counters(
char *buf,
209 const struct nf_conntrack *ct,
212 return (snprintf(buf, len,
"packets=%llu bytes=%llu ",
213 (
unsigned long long) ct->counters[dir].packets,
214 (
unsigned long long) ct->counters[dir].bytes));
218 __snprintf_mark(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
220 return (snprintf(buf, len,
"mark=%u ", ct->mark));
224 __snprintf_secmark(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
226 return (snprintf(buf, len,
"secmark=%u ", ct->secmark));
230 __snprintf_use(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
232 return (snprintf(buf, len,
"use=%u ", ct->use));
236 __snprintf_id(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
238 return (snprintf(buf, len,
"id=%u ", ct->id));
242 __snprintf_zone(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
244 return (snprintf(buf, len,
"zone=%u ", ct->zone));
248 __snprintf_secctx(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
250 return (snprintf(buf, len,
"secctx=%s ", ct->secctx));
254 __snprintf_timestamp_start(
char *buf,
unsigned int len,
255 const struct nf_conntrack *ct)
257 time_t start = (time_t)(ct->timestamp.start / NSEC_PER_SEC);
258 char *tmp = ctime(&start);
261 tmp[strlen(tmp)-1] =
'\0';
262 return (snprintf(buf, len,
"[start=%s] ", tmp));
266 __snprintf_timestamp_stop(
char *buf,
unsigned int len,
267 const struct nf_conntrack *ct)
269 time_t stop = (time_t)(ct->timestamp.stop / NSEC_PER_SEC);
270 char *tmp = ctime(&stop);
273 tmp[strlen(tmp)-1] =
'\0';
274 return (snprintf(buf, len,
"[stop=%s] ", tmp));
278 __snprintf_timestamp_delta(
char *buf,
unsigned int len,
279 const struct nf_conntrack *ct)
281 time_t delta_time, stop;
283 if (ct->timestamp.stop == 0)
286 stop = (time_t)(ct->timestamp.stop / NSEC_PER_SEC);
288 delta_time = stop - (time_t)(ct->timestamp.start / NSEC_PER_SEC);
290 return (snprintf(buf, len,
"delta-time=%llu ",
291 (
unsigned long long)delta_time));
295 __snprintf_helper_name(
char *buf,
unsigned int len,
const struct nf_conntrack *ct)
297 return (snprintf(buf, len,
"helper=%s ", ct->helper_name));
301 __snprintf_connlabels(
char *buf,
unsigned int len,
303 const struct nfct_bitmask *b,
const char *fmt)
306 int ret, size = 0, offset = 0;
308 max = nfct_bitmask_maxbit(b);
309 for (i = 0; i <= max && len; i++) {
311 if (!nfct_bitmask_test_bit(b, i))
314 if (!name || strcmp(name,
"") == 0)
317 ret = snprintf(buf + offset, len, fmt, name);
318 BUFFER_SIZE(ret, size, len, offset);
324 __snprintf_clabels(
char *buf,
unsigned int len,
327 const struct nfct_bitmask *b =
nfct_get_attr(ct, ATTR_CONNLABELS);
328 int ret, size = 0, offset = 0;
333 ret = snprintf(buf, len,
"labels=");
334 BUFFER_SIZE(ret, size, len, offset);
336 ret = __snprintf_connlabels(buf + offset, len, map, b,
"%s,");
338 BUFFER_SIZE(ret, size, len, offset);
342 ret = snprintf(buf + offset, len,
" ");
343 BUFFER_SIZE(ret, size, len, offset);
348 int __snprintf_conntrack_default(
char *buf,
350 const struct nf_conntrack *ct,
351 unsigned int msg_type,
355 int ret = 0, size = 0, offset = 0;
359 ret = snprintf(buf, len,
"%9s ",
"[NEW]");
362 ret = snprintf(buf, len,
"%9s ",
"[UPDATE]");
365 ret = snprintf(buf, len,
"%9s ",
"[DESTROY]");
371 BUFFER_SIZE(ret, size, len, offset);
373 if (flags & NFCT_OF_SHOW_LAYER3) {
374 ret = __snprintf_l3protocol(buf+offset, len, ct);
375 BUFFER_SIZE(ret, size, len, offset);
378 ret = __snprintf_protocol(buf+offset, len, ct);
379 BUFFER_SIZE(ret, size, len, offset);
381 if (test_bit(ATTR_TIMEOUT, ct->head.set)) {
382 ret = __snprintf_timeout(buf+offset, len, ct);
383 BUFFER_SIZE(ret, size, len, offset);
386 if (test_bit(ATTR_TCP_STATE, ct->head.set)) {
387 ret = __snprintf_protoinfo(buf+offset, len, ct);
388 BUFFER_SIZE(ret, size, len, offset);
391 if (test_bit(ATTR_SCTP_STATE, ct->head.set)) {
392 ret = __snprintf_protoinfo_sctp(buf+offset, len, ct);
393 BUFFER_SIZE(ret, size, len, offset);
396 if (test_bit(ATTR_DCCP_STATE, ct->head.set)) {
397 ret = __snprintf_protoinfo_dccp(buf+offset, len, ct);
398 BUFFER_SIZE(ret, size, len, offset);
401 ret = __snprintf_address(buf+offset, len, &ct->head.orig,
403 BUFFER_SIZE(ret, size, len, offset);
405 ret = __snprintf_proto(buf+offset, len, &ct->head.orig);
406 BUFFER_SIZE(ret, size, len, offset);
408 if (test_bit(ATTR_ORIG_ZONE, ct->head.set)) {
409 ret = __snprintf_tuple_zone(buf+offset, len,
"orig", &ct->head.orig);
410 BUFFER_SIZE(ret, size, len, offset);
413 if (test_bit(ATTR_ORIG_COUNTER_PACKETS, ct->head.set) &&
414 test_bit(ATTR_ORIG_COUNTER_BYTES, ct->head.set)) {
415 ret = __snprintf_counters(buf+offset, len, ct, __DIR_ORIG);
416 BUFFER_SIZE(ret, size, len, offset);
419 if (test_bit(ATTR_STATUS, ct->head.set)) {
420 ret = __snprintf_status_not_seen_reply(buf+offset, len, ct);
421 BUFFER_SIZE(ret, size, len, offset);
424 ret = __snprintf_address(buf+offset, len, &ct->repl,
426 BUFFER_SIZE(ret, size, len, offset);
428 ret = __snprintf_proto(buf+offset, len, &ct->repl);
429 BUFFER_SIZE(ret, size, len, offset);
431 if (test_bit(ATTR_REPL_ZONE, ct->head.set)) {
432 ret = __snprintf_tuple_zone(buf+offset, len,
"reply", &ct->repl);
433 BUFFER_SIZE(ret, size, len, offset);
436 if (test_bit(ATTR_REPL_COUNTER_PACKETS, ct->head.set) &&
437 test_bit(ATTR_REPL_COUNTER_BYTES, ct->head.set)) {
438 ret = __snprintf_counters(buf+offset, len, ct, __DIR_REPL);
439 BUFFER_SIZE(ret, size, len, offset);
442 if (test_bit(ATTR_STATUS, ct->head.set)) {
443 ret = __snprintf_status_assured(buf+offset, len, ct);
444 BUFFER_SIZE(ret, size, len, offset);
447 if (test_bit(ATTR_MARK, ct->head.set)) {
448 ret = __snprintf_mark(buf+offset, len, ct);
449 BUFFER_SIZE(ret, size, len, offset);
452 if (test_bit(ATTR_SECMARK, ct->head.set)) {
453 ret = __snprintf_secmark(buf+offset, len, ct);
454 BUFFER_SIZE(ret, size, len, offset);
457 if (test_bit(ATTR_SECCTX, ct->head.set)) {
458 ret = __snprintf_secctx(buf+offset, len, ct);
459 BUFFER_SIZE(ret, size, len, offset);
462 if (test_bit(ATTR_ZONE, ct->head.set)) {
463 ret = __snprintf_zone(buf+offset, len, ct);
464 BUFFER_SIZE(ret, size, len, offset);
467 if (test_bit(ATTR_TIMESTAMP_START, ct->head.set)) {
468 ret = __snprintf_timestamp_delta(buf+offset, len, ct);
469 BUFFER_SIZE(ret, size, len, offset);
471 if (flags & NFCT_OF_TIMESTAMP) {
472 if (test_bit(ATTR_TIMESTAMP_START, ct->head.set)) {
473 ret = __snprintf_timestamp_start(buf+offset, len, ct);
474 BUFFER_SIZE(ret, size, len, offset);
476 if (test_bit(ATTR_TIMESTAMP_STOP, ct->head.set)) {
477 ret = __snprintf_timestamp_stop(buf+offset, len, ct);
478 BUFFER_SIZE(ret, size, len, offset);
482 if (test_bit(ATTR_HELPER_NAME, ct->head.set)) {
483 ret = __snprintf_helper_name(buf+offset, len, ct);
484 BUFFER_SIZE(ret, size, len, offset);
487 if (test_bit(ATTR_USE, ct->head.set)) {
488 ret = __snprintf_use(buf+offset, len, ct);
489 BUFFER_SIZE(ret, size, len, offset);
492 if (flags & NFCT_OF_ID && test_bit(ATTR_ID, ct->head.set)) {
493 ret = __snprintf_id(buf+offset, len, ct);
494 BUFFER_SIZE(ret, size, len, offset);
497 if (map && test_bit(ATTR_CONNLABELS, ct->head.set)) {
498 ret = __snprintf_clabels(buf+offset, len, ct, map);
499 BUFFER_SIZE(ret, size, len, offset);
const void * nfct_get_attr(const struct nf_conntrack *ct, const enum nf_conntrack_attr type)
const char * nfct_labelmap_get_name(struct nfct_labelmap *m, unsigned int bit)