title: Using bitfields for parsing network packets
body: <p>I have the thankless job of writing an IPv6 header parser.</p>
  
  <p>I'm wondering if the version, traffic class and flow control labels could be parsed out using bitfields.</p>
  
  <p>I wrote some test code.  Executing on an x86 system I get unexpected results.</p>
  
  <pre><code>#include &lt;stdint.h&gt;
  #include &lt;stdio.h&gt;
  
  typedef struct __attribute__ ((__packed__)) {
          uint32_t                flow_label:20;
          uint32_t                traffic_class:8;
          uint32_t                ip_version:4;
  } test_t;
  
  int main(int argc, char **argv)
  {
          uint8_t data[] = { 0x60, 0x00, 0x00, 0x00 };
          test_t  *ipv6 = (void *)data;
  
          printf("Size is %zu, version %u, traffic class %u, flow label %u\n", sizeof(test_t), ipv6-&gt;ip_version, ipv6-&gt;traffic_class, ipv6-&gt;flow_label);
  }
  </code></pre>
  
  <p>I'd expect the first nibble to be available in ip_version, but it doesn't seem to be, instead I get:</p>
  
  <pre><code>Size is 4, version 0, traffic class 0, flow label 96
  </code></pre>
  
  <p>or with the field order inverted</p>
  
  <pre><code>Size is 4, version 0, traffic class 6, flow label 0
  </code></pre>
  
  <p>Can anyone explain why this happens?</p>