title: Scapy: How to implement a list of conditional fields?
body: <p>I am new to Scapy and I want to dissect a complicated protocol.  Here is where I get blocked: I have a packet holding, in two fields, the type and the number of records.  The rest of the packet constitutes the records. </p>
  
  <p>I implemented it with two layers: the first one, the MainPacket class, holding the record_type, the record_nb and a list of Records.  The second layer, the Record class, is fully composed of conditional fields, one per record type, as shown below:</p>
  
  <pre><code>from scapy.all import Packet, IntField, IntEnumField, FieldLenField\
  ,PacketListField, StrNullField, ConditionalField
  
  class Record(Packet):
      fields_desc = [
          #IntField("data_long_record", 0)
          #StrNullField("data_sz_record", "")
          ConditionalField(IntField("data_long_record", 0),
                           lambda pkt:pkt.underlayer.record_type==3),
          ConditionalField(StrNullField("data_sz_record", ""),
                           lambda pkt:pkt.underlayer.record_type==8)
      ]
      def extract_padding(self, s):
          return '', s
  
  class MainPacket(Packet):
      fields_desc = [
          IntEnumField("record_type", 1, {
              3:"DATA_LONG",            
              8:"DATA_SZ"}),
          FieldLenField("record_nb", 0, fmt="I", count_of="records"),
          PacketListField("records", None, Record, count_from=lambda pkt:pkt.record_nb)
      ]
      def extract_padding(self, s):
          return '', s
  
  if __name__ == "__main__":
      p1 = MainPacket("\x00\x00\x00\x03" # Type is DATA_LONG
                 "\x00\x00\x00\x04" # 4 records
                 "\x00\x00\x00\x01" 
                 "\x00\x00\x00\x02"
                 "\x00\x00\x00\x03"
                 "\x00\x00\x00\x04")
      p1.show()
      p2 = MainPacket("\x00\x00\x00\x08" # Type is DATA_SZ
                 "\x00\x00\x00\x02" # 2 records
                 "Hello\x00"
                 " world.\x00")
      p2.show()
  </code></pre>
  
  <p>Here is the result I get when testing the code:</p>
  
  <pre><code>WARNING: No route found for IPv6 destination :: (no default route?)
  ###[ MainPacket ]###
    record_type= DATA_LONG
    record_nb = 4
    \records   \
     |###[ Raw ]###
     |  load      = '\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04'
  ###[ MainPacket ]###
    record_type= DATA_SZ
    record_nb = 2
    \records   \
     |###[ Raw ]###
     |  load      = 'Hello\x00 world.\x00'
  </code></pre>
  
  <p>The sublayer is not dissected. However, Replacing the conditionals by the IntField or the StrNullField works well, except that it cannot handle all cases...</p>
  
  <p>My Python version is 2.7.6.
  My Scapy version is 2.3.2.
  I use Linux Mint 17.</p>
  
  <p>Do you have any clue?</p>