def get_reply(self, seq): start = time.time() timeout = self.max_wait while 1: rd, wt, er = select.select([self.icmp_sock], [], [], timeout) if rd: try: pkt, who = self.icmp_sock.recvfrom(4096) except socket.error: pass arrived = time.time() _reply = ip.Packet(pkt) reply = icmp.Packet(_reply.data) if (reply.type == icmp.ICMP_TIMXCEED \ and reply.code == icmp.ICMP_TIMXCEED_INTRANS) \ or reply.type == icmp.ICMP_UNREACH: encap = ip.Packet(reply.data) # what about this checksum? orig = udp.Packet(encap.data, 0) if orig.sport == self.id \ and orig.dport == self.def_port+seq: if reply.type == icmp.ICMP_UNREACH: self.got_there = 1 return _reply, arrived timeout = (start + self.max_wait) - time.time() if timeout < 0: return None, None
def probe_packet(self): """ Build the outgoing probe packet """ # build the packet, then set its length probe_ip = ip.Packet() probe_ip.src = self.src_addr probe_ip.dst = self.dst_addr probe_ip.p = socket.IPPROTO_UDP probe_ip.ttl = self.ttl probe_ip.df = self.dont_frag # build UPD packet as the payload of IP packet probe_udp = udp.Packet() # Because more than 1 traceroute can be running at the same time, we need to # distinguish the packets responding to this traceroute instance. We do this # by setting source port in UDP header to our process id. As ICMP will include # UDP header that triggers it in the payload, we will be able to compare the # UDP source port embedded in returned ICMP packet with our process id and # determine if the packet is of our interest. probe_udp.sport = self.src_port probe_udp.dport = self.dst_port # calculate the length of UDP data header_len = len(udp.assemble(probe_udp) + ip.assemble(probe_ip)) if self.packet_len <= header_len: raise TraceError, "packet length must be > %d" % (header_len) probe_udp.data = '\000' * (self.packet_len - header_len) probe_ip.data = udp.assemble(probe_udp) return ip.assemble(probe_ip, self.check_sum)
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.Packet(pkt) try: reply = icmp.Packet(repip.data) except ValueError: continue if reply.id == self.pid: self.recv_packet(reply, arrival) self.last_arrival = arrival timeout = (start + 1.0) - time.time() if timeout < 0: break
def setUp(self): embedded = ip.Packet() embedded.src = '127.0.0.1' embedded.dst = '0.0.0.0' self.echo = icmp.Echo(1234, 1343, 'python pinger') self.echo_reply = icmp.EchoReply(1234, 1343, 'python pinger') self.time_exceeded = icmp.TimeExceeded(code=1, embedded_ip=embedded) self.unreachable = icmp.Unreachable(code=2, embedded_ip=embedded)
def init_probe_packet(self, src, dest): # build the packet, then set its length p = ip.Packet() p.dst = dest p.p = socket.IPPROTO_UDP u = udp.Packet() u.sport = self.id u.data = 'python traceroute' * 4 # need to set up the lengths p.data = u.assemble() self.probe_ip = p self.probe_udp = u self.packlen = len(p.assemble())
def send(self, service_descriptor, response_data, REQUEST): import ip, udp response_packet = udp.Packet(dport=REQUEST[1], sport=self.port, data=response_data) ip_packet = ip.Packet(dst=REQUEST[0], src=service_descriptor.params['ip'], data=udp.assemble(response_packet, 0), p=socket.IPPROTO_UDP, ttl=15) self.logger.debug(response_packet) data = udp.assemble(response_packet, 0) self.logger.debug(response_data) self.logger.debug(ip_packet) self.raw_sock.sendto(ip.assemble(ip_packet, 0), REQUEST.REMOTE)
def disconnect(self, payload): # TODO Throttle disconnects! # Send fake packet to stop upload # Structure of content: # 254 254 06 B (A+1) (7 bytes) # # First 2 bytes marks it as udp paket(?!) # Thrid bytes is command (close connection to client) # B and A+1 are to 16 bit numbers where A and B # are content of 'payload' aHi, aLow = payload[1], payload[2] bHi, bLow = payload[3], payload[4] a_plus_1 = (aHi * 256 + aLow + 1) % 65536 data = bytes( [254, 254, 6, bHi, bLow, int(a_plus_1 / 256), (a_plus_1 % 256)]) logging.info('Disconnecting client at {!r}'.format(self)) upacket = udp2.Packet() upacket.sport = self.client_port upacket.dport = self.server_port upacket.data = data ipacket = ip2.Packet() ipacket.src = self.client_ip ipacket.dst = self.server_ip ipacket.df = 1 ipacket.ttl = 64 ipacket.p = 17 ipacket.data = udp2.assemble(upacket, False) raw_ip = ip2.assemble(ipacket, 1) # Send fake packet to the PB server that looks like its coming from the client try: sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) except socket.error as e: logging.error('Socket could not be created: {}'.format(e)) sock.sendto(raw_ip, (ipacket.dst, 0)) self.time_disconnected = time.time() self.number_unanswered_outgoing_packets = 0
def sendUdpReply(src,dst,data): upacket = udp2.Packet() upacket.sport = src[1] upacket.dport = dst[1] upacket.data = data ipacket = ip2.Packet() ipacket.src = src[0] ipacket.dst = dst[0] ipacket.df = 1 ipacket.ttl = 64 ipacket.p = 17 ipacket.data = udp2.assemble(upacket, False) raw_ip = ip2.assemble(ipacket, 1) try: sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) except socket.error , msg: print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
def read_received_response(self): """When you've selected on NonBlockingPingerRegistry.keys(), you will get a list back; iterate i over each element and call this NonBlockingPingerRegistry[i].read_received_response()""" try: pkt, who = self.sock.recvfrom(4096) except socket.error: raise ValueError, "There was no data on that socket" # could also use the ip module to get the payload repip = ip.Packet(pkt) try: reply = icmp.Packet(repip.data) except: self.received_garbage = 1 return if reply.id == self.pid: arrival = time.time() self.recv_packet(reply, arrival) self.last_arrival = arrival self.got_response = 1
def GetFromSock(self): start = time.time() to = self.timeout while 1: # Wait for some data to come in rd, wt, er = select.select([self.sock], [], [], to) if rd: arrival = time.time() try: pkt, who = self.sock.recvfrom(4096) except socket.error: continue try: # Send the data to the parsers repip = ip.Packet(pkt) readin = self.ReadInPacket(repip.data) if (readin and readin != ""): break except ValueError: continue to = (start + self.timeout) - time.time() if to < 0: break
def disconnect(self, payload): # TODO Throttle disconnects! # Send fake packet to stop upload # Structure of content: # 254 254 06 B (A+1) (7 bytes) A = payload[3:5] # String! B = payload[5:7] a1 = ord(A[0]) * 256 + ord(A[1]) + 1 A1 = chr(a1 / 256) + chr(a1 % 256) data = chr(254) + chr(254) + chr(06) + B + A1 logging.info('Disconnecting client at {!r}'.format(self)) upacket = udp2.Packet() upacket.sport = self.client_port upacket.dport = self.server_port upacket.data = data ipacket = ip2.Packet() ipacket.src = self.client_ip ipacket.dst = self.server_ip ipacket.df = 1 ipacket.ttl = 64 ipacket.p = 17 ipacket.data = udp2.assemble(upacket, False) raw_ip = ip2.assemble(ipacket, 1) # Send fake packet to the PB server that looks like its coming from the client try: sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) except socket.error as err: logging.error('Socket could not be created: {}'.format(err)) sock.sendto(raw_ip, (ipacket.dst, 0)) self.time_disconnected = time.time() self.number_unanswered_outgoing_packets = 0
import sys import ip import udp ClientHost = '192.168.0.22' ServerHost = '192.168.0.22' ClientPort = 2057 ServerPort = 2056 upacket = udp.Packet() upacket.sport = ClientPort upacket.dport = ServerPort upacket.data = "\xfe\xfe\x00\x06" #upacket.data = "Hello Server" ipacket = ip.Packet() ipacket.src = ClientHost ipacket.dst = ServerHost ipacket.df = 1 ipacket.ttl = 64 ipacket.p = 17 ipacket.data = udp.assemble(upacket, False) raw_ip = ip.assemble(ipacket, 1) try: sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) except socket.error, msg: print 'Socket could not be created. Error Code : ' + str( msg[0]) + ' Message ' + msg[1] sys.exit()
def setUp(self): self.simple = ip.Packet() self.simple.src = '127.0.0.1' self.simple.dst = '0.0.0.0'