def printIcmpPacket(self, packet): pkt = headers.IcmpHeader() try: pkt.decode(packet) print("--------------------------------") print("ICMP Header") print("--------------------------------") print(str(pkt)) except RuntimeError: print("...cant print icmp, invalid type") finally: pass
def test_icmp(self): """Check IcmpHeader""" h1 = headers.IcmpHeader(TestHeaders.EtherIpIcmpHddr[34:]) h2 = headers.IcmpHeader() offset = h2.decode(TestHeaders.EtherIpIcmpHddr[34:]) self.assertEqual(offset, 64) self.assertEqual(str(h1), str(h2)) self.assertEqual( str(h1), r"""IcmpHeader: type=0 code=0 sum=26887 id=50522 seqNum=2 data=b']\xd1\x98\x7f\x00\x01\xf0F\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567'""" ) self.assertEqual(h1.type, 0) self.assertEqual(h1.code, 0) self.assertEqual(h1.sum, 26887) self.assertEqual(h1.id, 50522) self.assertEqual(h1.seqNum, 2) self.assertEqual( h1.data, b']\xd1\x98\x7f\x00\x01\xf0F\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567' ) self.assertEqual(len(h1.data), 56) h3 = headers.IcmpHeader( type=0, code=0, sum=26887, id=50522, seqNum=2, data= b']\xd1\x98\x7f\x00\x01\xf0F\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567' ) self.assertEqual(len(h3.encode()), 64) self.assertEqual(str(h1), str(h3)) self.assertEqual(h3.encode(), TestHeaders.EtherIpIcmpHddr[34:34 + 64])
def handleArpRequest(self): # add more params as needed ''' IMPLEMENT THIS METHOD This method should handle sending ARP requests if necessary. The high-level logic: if now - req->timeSent > seconds(1) if req->nTimesSent >= 5: send icmp host unreachable to source addr of all pkts waiting on this request cache.removeRequest(req) else: send arp request req->timeSent = now req->nTimesSent++ ''' if (time.localtime - self.timeSent) > 1: if self.nTimesSent >= 5: pkt = headers.IcmpHeader(code=1) buf = pkt.encode() pass
def echoIcmp(self, packet, iface): print("...Starting echo process") self.printEthPacket(packet) ethPkt = headers.EtherHeader() decodeLength = ethPkt.decode(packet) temp = ethPkt.dhost ethPkt.dhost = ethPkt.shost ethPkt.shost = temp ipPkt = headers.IpHeader() ipDecodeLength = ipPkt.decode(packet[decodeLength:]) temp = ipPkt.dst ipPkt.dst = ipPkt.src ipPkt.src = temp pkt = headers.IcmpHeader() icmpDecode = pkt.decode(packet[decodeLength + ipDecodeLength:]) if len(packet[decodeLength + ipDecodeLength + icmpDecode:]) > 0: pkt.type = 3 pkt.code = 3 else: pkt.type = 0 pkt.sum = 0 checksum = utils.checksum(pkt.encode()) pkt.sum = checksum #print (str(pkt)) #print(ethPkt.shost) buf = ethPkt.encode() + ipPkt.encode() + pkt.encode( ) + packet[decodeLength + ipDecodeLength + icmpDecode:] outface = self.findIfaceByMac(ethPkt.shost) self.printEthPacket(buf) print("...sending icmp packet through interface: " + str(outface.name)) #self.printEthPacket(buf) self.sendPacket(buf, outface.name)
def ipProcess(self, packet, iface): print("...started ipv4 process") ethPkt = headers.EtherHeader() decodeLength = ethPkt.decode(packet) ipPkt = headers.IpHeader() ipDecode = ipPkt.decode(packet[decodeLength:]) inface = self.findIfaceByIp(ipPkt.dst) if inface: self.echoIcmp(packet, inface) else: ipPkt.ttl = ipPkt.ttl - 1 ipPkt.sum = 0 checksum = utils.checksum(ipPkt.encode()) ipPkt.sum = checksum if ipPkt.ttl < 1: pkt = headers.IcmpHeader() #icmpDecode = pkt.decode(packet[decodeLength + ipDecode:]) pkt.type = 11 pkt.code = 0 checksum = utils.checksum(pkt.encode()) pkt.sum = checksum buf = ethPkt.encode() + ipPkt.encode() + pkt.encode( ) + packet[decodeLength + ipDecode:] outface = self.findIfaceByMac(ethPkt.dhost) self.sendPacket(buf, outface.name) if (self.arpCache.lookup(ipPkt.dst) != None): print("...looking for packet destination: " + str(ipPkt.dst)) print("...return from routing table lookup: " + str(self.routingTable.lookup(str(ipPkt.dst)))) if (self.routingTable.lookup(str(ipPkt.dst)) != None): print("...checking queue") while self.queue: queuePkt = self.queue.pop(0) print("--------------------------------") print("...processing queue packet:") self.printEthPacket(queuePkt) tempEth = headers.EtherHeader() tempDecodeLength = tempEth.decode(queuePkt) tempIpPkt = headers.IpHeader() tempIpDecode = tempIpPkt.decode( queuePkt[tempDecodeLength:]) tempIpPkt.ttl = tempIpPkt.ttl - 1 tempIpPkt.sum = 0 checksum = utils.checksum(tempIpPkt.encode()) tempIpPkt.sum = checksum inface = self.findIfaceByIp(tempIpPkt.dst) outface = self.routingTable.lookup(str(tempIpPkt.dst)) #self.printEthPacket(packet) tempEth.shost = self.findIfaceByName(outface).mac tempEth.dhost = self.arpCache.lookup(tempIpPkt.dst).mac outPkt = tempEth.encode() + tempIpPkt.encode( ) + queuePkt[tempDecodeLength + tempIpDecode:] #print("...out packet: ") #self.printEthPacket(outPkt) self.sendPacket(outPkt, outface) print("...queue is empty") outface = self.routingTable.lookup(str(ipPkt.dst)) #self.printEthPacket(packet) ethPkt.shost = self.findIfaceByName(outface).mac ethPkt.dhost = self.arpCache.lookup(ipPkt.dst).mac outPkt = ethPkt.encode() + ipPkt.encode( ) + packet[decodeLength + ipDecode:] #print("...out packet: ") #self.printEthPacket(outPkt) self.sendPacket(outPkt, outface) else: self.queue.append(packet) if len(self.queue) > 4: while self.queue: queuePkt = self.queue.pop(0) print("--------------------------------") print("...processing unreachable host queue packet:") self.printEthPacket(queuePkt) tempEth = headers.EtherHeader() tempDecodeLength = tempEth.decode(queuePkt) tempEth.dhost = tempEth.shost tempEth.shost = iface.mac tempIpPkt = headers.IpHeader() tempIpDecode = tempIpPkt.decode( queuePkt[tempDecodeLength:]) tempIpPkt.dst = tempIpPkt.src tempIpPkt.src = iface.ip tempIcmp = headers.IcmpHeader() tempIcmpDecode = tempIcmp.decode( queuePkt[tempDecodeLength + tempIpDecode:]) tempIcmp.type = 3 tempIcmp.code = 0 tempIcmp.sum = 0 checksum = utils.checksum(tempIcmp.encode()) tempIcmp.sum = checksum tempIpPkt.sum = 0 checksum = utils.checksum(tempIpPkt.encode()) tempIpPkt.sum = checksum outface = iface.name #self.printEthPacket(packet) outPkt = tempEth.encode() + tempIpPkt.encode( ) + tempIcmp.encode() + queuePkt[tempDecodeLength + tempIpDecode + tempIcmpDecode:] #print("...out packet: ") #self.printEthPacket(outPkt) self.printEthPacket(outPkt) self.sendPacket(outPkt, outface) else: for ifc in self.ifaces: if ifc.name != iface.name: searchArpPkt = headers.ArpHeader( hln=6, pln=4, op=1, sha=ifc.mac, sip=ifc.ip, tha="FF:FF:FF:FF:FF:FF", tip=ipPkt.dst) buf = searchArpPkt.encode() replyEthPkt = headers.EtherHeader( shost=ifc.mac, dhost="FF:FF:FF:FF:FF:FF", type=2054) buf = replyEthPkt.encode() + buf print("--------------------------------") print("...sending arp request to interface " + ifc.name) #self.printEthPacket(buf) self.sendPacket(buf, ifc.name) #while True: # if self.arpCache.lookup(pkt.dst) != None: # print("...looking for packet destination: " + str(pkt.dst)) # print("...return from routingtable lookup: " + str(self.routingTable.lookup(str(pkt.dst)))) # if(self.routingTable.lookup(str(pkt.dst)) != None): # outface = self.routingTable.lookup(str(pkt.dst)) # outmac = self.arpCache # #self.printEthPacket(packet) # ethPkt.shost = self.findIfaceByName(outface).mac # ethPkt.dhost = self.arpCache.lookup(pkt.dst).mac # outPkt = ethPkt.encode() + packet[decodeLength:] # #print("...out packet: ") # #self.printEthPacket(outPkt) # self.sendPacket(outPkt,outface) # break # # #if self.arpCache.lookup(pkt.dst) == None: # print ("Adding to cache" + str(self.arpCache.queueRequest(pkt.dst, pkt, iface))) # self.routingTable.lookup(str(pkt.dst)) #else: # print("Exists in the cache: " + str(self.arpCache.lookup(pkt.dst))) pass