title: Sending hand-crafted BPDU (Spanning Tree Protocol packet) with Python
body: <p>I'm trying to send hand-crafted BPDU TCN packets (and a few others that belong to different protocols) to test my network lab for DoS attacks. </p>
  
  <p>I've found <a href="https://stackoverflow.com/questions/26827727/scapy-generating-stpspanning-tree-protocol-packets">this answer</a>, but it doesn't help.</p>
  
  <p>I've tried to use raw sockets and <code>scapy</code> but to no success. </p>
  
  <p>This is my code using raw sockets:</p>
  
  <pre><code>from socket import *
  from struct import pack
  class EthFrame():
      def __init__(self, dst_addr='', src_addr='',  llc_header ='',  payload =''):
          self.dst_addr = dst_addr
          self.src_addr = src_addr
          self.llc_header = llc_header
          self.payload = payload
          self.header = pack('!s', self.dst_addr + self.src_addr + self.llc_header)  
          self.frame = pack('s',  self.header + self.payload)
  
      def sendFrame(self,  interface):
          s = socket(AF_PACKET,  SOCK_RAW)
          s.bind((interface, 0))
          s.send(self.frame)
  
  p = EthFrame(b'\x01\x80\xC2\x00\x00\x00',  b'\x00'*6,  b'\x42\x42\x03',  b'\x00\x00\x00\x80')
  p.sendFrame('eth0')
  </code></pre>
  
  <p>The result is a malformed packet containing just one byte - "00000010". 
  As far as I read in documentation, NIC should add CRC and padding bits by itself.</p>
  
  <p>And this is my <code>scapy</code> code:</p>
  
  <pre><code>import scapy.all
  from scapy.all import *
  
  netpacket = Raw('\x00\x00\x00\x80')
  sendp(netpacket,  iface="eth0")
  </code></pre>
  
  <p>It also sends a malformed packet, this time containing two bytes.</p>
  
  <p>The packet I'm trying to prepare is described at page 5 of <a href="http://140.114.71.160/~cs4231/homework/hw3/BPDU.pdf" rel="nofollow noreferrer">this pdf document</a>.</p>
  
  <p>I'm using Linux.</p>
  
  <p>---- edit:
  Following Oliver's suggestion, I'm adding information from linked document.</p>
  
  <p>TCN (topology change notification) BPDU packet is layer 2, Ethernet(I) packet. There are minor differences in structure of BPDU packet, depending on hardware vendor. Here, in this example, I'm using CISCO implementation.</p>
  
  <p>Ethernet header should always have destination address set to 01:80:C2:00:00:00 (STP multicast address).</p>
  
  <p>Following Ethernet header, TCN BPDU should consist of:<br>
  Logical Link Control - 3 bytes, always set to [0x42, 0x42, 0x03]<br>
  BPDU header - 4 bytes, for TCN BPDU always set to [0x00, 0x00, 0x00, 0x80]  </p>
  
  <p>followed by padding (in this case 39 bytes set to 0x00)</p>