]> git.ipfire.org Git - thirdparty/libnl.git/commitdiff
Present port and icmp values in host byte order and beautify printing
authorThomas Graf <tgr@lsx.localdomain>
Thu, 22 May 2008 21:55:52 +0000 (23:55 +0200)
committerThomas Graf <tgr@lsx.localdomain>
Thu, 22 May 2008 21:55:52 +0000 (23:55 +0200)
This changes make nfnl_ct_get_src_port() and others return the value
in host byte order rather than in network byte order.

Also splits printing into details and statistical section and
improves readability.

include/netlink/netfilter/ct.h
lib/netfilter/ct.c
lib/netfilter/ct_obj.c

index e1f938694c731fbfba033faa387a0471b4051450..c4402b3b5e2562d5c4181085565bbb3ee63922b4 100644 (file)
@@ -66,6 +66,8 @@ extern int    nfnl_ct_str2tcp_state(const char *name);
 extern void    nfnl_ct_set_status(struct nfnl_ct *, uint32_t);
 extern void    nfnl_ct_unset_status(struct nfnl_ct *, uint32_t);
 extern uint32_t        nfnl_ct_get_status(const struct nfnl_ct *);
+extern char *  nfnl_ct_status2str(int, char *, size_t);
+extern int     nfnl_ct_str2status(const char *);
 
 extern void    nfnl_ct_set_timeout(struct nfnl_ct *, uint32_t);
 extern int     nfnl_ct_test_timeout(const struct nfnl_ct *);
index 2f111d661404cbd5de2c3545e865b7445219de54..d4d5a0ca50f9e9c465b0b4827bc6050f73b2cad9 100644 (file)
@@ -170,13 +170,13 @@ static int ct_parse_proto(struct nfnl_ct *ct, int repl, struct nlattr *attr)
                nfnl_ct_set_proto(ct, nla_get_u8(tb[CTA_PROTO_NUM]));
        if (tb[CTA_PROTO_SRC_PORT])
                nfnl_ct_set_src_port(ct, repl,
-                               nla_get_u16(tb[CTA_PROTO_SRC_PORT]));
+                       ntohs(nla_get_u16(tb[CTA_PROTO_SRC_PORT])));
        if (tb[CTA_PROTO_DST_PORT])
                nfnl_ct_set_dst_port(ct, repl,
-                               nla_get_u16(tb[CTA_PROTO_DST_PORT]));
+                       ntohs(nla_get_u16(tb[CTA_PROTO_DST_PORT])));
        if (tb[CTA_PROTO_ICMP_ID])
                nfnl_ct_set_icmp_id(ct, repl,
-                               nla_get_u16(tb[CTA_PROTO_ICMP_ID]));
+                       ntohs(nla_get_u16(tb[CTA_PROTO_ICMP_ID])));
        if (tb[CTA_PROTO_ICMP_TYPE])
                nfnl_ct_set_icmp_type(ct, repl,
                                nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]));
@@ -420,15 +420,15 @@ static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct,
 
        if (nfnl_ct_test_src_port(ct, repl))
                NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT,
-                           nfnl_ct_get_src_port(ct, repl));
+                       htons(nfnl_ct_get_src_port(ct, repl)));
 
        if (nfnl_ct_test_dst_port(ct, repl))
                NLA_PUT_U16(msg, CTA_PROTO_DST_PORT,
-                           nfnl_ct_get_dst_port(ct, repl));
+                       htons(nfnl_ct_get_dst_port(ct, repl)));
 
        if (nfnl_ct_test_icmp_id(ct, repl))
                NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID,
-                           nfnl_ct_get_icmp_id(ct, repl));
+                       htons(nfnl_ct_get_icmp_id(ct, repl)));
 
        if (nfnl_ct_test_icmp_type(ct, repl))
                NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE,
index 1625efcb8bbefbd641ee5311a910119ebb46fe04..794413852c3c7686e6150b8d009a4485200287a7 100644 (file)
@@ -103,38 +103,71 @@ static int ct_clone(struct nl_object *_dst, struct nl_object *_src)
        return 0;
 }
 
