def test_tcpv4(self): """Create one packet, copy its bytes, then compare their fields""" tcppacket = tcp() assert (tcppacket != None) tcppacket.sport = 51 tcppacket.dport = 50 tcppacket.sequence = 42 tcppacket.offset = 10 tcppacket.urgent = 1 tcppacket.ack = 1 tcppacket.push = 1 tcppacket.reset = 1 tcppacket.syn = 1 tcppacket.fin = 1 tcppacket.window = 1024 tcppacket.checksum = 0 # Create a packet to compare against tcpnew = tcp() tcpnew.decode(tcppacket.bytes) self.assertEqual(tcppacket.bytes, tcpnew.bytes, "bytes not equal") for field in tcppacket._fieldnames: self.assertEqual(getattr(tcppacket, field), getattr(tcpnew, field), ("%s not equal" % field))
def test_tcpv4_compare(self): """Test the underlying __compare__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" file = PcapConnector("wwwtcp.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) tcp1 = tcp(ip.data.bytes) tcp2 = tcp(ip.data.bytes) assert (tcp1 != None) assert (tcp2 != None) #hd = hexdumper() #print hd.dump(tcp1.bytes) #print hd.dump(tcp2.bytes) # tcp1 should not equal tcp2, they are different instances, # and will therefore have different timestamps -- unless # we end up racing the system clock. self.assertNotEqual(tcp1, tcp2, "instances SHOULD be equal") self.assertEqual(tcp1.bytes, tcp2.bytes, "packet data SHOULD be equal") tcp1.dport = 0 self.assertNotEqual(tcp1.bytes, tcp2.bytes, "packet data SHOULD NOT be equal")
def test_tcpv4_read(self): """This test reads from a pre-stored pcap file generated with tcpdump.""" file = PcapConnector("wwwtcp.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) tcppacket = tcp(ip.data.bytes) self.assertEqual(tcppacket.sport, 53678, "source port not equal %d" % tcppacket.sport) self.assertEqual(tcppacket.dport, 80, "destination port not equal %d" % tcppacket.dport) self.assertEqual(tcppacket.sequence, 1351059655, "sequence number not equal %d" % tcppacket.sequence) self.assertEqual(tcppacket.ack_number, 0, "ack number not equal %d" % tcppacket.ack_number) self.assertEqual(tcppacket.offset, 11, "offset not equal %d" % tcppacket.offset) self.assertEqual(tcppacket.reserved, 0, "reserved not equal %d" % tcppacket.reserved) self.assertEqual(tcppacket.urgent, 0, "urgent not equal %d" % tcppacket.urgent) self.assertEqual(tcppacket.ack, 0, "ack not equal %d" % tcppacket.ack) self.assertEqual(tcppacket.push, 0, "push not equal %d" % tcppacket.push) self.assertEqual(tcppacket.reset, 0, "reset not equal %d" % tcppacket.reset) self.assertEqual(tcppacket.syn, 1, "syn not equal %d" % tcppacket.syn) self.assertEqual(tcppacket.fin, 0, "fin not equal %d" % tcppacket.fin) self.assertEqual(tcppacket.window, 65535, "window not equal %d" % tcppacket.window) self.assertEqual(tcppacket.checksum, 15295, "checksum not equal %d" % tcppacket.checksum)
def test_tcpv4_println(self): """Test the println method.""" file = PcapConnector("wwwtcp.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) tcppacket = tcp(ip.data.bytes) assert (tcppacket) # pre tcp options: #expected = "<TCP: sport: 53678, dport: 80, sequence: 1351059655, ack_number: 0, offset: 11, reserved: 0, urgent: 0, ack: 0, push: 0, reset: 0, syn: 1, fin: 0, window: 65535, checksum: 15295, urg_pointer: 0>" # post tcp options: # XXX println() uses __repr__(), not __str__(). the rules for the # game "python" say we have to preserve the structure of # objects returned by __repr__(). expected = "<TCP: sport: 53678, dport: 80, sequence: 1351059655, " \ "ack_number: 0, offset: 11, reserved: 0, " \ "ns: 0, cwr: 0, ece: 0, urgent: 0, " \ "ack: 0, push: 0, reset: 0, syn: 1, fin: 0, " \ "window: 65535, checksum: 15295, urg_pointer: 0, " \ "options: [" \ "[Field: mss, Value: " \ "<pcs.Field name v, 16 bits, " \ "default 1460, discriminator 0>], " \ "[Field: nop, Value: 1], " \ "[Field: wscale, Value: " \ "<pcs.Field name v, 8 bits, " \ "default 0, discriminator 0>], " \ "[Field: nop, Value: 1], " \ "[Field: nop, Value: 1], " \ "[Field: tstamp, Value: " \ "<pcs.Field name v, 64 bits, " \ "default 0, discriminator 0>], " \ "[Field: sackok, Value: " \ "<pcs.Field name v, 0 bits, " \ "default 0, discriminator 0>], " \ "[Field: end, Value: 0], " \ "[Field: end, Value: 0]" \ "]>" # unusual naming to make it easier to spot deltas in an # 80 column display. gotttted = tcppacket.println() self.assertEqual( expected, gotttted, "strings are not equal \nexpected %s \ngotttted %s " % (expected, gotttted))
def test_tcpv4_println(self): """Test the println method.""" file = PcapConnector("wwwtcp.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) tcppacket = tcp(ip.data.bytes) assert (tcppacket) # pre tcp options: #expected = "<TCP: sport: 53678, dport: 80, sequence: 1351059655, ack_number: 0, offset: 11, reserved: 0, urgent: 0, ack: 0, push: 0, reset: 0, syn: 1, fin: 0, window: 65535, checksum: 15295, urg_pointer: 0>" # post tcp options: # XXX println() uses __repr__(), not __str__(). the rules for the # game "python" say we have to preserve the structure of # objects returned by __repr__(). expected = "<TCP: sport: 53678, dport: 80, sequence: 1351059655, " \ "ack_number: 0, offset: 11, reserved: 0, " \ "ns: 0, cwr: 0, ece: 0, urgent: 0, " \ "ack: 0, push: 0, reset: 0, syn: 1, fin: 0, " \ "window: 65535, checksum: 15295, urg_pointer: 0, " \ "options: [" \ "[Field: mss, Value: " \ "<pcs.Field name v, 16 bits, " \ "default 1460, discriminator 0>], " \ "[Field: nop, Value: 1], " \ "[Field: wscale, Value: " \ "<pcs.Field name v, 8 bits, " \ "default 0, discriminator 0>], " \ "[Field: nop, Value: 1], " \ "[Field: nop, Value: 1], " \ "[Field: tstamp, Value: " \ "<pcs.Field name v, 64 bits, " \ "default 0, discriminator 0>], " \ "[Field: sackok, Value: " \ "<pcs.Field name v, 0 bits, " \ "default 0, discriminator 0>], " \ "[Field: end, Value: 0], " \ "[Field: end, Value: 0]" \ "]>" # unusual naming to make it easier to spot deltas in an # 80 column display. gotttted = tcppacket.println() self.assertEqual(expected, gotttted, "strings are not equal \nexpected %s \ngotttted %s " % (expected, gotttted))
def test_tcpv4_str(self): """Test the ___str__ method to make sure the correct values are printed.""" file = PcapConnector("wwwtcp.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) tcppacket = tcp(ip.data.bytes) assert (tcppacket) # pre tcp options: #expected = "TCP\nsport 53678\ndport 80\nsequence 1351059655\nack_number 0\noffset 11\nreserved 0\nns 0\ncwr 0\nece 0\nurgent 0\nack 0\npush 0\nreset 0\nsyn 1\nfin 0\nwindow 65535\nchecksum 15295\nurg_pointer 0\n" # post tcp options: expected = "TCP\nsport 53678\ndport 80\nsequence 1351059655\nack_number 0\noffset 11\nreserved 0\nns 0\ncwr 0\nece 0\nurgent 0\nack 0\npush 0\nreset 0\nsyn 1\nfin 0\nwindow 65535\nchecksum 15295\nurg_pointer 0\n" \ "options [" \ "[Field: mss, Value: " \ "<pcs.Field name v, 16 bits, " \ "default 1460, discriminator 0>], " \ "[Field: nop, Value: 1], " \ "[Field: wscale, Value: " \ "<pcs.Field name v, 8 bits, " \ "default 0, discriminator 0>], " \ "[Field: nop, Value: 1], " \ "[Field: nop, Value: 1], " \ "[Field: tstamp, Value: " \ "<pcs.Field name v, 64 bits, " \ "default 0, discriminator 0>], " \ "[Field: sackok, Value: " \ "<pcs.Field name v, 0 bits, " \ "default 0, discriminator 0>], " \ "[Field: end, Value: 0], " \ "[Field: end, Value: 0]" \ "]\n" gotttted = tcppacket.__str__() self.assertEqual( expected, gotttted, "strings are not equal \nexpected %s \ngotttted %s " % (expected, gotttted))
def test_tcpv4_offset_with_options(self): """Test the computed data offset field of the packet, with options""" tcppacket = tcp() tcppacket.offset = 0 nop = pcs.Field("nop", 8) mss = pcs.TypeLengthValueField("mss", pcs.Field("t", 8, default=0x02), pcs.Field("l", 8), pcs.Field("v", 16)) end = pcs.Field("end", 8) nop.value = 1 mss.value.value = 1460 # Most common Internet MSS value. # Build a TCP option list which will be 32-bits aligned. tcppacket.options.append(nop) tcppacket.options.append(nop) tcppacket.options.append(mss) tcppacket.options.append(nop) tcppacket.options.append(end) tcppacket.calc_length() self.assertEqual(tcppacket.offset, 7)
def createtcp(self, tcb, ip, from_, to): """Create tcp packet""" tcp1 = tcp.tcp() tcp1.sport = tcb.tcpport[from_] tcp1.dport = tcb.tcpport[to] tcp1.sequence = tcb.tcpsequence[from_] tcp1.ack_number = tcb.tcpsequence[to] tcp1.offset = 5 tcp1.urgent = 0 tcp1.ack = 1 tcp1.push = 0 tcp1.reset = 0 tcp1.syn = 0 tcp1.fin = 0 tcp1.window = (1 << 16) - 1 tcp1.urg_point = 0 #tcp1.options #tcp1.checksum = tcp_cksum(tcp1 , ip) #doind this at checkout(createwrite) return tcp1
def test_tcpv4_str(self): """Test the ___str__ method to make sure the correct values are printed.""" file = PcapConnector("wwwtcp.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) tcppacket = tcp(ip.data.bytes) assert (tcppacket) # pre tcp options: #expected = "TCP\nsport 53678\ndport 80\nsequence 1351059655\nack_number 0\noffset 11\nreserved 0\nns 0\ncwr 0\nece 0\nurgent 0\nack 0\npush 0\nreset 0\nsyn 1\nfin 0\nwindow 65535\nchecksum 15295\nurg_pointer 0\n" # post tcp options: expected = "TCP\nsport 53678\ndport 80\nsequence 1351059655\nack_number 0\noffset 11\nreserved 0\nns 0\ncwr 0\nece 0\nurgent 0\nack 0\npush 0\nreset 0\nsyn 1\nfin 0\nwindow 65535\nchecksum 15295\nurg_pointer 0\n" \ "options [" \ "[Field: mss, Value: " \ "<pcs.Field name v, 16 bits, " \ "default 1460, discriminator 0>], " \ "[Field: nop, Value: 1], " \ "[Field: wscale, Value: " \ "<pcs.Field name v, 8 bits, " \ "default 0, discriminator 0>], " \ "[Field: nop, Value: 1], " \ "[Field: nop, Value: 1], " \ "[Field: tstamp, Value: " \ "<pcs.Field name v, 64 bits, " \ "default 0, discriminator 0>], " \ "[Field: sackok, Value: " \ "<pcs.Field name v, 0 bits, " \ "default 0, discriminator 0>], " \ "[Field: end, Value: 0], " \ "[Field: end, Value: 0]" \ "]\n" gotttted = tcppacket.__str__() self.assertEqual(expected, gotttted, "strings are not equal \nexpected %s \ngotttted %s " % (expected, gotttted))
def test_tcpv4_offset_with_options(self): """Test the computed data offset field of the packet, with options""" tcppacket = tcp() tcppacket.offset = 0 nop = pcs.Field("nop", 8) mss = pcs.TypeLengthValueField("mss", pcs.Field("t", 8, default = 0x02), pcs.Field("l", 8), pcs.Field("v", 16)) end = pcs.Field("end", 8) nop.value = 1 mss.value.value = 1460 # Most common Internet MSS value. # Build a TCP option list which will be 32-bits aligned. tcppacket.options.append(nop) tcppacket.options.append(nop) tcppacket.options.append(mss) tcppacket.options.append(nop) tcppacket.options.append(end) tcppacket.calc_length() self.assertEqual(tcppacket.offset, 7)
def test_tcpv4_offset(self): """Test the computed data offset field of the packet, without options""" tcppacket = tcp() tcppacket.offset = 0 tcppacket.calc_length() self.assertEqual(tcppacket.offset, 5)
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-i", "--interface", dest="interface", default=None, help="Network interface to send on.") parser.add_option("-t", "--target", dest="ip_target", default=None, help="IPv4 target address to lookup.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="IPv4 source address to use.") parser.add_option("-d", "--ether_destination", dest="ether_destination", default=None, help="Ethernet destination address to use.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="Ethernet source address to use.") parser.add_option("-o", "--source-port", dest="source_port", default=None, help="Tcp source port.") parser.add_option("-x", "--destination-port", dest="destination_port", default=None, help="Tcp destination port.") (options, args) = parser.parse_args() import random ipid = random.randrange(1, (1 << 16) - 1) tcpsport = random.randrange(50000, 60000) #int(options.source_port ) tcpsequence = random.randrange(1, (1 << 32) - 1) output = pcs.PcapConnector(options.interface) replyip = None replytcp = None reply = None packet = None # SYN what = "SYN" ip1 = ipv4.ipv4() ip1.version = 4 ip1.hlen = 5 ip1.tos = 0 ip1.id = ++ipid ip1.flags = 0 ip1.offset = 0 ip1.ttl = 64 ip1.protocol = pcs.IPPROTO_TCP ip1.src = pcs.inet_atol(options.ip_source) ip1.dst = pcs.inet_atol(options.ip_target) tcp1 = tcp.tcp() tcp1.sport = tcpsport tcp1.dport = int(options.destination_port) tcp1.sequence = tcpsequence tcpsequence = tcpsequence + 1 # SYN consumes the sequence tcp1.ack_number = 0 tcp1.offset = 5 tcp1.urgent = 0 tcp1.ack = 0 tcp1.push = 0 tcp1.reset = 0 tcp1.syn = 1 tcp1.fin = 0 tcp1.window = (1 << 16) - 1 tcp1.urg_point = 0 #tcp1.options tcp1.checksum = tcp_cksum(tcp1, ip1) ip1.length = len(ip1.bytes) + len(tcp1.bytes) # important, only calcs the ip checksum after fill length field ip1.checksum = ip_cksum(ip1) ether1 = ethernet.ethernet() ether1.src = ethernet.ether_atob(options.ether_source) ether1.dst = ethernet.ether_atob(options.ether_destination) ether1.type = 0x800 packet = pcs.Chain([ether1, ip1, tcp1]) print "\n%s---------------------------------" % what print tcp1 print "---------------------------------" out = output.write(packet.bytes, len(packet.bytes)) ## SYN # SYN+ACK what = "SYN+ACK" while 1: reply = output.read() packet = ethernet.ethernet(reply) try: replyip = packet.data replytcp = replyip.data if (ip1.src==replyip.dst and \ ip1.dst==replyip.src and \ tcp1.sport==replytcp.dport and \ tcp1.dport==replytcp.sport): break except: #it cannot be a tcp packet (without sport:) pass print "\n%s---------------------------------" % what print packet.data.data print "---------------------------------" ## SYN+ACK # ACK 134,187 what = "ACK (SYN)" ip3 = ipv4.ipv4() ip3.version = 4 ip3.hlen = 5 ip3.tos = 0 ip3.id = ++ipid ip3.flags = 0 ip3.offset = 0 ip3.ttl = 64 ip3.protocol = pcs.IPPROTO_TCP ip3.src = pcs.inet_atol(options.ip_source) ip3.dst = pcs.inet_atol(options.ip_target) tcp3 = tcp.tcp() tcp3.sport = tcpsport tcp3.dport = int(options.destination_port) tcp3.sequence = tcpsequence ##tcpsequence = tcpsequence + 1 # ACK DOES NOT consumes the sequence tcp3.ack_number = replytcp.sequence + 1 tcp3.offset = 5 tcp3.urgent = 0 tcp3.ack = 1 tcp3.push = 0 tcp3.reset = 0 tcp3.syn = 0 tcp3.fin = 0 tcp3.window = (1 << 16) - 1 tcp3.urg_point = 0 #tcp3.options tcp3.checksum = tcp_cksum(tcp3, ip3) ip3.length = len(ip3.bytes) + len(tcp3.bytes) # important, only calcs the ip checksum after fill length field ip3.checksum = ip_cksum(ip3) ether3 = ethernet.ethernet() ether3.src = ethernet.ether_atob(options.ether_source) ether3.dst = ethernet.ether_atob(options.ether_destination) ether3.type = 0x800 packet = pcs.Chain([ether3, ip3, tcp3]) print "\n%s---------------------------------" % what print tcp3 print "---------------------------------" out = output.write(packet.bytes, len(packet.bytes)) ## ACK # FIN 188,241 what = "FIN" ip4 = ipv4.ipv4() ip4.version = 4 ip4.hlen = 5 ip4.tos = 0 ip4.id = ++ipid ip4.flags = 0 ip4.offset = 0 ip4.ttl = 64 ip4.protocol = pcs.IPPROTO_TCP ip4.src = pcs.inet_atol(options.ip_source) ip4.dst = pcs.inet_atol(options.ip_target) tcp4 = tcp.tcp() tcp4.sport = tcpsport tcp4.dport = int(options.destination_port) tcp4.sequence = tcpsequence tcpsequence = tcpsequence + 1 # FIN consumes the sequence tcp4.ack_number = replytcp.sequence + 1 tcp4.offset = 5 tcp4.urgent = 0 tcp4.ack = 1 tcp4.push = 0 tcp4.reset = 0 tcp4.syn = 0 tcp4.fin = 1 tcp4.window = (1 << 16) - 1 tcp4.urg_point = 0 #tcp4.options tcp4.checksum = tcp_cksum(tcp4, ip4) ip4.length = len(ip4.bytes) + len(tcp4.bytes) # important, only calcs the ip checksum after fill length field ip4.checksum = ip_cksum(ip4) ether4 = ethernet.ethernet() ether4.src = ethernet.ether_atob(options.ether_source) ether4.dst = ethernet.ether_atob(options.ether_destination) ether4.type = 0x800 packet = pcs.Chain([ether4, ip4, tcp4]) print "\n%s---------------------------------" % what print tcp4 print "---------------------------------" out = output.write(packet.bytes, len(packet.bytes)) ## FIN # ACK (FIN) what = "ACK (FIN)" while 1: reply = output.read() packet = ethernet.ethernet(reply) try: replyip = packet.data replytcp = replyip.data if (ip1.src==replyip.dst and \ ip1.dst==replyip.src and \ tcp1.sport==replytcp.dport and \ tcp1.dport==replytcp.sport): break except: #it cannot be a tcp packet (without sport:) pass print "\n%s---------------------------------" % what print packet.data.data print "---------------------------------" ## ACK (FIN) # FIN what = "FIN" while 1: reply = output.read() packet = ethernet.ethernet(reply) try: replyip = packet.data replytcp = replyip.data if (ip1.src==replyip.dst and \ ip1.dst==replyip.src and \ tcp1.sport==replytcp.dport and \ tcp1.dport==replytcp.sport): break except: #it cannot be a tcp packet (without sport:) pass print "\n%s---------------------------------" % what print packet.data.data print "---------------------------------" ## FIN # ACK (FIN) 288,341 what = "ACK (FIN)" ip7 = ipv4.ipv4() ip7.version = 4 ip7.hlen = 5 ip7.tos = 0 ip7.id = ++ipid ip7.flags = 0 ip7.offset = 0 ip7.ttl = 64 ip7.protocol = pcs.IPPROTO_TCP ip7.src = pcs.inet_atol(options.ip_source) ip7.dst = pcs.inet_atol(options.ip_target) tcp7 = tcp.tcp() tcp7.sport = tcpsport tcp7.dport = int(options.destination_port) tcp7.sequence = tcpsequence ##tcpsequence = tcpsequence + 1 # ACK DOES NOT consumes the sequence tcp7.ack_number = replytcp.sequence + 1 tcp7.offset = 5 tcp7.urgent = 0 tcp7.ack = 1 tcp7.push = 0 tcp7.reset = 0 tcp7.syn = 0 tcp7.fin = 0 tcp7.window = (1 << 16) - 1 tcp7.urg_point = 0 #tcp7.options tcp7.checksum = tcp_cksum(tcp7, ip7) ip7.length = len(ip7.bytes) + len(tcp7.bytes) # important, only calcs the ip checksum after fill length field ip7.checksum = ip_cksum(ip7) ether7 = ethernet.ethernet() ether7.src = ethernet.ether_atob(options.ether_source) ether7.dst = ethernet.ether_atob(options.ether_destination) ether7.type = 0x800 packet = pcs.Chain([ether7, ip7, tcp7]) print "\n%s---------------------------------" % what print tcp7 print "---------------------------------" out = output.write(packet.bytes, len(packet.bytes))