def init_reply_doublecheck(self, pkt): """Ask the network who has each IP address. Does more than one host respond?""" print "Initiating doublecheck. Asking who has each IP address..." self.reply_doublecheck_dict = {} ips = self.cd.mac_of.keys() # sanity if len(ips) < 2: return for ip in ips: if self.network is None: print "self.network is None, will error out..." # assemble ARP request params xswitch = pkt["switch"] xinport = pkt["inport"] # find valid IP address other than destination IP address srcip = ips[0] if ips[0] != ip else ips[1] srcmac = self.cd.get_mac_of(srcip) dstmac = "ff:ff:ff:ff:ff:ff" dstip = ip # send out each physical port self.query.register_callback(self.log_reply_doublecheck) for loc in self.network.topology.egress_locations(): switch = loc.switch outport = loc.port_no send_arp(REQUEST,self.network,switch,outport,srcip,srcmac,dstip,dstmac) # in one second, check self.check_thread = threading.Thread(target=self.check_reply_doublecheck, args=(pkt['srcip'],)) self.check_thread.daemon = True self.check_thread.start() return
def test_promiscuity(self): """Test if each host responds to ARP request sent to invalid MAC""" while True: INTERVAL = 10 time.sleep(INTERVAL) print "Conducting promiscuity check..." now = time.time() # prepare to catch promiscuous hosts # to do this, we will send an ARP packet from a made up host to # each known host that has an INCORRECT dstmac address. If # the host responds, we know that it is listening on traffic that # is not intended for it, i.e. it is promiscuous. # ref. Sahai 01 "Detection of Promiscuous Nodes Using ARP Packets" wrong_mac = 'ff:ff:ff:ff:ff:fe' ips = self.cd.mac_of.keys() # need at least 2 ips known to do this test if len(ips) < 2: print "Done." continue # pick random, unlikely mac key_mac = "77:77:77:77:77:77" self.policy = if_(match(dstmac=EthAddr(key_mac)), self.query, flood()) # send out each physical port for loc in self.network.topology.egress_locations(): switch = loc.switch outport = loc.port_no dstmac = self.cd.get_port_to_mac(switch, outport) if not dstmac: # no mac associated with this port continue dstip = next((k for k, v in self.cd.mac_of.items() if v == dstmac), None) if not dstip: # no ip associated with this mac continue # find valid IP address other than destination IP address key_ip = ips[0] if ips[0] != dstip else ips[1] send_arp(REQUEST,self.network,switch,outport, key_ip, key_mac, dstip, wrong_mac) # wait for test to complete and revert policy time.sleep(1) self.policy = flood() print "Done."
def init_request_doublecheck(self, pkt): """Send ARP request to suspicious host.""" # store suspect info self.suspect = (pkt["srcip"], pkt["srcmac"], pkt["inport"], pkt["switch"]) self.suspect_guilt = True self.query.register_callback(self.log_request_doublecheck) # assemble ARP request params switch = pkt["switch"] outport = pkt["inport"] srcip = pkt['dstip'] srcmac = self.cd.get_mac_of(srcip) dstmac = "ff:ff:ff:ff:ff:ff" dstip = pkt["srcip"] # send request send_arp(REQUEST,self.network,switch,outport,srcip,srcmac,dstip,dstmac) # issue thread to check self.check_thread2 = threading.Thread(target=self.check_request_doublecheck) self.check_thread2.daemon = True self.check_thread2.start() return