title: Safely dereferencing pointers to unions of structs in C?
body: <p>I am trying to write a packet decoder for the SCTP protocol in C and running into some issues while dereferencing a pointer to a union of structs (which represent the SCTP chunks).</p>
  <p>Not everyone might be familiar with the SCTP (Stream Control Transmission Protocol), so here are some brief primers:</p>
  <p><a href="http://en.wikipedia.org/wiki/Stream_Control_Transmission_Protocol" rel="nofollow noreferrer">Stream Control Transmission Protocol</a><br>
  <a href="http://en.wikipedia.org/wiki/SCTP_packet_structure" rel="nofollow noreferrer">SCTP packet structure</a><br>
  <a href="https://www.rfc-editor.org/rfc/rfc4960" rel="nofollow noreferrer">RFC 4960</a></p>
  <p>In a nut shell, after the SCTP Common header are a series of one or more &quot;chunks&quot;.  Most of the time, each SCTP packet has just one chunk type, but you can have chunk bundling in which certain chunk types can be bundled together into a single packet.  Because of this bundling, I can't just define a union inside my SCTP header structure and call it a day.</p>
  <p>So this is what I have for <code>struct sctp_header</code>:</p>
  <pre><code>struct sctp_header {
      uint16_t srcport;
      uint16_t dstport;
      uint32_t vtag;
      uint32_t chksum;
      uint8_t ctype;
      uint8_t cflags;
      uint16_t clength;
      void *chunks;
  };
  </code></pre>
  <p><br>And for <code>union sctp_chunks</code> (truncated to just two chunk types for this question):</p>
  <pre><code>struct sctp_data {
      uint32_t tsn;
      uint16_t stream_id;
      uint16_t stream_seq;
      uint32_t pp_id;
      void *data;
  };
  
  struct sctp_init {
      uint32_t initate_tag;
      uint32_t a_rwnd;
      uint16_t num_out_streams;
      uint16_t num_in_streams;
      uint32_t tsn;
      void *params;
  };
  
  union sctp_chunks {
      struct sctp_data *data;
      struct sctp_init *init;
  };
  </code></pre>
  <p><br><br>Right now, I am overlaying <code>sctp_chunks</code> onto <code>sctp_header-&gt;chunks</code> (once I have done all the other necessary checks to make sure I am sitting on an SCTP packet).  I then read <code>sctp_header-&gt;ctype</code> in a switch statement, and based on that, I know whether I can access <code>sctp_header-&gt;chunks-&gt;data-&gt;tsn</code> or <code>sctp_header-&gt;chunks-&gt;init-&gt;initate_tag</code> (after casting to <code>(sctp_chunks *)</code>), and so on for other chunk types.  Later on, I'll do math and check for remaining chunks, and re-overlay the <code>sctp_chunks</code> union onto the remaining data until I have processed all chunks.  For now, I am operating on just the first chunk.</p>
  <p>Problem is, trying to access <code>data-&gt;tsn</code> or <code>init-&gt;initiate_tag</code> (or any other member of the union) causes a SIGSEGV.  I don't have GDB handy (I am just a user on the machine this is being coded on), so I am having a hard time figuring out why my program is segfaulting.  I believe my use of the structures/unions to be sound, but thus is the nature of C, it's probably something REALLY subtle that is hooking me here.</p>
  <p>Printing the pointer addresses for <code>chunks-&gt;data</code> or <code>chunks-&gt;init</code> shows me addresses that do not appear to be NULL pointers, and I am not getting any major errors or warnings out of gcc, so I am a bit stumped.</p>
  <p>Anything out of the ordinary, or is there a better way to tackle this?</p>