Exemple #1
0
 def wait(self):
     start = time.time()
     timeout = 1.0
     while 1:
         rd, wt, er = select.select([self.sock.socket], [], [], timeout)
         if rd:
             # okay to use time here, because select has told us
             # there is data and we don't care to measure the time
             # it takes the system to give us the packet.
             arrival = time.time()
             try:
                 pkt, who = self.sock.recvfrom(4096)
             except socket.error:
                 continue
             # could also use the ip module to get the payload
             repip = ip.disassemble(pkt)
             try:
                 reply = icmp.disassemble(repip.data)
             except ValueError:
                 continue
             if reply.get_id() == self.pid:
                 self.recv_packet(reply, arrival)
                 self.last_arrival = arrival
         timeout = (start + 1.0) - time.time()
         if timeout < 0:
             break
Exemple #2
0
	def wait(self):
		start = time.time()
		timeout = 0.05
		while 1:
			rd, wt, er = select.select([self.sock.socket], [], [], timeout)
			if rd:
				# okay to use time here, because select has told us
				# there is data and we don't care to measure the time
				# it takes the system to give us the packet.
				arrival = time.time()
				try:
					pkt, who = self.sock.recvfrom(4096)
				except socket.error:
					continue
				# could also use the ip module to get the payload
				repip = ip.disassemble(pkt)
				try:
					reply = icmp.disassemble(repip.data)
				except ValueError:
					continue
				try:
					if reply.get_id() == self.ping_ident:
						self.recv_packet(reply, arrival)
						self.last_arrival = arrival
				except AttributeError, e:
					if reply.get_embedded_ip().dst == self.addr:
						raise exceptions.DoesntExistException('host %s '
							'unreachable (%s)' % (self.addr, e))
					# else we are receiving a hostunreach for another host,
					# just ignore it and continue waiting.
			timeout = (start + 0.05) - time.time()
			if timeout < 0:
				break
Exemple #3
0
 def wait(self):
     start = time.time()
     timeout = 1.0
     while 1:
         rd, wt, er = select.select([self.sock.socket], [], [], timeout)
         if rd:
             # okay to use time here, because select has told us
             # there is data and we don't care to measure the time
             # it takes the system to give us the packet.
             arrival = time.time()
             try:
                 pkt, who = self.sock.recvfrom(4096)
             except socket.error:
                 continue
             # could also use the ip module to get the payload
             repip = ip.disassemble(pkt)
             try:
                 reply = icmp.disassemble(repip.data)
             except ValueError:
                 continue
             if reply.get_id() == self.pid:
                 self.recv_packet(reply, arrival)
                 self.last_arrival = arrival
         timeout = (start + 1.0) - time.time()
         if timeout < 0:
             break
Exemple #4
0
def incoming_packet_handler(pktlen, data, timestamp):
	if not data or data[12:14] != '\x08\x00':
		return

	ip_pkt = ip.disassemble(data[14:])
	udp_frag = udp.disassemble(ip_pkt.data, False)
	data_str = udp_frag.data.encode('hex') if udp_frag.data != '' else '-'
	sys.stdout.write("{} {} {} {}\n".format(ip_pkt.src, udp_frag.sport, udp_frag.dport, data_str))
	sys.stdout.flush()
Exemple #5
0
    def received(self, pkt, gateway):
        """ Upon received an incoming ICMP, determine if the packet is of our interest
             If it is, populate related fields, and return 1
             otherwise return 0
        """

        ip_reply = ip.disassemble(pkt)
        if icmp.HDR_SIZE_IN_BYTES > len(ip_reply.data):
            return 0  #IP payload is not long enough to hold ICMP

        icmp_reply = icmp.disassemble(ip_reply.data)  #ICMP is payload of IP

        if DEBUG:
            stdout.write(
                "recvfrom %s: ICMP_type: %d ICMP_code: %d" %
                (gateway, icmp_reply.get_type(), icmp_reply.get_code()))

        # 2 conditions interest us:
        #   1. ICMP_TIMEEXCEED, probe packet dropped by gateway in the middle,
        #      which then send ICMP_TIMEEXCEED back to us
        #   2. ICMP_ECHOREPLY, probe packet reach destination host,
        if (icmp_reply.get_type() == icmp.ICMP_TIMXCEED \
                    and icmp_reply.get_code() == icmp.ICMP_TIMXCEED_INTRANS) \
                    or icmp_reply.get_type() == icmp.ICMP_ECHOREPLY:
            if ip.MIN_HDR_SIZE_IN_BYTES > len(icmp_reply.data):
                return 0  #ICMP payload is not long enough for inner IP

            inner_ip = ip.disassemble(icmp_reply.data)

            if inner_ip.src != self.src_addr or inner_ip.dst != self.dst_addr:
                return 0

            self.gateway = gateway
            self.timestamp_received = time.time()
            if icmp_reply.get_type() == icmp.ICMP_ECHOREPLY:
                self.dst_reached = 1
            return 1

        if self.verbose:  # In verbose mode, ICMP packets other than IME_EXCEEDED and UNREACHABLE are listed
            stdout.write(
                "recvfrom %s: ICMP_type: %d ICMP_code: %d" %
                (gateway, icmp_reply.get_type(), icmp_reply.get_code()))

        return 0
