From 122300a6fff9892b697f8900a7f84e94bac151ee Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Tue, 19 Dec 2023 23:46:16 +0100 Subject: libxtables: xtoptions: Support XTOPT_NBO with XTTYPE_UINT* Value conversion into Big Endian byteorder is pretty straightforward, merely needed a small helper for uint64. --- libxtables/xtoptions.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) (limited to 'libxtables/xtoptions.c') diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c index 96946391..5a432ea1 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; + uint8_t 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]); + } } /** -- cgit v1.2.3