title: How to parse 802.1q triple tagged frames using Scapy?
body: <p><strong>Background:</strong></p>
  
  <p>I'm working with <code>scapy</code> to parse <code>IEEE 802.1Q triple tagged frames</code>.  I'm generating test frames using scapy and capturing them to a pcap file.
  The parsing is done in a separate script by reading in the pcap file.  I can successfully work with the 1st 802.1q tag.</p>
  
  <p><strong>Problem:</strong> </p>
  
  <p>It's not clear to me how to access at the 2nd and 3rd 802.1q tags.  I'm attempting to use <code>haslayer()</code> and <code>getlayer</code> to conditionally examine the frame headers.  <code>haslayer(Dot1Q)</code> returns the 
  values associated with the 1st Dot1Q tag.</p>
  
  <p><strong>Question:</strong> </p>
  
  <p>If the <code>type</code> field of the 1st tag is <code>0x8100</code>, then a 2nd tag is present.  Is there a way to advance to the 2nd and 3rd tags?  I've looked at the l2.py source and experimented, but no luck yet.</p>
  
  <p><strong>Code:</strong></p>
  
  <p>Send triple tag frame:</p>
  
  <pre><code>    sendp(Ether(dst='78:2B:CB:33:4B:9F',src="D4:AE:52:89:BA:FA")/Dot1Q(vlan=1,id=3,prio=2)/Dot1Q(vlan=2,id=3,prio=2)/Dot1Q(vlan=3,id=3,prio=2)/IP(dst='10.25.222.222')/ICMP())
  </code></pre>
  
  <p>Frame display:</p>
  
  <pre><code>###[ Ethernet ]###
    dst       = 78:2b:cb:33:4b:9f
    src       = d4:ae:52:89:ba:fa
    type      = 0x8100
  ###[ 802.1Q ]###
       prio      = 2L
       id        = 1L
       vlan      = 1L
       type      = 0x8100
  ###[ 802.1Q ]###
          prio      = 2L
          id        = 1L
          vlan      = 2L
          type      = 0x8100
  ###[ 802.1Q ]###
             prio      = 2L
             id        = 1L
             vlan      = 3L
             type      = 0x800
  ###[ IP ]###
                version   = 4L
                ihl       = 5L
                tos       = 0x0
                len       = 28
                id        = 1
                flags     = 
                frag      = 0L
                ttl       = 64
                proto     = icmp
                chksum    = 0xc55
                src       = 10.25.123.123
                dst       = 10.25.222.222
                \options   \
  ###[ ICMP ]###
                   type      = echo-request
                   code      = 0
                   chksum    = 0xf7ff
                   id        = 0x0
                   seq       = 0x0
  ###[ Padding ]###
                      load      = '\x00\x00\x00\x00\x00\x00'
  </code></pre>
  
  <p>Frame parsing:</p>
  
  <pre><code>pkts=rdpcap(self.file_name)
  
  for pkt in pkts:
  
      try:
          if pkt.haslayer(Ether):
              src     = pkt.getlayer(Ether).src
              dst     = pkt.getlayer(Ether).dst
              type    = pkt.getlayer(Ether).type
              # Do something 
  
          if pkt.haslayer(Dot1Q):
              prio    = pkt.getlayer(Dot1Q).prio
              id      = pkt.getlayer(Dot1Q).id
              vlan    = pkt.getlayer(Dot1Q).vlan
              type    = pkt.getlayer(Dot1Q).type
              # Do something
  
      except:
          raise `            
  </code></pre>