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 reply(cls, event, msg): orig = event.parsed.find('dhcp') broadcast = (orig.flags & orig.BROADCAST_FLAG) != 0 msg.op = msg.BOOTREPLY msg.chaddr = event.parsed.src msg.htype = 1 msg.hlen = 6 msg.xid = orig.xid msg.add_option(pkt.DHCP.DHCPServerIdentifierOption(cls.server_addr)) ethp = pkt.ethernet(src=EthAddr('02:00:00:00:00:24'), dst=event.parsed.src) ethp.type = pkt.ethernet.IP_TYPE ipp = pkt.ipv4(srcip=cls.server_addr) ipp.dstip = event.parsed.find('ipv4').srcip if broadcast: ipp.dstip = IPAddr('255.255.255.255') eth.dst = pkt.ETHERNET.ETHER_BROADCAST ipp.protocol = ipp.UDP_PROTOCOL udpp = pkt.udp() udpp.srcport = pkt.dhcp.SERVER_PORT udpp.dstport = pkt.dhcp.CLIENT_PORT udpp.payload = msg ipp.payload = udpp ethp.payload = ipp po = of.ofp_packet_out(data=ethp.pack()) po.actions.append(of.ofp_action_output(port=event.port)) event.connection.send(po)
def reply(self, event, subnet, msg): # fill out the rest of the DHCP packet orig = event.parsed.find('dhcp') broadcast = (orig.flags & orig.BROADCAST_FLAG) != 0 msg.op = msg.BOOTREPLY msg.chaddr = event.parsed.src msg.htype = 1 msg.hlen = 6 msg.xid = orig.xid msg.add_option(pkt.DHCP.DHCPServerIdentifierOption(subnet.server.addr)) # create ethernet header ethp = pkt.ethernet(src=ip_for_event(event), dst=event.parsed.src) ethp.type = pkt.ethernet.IP_TYPE ipp = pkt.ipv4(srcip=subnet.server.addr) ipp.dstip = event.parsed.find('ipv4').srcip if broadcast: ipp.dstip = IP_BROADCAST ethp.dst = pkt.ETHERNET.ETHER_BROADCAST # create UDP header ipp.protocol = ipp.UDP_PROTOCOL udpp = pkt.udp() udpp.srcport = pkt.dhcp.SERVER_PORT udpp.dstport = pkt.dhcp.CLIENT_PORT # encapsulate and reply to host udpp.payload = msg ipp.payload = udpp ethp.payload = ipp po = of.ofp_packet_out(data=ethp.pack()) po.actions.append(of.ofp_action_output(port=event.port)) event.connection.send(po)
def create_ipv4_dns(self, req_packet, dns_rep): ether_req = req_packet.find('ethernet') udp_req = req_packet.find('udp') ipv4_req = req_packet.find('ipv4') if ether_req is None or udp_req is None or ipv4_req is None: return ether_rep = pkt.ethernet(ether_req.raw) #reply ethernet udp_rep = pkt.udp(udp_req.raw) #reply upd pkt ipv4_rep = pkt.ipv4(ipv4_req.raw) #reply ipv4 pkt #swap MACs ether_rep.dst = ether_req.src ether_rep.src = ether_req.dst ether_rep.type = pkt.ethernet.IP_TYPE #swap udp ports. udp_rep.dstport = udp_req.srcport udp_rep.srcport = 53 #swap ipaddresses. ipv4_rep.srcip = ipv4_req.dstip ipv4_rep.dstip = ipv4_req.srcip #ipv4_rep.srcport = ipv4_req.dstport #ipv4_rep.dstport = ipv4_req.srcport #put payloads udp_rep.payload = dns_rep ipv4_rep.payload = udp_rep ether_rep.payload = ipv4_rep return ether_rep
def reply (self, event, msg): orig = event.parsed.find('dhcp') broadcast = (orig.flags & orig.BROADCAST_FLAG) != 0 msg.op = msg.BOOTREPLY msg.chaddr = event.parsed.src msg.htype = 1 msg.hlen = 6 msg.xid = orig.xid msg.add_option(pkt.DHCP.DHCPServerIdentifierOption(self.ip_addr)) ethp = pkt.ethernet(src=ip_for_event(event),dst=event.parsed.src) ethp.type = pkt.ethernet.IP_TYPE ipp = pkt.ipv4(srcip = self.ip_addr) ipp.dstip = event.parsed.find('ipv4').srcip if broadcast: ipp.dstip = IP_BROADCAST ethp.dst = pkt.ETHERNET.ETHER_BROADCAST ipp.protocol = ipp.UDP_PROTOCOL udpp = pkt.udp() udpp.srcport = pkt.dhcp.SERVER_PORT udpp.dstport = pkt.dhcp.CLIENT_PORT udpp.payload = msg ipp.payload = udpp ethp.payload = ipp po = of.ofp_packet_out(data=ethp.pack()) po.actions.append(of.ofp_action_output(port=event.port)) event.connection.send(po)
def send_udp_packet_out(self, conn, payload, tp_src, tp_dst,src_ip, dst_ip, src_mac, dst_mac, fw_port = of.OFPP_ALL): msg = of.ofp_packet_out(in_port=of.OFPP_NONE) msg.buffer_id = None #Make the udp packet udpp = pkt.udp() udpp.srcport = tp_src udpp.dstport = tp_dst udpp.payload = payload #Make the IP packet around it ipp = pkt.ipv4() ipp.protocol = ipp.UDP_PROTOCOL ipp.srcip = IPAddr(src_ip) ipp.dstip = IPAddr(dst_ip) # Ethernet around that... ethp = pkt.ethernet() ethp.src = EthAddr(src_mac) ethp.dst = EthAddr(dst_mac) ethp.type = ethp.IP_TYPE # Hook them up... ipp.payload = udpp ethp.payload = ipp # Send it to the sw msg.actions.append(of.ofp_action_output(port = fw_port)) msg.data = ethp.pack() #show msg before sending """ print '*******************' print 'msg.show(): ',msg.show() print '*******************' """ print "self.send_udp_packet_out; sw%s and fw_port:%s" %(conn.dpid, fw_port) conn.send(msg)
def send_udp_packet_out(self, conn, payload, tp_src, tp_dst,src_ip, dst_ip, src_mac, dst_mac, fw_port = of.OFPP_ALL): msg = of.ofp_packet_out(in_port=of.OFPP_NONE) msg.buffer_id = None #Make the udp packet udpp = pkt.udp() udpp.srcport = tp_src udpp.dstport = tp_dst udpp.payload = payload #Make the IP packet around it ipp = pkt.ipv4() ipp.protocol = ipp.UDP_PROTOCOL ipp.srcip = IPAddr(src_ip) ipp.dstip = IPAddr(dst_ip) # Ethernet around that... ethp = pkt.ethernet() ethp.src = EthAddr(src_mac) ethp.dst = EthAddr(dst_mac) ethp.type = ethp.IP_TYPE # Hook them up... ipp.payload = udpp ethp.payload = ipp # Send it to the sw msg.actions.append(of.ofp_action_output(port = fw_port)) msg.data = ethp.pack() #show msg before sending """ print '*******************' print 'msg.show(): ',msg.show() print '*******************' """ #print "send_udp_packet_out; sw%s and fw_port:%s" %(conn.dpid, fw_port) conn.send(msg)
def send_updates(self, force): conn = self._conn if not conn: return direct = self._get_port_ip_map() out = [] for port, dests in direct.items(): if port not in conn.ports: self.log.warn("No such port %s", port) continue if port not in self._ports: # We aren't configured to do RIP on this port continue responses = self.get_responses(dests, force=force) #self.log.debug("Sending %s RIP packets via %s", len(responses), iface) for r in responses: udpp = pkt.udp() udpp.payload = r udpp.dstport = RIP.RIP_PORT udpp.srcport = RIP.RIP_PORT ipp = pkt.ipv4() ipp.payload = udpp ipp.dstip = RIP.RIP2_ADDRESS ipp.protocol = ipp.UDP_PROTOCOL # We may have multiple IPs on this interface. Should we send an # advertisement from each one? The RIP spec isn't very clear. # Assume no, and we want to just send one. So just pick a source # IP from the ones available. ipp.srcip = self._ports[port].any_ip ethp = pkt.ethernet() ethp.payload = ipp ethp.dst = RIP.RIP2_ADDRESS.multicast_ethernet_address ethp.type = ethp.IP_TYPE src = conn.ports.get(port) if src is None: self.log.warn("Missing port %s", port) continue ethp.src = src.hw_addr msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=port)) msg.data = ethp.pack() out.append(msg.pack()) #self.log.debug("Sending %s updates", len(out)) if out: conn.send(b''.join(out)) self._mark_all_clean()
def parse_dhcp(self, dhcp_packet, event): print "dhcp packet handler" if len(dhcp_packet.options) == 0: return if pkt.dhcp.HOST_NAME_OPT in dhcp_packet.options: self.hostname = dhcp_packet.options[pkt.dhcp.HOST_NAME_OPT].data if pkt.dhcp.REQUEST_IP_OPT in dhcp_packet.options: self.requestedIp = dhcp_packet.options[pkt.dhcp.REQUEST_IP_OPT].addr if pkt.dhcp.MSG_TYPE_OPT in dhcp_packet.options: mt = dhcp_packet.options[pkt.dhcp.MSG_TYPE_OPT] self.dhcp_msg_type = mt if mt == pkt.dhcp.INFORM_MSG: return elif mt == pkt.dhcp.DECLINE_MSG: return ip = self.select_ip(dhcp_packet.chaddr, mt) if mt == pkt.dhcp.RELEASE_MSG: #find mapping and delete it self.insert_couchdb("del", ip, dhcp_packet.chaddr, None) return reply_msg_type = pkt.dhcp.OFFER_MSG if self.dhcp_msg_type.type == pkt.dhcp.DISCOVER_MSG else pkt.dhcp.ACK_MSG if self.requestedIp != 0 and self.dhcp_msg_type == pkt.dhcp.REQUEST_MSG and self.requestedIp != int(ip): reply_msg_type = pkt.dhcp.nak ip = self.requestedIp print "not allowed that address" reply = self.generate_dhcp_reply(dhcp_packet, ip, reply_msg_type, MAX_ROUTABLE_LEASE) if reply_msg_type == pkt.dhcp.ACK_MSG: self.add_addr(str(self.increment_ip(ip))) self.insert_couchdb("add", ip, dhcp_packet.chaddr, self.hostname) eth = pkt.ethernet(src=ip_for_event(event), dst=event.parsed.src) eth.type = pkt.ethernet.IP_TYPE ipp = pkt.ipv4(srcip=self.increment_ip(ip)) ipp.dstip = event.parsed.find('ipv4').srcip broadcast = (dhcp_packet.ciaddr == 0) if broadcast: ipp.dstip = IP_BROADCAST eth.dst = pkt.ETHERNET.ETHER_BROADCAST ipp.protocol = ipp.UDP_PROTOCOL udpp = pkt.udp() udpp.srcport = pkt.dhcp.SERVER_PORT udpp.dstport = pkt.dhcp.CLIENT_PORT udpp.payload = reply ipp.payload = udpp eth.payload = ipp msg = of.ofp_packet_out(data=eth.pack()) msg.actions.append(of.ofp_action_output(port=event.port)) event.connection.send(msg)
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 _send_dhcp (self, msg): ethp = pkt.ethernet(src=self.port_eth, dst=pkt.ETHER_BROADCAST) ethp.type = pkt.ethernet.IP_TYPE ipp = pkt.ipv4() ipp.srcip = pkt.IP_ANY #NOTE: If rebinding, use existing local IP? ipp.dstip = pkt.IP_BROADCAST ipp.protocol = ipp.UDP_PROTOCOL udpp = pkt.udp() udpp.srcport = pkt.dhcp.CLIENT_PORT udpp.dstport = pkt.dhcp.SERVER_PORT udpp.payload = msg ipp.payload = udpp ethp.payload = ipp self._send_data(ethp.pack())
def handle_dns_packet(self, packet, event): dns_name = str(packet.questions[0].name) dns_type = packet.questions[0].qtype dns_class = packet.questions[0].qclass log.info("name " + dns_name + " type " + pkt.rrtype_to_str[dns_type] + " class " + pkt.rrclass_to_str[dns_class]) log.info("Len " + str(len(packet.questions))) dns_reply = dns() dns_reply.qr = True dns_reply.rd = True dns_reply.ra = True answ = dns.rr("www.google.com",1,1,3600,4,IPAddr("1.1.1.1")) dns_reply.answers.append(answ) dns_reply.questions = packet.questions dns_reply.id = packet.id #dns_reply.total_questions = packet.total_questions #dns_reply.total_answers = 1 udp_req = event.parsed.find("udp") udp_reply = udp() udp_reply.srcport = udp_req.srcport udp_reply.dstport = udp_req.dstport udp_reply.len = len(dns_reply) + udp_reply.MIN_LEN udp_reply.set_payload(dns_reply) ip_reply = ipv4() ip_req = event.parsed.find("ipv4") reqSrc = ip_req.dstip reqDst = ip_req.srcip ip_reply = ip_req ip_reply.srcip = reqDst ip_reply.dstip = reqSrc ip_reply.set_payload(udp_reply) eth_reply = ethernet() eth_reply.type = ethernet.IP_TYPE eth_reply.dst = EthAddr("00:00:00:00:00:02") eth_reply.src = EthAddr("00:00:00:00:00:01") eth_reply.set_payload(ip_reply) msg = of.ofp_packet_out() msg.data = eth_reply.pack() msg.actions.append(of.ofp_action_output(port = 2)) msg.in_port = event.port self.connection.send(msg) log.info("send DNS response...")
def _send_dhcp (self, msg): ethp = pkt.ethernet(src=self.port_eth, dst=pkt.ETHER_BROADCAST) ethp.type = pkt.ethernet.IP_TYPE ipp = pkt.ipv4() ipp.srcip = pkt.IP_ANY #NOTE: If rebinding, use existing local IP? ipp.dstip = pkt.IP_BROADCAST ipp.protocol = ipp.UDP_PROTOCOL udpp = pkt.udp() udpp.srcport = pkt.dhcp.CLIENT_PORT udpp.dstport = pkt.dhcp.SERVER_PORT udpp.payload = msg ipp.payload = udpp ethp.payload = ipp po = of.ofp_packet_out(data=ethp.pack()) po.actions.append(of.ofp_action_output(port=self.portno)) self._con.send(po)
def _send_dhcp(self, msg): ethp = pkt.ethernet(src=self.port_eth, dst=pkt.ETHER_BROADCAST) ethp.type = pkt.ethernet.IP_TYPE ipp = pkt.ipv4() ipp.srcip = pkt.IP_ANY #NOTE: If rebinding, use existing local IP? ipp.dstip = pkt.IP_BROADCAST ipp.protocol = ipp.UDP_PROTOCOL udpp = pkt.udp() udpp.srcport = pkt.dhcp.CLIENT_PORT udpp.dstport = pkt.dhcp.SERVER_PORT udpp.payload = msg ipp.payload = udpp ethp.payload = ipp po = of.ofp_packet_out(data=ethp.pack()) po.actions.append(of.ofp_action_output(port=self.portno)) self._con.send(po)
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 _handle_PacketIn (self, event): if not event.parsed: return q_dns = event.parsed.find('dns') if q_dns is None: return if not event.parsed.find('ipv4'): return log.debug(q_dns) r_dns = pkt_dns() r_dns.qr = True r_dns.aa = True for q in q_dns.questions: if rrclass_to_str[q.qclass] != "IN": # Internet only continue log.debug('q: (%s,%s)' % (q.name, q.qtype)) qtype = rrtype_to_str.get(q.qtype, 'unknown') attr = getattr(self, "_answer_" + qtype, self._answer_unknown) port, rr = attr(q) if port: r_dns.answers.append(rr) r_mac_src = EthAddr(port.mac) r_ip_src = IPAddr(port.ip) if not r_dns.answers: log.debug('cannot answer questions') return q_eth = event.parsed.find('ethernet') q_ip = event.parsed.find('ipv4') q_udp = event.parsed.find('udp') r_eth = pkt.ethernet(src=r_mac_src, dst=q_eth.dst) r_eth.type = pkt.ethernet.IP_TYPE r_ip = pkt.ipv4(srcip=r_ip_src, dstip=q_ip.dstip) r_ip.protocol = r_ip.UDP_PROTOCOL r_udp = pkt.udp() r_udp.srcport = q_udp.dstport r_udp.dstport = q_udp.srcport r_udp.payload = r_dns r_ip.payload = r_udp r_eth.payload = r_ip r_pkt = of.ofp_packet_out(data=r_eth.pack()) r_pkt.actions.append(of.ofp_action_output(port=event.port)) log.debug('response: %s' % r_dns) event.connection.send(r_pkt)
def _handle_PacketIn (self, event): if not event.parsed: return q_dns = event.parsed.find('dns') if q_dns is None: return if not event.parsed.find('ipv4'): return log.debug(q_dns) r_dns = pkt_dns() r_dns.qr = True r_dns.aa = True for q in q_dns.questions: if rrclass_to_str[q.qclass] != "IN": # Internet only continue log.debug('q: (%s,%s)' % (q.name, q.qtype)) attr = getattr(self, "_answer_" + rrtype_to_str[q.qtype], self._answer_unknown) port, rr = attr(q) if port: r_dns.answers.append(rr) r_mac_src = EthAddr(port.mac) r_ip_src = IPAddr(port.ip) if not r_dns.answers: log.debug('cannot answer questions') return q_eth = event.parsed.find('ethernet') q_ip = event.parsed.find('ipv4') q_udp = event.parsed.find('udp') r_eth = pkt.ethernet(src=r_mac_src, dst=q_eth.dst) r_eth.type = pkt.ethernet.IP_TYPE r_ip = pkt.ipv4(srcip=r_ip_src, dstip=q_ip.dstip) r_ip.protocol = r_ip.UDP_PROTOCOL r_udp = pkt.udp() r_udp.srcport = q_udp.dstport r_udp.dstport = q_udp.srcport r_udp.payload = r_dns r_ip.payload = r_udp r_eth.payload = r_ip r_pkt = of.ofp_packet_out(data=r_eth.pack()) r_pkt.actions.append(of.ofp_action_output(port=event.port)) log.debug('response: %s' % r_dns) event.connection.send(r_pkt)
def tests(): f = Firewall() ip1 = ipv4() ip1.srcip = IPAddr("172.16.42.1") ip1.dstip = IPAddr("10.0.0.2") ip1.protocol = 17 xudp1 = udp() xudp1.srcport = 53 xudp1.dstport = 53 xudp1.payload = "Hello, world" xudp1.len = 8 + len(xudp1.payload) ip1.payload = xudp1 ip2 = ipv4() ip2.srcip = IPAddr("172.16.40.1") ip2.dstip = IPAddr("10.0.0.1") ip2.protocol = ip2.ICMP_PROTOCOL icmppkt = icmp() icmppkt.type = pktlib.TYPE_ECHO_REQUEST ping = pktlib.echo() ping.id = 5 ping.seq = 10 icmppkt.payload = ping ip2.payload = icmppkt ip3 = ipv4() ip3.srcip = IPAddr("172.16.38.0") ip3.dstip = IPAddr("10.0.0.5") ip3.protocol = ip2.ICMP_PROTOCOL icmppkt = icmp() icmppkt.type = pktlib.TYPE_ECHO_REQUEST ping = pktlib.echo() ping.id = 5 ping.seq = 10 icmppkt.payload = ping ip3.payload = icmppkt i=0 while i<10: print "+"*70 f.update_token_buckets() f.allow(ip2) f.allow(ip3) time.sleep(0.5) i+=1
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 broadcast_routing_table(self): rip_msg = pkt.rip() rip_msg.version = 2 rip_msg.command = pkt.RIP_RESPONSE for entry in self.routing_table: rip_entry = pkt.RIPEntry() rip_entry.ip = adr.IPAddr(entry.split("/")[0]) rip_entry.netmask = int(entry.split("/")[1]) rip_entry.metric = self.routing_table[entry][-1] rip_msg.entries.append(rip_entry) if entry[1] != forever_ttl: --self.routing_table[entry][1] if self.routing_table[entry][1] == 0: del self.routing_table[entry] udp = pkt.udp() udp.srcport = 520 udp.dstport = 520 # log.debug( "Created rip msg of len: %d", len(rip_msg) ) udp.len = len(rip_msg) udp.payload = rip_msg ipv4 = pkt.ipv4() ipv4.protocol = pkt.ipv4.UDP_PROTOCOL ipv4.srcip = pkt.IP_ANY ipv4.dstip = pkt.rip.RIP2_ADDRESS ipv4.payload = udp ether = pkt.ethernet() ether.type = pkt.ethernet.IP_TYPE ether.dst = adr.EthAddr('ff:ff:ff:ff:ff:ff') ether.payload = ipv4 for port in self.port_to_hwaddr.keys()[0:-1]: ether.src = self.port_to_hwaddr[port] # log.debug( "Broadcasting routing table" ) msg = of.ofp_packet_out() msg.data = ether.pack() # Add an action to send to the specified port action = of.ofp_action_output(port=port) msg.actions.append(action) self.connection.send(msg)
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 create_udp_pkt(srcip, dstip, dstport, dstmac, data): """ """ payload = data udp_pkt = pkt.udp() udp_pkt.srcport = 10000 udp_pkt.dstport = dstport udp_pkt.payload = payload ipv4_pkt = pkt.ipv4() ipv4_pkt.protocol = pkt.ipv4.UDP_PROTOCOL ipv4_pkt.srcip = srcip ipv4_pkt.dstip = dstip ipv4_pkt.payload = udp_pkt ether_pkt = pkt.ethernet() ether_pkt.dst = dstmac ether_pkt.src = EthAddr("00:11:22:33:44:55") ether_pkt.type = ether_pkt.IP_TYPE ether_pkt.payload = ipv4_pkt return ether_pkt
def send_UDP_response(self, responseCode, destIP, data): routable, destination_network = self.checkRoutableDestination(destIP) if routable: print "#Building a UDP packet destined for " + str(destIP) sourceMAC = self.arp_table[self.routing_table[destination_network] ['RouterInterface']] destMAC = self.arp_table[destIP] output_port = self.routing_table[destination_network]['Port'] sourceIP = self.routing_table[destination_network][ 'RouterInterface'] print "#Source IP : " + str(sourceIP) + " Source MAC : " + str( sourceMAC) + " destMAC : " + str( destMAC) + " output_port : " + str(output_port) if destIP not in self.arp_table: print "\n#Sending ARP Request to destination IP ...#" self.ARPResolve(destIP, destination_network, output_port) print "Waiting for ARP Reply ..." while destIP not in self.buffer.keys(): pass print "ARP Response was received!" #Building and sending a UDP response to the client. e = pkt.ethernet(src=EthAddr(sourceMAC), dst=EthAddr(destMAC), type=pkt.ethernet.IP_TYPE) i = pkt.ipv4(srcip=IPAddr(sourceIP), dstip=IPAddr(destIP), protocol=pkt.ipv4.UDP_PROTOCOL) u = pkt.udp(srcport=10000, dstport=10000) #,off = 5,win = 1) #t.ACK = True u.payload = str({"res": responseCode, "data": data}) i.payload = u e.payload = i self.resend_packet(e, output_port)
def _handle_PacketIn (self, event): packet = event.parsed # Hold on to the original UDP packet we received old_udp = packet.find("udp") # Check for some conditions # In our Mozilla experiment, we send UDP packets on port 10002 # so we look for those if old_udp and old_udp.dstport == 10002: # The goal here is to take the contents of the original # UDP packet and modify them. When then need to package # It up in an enclosing IP packet # And finally, enclose it in an Ethernet packet # Create a new packet with the same info as the old # - ecept the contents are modified new_udp = pkt.udp() new_udp.srcport = old_udp.srcport new_udp.dstport = old_udp.dstport new_udp.payload = 'Modified with Openflow:' + old_udp.payload # Create new new IP packet to enclose the UDP # packet we just created. The line that says new_ip.payload = new_udp # is where that happens new_ip = pkt.ipv4() new_ip.protocol = new_ip.UDP_PROTOCOL new_ip.srcip = packet.find("ipv4").srcip new_ip.dstip = packet.find("ipv4").dstip new_ip.payload = new_udp # And like before, enclose the IP packet in an ethernet packet new_eth = pkt.ethernet() new_eth.src = packet.src new_eth.dst = packet.dst new_eth.type = new_eth.IP_TYPE new_eth.payload = new_ip # Now let's encapsulate all this in a special message that # will be sent back to our router. The instruction here # for the switch is to forward the packet we created on # all of the router/switch's physical ports msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL)) msg.data = new_eth.pack() # Send it along event.connection.send(msg) # Log some data describing what just happened log.debug("Sent a modified UDP packet from %s to %s", new_ip.dstip, new_ip.srcip) log.debug('Original Payload: ' + old_udp.payload) log.debug('New Payload: ' + new_udp.payload) else: # In the event we received some packet we don't care about, # send it to along to where it was headed on all physical ports msg = of.ofp_packet_out() # A bit of a shortcode. Here we're just jamming the old # packet data into a message for the switch. We don't # need to construct a new packet like we did before msg.data = event.ofp msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL)) # Send the instruction to switch self.connection.send(msg)
def _handle_PacketIn(self, event): packet = event.parsed # Hold on to the original UDP packet we received old_udp = packet.find("udp") # Check for some conditions # In our Mozilla experiment, we send UDP packets on port 10002 # so we look for those if old_udp and old_udp.dstport == 10002: # The goal here is to take the contents of the original # UDP packet and modify them. When then need to package # It up in an enclosing IP packet # And finally, enclose it in an Ethernet packet # Create a new packet with the same info as the old # - ecept the contents are modified new_udp = pkt.udp() new_udp.srcport = old_udp.srcport new_udp.dstport = old_udp.dstport new_udp.payload = 'Modified with Openflow:' + old_udp.payload # Create new new IP packet to enclose the UDP # packet we just created. The line that says new_ip.payload = new_udp # is where that happens new_ip = pkt.ipv4() new_ip.protocol = new_ip.UDP_PROTOCOL new_ip.srcip = packet.find("ipv4").srcip new_ip.dstip = packet.find("ipv4").dstip new_ip.payload = new_udp # And like before, enclose the IP packet in an ethernet packet new_eth = pkt.ethernet() new_eth.src = packet.src new_eth.dst = packet.dst new_eth.type = new_eth.IP_TYPE new_eth.payload = new_ip # Now let's encapsulate all this in a special message that # will be sent back to our router. The instruction here # for the switch is to forward the packet we created on # all of the router/switch's physical ports msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL)) msg.data = new_eth.pack() # Send it along event.connection.send(msg) # Log some data describing what just happened log.debug("Sent a modified UDP packet from %s to %s", new_ip.dstip, new_ip.srcip) log.debug('Original Payload: ' + old_udp.payload) log.debug('New Payload: ' + new_udp.payload) else: # In the event we received some packet we don't care about, # send it to along to where it was headed on all physical ports msg = of.ofp_packet_out() # A bit of a shortcode. Here we're just jamming the old # packet data into a message for the switch. We don't # need to construct a new packet like we did before msg.data = event.ofp msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL)) # Send the instruction to switch self.connection.send(msg)
def sendPacket(self, event, new_addr): dpid = event.connection.dpid ipEth = core.learning_switch.arpTable[dpid] packet = event.parsed old_udp = packet.find('udp') # The goal here is to take the contents of the original # UDP packet and modify them. When then need to package # It up in an enclosing IP packet # And finally, enclose it in an Ethernet packet new_addr = IPAddr(new_addr) #log.debug('Sent packet to: %s', new_addr) #log.debug(ipEth) if new_addr in ipEth: packet.dst = ipEth[new_addr] packet.payload.dstip = new_addr log.debug('Sending SUPERCAST from %s to %s: %s', packet.payload.srcip, new_addr, old_udp.payload) new_udp = pkt.udp() new_udp.srcport = old_udp.srcport new_udp.dstport = old_udp.dstport new_udp.payload = old_udp.payload # Create new new IP packet to enclose the UDP # packet we just created. The line that says new_ip.payload = new_udp # is where that happens new_ip = pkt.ipv4() new_ip.protocol = new_ip.UDP_PROTOCOL new_ip.srcip = packet.find("ipv4").srcip new_ip.dstip = new_addr new_ip.payload = new_udp # And like before, enclose the IP packet in an ethernet packet new_eth = pkt.ethernet() new_eth.src = packet.src new_eth.dst = ipEth[new_addr].mac new_eth.type = new_eth.IP_TYPE new_eth.payload = new_ip # Now let's encapsulate all this in a special message that # will be sent back to our router. The instruction here # for the switch is to forward the packet we created on # all of the router/switch's physical ports msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL)) msg.data = new_eth.pack() # Send it along event.connection.send(msg) else: log.debug('Saw a SUPERCAST packet with %s as a recipient, but unknown MAC', new_addr) # Now let's encapsulate all this in a special message that # will be sent back to our router. The instruction here # for the switch is to forward the packet we created on # all of the router/switch's physical ports msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL)) msg.data = event.ofp # Send it along event.connection.send(msg)
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 sendPacket(self, event, new_addr): dpid = event.connection.dpid ipEth = core.learning_switch.arpTable[dpid] packet = event.parsed old_udp = packet.find('udp') # The goal here is to take the contents of the original # UDP packet and modify them. When then need to package # It up in an enclosing IP packet # And finally, enclose it in an Ethernet packet new_addr = IPAddr(new_addr) #log.debug('Sent packet to: %s', new_addr) #log.debug(ipEth) if new_addr in ipEth: packet.dst = ipEth[new_addr] packet.payload.dstip = new_addr log.debug('Sending SUPERCAST from %s to %s: %s', packet.payload.srcip, new_addr, old_udp.payload) new_udp = pkt.udp() new_udp.srcport = old_udp.srcport new_udp.dstport = old_udp.dstport new_udp.payload = old_udp.payload # Create new new IP packet to enclose the UDP # packet we just created. The line that says new_ip.payload = new_udp # is where that happens new_ip = pkt.ipv4() new_ip.protocol = new_ip.UDP_PROTOCOL new_ip.srcip = packet.find("ipv4").srcip new_ip.dstip = new_addr new_ip.payload = new_udp # And like before, enclose the IP packet in an ethernet packet new_eth = pkt.ethernet() new_eth.src = packet.src new_eth.dst = ipEth[new_addr].mac new_eth.type = new_eth.IP_TYPE new_eth.payload = new_ip # Now let's encapsulate all this in a special message that # will be sent back to our router. The instruction here # for the switch is to forward the packet we created on # all of the router/switch's physical ports msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL)) msg.data = new_eth.pack() # Send it along event.connection.send(msg) else: log.debug( 'Saw a SUPERCAST packet with %s as a recipient, but unknown MAC', new_addr) # Now let's encapsulate all this in a special message that # will be sent back to our router. The instruction here # for the switch is to forward the packet we created on # all of the router/switch's physical ports msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_ALL)) msg.data = event.ofp # Send it along event.connection.send(msg)