[libnftnl RFC] data_reg: Improve data reg value printing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The old code printing each field with data as u32 value is problematic
in two ways:

A) Field values are printed in host byte order which may not be correct
   and output for identical data will divert between machines of
   different Endianness.

B) The actual data length is not clearly readable from given output.

This patch won't entirely fix for (A) given that data may be in host
byte order but it solves for the common case of matching against packet
data.

Fixing for (B) is crucial to see what's happening beneath the bonnet.
The new output will show exactly what is used e.g. by a cmp expression.

Signed-off-by: Phil Sutter <phil@xxxxxx>
---
This change will affect practically all stored payload dumps in nftables
test suite. I have an alternative version which prints "full" reg fields
as before and uses the byte-by-byte printing only for the remainder (if
any). This would largely reduce the churn in stored payload dumps, but
also make this less useful.
---
 src/expr/data_reg.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index fd5e0d6e749e1..d7531a76af68f 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -26,13 +26,22 @@ nftnl_data_reg_value_snprintf_default(char *buf, size_t remain,
 				      uint32_t flags)
 {
 	const char *pfx = flags & DATA_F_NOPFX ? "" : "0x";
-	int offset = 0, ret, i;
-
+	int num32 = reg->len / sizeof(uint32_t);
+	int rem32 = reg->len % sizeof(uint32_t);
+	int offset = 0, ret, i, j;
 
+	for (i = 0; i < num32 + !!rem32; i++) {
+		ret = snprintf(buf + offset, remain, "%s", pfx);
+		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
 
-	for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) {
-		ret = snprintf(buf + offset, remain,
-			       "%s%.8x ", pfx, reg->val[i]);
+		for (j = 0; j < sizeof(uint32_t); j++) {
+			if (i == num32 && j == rem32)
+				break;
+			ret = snprintf(buf + offset, remain, "%.2x",
+				       ((unsigned char *)&reg->val[i])[j]);
+			SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+		}
+		ret = snprintf(buf + offset, remain, " ");
 		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
 	}
 
-- 
2.51.0





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux