File: 0016-Fix-ipv4-options-parsing-and-bit-numbering.patch

package info (click to toggle)
iptables-netflow 2.6-7.2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,632 kB
  • sloc: ansic: 6,831; sh: 896; ruby: 619; makefile: 239
file content (132 lines) | stat: -rw-r--r-- 4,728 bytes parent folder | download | duplicates (2)
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