title: Can't Parse DHCP packets with Ryu's get_protocol(dhcp.dhcp)
body: <p>I'm using the Ryu SDN controller with an Open vSwitch on mininet using OpenFlow 1.3 to parse DHCP packets. Following online examples and the Ryu resources, I've implemented a DHCP packet parser. However, it does not work as I expected it to, and I'm wondering if anyone has any insight as to why my first solution does not work? </p>
  
  <p>An example of a code snippet for parsing a DHCP packet is below:</p>
  
  <pre><code>from ryu.lib.packet import dhcp
  ...
  ...
  @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
  def _packet_in_handler(self, ev):
      msg = ev.msg
      datapath = msg.datapath
      pkt = packet.Packet(msg.data)
      dhcpPacket = pkt.get_protocol(dhcp.dhcp)
  </code></pre>
  
  <p>My code follows a similar vein:</p>
  
  <pre><code>from ryu.lib.packet import dhcp
  ...
  ...
  @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
  def _packet_in_handler(self, ev):
      pkt = {}
      pkt['msg'] = ev.msg
      pkt['dp'] = pkt['msg'].datapath
      pkt['pkt'] = packet.Packet(pkt['msg'].data)
      pkt['dhcp'] = pkt['pkt'].get_protocol(dhcp.dhcp)
  </code></pre>
  
  <p>This seems reasonable as I am following this exact sequence with other protocols like ARP, ICMP, IP, etc. Examples below. </p>
  
  <pre><code>pkt['arp'] = pkt['pkt'].get_protocol(arp.arp)
  pkt['ip'] = pkt['pkt'].get_protocol(ipv4.ipv4)
  pkt['icmp'] = pkt['pkt'].get_protocol(icmp.icmp)
  </code></pre>
  
  <p>The only problem is that the three parsers I list above actually return data, while the get_protocol for DHCP consistently returns None. I have already tested this by sending DHCP packets through my switch. </p>
  
  <p>What does work is the following code snippet where I identify packet lists having more than three values. I save the value at index three and set that as my DHCP packet. In the DHCP packet, I concentrate of parsing the string at index 2. That contains the data I'm interested in. </p>
  
  <pre><code># pkt['dhcp'] = pkt['pkt'].get_protocol(dhcp.dhcp)
  # Check if pkt['pkt]] &gt; 3 elements, if so, parse DHCP string
  #Standard pkt['dhcp'] = (None, None, String)
  if len(pkt['pkt']) &gt; 3:
      pkt['dhcp'] = dhcp.dhcp.parser(pkt['pkt'][3])
      pkt['op'] = hex(ord(dhcp_p[2][0]))
      pkt['htype'] = hex(ord(dhcp_p[2][1]))
      pkt['hlen'] = hex(ord(dhcp_p[2][2]))
      pkt['hops'] = hex(ord(dhcp_p[2][3]))
  
      def parseDHCP(pkt_d,start,stop):
          s_value = ''
          stop += 1
          for val in range(start,stop):
          s_value += str(hex(ord(pkt_d[val])))
          return s_value
  
      pkt['xid'] = parseDHCP(dhcp_p[2],4,7)
      pkt['secs'] = parseDHCP(dhcp_p[2],8,9)
      pkt['flags'] = parseDHCP(dhcp_p[2],10,11)
      pkt['ciaddr'] = parseDHCP(dhcp_p[2],12,15)
      pkt['yiaddr'] = parseDHCP(dhcp_p[2],16,19)
      pkt['siaddr'] = parseDHCP(dhcp_p[2],20,23)
      pkt['giaddr'] = parseDHCP(dhcp_p[2],24,27)
      pkt['chaddr'] = parseDHCP(dhcp_p[2],28,33)
      pkt['pad'] = parseDHCP(dhcp_p[2],34,43)
  </code></pre>
  
  <p>A print out of these values looks like so: </p>
  
  <pre><code>0x1
  0x1
  0x6
  0x0
  0x440x30x980x11
  0x00x0
  0x00x0
  0x00x00x00x0
  0x00x00x00x0
  0x00x00x00x0
  0x00x00x00x0
  0x7e0x1d0xcc0xe70xee0x4f
  0x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x0
  </code></pre>
  
  <p>The above code allows me to observe the contents of DHCP packets, but I'm really trying to figure out why I'm not achieving similar results using the pkt['pkt'].get_protocol(dhcp.dhcp) method? </p>