def _handle_openflow_PacketIn (self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed global set_Timer global defendDDOS global blockPort timerSet =False global diction def preventing(): global diction global set_Timer if not set_Timer: set_Timer =True #Timer(1, _timer_func(), recurring=True) #print"\n\n*********new packetIN************" if len(diction) == 0: print("Enpty diction ",str(event.connection.dpid), str(event.port)) diction[event.connection.dpid] = {} diction[event.connection.dpid][event.port] = 1 elif event.connection.dpid not in diction: diction[event.connection.dpid] = {} diction[event.connection.dpid][event.port] = 1 #print "ERROR" else: if event.connection.dpid in diction: # temp = diction[event.connection.dpid] #print(temp) #print "error check " , str(diction[event.connection.dpid][event.port]) if event.port in diction[event.connection.dpid]: temp_count=0 temp_count =diction[event.connection.dpid][event.port] temp_count = temp_count+1 diction[event.connection.dpid][event.port]=temp_count #print "printting dpid port number and its packet count: ", str(event.connection.dpid), str(diction[event.connection.dpid]), str(diction[event.connection.dpid][event.port]) else: diction[event.connection.dpid][event.port] = 1 print "\n",datetime.datetime.now(gst), ": printing diction ",str(diction),"\n" def _timer_func (): global diction global set_Timer if set_Timer==True: #print datetime.datetime.now(),": calling timer fucntion now!!!!!" for k,v in diction.iteritems(): for i,j in v.iteritems(): if j >=50: print "_____________________________________________________________________________________________" print "\n",datetime.datetime.now(gst),"******* DDOS DETECTED ********" print "\n",str(diction) print "\n",datetime.datetime.now(gst),": BLOCKED PORT NUMBER : ", str(i), " OF SWITCH ID: ", str(k) print "\n_____________________________________________________________________________________________" #self.dropDDOS () dpid = k msg = of.ofp_packet_out(in_port=i) #msg.priority=42 #msg.in_port = event.port #po = of.ofp_packet_out(buffer_id = buffer_id, in_port = in_port) core.openflow.sendToDPID(dpid,msg) diction={} if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry(of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid,inport, packet.next.srcip,packet.next.dstip) ent_obj.statcolect(event.parsed.next.dstip)#editing print "\n***** Entropy Value = ",str(ent_obj.value),"*****\n" if ent_obj.value <0.5: preventing() if timerSet is not True: Timer(2, _timer_func, recurring=True) timerSet=False else: timerSet=False # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid,inport,packet.next.srcip) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = packet.next.srcip msg.match.dl_type = ethernet.IP_TYPE event.connection.send(msg) else: log.debug("%i %i learned %s", dpid,inport,packet.next.srcip) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) #nandan: getting source ip address from the packetIn #myPacketInSrcIP= packet.next.srcip #myPacketInSrcEth= packet.src #myPacketInDstIP= packet.next.dstip #myPacketInDstEth= packet.dst #print "switcID: "+str(dpid)+" ,Port: "+str(event.port)+" ,MAC address: "+str(myPacketInSrcEth)+" ,SrcIP: "+ str(myPacketInSrcIP)+", Dst Mac: "+str(myPacketInDstEth)+", Dst IP: "+str(myPacketInDstEth) # Try to forward dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning("%i %i not sending packet for %s back out of the " "input port" % (dpid, inport, dstaddr)) else: log.debug("%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port = prt)) if self.wide: match = of.ofp_match(dl_type = packet.type, nw_dst = dstaddr) else: match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) elif self.arp_for_unknowns: # We don't know this destination. # First, we track this buffer so that we can try to resend it later # if we learn the destination, second we ARP for the destination, # which should ultimately result in it responding and us learning # where it is # Add to tracked buffers if (dpid,dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid,dstaddr)] = [] bucket = self.lost_buffers[(dpid,dstaddr)] entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = {k:v for k,v in self.outstanding_arps.iteritems() if v > time.time()} # Check if we've already ARPed recently if (dpid,dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return # And ARP... self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid,inport,a.protosrc) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_dst = a.protosrc event.connection.send(msg) else: log.debug("%i %i learned %s", dpid,inport,a.protosrc) self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src) # Send any waiting packets... self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # We have an answer... if not self.arpTable[dpid][a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst)) msg = of.ofp_packet_out(in_port = inport, data = event.ofp, action = of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg)
data = f.readlines() #print (data) f.close() i=0 for line in data: columns=line.split() if (columns.__len__()==0): break serverList[i]={'ip':IPAddr(columns[0]), 'mac':EthAddr(columns[1]), 'port': int(columns[2])} #serverList[i]={'ip':columns[0], 'mac':columns[1], 'outport': columns[2]} print (serverList[i]) i=i+1 print (i) server_virtual_ip = IPAddr(virtual_ip) server_virtual_mac = EthAddr(virtual_mac) print (server_virtual_ip) print (server_virtual_mac) #Round Robin ServerUsed = 0 def _handle_PacketIn (event): #Round_Robin(event) global ServerUsed global server_virtual_ip global server_virtual_mac packet = event.parsed msg_to_server = of.ofp_flow_mod() msg_to_server.match = of.ofp_match.from_packet(packet)
def connect(self, connection): if connection is None: self.log.warn("Can't connect to nothing") return if self.dpid is None: self.dpid = connection.dpid assert self.dpid == connection.dpid if self.ports is None: self.ports = connection.features.ports self.disconnect() self.connection = connection self._listeners = self.listenTo(connection) self._connected_at = time.time() label = dpid_to_str(connection.dpid) self.log = log.getChild(label) self.log.debug("Connect %s" % (connection, )) if self._id is None: if self.dpid not in switches_by_id and self.dpid <= 254: self._id = self.dpid else: self._id = TopoSwitch._next_id TopoSwitch._next_id += 1 switches_by_id[self._id] = self self.network = IPAddr("10.%s.0.0" % (self._id, )) self.mac = dpid_to_mac(self.dpid) # Disable flooding con = connection log.debug("Disabling flooding for %i ports", len(con.ports)) for p in con.ports.itervalues(): if p.port_no >= of.OFPP_MAX: continue pm = of.ofp_port_mod(port_no=p.port_no, hw_addr=p.hw_addr, config=of.OFPPC_NO_FLOOD, mask=of.OFPPC_NO_FLOOD) con.send(pm) con.send(of.ofp_barrier_request()) con.send(of.ofp_features_request()) # Some of this is copied from DHCPD's __init__(). self.send_table() def fix_addr(addr, backup): if addr is None: return None if addr is (): return IPAddr(backup) return IPAddr(addr) self.ip_addr = IPAddr("10.%s.0.1" % (self._id, )) #self.router_addr = self.ip_addr self.router_addr = None self.dns_addr = None #fix_addr(dns_address, self.router_addr) self.subnet = IPAddr("255.0.0.0") self.pools = {} for p in connection.ports: if p < 0 or p >= of.OFPP_MAX: continue self.pools[p] = [ IPAddr("10.%s.%s.%s" % (self._id, p, n)) for n in range(1, 255) ] self.lease_time = 60 * 60 # An hour #TODO: Actually make them expire :) self.offers = {} # Eth -> IP we offered self.leases = {} # Eth -> IP we leased
def install_SDN_path(): #端口 转发 for p in path_did.keys(): #在第一层就返回的情况 if len(p) == 1: msg = of.ofp_flow_mod(match=monitor.match.clone()) msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = ( None, ) * 3 msg.match.tp_src = path_did[p] msg.match.in_port = adj[p[0]][monitor.dpid] msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[p[0]].connection.send(msg) else: # 到达第一层交换机 msg = of.ofp_flow_mod() msg.match = monitor.match.clone() msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = ( None, ) * 3 msg.match.tp_src = path_did[p] msg.match.in_port = adj[p[0]][monitor.dpid] msg.actions.append(of.ofp_action_output(port=adj[p[0]][p[1]])) switches[p[0]].connection.send(msg) #从第二层一直到底层的情况 for n in range(1, len(p)): if n < (len(p) - 1): msg = of.ofp_flow_mod() msg.match = monitor.match.clone() msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = ( None, ) * 3 msg.match.tp_src = path_did[p] msg.match.in_port = adj[p[n]][p[n - 1]] msg.actions.append( of.ofp_action_output(port=adj[p[n]][p[n + 1]])) switches[p[n]].connection.send(msg) else: msg = of.ofp_flow_mod() msg.match = monitor.match.clone() msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = ( None, ) * 3 msg.match.tp_src = path_did[p] msg.match.in_port = adj[p[n]][p[n - 1]] msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[p[n]].connection.send(msg) # 返回到一层的操作 for m in range((len(p) - 2), 0, -1): msg = of.ofp_flow_mod() msg.match = monitor.match.clone() msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = ( None, ) * 3 msg.match.tp_src = path_did[p] msg.match.in_port = adj[p[m]][p[m + 1]] msg.actions.append( of.ofp_action_output(port=adj[p[m]][p[m - 1]])) switches[p[m]].connection.send(msg) #返回到一层之后,返回到r24 msg = of.ofp_flow_mod() msg.match = monitor.match.clone() msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = ( None, ) * 3 msg.match.tp_src = path_did[p] msg.match.in_port = adj[p[0]][p[1]] msg.actions.append( of.ofp_action_output(port=adj[p[0]][monitor.dpid])) switches[p[0]].connection.send(msg) #在达到s24之后的处理 ''' msg = of.ofp_flow_mod() msg.match = monitor.match.clone() msg.match.nw_src=IPAddr('10.0.1.1') msg.match.tp_src = path_did[p] msg.match.in_port = adj[monitor.dpid][p[0]] msg.actions.append(of.ofp_action_nw_addr.set_dst(nw_addr=monitor.ip)) msg.actions.append(of.ofp_action_nw_addr.set_src(nw_addr=IPAddr('10.0.0.2'))) msg.actions.append(of.ofp_action_dl_addr.set_dst(dl_addr=monitor.hw)) msg.actions.append(of.ofp_action_dl_addr.set_src(dl_addr=EthAddr("00:00:00:00:00:02"))) msg.actions.append(of.ofp_action_output(port=monitor.switch_port)) switches[monitor.dpid].connection.send(msg) ''' ''' #根节点收到上面的probe后 for node in adj_path.keys(): msg = of.ofp_flow_mod(match=monitor.match.clone()) #匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = IPAddr('10.0.0.1') msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[node][monitor.dpid] #modify ip and 向下转发 msg.actions.append(of.ofp_action_nw_addr.set_src(nw_addr = switches_ip[node])) for nextnode in adj_path[node].keys(): msg.actions.append(of.ofp_action_output(port=adj[node][nextnode])) #修改udp_port,发送回r24 temp_path = [] temp_path.append(24) temp_path.append(node) temp_path = tuple(temp_path) msg.actions.append(of.ofp_action_tp_port.set_src(tp_port=path_id[temp_path])) msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[node].connection.send(msg) #第二层节点收到第一层的probe以后 for node in adj_path.keys(): for nextnode in adj_path[node].keys(): msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = switches_ip[node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[nextnode][node] # 向下转发 for lastnode in adj_path[node][nextnode]: msg.actions.append(of.ofp_action_output(port=adj[nextnode][lastnode])) #modify and send back temp_path = [] temp_path.append(24) temp_path.append(node) temp_path.append(nextnode) temp_path = tuple(temp_path) msg.actions.append(of.ofp_action_tp_port.set_src(tp_port=path_id[temp_path])) msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[nextnode].connection.send(msg) #第三层节点收到probe以后 for node in adj_path.keys(): for nextnode in adj_path[node].keys(): for lastnode in adj_path[node][nextnode]: msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = switches_ip[node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[lastnode][nextnode] #转发回去 temp_path = [] temp_path.append(24) temp_path.append(node) temp_path.append(nextnode) temp_path.append(lastnode) temp_path = tuple(temp_path) msg.actions.append(of.ofp_action_tp_port.set_src(tp_port=path_id[temp_path])) msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[lastnode].connection.send(msg) #第二层节点收到第三层的probe以后 for node in adj_path.keys(): for nextnode in adj_path[node].keys(): for lastnode in adj_path[node][nextnode]: msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = switches_ip[node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[nextnode][lastnode] #往上转发 msg.actions.append(of.ofp_action_output(port=adj[nextnode][node])) switches[nextnode].connection.send(msg) #第一层节点收到第二层的probe以后 for node in adj_path.keys(): for nextnode in adj_path[node].keys(): msg = of.ofp_flow_mod(match=monitor.match.clone()) msg.match.tp_dst, msg.match.tp_src = (None,) * 2 msg.match.nw_src = switches_ip[node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[node][nextnode] #往上转发 msg.actions.append(of.ofp_action_output(port=adj[node][monitor.dpid])) switches[node].connection.send(msg) log.debug('monitor num') ''' for node in adj_path.keys(): msg = of.ofp_flow_mod() msg.match = monitor.match.clone() #匹配 msg.match.nw_src, msg.match.tp_dst, msg.match.tp_src, msg.match.nw_dst = ( None, ) * 4 #msg.match.nw_src = IPAddr('10.0.0.1') #msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[monitor.dpid][node] #修改IP # msg.actions.append(of.ofp_action_nw_addr.set_dst(nw_addr = IPAddr('10.0.0.2'))) # msg.actions.append(of.ofp_action_dl_addr.set_dst(dl_addr = EthAddr("00:00:00:00:00:02"))) # msg.actions.append(of.ofp_action_dl_addr.set_dst(dl_addr = EthAddr("00:00:00:00:00:02"))) #向上转发 msg.actions.append( of.ofp_action_nw_addr.set_dst(nw_addr=monitor.ip)) msg.actions.append( of.ofp_action_nw_addr.set_src(nw_addr=IPAddr('10.0.0.2'))) msg.actions.append( of.ofp_action_dl_addr.set_dst(dl_addr=monitor.hw)) msg.actions.append( of.ofp_action_dl_addr.set_src( dl_addr=EthAddr("00:00:00:00:00:02"))) msg.actions.append(of.ofp_action_output(port=monitor.switch_port)) switches[monitor.dpid].connection.send(msg) ''' msg = of.ofp_flow_mod() msg.match = monitor.match.clone() #匹配h1 msg.match.tp_dst= None msg.match.nw_src = IPAddr('10.0.0.1') msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.tp_src = 9999 msg.match.in_port = monitor.switch_port print monitor.switch_port #转发 for node in adj_path.keys(): msg.actions.append(of.ofp_action_output(port=adj[monitor.dpid][node])) switches[monitor.dpid].connection.send(msg) ''' #r24收到h1的probe后(除去操作时延) for p in path_did.keys(): msg = of.ofp_flow_mod() msg.match = monitor.match.clone() msg.match.tp_dst, msg.match.nw_src, msg.match.nw_dst = (None, ) * 3 msg.match.in_port = monitor.switch_port msg.match.tp_src = path_did[p] msg.actions.append( of.ofp_action_nw_addr.set_src(nw_addr=IPAddr('10.0.1.2'))) msg.actions.append( of.ofp_action_output(port=adj[monitor.dpid][p[0]])) switches[monitor.dpid].connection.send(msg)
def _handle_openflow_PacketIn(self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed log.warning("Inho #5168 : %s %s ", type(dpid), dpid) if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry( of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip, packet.next.dstip) # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, packet.next.srcip) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = packet.next.srcip msg.match.dl_type = ethernet.IP_TYPE event.connection.send(msg) else: log.debug("%i %i learned %s", dpid, inport, packet.next.srcip) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) # Try to forward dstaddr = packet.next.dstip if dstaddr not in self.arpTable[dpid]: if packet.next.srcip == IPAddr("10.0.0.1"): self.arpTable[dpid][packet.next.dstip] = Entry( inport, packet.src) self.arpTable[dpid][packet.next.dstip].mac = EthAddr( "32:d5:a3:be:19:77") else: self.arpTable[dpid][packet.next.dstip] = Entry( inport, packet.src) self.arpTable[dpid][packet.next.dstip].mac = EthAddr( "08:00:27:2a:87:c3") if packet.next.protocol == ipv4.TCP_PROTOCOL: if packet.next.dstip == "10.0.0.1": e = pkt.ethernet() e.src = EthAddr(packet.src) e.dst = self.arpTable[dpid][dstaddr].mac e.type = e.IP_TYPE tcpp = pkt.tcp() tcpp.srcport = packet.next.payload.srcport #packet.next.payload = tcpp, packet.next = ip, packet = E tcpp.dstport = packet.next.payload.dstport tcpp.seq = packet.next.payload.seq tcpp.ack = packet.next.payload.ack tcpp.win = 29200 tcpp.SYN = True #send SYN tcpp.ACK = False tcp = pkt.ipv4() tcp.protocol = tcp.TCP_PROTOCOL tcp.srcip = packet.next.srcip tcp.dstip = packet.next.dstip tcp.payload = tcpp e.payload = tcp msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) print(e.dst) print(packet.next.dstip) if packet.next.protocol == ipv4.ICMP_PROTOCOL: e = pkt.ethernet() e.src = self.arpTable[dpid][dstaddr].mac e.dst = EthAddr(packet.src) e.type = e.IP_TYPE ipp = pkt.ipv4() ipp.protocol = ipp.ICMP_PROTOCOL ipp.srcip = packet.next.dstip print(ipp.srcip) ipp.dstip = packet.next.srcip icmp = pkt.icmp() icmp.type = pkt.ICMP.TYPE_ECHO_REPLY icmp.payload = packet.next.payload.payload #copy the ping payload of the packet that they receive ipp.payload = icmp e.payload = ipp msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return if packet.next.protocol == ipv4.TCP_PROTOCOL and packet.next.dstip != "10.0.0.1": if packet.next.payload.SYN and not packet.next.payload.ACK: #this is to send SYN, ACK print "SYN packet", packet.next.payload e = pkt.ethernet() e.src = self.arpTable[dpid][dstaddr].mac e.dst = EthAddr(packet.src) e.type = e.IP_TYPE tcpp = pkt.tcp() tcpp.srcport = packet.next.payload.dstport #packet.next.payload = tcpp, packet.next = ip, packet = E tcpp.dstport = packet.next.payload.srcport tcpp.seq = 0 tcpp.ack = packet.next.payload.seq + 1 tcpp.win = 29200 tcpp.SYN = True #send SYN tcpp.ACK = True #send ACK tcp = pkt.ipv4() tcp.protocol = tcp.TCP_PROTOCOL tcp.srcip = packet.next.dstip tcp.dstip = packet.next.srcip tcp.payload = tcpp e.payload = tcp msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) time.sleep(0.15) e = pkt2.ethernet() e.src = self.arpTable[dpid][dstaddr].mac e.dst = EthAddr(packet.src) e.type = e.IP_TYPE tcpp = pkt2.tcp() tcpp.srcport = packet.next.payload.dstport tcpp.dstport = packet.next.payload.srcport #print(packet.next.payload.ack) tcpp.seq = 1 tcpp.ack = packet.next.payload.seq + 127 tcpp.win = 29200 tcpp.PSH = True #send PSH tcpp.ACK = True #send ACK tcpp.payload = makeMessage( magic, "version", makeVersionPayload(str(packet.next.dstip), str(packet.next.srcip))) tcp = pkt2.ipv4() tcp.protocol = tcp.TCP_PROTOCOL tcp.srcip = packet.next.dstip tcp.dstip = packet.next.srcip tcp.payload = tcpp e.payload = tcp print "*****" msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return # if not packet.next.payload.SYN and packet.next.payload.ACK: # print "ACK packet", packet.next.payload # e = pkt.ethernet() # e.src = self.arpTable[dpid][dstaddr].mac # e.dst = EthAddr(packet.src) # e.type = e.IP_TYPE # tcpp = pkt.tcp() # tcpp.srcport = packet.next.payload.dstport # tcpp.dstport = packet.next.payload.srcport # # tcpp.seq = 1 # will be random # tcpp.ack = packet.next.payload.ack+1 # # tcpp.SYN = True # tcpp.ACK = True # tcp = pkt.ipv4() # tcp.protocol = tcp.TCP_PROTOCOL # tcp.srcip = packet.next.dstip # tcp.dstip = packet.next.srcip # tcp.payload = tcpp # e.payload = tcp # msg = of.ofp_packet_out() # msg.data = e.pack() # msg.actions.append(of.ofp_action_output(port = # of.OFPP_IN_PORT)) # msg.in_port = inport # event.connection.send(msg) # return else: print "Not SYN", packet.next.payload elif self.arp_for_unknowns: # We don't know this destination. # First, we track this buffer so that we can try to resend it later # if we learn the destination, second we ARP for the destination, # which should ultimately result in it responding and us learning # where it is # Add to tracked buffers if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } # Check if we've already ARPed recently if (dpid, dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return # And ARP... self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst) if a.protosrc == IPAddr("10.0.0.1"): if a.opcode == arp.REQUEST: if a.protodst not in self.arpTable[dpid]: self.arpTable[dpid][a.protodst] = Entry( inport, packet.src) self.arpTable[dpid][a.protodst].mac = EthAddr( "32:d5:a3:be:19:77") r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s: %s" % (dpid, inport, r.protosrc, r.hwsrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)) msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def _handle_PacketIn(self, event): global ipTable global last_entry_id if event.dpid in adjacency.keys(): packet = event.parsed if isinstance(packet.next, ipv4): if packet.next.dstip in ipTable.keys(): ip_addr_hex = ip2hex(packet.next.dstip.toStr()) first_hop_outport, port_list, path_list = cal_route(event.dpid, packet.next.dstip) last_hop = path_list[-1] log.info('path: %s' % path_list) log.info('output port: %s' % port_list) ''' entry_id = encap_sr_header_by_dip_w_pktout(dpid=event.dpid, \ dip=ip_addr_hex, \ dip_mask = 'FFffFFff', \ output_port = first_hop_outport, \ port_list = port_list,\ event = event, \ out_dpid = last_hop) ''' encap_sr_header_by_dip(dpid=event.dpid, \ dip=ip_addr_hex, \ dip_mask = 'FFffFFff', \ output_port = first_hop_outport, \ port_list = port_list) elif packet.next.dstip.in_network(IPAddr("192.0.0.0"), 8): # for background north-south traffic ip_addr_hex = ip2hex(packet.next.dstip.toStr()) path_list = [4, 5, 7, 8, 9] port_list = ['02', '03', '01', '03', '05'] port_list_int = [2,3,1,3,5] i = path_list.index(event.dpid) # print event.dpid # print port_list[i], port_list[i+1:] if i==4: last_entry_id[event.dpid] = install_dip_entry(event.dpid, ip_addr_hex, 5) else: last_entry_id[event.dpid] = encap_sr_header_by_dip(dpid=event.dpid, \ dip=ip_addr_hex, \ dip_mask='FFffFFff', \ output_port=port_list_int[i], \ port_list=port_list[i+1:]) if last_entry_id[event.dpid] > 99: dip_table_id = core.PofManager.get_flow_table_id(event.dpid, 'SRHeaderEncapTable') core.PofManager.delete_flow_entry(event.dpid, dip_table_id, last_entry_id[event.dpid] - 5) else: log.info('IP address:' + packet.next.dstip.toStr() + ' is unreachable!') elif isinstance(packet.next, arp): log.info(packet.next._to_str()) ip_addr_hex = ip2hex(packet.next.protodst.toStr()) print 'target ip address:', packet.next.protodst, ip_addr_hex # IPAddr type if packet.next.protodst in ipTable.keys(): port_list, path_list = cal_path(event.dpid, packet.next.protodst) print 'port list', port_list print 'path list', path_list for dpid, port in zip(path_list, port_list): install_arp_target_ip_match_entry(dpid, ip_addr_hex, port) # reverse path flow entry port_list_rev, path_list_rev = cal_path(path_list[-1], packet.next.protosrc) ip_addr_hex_rev = ip2hex(packet.next.protosrc.toStr()) print 'port list reverse', port_list_rev print 'path list reverse', path_list_rev for dpid, port in zip(path_list_rev, port_list_rev): install_arp_target_ip_match_entry(dpid, ip_addr_hex_rev, port) else: log.info('Request IP address unreachable!')
def install_SDN_path(): #第一层收到上面的probe后 for node in adj_path.keys(): msg = of.ofp_flow_mod(match=monitor.match.clone()) #匹配 msg.match.tp_dst, msg.match.tp_src = (None, ) * 2 msg.match.nw_src = IPAddr('10.0.0.1') msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[node][monitor.dpid] #向下转发 for nextnode in adj_path[node].keys(): msg.actions.append( of.ofp_action_nw_addr.set_src(nw_addr=switches_ip[node])) msg.actions.append( of.ofp_action_output(port=adj[node][nextnode])) #修改udp_port,发送回r24 temp_path = [] temp_path.append(24) temp_path.append(node) temp_path = tuple(temp_path) msg.actions.append( of.ofp_action_tp_port.set_src(tp_port=path_id[temp_path])) msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[node].connection.send(msg) nextnode_list = {} #第二层节点收到第一层的probe以后 for node in adj_path.keys(): for nextnode in adj_path[node].keys(): msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None, ) * 2 msg.match.nw_src = switches_ip[node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[nextnode][node] # 向下转发 for lastnode in adj_path[node][nextnode]: msg.actions.append( of.ofp_action_output(port=adj[nextnode][lastnode])) #modify and send back temp_path = [] temp_path.append(24) temp_path.append(node) temp_path.append(nextnode) temp_path = tuple(temp_path) msg.actions.append( of.ofp_action_tp_port.set_src(tp_port=path_id[temp_path])) msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) if nextnode in node_list: msg.actions.append( of.ofp_action_nw_addr.set_src( nw_addr=IPAddr('10.0.0.3'))) msg.actions.append( of.ofp_action_output(port=adj[nextnode][monitor.dpid])) switches[nextnode].connection.send(msg) #第三层节点收到probe以后 for node in adj_path.keys(): for nextnode in adj_path[node].keys(): for lastnode in adj_path[node][nextnode]: msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None, ) * 2 msg.match.nw_src = switches_ip[node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[lastnode][nextnode] #转发回去 temp_path = [] temp_path.append(24) temp_path.append(node) temp_path.append(nextnode) temp_path.append(lastnode) temp_path = tuple(temp_path) msg.actions.append( of.ofp_action_tp_port.set_src( tp_port=path_id[temp_path])) msg.actions.append( of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[lastnode].connection.send(msg) #第二层节点收到第三层的probe以后 for node in adj_path.keys(): for nextnode in adj_path[node].keys(): for lastnode in adj_path[node][nextnode]: msg = of.ofp_flow_mod(match=monitor.match.clone()) # 匹配 msg.match.tp_dst, msg.match.tp_src = (None, ) * 2 msg.match.nw_src = switches_ip[node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[nextnode][lastnode] #往上转发 msg.actions.append( of.ofp_action_output(port=adj[nextnode][node])) switches[nextnode].connection.send(msg) #第一层节点收到第二层的probe以后 for node in adj_path.keys(): for nextnode in adj_path[node].keys(): msg = of.ofp_flow_mod(match=monitor.match.clone()) msg.match.tp_dst, msg.match.tp_src = (None, ) * 2 msg.match.nw_src = switches_ip[node] msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[node][nextnode] #往上转发 msg.actions.append( of.ofp_action_output(port=adj[node][monitor.dpid])) switches[node].connection.send(msg) log.debug('monitor num') #r24收到第一层的probe后 for node in adj_path.keys(): msg = of.ofp_flow_mod() msg.match = monitor.match.clone() #匹配 msg.match.tp_dst, msg.match.tp_src = (None, ) * 2 msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.nw_src = switches_ip[node] msg.match.in_port = adj[monitor.dpid][node] #修改IP msg.actions.append( of.ofp_action_nw_addr.set_dst(nw_addr=monitor.ip)) msg.actions.append( of.ofp_action_nw_addr.set_src(nw_addr=IPAddr('10.0.0.2'))) msg.actions.append( of.ofp_action_dl_addr.set_dst(dl_addr=monitor.hw)) msg.actions.append( of.ofp_action_dl_addr.set_src( dl_addr=EthAddr("00:00:00:00:00:02"))) msg.actions.append(of.ofp_action_output(port=monitor.switch_port)) switches[monitor.dpid].connection.send(msg) #r24shou dao shi jian de switch yi hou for nextnode in node_list: msg = of.ofp_flow_mod() msg.match = monitor.match.clone() #匹配 msg.match.tp_dst, msg.match.tp_src = (None, ) * 2 msg.match.nw_src = IPAddr('10.0.0.3') msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[monitor.dpid][nextnode] #修改IP msg.actions.append( of.ofp_action_nw_addr.set_dst(nw_addr=monitor.ip)) msg.actions.append( of.ofp_action_dl_addr.set_dst(dl_addr=monitor.hw)) msg.actions.append( of.ofp_action_dl_addr.set_src( dl_addr=EthAddr("00:00:00:00:00:03"))) msg.actions.append(of.ofp_action_output(port=monitor.switch_port)) switches[monitor.dpid].connection.send(msg) #r24收到h1的probe后 msg = of.ofp_flow_mod() msg.match = monitor.match.clone() #匹配h1 msg.match.tp_dst, msg.match.tp_src = (None, ) * 2 msg.match.nw_src = IPAddr('10.0.0.1') msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = monitor.switch_port #转发 for node in adj_path.keys(): msg.actions.append( of.ofp_action_output(port=adj[monitor.dpid][node])) # print monitor.dpid switches[monitor.dpid].connection.send(msg)
def remove(self, item): item = IPAddr(item) if item not in self: raise RuntimeError("%s not in this pool" % (item, )) self.removed.add(item)
def __init__(self, ip_address="192.168.0.254", router_address=(), dns_address=(), pool=None, subnet=None, install_flow=True, dpid=None, ports=None): def fix_addr(addr, backup): if addr is None: return None if addr is (): return IPAddr(backup) return IPAddr(addr) self._install_flow = install_flow self.ip_addr = IPAddr(ip_address) self.router_addr = fix_addr(router_address, ip_address) self.dns_addr = fix_addr(dns_address, self.router_addr) if dpid is None: self.dpid = None else: try: dpid = long(dpid) except: dpid = util.str_to_dpid(dpid) self.dpid = dpid if ports is None: self.ports = None else: self.ports = set(ports) if self.ports: assert self.dpid is not None # Doesn't make sense self._servers.append(self) if pool is None: self.pool = [ IPAddr("192.168.0." + str(x)) for x in range(100, 199) ] self.subnet = IPAddr(subnet or "255.255.255.0") else: self.pool = pool self.subnet = subnet if hasattr(pool, 'subnet_mask'): self.subnet = pool.subnet_mask if self.subnet is None: raise RuntimeError("You must specify a subnet mask or use a " "pool with a subnet hint") self.lease_time = 60 * 60 # An hour #TODO: Actually make them expire :) self.offers = {} # Eth -> IP we offered self.leases = {} # Eth -> IP we leased if self.ip_addr in self.pool: log.debug("Removing my own IP (%s) from address pool", self.ip_addr) self.pool.remove(self.ip_addr) core.openflow.addListeners(self)
def __str__(self): t = self.network.toUnsigned() t = (IPAddr(t | self.first), IPAddr(t | self.last)) return "<Addresses from %s to %s>" % t
def subnet_mask(self): return IPAddr(((1 << self.network_size) - 1) << self.host_size)
def _handle_PacketIn(self, event): """ Handles packet in messages from the switch. """ etherFrame = event.parsed # This is the parsed packet data. if not etherFrame.parsed: log.warning("!LOG WARN! S1 : Ignoring incomplete packet") return packet_in = event.ofp # The actual ofp_packet_in message. # Add the new MAC into CAM table if str(etherFrame.src) not in self.mac_to_port: log.debug('!LOG! S1 : Adding %s into CAM, recv from %s' % (str(etherFrame.src), str(packet_in.in_port))) self.mac_to_port[str(etherFrame.src)] = packet_in.in_port # ARP if etherFrame.type == ethernet.ARP_TYPE: log.debug('!LOG! S1 : RECEIVED: EtherType -> ARP') self.ARP_Handler(etherFrame, packet_in) # IP elif etherFrame.type == ethernet.IP_TYPE: log.debug('!LOG! S1 : RECEIVED: EtherType -> IP') # Extract IP Packet from Ethernet Frame ip_packet = etherFrame.payload # Routable? destination_ip = str(ip_packet.dstip) routable = False for netaddr in self.routing_table: destination_network = netaddr if IPAddress(destination_ip) in IPNetwork(destination_network): log.debug('!LOG! S1 : PACKET IS ROUTABLE!') routable = True break if routable: # Destined for router if self.routing_table[str(destination_network)][ 'RouterInterface'] == destination_ip: if ip_packet.protocol == ipv4.ICMP_PROTOCOL: log.debug('!LOG! S1 : ICMP ECHO -> ROUTER INTERFACE') self.ICMP_Handler(etherFrame, packet_in) # Check if any there's any routable networks for the destination IP elif routable: # Route the packet to it's respective ports output_port = self.routing_table[destination_network][ 'Port'] # ARP if host MAC Address is not present if destination_ip not in self.arp_table: # Push frame to buffer self.buffer[destination_ip] = { 'IP_Packet': ip_packet, 'DestinationNetwork': destination_network } # Construct ARP Packet arp_request = arp() arp_request.opcode = arp.REQUEST arp_request.protosrc = IPAddr( self.routing_table[destination_network] ['RouterInterface']) arp_request.protodst = IPAddr(destination_ip) arp_request.hwsrc = EthAddr(self.arp_table[ self.routing_table[destination_network] ['RouterInterface']]) arp_request.hwdst = EthAddr('00:00:00:00:00:00') ether = ethernet() ether.type = ether.ARP_TYPE ether.src = EthAddr(self.arp_table[self.routing_table[ destination_network]['RouterInterface']]) ether.dst = EthAddr('FF:FF:FF:FF:FF:FF') ether.payload = arp_request self.resend_packet(ether, output_port) if destination_ip in self.arp_table: etherFrame.src = EthAddr(self.arp_table[ self.routing_table[destination_network] ['RouterInterface']]) etherFrame.dst = EthAddr( self.arp_table[destination_ip]) self.resend_packet(etherFrame, output_port) # ICMP Destination Unreachable for non-routable networks else: log.debug('!LOG! S1 : PACKET IS NOT ROUTABLE!') ethernet_frame = etherFrame ip_packet = etherFrame.payload icmp_request_packet = ip_packet.payload icmp_echo_reply_packet = icmp() icmp_echo_reply_packet.code = 0 icmp_echo_reply_packet.type = 3 icmp_echo_reply_packet.payload = icmp_request_packet.payload ip = ipv4() ip.srcip = ip_packet.dstip ip.dstip = ip_packet.srcip ip.protocol = ipv4.ICMP_PROTOCOL ip.payload = icmp_echo_reply_packet ether = ethernet() ether.type = ethernet.IP_TYPE ether.src = ethernet_frame.dst ether.dst = ethernet_frame.src ether.payload = ip self.resend_packet(ether, packet_in.in_port) log.debug("!LOG! S1 : ICMP DESTINATION UNREACHABLE SENT")
def sql_flow(event, query): dbmgr = DBManager(":memory:") #dbmgr = DBManager("testdb.db") #dbmgr.query("INSERT INTO person VALUES ('kamran','ali',30)") #dbmgr.query("INSERT INTO person VALUES ('yousaf','akhtar',50)") #dbmgr.query('INSERT INTO OF_table (MAC_src, MAC_dst, Action) VALUES ("00:00:00:00:00:05","00:00:00:00:00:01", "drop" )') dbmgr.query1(query) for row in dbmgr.query1("SELECT * FROM OF_table"): msg = of.ofp_flow_mod() if row[0] != None: msg.match.in_port = int(row[0]) # 2 if row[1] != None: msg.match.dl_src = EthAddr(row[1]) # EthAddr("01:02:03:04:05:06") if row[2] != None: msg.match.dl_dst = EthAddr(row[2]) # EthAddr("01:02:03:04:05:06") if row[3] != None: msg.match.dl_type = int(row[3]) # 0x800 if row[4] != None: msg.match.dl_vlan = int(row[4]) # 10 if row[5] != None: msg.match.dl_vlan_pcp = int( row[5]) # 100 value may vary from 0~255 if row[6] != None: msg.match.nw_src = IPAddr(row[6]) # "192.168.66.0/24" if row[7] != None: msg.match.nw_dst = IPAddr(row[7]) # "192.168.66.0/24" if row[8] != None: msg.match.nw_proto = int(row[8]) # 6 is for tcp if row[9] != None: msg.match.nw_tos = int(row[9]) # 3 # quality of service class if row[10] != None: msg.match.tp_src = int(row[10]) # 80 if row[11] != None: msg.match.tp_dst = int(row[11]) # 80 if row[12] != None: if row[12] == "flood" or row[12] == "FLOOD": msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) elif row[12] == "drop" or row[12] == "DROP": pass else: msg.actions.append(of.ofp_action_output(port=int(row[12]))) if row[13] == None: msg.idle_timeout = 1000 else: msg.idle_timeout = int(row[13]) # 1000 int if row[14] == None: msg.hard_timeout = 1000 else: msg.hard_timeout = int(row[14]) # 0 int if row[15] != None: msg.buffer_id = int(row[15]) # 2870 int if row[16] != None: msg.priority = int( row[16] ) # uint16_t priority, Priority level of flow entry 0 is highest priority event.connection.send(msg) #print "Flow is being deployed" log.info("SQL Flow Mode Query from sql module %s", dpidToStr(event.dpid))
def _handle_openflow_PacketIn(self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed global set_Timer global defendDDOS global blockPort timerSet = False global diction def preventing(): global diction global set_Timer if not set_Timer: set_Timer = True if len(diction) == 0: print("Empty diction ", str(event.connection.dpid), str(event.port)) diction[event.connection.dpid] = {} diction[event.connection.dpid][event.port] = 1 elif event.connection.dpid not in diction: diction[event.connection.dpid] = {} diction[event.connection.dpid][event.port] = 1 else: if event.connection.dpid in diction: if event.port in diction[event.connection.dpid]: temp_count = 0 temp_count = diction[event.connection.dpid][event.port] temp_count = temp_count + 1 diction[event.connection.dpid][event.port] = temp_count #print "*****************************************************************************************************************************************************************************" print "dpid port and its packet count: ", str( event.connection.dpid), str( diction[event.connection.dpid]), str( diction[event.connection.dpid][event.port]) #print "*****************************************************************************************************************************************************************************" else: diction[event.connection.dpid][event.port] = 1 def _timer_func(): global diction global set_Timer if set_Timer == True: for k, v in diction.iteritems(): for i, j in v.iteritems(): if j >= 5: print "_____________________________________________________________________________________________" print "\n DDOS DETECTED \n" print "\n", str(diction) print "\n", datetime.datetime.now( ), ": BLOCKED PORT NUMBER : ", str( i), " OF SWITCH ID: ", str(k) print "\n___________________________________________________________________________________________" os._exit(0) dpid = k msg = of.ofp_packet_out(in_port=i) core.openflow.sendToDPID(dpid, msg) diction = {} if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry( of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip, packet.next.dstip) ent_obj.collectStats(event.parsed.next.dstip) print "Entropy : ", str(ent_obj.value) if ent_obj.value < 1.0: preventing() if timerSet is not True: Timer(1, _timer_func, recurring=True) timerSet = False else: timerSet = False self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, packet.next.srcip) if self.wide: msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = packet.next.srcip msg.match.dl_type = ethernet.IP_TYPE event.connection.send(msg) else: log.debug("%i %i learned %s", dpid, inport, packet.next.srcip) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning( "%i %i not sending packet for %s back out of the " "input port" % (dpid, inport, dstaddr)) else: log.debug( "%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port=prt)) if self.wide: match = of.ofp_match(dl_type=packet.type, nw_dst=dstaddr) else: match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) elif self.arp_for_unknowns: if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } if (dpid, dstaddr) in self.outstanding_arps: return self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, a.protosrc) if self.wide: msg = of.ofp_flow_mod( command=of.OFPFC_DELETE) msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_dst = a.protosrc event.connection.send(msg) else: log.debug("%i %i learned %s", dpid, inport, a.protosrc) self.arpTable[dpid][a.protosrc] = Entry( inport, packet.src) self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: if a.protodst in self.arpTable[dpid]: if not self.arpTable[dpid][ a.protodst].isExpired(): r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][ a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output( port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)) msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def _handle_PacketIn(self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry( of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip, packet.next.dstip) # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, packet.next.srcip) else: log.debug("%i %i learned %s", dpid, inport, str(packet.next.srcip)) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) # Try to forward dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning( "%i %i not sending packet for %s back out of the " + "input port" % (dpid, inport, str(dstaddr))) else: log.debug( "%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port=prt)) match = of.ofp_match.from_packet(packet, inport) match.dl_src = None # Wildcard source MAC msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=of.ofp_match.from_packet( packet, inport)) event.connection.send(msg.pack()) elif self.arp_for_unknowns: # We don't know this destination. # First, we track this buffer so that we can try to resend it later # if we learn the destination, second we ARP for the destination, # which should ultimately result in it responding and us learning # where it is # Add to tracked buffers if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } # Check if we've already ARPed recently if (dpid, dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return # And ARP... self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, str(r.protodst), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, str(a.protosrc)) else: log.debug("%i %i learned %s", dpid, inport, str(a.protosrc)) self.arpTable[dpid][a.protosrc] = Entry( inport, packet.src) # Send any waiting packets... self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # We have an answer... if not self.arpTable[dpid][ a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][ a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output( port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst))) msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def _handle_PacketIn(self, event): log.debug("FUNCTION: _handle_PacketIn") packet = event.parsed connection = event.connection inport = event.port # Handle LLDP or Ipv6 packets if packet.type == packet.LLDP_TYPE or packet.type == packet.IPV6_TYPE: log.info("Received LLDP or IPv6 Packet...") # Handle ARP packets elif packet.type == packet.ARP_TYPE: log.debug("Received ARP Packet") response = packet.payload # Handle ARP reply if response.opcode == response.REPLY: log.debug("ARP REPLY Received") if response.protosrc not in self.SERVERS.keys(): # Adding the servers' MAC addresses and port numbers to the SERVERS dictionary if they're not # there already self.SERVERS[IPAddr(response.protosrc)] = {'server_mac': EthAddr(response.hwsrc), 'port': inport} # Handle ARP request elif response.opcode == response.REQUEST: log.debug("ARP REQUEST Received") if response.protosrc not in self.SERVERS.keys() and response.protosrc not in self.CLIENTS.keys(): # Indexing the client IP, mac and port number in a forwarding table self.CLIENTS[response.protosrc] = {'client_mac': EthAddr(packet.payload.hwsrc), 'port': inport} if response.protosrc in self.CLIENTS.keys() and response.protodst == self.LOADBALANCER_IP: log.info("Client %s sent ARP req to LB %s" % (response.protosrc, response.protodst)) self.send_arp_reply(packet, connection, inport) elif response.protosrc in self.SERVERS.keys() and response.protodst in self.CLIENTS.keys(): log.info("Server %s sent ARP req to client" % response.protosrc) self.send_arp_reply(packet, connection, inport) else: log.info("Invalid ARP request") # Handle IPv4 packets elif packet.type == packet.IP_TYPE: log.debug("Received IP Packet from %s" % packet.next.srcip) # Handle Requests from Clients to Servers # Install flow rule Client -> Server if (packet.next.dstip == self.LOADBALANCER_IP) and (packet.next.srcip not in self.SERVERS.keys()): self.update_lb_mapping(packet.next.srcip) client_ip = packet.payload.srcip server_ip = self.LOADBALANCER_MAP.get(packet.next.srcip) outport = self.SERVERS[server_ip].get('port') self.install_flow_rule_client_to_server(event, connection, outport, client_ip, server_ip) eth = ethernet() #Creating ethernet frame eth.type = eth.IP_TYPE eth.dst = self.SERVERS[server_ip].get('server_mac') eth.src = LOADBALANCER_MAC eth.set_payload(packet.next) # Send the first packet (which was sent to the controller from the switch) # to the chosen server, so there is no packetloss msg = of.ofp_packet_out() msg.data = eth.pack() msg.in_port = inport msg.actions.append(of.ofp_action_dl_addr.set_src(LOADBALANCER_MAC)) msg.actions.append(of.ofp_action_dl_addr.set_dst(self.SERVERS[server_ip].get('server_mac'))) msg.actions.append(of.ofp_action_nw_addr.set_src(client_ip)) msg.actions.append(of.ofp_action_nw_addr.set_dst(server_ip)) msg.actions.append(of.ofp_action_output(port=outport)) connection.send(msg) # Handle traffic from Server to Client # Install flow rule Client <- Server elif packet.next.dstip in self.CLIENTS.keys(): # server to client log.info("Installing flow rule from Server -> Client") if packet.next.srcip in self.SERVERS.keys(): server_ip = packet.next.srcip client_ip = self.LOADBALANCER_MAP.keys()[ list(self.LOADBALANCER_MAP.values()).index(packet.next.srcip)] outport = self.CLIENTS[client_ip].get('port') self.install_flow_rule_server_to_client(connection, outport, server_ip, client_ip) eth = ethernet() #Creating ethernet frame eth.type = eth.IP_TYPE eth.dst = self.SERVERS[server_ip].get('server_mac') eth.src = LOADBALANCER_MAC eth.set_payload(packet.next) # Send the first packet (which was sent to the controller from the switch) # to the chosen server, so there is no packetloss msg = of.ofp_packet_out() msg.data = eth.pack() msg.in_port = inport msg.actions.append(of.ofp_action_dl_addr.set_src(LOADBALANCER_MAC)) msg.actions.append(of.ofp_action_dl_addr.set_dst(self.CLIENTS[client_ip].get('client_mac'))) msg.actions.append(of.ofp_action_nw_addr.set_src(self.LOADBALANCER_IP)) msg.actions.append(of.ofp_action_nw_addr.set_dst(client_ip)) msg.actions.append(of.ofp_action_output(port=outport)) self.connection.send(msg) else: log.info("Unknown Packet type: %s" % packet.type) return return
ipTable = defaultdict(lambda: defaultdict(lambda: None)) # ipTable[IPAddr('10.0.0.1')] = (1, 1) # (dpid, port) # ipTable[IPAddr('10.0.0.2')] = (2, 1) # ipTable[IPAddr('10.0.0.3')] = (3, 1) # ipTable[IPAddr('10.0.0.4')] = (4, 1) # six node topo # ipTable[IPAddr('10.1.0.0')] = (1, 3) # (dpid, port) # ipTable[IPAddr('10.2.0.0')] = (2, 4) # (dpid, port) # ipTable[IPAddr('10.3.0.0')] = (3, 4) # ipTable[IPAddr('10.4.0.0')] = (4, 3) # ipTable[IPAddr('10.5.0.0')] = (5, 4) # ipTable[IPAddr('10.6.0.0')] = (6, 4) # 14 Node NSFNET ipTable[IPAddr('10.0.0.1')] = (1, 1) ipTable[IPAddr('10.0.0.2')] = (2, 1) ipTable[IPAddr('10.0.0.3')] = (3, 1) ipTable[IPAddr('10.0.0.4')] = (4, 1) ipTable[IPAddr('10.0.0.5')] = (5, 1) ipTable[IPAddr('10.0.0.6')] = (6, 1) ipTable[IPAddr('10.0.0.7')] = (7, 1) ipTable[IPAddr('10.0.0.8')] = (8, 1) ipTable[IPAddr('10.0.0.9')] = (9, 2) ipTable[IPAddr('10.0.0.10')] = (10, 1) ipTable[IPAddr('10.0.0.11')] = (11, 1) ipTable[IPAddr('10.0.0.12')] = (12, 1) ipTable[IPAddr('10.0.0.13')] = (13, 1) ipTable[IPAddr('10.0.0.14')] = (14, 1)
from pox.core import core import pox.openflow.libopenflow_01 as of from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST from pox.lib.packet.ipv4 import ipv4 from pox.lib.packet.arp import arp from pox.lib.packet.icmp import icmp import pox.lib.packet as pkt from pox.lib.addresses import IPAddr, EthAddr import struct import time log = core.getLogger() DEFAULT_GATEWAY = 1 validIP = [IPAddr('10.0.1.1'), IPAddr('10.0.1.2'), IPAddr('10.0.1.3'), IPAddr('10.0.2.1'), IPAddr('10.0.2.2'), IPAddr('10.0.2.3'), IPAddr('10.0.2.4')] subnet1 = ['10.0.1.1', '10.0.1.2', '10.0.1.3'] subnet2 = ['10.0.2.1', '10.0.2.2', '10.0.2.3', '10.0.2.4'] class router(object): def __init__(self): log.debug('router registered') # The dict for all routers, desginated by dpid # In each dict, each component is also a dict indexed by dpid self.arpTable = {} self.arpWait = {} self.routingTable = {} self.connections = {} self.routerIP = {} core.openflow.addListeners(self) def _handle_GoingUpEvent(self, event): self.listenTo(core.openflow)
def try_bad(): e = nx.NXM_OF_IP_SRC(IPAddr("192.168.56.1"), IPAddr("255.255.255.0")) e.pack()
def _handle_PacketIn (self, event): log.debug("---------------------------event---------------------------") packet = event.parsed dpid = event.connection.dpid inport = event.port log.debug("Router {0}: in port {1}, {2}".format(dpid, inport, packet)) if not packet.parsed: log.error("Incomplete packet") return packetIn = event.ofp payload = packet.payload log.debug("Router {0}: {1}".format(dpid, payload)) if isinstance(payload, arp): # arp self._handle_ARP(payload, inport, dpid, packetIn) elif isinstance(payload, ipv4): # ip log.debug("Router {0}: ipv4 packet in port {1}, from {2} to {3}".format(dpid, inport, packet.next.srcip, packet.next.dstip)) self._add_IP(payload.srcip, dpid, inport) if payload.dstip not in validIP: self._handle_ICMP_Reply(dpid, packet, payload.srcip, payload.dstip, pkt.TYPE_DEST_UNREACH) return if payload.dstip == self.routerIP[dpid]: # payload for you, should be an icmp request if isinstance(payload.next, icmp): log.debug("Router {0}: ICMP packet comes to router".format(dpid)) self._handle_ICMP_Reply(dpid, packet, payload.srcip, payload.dstip, pkt.TYPE_ECHO_REPLY) elif (payload.dstip in subnet1 and self.routerIP[dpid] in subnet2) or (payload.dstip in subnet2 and self.routerIP[dpid] in subnet1): #different subnet nextIP = IPAddr('10.0.{0}.1'.format(3-dpid)) nextMac = self.arpTable[dpid][nextIP] msg = of.ofp_packet_out(buffer_id=packetIn.buffer_id, in_port=inport) msg.actions.append(of.ofp_action_dl_addr.set_dst(nextMac)) msg.actions.append(of.ofp_action_output(port=1))# FIXED router to router port self.connections[dpid].send(msg) log.debug('Router {0}: packet from {1} to {2}, is in different subnet, send to port 1'.format(dpid, payload.srcip, payload.dstip)) # install flow fm = of.ofp_flow_mod() fm.match.dl_type = 0x800 fm.match.nw_dst = payload.dstip fm.actions.append(of.ofp_action_dl_addr.set_dst(nextMac)) fm.actions.append(of.ofp_action_output(port=1)) self.connections[dpid].send(fm) else: #same subnet if payload.dstip not in self.routingTable[dpid] or payload.dstip not in self.arpTable[dpid]: log.debug("Router {0}, packet from {1} to {2}, unknown destination, adding to arpWait".format(dpid, payload.srcip, payload.dstip)) # create a list of pending packet, check if any if payload.dstip not in self.arpWait[dpid]: self.arpWait[dpid][payload.dstip] = [] entry = (packetIn.buffer_id, inport) self.arpWait[dpid][payload.dstip].append(entry) self._handle_ARP_Request(payload.srcip, payload.dstip, packet.src, inport, dpid) else: msg = of.ofp_packet_out(buffer_id=packetIn.buffer_id, in_port=inport) msg.actions.append(of.ofp_action_dl_addr.set_dst(self.arpTable[dpid][payload.dstip])) msg.actions.append(of.ofp_action_output(port=self.routingTable[dpid][payload.dstip])) self.connections[dpid].send(msg) log.debug('Router {0}: packet from {1} to {2}, same subnet, sending to port {3}'.format(dpid, payload.srcip, payload.dstip, self.routingTable[dpid][payload.dstip])) # install flow msg = of.ofp_flow_mod() msg.match.dl_type = 0x800 msg.match.nw_dst = payload.dstip msg.actions.append(of.ofp_action_dl_addr.set_dst(self.arpTable[dpid][payload.dstip])) msg.actions.append(of.ofp_action_output(port=self.routingTable[dpid][payload.dstip])) self.connections[dpid].send(msg)
#flow3: switch2 = 0000000000000003 flow2msg = of.ofp_flow_mod() flow2msg.cookie = 0 flow2msg.match.in_port = 2 flow2msg.match.dl_type = 0x0800 flow2msg.match.nw_dst = IPAddr("10.0.0.2") # ACTIONS--------------------------------- flow2out = of.ofp_action_output (port = 1) flow2dstIP = of.ofp_action_nw_addr.set_dst(IPAddr("10.0.0.1")) flow2srcMAC = of.ofp_action_dl_addr.set_src(EthAddr("00:00:00:00:00:04")) flow2dstMAC = of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:01")) flow2msg.actions = [flow2dstIP, flow2srcMAC, flow2dstMAC, flow2out]
def ip(addr): if addr is None: return None return IPAddr(addr, networkOrder=True)
def install_flowrule(self, id, match, action): """ Install a flowrule in an OpenFlow switch. :param id: ID of the infra element stored in the NFFG :type id: str :param match: match part of the rule (keys: in_port, vlan_id) :type match: dict :param action: action part of the rule (keys: out, vlan_push, vlan_pop) :type action: dict :return: None """ conn = self.openflow.getConnection(dpid=self.infra_to_dpid[id]) if not conn: log.warning( "Missing connection for node element: %s! Skip flowrule " "installation..." % id) msg = of.ofp_flow_mod() msg.match.in_port = match['in_port'] if 'vlan_id' in match: try: vlan_id = int(match['vlan_id']) except ValueError: log.warning( "VLAN_ID: %s in match field is not a valid number! " "Skip flowrule installation..." % match['vlan_id']) return msg.match.dl_vlan = vlan_id # Append explicit matching parameters to OF flowrule if 'flowclass' in match: for ovs_match_entry in match['flowclass'].split(','): kv = ovs_match_entry.split('=') # kv = [field, value] ~ ['dl_src', '00:0A:E4:25:6B:B6'] # msg.match.dl_src = "00:00:00:00:00:01" if kv[0] in ('dl_src', 'dl_dst'): setattr(msg.match, kv[0], EthAddr(kv[1])) elif kv[0] in ('in_port', 'dl_vlan', 'dl_type', 'ip_proto', 'nw_proto', 'nw_tos', 'nw_ttl', 'tp_src', 'tp_dst'): setattr(msg.match, kv[0], int(kv[1], 0)) elif kv[0] in ('nw_src', 'nw_dst'): setattr(msg.match, kv[0], IPAddr(kv[1])) else: setattr(msg.match, kv[0], kv[1]) if 'vlan_push' in action: try: vlan_push = int(action['vlan_push']) except ValueError: log.warning( "VLAN_PUSH: %s in action field is not a valid number! " "Skip flowrule installation..." % action['vlan_push']) return msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan_push)) # msg.actions.append(of.ofp_action_vlan_vid()) out = action['out'] # If out is in the detected saps --> always remove the VLAN tags if 'vlan_pop' in action: msg.actions.append(of.ofp_action_strip_vlan()) else: try: # If next node is a SAP we need to setup the MAC addresses and # strip VLAN from the frame explicitly if out in self.saps[id]: msg.actions.append(of.ofp_action_strip_vlan()) except KeyError: pass try: if out in self.saps[id]: dl_dst = self.saps[id][str(out)]['dl_dst'] dl_src = self.saps[id][str(out)]['dl_src'] msg.actions.append( of.ofp_action_dl_addr.set_dst(EthAddr(dl_dst))) msg.actions.append( of.ofp_action_dl_addr.set_src(EthAddr(dl_src))) except KeyError: pass try: out_port = int(action['out']) except ValueError: log.warning( "Output port: %s is not a valid port in flowrule action: %s! " "Skip flowrule installation..." % (action['out'], action)) return msg.actions.append(of.ofp_action_output(port=out_port)) log.debug("Install flow entry into INFRA: %s on connection: %s ..." % (id, conn)) conn.send(msg) log.log(VERBOSE, "Sent OpenFlow flowrule:\n%s" % msg)
def handle_ARP_pktin(): srcip = IPAddr(packet.next.protosrc) print "__________________________________srcip: ", srcip dstip = IPAddr(packet.next.protodst) print "__________________________________dstip: ", dstip if (srcip in self.ignored_IPs) or (dstip in self.ignored_IPs): return if packet.next.opcode == arp.REQUEST: log.info("Handling ARP packet: %s requests the MAC of %s" % (str(srcip), str(dstip))) self.update_learned_arp_info(packet, dpid, inport) #FIREWALL functionality if self.firewall_capability: try: src = 0 #temporary src switch counter dst = 0 #temporary dst switch counter for key, value in self.firewall_policies.items( ): #here we check if src and dst switches are both in the same tan if key == srcip: src = value if key == dstip: dst = value #handle ARP and IP Packetsins and install rules on the OpenFlow switches #to drop packets whenever tenants from different services attempt to communicate. #so given a topology with 2 tenants we check if src switch and dst are in from defferent services #so we drop those packets. if src != dst: self.drop_packets(dstip, packet) pass except KeyError: log.info("IPs not covered by policy!") return if self.migration_capability: #ignore ARP requests coming from old migrated IPs or directed to new ones if (srcip in self.old_migrated_IPs) or ( dstip in self.new_migrated_IPs): return if dstip in self.arpmap: log.info("I know where to send the crafted ARP reply!") (req_mac, req_dpid, req_port) = self.arpmap[dstip] (dst_mac, dst_dpid, dst_port) = self.arpmap[srcip] self.switches[dst_dpid].send_arp_reply( packet, dst_port, req_mac) else: log.info( "Flooding initial ARP request on all switch edges") self.flood_on_all_switch_edges(packet, dpid, inport) elif packet.next.opcode == arp.REPLY: log.info("Handling ARP packet: %s responds to %s" % (str(srcip), str(dstip))) self.update_learned_arp_info(packet, dpid, inport) #FIREWALL functionality if self.firewall_capability: try: src = 0 #temporary src switch counter dst = 0 #temporary dst switch counter for key, value in self.firewall_policies.items( ): #here we check if src and dst switches are both in the same tan if key == srcip: src = value if key == dstip: dst = value #handle ARP and IP Packetsins and install rules on the OpenFlow switches #to drop packets whenever tenants from different services attempt to communicate. #so given a topology with 2 tenants we check if src switch and dst are in from defferent services #so we drop those packets. if src != dst: self.drop_packets(dstip, packet) pass except KeyError: return if self.migration_capability: #ignore ARP replies coming from old migrated IPs or directed to new ones if (srcip in self.old_migrated_IPs) or ( dstip in self.new_migrated_IPs): return if dstip in self.arpmap.keys(): log.info("I know where to send the initial ARP reply!") (dst_mac, dst_dpid, dst_port) = self.arpmap[dstip] self.switches[dst_dpid].send_packet(dst_port, packet) else: log.info("Flooding initial ARP reply on all switch edges") self.flood_on_all_switch_edges(packet, dpid, inport) else: log.info("Unknown ARP type") return
def install_SDN_path(): #端口 转发 for p in path_did.keys(): #在第一层就返回的情况 if len(p)==1: msg = of.ofp_flow_mod(match=monitor.match.clone()) msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = (None,) * 3 msg.match.tp_src = path_did[p] msg.match.in_port=adj[p[0]][monitor.dpid] msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[p[0]].connection.send(msg) else : # 到达第一层交换机 msg = of.ofp_flow_mod() msg.match = monitor.match.clone() msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = (None,) * 3 msg.match.tp_src = path_did[p] msg.match.in_port = adj[p[0]][monitor.dpid] msg.actions.append(of.ofp_action_output(port=adj[p[0]][p[1]])) switches[p[0]].connection.send(msg) #从第二层一直到底层的情况 for n in range(1,len(p)): if n < (len(p)-1): msg=of.ofp_flow_mod() msg.match=monitor.match.clone() msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = (None,) * 3 msg.match.tp_src = path_did[p] msg.match.in_port=adj[p[n]][p[n-1]] msg.actions.append(of.ofp_action_output(port=adj[p[n]][p[n+1]])) switches[p[n]].connection.send(msg) else: msg = of.ofp_flow_mod() msg.match = monitor.match.clone() msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = (None,) * 3 msg.match.tp_src = path_did[p] msg.match.in_port = adj[p[n]][p[n-1]] msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) switches[p[n]].connection.send(msg) # 返回到一层的操作 for m in range((len(p)-2),0,-1): msg=of.ofp_flow_mod() msg.match=monitor.match.clone() msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = (None,) * 3 msg.match.tp_src = path_did[p] msg.match.in_port=adj[p[m]][p[m+1]] msg.actions.append(of.ofp_action_output(port=adj[p[m]][p[m-1]])) switches[p[m]].connection.send(msg) #返回到一层之后,返回到r24 msg=of.ofp_flow_mod() msg.match=monitor.match.clone() msg.match.nw_src, msg.match.tp_dst, msg.match.nw_dst = (None,) * 3 msg.match.tp_src = path_did[p] msg.match.in_port=adj[p[0]][p[1]] msg.actions.append(of.ofp_action_output(port=adj[p[0]][monitor.dpid])) switches[p[0]].connection.send(msg) for node in adj_path.keys(): msg = of.ofp_flow_mod() msg.match = monitor.match.clone() #匹配 msg.match.nw_src,msg.match.tp_dst,msg.match.tp_src,msg.match.nw_dst = (None,) * 4 #msg.match.nw_src = IPAddr('10.0.0.1') #msg.match.nw_dst = IPAddr('10.0.0.2') msg.match.in_port = adj[monitor.dpid][node] #修改IP # msg.actions.append(of.ofp_action_nw_addr.set_dst(nw_addr = IPAddr('10.0.0.2'))) # msg.actions.append(of.ofp_action_dl_addr.set_dst(dl_addr = EthAddr("00:00:00:00:00:02"))) # msg.actions.append(of.ofp_action_dl_addr.set_dst(dl_addr = EthAddr("00:00:00:00:00:02"))) #向上转发 msg.actions.append(of.ofp_action_nw_addr.set_dst(nw_addr = monitor.ip)) msg.actions.append(of.ofp_action_nw_addr.set_src(nw_addr = IPAddr('10.0.0.2'))) msg.actions.append(of.ofp_action_dl_addr.set_dst(dl_addr = monitor.hw)) msg.actions.append(of.ofp_action_dl_addr.set_src(dl_addr = EthAddr("00:00:00:00:00:02"))) msg.actions.append(of.ofp_action_output(port=monitor.switch_port)) switches[monitor.dpid].connection.send(msg) #r24收到h1的probe后(除去操作时延) for p in path_did.keys(): msg = of.ofp_flow_mod() msg.match = monitor.match.clone() msg.match.tp_dst, msg.match.nw_src, msg.match.nw_dst =(None,) *3 msg.match.in_port = monitor.switch_port msg.match.tp_src=path_did[p] msg.actions.append(of.ofp_action_nw_addr.set_src(nw_addr=IPAddr('10.0.1.2'))) msg.actions.append(of.ofp_action_output(port=adj[monitor.dpid][p[0]])) switches[monitor.dpid].connection.send(msg)
def handle_IP_pktin(): srcip = IPAddr(packet.next.srcip) dstip = IPAddr(packet.next.dstip) if (srcip in self.ignored_IPs) or (dstip in self.ignored_IPs): return log.info("Handling IP packet between %s and %s" % (str(srcip), str(dstip))) #FIREWALL functionality if self.firewall_capability: try: #WRITE YOUR CODE HERE! src = 0 #temporary src switch counter dst = 0 #temporary dst switch counter for key, value in self.firewall_policies.items( ): #here we check if src and dst switches are both in the same tan if key == srcip: src = value if key == dstip: dst = value #handle ARP and IP Packetsins and install rules on the OpenFlow switches #to drop packets whenever tenants from different services attempt to communicate. #so given a topology with 2 tenants we check if src switch and dst are in from defferent services #so we drop those packets. if src != dst: self.drop_packets(dstip, packet) pass except KeyError: log.info("IPs not covered by policy!") return if self._paths_computed: #print "Routing calculations have converged" log.info("Path requested for flow %s-->%s" % (str(srcip), str(dstip))) if dstip in self.arpmap: #I know where to send the packet (dst_mac, dst_dpid, dst_port) = self.arpmap[dstip] #MIGRATION functionality if self.migration_capability: #IP packet goes to old server after migration is done if dstip in self.old_migrated_IPs: (dst_mac, dst_dpid, dst_port ) = self.arpmap[self.old_migrated_IPs[dstip]] #install path to new server and change packet headers log.info( "Installing migrated forward path towards: old IP: %s, new IP: %s" % (str(dstip), str( self.old_migrated_IPs[dstip]))) self.install_migrated_end_to_end_IP_path( event, dst_dpid, dst_port, packet, forward_path=True) log.info("Forward migrated path installed") #IP packet comes from new server after migration is done elif srcip in self.new_migrated_IPs: (dst_mac, dst_dpid, dst_port) = self.arpmap[dstip] log.info( "Installing migrated reverse path from: old IP: %s, new IP: %s" % (str(srcip), str( self.new_migrated_IPs[srcip]))) self.install_migrated_end_to_end_IP_path( event, dst_dpid, dst_port, packet, forward_path=False) log.info("Reverse migrated path installed") else: self.install_end_to_end_IP_path( event, dst_dpid, dst_port, packet) else: self.install_end_to_end_IP_path( event, dst_dpid, dst_port, packet) else: self.flood_on_all_switch_edges(packet, dpid, inport) else: print "Routing calculations have not converged, discarding packet" return
ARPResponder._handle_PacketIn = new_pi # Hackery done. Now start it. from proto.arp_responder import launch as arp_launch arp_launch(eat_packets=False,**{str(ip):True}) import logging logging.getLogger("proto.arp_responder").setLevel(logging.WARN) def _handle_ConnectionUp (event): global _dpid if _dpid is None: _dpid = event.dpid if _dpid != event.dpid: log.warn("Ignoring switch %s", event.connection) else: if not core.hasComponent('iplb'): # Need to initialize first... core.registerNew(iplb, event.connection, IPAddr(ip), servers) log.info("IP Load Balancer Ready.") log.info("Load Balancing on %s", event.connection) # Gross hack core.iplb.con = event.connection event.connection.addListeners(core.iplb) core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp)
import os import struct import fcntl import pprint import select from pox.lib.packet import ipv4 from pox.lib.addresses import IPAddr from pox.lib.packet import ICMP from nat_wrapper import snat_wrapper TUNSETIFF = 0x400454ca TUNSETOWNER = TUNSETIFF + 2 IFF_TUN = 0x0001 IFF_TAP = 0x0002 IFF_NO_PI = 0x1000 host = IPAddr("10.170.0.2") snat_wrapper.ip_pool([host]) def processICMP(pkt): req = pkt.next if pkt.dstip == host and req.type == ICMP.TYPE_ECHO_REQUEST: pkt.dstip = pkt.srcip pkt.srcip = host req.type = ICMP.TYPE_ECHO_REPLY size = os.write(tun, pkt.pack()) print("write to eic %s bytes" % size) tcp_nat_table = {}
def fix_addr(addr, backup): if addr is None: return None if addr is (): return IPAddr(backup) return IPAddr(addr)
def match_dst_ip(msg, ip_string): msg.match.dl_type = 0x800 msg.match.nw_dst = IPAddr(ip_string)