title: Udp port scanner python
body: <p>I wanted to write simple udp port scanner on python and I faced some problems.</p>
  
  <p>First of all am I understand right that there are 3 options:</p>
  
  <ul>
  <li><p>send UDP - get nothing -> port is filtered|opened</p></li>
  <li><p>send UDP - get icmp port unreachable -> port is closed</p></li>
  <li><p>send UDP - get UDP - port is opened</p></li>
  </ul>
  
  <p>I create raw socket, create ip header and udp header. In udp header write the dest port and add some data.
  Then I send it to server and with <code>select</code> wait for a reply. But nothing neither on opened port nor on closed. Only timeout.</p>
  
  <p>And is it possible to send just dummy data but not correct packet of the next level ?</p>
  
  <p><em>[Update 1]</em>
  Added more data to send in udp packet. Now I get udp packet back from (<code>194.226.244.126</code>, 53) but my host send back icmp type 3 to <code>194.226.244.126</code> before I could read any recieved data. But still no response from 8.8.8.8</p>
  
  <p><em>[Update 2]</em>
  Found that 8.8.8.8 reply only on correct dns packets. But still can't read udp packet with raw socket.</p>
  
  <pre><code>import socket
  import time
  import select
  import sys
  from packets_headers import iphdr, udphdr
  from get_ip import Getip
  
  timeout = 3
  host = "8.8.8.8"
  port = 53
  my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW)
  udp_header = udphdr(b"00000000000000000", port, 4242)
  udp_packet = udp_header.assemble()
  g = Getip()
  ip_packet_header = iphdr(socket.IPPROTO_UDP, g.get_lan_ip(), host)
  ip_packet_header.data = udp_packet
  ip_packet = ip_packet_header.assemble()
  my_socket.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
  full_packet = ip_packet
  while full_packet:
      sent = my_socket.sendto(full_packet, (host, port))
      full_packet = full_packet[sent:]
  
  ready = select.select([my_socket], [], [], timeout)
  if ready[0] == []:  # Timeout
      print("Timeout")
      sys.exit()
  rec_packet, addr = my_socket.recvfrom(1024)
  print(rec_packet, addr)
  </code></pre>
  
  <p>Also <code>packets_header.py</code></p>
  
  <pre><code>import socket
  import struct
  import random
  
  
  class iphdr(object):
  
      """
      This represents an IP packet header.
      @assemble packages the packet
      @disassemble disassembles the packet
      """
  
      def __init__(self, proto=socket.IPPROTO_ICMP, src="0.0.0.0", dst=None):
          self.version = 4
          self.hlen = 5
          self.tos = 0
          self.length = 20
          self.id = random.randint(2 ** 10, 2 ** 16)
          self.frag = 0
          self.ttl = 255
          self.proto = proto
          self.cksum = 0
          self.src = src
          self.saddr = socket.inet_aton(src)
          self.dst = dst or "0.0.0.0"
          self.daddr = socket.inet_aton(self.dst)
          self.data = ""
  
      def assemble(self):
          header = struct.pack('BBHHHBB',
                               (self.version &amp; 0x0f) &lt;&lt; 4 | (self.hlen &amp; 0x0f),
                               self.tos, self.length + len(self.data),
                               socket.htons(self.id), self.frag,
                               self.ttl, self.proto)
          self._raw = header + b"\x00\x00" + self.saddr + self.daddr + self.data
          return self._raw
  
      @classmethod
      def disassemble(self, data):
          self._raw = data
          ip = iphdr()
          pkt = struct.unpack('!BBHHHBBH', data[:12])
          ip.version = (pkt[0] &gt;&gt; 4 &amp; 0x0f)
          ip.hlen = (pkt[0] &amp; 0x0f)
          ip.tos, ip.length, ip.id, ip.frag, ip.ttl, ip.proto, ip.cksum = pkt[1:]
          ip.saddr = data[12:16]
          ip.daddr = data[16:20]
          ip.src = socket.inet_ntoa(ip.saddr)
          ip.dst = socket.inet_ntoa(ip.daddr)
          return ip
  
      def __repr__(self):
          return "IP (tos %s, ttl %s, id %s, frag %s, proto %s, length %s) " \
                 "%s -&gt; %s" % \
                 (self.tos, self.ttl, self.id, self.frag, self.proto,
                  self.length, self.src, self.dst)
  
  
  class udphdr(object):
  
      def __init__(self, data="", dport=4242, sport=4242):
          self.dport = dport
          self.sport = sport
          self.cksum = 0
          self.length = 0
          self.data = data
  
      def assemble(self):
          self.length = len(self.data) + 8
          part1 = struct.pack("!HHH", self.sport, self.dport, self.length)
          cksum = self.checksum(self.data)
          cksum = struct.pack("!H", cksum)
  
          self._raw = part1 + cksum + self.data
          return self._raw
  
      @classmethod
      def checksum(self, data):
          # XXX implement proper checksum
          cksum = 0
          return cksum
  
      def disassemble(self, data):
          self._raw = data
          udp = udphdr()
          pkt = struct.unpack("!HHHH", data)
          udp.src_port, udp.dst_port, udp.length, udp.cksum = pkt
          return udp
  </code></pre>