def test_ethernet_eq(self): "Test whether the eq function works for ethernet" ether = ethernet() assert (ether != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 # Create a packet to compare against ethernew = ethernet() ethernew.decode(ether.bytes) self.assertEqual(ether.bytes, ethernew.bytes, "bytes not equal") self.assertEqual( ether.src, ethernew.src, "sources not equal ether %s ethernew %s" % (ether.src, ethernew.src)) self.assertEqual( ether.dst, ethernew.dst, "destinations not equal ether %s ethernew %s" % (ether.dst, ethernew.dst)) self.assertEqual( ether.type, ethernew.type, "types not equal ether %s ethernew %s" % (ether.type, ethernew.type)) self.assertEqual(ether, ethernew, "ether != to ethernew but should be")
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="target", default=None, help="IPv4 target address to lookup.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="Ethernet source address to use.") parser.add_option("-p", "--ip_source", dest="ip_source", default=None, help="IPv4 source address to use.") (options, args) = parser.parse_args() arppkt = arp() arppkt.op = 1 arppkt.sha = ether_atob(options.ether_source) arppkt.spa = inet_atol(options.ip_source) arppkt.tha = "\x00\x00\x00\00\x00\x00" arppkt.tpa = inet_atol(options.target) ether = ethernet() ether.src = ether_atob(options.ether_source) ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 0x806 packet = Chain([ether, arppkt]) output = PcapConnector(options.interface) out = output.write(packet.bytes, len(packet.bytes)) reply = output.read() reply = output.read() packet = ethernet(reply) print packet print packet.data
def test_ethernet_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("etherping.out") packet = file.read() ether1 = ethernet(packet[0:file.dloff]) ether2 = ethernet(packet[0:file.dloff]) assert (ether1 != None) assert (ether2 != None) self.assertEqual(ether1, ether2, "packets should be equal but are not") ether1.dst = "\xff\xff\xff\xff\xff\xff" self.assertNotEqual(ether1, ether2, "packets compare equal but should not")
def test_ethernet_dump(self): """This test dumps a fake ethernet packet, with timetamp, to a dump file.""" from pcs.pcap import DLT_EN10MB file = PcapDumpConnector("pcapdump2.out", DLT_EN10MB) # create one packet, copy its bytes, then compare their fields ether = ethernet() assert (ethernet != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 class header: sec = 0 usec = 0 caplen = 0 header.sec = 69 header.usec = 69 header.caplen = len(ether.bytes) file.sendto(ether.bytes, header) file.close() # Re read what we just wrote. file = PcapConnector("pcapdump2.out", DLT_EN10MB) ether = file.readpkt() assert(ether.timestamp == 69.000069)
def test_ethernet_dump(self): """This test dumps a fake ethernet packet, with timetamp, to a dump file.""" from pcs.pcap import DLT_EN10MB file = PcapDumpConnector("pcapdump2.out", DLT_EN10MB) # create one packet, copy its bytes, then compare their fields ether = ethernet() assert (ethernet != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 class header: sec = 0 usec = 0 caplen = 0 header.sec = 69 header.usec = 69 header.caplen = len(ether.bytes) file.sendto(ether.bytes, header) file.close() # Re read what we just wrote. file = PcapConnector("pcapdump2.out", DLT_EN10MB) ether = file.readpkt() assert (ether.timestamp == 69.000069)
def test_udpv4_raw(self): # Create a packet for raw injection and verify it meets criteria. from pcs import inet_atol from pcs.packets.payload import payload c = ethernet(src="\x01\x02\x03\x04\x05\x06", \ dst="\xff\xff\xff\xff\xff\xff") / \ ipv4(src=inet_atol("192.168.123.17"), \ dst=inet_atol("192.0.2.2"), id=5235) / \ udp(sport=67, dport=68) / \ payload("foobar\n") c.calc_lengths() c.calc_checksums() c.encode() expected = \ "\xFF\xFF\xFF\xFF\xFF\xFF\x01\x02" \ "\x03\x04\x05\x06\x08\x00\x45\x00" \ "\x00\x23\x14\x73\x00\x00\x40\x11" \ "\x68\x9B\xC0\xA8\x7B\x11\xC0\x00" \ "\x02\x02\x00\x43\x00\x44\x00\x0F" \ "\xC0\x48\x66\x6F\x6F\x62\x61\x72" \ "\x0A" gotttted = c.bytes self.assertEqual(expected, gotttted, "test raw encoding")
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group to spoof an IGMPv3 leave for.") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ip_source is None or \ options.igmp_group is None: print "Non-optional argument missing." return # Create an IGMPv3 change-to-include report for the given group # with no sources, which means we're leaving the group. # IGMPv3 Host Reports are always sent to IGMP.MCAST.NET (224.0.0.22), # and must always contain the Router Alert option. c = ethernet(src=ether_atob(options.ether_source), \ dst=ETHER_MAP_IP_MULTICAST(INADDR_ALLRPTS_GROUP)) / \ ipv4(src=inet_atol(options.ip_source), dst=INADDR_ALLRPTS_GROUP, \ ttl=1, flags=IP_DF, options=[ipvt4opt(IPOPT_RA)]) / \ igmp(type=IGMP_v3_HOST_MEMBERSHIP_REPORT) / \ igmpv3.report(records=[GroupRecordField("", \ group=inet_atol(options.igmp_group), \ type=IGMP_CHANGE_TO_INCLUDE)]) c.fixup() # Send it. output = PcapConnector(options.ether_iface) out = output.write(c.bytes, len(c.bytes))
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group to spoof a leave message for.") parser.add_option("-A", "--no-router-alert", action="store_true", dest="no_ra", help="Disable the use of the IP Router Alert option.") (options, args) = parser.parse_args() if options.igmp_group is None or \ options.ether_source is None or \ options.ether_iface is None or \ options.ip_source is None: print "A required argument is missing." return output = PcapConnector(options.ether_iface) c = ethernet(src=ether_atob(options.ether_source), \ dst=ETHER_MAP_IP_MULTICAST(INADDR_ALLRTRS_GROUP)) / \ ipv4(flags=IP_DF, id=123, ttl=1, \ src=inet_atol(options.ip_source), \ dst=INADDR_ALLRTRS_GROUP) / \ igmp(type=IGMP_HOST_LEAVE_MESSAGE) / \ igmpv2(group=inet_atol(options.igmp_group)) c.fixup() out = output.write(c.bytes, len(c.bytes))
def test_ethernet_write(self): """This test writes a fake ethernet packet to a dump file.""" from pcs.pcap import DLT_EN10MB file = PcapDumpConnector("etherdump.out", DLT_EN10MB) # create one packet, copy its bytes, then compare their fields ether = ethernet() assert (ethernet != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 file.write(ether.bytes)
def ICMPv6_pack_message(iface, pkt_type): #procedure to get iface address #iface = 'wlan2' #interface addrs = netifaces.ifaddresses(iface) ll_src_addr = addrs[netifaces.AF_INET6][1]['addr'] ll_src_addr = ll_src_addr[:ll_src_addr.find('%')] gl_src_addr = addrs[netifaces.AF_INET6][0]['addr'] #gl_src_addr = gl_src_addr[:gl_src_addr.find('%')] #print gl_src_addr #print ll_src_addr # building ethernet header e = ethernet() mac = netifaces.ifaddresses(iface)[netifaces.AF_LINK][0]['addr'] #geting mac addr e.src = ether_atob(mac) e.dst = ether_atob('ff:ff:ff:ff:ff:ff') e.type = 0x86dd #ETHERTYPE_IPV6 #building ipv6 packet basic info ip6 = ipv6() ip6.version = 6 #cs = icmp6.cksum(ip6) & 0xffff # building ipv6 header ip6.traffic_class = 0x0a ip6.flow = 0 ip6.length = 50 ip6.next_header = 58#IPPROTO_ICMPV6 ip6.hop = 255 ip6.src = pcs.inet_pton(AF_INET6, ll_src_addr) ip6.dst = pcs.inet_pton(AF_INET6, 'ff02::1') # building icmpv6 icmp6 = icmpv6(ICMP6_ECHO_REQUEST) #ICMP6_ECHO_REPLY icmp6.code = 0 icmp6.seq = 0 icmp6.id = 0x03e8 icmp6.checksum = 0x0 #kt.calc_checksums() data = payload(payload = gl_src_addr) #message data ip6.length = len(icmp6.getbytes()) + len(data) #recalculation of packet length if(pkt_type == 0): icmp6.cheksum = 0xf220 ip6.traffic_class = 0x0a pkt = pcs.Chain([e, ip6, icmp6, data]) #appendin packet else: icmp6.checksum = 0xe91b ip6.traffic_class = 0x0f pkt = pcs.Chain([e, ip6, icmp6]) #appendin packet #icmp6.checksum = pkt.calc_checksums() pkt.encode() #print pkt return pkt
def executeTrigger(self, pkt): """ Execute the trigger action the pkt which satisfies the trigger's action conditions. @param pkt: The packet against which a trigger is actioned @return: A trigger Chain for transmission, None if action is internal """ retChain = None # Action based on trigger type if self.action == Trigger.Trigger.STOP: # Test if pkt is really a HTTP packet (p, i) = pkt.chain().find_first_of(pcs.packets.http.httpResponse) if not p: self.logger.debug("HTTP trigger.STOP:\n%s" % pkt.chain()) raise PcapReplayError(Trigger.ERR_PCAPR_TRIGGER_INVALID, 'executeTrigger : Invalid trigger/pkt ' + 'pair execution') # Create a terminating response chain for xmit by the caller ether = pkt e = ethernet() e.dst = ether.src e.src = ether.dst e.type = ether.type ip = pkt.data if type(ip) == pcs.packets.ipv4.ipv4: i = ipv4() i.tos = ip.tos i.protocol = ip.protocol i.id = 0 i.flags = 0 elif type(ip) == pcs.packets.ipv6.ipv6: i = ipv6() i.traffic_class = ip.traffic_class i.next_header = ip.next_header i.src = ip.dst i.dst = ip.src tcp = pkt.data.data t = pcs.packets.tcp.tcp() t.sport = tcp.dport t.dport = tcp.sport t.reset = 1 t.ack = 1 t.ack_number = tcp.ack_number t.sequence = tcp.sequence t.data = None retChain = pcs.Chain([e, i, t]) retChain.fixup() return retChain
def test_ethernet(self): # create one packet, copy its bytes, then compare their fields ether = ethernet() assert (ethernet != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 # Create a packet to compare against ethernew = ethernet() ethernew.decode(ether.bytes) self.assertEqual(ether.bytes, ethernew.bytes, "bytes not equal") self.assertEqual(ether.src, ethernew.src, "sources not equal ether %s ethernew %s" % (ether.src, ethernew.src)) self.assertEqual(ether.dst, ethernew.dst, "destinations not equal ether %s ethernew %s" % (ether.dst, ethernew.dst)) self.assertEqual(ether.type, ethernew.type, "types not equal ether %s ethernew %s" % (ether.type, ethernew.type))
def test_ethernet_eq(self): "Test whether the eq function works for ethernet" ether = ethernet() assert (ether != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 # Create a packet to compare against ethernew = ethernet() ethernew.decode(ether.bytes) self.assertEqual(ether.bytes, ethernew.bytes, "bytes not equal") self.assertEqual(ether.src, ethernew.src, "sources not equal ether %s ethernew %s" % (ether.src, ethernew.src)) self.assertEqual(ether.dst, ethernew.dst, "destinations not equal ether %s ethernew %s" % (ether.dst, ethernew.dst)) self.assertEqual(ether.type, ethernew.type, "types not equal ether %s ethernew %s" % (ether.type, ethernew.type)) self.assertEqual(ether, ethernew, "ether != to ethernew but should be")
def test_ethernet_println(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on an ethernet interface and tests the println method to make sure the correct values are printed.""" file = PcapConnector("etherping.out") packet = file.read() ether = ethernet(packet[0:file.dloff]) assert (ether != None) string = ether.println() test_string = "<Ethernet: dst: 0:10:db:3a:3a:77 src: 0:d:93:44:fa:62 type: 0x800>" self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string))
def test_ethernet_println(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on an ethernet interface and tests the __str__ method to make sure the correct values are printed.""" file = PcapConnector("etherping.out") packet = file.read() ether = ethernet(packet[0:file.dloff]) assert (ether != None) test_string = "<Ethernet: dst: 0:10:db:3a:3a:77 src: 0:d:93:44:fa:62 type: 0x800>" string = ether.println() self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string))
def createIpv6Pkt(self, ipproto=6, layer1=None, layer2=None): e = ethernet() e.dst = self.dmac e.src = self.smac e.type = 0x86dd i = ipv6() i.next_header = ipproto i.src = self.src6 i.dst = self.dst6 e.data = i i.data = layer1 layer1.data = layer2 if layer2 == None: retChain = pcs.Chain([e, i, layer1]).packets[0] else: retChain = pcs.Chain([e, i, layer1, layer2]).packets[0] return retChain
def createIpv4Pkt(self, ipproto=6, layer1=None, layer2=None): e = ethernet() e.dst = self.dmac e.src = self.smac e.type = 0x0800 i = ipv4() i.protocol = ipproto i.id = 0 i.flags = 0 i.src = self.src i.dst = self.dst e.data = i i.data = layer1 layer1.data = layer2 if layer2 == None: retChain = pcs.Chain([e, i, layer1]).packets[0] else: retChain = pcs.Chain([e, i, layer1, layer2]).packets[0] return retChain
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-g", "--ether_dest", dest="ether_dest", default=None, help="The host Ethernet destination address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-D", "--ip_dest", dest="ip_dest", default=None, help="The IP destination address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group to query.") parser.add_option("-S", "--igmp_sources", dest="igmp_sources", default=None, help="Comma-delimited list of IPv4 sources for " "a group-and-source specific query.") parser.add_option("-M", "--igmp_maxresp", dest="igmp_maxresp", default=None, help="The maximum time for end-stations to " "respond (in seconds).") parser.add_option("-c", "--count", dest="count", default=None, help="Stop after receiving at least count responses.") parser.add_option("-2", "--igmp_v2_listen", action="store_true", dest="igmp_v2_listen", help="Listen for responses from IGMPv2 end-stations.") parser.add_option("-R", "--igmp_robustness", dest="igmp_robustness", default=None, help="Querier Robustness (default 2)") parser.add_option("-Q", "--igmp_qqic", dest="igmp_qqic", default=None, help="Querier's Query Interval (default 10s)") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ip_source is None or \ options.count is None: print "Non-optional argument missing." return #if options.ip_dest is not None and options.ether_dest is None: # print "Non-optional argument missing." # return maxresp = 10 * 10 if options.igmp_maxresp is not None: maxresp = int(options.igmp_maxresp) * 10 # in units of deciseconds # # Parse source list for a GSR query. # sources = [] if options.igmp_sources is not None: if options.igmp_group is None: raise "A group must be specified for a GSR query." else: for source in options.igmp_sources.split(','): sources.append(inet_atol(source)) if len(sources) == 0: raise "Error parsing source list." # Set up the vanilla packet if options.ether_dest is not None: edst = ether_atob(options.ether_dest) else: edst = ETHER_MAP_IP_MULTICAST(INADDR_ALLHOSTS_GROUP) c = ethernet(src=ether_atob(options.ether_source), dst=edst) / \ ipv4(flags=IP_DF, ttl=1, src=inet_atol(options.ip_source)) / \ igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) / \ igmpv3.query() ip = c.packets[1] q = c.packets[3] # IGMPv3 General Queries are always sent to ALL-SYSTEMS.MCAST.NET. # However we allow this to be overidden for protocol testing -- Windows, # in particular, doesn't seem to respond. # # We expect reports on 224.0.0.22. # Queries don't contain the Router Alert option as they are # destined for end stations, not routers. if options.igmp_robustness is not None: q.qrv = int(options.igmp_robustness) else: q.qrv = 2 # SHOULD NOT be 1, MUST NOT be 0 if options.igmp_qqic is not None: q.qqic = int(options.igmp_qqic) else: q.qqic = 10 # I query every 10 seconds if options.igmp_group is None: # General query. if options.ip_dest is not None: ip.dst = inet_atol(options.ip_dest) else: ip.dst = INADDR_ALLHOSTS_GROUP q.group = INADDR_ANY else: # Group-specific query, possibly with sources. if options.ip_dest is not None: ip.dst = inet_atol(options.ip_dest) else: ip.dst = inet_atol(options.igmp_group) q.group = ip.dst if IN_MULTICAST(ip.dst) is True and \ options.ether_dest is None: c.packets[0].dst = ETHER_MAP_IP_MULTICAST(ip.dst) for src in sources: q.sources.append(pcs.Field("", 32, default=src)) c.fixup() input = PcapConnector(options.ether_iface) input.setfilter("igmp") output = PcapConnector(options.ether_iface) out = output.write(c.bytes, len(c.bytes)) # # Wait for up to 'count' responses to the query to arrive and print them. # If options.igmp_v2_listen is True, also count responses from # end-stations which respond with IGMPv2. # # TODO: Pretty-print IGMPv3 reports. # count = int(options.count) while count > 0: packet = input.readpkt() chain = packet.chain() if ((chain.packets[2].type == IGMP_v3_HOST_MEMBERSHIP_REPORT) or ((chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT) and \ (options.igmp_v2_listen is True))): version = 3 if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT: version = 2 #print chain.packets[2].println() print "%s responded to query with IGMPv%d." % \ ((inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src))), version) count -= 1
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-c", "--count", dest="count", default=1, help="Stop after sending (and recieving) count ECHO_RESPONSE packets..") parser.add_option("-D", "--dont_fragment", dest="df", default=False, help="Set the Don't Fragment bit.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-d", "--ip_dest", dest="ip_dest", default=None, help="The IP destination address.") parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-g", "--ether_dest", dest="ether_dest", default=None, help="The gateway Ethernet destination address.") parser.add_option("-r", "--rt_hop", dest="hop", default="::", help="The intermediate router address.") (options, args) = parser.parse_args() rtcount = 1 # plen is 8 + rtcount * 16 for rt hdr, 8 for ICMP, 6 for foobar plen = 8 + rtcount * 16 + 8 + 6 c = ethernet(src=ether_atob(options.ether_source), \ dst=ether_atob(options.ether_dest)) / \ ipv6(hop=64, next_header = 43, length = plen, \ src=inet_pton(AF_INET6, options.ip_source), \ dst=inet_pton(AF_INET6, options.ip_dest)) / \ ipv6ext.rt_ext(next_header = 58, \ addr1 = inet_pton(AF_INET6, options.hop)) / \ icmpv6(type=ICMP6_ECHO_REQUEST, id=12345) / \ payload(payload="foobar") c.calc_lengths() # # Increment ICMP echo sequence number with each iteration. # output = PcapConnector(options.ether_iface) ip = c.packets[1] icmpecho = c.packets[3] count = int(options.count) while (count > 0): # c.calc_checksums() # icmpecho.cksum = icmpv6.cksum(icmpecho, ip) # icmpecho.calc_checksum() c.encode() out = output.write(c.bytes, len(c.bytes)) # packet = input.read() # print packet sleep(1) count -= 1 icmpecho.sequence += 1
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group for a group-specific query. " "If omitted, send a general query.") parser.add_option("-M", "--maxresp", dest="igmp_maxresp", default=None, help="The maximum time for end-stations to respond " "(in seconds).") parser.add_option("-c", "--count", dest="count", default=None, help="Stop after receiving at least count responses.") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ip_source is None or \ options.count is None: print "Non-optional argument missing." return maxresp = 3 * 10 if options.igmp_maxresp is not None: maxresp = int(options.igmp_maxresp) * 10 # in units of deciseconds if options.igmp_group is None: # General query. dst = INADDR_ALLHOSTS_GROUP group = INADDR_ANY else: # Group-specific query. dst = inet_atol(options.igmp_group) group = dst # Queries don't contain the Router Alert option as they are # destined for end stations, not routers. c = ethernet(src=ether_atob(options.ether_source), \ dst=ETHER_MAP_IP_MULTICAST(dst)) / \ ipv4(flags=IP_DF, ttl=1, \ src=inet_atol(options.ip_source), \ dst=dst) / \ igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) / \ igmpv2(group=group) c.fixup() input = PcapConnector(options.ether_iface) input.setfilter("igmp") output = PcapConnector(options.ether_iface) out = output.write(c.bytes, len(c.bytes)) # # Wait for up to 'count' responses to the query to arrive and print them. # count = int(options.count) while count > 0: packet = input.readpkt() chain = packet.chain() if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT: #print chain.packets[2].println() print "%s is in %s" % \ (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \ inet_ntop(AF_INET, struct.pack('!L', chain.packets[3].group))) count -= 1
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 test_stringfield(self): ether = ethernet() self.assertRaises(pcs.FieldBoundsError, setattr, ether, 'src', "\x00\x00\x00\x00\x00\x00\x00")
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-g", "--ether_dest", dest="ether_dest", default=None, help="The host Ethernet destination address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-D", "--ip_dest", dest="ip_dest", default=None, help="The IP destination address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group to query.") parser.add_option("-S", "--igmp_sources", dest="igmp_sources", default=None, help="Comma-delimited list of IPv4 sources for " "a group-and-source specific query.") parser.add_option("-M", "--igmp_maxresp", dest="igmp_maxresp", default=None, help="The maximum time for end-stations to " "respond (in seconds).") parser.add_option("-c", "--count", dest="count", default=None, help="Stop after receiving at least count responses.") parser.add_option("-2", "--igmp_v2_listen", action="store_true", dest="igmp_v2_listen", help="Listen for responses from IGMPv2 end-stations.") parser.add_option("-R", "--igmp_robustness", dest="igmp_robustness", default=None, help="Querier Robustness (default 2)") parser.add_option("-Q", "--igmp_qqic", dest="igmp_qqic", default=None, help="Querier's Query Interval (default 10s)") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ip_source is None or \ options.count is None: print "Non-optional argument missing." return #if options.ip_dest is not None and options.ether_dest is None: # print "Non-optional argument missing." # return maxresp = 10 * 10 if options.igmp_maxresp is not None: maxresp = int(options.igmp_maxresp) * 10 # in units of deciseconds # # Parse source list for a GSR query. # sources = [] if options.igmp_sources is not None: if options.igmp_group is None: raise "A group must be specified for a GSR query." else: for source in options.igmp_sources.split(','): sources.append(inet_atol(source)) if len(sources) == 0: raise "Error parsing source list." # Set up the vanilla packet if options.ether_dest is not None: edst = ether_atob(options.ether_dest) else: edst = ETHER_MAP_IP_MULTICAST(INADDR_ALLHOSTS_GROUP) c = ethernet(src=ether_atob(options.ether_source), dst=edst) / \ ipv4(flags=IP_DF, ttl=1, src=inet_atol(options.ip_source)) / \ igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) / \ igmpv3.query() ip = c.packets[1] q = c.packets[3] # IGMPv3 General Queries are always sent to ALL-SYSTEMS.MCAST.NET. # However we allow this to be overidden for protocol testing -- Windows, # in particular, doesn't seem to respond. # # We expect reports on 224.0.0.22. # Queries don't contain the Router Alert option as they are # destined for end stations, not routers. if options.igmp_robustness is not None: q.qrv = int(options.igmp_robustness) else: q.qrv = 2 # SHOULD NOT be 1, MUST NOT be 0 if options.igmp_qqic is not None: q.qqic = int(options.igmp_qqic) else: q.qqic = 10 # I query every 10 seconds if options.igmp_group is None: # General query. if options.ip_dest is not None: ip.dst = inet_atol(options.ip_dest) else: ip.dst = INADDR_ALLHOSTS_GROUP q.group = INADDR_ANY else: # Group-specific query, possibly with sources. if options.ip_dest is not None: ip.dst = inet_atol(options.ip_dest) else: ip.dst = inet_atol(options.igmp_group) q.group = ip.dst if IN_MULTICAST(ip.dst) is True and \ options.ether_dest is None: c.packets[0].dst = ETHER_MAP_IP_MULTICAST(ip.dst) for src in sources: q.sources.append(pcs.Field("", 32, default = src)) c.fixup() input = PcapConnector(options.ether_iface) input.setfilter("igmp") output = PcapConnector(options.ether_iface) out = output.write(c.bytes, len(c.bytes)) # # Wait for up to 'count' responses to the query to arrive and print them. # If options.igmp_v2_listen is True, also count responses from # end-stations which respond with IGMPv2. # # TODO: Pretty-print IGMPv3 reports. # count = int(options.count) while count > 0: packet = input.readpkt() chain = packet.chain() if ((chain.packets[2].type == IGMP_v3_HOST_MEMBERSHIP_REPORT) or ((chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT) and \ (options.igmp_v2_listen is True))): version = 3 if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT: version = 2 #print chain.packets[2].println() print "%s responded to query with IGMPv%d." % \ ((inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src))), version) count -= 1
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group for a group-specific query. " "If omitted, send a general query.") parser.add_option("-S", "--seconds", dest="seconds", default=1.0, help="Number of seconds between packets.") parser.add_option("-c", "--count", dest="count", default=None, help="Stop after sending count packets.") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ip_source is None or \ options.count is None: print "Non-optional argument missing." return maxresp = 3 * 10 if options.igmp_group is None: # General query. dst = INADDR_ALLHOSTS_GROUP group = INADDR_ANY else: # Group-specific query. dst = inet_atol(options.igmp_group) group = dst # Queries don't contain the Router Alert option as they are # destined for end stations, not routers. c = ethernet(src=ether_atob(options.ether_source), \ dst=ETHER_MAP_IP_MULTICAST(dst)) / \ ipv4(flags=IP_DF, ttl=1, \ src=inet_atol(options.ip_source), \ dst=dst) / \ igmp(type=IGMP_v2_HOST_MEMBERSHIP_REPORT, code=maxresp) / \ igmpv2(group=group) c.fixup() output = PcapConnector(options.ether_iface) # # Send count packets, delayed by seconds # count = int(options.count) if count < 0: count = sys.maxint while count > 0: out = output.write(c.bytes, len(c.bytes)) count -= 1 sleep(float(options.seconds))
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-G", "--ether_dest", dest="ether_dest", default=None, help="The gateway Ethernet destination address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-d", "--ip_dest", dest="ip_dest", default=None, help="The IP destination address.") parser.add_option("-c", "--count", dest="count", default=None, help="Stop after receiving at least count responses.") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ether_dest is None or \ options.ip_source is None or \ options.count is None: print "Non-optional argument missing." return if options.ip_dest is None: idst = INADDR_DVMRP_GROUP else: idst = inet_atol(options.ip_dest) c = ethernet(src=ether_atob(options.ether_source), \ dst=ether_atob(options.ether_dest)) / \ ipv4(ttl=1, src=inet_atol(options.ip_source), dst=idst) / \ igmp(type=IGMP_DVMRP, code=DVMRP_ASK_NEIGHBORS2) / \ dvmrp(capabilities=DVMRP_CAP_DEFAULT, minor=0xFF, major=3) # # DVMRP "ask neighbors" does not contain the Router Alert option, # because DVMRP traffic is usually tunneled, and we don't need to # wake up every router on the path. # # The Ask_neighbors2 payload is: reserved, caps, minor, major: # 0x00, 0E, 0xFF, 0x03 is how mrinfo fills this out (DVMRPv3 compliant). # # PIM itself knows nothing about these messages, however, a DVMRP router # which handles these messages MAY tell you if it's peering with other # PIM routers (I believe only Ciscos do this). # c.calc_lengths() c.calc_checksums() c.encode() input = PcapConnector(options.ether_iface) input.setfilter("igmp") output = PcapConnector(options.ether_iface) out = output.write(c.bytes, len(c.bytes)) # # Wait for up to 'count' responses to the query to arrive and print them. # count = int(options.count) while count > 0: packet = input.readpkt() chain = packet.chain() if chain.packets[2].type == IGMP_DVMRP: print chain.packets[2].println() #print "%s is in %s" % \ # (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \ # inet_ntop(AF_INET, struct.pack('!L', chain.packets[2].group))) count -= 1
class PcapReplayTestCase(PcapReplayTestBase): """ PcapReplay test cases """ def setUp(self): PcapReplayTestBase.setUp(self) self.tmpPcapFile = '/tmp/pcap.cap' self.pcr = None self.proto = UDP self.flowType = UdpFlow.UdpFlow self.sT = '172.16.0.20' self.dT = '10.2.1.11' self.src = NetworkInfo.netPToN(ipv4=self.sT) self.dst = NetworkInfo.netPToN(ipv4=self.dT) self.sport = 3565 self.dport = 53 self.proto6 = TCP self.flowType6 = TcpFlow.TcpFlow self.s6T = '2301::10:20:2:2' self.d6T = '2302::10:20:40:2' self.src6 = NetworkInfo.netPToN(ipv6=self.s6T) self.dst6 = NetworkInfo.netPToN(ipv6=self.d6T) self.sport6 = 1106 self.dport6 = 80 self.protoM = GENERIC self.flowTypeM = GenericFlow.GenericFlow self.msT = '0:c:29:f2:c8:a7' self.mdT = '0:1:6c:9e:73:7b' self.smac = NetworkInfo.macPToN(self.msT) self.dmac = NetworkInfo.macPToN(self.mdT) self.pcapDumpPktNum = 27 self.pcapDumpProtoPktNum = {ICMP: 2, TCP: 14, UDP: 4, GENERIC: 7} self.pcapDumpFlowNum = {ICMP: 1, TCP: 2, UDP: 2, GENERIC: 3} self.pcapDump = array.array('b', [ -44, -61, -78, -95, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 1, 0, 1, 0, 0, 0, 102, 35, 99, 60, -32, 4, 7, 0, 74, 0, 0, 0, 74, 0, 0, 0, 8, 0, 32, -94, -95, -94, 0, -112, 39, -3, 55, 71, 8, 0, 69, 0, 0, 60, 50, 29, 64, 0, 64, 6, -93, 82, -84, 16, 6, 100, -84, 16, 6, -56, 11, 54, 0, 80, -63, 127, 31, -15, 0, 0, 0, 0, -96, 2, 62, -68, 84, -105, 0, 0, 2, 4, 5, -76, 4, 2, 8, 10, 21, -95, 76, -49, 0, 0, 0, 0, 1, 3, 3, 0, 102, 35, 99, 60, -32, 4, 7, 0, 78, 0, 0, 0, 78, 0, 0, 0, 0, -112, 39, -3, 55, 71, 8, 0, 32, -94, -95, -94, 8, 0, 69, 0, 0, 64, -13, -18, 64, 0, -1, 6, 34, 124, -84, 16, 6, -56, -84, 16, 6, 100, 0, 80, 11, 54, 3, -67, 44, -16, -63, 127, 31, -14, -80, 18, 39, -104, 113, 35, 0, 0, 1, 1, 8, 10, 0, 0, -73, -45, 21, -95, 76, -49, 1, 3, 3, 0, 1, 1, 4, 2, 2, 4, 5, -76, 102, 35, 99, 60, -32, 4, 7, 0, 66, 0, 0, 0, 66, 0, 0, 0, 8, 0, 32, -94, -95, -94, 0, -112, 39, -3, 55, 71, 8, 0, 69, 0, 0, 52, 50, 30, 64, 0, 64, 6, -93, 89, -84, 16, 6, 100, -84, 16, 6, -56, 11, 54, 0, 80, -63, 127, 31, -14, 3, -67, 44, -15, -128, 16, 62, -68, -102, -54, 0, 0, 1, 1, 8, 10, 21, -95, 76, -49, 0, 0, -73, -45, 102, 35, 99, 60, -32, 4, 7, 0, 56, 1, 0, 0, 56, 1, 0, 0, 8, 0, 32, -94, -95, -94, 0, -112, 39, -3, 55, 71, 8, 0, 69, 0, 1, 42, 50, 31, 64, 0, 64, 6, -94, 98, -84, 16, 6, 100, -84, 16, 6, -56, 11, 54, 0, 80, -63, 127, 31, -14, 3, -67, 44, -15, -128, 24, 62, -68, -78, 62, 0, 0, 1, 1, 8, 10, 21, -95, 76, -49, 0, 0, -73, -45, 71, 69, 84, 32, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 10, 102, 35, 99, 60, -32, 4, 7, 0, 66, 0, 0, 0, 66, 0, 0, 0, 0, -112, 39, -3, 55, 71, 8, 0, 32, -94, -95, -94, 8, 0, 69, 0, 0, 52, -13, -17, 64, 0, -1, 6, 34, -121, -84, 16, 6, -56, -84, 16, 6, 100, 0, 80, 11, 54, 3, -67, 44, -15, -63, 127, 32, -24, -128, 16, 38, -94, -79, -18, 0, 0, 1, 1, 8, 10, 0, 0, -73, -45, 21, -95, 76, -49, 102, 35, 99, 60, -40, -108, 11, 0, 7, 3, 0, 0, 7, 3, 0, 0, 0, -112, 39, -3, 55, 71, 8, 0, 32, -94, -95, -94, 8, 0, 69, 0, 2, -7, -13, -16, 64, 0, -1, 6, 31, -63, -84, 16, 6, -56, -84, 16, 6, 100, 0, 80, 11, 54, 3, -67, 44, -15, -63, 127, 32, -24, -128, 24, 39, -104, 94, -78, 0, 0, 1, 1, 8, 10, 0, 0, -73, -43, 21, -95, 76, -49, 60, 104, 116, 109, 108, 62, 10, 60, 33, 45, 45, 116, 101, 115, 116, 32, 119, 101, 98, 32, 112, 97, 103, 101, 32, 102, 111, 114, 32, 82, 101, 100, 98, 97, 110, 107, 45, 62, 10, 60, 104, 101, 97, 100, 62, 10, 32, 32, 60, 116, 105, 116, 108, 101, 62, 82, 101, 100, 98, 97, 110, 107, 60, 47, 116, 105, 116, 108, 101, 62, 10, 32, 32, 60, 109, 101, 116, 97, 32, 110, 97, 109, 101, 61, 34, 100, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 99, 111, 110, 116, 101, 110, 116, 61, 34, 34, 62, 10, 32, 32, 60, 109, 101, 116, 97, 32, 110, 97, 109, 101, 61, 34, 107, 101, 121, 119, 111, 114, 100, 115, 34, 32, 99, 111, 110, 116, 101, 110, 116, 61, 34, 34, 62, 10, 60, 47, 104, 101, 97, 100, 62, 10, 60, 98, 111, 100, 121, 32, 98, 103, 99, 111, 108, 111, 114, 61, 34, 35, 48, 48, 48, 48, 48, 48, 34, 32, 116, 101, 120, 116, 61, 34, 35, 70, 70, 70, 70, 70, 70, 34, 32, 108, 105, 110, 107, 61, 34, 35, 51, 51, 54, 54, 70, 70, 34, 32, 118, 108, 105, 110, 107, 61, 34, 35, 48, 48, 67, 67, 70, 70, 34, 62, 10, 60, 112, 32, 97, 108, 105, 103, 110, 61, 34, 99, 101, 110, 116, 101, 114, 34, 62, 60, 102, 111, 110, 116, 32, 115, 105, 122, 101, 61, 34, 54, 34, 32, 102, 97, 99, 101, 61, 34, 65, 114, 105, 97, 108, 34, 62, 60, 98, 62, 60, 105, 62, 71, 114, 101, 101, 116, 105, 110, 103, 115, 44, 32, 97, 110, 100, 32, 119, 101, 108, 99, 111, 109, 101, 32, 116, 111, 32, 99, 114, 97, 99, 107, 32, 116, 111, 119, 110, 46, 60, 47, 105, 62, 60, 47, 98, 62, 60, 47, 102, 111, 110, 116, 62, 60, 47, 112, 62, 10, 60, 104, 114, 32, 97, 108, 105, 103, 110, 61, 34, 99, 101, 110, 116, 101, 114, 34, 32, 119, 105, 100, 116, 104, 61, 34, 56, 48, 37, 34, 32, 115, 105, 122, 101, 61, 34, 55, 34, 62, 10, 60, 112, 62, 84, 104, 105, 115, 32, 105, 115, 32, 82, 101, 100, 98, 97, 110, 107, 32, 111, 114, 32, 115, 111, 109, 101, 116, 104, 105, 110, 103, 60, 47, 112, 62, 10, 60, 112, 62, 72, 101, 114, 101, 32, 97, 114, 101, 32, 115, 111, 109, 101, 32, 116, 101, 115, 116, 32, 108, 105, 110, 107, 115, 58, 60, 47, 112, 62, 10, 60, 117, 108, 62, 10, 32, 32, 32, 32, 60, 108, 105, 62, 60, 97, 32, 104, 114, 101, 102, 61, 34, 116, 101, 115, 116, 49, 46, 104, 116, 109, 108, 34, 62, 74, 97, 121, 32, 97, 110, 100, 32, 66, 111, 98, 60, 47, 97, 62, 60, 47, 108, 105, 62, 10, 32, 32, 32, 32, 60, 108, 105, 62, 60, 97, 32, 104, 114, 101, 102, 61, 34, 102, 105, 108, 101, 112, 97, 114, 101, 110, 116, 46, 104, 116, 109, 108, 34, 62, 66, 97, 116, 116, 108, 101, 115, 116, 97, 114, 60, 47, 97, 62, 60, 47, 108, 105, 62, 10, 32, 32, 32, 32, 60, 108, 105, 62, 60, 97, 32, 104, 114, 101, 102, 61, 34, 104, 116, 100, 111, 99, 115, 47, 109, 97, 110, 117, 97, 108, 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 34, 62, 65, 112, 97, 99, 104, 101, 32, 68, 111, 99, 115, 60, 47, 97, 62, 60, 47, 108, 105, 62, 10, 60, 47, 117, 108, 62, 10, 10, 60, 105, 109, 103, 32, 115, 114, 99, 61, 34, 97, 112, 97, 99, 104, 101, 95, 112, 98, 46, 103, 105, 102, 34, 32, 119, 105, 100, 116, 104, 61, 34, 50, 53, 57, 34, 32, 104, 101, 105, 103, 104, 116, 61, 34, 51, 50, 34, 32, 97, 108, 116, 61, 34, 34, 32, 98, 111, 114, 100, 101, 114, 61, 34, 48, 34, 62, 10, 60, 47, 98, 111, 100, 121, 62, 10, 60, 47, 104, 116, 109, 108, 62, 10, 10, 102, 35, 99, 60, -40, -108, 11, 0, 66, 0, 0, 0, 66, 0, 0, 0, 8, 0, 32, -94, -95, -94, 0, -112, 39, -3, 55, 71, 8, 0, 69, 0, 0, 52, 50, 32, 64, 0, 64, 6, -93, 87, -84, 16, 6, 100, -84, 16, 6, -56, 11, 54, 0, 80, -63, 127, 32, -24, 3, -67, 47, -74, -128, 16, 59, -9, -103, -48, 0, 0, 1, 1, 8, 10, 21, -95, 76, -47, 0, 0, -73, -43, 102, 35, 99, 60, -40, -108, 11, 0, 66, 0, 0, 0, 66, 0, 0, 0, 0, -112, 39, -3, 55, 71, 8, 0, 32, -94, -95, -94, 8, 0, 69, 0, 0, 52, -13, -15, 64, 0, -1, 6, 34, -123, -84, 16, 6, -56, -84, 16, 6, 100, 0, 80, 11, 54, 3, -67, 47, -74, -63, 127, 32, -24, -128, 17, 39, -104, -82, 46, 0, 0, 1, 1, 8, 10, 0, 0, -73, -43, 21, -95, 76, -47, 102, 35, 99, 60, 112, -49, 11, 0, 66, 0, 0, 0, 66, 0, 0, 0, 8, 0, 32, -94, -95, -94, 0, -112, 39, -3, 55, 71, 8, 0, 69, 0, 0, 52, 50, 33, 64, 0, 64, 6, -93, 86, -84, 16, 6, 100, -84, 16, 6, -56, 11, 54, 0, 80, -63, 127, 32, -24, 3, -67, 47, -73, -128, 16, 62, -68, -105, 10, 0, 0, 1, 1, 8, 10, 21, -95, 76, -47, 0, 0, -73, -43, 102, 35, 99, 60, 112, -49, 11, 0, 66, 0, 0, 0, 66, 0, 0, 0, 8, 0, 32, -94, -95, -94, 0, -112, 39, -3, 55, 71, 8, 0, 69, 0, 0, 52, 50, 34, 64, 0, 64, 6, -93, 85, -84, 16, 6, 100, -84, 16, 6, -56, 11, 54, 0, 80, -63, 127, 32, -24, 3, -67, 47, -73, -128, 17, 62, -68, -105, 9, 0, 0, 1, 1, 8, 10, 21, -95, 76, -47, 0, 0, -73, -43, 102, 35, 99, 60, 112, -49, 11, 0, 66, 0, 0, 0, 66, 0, 0, 0, 0, -112, 39, -3, 55, 71, 8, 0, 32, -94, -95, -94, 8, 0, 69, 0, 0, 52, -13, -14, 64, 0, -1, 6, 34, -124, -84, 16, 6, -56, -84, 16, 6, 100, 0, 80, 11, 54, 3, -67, 47, -73, -63, 127, 32, -23, -128, 16, 39, -104, -82, 45, 0, 0, 1, 1, 8, 10, 0, 0, -73, -43, 21, -95, 76, -47, -83, -52, -58, 67, 15, -18, 2, 0, 72, 0, 0, 0, 72, 0, 0, 0, 0, 3, -97, -57, -80, 11, 0, 3, 71, -85, -13, -126, 8, 0, 69, 0, 0, 58, 44, -127, 0, 0, -128, 17, 87, 1, -84, 16, 0, 20, 10, 2, 1, 11, 13, -21, 0, 53, 0, 38, -48, 3, 46, 11, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 119, 119, 119, 4, 116, 101, 115, 116, 3, 110, 101, 116, 0, 0, 1, 0, 1, -83, -52, -58, 67, 100, -65, 3, 0, -91, 0, 0, 0, -91, 0, 0, 0, 0, 3, 71, -85, -13, -126, 0, 3, -97, -57, -80, 11, 8, 0, 69, 0, 0, -105, 57, -46, 64, 0, -2, 17, -117, 82, 10, 2, 1, 11, -84, 16, 0, 20, 0, 53, 13, -21, 0, -125, -19, -62, 46, 11, -127, -128, 0, 1, 0, 1, 0, 2, 0, 2, 3, 119, 119, 119, 4, 116, 101, 115, 116, 3, 110, 101, 116, 0, 0, 1, 0, 1, -64, 12, 0, 1, 0, 1, 0, 0, 0, 60, 0, 4, -57, -65, 1, 6, -64, 16, 0, 2, 0, 1, 0, 0, 0, 60, 0, 15, 3, 110, 115, 49, 8, 109, 105, 100, 109, 97, 105, 110, 101, -64, 21, -64, 16, 0, 2, 0, 1, 0, 0, 0, 60, 0, 6, 3, 110, 115, 50, -64, 62, -64, 58, 0, 1, 0, 1, 0, 0, -53, -113, 0, 4, -40, -36, -26, 24, -64, 85, 0, 1, 0, 1, 0, 0, -53, -113, 0, 4, -40, -36, -26, 25, -83, -52, -58, 67, -120, -56, 5, 0, 78, 0, 0, 0, 78, 0, 0, 0, 0, 3, -97, -57, -80, 11, 0, 3, 71, -85, -13, -126, 8, 0, 69, 0, 0, 64, 44, -121, 0, 0, -128, 17, 86, -11, -84, 16, 0, 20, 10, 2, 1, 11, 13, -19, 0, 53, 0, 44, -98, 51, 37, 8, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 119, 119, 119, 4, 117, 109, 99, 115, 5, 109, 97, 105, 110, 101, 3, 101, 100, 117, 0, 0, 1, 0, 1, -83, -52, -58, 67, -40, -31, 7, 0, -89, 0, 0, 0, -89, 0, 0, 0, 0, 3, 71, -85, -13, -126, 0, 3, -97, -57, -80, 11, 8, 0, 69, 0, 0, -103, 57, -45, 64, 0, -2, 17, -117, 79, 10, 2, 1, 11, -84, 16, 0, 20, 0, 53, 13, -19, 0, -123, -73, 92, 37, 8, -127, -128, 0, 1, 0, 2, 0, 2, 0, 1, 3, 119, 119, 119, 4, 117, 109, 99, 115, 5, 109, 97, 105, 110, 101, 3, 101, 100, 117, 0, 0, 1, 0, 1, -64, 12, 0, 5, 0, 1, 0, 1, 81, -128, 0, 10, 7, 71, 65, 78, 68, 65, 76, 70, -64, 16, -64, 48, 0, 1, 0, 1, 0, 1, 81, -128, 0, 4, -126, 111, 112, 21, -64, 16, 0, 2, 0, 1, 0, 0, 3, -24, 0, 9, 6, 103, 111, 108, 108, 117, 109, -64, 16, -64, 16, 0, 2, 0, 1, 0, 0, 3, -24, 0, 2, -64, 48, -64, 86, 0, 1, 0, 1, 0, 1, 81, -128, 0, 4, -126, 111, 112, 22, -104, 9, 31, 71, 39, -44, 3, 0, 42, 0, 0, 0, 42, 0, 0, 0, 0, 25, -86, -43, -59, 63, 0, 20, 108, -63, -90, 81, 8, 0, 69, 0, 0, 28, -100, 73, 0, 0, 64, 1, 15, 39, -84, 16, 67, -81, -84, 16, 51, -95, 8, 8, 77, -53, -86, 44, 0, 0, -104, 9, 31, 71, 60, -33, 3, 0, 60, 0, 0, 0, 60, 0, 0, 0, 0, 20, 108, -63, -90, 81, 0, 25, -86, -43, -59, 63, 8, 0, 69, 0, 0, 28, -74, -88, 0, 0, 127, 1, -75, -57, -84, 16, 51, -95, -84, 16, 67, -81, 0, 0, 85, -45, -86, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -73, -49, 51, 73, 119, 32, 1, 0, 42, 0, 0, 0, 42, 0, 0, 0, -1, -1, -1, -1, -1, -1, 0, 1, 108, -98, 115, 123, 8, 6, 0, 1, 8, 0, 6, 4, 0, 1, 0, 1, 108, -98, 115, 123, -84, 22, 6, 28, 0, 0, 0, 0, 0, 0, -84, 22, 6, -117, -73, -49, 51, 73, -120, 32, 1, 0, 42, 0, 0, 0, 42, 0, 0, 0, -1, -1, -1, -1, -1, -1, 0, 1, 108, -98, 115, 123, 8, 6, 0, 1, 8, 0, 6, 4, 0, 1, 0, 1, 108, -98, 115, 123, -84, 22, 6, 28, 0, 0, 0, 0, 0, 0, -84, 22, 6, -117, -73, -49, 51, 73, -120, 34, 1, 0, 106, 0, 0, 0, 106, 0, 0, 0, 0, 1, 108, -98, 115, 123, 0, 12, 41, -14, -56, -89, 8, 6, 0, 1, 8, 0, 6, 4, 0, 2, 0, 12, 41, -14, -56, -89, -84, 22, 6, -117, 0, 1, 108, -98, 115, 123, -84, 22, 6, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -73, -49, 51, 73, -105, 13, 9, 0, 60, 0, 0, 0, 60, 0, 0, 0, -1, -1, -1, -1, -1, -1, 0, 1, 108, -98, 115, -118, 8, 6, 0, 1, 8, 0, 6, 4, 0, 1, 0, 1, 108, -98, 115, -118, -84, 22, 6, 76, 0, 0, 0, 0, 0, 0, -84, 22, 6, -44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -69, -49, 51, 73, 13, -105, 12, 0, 106, 0, 0, 0, 106, 0, 0, 0, 0, 1, 108, -98, 115, 123, 0, 12, 41, -14, -56, -89, 8, 6, 0, 1, 8, 0, 6, 4, 0, 1, 0, 12, 41, -14, -56, -89, -84, 22, 6, -117, 0, 0, 0, 0, 0, 0, -84, 22, 6, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -69, -49, 51, 73, 25, -105, 12, 0, 42, 0, 0, 0, 42, 0, 0, 0, 0, 12, 41, -14, -56, -89, 0, 1, 108, -98, 115, 123, 8, 6, 0, 1, 8, 0, 6, 4, 0, 2, 0, 1, 108, -98, 115, 123, -84, 22, 6, 28, 0, 12, 41, -14, -56, -89, -84, 22, 6, -117, -69, -49, 51, 73, 35, -105, 12, 0, 42, 0, 0, 0, 42, 0, 0, 0, 0, 12, 41, -14, -56, -89, 0, 1, 108, -98, 115, 123, 8, 6, 0, 1, 8, 0, 6, 4, 0, 2, 0, 1, 108, -98, 115, 123, -84, 22, 6, 28, 0, 12, 41, -14, -56, -89, -84, 22, 6, -117, 31, 39, 118, 73, 81, -82, 10, 0, 82, 0, 0, 0, 82, 0, 0, 0, 0, 27, -44, 38, 49, 89, 0, 12, 41, -24, -67, -25, -122, -35, 96, 0, 0, 0, 0, 28, 6, 64, 35, 1, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 2, 0, 2, 35, 2, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 64, 0, 2, 4, 82, 0, 80, -69, 66, 1, -111, 0, 0, 0, 0, 112, 2, -6, -16, -128, 16, 0, 0, 2, 4, 5, -76, 1, 1, 4, 2, 31, 39, 118, 73, 120, -45, 10, 0, 82, 0, 0, 0, 82, 0, 0, 0, 0, 12, 41, -24, -67, -25, 0, 27, -44, 38, 49, 89, -122, -35, 96, 0, 0, 0, 0, 28, 6, 64, 35, 2, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 64, 0, 2, 35, 1, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 2, 0, 2, 0, 80, 4, 82, -65, 110, -32, -73, -69, 66, 1, -110, 112, 18, -6, -16, -33, -40, 0, 0, 2, 4, 5, -76, 1, 1, 4, 2, 31, 39, 118, 73, 86, -16, 10, 0, 80, 0, 0, 0, 80, 0, 0, 0, 0, 27, -44, 38, 49, 89, 0, 12, 41, -24, -67, -25, -122, -35, 96, 0, 0, 0, 0, 20, 6, 64, 35, 1, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 2, 0, 2, 35, 2, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 64, 0, 2, 4, 82, 0, 80, -69, 66, 1, -110, -65, 110, -32, -72, 80, 16, -6, -16, 12, -99, 0, 0, 0, 0, 0, 59, -1, 83 ]) def _createPcapFile(self): file = open(self.tmpPcapFile, mode='wb') self.pcapDump.tofile(file) file.close() def _deletePcapFile(self): if os.path.exists(self.tmpPcapFile): os.remove(self.tmpPcapFile) @enabletest def test03001create(self): self.pcr = PcapReplay.PcapReplay() self.assertEqual(self.pcr.flowlessTcpPkts, [], 'Create failed: flowlessTcpPkts not initialised') self.assertNotEqual(self.pcr.pktList, None, 'Create failed: pktList not initialised') for proto in self.pcr.pktList: self.assertEqual( self.pcr.pktList[proto], [], 'Create failed: pktList[%s] not initialised' % proto) self.assertNotEqual(self.pcr.flows, None, 'Create failed: flows not initialised') for proto in self.pcr.flows: self.assertEqual( self.pcr.flows[proto], {}, 'Create failed: flows[%s] not initialised' % proto) self.assertEqual(self.pcr.seqNum, 0, 'Create failed: seqNum not initialised') @enabletest 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)) while True: try: pkt = file.read() except: break ether = ethernet(pkt[0:len(pkt)]) pktList.append(ether) self.pcr.parsePacketList(pktList) self.assertEqual(self.pcr.seqNum, self.pcapDumpPktNum, 'Parse Pkt List failed: pktList incorrectly parsed') self.assertEqual(len(self.pcr.pktList[ICMP]), self.pcapDumpProtoPktNum[ICMP], 'Parse Pkt List failed: ICMP pkts not parsed') self.assertEqual(len(self.pcr.pktList[TCP]), self.pcapDumpProtoPktNum[TCP], 'Parse Pkt List failed: TCP pkts not parsed') self.assertEqual(len(self.pcr.pktList[UDP]), self.pcapDumpProtoPktNum[UDP], 'Parse Pkt List failed: UDP pkts not parsed') self.assertEqual(len(self.pcr.pktList[GENERIC]), self.pcapDumpProtoPktNum[GENERIC], 'Parse Pkt List failed: GENERIC pkts not parsed') self._deletePcapFile()
class PcapReplay(PcapReplayObject): """ PcapReplay contains all information and operatives that are associated with all TcpFlows contained within a give packet list. Beyond storage of these flows, this class provides the mechanisms associated with parsing a "raw" list of packets. """ ## # Constants ## # Class Fields ## # Methods def __init__(self, diagLevel=logging.ERROR): """ PcapReplay's constructor. @param diagLevel: The desired level of logging """ PcapReplayObject.__init__(self, diagLevel) self.flowlessTcpPkts = [] """A list of all flowless TCP packets""" self.pktList = {TCP: [], UDP: [], ICMP: [], GENERIC: []} """A map of all packets to protocol""" self.flows = {TCP: {}, UDP: {}, ICMP: {}, GENERIC: {}} """A map of all flows to protocol""" self.seqNum = 0 """Capture file ordered sequence number""" def parsePacketList(self, pktList): """ Parses a packet list and appends each packet to the appropriate protocol packet list @param pktList: The list of packets to be parsed """ # We are only interested in TCP, UDP and ICMP traffic for pkt in pktList: if (type(pkt.data) == pcs.packets.ipv4.ipv4 or type(pkt.data) == pcs.packets.ipv6.ipv6): ip = pkt.data if type(ip.data) == pcs.packets.tcp.tcp: self.pktList[TCP].append((self.seqNum, pkt)) elif type(ip.data) == pcs.packets.udp.udp: self.pktList[UDP].append((self.seqNum, pkt)) elif type(ip.data) == pcs.packets.icmpv4.icmpv4 or \ type(ip.data) == pcs.packets.icmpv6.icmpv6: self.pktList[ICMP].append((self.seqNum, pkt)) else: self.pktList[GENERIC].append((self.seqNum, pkt)) else: self.pktList[GENERIC].append((self.seqNum, pkt)) # Increment sequence self.seqNum += 1 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)) while True: # This is a hacky way of completing a read in the # absence of a true iterator try: pkt = file.read() except: break ether = ethernet(pkt[0:len(pkt)]) pktList.append(ether) self.parsePacketList(pktList)
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("-d", "--devname", dest="devname", default=None, help="The name of the tap device to open.") parser.add_option("-i", "--ifname", dest="ifname", default=None, help="The name of the interface to listen on.") parser.add_option("-g", "--group", dest="group", default=None, help="The IPv4 group to use for UML-style multicasts.") parser.add_option("-p", "--port", dest="port", default=None, help="The IPv4 port to use for UML-style multicasts.") parser.add_option("-a", "--ifaddr", dest="ifaddr", default=None, help="The IP address to listen on.") parser.add_option("-S", "--ether_source", dest="ether_source", default=None, help="The Ethernet address to listen on.") (options, args) = parser.parse_args() if options.devname is not None: input = TapConnector(options.devname) output = input elif options.group is not None: if options.port is None: print "Non-optional argument missing." return # XXX Currently, UmlMcast4Connector has to use the same broken # semantics as QEMU does, to see its traffic -- apps SHOULD be # joining groups on specific interfaces. # Note that we'll also end up seeing our own traffic. #input = UmlMcast4Connector(options.group, options.port, options.ifaddr) input = UmlMcast4Connector(options.group, options.port, "0.0.0.0") output = input elif options.ifname is not None: input = PcapConnector(options.ifname) output = PcapConnector(options.ifname) input.setfilter("udp port 67 or udp port 68") if options.ifaddr is None or \ options.ether_source is None: print "Non-optional argument missing." return ifaddr = inet_atol(options.ifaddr) ether_source = ether_atob(options.ether_source) ip_id = int(random.random() * 32768) # XXX Should really have an API for extracting our # local ethernet address. running = True while running is True: packet = input.readpkt() chain = packet.chain() # Must have: ether + ip + udp + dhcp. # UDP checksum ignored. Assume pcap filter above did its job. if len(chain.packets) < 4 or \ not isinstance(chain.packets[3], dhcpv4): continue i_ether = chain.packets[0] i_ip = chain.packets[1] i_udp = chain.packets[2] i_dhcp = chain.packets[3] # check dhcp htype is ethernet. # check if dhcp.cid in map. if i_dhcp.op != pcs.packets.dhcpv4.BOOTREQUEST or \ i_dhcp.htype != pcs.packets.dhcpv4.HTYPE_ETHER or \ i_dhcp.hlen != 6: continue #print i_dhcp chaddr_s = ether_btoa(i_dhcp.chaddr[:i_dhcp.hlen]) if not chaddr_s in map: print "%s not in map" % chaddr_s continue ciaddr = inet_atol(map[chaddr_s]) # from map dhcp = dhcpv4() dhcp.op = pcs.packets.dhcpv4.BOOTREPLY dhcp.htype = pcs.packets.dhcpv4.HTYPE_ETHER dhcp.hlen = 6 dhcp.hops = 0 dhcp.xid = i_dhcp.xid dhcp.flags = 0 #dhcp.ciaddr = ciaddr dhcp.siaddr = ifaddr # XXX should only fill out if i_dhcp.ciaddr was 0.0.0.0 dhcp.yiaddr = ciaddr dhcp.chaddr = i_dhcp.chaddr #dhcp.sname = "myhost" #dhcp.file = "/vmunix" #dhcp.options.append(dhcpv4_options.cookie().field()) # server ID. # XXX Weeiiird! #sid = dhcpv4_options.dhcp_server_identifier() #sid.value = ifaddr #sid.value = inet_atol("0.0.0.0") #dhcp.options.append(sid.field()) # Subnet mask. #sm = dhcpv4_options.subnet_mask() #sm.value = inet_atol("255.255.255.0") #dhcp.options.append(sm.field()) # Default gateway. #dg = dhcpv4_options.routers() #dg.value = ifaddr #dhcp.options.append(dg.field()) # Add end marker. #end = dhcpv4_options.end() #dhcp.options.append(end.field()) # Pad BOOTP payload to 32-bit width. # XXX BOOTP is problematic because the field which contains # the options needs to be clamped to 64 bytes in total. This # means we need to know the encoded length of each option. # For now, guess it... total length of an RFC-951 payload # is always 300 bytes. # this shuts up wireshark. #padlen = 300 - (len(dhcp.bytes) % 4) #padlen = 50 - (len(dhcp.bytes) % 4) #padlen = 4 #pad = dhcpv4_options.pad(padlen) #dhcp.options.append(pad.field()) # Encapsulate ethernet. ether = ethernet() ether.type = 0x0800 ether.src = ether_source ether.dst = i_dhcp.chaddr[:i_dhcp.hlen] # Encapsulate IPv4. ip = ipv4() ip.version = 4 ip.hlen = 5 ip.tos = 0 ip.id = ip_id ip.flags = 0x00 ip.offset = 0 ip.ttl = 1 ip.protocol = IPPROTO_UDP ip.src = ifaddr ip.dst = ciaddr ip_id += 1 # Encapsulate UDPv4. udp = udpv4() udp.sport = 67 udp.dport = 68 udp.length = len(dhcp.bytes) udp.checksum = udp.cksum(ip, dhcp.bytes) # Compute header checksums. ip.length = len(ip.bytes) + len(udp.bytes) + len(dhcp.bytes) ip.checksum = ip.cksum() # Send the lot. packet = Chain([ether, ip, udp, dhcp]) packet.encode() out = output.write(packet.bytes, len(packet.bytes)) print out
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-c", "--count", dest="count", default=1, help="Stop after sending (and recieving) count ECHO_RESPONSE packets..") parser.add_option("-D", "--dont_fragment", dest="df", default=False, help="Set the Don't Fragment bit.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-d", "--ip_dest", dest="ip_dest", default=None, help="The IP destination address.") parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-g", "--ether_dest", dest="ether_dest", default=None, help="The gateway Ethernet destination address.") (options, args) = parser.parse_args() c = ethernet(src=ether_atob(options.ether_source), \ dst=ether_atob(options.ether_dest)) / \ ipv4(ttl=64, src=inet_atol(options.ip_source), \ dst=inet_atol(options.ip_dest)) / \ icmpv4(type=8) / icmpv4echo(id=12345) / payload(payload="foobar") c.calc_lengths() # # Increment ICMP echo sequence number with each iteration. # output = PcapConnector(options.ether_iface) ip = c.packets[1] echo = c.packets[3] count = int(options.count) while (count > 0): c.calc_checksums() c.encode() out = output.write(c.bytes, len(c.bytes)) # packet = input.read() # print packet sleep(1) count -= 1 ip.id += 1 echo.sequence += 1
def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group for a group-specific query. " "If omitted, send a general query.") parser.add_option("-M", "--maxresp", dest="igmp_maxresp", default=None, help="The maximum time for end-stations to respond " "(in seconds).") parser.add_option("-l", "--host_list", dest="hostlist", action="append", help="List of hosts we expect responses from.") parser.add_option("-n", "--number", dest="number", default = 1, type=int, help="Query a number of groups starting at " "the one given by -G") parser.add_option("-c", "--count", dest="count", default=None, help="Stop after receiving at least count responses.") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ip_source is None or \ options.count is None: print "Non-optional argument missing." return maxresp = 3 * 10 if options.igmp_maxresp is not None: maxresp = int(options.igmp_maxresp) * 10 # in units of deciseconds if options.igmp_group is None: # General query. dst = INADDR_ALLHOSTS_GROUP group = INADDR_ANY else: # Group-specific query. dst = inet_atol(options.igmp_group) group = dst # Set up our match table global match match = {} for host in options.hostlist: for addr in range(group, group + options.number): match[(inet_atol(host), (addr))] = False signal.signal(signal.SIGINFO, results) while (options.number >= 0): # Queries don't contain the Router Alert option as they are # destined for end stations, not routers. c = ethernet(src=ether_atob(options.ether_source), \ dst=ETHER_MAP_IP_MULTICAST(dst)) / \ ipv4(flags=IP_DF, ttl=1, \ src=inet_atol(options.ip_source), \ dst=dst + options.number) / \ igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) / \ igmpv2(group=(group + options.number)) c.fixup() input = PcapConnector(options.ether_iface) input.setfilter("igmp") output = PcapConnector(options.ether_iface) out = output.write(c.bytes, len(c.bytes)) options.number -= 1 # # Wait for up to 'count' responses to the query to arrive and print them. # count = int(options.count) while count > 0: packet = input.readpkt() chain = packet.chain() if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT: #print chain.packets[2].println() # print "%s is in %s" % \ # (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \ # inet_ntop(AF_INET, struct.pack('!L', chain.packets[3].group))) match[(chain.packets[1].src, chain.packets[3].group)] = True count -= 1 results(0, 0)