diff mbox series

[iptables,02/23] libxtables: xtoptions: Support XTOPT_NBO with XTTYPE_UINT*

Message ID 20231220160636.11778-3-phil@nwl.cc
State Accepted
Headers show
Series Guided option parser for ebtables | expand

Commit Message

Phil Sutter Dec. 20, 2023, 4:06 p.m. UTC
Value conversion into Big Endian byteorder is pretty straightforward,
merely needed a small helper for uint64.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 libxtables/xtoptions.c | 40 +++++++++++++++++++++++++++++++---------
 1 file changed, 31 insertions(+), 9 deletions(-)

Comments

Jan Engelhardt Dec. 20, 2023, 7:07 p.m. UTC | #1
On Wednesday 2023-12-20 17:06, Phil Sutter wrote:
> {
> 	const struct xt_option_entry *entry = cb->entry;
>+	int i = cb->nvals;
>
>-	if (cb->nvals >= ARRAY_SIZE(cb->val.u32_range))
>+	if (i >= ARRAY_SIZE(cb->val.u32_range))
> 		return;

`i` should be unsigned (size_t) because ARRAY_SIZE is,
else you get -Wsigned warnings at some point.
Phil Sutter Dec. 20, 2023, 9:28 p.m. UTC | #2
On Wed, Dec 20, 2023 at 08:07:41PM +0100, Jan Engelhardt wrote:
> 
> On Wednesday 2023-12-20 17:06, Phil Sutter wrote:
> > {
> > 	const struct xt_option_entry *entry = cb->entry;
> >+	int i = cb->nvals;
> >
> >-	if (cb->nvals >= ARRAY_SIZE(cb->val.u32_range))
> >+	if (i >= ARRAY_SIZE(cb->val.u32_range))
> > 		return;
> 
> `i` should be unsigned (size_t) because ARRAY_SIZE is,
> else you get -Wsigned warnings at some point.

Oh, right! I'll make it uint8_t to match typeof(cb->nvals).

Thanks, Phil
diff mbox series

Patch

diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c
index 9694639188006..3973c807ded0e 100644
--- a/libxtables/xtoptions.c
+++ b/libxtables/xtoptions.c
@@ -147,6 +147,14 @@  static size_t xtopt_esize_by_type(enum xt_option_type type)
 	}
 }
 
+static uint64_t htonll(uint64_t val)
+{
+	uint32_t high = val >> 32;
+	uint32_t low = val & UINT32_MAX;
+
+	return (uint64_t)htonl(low) << 32 | htonl(high);
+}
+
 /**
  * Require a simple integer.
  */
@@ -174,14 +182,20 @@  static void xtopt_parse_int(struct xt_option_call *cb)
 			*(uint8_t *)XTOPT_MKPTR(cb) = cb->val.u8;
 	} else if (entry->type == XTTYPE_UINT16) {
 		cb->val.u16 = value;
+		if (entry->flags & XTOPT_NBO)
+			cb->val.u16 = htons(cb->val.u16);
 		if (entry->flags & XTOPT_PUT)
 			*(uint16_t *)XTOPT_MKPTR(cb) = cb->val.u16;
 	} else if (entry->type == XTTYPE_UINT32) {
 		cb->val.u32 = value;
+		if (entry->flags & XTOPT_NBO)
+			cb->val.u32 = htonl(cb->val.u32);
 		if (entry->flags & XTOPT_PUT)
 			*(uint32_t *)XTOPT_MKPTR(cb) = cb->val.u32;
 	} else if (entry->type == XTTYPE_UINT64) {
 		cb->val.u64 = value;
+		if (entry->flags & XTOPT_NBO)
+			cb->val.u64 = htonll(cb->val.u64);
 		if (entry->flags & XTOPT_PUT)
 			*(uint64_t *)XTOPT_MKPTR(cb) = cb->val.u64;
 	}
@@ -216,17 +230,25 @@  static void xtopt_parse_float(struct xt_option_call *cb)
 static void xtopt_mint_value_to_cb(struct xt_option_call *cb, uintmax_t value)
 {
 	const struct xt_option_entry *entry = cb->entry;
+	int i = cb->nvals;
 
-	if (cb->nvals >= ARRAY_SIZE(cb->val.u32_range))
+	if (i >= ARRAY_SIZE(cb->val.u32_range))
 		return;
-	if (entry->type == XTTYPE_UINT8RC)
-		cb->val.u8_range[cb->nvals] = value;
-	else if (entry->type == XTTYPE_UINT16RC)
-		cb->val.u16_range[cb->nvals] = value;
-	else if (entry->type == XTTYPE_UINT32RC)
-		cb->val.u32_range[cb->nvals] = value;
-	else if (entry->type == XTTYPE_UINT64RC)
-		cb->val.u64_range[cb->nvals] = value;
+	if (entry->type == XTTYPE_UINT8RC) {
+		cb->val.u8_range[i] = value;
+	} else if (entry->type == XTTYPE_UINT16RC) {
+		cb->val.u16_range[i] = value;
+		if (entry->flags & XTOPT_NBO)
+			cb->val.u16_range[i] = htons(cb->val.u16_range[i]);
+	} else if (entry->type == XTTYPE_UINT32RC) {
+		cb->val.u32_range[i] = value;
+		if (entry->flags & XTOPT_NBO)
+			cb->val.u32_range[i] = htonl(cb->val.u32_range[i]);
+	} else if (entry->type == XTTYPE_UINT64RC) {
+		cb->val.u64_range[i] = value;
+		if (entry->flags & XTOPT_NBO)
+			cb->val.u64_range[i] = htonll(cb->val.u64_range[i]);
+	}
 }
 
 /**