-static void ct_dump_dir(struct nfnl_ct *ct, int repl,
-                       struct nl_dump_params *p)
+static void dump_addr(struct nl_dump_params *p, struct nl_addr *addr, int port)
 {
-       struct nl_addr *addr;
-       char addrbuf[64];
+       char buf[64];
 
-       addr = nfnl_ct_get_src(ct, repl);
        if (addr)
-               dp_dump(p, "src=%s ",
-                       nl_addr2str(addr, addrbuf, sizeof(addrbuf)));
+               nl_dump(p, "%s", nl_addr2str(addr, buf, sizeof(buf)));
 
-       addr = nfnl_ct_get_dst(ct, repl);
-       if (addr)
-               dp_dump(p, "dst=%s ",
-                       nl_addr2str(addr, addrbuf, sizeof(addrbuf)));
+       if (port)
+               nl_dump(p, ":%u ", port);
+       else if (addr)
+               nl_dump(p, " ");
+}
+
+static void dump_icmp(struct nl_dump_params *p, struct nfnl_ct *ct, int reply)
+{
+       if (nfnl_ct_test_icmp_type(ct, reply))
+               nl_dump(p, "icmp type %d ", nfnl_ct_get_icmp_type(ct, reply));
+
+       if (nfnl_ct_test_icmp_type(ct, reply))
+               nl_dump(p, "code %d ", nfnl_ct_get_icmp_code(ct, reply));
+
+       if (nfnl_ct_test_icmp_type(ct, reply))
+               nl_dump(p, "id %d ", nfnl_ct_get_icmp_id(ct, reply));
+}
+
+static void ct_dump_tuples(struct nfnl_ct *ct, struct nl_dump_params *p)
+{
+       struct nl_addr *orig_src, *orig_dst, *reply_src, *reply_dst;
+       int orig_sport = 0, orig_dport = 0, reply_sport = 0, reply_dport = 0;
+       int sync = 0;
+
+       orig_src = nfnl_ct_get_src(ct, 0);
+       orig_dst = nfnl_ct_get_dst(ct, 0);
+       reply_src = nfnl_ct_get_src(ct, 1);
+       reply_dst = nfnl_ct_get_dst(ct, 1);
 
-       if (nfnl_ct_test_src_port(ct, repl))
-               dp_dump(p, "sport=%u ", ntohs(nfnl_ct_get_src_port(ct, repl)));
-       if (nfnl_ct_test_dst_port(ct, repl))
-               dp_dump(p, "dport=%u ", ntohs(nfnl_ct_get_dst_port(ct, repl)));
+       if (nfnl_ct_test_src_port(ct, 0))
+               orig_sport = nfnl_ct_get_src_port(ct, 0);
 
-       if (nfnl_ct_test_icmp_type(ct, repl))
-               dp_dump(p, "type=%d ", nfnl_ct_get_icmp_type(ct, repl));
-       if (nfnl_ct_test_icmp_type(ct, repl))
-               dp_dump(p, "code=%d ", nfnl_ct_get_icmp_code(ct, repl));
-       if (nfnl_ct_test_icmp_type(ct, repl))
-               dp_dump(p, "id=%d ", ntohs(nfnl_ct_get_icmp_id(ct, repl)));
+       if (nfnl_ct_test_dst_port(ct, 0))
+               orig_dport = nfnl_ct_get_dst_port(ct, 0);
 
-       if (nfnl_ct_test_packets(ct, repl))
-               dp_dump(p, "packets=%llu ", nfnl_ct_get_packets(ct, repl));
-       if (nfnl_ct_test_bytes(ct, repl))
-               dp_dump(p, "bytes=%llu ", nfnl_ct_get_bytes(ct, repl));
+       if (nfnl_ct_test_src_port(ct, 1))
+               reply_sport = nfnl_ct_get_src_port(ct, 1);
+
+       if (nfnl_ct_test_dst_port(ct, 1))
+               reply_dport = nfnl_ct_get_dst_port(ct, 1);
+
+       if (orig_src && orig_dst && reply_src && reply_dst &&
+           orig_sport == reply_dport && orig_dport == reply_sport &&
+           !nl_addr_cmp(orig_src, reply_dst) &&
+           !nl_addr_cmp(orig_dst, reply_src))
+               sync = 1;
+
+       dump_addr(p, orig_src, orig_sport);
+       nl_dump(p, sync ? "<-> " : "-> ");
+       dump_addr(p, orig_dst, orig_dport);
+       dump_icmp(p, ct, 0);
+
+       if (!sync) {
+               dump_addr(p, reply_src, reply_sport);
+               nl_dump(p, "<- ");
+               dump_addr(p, reply_dst, reply_dport);
+               dump_icmp(p, ct, 1);
+       }
 }
 
 /* Compatible with /proc/net/nf_conntrack */
@@ -142,47 +175,102 @@ static int ct_dump(struct nl_object *a, struct nl_dump_params *p)
 {
        struct nfnl_ct *ct = (struct nfnl_ct *) a;
        char buf[64];
-       uint32_t status;
-       uint8_t family;
-       uint8_t proto;
-
-       family = nfnl_ct_get_family(ct);
-       dp_dump(p, "%-8s %u ", nl_af2str(family, buf, sizeof(buf)), family);
 
-       if (nfnl_ct_test_proto(ct)) {
-               proto = nfnl_ct_get_proto(ct);
-               dp_dump(p, "%-8s %u ",
-                       nl_ip_proto2str(proto, buf, sizeof(buf)), proto);
-       }
-
-       if (nfnl_ct_test_timeout(ct))
-               dp_dump(p, "%ld ", nfnl_ct_get_timeout(ct));
+       if (nfnl_ct_test_proto(ct))
+               nl_dump(p, "%s ",
+                 nl_ip_proto2str(nfnl_ct_get_proto(ct), buf, sizeof(buf)));
 
        if (nfnl_ct_test_tcp_state(ct))
-               dp_dump(p, "%s ",
+               nl_dump(p, "%s ",
                        nfnl_ct_tcp_state2str(nfnl_ct_get_tcp_state(ct),
                                              buf, sizeof(buf)));
 
-       ct_dump_dir(ct, 0, p);
+       ct_dump_tuples(ct, p);
 
-       status = nfnl_ct_get_status(ct);
-       if (!(status & IPS_SEEN_REPLY))
-               dp_dump(p, "[UNREPLIED] ");
+       if (nfnl_ct_test_mark(ct) && nfnl_ct_get_mark(ct))
+               nl_dump(p, "mark %u ", nfnl_ct_get_mark(ct));
 
-       ct_dump_dir(ct, 1, p);
+       nl_dump(p, "\n");
 
-       if (status & IPS_ASSURED)
-               dp_dump(p, "[ASSURED] ");
+       return 1;
+}
 
-       if (nfnl_ct_test_mark(ct))
-               dp_dump(p, "mark=%u ", nfnl_ct_get_mark(ct));
+static int ct_dump_details(struct nl_object *a, struct nl_dump_params *p)
+{
+       struct nfnl_ct *ct = (struct nfnl_ct *) a;
+       char buf[64];
+       int fp = 0;
+
+       ct_dump(a, p);
+
+       nl_dump(p, "    id 0x%x ", ct->ct_id);
+       nl_dump_line(p, "family %s ",
+               nl_af2str(ct->ct_family, buf, sizeof(buf)));
 
        if (nfnl_ct_test_use(ct))
-               dp_dump(p, "use=%u ", nfnl_ct_get_use(ct));
+               nl_dump(p, "refcnt %u ", nfnl_ct_get_use(ct));
 
-       dp_dump(p, "\n");
+       if (nfnl_ct_test_timeout(ct)) {
+               uint64_t timeout_ms = nfnl_ct_get_timeout(ct) * 1000UL;
+               nl_dump(p, "timeout %s ",
+                       nl_msec2str(timeout_ms, buf, sizeof(buf)));
+       }
 
-       return 1;
+       if (ct->ct_status)
+               nl_dump(p, "<");
+
+#define PRINT_FLAG(str) \
+       { nl_dump(p, "%s%s", fp++ ? "," : "", (str)); }
+
+       if (ct->ct_status & IPS_EXPECTED)
+               PRINT_FLAG("EXPECTED");
+       if (!(ct->ct_status & IPS_SEEN_REPLY))
+               PRINT_FLAG("NOREPLY");
+       if (ct->ct_status & IPS_ASSURED)
+               PRINT_FLAG("ASSURED");
+       if (!(ct->ct_status & IPS_CONFIRMED))
+               PRINT_FLAG("NOTSENT");
+       if (ct->ct_status & IPS_SRC_NAT)
+               PRINT_FLAG("SNAT");
+       if (ct->ct_status & IPS_DST_NAT)
+               PRINT_FLAG("DNAT");
+       if (ct->ct_status & IPS_SEQ_ADJUST)
+               PRINT_FLAG("SEQADJUST");
+       if (!(ct->ct_status & IPS_SRC_NAT_DONE))
+               PRINT_FLAG("SNAT_INIT");
+       if (!(ct->ct_status & IPS_DST_NAT_DONE))
+               PRINT_FLAG("DNAT_INIT");
+       if (ct->ct_status & IPS_DYING)
+               PRINT_FLAG("DYING");
+       if (ct->ct_status & IPS_FIXED_TIMEOUT)
+               PRINT_FLAG("FIXED_TIMEOUT");
+#undef PRINT_FLAG
+
+       if (ct->ct_status)
+               nl_dump(p, ">");
+       nl_dump(p, "\n");
+
+       return 0;
+}
+
+static int ct_dump_stats(struct nl_object *a, struct nl_dump_params *p)
+{
+       struct nfnl_ct *ct = (struct nfnl_ct *) a;
+       int line = ct_dump_details(a, p);
+       double res;
+       char *unit;
+
+       dp_dump_line(p, line++, "        # packets      volume\n");
+
+       res = nl_cancel_down_bytes(nfnl_ct_get_bytes(ct, 1), &unit);
+       dp_dump_line(p, line++, "    rx %10llu %7.2f %s\n",
+               nfnl_ct_get_packets(ct, 1), res, unit);
+
+       res = nl_cancel_down_bytes(nfnl_ct_get_bytes(ct, 0), &unit);
+       dp_dump_line(p, line++, "    tx %10llu %7.2f %s\n",
+               nfnl_ct_get_packets(ct, 0), res, unit);
+
+       return line;
 }
 
 static int ct_compare(struct nl_object *_a, struct nl_object *_b,
@@ -387,6 +475,31 @@ uint32_t nfnl_ct_get_status(const struct nfnl_ct *ct)
        return ct->ct_status;
 }
 
+static struct trans_tbl status_flags[] = {
+       __ADD(IPS_EXPECTED, expected)
+       __ADD(IPS_SEEN_REPLY, seen_reply)
+       __ADD(IPS_ASSURED, assured)
+       __ADD(IPS_CONFIRMED, confirmed)
+       __ADD(IPS_SRC_NAT, snat)
+       __ADD(IPS_DST_NAT, dnat)
+       __ADD(IPS_SEQ_ADJUST, seqadjust)
+       __ADD(IPS_SRC_NAT_DONE, snat_done)
+       __ADD(IPS_DST_NAT_DONE, dnat_done)
+       __ADD(IPS_DYING, dying)
+       __ADD(IPS_FIXED_TIMEOUT, fixed_timeout)
+};
+
+char * nfnl_ct_status2str(int flags, char *buf, size_t len)
+{
+       return __flags2str(flags, buf, len, status_flags,
+                          ARRAY_SIZE(status_flags));
+}
+
+int nfnl_ct_str2status(const char *name)
+{
+       return __str2flags(name, status_flags, ARRAY_SIZE(status_flags));
+}
+
 void nfnl_ct_set_timeout(struct nfnl_ct *ct, uint32_t timeout)
 {
        ct->ct_timeout = timeout;
@@ -664,8 +777,8 @@ struct nl_object_ops ct_obj_ops = {
        .oo_free_data           = ct_free_data,
        .oo_clone               = ct_clone,
        .oo_dump[NL_DUMP_BRIEF] = ct_dump,
-       .oo_dump[NL_DUMP_FULL]  = ct_dump,
-       .oo_dump[NL_DUMP_STATS] = ct_dump,
+       .oo_dump[NL_DUMP_FULL]  = ct_dump_details,
+       .oo_dump[NL_DUMP_STATS] = ct_dump_stats,
        .oo_compare             = ct_compare,
        .oo_attrs2str           = ct_attrs2str,
 };