Exemple #6
0
def incoming_packet_handler(pktlen, data, timestamp):
    if not data or data[12:14] != '\x08\x00':
        return

    ip_pkt = ip.disassemble(data[14:])
    udp_frag = udp.disassemble(ip_pkt.data, False)
    data_str = udp_frag.data.encode('hex') if udp_frag.data != '' else '-'
    sys.stdout.write("{} {} {} {}\n".format(ip_pkt.src, udp_frag.sport,
                                            udp_frag.dport, data_str))
    sys.stdout.flush()
Exemple #7
0
    def testUdpPortWronlyParsed(self):
        ip_reply = ip.disassemble(self.pkt)
        icmp_reply = icmp.disassemble(ip_reply.data)  #ICMP is payload of IP
        inner_ip = icmp_reply.get_embedded_ip()

        self.assertEqual('10.249.64.152', inner_ip.src)
        self.assertEqual('207.68.173.76', inner_ip.dst)

        udp_in_icmp = udp.disassemble(inner_ip.data, 0)
        self.assertEqual(40164, udp_in_icmp.sport)
        self.assertEqual(33435, udp_in_icmp.dport)
Exemple #8
0
    def testUdpPortWronlyParsed(self):
        ip_reply = ip.disassemble(self.pkt)
        icmp_reply = icmp.disassemble(ip_reply.data)                #ICMP is payload of IP
        inner_ip = icmp_reply.get_embedded_ip()

        self.assertEqual('10.249.64.152', inner_ip.src)
        self.assertEqual('207.68.173.76', inner_ip.dst)
        
        udp_in_icmp = udp.disassemble(inner_ip.data, 0)
        self.assertEqual(40164, udp_in_icmp.sport)
        self.assertEqual(33435, udp_in_icmp.dport)
Exemple #9
0
 def received(self, pkt, gateway):
     """ Upon received an incoming ICMP, determine if the packet is of our interest
          If it is, populate related fields, and return 1
          otherwise return 0
     """
      
     ip_reply = ip.disassemble(pkt)
     if icmp.HDR_SIZE_IN_BYTES > len(ip_reply.data):
         return 0                #IP payload is not long enough to hold ICMP
      
     icmp_reply = icmp.disassemble(ip_reply.data)                #ICMP is payload of IP
      
     if DEBUG:
         stdout.write("recvfrom %s: ICMP_type: %d ICMP_code: %d" % (gateway, icmp_reply.get_type(), icmp_reply.get_code()))
     
     # 2 conditions interest us:
     #   1. ICMP_TIMEEXCEED, probe packet dropped by gateway in the middle,
     #      which then send ICMP_TIMEEXCEED back to us
     #   2. ICMP_ECHOREPLY, probe packet reach destination host, 
     if (icmp_reply.get_type() == icmp.ICMP_TIMXCEED \
                 and icmp_reply.get_code() == icmp.ICMP_TIMXCEED_INTRANS) \
                 or icmp_reply.get_type() == icmp.ICMP_ECHOREPLY:
         if ip.MIN_HDR_SIZE_IN_BYTES > len(icmp_reply.data):
             return 0        #ICMP payload is not long enough for inner IP
                 
         inner_ip = ip.disassemble(icmp_reply.data)
          
         if inner_ip.src != self.src_addr or inner_ip.dst != self.dst_addr:
             return 0
          
         self.gateway = gateway
         self.timestamp_received = time.time()
         if icmp_reply.get_type() == icmp.ICMP_ECHOREPLY:
             self.dst_reached = 1
         return 1
      
     if self.verbose:                # In verbose mode, ICMP packets other than IME_EXCEEDED and UNREACHABLE are listed
         stdout.write("recvfrom %s: ICMP_type: %d ICMP_code: %d" % (gateway, icmp_reply.get_type(), icmp_reply.get_code()))
          
     return 0             
