def setUp(self): """ """ import random #constants self.thisside = 0 self.thatside = 1 self.tcb = tcptest.tcb() self.tcb.ip = { self.thisside : pcs.inet_atol("10.211.55.210") , \ self.thatside : pcs.inet_atol("10.211.55.255")} self.tcb.ipid = { self.thisside : random.randrange(1,(1<<16)-1) , \ self.thatside : 0} self.tcb.tcpport = { self.thisside : random.randrange(50000,60000) , \ self.thatside : 9} self.tcb.tcpsequence = { self.thisside : random.randrange(1,(1<<32)-1),\ self.thatside : 0} self.tcb.ether = \ { self.thisside : ethernet.ether_atob("00:1c:42:9d:57:c9") , \ self.thatside : ethernet.ether_atob("00:1c:42:db:c5:22") } self.tcb.output = { self.thisside : pcs.PcapConnector("ed0") ,\ self.thatside : pcs.PcapConnector("ed0") }
def setUp(self): """ As it's the first test, I will use this method as a simple TCB. I'm planning use some object to handle that. In this version, TCB is being initialized with test setup values. Tcpdump file format would a form to store setup values. """ import random self.tcb = self #constants self.thisside = 0 self.thatside = 1 #...Can add other sides #opt 1 - this opt reduce the scalability, and bring more code. #self.ipsrc = pcs.inet_atol("192.168.1.10") #self.ipdst = pcs.inet_atol("192.168.1.20") #opt 2 self.ip = { self.thisside : pcs.inet_atol("10.211.55.210") , \ self.thatside : pcs.inet_atol("10.211.55.220")} self.ipid = { self.thisside : random.randrange(1,(1<<16)-1) , \ self.thatside : 0} self.tcpport = { self.thisside : random.randrange(50000,60000) , \ self.thatside : 9} self.tcpsequence = { self.thisside: random.randrange(1, (1 << 32) - 1), self.thatside: 0 } # see TODO self.ether = \ { self.thisside : ethernet.ether_atob("00:1c:42:9d:57:c9") , \ self.thatside : ethernet.ether_atob("00:1c:42:db:c5:22") } # see TODO self.output = { self.thisside : pcs.PcapConnector("ed0") ,\ self.thatside : pcs.PcapConnector("ed0") }
def test_dns_read(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface.""" file = pcs.PcapConnector("dns.out") packet = file.readpkt() ip = packet.data assert (ip != None) udp = ip.data dns = udp.data
def test03002parsePktList(self): self.pcr = PcapReplay.PcapReplay() self._createPcapFile() pktList = [] try: file = pcs.PcapConnector(self.tmpPcapFile) except Exception, e: self.fail('Parse Pkt List failed: %s' % str(e))
def main(): file = pcs.PcapConnector("fxp0") # First, build a chain and use it as a filter to match any IGMPv2 joins # seen on the network. m = ethernet.ethernet() / ipv4.ipv4() / \ igmp.igmp(type=IGMP_v2_HOST_MEMBERSHIP_REPORT) / igmpv2.igmpv2() t = 50 print "Waiting %d seconds to see an IGMPv2 report." % t try: file.expect([m], t) except pcs.TimeoutError: print "Timed out." sys.exit(1) # Now try it with a "contains" filter. # This will match any packet chain containing an IGMPv2 message. c = igmpv2.igmpv2() t = 50 print "Waiting %d seconds to see an IGMPv2 report using 'contains'." % t try: file.expect([c], t) except pcs.TimeoutError: print "Timed out." sys.exit(1) print "And the matching packet chain is:" print file.match # Define a match function to apply to a field. # We could really use some syntactic sugar for this... def contains_router_alert(lp, lf, rp, rf): for i in rf._options: if isinstance(i, pcs.TypeLengthValueField) and \ i.type.value == IPOPT_RA: return True return False # Create a "contains" filter consisting of a single IPv4 datagram # with a "Router Alert" option in the header. Strictly speaking the # option isn't needed, as above we define a function which is used # as a compare function for the option list field. c = ipv4.ipv4(options=[ipv4opt(IPOPT_RA)]) c.options.compare = contains_router_alert t = 50 print "Waiting %d seconds to see any IP packet containing a Router Alert option." % t try: file.expect([c], t) except pcs.TimeoutError: print "Timed out." sys.exit(1) print "And the matching packet chain is:" print file.match sys.exit(0)
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="file", default=None, help="pcap file to read from") (options, args) = parser.parse_args() file = pcs.PcapConnector(options.file) done = False data = None timestamp = None connection_map = {} in_network = 0 win_prev = 0 # Set up our signal handler global packets packets = 0 signal.signal(signal.SIGINFO, progress) while not done: try: (timestamp, data) = file.next() except: done = True packet = file.unpack(data, file.dlink, file.dloff, timestamp) packets += 1 if (packet.type != 0x800): continue ip = packet.data if (ip.protocol != IPPROTO_TCP): continue tcp = ip.data quad = (inet_ntop(AF_INET, struct.pack('!L', ip.src)), inet_ntop(AF_INET, struct.pack('!L', ip.dst)), tcp.sport, tcp.dport) if (quad not in connection_map): outfile = 'tcp-' + quad[0] + '-' + repr(quad[2]) + '-' +\ quad[1] + '-' + repr(quad[3]) + '.pcap' connection_map[quad] = pcs.PcapDumpConnector(outfile, file.dlink) connection_map[quad].write(data)
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-i", "--in", dest="infile", default=None, help="pcap file to read from") parser.add_option("-o", "--out", dest="outfile", default=None, help="pcap file to write to") parser.add_option("-f", "--first", dest="first", default=0, type=int, help="first packet to start at") parser.add_option("-l", "--last", dest="last", default=None, type=int, help="last packet to keep") (options, args) = parser.parse_args() infile = pcs.PcapConnector(options.infile) outfile = pcs.PcapDumpConnector(options.outfile, infile.dlink) first = options.first last = options.last done = False packets = 0 written = 0 while not done: try: packet = infile.read() except: done = True packets += 1 if packets < first: continue if packets >= last: done = True outfile.write(packet) written +=1 print "%d packets copied from %s to %s" % (written, options.infile, options.outfile)
def resetTcb(self, tcb): tcb.ip = { self.thisside : pcs.inet_atol("10.211.55.210") , \ self.thatside : pcs.inet_atol("10.211.55.220")} tcb.ipid = { self.thisside : random.randrange(1, (1<<16)-1) , \ self.thatside : 0} tcb.tcpport = { self.thisside : random.randrange(50000, 60000) , \ self.thatside : 9} tcb.tcpsequence = { self.thisside : random.randrange(1,(1<<32)-1),\ self.thatside : 0} tcb.ether = \ { self.thisside : ethernet.ether_atob("00:1c:42:9d:57:c9") , \ self.thatside : ethernet.ether_atob("00:1c:42:db:c5:22") } tcb.output = { self.thisside : pcs.PcapConnector("ed0") , \ self.thatside : pcs.PcapConnector("ed0") }
def rewrite(self, netInfo): r""" Rewrite the L{Flow} based on network information passed in. @param netInfo: NetworkInfo instance containing information about the server and client network interfaces """ # Get the flow packet re-written with network information rPkts = self.getReplayPktList(netInfo, pcs.PcapConnector(), pcs.PcapConnector(), True) # Unzip rewritten packets and create (seq, pkt) list seq, pktChain, iface = map(list, zip(*rPkts)) pkts = zip(seq, [p.packets[0] for p in pktChain]) # Flush current Flow information self.pkts = [] self.flk = None self.rfk = None # Add rewritten packets to the current Flow for p in pkts: self.addPacket(p)
def parsePcapFile(self, file): """ Parses the named pcap file and appends to the raw protocol packet lists @param file: The name of the capture file to be parsed """ pktList = [] # Attempt to read the capture file try: file = pcs.PcapConnector(file) except Exception, error: raise PcapReplayError(PcapReplayError.ERR_PCAPR_FILE, 'processPcapFile() : Error parsing "%s" : %s' % (file, error))
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-i", "--interface", dest="interface", default=None, help="Which interface to snarf from.") (options, args) = parser.parse_args() snarf = pcs.PcapConnector(options.interface) while 1: packet = ethernet(snarf.read()) print packet print packet.data
def test_dns_print(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface and tests the __str__ method to make sure the correct values are printed.""" file = pcs.PcapConnector("dns.out") packet = file.readpkt() ip = packet.data assert (ip != None) test_string = "UDP\nsport 50942\ndport 53\nlength 62\nchecksum 46791\n" udpv4 = ip.data string = udpv4.__str__() self.assertEqual( string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string))
def test_dns_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 = pcs.PcapConnector("dns.out") packet = file.readpkt() ip = packet.data assert (ip != None) udp1 = udpv4(ip.data.bytes) udp2 = udpv4(ip.data.bytes) assert (udp1 != None) assert (udp2 != None) self.assertEqual(udp1, udp2, "packets should be equal but are not") udp1.dport = 0xffff self.assertNotEqual( udp1, udp2, "packets compare equal but should not\ngot %sexpect %s" % (udp1, udp2))
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="file", default=None, help="File to read from.") parser.add_option("-n", "--natural", action="store_true", dest="natural", default=False, help="human readable time.") (options, args) = parser.parse_args() file = pcs.PcapConnector(options.file) packet = file.readpkt() while (packet != None): if packet.data == None: continue if packet.data.data == None: continue if packet.data.data.data != None: if (options.natural == True): ts = datetime.datetime.fromtimestamp( packet.data.data.timestamp) ms = ts.microsecond / 1000 msecond = ts.strftime("%H:%M:%S") msecond += (".%d") % ms print msecond else: print packet.data.data.timestamp print packet.data.data.data if packet.data.data.data.data != None: print packet.data.data.data.data packet = file.readpkt()
def main(): file = pcs.PcapConnector("fxp0") # Construct a filter chain. we are only interested in 3 fields. a = ethernet.ethernet() / arp.arp() a.wildcard_mask() a.packets[0].wildcard_mask(["type"], False) a.packets[1].wildcard_mask(["pro", "op"], False) a.packets[1].pro = 0x0800 # ETHERTYPE_IP (default) a.packets[1].op = 1 # ARPOP_REQUEST print "Waiting 10 seconds to see an ARP query." try: file.expect([a], 10) except pcs.TimeoutError: print "Timed out." sys.exit(1) print "And the matching packet chain is:" print file.match sys.exit(0)
def test_ptp_read(self): # read a ptp packet from a pcap capture file file = pcs.PcapConnector("ptp.out") packet = file.readpkt() print "Common" print packet.data.data.data print "Sync" print packet.data.data.data.data packet = file.readpkt() print "Delay Request" print packet.data.data.data print packet.data.data.data.data for i in range(0, 51): packet = file.readpkt() print "Follow Up" print packet.data.data.data print packet.data.data.data.data
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="file", default=None, help="pcap file to read from") parser.add_option("-m", "--max", dest="max", default=10, type=int, help="top N addresses to report") parser.add_option("-s", "--subnet-mask", dest="mask", default=None, help="subnetmask") parser.add_option("-n", "--network", dest="network", default=None, help="network we're looking at") (options, args) = parser.parse_args() file = pcs.PcapConnector(options.file) max = options.max mask = pcs.inet_atol(options.mask) network = pcs.inet_atol(options.network) done = False srcmap = {} packets = 0 in_network = 0 while not done: try: packet = file.readpkt() except: done = True packets += 1 ip = packet.data if (ip.src & mask) != network: if ip.src in srcmap: srcmap[ip.src] += 1 else: srcmap[ip.src] = 1 else: in_network +=1 print "%d packets in dumpfile" % packets print "%d unique source IPs" % len(srcmap) print "%d packets in specified network" % in_network print "Top %d source addresses were" % max hit_list = sorted(srcmap.itervalues(), reverse = True) for i in range(1,max): for addr in srcmap.items(): if addr[1] == hit_list[i]: print "Address %s\t Count %s\t Percentage %f" % (inet_ntop(AF_INET, struct.pack('!L', addr[0])), addr[1], (float(addr[1]) / float(packets)) * float(100))
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="file", default=None, help="pcap file to read from") parser.add_option( "-s", "--streams", dest="streams", default=False, help="print out streams in format easily consumed by other scripts") (options, args) = parser.parse_args() file = pcs.PcapConnector(options.file) done = False connection_map = [] packets = 0 in_network = 0 win_prev = 0 while not done: try: packet = file.readpkt() except: done = True packets += 1 if (packet.type != 0x800): continue ip = packet.data if (ip.protocol != IPPROTO_TCP): continue tcp = ip.data quad = (inet_ntop(AF_INET, struct.pack('!L', ip.src)), inet_ntop(AF_INET, struct.pack('!L', ip.dst)), tcp.sport, tcp.dport) if (quad in connection_map): continue connection_map.append(quad) if (options.streams == False): print "Analyzed %d packets, found %d connections:" % ( packets, len(connection_map)) for connection in connection_map: if (options.streams): print "-s %s -S %d -d %s -D %d" % (connection[0], connection[2], connection[1], connection[3]) else: print connection
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="file", default=None, help="tcpdump file to read from") (options, args) = parser.parse_args() file = pcs.PcapConnector(options.file) srcmap = {} packets = 0 ip_cnt = 0 non_ip_cnt = 0 tcp_cnt = 0 udp_cnt = 0 icmp_cnt = 0 arp_cnt = 0 done = False while not done: ip = None try: packet = file.read() except: done = True packets += 1 ether = ethernet(packet[0:len(packet)]) if type(ether.data) == pcs.packets.ipv4.ipv4: ip_cnt += 1 ip = ether.data else: non_ip_cnt += 1 if type(ether.data) == pcs.packets.arp.arp: arp_cnt += 1 if ip != None: if type(ip.data) == pcs.packets.icmpv4.icmpv4: icmp_cnt += 1 if type(ip.data) == pcs.packets.udp.udp: udp_cnt += 1 if type(ip.data) == pcs.packets.tcp.tcp: tcp_cnt += 1 if ip.src in srcmap: srcmap[ip.src] += 1 else: srcmap[ip.src] = 1 print "%d packets in dumpfile" % packets print "%d unique source IPs" % len(srcmap) print "%d ARP packets" % arp_cnt print "%d IPv4 packets" % ip_cnt print "%d ICMPv4 packets" % icmp_cnt print "%d UDP packets" % udp_cnt print "%d TCP packets" % tcp_cnt print "Top 10 source addresses were" hit_list = sorted(srcmap.itervalues(), reverse=True) for i in range(1, 10): for addr in srcmap.items(): if addr[1] == hit_list[i]: print "Address %s\t Count %s\t Percentage %f" % ( inet_ntop(AF_INET, struct.pack('!L', addr[0])), addr[1], (float(addr[1]) / float(packets)) * float(100))
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-y", "--ymin", dest="ymin", default="0", help="minimum y value") parser.add_option("-Y", "--ymax", dest="ymax", default="10", help="maximum y value") parser.add_option("-N", "--Names", dest="hosts", nargs=2, default=None, help="host list for sync graph") parser.add_option("-s", "--start", dest="start", type="int", default=0, help="starting sequence number") parser.add_option("-p", "--print", dest="png", default=None, help="print the graph to a file") parser.add_option("-d", "--debug", dest="debug", type="int", default=0, help="print debugging info (verbose)") (options, args) = parser.parse_args() files = [] for filename in options.hosts: pcap = pcs.PcapConnector(filename) trace = {} done = False while not done: try: packet = pcap.readpkt() except StopIteration: done = True except: raise # We only handle pcap files with Ethernet or RAW IP if type(packet) == ethernet: if packet.data == None: continue if packet.data.data == None: continue if type(packet.data.data) != icmpv4: continue icmp = packet.data.data elif type(packet) == ipv4: if type(packet.data) != icmpv4: continue icmp = packet.data else: continue if type(icmp.data) != icmpv4echo: continue if icmp.type != ICMP_ECHO: continue if ((icmp.data.sequence != 0) and (icmp.data.sequence < options.start)): continue trace[icmp.data.sequence] = datetime.datetime.fromtimestamp( packet.timestamp) files.append(trace) sequences = [] sequences.append(sorted(files[0].keys())) sequences.append(sorted(files[1].keys())) if ((min(sequences[0]) > max(sequences[1])) or (min(sequences[1]) > max(sequences[1]))): print "sequences do not overlap" sys.exit(1) # Trim the dictionaries of non overlapping elements index = 0 if ((min(sequences[0]) < min(sequences[1]))): start = min(sequences[0]) end = min(sequences[1]) index = 0 else: start = min(sequences[1]) end = min(sequences[0]) index = 1 for i in range(start, end): del files[index][i] if ((max(sequences[0]) > max(sequences[1]))): start = max(sequences[1]) end = max(sequences[0]) index = 0 else: start = max(sequences[0]) end = max(sequences[1]) index = 1 for i in range(start, end): del files[index][i] if options.start == 0: options.start = min(files[0].keys()) graph = [] minimum = datetime.timedelta.max maximum = datetime.timedelta.min for i in range(options.start, options.start + len(files[0])): try: delta = abs(files[1][i] - files[0][i]) except KeyError: print "9:99:99.000900" print "missing packet %d" % i continue if delta > maximum: maximum = delta if delta < minimum: minimum = delta if (options.debug != 0): print delta graph.append(delta.microseconds) print "min %s, max %s" % (minimum, maximum) if (minimum.seconds > 1): print "Time difference exceeded one second maximum, " \ "cannot graph differences" sys.exit(1) plotter = Gnuplot.Gnuplot(debug=1) # if ((options.ymin != 0) or (options.ymax != 10)): # plotter.set_range('yrange', [options.ymin, options.ymax]) plotter.ylabel('Time Offset\\nMicroseconds') plotter.xlabel('Sample Number') plotter.plot(graph) if (options.png != None): plotter.hardcopy(options.png + ".png", terminal='png') raw_input('Press return to exit') else: raw_input('Press return to exit')
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))
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="file", default=None, help="pcap file to read from") parser.add_option("-m", "--max", dest="max", default=10, type=int, help="top N addresses to report") parser.add_option("-s", "--source", dest="source", default=None, type=str, help="source IP address") parser.add_option("-d", "--dest", dest="dest", default=None, type=str, help="destination IP address") parser.add_option("-S", "--sport", dest="sport", default=None, type=int, help="source TCP port") parser.add_option("-D", "--dport", dest="dport", default=None, type=int, help="destination TCP port") parser.add_option("-g", "--graph", dest="graph", default=None, help="graph the window size changes over time") parser.add_option("-B", "--batch", dest="batch", default=False, help="create PNG graphs but do not display them") parser.add_option("-G", "--debug", dest="debug", default=0, help="debug gnuplot") (options, args) = parser.parse_args() file = pcs.PcapConnector(options.file) max = options.max source = pcs.inet_atol(options.source) dest = pcs.inet_atol(options.dest) done = False packets = 0 win_prev = 0 if (options.graph != None): tmpfile = tempfile.NamedTemporaryFile() plotter = Gnuplot.Gnuplot(debug=options.debug) plotter.xlabel('Packet #') plotter.ylabel('Window Size') while not done: try: packet = file.readpkt() except: done = True packets += 1 if (packet.type != 0x800): continue ip = packet.data if (ip.protocol != IPPROTO_TCP): continue if (ip.src != source): continue if (ip.dst != dest): continue tcp = ip.data if (tcp.sport != options.sport): continue if (tcp.dport != options.dport): continue if (win_prev == 0): win_prev = tcp.window elif (win_prev != tcp.window): if (options.graph): tmpfile.write("%s %s\n" % (packets, tcp.window)) else: print "Window size changed to %d at %d" % (tcp.window, packets) win_prev = tcp.window if (options.graph != None): if (options.batch != False): plotter('set terminal png') plotter('set output "' + options.graph + ".png") tmpfile.flush() plotter.plot(Gnuplot.File(tmpfile.name)) if (options.batch == False): raw_input('Press return to exit') else: time.sleep(1)