1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
From b049e91df68d58846203f72233acc0a476317791 Mon Sep 17 00:00:00 2001
From: ABC <abc@openwall.com>
Date: Wed, 18 Jan 2023 09:40:48 +0300
Subject: [PATCH 16/17] Fix ipv4 options parsing and bit numbering
RFC 5102 and its Errata[1] several times messed with a bit numbering.
"Options are mapped to bits according to their option numbers.
Option number X is mapped to bit X."
But actually it's in inverted order.
"A misunderstand arose as to whether bits were assigned in host order
or network order - so clarify that the bits are assigned from the
least significant to the most significant, ie right-to-left rather
than left-to-right."
That's about bit numbering in diagram. So final correct options mask is (from
Errata 2944):
0 1 2 3 4 5 6 7
+------+------+------+------+------+------+------+------+
| | EXP | to be assigned by IANA | QS | UMP | ...
+------+------+------+------+------+------+------+------+
8 9 10 11 12 13 14 15
+------+------+------+------+------+------+------+------+
... | DPS |NSAPA | SDB |RTRALT|ADDEXT| TR | EIP |IMITD | ...
+------+------+------+------+------+------+------+------+
16 17 18 19 20 21 22 23
+------+------+------+------+------+------+------+------+
... |ENCODE| VISA | FINN | MTUR | MTUP | ZSU | SSR | SID | ...
+------+------+------+------+------+------+------+------+
24 25 26 27 28 29 30 31
+------+------+------+------+------+------+------+------+
... | RR |CIPSO |E-SEC | TS | LSR | SEC | NOP | EOOL |
+------+------+------+------+------+------+------+------+
Link: https://www.rfc-editor.org/errata/rfc5102
Fixes: f631ed5 ("IPv6 support, and IP options support for v9/IPFIX.")
Signed-off-by: ABC <abc@openwall.com>
---
ipt_NETFLOW.c | 64 ++++++++++++++-------------------------------------
1 file changed, 17 insertions(+), 47 deletions(-)
diff --git a/ipt_NETFLOW.c b/ipt_NETFLOW.c
index ab4afda..b3c2c99 100644
--- a/ipt_NETFLOW.c
+++ b/ipt_NETFLOW.c
@@ -4769,39 +4769,7 @@ static inline __u16 observed_hdrs(const __u8 currenthdr)
return SetXBit(3); /* Unknown header. */
}
-/* http://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml */
-static const __u8 ip4_opt_table[] = {
- [7] = 0, /* RR */ /* parsed manually because of 0 */
- [134] = 1, /* CIPSO */
- [133] = 2, /* E-SEC */
- [68] = 3, /* TS */
- [131] = 4, /* LSR */
- [130] = 5, /* SEC */
- [1] = 6, /* NOP */
- [0] = 7, /* EOOL */
- [15] = 8, /* ENCODE */
- [142] = 9, /* VISA */
- [205] = 10, /* FINN */
- [12] = 11, /* MTUR */
- [11] = 12, /* MTUP */
- [10] = 13, /* ZSU */
- [137] = 14, /* SSR */
- [136] = 15, /* SID */
- [151] = 16, /* DPS */
- [150] = 17, /* NSAPA */
- [149] = 18, /* SDB */
- [147] = 19, /* ADDEXT */
- [148] = 20, /* RTRALT */
- [82] = 21, /* TR */
- [145] = 22, /* EIP */
- [144] = 23, /* IMITD */
- [30] = 25, /* EXP */
- [94] = 25, /* EXP */
- [158] = 25, /* EXP */
- [222] = 25, /* EXP */
- [25] = 30, /* QS */
- [152] = 31, /* UMP */
-};
+/* https://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml */
/* Parse IPv4 Options array int ipv4Options IPFIX value. */
static inline __u32 ip4_options(const u_int8_t *p, const unsigned int optsize)
{
@@ -4810,20 +4778,22 @@ static inline __u32 ip4_options(const u_int8_t *p, const unsigned int optsize)
for (i = 0; likely(i < optsize); ) {
u_int8_t op = p[i++];
-
- if (op == 7) /* RR: bit 0 */
- ret |= 1;
- else if (likely(op < ARRAY_SIZE(ip4_opt_table))) {
- /* Btw, IANA doc is messed up in a crazy way:
- * http://www.ietf.org/mail-archive/web/ipfix/current/msg06008.html (2011)
- * I decided to follow IANA _text_ description from
- * http://www.iana.org/assignments/ipfix/ipfix.xhtml (2013-09-18)
- *
- * Set proper bit for htonl later. */
- if (ip4_opt_table[op])
- ret |= 1 << (31 - ip4_opt_table[op]);
- }
- if (likely(i >= optsize || op == 0))
+ u_int8_t nn = op & 0x17; /* 5 bits option number */
+
+ /*
+ * "Note that for identifying an option not just the 5-bit Option
+ * Number, but all 8 bits of the Option Type need to match one
+ * of the IPv4 options specified at
+ * http://www.iana.org/assignments/ip-parameters.
+ *
+ * Options are mapped to bits according to their option numbers.
+ * Option number X is mapped to bit X." - In inverted order, see
+ * RFC 5102 Errata 2944.
+ */
+
+ if (likely(nn < 32))
+ ret |= 1 << (31 - nn);
+ if (i >= optsize || op == 0) /* 0 is EOOL. */
break;
else if (unlikely(op == 1))
continue;
--
2.39.5
|