Exemple #10
0
    def recvPackets(self,pingJob):
        """receive a packet and decode its header"""
        while time.time() - pingJob.start<self.timeout:
            rl,wl,el = select.select([self.pingsocket],[],[],0)
            if self.pingsocket in rl:
                try:
                    data, (host, port) = self.pingsocket.recvfrom(1024)
                    if not data: return
                    ipreply = ip.disassemble(data)
                    try:
                        icmppkt = icmp.disassemble(ipreply.data)
                    except ValueError:
                        print ("checksum failure on packet %r", ipreply.data)
                        try:
                            icmppkt = icmp.disassemble(ipreply.data, 0)
                        except ValueError:
                            continue            # probably Unknown type
                    except Exception, ex:
                        print ("Unable to decode reply packet payload %s", ex)
                        continue
                    sip =  ipreply.src
                    if (icmppkt.get_type() == icmp.ICMP_ECHOREPLY and
                        icmppkt.get_id() == self.procId and
                        sip == pingJob.ipaddr):
                        pingJob.rrt = (time.time()-pingJob.start)*1000
                        if pingJob.rrt  < 1:
                            time_print = "time<1ms"
                        else:
                            time_print = "time=%dms"%(pingJob.rrt)
                        print "Reply from %s: bytes=%s %s TTL=%d"%(sip,ipreply.len,time_print,ipreply.ttl)
                        pingJob.pingSuc()
                    elif icmppkt.get_type() == icmp.ICMP_UNREACH:
                        try:
                            origpkt = icmppkt.get_embedded_ip()
                            dip = origpkt.dst
                            if (origpkt.data.find(self.pktdata) > -1
                                and dip == pingJob.ipaddr):
                                print ("pj fail for %s", pingJob.ipaddr)

                        except ValueError, ex:
                            print ("failed to parse host unreachable packet")
                    else:
                        pingJob.message = "unexpected pkt %s %s"% (sip, icmppkt)
                        continue
                    break
                except (SystemExit, KeyboardInterrupt): raise
                except socket.error, err:
                    errnum, errmsg = err.args
                    if errnum == errno.EAGAIN:
                        return
                    raise err
Exemple #11
0
 def received(self, pkt, gateway):
     """ Upon received an incoming ICMP, determine if the packet is of our interest
          If it is, populate related fields, and return 1
          otherwise return 0
     """
     
     ip_reply = ip.disassemble(pkt)
     if icmp.HDR_SIZE_IN_BYTES > len(ip_reply.data):
         return 0                #IP payload is not long enough to hold ICMP
  
     try:
         icmp_reply = icmp.disassemble(ip_reply.data)                #ICMP is payload of IP
     except ValueError, msg:
         if DEBUG:
             stdout.write("Bad Packet received!")
         return 0
Exemple #12
0
    def received(self, pkt, gateway):
        """ Upon received an incoming ICMP, determine if the packet is of our interest
             If it is, populate related fields, and return 1
             otherwise return 0
        """

        ip_reply = ip.disassemble(pkt)
        if icmp.HDR_SIZE_IN_BYTES > len(ip_reply.data):
            return 0  #IP payload is not long enough to hold ICMP

        try:
            icmp_reply = icmp.disassemble(
                ip_reply.data)  #ICMP is payload of IP
        except ValueError, msg:
            if DEBUG:
                stdout.write("Bad Packet received!")
            return 0
Exemple #13
0
 def _disassemble(self, buffer, cksum):
     code = ord(buffer[1])
     self.__embedded_ip = ip.disassemble(buffer[8:])
     Packet._disassemble(self, buffer, cksum)
