2

I'm trying to parse IPv6 packet received through raw socket and decide if it is ICMPv6 or not. I can process the Ethernet and IPv6 header, but then there are optional extension headers. If the Next Header field of IPv6 header is not ICMPv6, I have to iterate through any extensions that might precede.

The iteration itself is not a problem as each extension header carry its length. However, I can't find a good way to differentiate between extension header that might follow and other upper-level protocols such as TCP and UDP. I can either check if the Next Header is one of known extension headers (in which case I can iterate) or if the Next Header is upper-layer protocol (in which case I have to stop, there won't be any ICMP..).

In both approaches I'm relying on some self-built list of constants against which I'm checking Next Header and that list might change in future. Isn't there a better way to tell when I'm at the end of extension headers and upper-layer header (or nothing) follows?

Raven
  • 4,783
  • 8
  • 44
  • 75
  • 1
    Unfortunately there is no way to determine what an unknown next header value means. You'll have to rely on tables in your code. – Sander Steffann Feb 17 '17 at 16:59

2 Answers2

3

Each extension header has its own Next Header field as its first octet, with the same meaning as (but different relative location from) the corresponding field of the fixed IPv6 header. You can use these together with the extension headers' length fields to step through the extension headers until you find the transport layer header. Wikipedia covers this in some detail.


Update:

With respect to your revised question, no, there is no standard function or algorithm for distinguishing between header codes designating extension headers and those designating protocol headers, except simply to know which are which. They are assigned from the same code space, with no special internal structure.

There are only 256 possible values, however, so knowing which are which is feasible. Do be careful, however: nearly half of the available codes are currently unassigned, but may be assigned to either extension header types or protocol types in the future. Until and unless the codes are exhausted, your software will need to recognize three categories:

  • extension header,
  • protocol header, and
  • unknown.

Additionally, as for implementing such a test, I would recommend creating and using a lookup table instead of building a complicated conditional expression. Something along these lines:

enum header_type { HDR_PROTOCOL, HDR_EXTENSION, HDR_UNKNOWN };

const enum header_type header_types[256] = {
    [0x00] = HDR_EXTENSION,  // IPv6 hop-by-hop option
    [0x01] = HDR_PROTOCOL,   // ICMP
    // ... both extension and protocol headers in this range ...
    [0x8e] = HDR_PROTOCOL,   // robust header compression
    [0x8f] = HDR_UNKNOWN,    // unassigned
    // ... more unassigned ...
    [0xfd] = HDR_UNKNOWN,    // for experimentation
    [0xfe] = HDR_UNKNOWN,    // for experimentation
    [0xff] = HDR_UNKNOWN,    // reserved
};

You can use that to answer several kinds of questions, and very efficiently, too. The explicit designators in the initializer are not strictly necessary, but I think they're a good idea: they will help you verify and maintain the table.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • 1
    Also, IANA maintains the list of possible IPv4 Protocol / IPv6 Next Header values (there are only 256 possible values) at [Assigned Internet Protocol Numbers](https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml). – Ron Maupin Feb 16 '17 at 23:15
  • I see now that I didn't say that I'm already looking also on extension header's `Next Header` field. The problem is still that I was looking for some standard way to find out if the next header will also be extension or not. As @RonMaupin pointed out, there are not that much values, so I ended up writing function like this http://pastebin.com/SXeshCmA, but I was hoping for a better approach. – Raven Feb 17 '17 at 01:08
  • @Raven, I have updated this answer with information and recommendations pertaining to your revised question. – John Bollinger Feb 17 '17 at 14:31
2

There really isn't anything to do other than walk the chain, and it sounds like that is what you are doing. As you ask in your comment, the "standard way to find out if the next header will also be extension or not" is if it is one of the values that means it is an IPv6 extension header. Originally, with the exception of the Hop-by-hop extension header (which most network administrators ignore because it is a poor practice to let end-devices dictate routing), all the intermediate nodes (routers, etc.) were supposed to ignore extension headers:

With one exception, extension headers are not examined or processed by any node along a packet's delivery path, until the packet reaches the node (or each of the set of nodes, in the case of multicast) identified in the Destination Address field of the IPv6 header. There, normal demultiplexing on the Next Header field of the IPv6 header invokes the module to process the first extension header, or the upper-layer header if no extension header is present. The contents and semantics of each extension header determine whether or not to proceed to the next header. Therefore, extension headers must be processed strictly in the order they appear in the packet; a receiver must not, for example, scan through a packet looking for a particular kind of extension header and process that header prior to processing all preceding ones.

The exception referred to in the preceding paragraph is the Hop-by- Hop Options header, which carries information that must be examined and processed by every node along a packet's delivery path, including the source and destination nodes. The Hop-by-Hop Options header, when present, must immediately follow the IPv6 header. Its presence is indicated by the value zero in the Next Header field of the IPv6 header.

If, as a result of processing a header, a node is required to proceed to the next header but the Next Header value in the current header is unrecognized by the node, it should discard the packet and send an ICMP Parameter Problem message to the source of the packet, with an ICMP Code value of 1 ("unrecognized Next Header type encountered") and the ICMP Pointer field containing the offset of the unrecognized value within the original packet. The same action should be taken if a node encounters a Next Header value of zero in any header other than an IPv6 header.

Unfortunately, reality set in, and that is no longer the case. It is now even possible that intermediate nodes will add extension headers, and the header chain may end up fragmented.

RFC 6564, A Uniform Format for IPv6 Extension Headers tries to bring some order the IPv6 extension headers, but, unfortunately, it can't do anything about previously defined IPv6 extension headers.

RFC 7045, Transmission and Processing of IPv6 Extension Headers discusses problems about IPv6 extension headers.

Community
  • 1
  • 1
Ron Maupin
  • 6,180
  • 4
  • 29
  • 36