Skip to content

Commit

Permalink
Fix ipv4 options parsing and bit numbering
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
aabc committed Jan 18, 2023
1 parent 0a7967d commit b049e91
Showing 1 changed file with 17 additions and 47 deletions.
64 changes: 17 additions & 47 deletions ipt_NETFLOW.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down

0 comments on commit b049e91

Please sign in to comment.