def tests(): f = Firewall() ip = ipv4() ip.dstip = IPAddr("192.168.100.2") ip.srcip = IPAddr("172.16.42.1") ip.protocol = ip.TCP_PROTOCOL xudp = tcp() xudp.srcport = 49662 xudp.dstport = 80 xudp.payload = "Hello, world" xudp.len = 8 + len(xudp.payload) ip.payload = xudp print len(ip) # print the length of the packet, just for fun # you can name this method what ever you like, but you'll # need some method that gets periodically invoked for updating # token bucket state for any rules with rate limits f.update_tokens() # again, you can name your "checker" as you want, but the # idea here is that we call some method on the firewall to # test whether a given packet should be permitted or denied. print f.forward_packet(ip) ip2 = ipv4() ip2.srcip = IPAddr("192.168.100.2") ip2.dstip = IPAddr("172.16.42.1") ip2.protocol = ip2.TCP_PROTOCOL xudp2 = tcp() xudp2.srcport = 80 xudp2.dstport = 49662 xudp2.payload = "Hello, world" xudp2.len = 8 + len(xudp2.payload) ip2.payload = xudp2 print len(ip2) # print the length of the packet, just for fun # you can name this method what ever you like, but you'll # need some method that gets periodically invoked for updating # token bucket state for any rules with rate limits f.update_tokens() # again, you can name your "checker" as you want, but the # idea here is that we call some method on the firewall to # test whether a given packet should be permitted or denied. print f.forward_packet(ip2) # if you want to simulate a time delay and updating token buckets, # you can just call time.sleep and then update the buckets. time.sleep(0.5) f.update_tokens()
def tests(): f = Firewall() ip = ipv4() ip.srcip = IPAddr("172.16.42.1") ip.dstip = IPAddr("172.16.42.35") # 17 for udp, 6 tcp, 1 icmp ip.protocol = 6 icmppkt = pktlib.icmp() icmppkt.type = pktlib.TYPE_ECHO_REQUEST icmppkt.payload ="Hello, world" xudp = udp() xudp.srcport = 53 xudp.dstport = 53 xudp.payload = "Hello, world" xudp.len = 8 + len(xudp.payload) tcppkt = pktlib.tcp() tcppkt.SYN = 1 tcppkt.seq = 14 tcppkt.srcport = 80 tcppkt.dstport = 80 tcppkt.offset = 5 tcppkt.payload = "Hello, world" tcppkt.tcplen = 20 # ip.payload = xudp # ip.payload = icmppkt ip.payload = tcppkt f=Firewall() f.mainframe(ip, time.time())
def new_packet(self, ack=True, data=None, syn=False): """ Creates and returns a new TCP segment encapsulated in an IP packet. If ack is set, it sets the ACK flag. If data is set, it is set as the TCP payload. If syn is set, it sets the SYN flag """ assert self.is_peered assert self.is_bound p = self.stack.new_packet() p.ipv4 = pkt.ipv4(srcip=self.name[0], dstip=self.peer[0]) p.ipv4.protocol = pkt.ipv4.TCP_PROTOCOL p.tcp = pkt.tcp(srcport=self.name[1], dstport=self.peer[1]) p.ipv4.payload = p.tcp p.tcp.seq = self.snd.nxt p.tcp.ack = self.rcv.nxt p.tcp.ACK = ack p.tcp.SYN = syn if data: p.tcp.payload = data p.tcp.win = min(0xffFF, self.rcv.wnd) return p
def create_packet(e1, e2, i1, i2, t1, t2): e = pkt.ethernet(src=e1, dst=e2, type=pkt.ethernet.IP_TYPE) i = pkt.ipv4(srcip=i1, dstip=i2, protocol=pkt.ipv4.TCP_PROTOCOL) t = pkt.tcp(srcport=t1, dstport=t2, off=5, win=1) t.ACK = True i.payload = t e.payload = i return e
def import_rules(self): file = open("firewall_rules.txt", "r") for line in file: if len(line) != 1: #this is to get rid of the empty lines words = [] words = line.split() if words[0] == "permit" or words[0] == "deny": #make sure it is not a comment ruleObject = Rules() ruleObject.line = line for idx in range(len(words)): if words[idx] == "permit": ruleObject.action = "permit" if words[idx] == "deny": ruleObject.action = "deny" if words[idx] == "ip": ruleObject.type = type(pktlib.ipv4()) if words[idx] == "tcp": ruleObject.type = type(pktlib.tcp()) if words[idx] == "udp": ruleObject.type = type(pktlib.udp()) if words[idx] == "icmp": ruleObject.type = type(pktlib.icmp()) if words[idx] == "src": if words[idx+1] == "any": ruleObject.src = 1 else: ruleObject.src = words[idx+1] if "/" in ruleObject.src: #meaning its a net addr-we need the netmask temp = parse_cidr(ruleObject.src) srcnetMask = cidr_to_netmask(temp[1]) ruleObject.netMask = srcnetMask if words[idx] == "srcport": if words[idx+1] == "any": ruleObject.srcport = 1 else: ruleObject.srcport = words[idx+1] if words[idx] == "dst": if words[idx+1] == "any": ruleObject.dst = 1 else: ruleObject.dst = words[idx+1] if words[idx] == "dstport": if words[idx+1] == "any": ruleObject.dstport = 1 else: ruleObject.dstport = words[idx+1] if words[idx] == "ratelimit": ruleObject.ratelimit = words[idx+1] self.rules.append(ruleObject)
def flowlet_to_packet(flowlet): if hasattr(flowlet, "origpkt"): return getattr(flowlet, "origpkt") ident = flowlet.ident.key etherhdr = pktlib.ethernet() etherhdr.src = EthAddr(flowlet.srcmac) etherhdr.dst = EthAddr(flowlet.dstmac) etherhdr.type = pktlib.ethernet.IP_TYPE ipv4 = pktlib.ipv4() ipv4.srcip = IPAddr(ident.srcip) ipv4.dstip = IPAddr(ident.dstip) ipv4.protocol = ident.ipproto ipv4.tos = flowlet.iptos iplen = flowlet.bytes / flowlet.pkts ipv4.iplen = iplen payloadlen = 0 etherhdr.payload = ipv4 if ident.ipproto == IPPROTO_ICMP: layer4 = pktlib.icmp() layer4.type = ident.dport >> 8 layer4.code = ident.dport & 0x00FF payloadlen = max(iplen - 28, 0) elif ident.ipproto == IPPROTO_UDP: layer4 = pktlib.udp() layer4.srcport = ident.sport layer4.dstport = ident.dport elif ident.ipproto == IPPROTO_TCP: layer4 = pktlib.tcp() layer4.srcport = ident.sport layer4.dstport = ident.dport layer4.flags = flowlet.tcpflags layer4.off = 5 payloadlen = max(iplen - 40, 0) layer4.tcplen = payloadlen layer4.payload = spack("{}x".format(payloadlen)) else: raise UnhandledPoxPacketFlowletTranslation( "Can't translate IP protocol {} from flowlet to POX packet".format(fident.ipproto) ) ipv4.payload = layer4 etherhdr.origflet = flowlet return etherhdr
def send_tcp_fin_ack (event,packet): # Check if TCP tcp_in = packet.find("tcp") #print "Send TCP Reset" http_resp = pkt.tcp() payload = "" # Send HTTP response packet # Ethernet frame e = pkt.ethernet() e.src = packet.dst e.dst = packet.src e.type = e.IP_TYPE # Now create the IPv4 packet ipp = pkt.ipv4() ipp.protocol = ipp.TCP_PROTOCOL ipp.srcip = packet.find("ipv4").dstip ipp.dstip = packet.find("ipv4").srcip ipp.flags = packet.find("ipv4").flags #http_resp.FIN = True http_resp.ACK = True http_resp.dstport = tcp_in.srcport http_resp.srcport = tcp_in.dstport http_resp.seq = tcp_in.ack http_resp.ack = tcp_in.seq +1 http_resp.options = tcp_in.options http_resp.off = 8 http_resp.win = tcp_in.win # Hook them up... ipp.payload = http_resp e.payload = ipp # Send it back to the input port msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.data = e.pack() msg.in_port = event.port event.connection.send(msg)
def flowlet_to_packet(flowlet): '''Translate an fs flowlet to a POX packet''' if hasattr(flowlet, "origpkt"): return getattr(flowlet, "origpkt") ident = flowlet.ident.key etherhdr = pktlib.ethernet() etherhdr.src = EthAddr(flowlet.srcmac) etherhdr.dst = EthAddr(flowlet.dstmac) etherhdr.type = pktlib.ethernet.IP_TYPE ipv4 = pktlib.ipv4() ipv4.srcip = IPAddr(ident.srcip) ipv4.dstip = IPAddr(ident.dstip) ipv4.protocol = ident.ipproto ipv4.tos = flowlet.iptos iplen = flowlet.bytes / flowlet.pkts ipv4.iplen = iplen payloadlen = 0 etherhdr.payload = ipv4 if ident.ipproto == IPPROTO_ICMP: layer4 = pktlib.icmp() layer4.type = ident.dport >> 8 layer4.code = ident.dport & 0x00FF payloadlen = max(iplen-28,0) elif ident.ipproto == IPPROTO_UDP: layer4 = pktlib.udp() layer4.srcport = ident.sport layer4.dstport = ident.dport elif ident.ipproto == IPPROTO_TCP: layer4 = pktlib.tcp() layer4.srcport = ident.sport layer4.dstport = ident.dport layer4.flags = flowlet.tcpflags layer4.off = 5 payloadlen = max(iplen-40,0) layer4.tcplen = payloadlen layer4.payload = spack('{}x'.format(payloadlen)) else: raise UnhandledPoxPacketFlowletTranslation("Can't translate IP protocol {} from flowlet to POX packet".format(fident.ipproto)) ipv4.payload = layer4 etherhdr.origflet = flowlet return etherhdr
def create_packet (e1,e2,i1,i2,t1,t2): e = pkt.ethernet( src = e1, dst = e2, type = pkt.ethernet.IP_TYPE) i = pkt.ipv4( srcip = i1, dstip = i2, protocol = pkt.ipv4.TCP_PROTOCOL) t = pkt.tcp( srcport = t1, dstport = t2, off = 5, win = 1) t.ACK = True i.payload = t e.payload = i return e
def create_packet(self, e1, e2, i1, i2, t1, t2): """ Cria um pacote Ethernet. :param e1: Endereço de origem do pacote. :param e2: Endereço de destino do pacote. :param i1: IP de origem do pacote. :param i2: IP de destino do pacote. :param t1: Porta de origem do pacote. :param t2: Porta de destino do pacote. :return: Pacote Ethernet. """ e = pkt.ethernet(src=e1, dst=e2, type=pkt.ethernet.IP_TYPE) i = pkt.ipv4(srcip=i1, dstip=i2, protocol=pkt.ipv4.TCP_PROTOCOL) t = pkt.tcp(srcport=t1, dstport=t2, off=5, win=1) t.ACK = True i.payload = t e.payload = i return e
def send_control_packet(self, packet, port, SYN, ACK, FIN): """ Send control packet SYN, ACK, FIN according to specified flag """ src_mac = packet.src ip_packet = packet.find('ipv4') tcpp = packet.find('tcp') key = str(ip_packet.srcip)+":"+str(tcpp.srcport) client = self.clients[key] conn_seq = client['seq'] if tcpp.FIN: client['ack'] = client['ack'] + 1 else: client['ack'] = tcpp.seq + tcpp.tcplen - tcpp.off * 4 tcp_packet = pkt.tcp() tcp_packet.srcport = 11111 tcp_packet.dstport = tcpp.srcport tcp_packet.seq = conn_seq tcp_packet.ack = client['ack'] tcp_packet.off = 5 tcp_packet.tcplen = pkt.tcp.MIN_LEN tcp_packet.win = 29000 tcp_packet._setflag(tcp_packet.SYN_flag, SYN) tcp_packet._setflag(tcp_packet.ACK_flag, ACK) tcp_packet._setflag(tcp_packet.FIN_flag, FIN) ipv4_packet = pkt.ipv4() ipv4_packet.iplen = pkt.ipv4.MIN_LEN + len(tcp_packet) ipv4_packet.protocol = pkt.ipv4.TCP_PROTOCOL ipv4_packet.dstip = ip_packet.srcip ipv4_packet.srcip = self.ip ipv4_packet.set_payload(tcp_packet) eth_packet = pkt.ethernet() eth_packet.set_payload(ipv4_packet) eth_packet.dst = src_mac eth_packet.src = self.mac eth_packet.type = pkt.ethernet.IP_TYPE self.send_packet(eth_packet, port)
def tests(): f = Firewall() ip = pktlib.tcp() ip.srcip = IPAddr("172.16.42.42") ip.dstip = IPAddr("192.128.42.42") ip.protocol = 17 xudp = pktlib.udp() xudp.srcport = 80 xudp.dstport = 53 xudp.payload = "Hello, world" xudp.len = 8 + len(xudp.payload) ip.payload = xudp print len(ip) # print the length of the packet, just for fun assert(f.allow(ip) == True) time.sleep(0.5) f.update_token_buckets()
def networkMatch(self, ruleObject, pkt): if (ruleObject.type == type(pkt)): if ruleObject.netMask != None: pktsrc = IPAddr(ruleObject.netMask.toUnsigned() & pkt.srcip.toUnsigned()) else: pktsrc = pkt.srcip #checks if it is a network address or not if "/" in str(ruleObject.src): templist = [] templist = ruleObject.src.split("/") rulesrc = IPAddr(templist[0]) else: rulesrc = ruleObject.src if "/" in str(ruleObject.dst): templist = [] templist = ruleObject.dst.split("/") ruledst = IPAddr(templist[0]) else: ruledst = ruleObject.dst #first type: ipv4/icmp if type(pkt) == type(pktlib.ipv4()) or type(pkt) == type(pktlib.icmp()): conditional1 = (ruleObject.type == type(pkt)), (rulesrc == pktsrc or rulesrc == 1), (ruledst == pkt.dstip or ruledst == 1) if ruleObject.ratelimit != None: conditional1a = (ruleObject.type == type(pkt)), (rulesrc == pktsrc or rulesrc == 1), (ruledst == pkt.dstip or ruledst == 1), (ruleObject.bucket >= len(pkt.pack())) return all(conditional1a) else: return all(conditional1) #second type: udp/tcp if type(pkt) == type(pktlib.tcp()) or type(pkt) == type(pktlib.udp()): conditional2 = (ruleObject.type == type(pkt)), (rulesrc == pktsrc or rulesrc == 1), ((ruledst == 1) or (ruledst == pkt.dstip)), (int(ruleObject.srcport) == int(pkt.payload.srcport) or int(ruleObject.srcport) == 1), (int(ruleObject.dstport) == int(pkt.payload.dstport) or int(ruleObject.dstport) == 1) if ruleObject.ratelimit != None: conditional2a = (ruleObject.type == type(pkt)), (rulesrc == pktsrc or rulesrc == 1), (ruledst == pkt.dstip or ruledst ==1), (int(ruleObject.srcport) == int(pkt.payload.srcport) or int(ruleObject.srcport) == 1), (int(ruleObject.dstport) == int(pkt.payload.dstport) or int(ruleObject.dstport) == 1), (ruleObject.bucket >= len(pkt.pack())) return all(conditional2a) else: return all(conditional2)
def pack_message(self, packet, client): """ Repack a message packet according to different clients connection info """ ip_packet = packet.find('ipv4') tcpp = packet.find('tcp') client_ip = client['ip'] client_mac = client['mac'] client_port = client['host_port'] conn_seq = client['seq'] conn_ack = client['ack'] tcp_packet = pkt.tcp() tcp_packet.srcport = 11111 tcp_packet.dstport = client_port tcp_packet.seq = conn_seq tcp_packet.ack = conn_ack tcp_packet.off = 5 tcp_packet.tcplen = tcpp.tcplen tcp_packet.win = 29000 tcp_packet._setflag(tcp_packet.SYN_flag,0) tcp_packet._setflag(tcp_packet.ACK_flag,1) tcp_packet._setflag(tcp_packet.PSH_flag,1) tcp_packet.payload = tcpp.payload ipv4_packet = pkt.ipv4() ipv4_packet.iplen = pkt.ipv4.MIN_LEN + len(tcp_packet) ipv4_packet.protocol = pkt.ipv4.TCP_PROTOCOL ipv4_packet.dstip = client_ip ipv4_packet.srcip = self.ip ipv4_packet.set_payload(tcp_packet) eth_packet = pkt.ethernet() eth_packet.set_payload(ipv4_packet) eth_packet.dst = client_mac eth_packet.src = self.mac eth_packet.type = pkt.ethernet.IP_TYPE return eth_packet
def new_connection(self, packet, in_port): """ Send SYN/ACK to client, maintain connection info for new client """ src_mac = packet.src ip_packet = packet.find('ipv4') tcpp = packet.find('tcp') tcp_packet = pkt.tcp() tcp_packet.srcport = 11111 tcp_packet.dstport = tcpp.srcport tcp_packet.seq = 0 tcp_packet.ack = tcpp.seq + 1 tcp_packet.off = 10 tcp_packet.win = 29000 tcp_packet.tcplen = tcpp.tcplen tcp_packet._setflag(tcp_packet.SYN_flag,1) tcp_packet._setflag(tcp_packet.ACK_flag,1) tcp_packet.options = tcpp.options ipv4_packet = pkt.ipv4() ipv4_packet.iplen = pkt.ipv4.MIN_LEN + len(tcp_packet) ipv4_packet.protocol = pkt.ipv4.TCP_PROTOCOL ipv4_packet.dstip = ip_packet.srcip ipv4_packet.srcip = self.ip ipv4_packet.set_payload(tcp_packet) eth_packet = pkt.ethernet() eth_packet.set_payload(ipv4_packet) eth_packet.dst = src_mac eth_packet.src = self.mac eth_packet.type = pkt.ethernet.IP_TYPE client = {'ip':ip_packet.srcip, 'host_port':tcpp.srcport, 'switch_port':in_port, 'mac':src_mac, 'seq':1, 'ack':1} key = str(ip_packet.srcip)+":"+str(tcpp.srcport) self.clients[key] = client self.send_packet(eth_packet, in_port)
def tests(): f = Firewall() ip = ipv4() ip.srcip = IPAddr("172.16.42.1") ip.dstip = IPAddr("10.0.0.2") ip.protocol = 17 xudp = udp() xudp.srcport = 53 xudp.dstport = 53 xudp.payload = "Hello, world" xudp.len = 8 + len(xudp.payload) ip.payload = xudp print len(ip) # print the length of the packet, just for fun # you can name this method what ever you like, but you'll # need some method that gets periodically invoked for updating # token bucket state for any rules with rate limits f.update_token_buckets() # again, you can name your "checker" as you want, but the # idea here is that we call some method on the firewall to # test whether a given packet should be permitted or denied. assert(f.allow(ip) == True) #if you want to simulate a time delay and updating token buckets, #you can just call time.sleep and then update the buckets. ##time.sleep(0.5) ##f.update_token_buckets() #### #192.168.42.0/24, should be denied ip = ipv4() ip.srcip = IPAddr("192.168.42.1") ip.dstip = IPAddr("10.0.0.2") ip.protocol = 17 xudp = udp() xudp.srcport = 53 xudp.dstport = 53 xudp.payload = "Hello, world, ye shall never know me" xudp.len = 8 + len(xudp.payload) ip.payload = xudp print len(ip) # print the length of the packet, just for fun assert(f.allow(ip) == False) ##### #permit tcp src 172.16.42.0/24 srcport any dst any dstport 443 ip = ipv4() ip.srcip = IPAddr("172.16.42.3") ip.dstip = IPAddr("192.168.0.2") ip.protocol = 6 xtcp = tcp() xtcp.srcport = 666 xtcp.dstport = 443 xtcp.payload = "And so I shall pass from this world and into the next" xtcp.len = 8 + len(xtcp.payload) ip.payload = xtcp print len(ip) # print the length of the packet, just for fun assert(f.allow(ip) == True) ###### ip = ipv4() ip.srcip = IPAddr("172.16.42.1") ip.dstip = IPAddr("10.0.0.2") ip.protocol = 6 xtcp = tcp() xtcp.srcport = 53 xtcp.dstport = 80 xtcp.payload = "Hello, world" xtcp.len = 8 + len(xtcp.payload) ip.payload = xtcp print len(ip) # print the length of the packet, just for fun for i in range(400): #Trying to break the bucket. Works at a bit above 400 if i % 100 == 0: print i/100 assert(f.allow(ip) == True) ##### time.sleep(0.5) f.update_token_buckets()
def send_redirect (event,packet,url): # Check if TCP tcp_in = packet.find("tcp") #print "Send TCP Reset" http_resp = pkt.tcp() payload = "" # Send HTTP response packet # Ethernet frame e = pkt.ethernet() e.src = packet.dst e.dst = packet.src e.type = e.IP_TYPE # Now create the IPv4 packet ipp = pkt.ipv4() ipp.protocol = ipp.TCP_PROTOCOL ipp.srcip = packet.find("ipv4").dstip ipp.dstip = packet.find("ipv4").srcip ipp.flags = packet.find("ipv4").flags # Now that we are established respond to any request with an ACK http_resp.ACK = True http_resp.dstport = tcp_in.srcport http_resp.srcport = tcp_in.dstport http_resp.seq = tcp_in.seq # Needs to be seq_num + http_resp.ack = tcp_in.seq + tcp_in.payload_len http_resp.options = tcp_in.options http_resp.off = 8 http_resp.win = tcp_in.win # Hook them up... ipp.payload = http_resp e.payload = ipp # Send it back to the input port msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.data = e.pack() msg.in_port = event.port event.connection.send(msg) # Next lets send the HTTP redirect http_resp.PSH = True # ADD MAC AND IP TO URL url_f = url + "?mac=" + str(e.dst) + "&ip=" + str(ipp.dstip) http_resp.payload = get_redirect_payload(url_f) #PRINT "GET TOTAL SIZE %D" % LEN(TCP_IN) print "GET PAYLOAD SIZE %d" % tcp_in.payload_len # Hook them up... ipp.payload = http_resp e.payload = ipp # Send it back to the input port msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.data = e.pack() msg.in_port = event.port event.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)