Exemple #14
0
    def ping(self, packets=1):
        """
        Send ping messages, as many as given with packets parameter.

        Returns a dictionary of results, may raise PingError.
        """

        try:
            packets = int(packets)
            if packets < 0 or packets > MAX_PACKETS:
                raise ValueError
        except ValueError:
            raise PingError('Invalid number of packets: %s' % packets)

        interval = float(self.interval)/1000
        timeout = float(self.timeout)/1000
        last_sent = 0
        while 1:
            now = time.time()
            if self.sent < packets and (last_sent+interval)<now:
                self.__send_packet()
                last_sent = now

            if len(self.times) == packets:
                if filter(lambda t: t+timeout>now, self.times.values())==[]:
                    break

            (rd, wt, er) = select.select([self.socket.socket], [], [], timeout)
            if not rd:
                continue
            arrival = time.time()
            try:
                (pkt, who) = self.socket.recvfrom(4096)
            except socket.error:
                continue

            reply_address = ip.disassemble(pkt)
            try:
                reply = icmp.disassemble(reply_address.data)
            except ValueError:
                print 'Invalid ICMP reply packet received'
                continue

            if reply.get_id() != self.pid:
                print 'PID in response does not match'
                continue
            self.__recv_packet(reply, arrival, timeout)

            if self.sent < packets:
                continue

            if len(self.deltas)+len(self.timed_out) == packets:
                break

        received = len(self.deltas)
        loss = (float(packets-received)/float(packets))*100

        if len(self.deltas) == 0:
            summary = {
                'min': None,
                'max': None,
                'average': None,
                'sent': packets,
                'received': len(self.deltas) + len(self.timed_out),
                'packetloss': loss
            }

        else:
            summary = {
                'min': min(self.deltas),
                'max': max(self.deltas),
                'average': reduce(lambda x, y: x+y, self.deltas) / len(self.deltas),
                'sent': packets,
                'received': received,
                'packetloss': loss
            }

        self.__reset_counters()
        return summary
Exemple #15
0
    def ping(self, packets=1):
        """
        Send ping messages, as many as given with packets parameter.

        Returns a dictionary of results, may raise PingError.
        """

        try:
            packets = int(packets)
            if packets < 0 or packets > MAX_PACKETS:
                raise ValueError
        except ValueError:
            raise PingError('Invalid number of packets: %s' % packets)

        interval = float(self.interval) / 1000
        timeout = float(self.timeout) / 1000
        last_sent = 0
        while 1:
            now = time.time()
            if self.sent < packets and (last_sent + interval) < now:
                self.__send_packet()
                last_sent = now

            if len(self.times) == packets:
                if filter(lambda t: t + timeout > now,
                          self.times.values()) == []:
                    break

            (rd, wt, er) = select.select([self.socket.socket], [], [], timeout)
            if not rd:
                continue
            arrival = time.time()
            try:
                (pkt, who) = self.socket.recvfrom(4096)
            except socket.error:
                continue

            reply_address = ip.disassemble(pkt)
            try:
                reply = icmp.disassemble(reply_address.data)
            except ValueError:
                print 'Invalid ICMP reply packet received'
                continue

            if reply.get_id() != self.pid:
                print 'PID in response does not match'
                continue
            self.__recv_packet(reply, arrival, timeout)

            if self.sent < packets:
                continue

            if len(self.deltas) + len(self.timed_out) == packets:
                break

        received = len(self.deltas)
        loss = (float(packets - received) / float(packets)) * 100

        if len(self.deltas) == 0:
            summary = {
                'min': None,
                'max': None,
                'average': None,
                'sent': packets,
                'received': len(self.deltas) + len(self.timed_out),
                'packetloss': loss
            }

        else:
            summary = {
                'min':
                min(self.deltas),
                'max':
                max(self.deltas),
                'average':
                reduce(lambda x, y: x + y, self.deltas) / len(self.deltas),
                'sent':
                packets,
                'received':
                received,
                'packetloss':
                loss
            }

        self.__reset_counters()
        return summary
Exemple #16
0
 def testSimplePacket(self):
     buf = ip.assemble(self.simple, 1)
     new = ip.disassemble(buf, 1)
     self.assertEqual(self.simple, new)
Exemple #17
0
 def _disassemble(self, buffer, cksum):
     code = ord(buffer[1])
     self.__embedded_ip = ip.disassemble(buffer[8:])
     Packet._disassemble(self, buffer, cksum)
Exemple #18
0
 def testSimplePacket(self):
     buf = ip.assemble(self.simple, 1)
     new = ip.disassemble(buf, 1)
     self.assertEqual(self.simple, new)