def _rcv_frame(self, frame): pkt = Ether(frame) self.log.info('received packet', pkt=pkt) if pkt.haslayer(Dot1Q): if pkt.haslayer(Dot1AD): outer_shim = pkt.getlayer(Dot1AD) else: outer_shim = pkt.getlayer(Dot1Q) if pkt.haslayer(IP) or outer_shim.type == EAP_ETH_TYPE: # We don't have any context about the packet at this point. # Assume that only downstream traffic is double-tagged. if isinstance(outer_shim.payload, Dot1Q): logical_port = int(self.nni_port.port_no) else: cvid = outer_shim.vlan logical_port = self.get_subscriber_uni_port(cvid) popped_frame = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload ) kw = dict( logical_device_id=self.logical_device_id, logical_port_no=logical_port, ) self.log.info('sending-packet-in', **kw) self.adapter_agent.send_packet_in( packet=str(popped_frame), **kw) elif pkt.haslayer(Raw): raw_data = json.loads(pkt.getlayer(Raw).load) self.alarms.send_alarm(self, raw_data)
def on_pkt_rx(self, pkt, start_ts): scapy_pkt = Ether(pkt['binary']) if scapy_pkt.haslayer('ICMPv6EchoReply'): node_ip = scapy_pkt.getlayer(IPv6).src hlim = scapy_pkt.getlayer(IPv6).hlim dst_ip = scapy_pkt.getlayer(IPv6).dst if dst_ip != self.src_ip: # not our ping return dt = pkt['ts'] - start_ts self.result['formatted_string'] = 'Reply from {0}: bytes={1}, time={2:.2f}ms, hlim={3}'.format(node_ip, len(pkt['binary']), dt * 1000, hlim) self.result['src_ip'] = node_ip self.result['rtt'] = dt * 1000 self.result['ttl'] = hlim self.result['status'] = 'success' return self.port.ok(self.result) if scapy_pkt.haslayer('ICMPv6ND_NS') and scapy_pkt.haslayer('ICMPv6NDOptSrcLLAddr'): node_mac = scapy_pkt.getlayer(ICMPv6NDOptSrcLLAddr).lladdr node_ip = scapy_pkt.getlayer(IPv6).src dst_ip = scapy_pkt.getlayer(IPv6).dst if dst_ip != self.src_ip: # not our ping return self.send_intermediate(self.generate_ns_na(node_mac, node_ip)) if scapy_pkt.haslayer('ICMPv6DestUnreach'): node_ip = scapy_pkt.getlayer(IPv6).src dst_ip = scapy_pkt.getlayer(IPv6).dst if dst_ip != self.src_ip: # not our ping return self.result['formatted_string'] = 'Reply from {0}: Destination host unreachable'.format(node_ip) self.result['status'] = 'unreachable' return self.port.ok(self.result)
def on_pkt_rx(self, pkt, start_ts): # convert to scapy scapy_pkt = Ether(pkt['binary']) if scapy_pkt.haslayer('ICMPv6ND_NS') and scapy_pkt.haslayer('ICMPv6NDOptSrcLLAddr'): node_mac = scapy_pkt.getlayer(ICMPv6NDOptSrcLLAddr).lladdr node_ip = scapy_pkt.getlayer(IPv6).src if node_ip not in self.responses: self.send_intermediate(self.generate_ns_na(node_mac, node_ip)) elif scapy_pkt.haslayer('ICMPv6ND_NA'): is_router = scapy_pkt.getlayer(ICMPv6ND_NA).R node_ip = scapy_pkt.getlayer(ICMPv6ND_NA).tgt dst_ip = scapy_pkt.getlayer(IPv6).dst node_mac = scapy_pkt.src if node_ip not in self.responses and dst_ip == self.src_ip: self.responses[node_ip] = {'type': 'Router' if is_router else 'Host', 'mac': node_mac} elif scapy_pkt.haslayer('ICMPv6EchoReply'): node_mac = scapy_pkt.src node_ip = scapy_pkt.getlayer(IPv6).src if node_ip == self.dst_ip and node_ip != 'ff02::1': # for ping ipv6 return self.port.ok([{'type': 'N/A', 'ipv6': node_ip, 'mac': node_mac}]) if node_ip not in self.responses: self.send_intermediate(self.generate_ns_na(node_mac, node_ip))
def packet_out(self, egress_port, msg): pkt = Ether(msg) self.log.info('packet out', egress_port=egress_port, packet=str(pkt).encode("HEX")) if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): payload = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload ) else: payload = pkt else: payload = pkt self.log.info('sending-packet-to-device', egress_port=egress_port, packet=str(payload).encode("HEX")) send_pkt = binascii.unhexlify(str(payload).encode("HEX")) onu_pkt = openolt_pb2.OnuPacket(intf_id=intf_id_from_port_num(egress_port), onu_id=onu_id_from_port_num(egress_port), pkt=send_pkt) self.stub.OnuPacketOut(onu_packet)
def packet_out(self, egress_port, msg): pkt = Ether(msg) self.log.debug('packet out', egress_port=egress_port, device_id=self.device_id, logical_device_id=self.logical_device_id, packet=str(pkt).encode("HEX")) # Find port type egress_port_type = self.platform.intf_id_to_port_type_name(egress_port) if egress_port_type == Port.ETHERNET_UNI: if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): # If double tag, remove the outer tag payload = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload) else: payload = pkt else: payload = pkt send_pkt = binascii.unhexlify(str(payload).encode("HEX")) self.log.debug( 'sending-packet-to-ONU', egress_port=egress_port, intf_id=self.platform.intf_id_from_uni_port_num(egress_port), onu_id=self.platform.onu_id_from_port_num(egress_port), uni_id=self.platform.uni_id_from_port_num(egress_port), port_no=egress_port, packet=str(payload).encode("HEX")) onu_pkt = openolt_pb2.OnuPacket( intf_id=self.platform.intf_id_from_uni_port_num(egress_port), onu_id=self.platform.onu_id_from_port_num(egress_port), port_no=egress_port, pkt=send_pkt) self.stub.OnuPacketOut(onu_pkt) elif egress_port_type == Port.ETHERNET_NNI: self.log.debug('sending-packet-to-uplink', egress_port=egress_port, packet=str(pkt).encode("HEX")) send_pkt = binascii.unhexlify(str(pkt).encode("HEX")) uplink_pkt = openolt_pb2.UplinkPacket( intf_id=self.platform.intf_id_from_nni_port_num(egress_port), pkt=send_pkt) self.stub.UplinkPacketOut(uplink_pkt) else: self.log.warn('Packet-out-to-this-interface-type-not-implemented', egress_port=egress_port, port_type=egress_port_type)
def packet_out(self, egress_port, msg): self.log.debug('sending-packet-out', egress_port=egress_port, msg_hex=hexify(msg)) pkt = Ether(msg) out_pkt = pkt self.log.debug("packet_out: incoming: %s" % pkt.summary()) if egress_port != self.nni_port.port_no: # don't do the vlan manipulation for the NNI port, vlans are already correct if pkt.haslayer(Dot1Q): if pkt.haslayer(Dot1AD): outer_shim = pkt.getlayer(Dot1AD) else: outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): # If double tag, remove the outer tag out_pkt = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload ) else: out_pkt = pkt else: # Add egress port as VLAN tag out_pkt = ( Ether(src=pkt.src, dst=pkt.dst) / Dot1Q(vlan=egress_port, type=pkt.type) / pkt.payload ) self.log.debug("packet_out: outgoing: %s" % out_pkt.summary()) # TODO need better way of mapping logical ports to PON ports out_port = self.nni_port.port_no if egress_port == self.nni_port.port_no else 1 if self.ponsim_comm == 'grpc': # send over grpc stream stub = ponsim_pb2_grpc.PonSimStub(self.get_channel()) frame = PonSimFrame(id=self.device_id, payload=str(out_pkt), out_port=out_port) stub.SendFrame(frame) else: # send over frameio self.io_port.send(str(out_pkt))
def _rcv_frame(self, frame): pkt = Ether(frame) if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): inner_shim = outer_shim.payload cvid = inner_shim.vlan popped_frame = ( Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) / inner_shim.payload) self.log.info('sending-packet-in', device_id=self.device_id, port=cvid) yield self.core_proxy.send_packet_in(device_id=self.device_id, port=cvid, packet=str(popped_frame)) elif pkt.haslayer(Raw): raw_data = json.loads(pkt.getlayer(Raw).load) self.alarms.send_alarm(self, raw_data)
def _rcv_frame(self, frame): pkt = Ether(frame) if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): inner_shim = outer_shim.payload cvid = inner_shim.vlan logical_port = cvid popped_frame = ( Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) / inner_shim.payload) kw = dict( logical_device_id=self.logical_device_id, logical_port_no=logical_port, ) self.log.info('sending-packet-in', **kw) self.adapter_agent.send_packet_in(packet=str(popped_frame), **kw) elif pkt.haslayer(Raw): raw_data = json.loads(pkt.getlayer(Raw).load) self.alarms.send_alarm(self, raw_data)
def analyze_pcap(pcap_name): try: p = RawPcapReader(pcap_name) except: print(f"Error opening file: {pcap_name}", file=sys.stderr) return for (pkt_data, *_) in p: ether_pkt = Ether(pkt_data) # If the src MAC is not from a device we care about, skip packet if ether_pkt.src.lower() not in globals.DEVICES.keys(): continue if ether_pkt.haslayer(DNS): # DNS queries are often sent to the local router, so # we extract them first (extract_IPs ignores packets # sent to private addresses) extract_dns(ether_pkt) # TODO: Before defaulting to IP layer, maybe check for other # data we could get (e.g. http requests w/URLs?) elif ether_pkt.haslayer(IP): extract_IPs(ether_pkt)
def measure_packet(self, packet_bytes, time): packet = Ether(packet_bytes) if not packet.haslayer(HTTPRequest): return port = self.classify_packet(packet, self.port_mapping) if port is None: return new_entry = ApiData(services=self.services, service_port_map=self.port_mapping, time=time, session=self.session) new_entry.set_service(port) new_entry.set_action(packet) new_entry.set_request_data(packet) new_entry.save()
def measure_packet(self, packet_bytes, buffer): packet = Ether(packet_bytes) port = self.classify_packet(packet, self.port_mapping) if IPv6 in packet: plen = packet.plen elif IP in packet: plen = packet.len else: buffer.ignored_count += 1 return if port is not None: buffer[port] += plen # Packet without TCP Layer (subsequently, without destination port) elif packet.haslayer(TCP): buffer['etc'] += plen
def rcv_io(self, port, frame): self.log.info('received', iface_name=port.iface_name, frame_len=len(frame)) pkt = Ether(frame) if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): inner_shim = outer_shim.payload cvid = inner_shim.vlan logical_port = cvid popped_frame = ( Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) / inner_shim.payload) kw = dict( logical_device_id=self.logical_device_id, logical_port_no=logical_port, ) self.log.info('sending-packet-in', **kw) self.adapter_agent.send_packet_in(packet=str(popped_frame), **kw)
def process_pcap(pcap_file_name): func_name = "process_pcap - " print(func_name + "opening file:" + pcap_file_name) count = 0 interesting_packet_count = 0 for ( pkt_data, pkt_metadata, ) in RawPcapReader(pcap_file_name): count += 1 ether_pkt = Ether(pkt_data) ''' if 'type' not in ether_pkt.fields: # LLC frames will have 'len' instead of 'type'. # We disregard those continue ''' print(func_name + "packet[" + str(count) + "] content:\n") #print(ether_pkt.show()) isis_common_header = "ISIS Common Header" for key, val in ether_pkt.fields.items(): print(str(key) + ":" + str(val)) if not ether_pkt.haslayer(isis_common_header): print(func_name + "packet[" + str(count) + "] is NOT an ISIS packet, ignore it") continue isis_hello_pdu_type_num = 17 isis_common_header_feilds = ether_pkt.getlayer( isis_common_header).fields for key, val in isis_common_header_feilds.items(): print(str(key) + ":" + str(val)) if val == isis_hello_pdu_type_num: print(func_name + "packet[" + str(count) + "] is ISIS Hello PDU") '''
def handle_packet_in(self, ind_info): self.log.info('Received Packet-In', ind_info=ind_info) pkt = Ether(ind_info['packet']) if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): inner_shim = outer_shim.payload cvid = inner_shim.vlan logical_port = cvid popped_frame = ( Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) / inner_shim.payload) kw = dict( logical_device_id=self.logical_device_id, logical_port_no=logical_port, ) self.log.info('sending-packet-in', **kw) self.adapter_agent.send_packet_in(packet=str(popped_frame), **kw) reactor.callLater(1, self.process_packet_in)
def igp_packet_parser_get_packet_protocol_type(self, packet_data): if packet_data is None: print(self.log_me() + "got None packet data") return None ether_pkt = Ether(packet_data) if ether_pkt is None: print(self.log_me() + "had an error extracting the packet") return None ''' print(self.log_me() + "the entire packet (frame) content received is:\n") ether_pkt.show() for key, val in ether_pkt.fields.items(): print(str(key) + ":" + str(val)) if not ether_pkt.haslayer("Ethernet") or not ether_pkt.haslayer("802.3"): print(self.log_me() + "the frame is not of ethernet type, ignoring it (not supported)") return None ''' # first check the frame fo ISIS header (remember that ISIS does not rely on IP # so there is no point to "cast" the frame to an IP packet) isis_common_header = "ISIS Common Header" if ether_pkt.haslayer(isis_common_header): return "ISIS" # second check if it is an OSPF packet that DOES ride on IP ospf_common_header = "OSPF Header" ip_pkt = ether_pkt[IP] ''' ip_pkt.show() for key,val in ip_pkt.fields.items(): print(str(key) + ":" + str(val)) ''' if ip_pkt.haslayer(ospf_common_header): return "OSPF" print(self.log_me() + "packet is not an ISIS nor OSPF control packet") return None
def process_packet(self, packet): packet = Ether(packet) print("PACKET") print(packet) IPtype = np.nan timestamp = packet.time framelen = len(packet) if packet.haslayer(IP): # IPv4 srcIP = packet[IP].src dstIP = packet[IP].dst IPtype = 0 elif packet.haslayer(IPv6): # ipv6 srcIP = packet[IPv6].src dstIP = packet[IPv6].dst IPtype = 1 else: srcIP = '' dstIP = '' if packet.haslayer(TCP): srcproto = str(packet[TCP].sport) dstproto = str(packet[TCP].dport) elif packet.haslayer(UDP): srcproto = str(packet[UDP].sport) dstproto = str(packet[UDP].dport) else: srcproto = '' dstproto = '' srcMAC = packet.src dstMAC = packet.dst if srcproto == '': # it's a L2/L1 level protocol if packet.haslayer(ARP): # is ARP srcproto = 'arp' dstproto = 'arp' srcIP = packet[ARP].psrc # src IP (ARP) dstIP = packet[ARP].pdst # dst IP (ARP) IPtype = 0 elif packet.haslayer(ICMP): # is ICMP srcproto = 'icmp' dstproto = 'icmp' IPtype = 0 elif srcIP + srcproto + dstIP + dstproto == '': # some other protocol srcIP = packet.src # src MAC dstIP = packet.dst # dst MAC
def extract_one_packet(buf): """Extract one packet from the incoming buf buffer. Takes string as input and looks for first whole packet in it. If it finds one, it returns substring from the buf parameter. :param buf: String representation of incoming packet buffer. :type buf: str :returns: String representation of first packet in buf. :rtype: str """ pkt_len = 0 if len(buf) < 60: return None try: ether_type = Ether(buf[0:14]).type except AttributeError: raise RuntimeError(f"No EtherType in packet {buf!r}") if ether_type == ETH_P_IP: # 14 is Ethernet fame header size. # 4 bytes is just enough to look for length in ip header. # ip total length contains just the IP packet length so add the Ether # header. pkt_len = Ether(buf[0:14 + 4]).len + 14 if len(buf) < 60: return None elif ether_type == ETH_P_IPV6: if not Ether(buf[0:14 + 6]).haslayer(IPv6): raise RuntimeError(f"Invalid IPv6 packet {buf!r}") # ... to add to the above, 40 bytes is the length of IPV6 header. # The ipv6.len only contains length of the payload and not the header pkt_len = Ether(buf)[u"IPv6"].plen + 14 + 40 if len(buf) < 60: return None elif ether_type == ETH_P_ARP: pkt = Ether(buf[:20]) if not pkt.haslayer(ARP): raise RuntimeError(u"Incomplete ARP packet") # len(eth) + arp(2 hw addr type + 2 proto addr type # + 1b len + 1b len + 2b operation) pkt_len = 14 + 8 pkt_len += 2 * pkt.getlayer(ARP).hwlen pkt_len += 2 * pkt.getlayer(ARP).plen del pkt elif ether_type == 32821: # RARP (Reverse ARP) pkt = Ether(buf[:20]) pkt.type = ETH_P_ARP # Change to ARP so it works with scapy pkt = Ether(pkt) if not pkt.haslayer(ARP): pkt.show() raise RuntimeError(u"Incomplete RARP packet") # len(eth) + arp(2 hw addr type + 2 proto addr type # + 1b len + 1b len + 2b operation) pkt_len = 14 + 8 pkt_len += 2 * pkt.getlayer(ARP).hwlen pkt_len += 2 * pkt.getlayer(ARP).plen del pkt else: raise RuntimeError(f"Unknown protocol {ether_type}") if pkt_len < 60: pkt_len = 60 if len(buf) < pkt_len: return None return buf[0:pkt_len]
def cpu_port_handler(self, packet, psock): eth = Ether(packet) if not self.running: raise Exception('stop') if not eth.haslayer(bgp.BGPUpdate): # Release the packet. psock.send(packet) return #log("Get BGP update packet: {}".format(eth.summary()), "yellow") update = eth[bgp.BGPUpdate] # Flag to determine whether this packet should be stopped. quarantine = False drop = False quarantine_key = None while True: # Check if this path_attr ends at a different AS compared to # known for this prefix, and if so, quarantine this BGP update packet. p = [ path_attr for path_attr in update.path_attr if path_attr.type_code == AS_PATH ] if len(p) > 0: s = [ path.segment_value for path in p[0].attribute.segments if path.segment_type == AS_SEQUENCE ] if len(s) > 0: # Get the destination AS in each sequence. Assert that they are all the same. dest = [seq[-1] for seq in s] assert (all(d == dest[0] for d in dest)) if dest[0] in self.blocked_as: log( "Dropping packet announcing blocked AS {}.".format( dest[0]), "red") drop = True break if dest[0] != 0: for dest_prefix in [ nlri.prefix for nlri in update.nlri ]: #print("Announcement for prefix {}:".format(dest_prefix)) #print(s) if dest_prefix.split('.')[0] == 9: continue # TODO: this skips the internal network. Should be fixed with CIDR below. if (dest[0], dest_prefix.split('.')[0] ) in self.quarantined: drop = True # Ignore this packet that's advertising a quarantined route. elif dest_prefix in self.routing_table and self.routing_table[ dest_prefix] != dest[0]: log( "Delay AS {} announcing prefix {}.".format( dest[0], dest_prefix), "red") # Ideally, we should look through all of the updates and notify all the # ASes being targeted in a single update. For now though, we only notify # the first, and similarly unblock the AS when this is done. # Hardcode the prefix to /8. This needs modification on the P4 side to support # proper CIDR. quarantine_key = (dest[0], dest_prefix.split('.')[0]) if not quarantine_key in self.allowed: quarantine = True break else: log("Route {}: {}".format(dest_prefix, s[0])) self.routing_table[dest_prefix] = dest[0] if not update.haslayer( bgp.BGPHeader) or not update[bgp.BGPHeader].haslayer( bgp.BGPUpdate): break else: # next update update = update[bgp.BGPHeader][bgp.BGPUpdate] if drop: pass # blackhole elif not quarantine: psock.send(packet) elif not quarantine_key in self.quarantined: self.quarantined[quarantine_key] = int( time.time()) + _QUARANTINE_EXPIRATION_SEC (gap, prefix) = quarantine_key self.add_slice(prefix, gap)
def create_stream( self, mac_type, ip_type, packet_count, src_if, dst_if, traffic, is_ip6, tags=PERMIT_TAGS, ): # exact MAC and exact IP # exact MAC and subnet of IPs # exact MAC and wildcard IP # wildcard MAC and exact IP # wildcard MAC and subnet of IPs # wildcard MAC and wildcard IP # OUI restricted MAC and exact IP # OUI restricted MAC and subnet of IPs # OUI restricted MAC and wildcard IP packets = [] macip_rules = [] acl_rules = [] ip_permit = "" mac_permit = "" dst_mac = "" mac_rule = "00:00:00:00:00:00" mac_mask = "00:00:00:00:00:00" for p in range(0, packet_count): remote_dst_index = p % len(dst_if.remote_hosts) remote_dst_host = dst_if.remote_hosts[remote_dst_index] dst_port = 1234 + p src_port = 4321 + p is_permit = self.PERMIT if p % 3 == 0 else self.DENY denyMAC = True if not is_permit and p % 3 == 1 else False denyIP = True if not is_permit and p % 3 == 2 else False if not is_permit and ip_type == self.WILD_IP: denyMAC = True if not is_permit and mac_type == self.WILD_MAC: denyIP = True if traffic == self.BRIDGED: if is_permit: src_mac = remote_dst_host._mac dst_mac = "de:ad:00:00:00:00" src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 ip_permit = src_ip6 if is_ip6 else src_ip4 mac_permit = src_mac if denyMAC: mac = src_mac.split(":") mac[0] = format(int(mac[0], 16) + 1, "02x") src_mac = ":".join(mac) if is_ip6: src_ip6 = ip_permit else: src_ip4 = ip_permit if denyIP: if ip_type != self.WILD_IP: src_mac = mac_permit src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 else: if is_permit: src_mac = remote_dst_host._mac dst_mac = src_if.local_mac src_ip4 = src_if.remote_ip4 dst_ip4 = remote_dst_host.ip4 src_ip6 = src_if.remote_ip6 dst_ip6 = remote_dst_host.ip6 ip_permit = src_ip6 if is_ip6 else src_ip4 mac_permit = src_mac if denyMAC: mac = src_mac.split(":") mac[0] = format(int(mac[0], 16) + 1, "02x") src_mac = ":".join(mac) if is_ip6: src_ip6 = ip_permit else: src_ip4 = ip_permit if denyIP: src_mac = remote_dst_host._mac if ip_type != self.WILD_IP: src_mac = mac_permit src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 if is_permit: info = self.create_packet_info(src_if, dst_if) payload = self.info_to_payload(info) else: payload = "to be blocked" if mac_type == self.WILD_MAC: mac = src_mac.split(":") for i in range(1, 5): mac[i] = format(random.randint(0, 255), "02x") src_mac = ":".join(mac) # create packet packet = Ether(src=src_mac, dst=dst_mac) ip_rule = src_ip6 if is_ip6 else src_ip4 if is_ip6: if ip_type != self.EXACT_IP: sub_ip = list(unpack("<16B", inet_pton(AF_INET6, ip_rule))) if ip_type == self.WILD_IP: sub_ip[0] = random.randint(240, 254) sub_ip[1] = random.randint(230, 239) sub_ip[14] = random.randint(100, 199) sub_ip[15] = random.randint(200, 255) elif ip_type == self.SUBNET_IP: if denyIP: sub_ip[2] = int(sub_ip[2]) + 1 sub_ip[14] = random.randint(100, 199) sub_ip[15] = random.randint(200, 255) packed_src_ip6 = b"".join([scapy.compat.chb(x) for x in sub_ip]) src_ip6 = inet_ntop(AF_INET6, packed_src_ip6) packet /= IPv6(src=src_ip6, dst=dst_ip6) else: if ip_type != self.EXACT_IP: sub_ip = ip_rule.split(".") if ip_type == self.WILD_IP: sub_ip[0] = random.randint(1, 49) sub_ip[1] = random.randint(50, 99) sub_ip[2] = random.randint(100, 199) sub_ip[3] = random.randint(200, 255) elif ip_type == self.SUBNET_IP: if denyIP: sub_ip[1] = int(sub_ip[1]) + 1 sub_ip[2] = random.randint(100, 199) sub_ip[3] = random.randint(200, 255) src_ip4 = ".".join(["{!s}".format(x) for x in sub_ip]) packet /= IP(src=src_ip4, dst=dst_ip4, frag=0, flags=0) packet /= UDP(sport=src_port, dport=dst_port) / Raw(payload) packet[Raw].load += b" mac:%s" % src_mac.encode("utf-8") size = self.pg_if_packet_sizes[p % len(self.pg_if_packet_sizes)] if isinstance(src_if, VppSubInterface): size = size + 4 if isinstance(src_if, VppDot1QSubint): if src_if is self.subifs[0]: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1q_layer(packet, 10) else: packet = src_if.add_dot1q_layer(packet, 11) else: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1q_layer(packet, 30) else: packet = src_if.add_dot1q_layer(packet, 33) elif isinstance(src_if, VppDot1ADSubint): if src_if is self.subifs[1]: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1ad_layer(packet, 300, 400) else: packet = src_if.add_dot1ad_layer(packet, 333, 444) else: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1ad_layer(packet, 600, 700) else: packet = src_if.add_dot1ad_layer(packet, 666, 777) self.extend_packet(packet, size) packets.append(packet) # create suitable MACIP rule if mac_type == self.EXACT_MAC: mac_rule = src_mac mac_mask = "ff:ff:ff:ff:ff:ff" elif mac_type == self.WILD_MAC: mac_rule = "00:00:00:00:00:00" mac_mask = "00:00:00:00:00:00" elif mac_type == self.OUI_MAC: mac = src_mac.split(":") mac[3] = mac[4] = mac[5] = "00" mac_rule = ":".join(mac) mac_mask = "ff:ff:ff:00:00:00" if is_ip6: if ip_type == self.WILD_IP: ip = "0::0" else: ip = src_ip6 if ip_type == self.SUBNET_IP: sub_ip = list(unpack("<16B", inet_pton(AF_INET6, ip))) for i in range(8, 16): sub_ip[i] = 0 packed_ip = b"".join([scapy.compat.chb(x) for x in sub_ip]) ip = inet_ntop(AF_INET6, packed_ip) else: if ip_type == self.WILD_IP: ip = "0.0.0.0" else: ip = src_ip4 if ip_type == self.SUBNET_IP: sub_ip = ip.split(".") sub_ip[2] = sub_ip[3] = "0" ip = ".".join(sub_ip) prefix_len = 128 if is_ip6 else 32 if ip_type == self.WILD_IP: prefix_len = 0 elif ip_type == self.SUBNET_IP: prefix_len = 64 if is_ip6 else 16 ip_rule = inet_pton(AF_INET6 if is_ip6 else AF_INET, ip) # create suitable ACL rule if is_permit: rule_l4_sport = packet[UDP].sport rule_l4_dport = packet[UDP].dport rule_family = AF_INET6 if packet.haslayer(IPv6) else AF_INET rule_prefix_len = 128 if packet.haslayer(IPv6) else 32 rule_l3_layer = IPv6 if packet.haslayer(IPv6) else IP if packet.haslayer(IPv6): rule_l4_proto = packet[UDP].overload_fields[IPv6]["nh"] else: rule_l4_proto = packet[IP].proto src_network = ip_network((packet[rule_l3_layer].src, rule_prefix_len)) dst_network = ip_network((packet[rule_l3_layer].dst, rule_prefix_len)) acl_rule = AclRule( is_permit=is_permit, proto=rule_l4_proto, src_prefix=src_network, dst_prefix=dst_network, sport_from=rule_l4_sport, sport_to=rule_l4_sport, dport_from=rule_l4_dport, dport_to=rule_l4_dport, ) acl_rules.append(acl_rule) if mac_type == self.WILD_MAC and ip_type == self.WILD_IP and p > 0: continue if is_permit: macip_rule = MacipRule( is_permit=is_permit, src_prefix=ip_network((ip_rule, prefix_len)), src_mac=MACAddress(mac_rule).packed, src_mac_mask=MACAddress(mac_mask).packed, ) macip_rules.append(macip_rule) # deny all other packets if not (mac_type == self.WILD_MAC and ip_type == self.WILD_IP): network = IPv6Network((0, 0)) if is_ip6 else IPv4Network((0, 0)) macip_rule = MacipRule( is_permit=0, src_prefix=network, src_mac=MACAddress("00:00:00:00:00:00").packed, src_mac_mask=MACAddress("00:00:00:00:00:00").packed, ) macip_rules.append(macip_rule) network = IPv6Network((0, 0)) if is_ip6 else IPv4Network((0, 0)) acl_rule = AclRule( is_permit=0, src_prefix=network, dst_prefix=network, sport_from=0, sport_to=0, dport_from=0, dport_to=0, ) acl_rules.append(acl_rule) return {"stream": packets, "macip_rules": macip_rules, "acl_rules": acl_rules}
def _rcv_io(self, port, frame): log.info('frame-received', frame=hexify(frame)) # make into frame to extract source mac response = Ether(frame) if response.haslayer(Dot1Q): # All OAM responses from the OLT should have a TIBIT_MGMT_VLAN. # Responses from the ONUs should have a TIBIT_MGMT_VLAN followed by a ONU CTAG # All packet-in frames will have the TIBIT_PACKET_IN_VLAN. if response.getlayer(Dot1Q).type == 0x8100: if response.getlayer(Dot1Q).vlan == TIBIT_PACKET_IN_VLAN: inner_tag_and_rest = response.payload.payload if isinstance(inner_tag_and_rest, Dot1Q): cvid = inner_tag_and_rest.vlan frame = Ether(src=response.src, dst=response.dst, type=inner_tag_and_rest.type) /\ inner_tag_and_rest.payload _, logical_device_id = self.vlan_to_device_ids.get(cvid) if logical_device_id is None: log.error('invalid-cvid', cvid=cvid) else: self.adapter_agent.send_packet_in( logical_device_id=logical_device_id, logical_port_no=cvid, # C-VID encodes port no packet=str(frame)) else: log.error('packet-in-single-tagged', frame=hexify(response)) else: ## Mgmt responses received from the ONU ## Since the type of the first layer is 0x8100, ## then the frame must have an inner tag layer olt_mac = response.src device_id = self.device_ids[olt_mac] channel_id = response[Dot1Q:2].vlan log.info('received_channel_id', channel_id=channel_id, device_id=device_id) proxy_address=Device.ProxyAddress( device_id=device_id, channel_id=channel_id ) # pop dot1q header(s) msg = response.payload.payload self.adapter_agent.receive_proxied_message(proxy_address, msg) else: ## Mgmt responses received from the OLT ## enqueue incoming parsed frame to right device log.info('received-dot1q-not-8100') self.incoming_queues[response.src].put(response)
def create_stream(self, mac_type, ip_type, packet_count, src_if, dst_if, traffic, is_ip6, tags=PERMIT_TAGS): # exact MAC and exact IP # exact MAC and subnet of IPs # exact MAC and wildcard IP # wildcard MAC and exact IP # wildcard MAC and subnet of IPs # wildcard MAC and wildcard IP # OUI restricted MAC and exact IP # OUI restricted MAC and subnet of IPs # OUI restricted MAC and wildcard IP packets = [] macip_rules = [] acl_rules = [] ip_permit = "" mac_permit = "" dst_mac = "" mac_rule = "00:00:00:00:00:00" mac_mask = "00:00:00:00:00:00" for p in range(0, packet_count): remote_dst_index = p % len(dst_if.remote_hosts) remote_dst_host = dst_if.remote_hosts[remote_dst_index] dst_port = 1234 + p src_port = 4321 + p is_permit = self.PERMIT if p % 3 == 0 else self.DENY denyMAC = True if not is_permit and p % 3 == 1 else False denyIP = True if not is_permit and p % 3 == 2 else False if not is_permit and ip_type == self.WILD_IP: denyMAC = True if not is_permit and mac_type == self.WILD_MAC: denyIP = True if traffic == self.BRIDGED: if is_permit: src_mac = remote_dst_host._mac dst_mac = 'de:ad:00:00:00:00' src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 ip_permit = src_ip6 if is_ip6 else src_ip4 mac_permit = src_mac if denyMAC: mac = src_mac.split(':') mac[0] = format(int(mac[0], 16)+1, "02x") src_mac = ":".join(mac) if is_ip6: src_ip6 = ip_permit else: src_ip4 = ip_permit if denyIP: if ip_type != self.WILD_IP: src_mac = mac_permit src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 else: if is_permit: src_mac = remote_dst_host._mac dst_mac = src_if.local_mac src_ip4 = src_if.remote_ip4 dst_ip4 = remote_dst_host.ip4 src_ip6 = src_if.remote_ip6 dst_ip6 = remote_dst_host.ip6 ip_permit = src_ip6 if is_ip6 else src_ip4 mac_permit = src_mac if denyMAC: mac = src_mac.split(':') mac[0] = format(int(mac[0], 16) + 1, "02x") src_mac = ":".join(mac) if is_ip6: src_ip6 = ip_permit else: src_ip4 = ip_permit if denyIP: src_mac = remote_dst_host._mac if ip_type != self.WILD_IP: src_mac = mac_permit src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 if is_permit: info = self.create_packet_info(src_if, dst_if) payload = self.info_to_payload(info) else: payload = "to be blocked" if mac_type == self.WILD_MAC: mac = src_mac.split(':') for i in range(1, 5): mac[i] = format(random.randint(0, 255), "02x") src_mac = ":".join(mac) # create packet packet = Ether(src=src_mac, dst=dst_mac) ip_rule = src_ip6 if is_ip6 else src_ip4 if is_ip6: if ip_type != self.EXACT_IP: sub_ip = list(unpack('<16B', inet_pton(AF_INET6, ip_rule))) if ip_type == self.WILD_IP: sub_ip[0] = random.randint(240, 254) sub_ip[1] = random.randint(230, 239) sub_ip[14] = random.randint(100, 199) sub_ip[15] = random.randint(200, 255) elif ip_type == self.SUBNET_IP: if denyIP: sub_ip[2] = int(sub_ip[2]) + 1 sub_ip[14] = random.randint(100, 199) sub_ip[15] = random.randint(200, 255) packed_src_ip6 = b''.join( [scapy.compat.chb(x) for x in sub_ip]) src_ip6 = inet_ntop(AF_INET6, packed_src_ip6) packet /= IPv6(src=src_ip6, dst=dst_ip6) else: if ip_type != self.EXACT_IP: sub_ip = ip_rule.split('.') if ip_type == self.WILD_IP: sub_ip[0] = random.randint(1, 49) sub_ip[1] = random.randint(50, 99) sub_ip[2] = random.randint(100, 199) sub_ip[3] = random.randint(200, 255) elif ip_type == self.SUBNET_IP: if denyIP: sub_ip[1] = int(sub_ip[1])+1 sub_ip[2] = random.randint(100, 199) sub_ip[3] = random.randint(200, 255) src_ip4 = '.'.join(['{!s}'.format(x) for x in sub_ip]) packet /= IP(src=src_ip4, dst=dst_ip4, frag=0, flags=0) packet /= UDP(sport=src_port, dport=dst_port)/Raw(payload) packet[Raw].load += b" mac:%s" % scapy.compat.raw(src_mac) size = self.pg_if_packet_sizes[p % len(self.pg_if_packet_sizes)] if isinstance(src_if, VppSubInterface): size = size + 4 if isinstance(src_if, VppDot1QSubint): if src_if is self.subifs[0]: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1q_layer(packet, 10) else: packet = src_if.add_dot1q_layer(packet, 11) else: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1q_layer(packet, 30) else: packet = src_if.add_dot1q_layer(packet, 33) elif isinstance(src_if, VppDot1ADSubint): if src_if is self.subifs[1]: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1ad_layer(packet, 300, 400) else: packet = src_if.add_dot1ad_layer(packet, 333, 444) else: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1ad_layer(packet, 600, 700) else: packet = src_if.add_dot1ad_layer(packet, 666, 777) self.extend_packet(packet, size) packets.append(packet) # create suitable MACIP rule if mac_type == self.EXACT_MAC: mac_rule = src_mac mac_mask = "ff:ff:ff:ff:ff:ff" elif mac_type == self.WILD_MAC: mac_rule = "00:00:00:00:00:00" mac_mask = "00:00:00:00:00:00" elif mac_type == self.OUI_MAC: mac = src_mac.split(':') mac[3] = mac[4] = mac[5] = '00' mac_rule = ":".join(mac) mac_mask = "ff:ff:ff:00:00:00" if is_ip6: if ip_type == self.WILD_IP: ip = "0::0" else: ip = src_ip6 if ip_type == self.SUBNET_IP: sub_ip = list(unpack('<16B', inet_pton(AF_INET6, ip))) for i in range(8, 16): sub_ip[i] = 0 packed_ip = b''.join( [scapy.compat.chb(x) for x in sub_ip]) ip = inet_ntop(AF_INET6, packed_ip) else: if ip_type == self.WILD_IP: ip = "0.0.0.0" else: ip = src_ip4 if ip_type == self.SUBNET_IP: sub_ip = ip.split('.') sub_ip[2] = sub_ip[3] = '0' ip = ".".join(sub_ip) prefix_len = 128 if is_ip6 else 32 if ip_type == self.WILD_IP: prefix_len = 0 elif ip_type == self.SUBNET_IP: prefix_len = 64 if is_ip6 else 16 ip_rule = inet_pton(AF_INET6 if is_ip6 else AF_INET, ip) # create suitable ACL rule if is_permit: rule_l4_sport = packet[UDP].sport rule_l4_dport = packet[UDP].dport rule_family = AF_INET6 if packet.haslayer(IPv6) else AF_INET rule_prefix_len = 128 if packet.haslayer(IPv6) else 32 rule_l3_layer = IPv6 if packet.haslayer(IPv6) else IP if packet.haslayer(IPv6): rule_l4_proto = packet[UDP].overload_fields[IPv6]['nh'] else: rule_l4_proto = packet[IP].proto acl_rule = { 'is_permit': is_permit, 'is_ipv6': is_ip6, 'src_ip_addr': inet_pton(rule_family, packet[rule_l3_layer].src), 'src_ip_prefix_len': rule_prefix_len, 'dst_ip_addr': inet_pton(rule_family, packet[rule_l3_layer].dst), 'dst_ip_prefix_len': rule_prefix_len, 'srcport_or_icmptype_first': rule_l4_sport, 'srcport_or_icmptype_last': rule_l4_sport, 'dstport_or_icmpcode_first': rule_l4_dport, 'dstport_or_icmpcode_last': rule_l4_dport, 'proto': rule_l4_proto} acl_rules.append(acl_rule) if mac_type == self.WILD_MAC and ip_type == self.WILD_IP and p > 0: continue if is_permit: macip_rule = ({ 'is_permit': is_permit, 'is_ipv6': is_ip6, 'src_ip_addr': ip_rule, 'src_ip_prefix_len': prefix_len, 'src_mac': binascii.unhexlify(mac_rule.replace(':', '')), 'src_mac_mask': binascii.unhexlify( mac_mask.replace(':', ''))}) macip_rules.append(macip_rule) # deny all other packets if not (mac_type == self.WILD_MAC and ip_type == self.WILD_IP): macip_rule = ({'is_permit': 0, 'is_ipv6': is_ip6, 'src_ip_addr': "", 'src_ip_prefix_len': 0, 'src_mac': "", 'src_mac_mask': ""}) macip_rules.append(macip_rule) acl_rule = {'is_permit': 0, 'is_ipv6': is_ip6} acl_rules.append(acl_rule) return {'stream': packets, 'macip_rules': macip_rules, 'acl_rules': acl_rules}
def create_stream(self, mac_type, ip_type, packet_count, src_if, dst_if, traffic, is_ip6, tags=PERMIT_TAGS): # exact MAC and exact IP # exact MAC and subnet of IPs # exact MAC and wildcard IP # wildcard MAC and exact IP # wildcard MAC and subnet of IPs # wildcard MAC and wildcard IP # OUI restricted MAC and exact IP # OUI restricted MAC and subnet of IPs # OUI restricted MAC and wildcard IP packets = [] macip_rules = [] acl_rules = [] ip_permit = "" mac_permit = "" dst_mac = "" mac_rule = "00:00:00:00:00:00" mac_mask = "00:00:00:00:00:00" for p in range(0, packet_count): remote_dst_index = p % len(dst_if.remote_hosts) remote_dst_host = dst_if.remote_hosts[remote_dst_index] dst_port = 1234 + p src_port = 4321 + p is_permit = self.PERMIT if p % 3 == 0 else self.DENY denyMAC = True if not is_permit and p % 3 == 1 else False denyIP = True if not is_permit and p % 3 == 2 else False if not is_permit and ip_type == self.WILD_IP: denyMAC = True if not is_permit and mac_type == self.WILD_MAC: denyIP = True if traffic == self.BRIDGED: if is_permit: src_mac = remote_dst_host._mac dst_mac = 'de:ad:00:00:00:00' src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 ip_permit = src_ip6 if is_ip6 else src_ip4 mac_permit = src_mac if denyMAC: mac = src_mac.split(':') mac[0] = format(int(mac[0], 16) + 1, "02x") src_mac = ":".join(mac) if is_ip6: src_ip6 = ip_permit else: src_ip4 = ip_permit if denyIP: if ip_type != self.WILD_IP: src_mac = mac_permit src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 else: if is_permit: src_mac = remote_dst_host._mac dst_mac = src_if.local_mac src_ip4 = src_if.remote_ip4 dst_ip4 = remote_dst_host.ip4 src_ip6 = src_if.remote_ip6 dst_ip6 = remote_dst_host.ip6 ip_permit = src_ip6 if is_ip6 else src_ip4 mac_permit = src_mac if denyMAC: mac = src_mac.split(':') mac[0] = format(int(mac[0], 16) + 1, "02x") src_mac = ":".join(mac) if is_ip6: src_ip6 = ip_permit else: src_ip4 = ip_permit if denyIP: src_mac = remote_dst_host._mac if ip_type != self.WILD_IP: src_mac = mac_permit src_ip4 = remote_dst_host.ip4 dst_ip4 = src_if.remote_ip4 src_ip6 = remote_dst_host.ip6 dst_ip6 = src_if.remote_ip6 if is_permit: info = self.create_packet_info(src_if, dst_if) payload = self.info_to_payload(info) else: payload = "to be blocked" if mac_type == self.WILD_MAC: mac = src_mac.split(':') for i in range(1, 5): mac[i] = format(random.randint(0, 255), "02x") src_mac = ":".join(mac) # create packet packet = Ether(src=src_mac, dst=dst_mac) ip_rule = src_ip6 if is_ip6 else src_ip4 if is_ip6: if ip_type != self.EXACT_IP: sub_ip = list(unpack('<16B', inet_pton(AF_INET6, ip_rule))) if ip_type == self.WILD_IP: sub_ip[0] = random.randint(240, 254) sub_ip[1] = random.randint(230, 239) sub_ip[14] = random.randint(100, 199) sub_ip[15] = random.randint(200, 255) elif ip_type == self.SUBNET_IP: if denyIP: sub_ip[2] = str(int(sub_ip[2]) + 1) sub_ip[14] = random.randint(100, 199) sub_ip[15] = random.randint(200, 255) src_ip6 = inet_ntop(AF_INET6, str(bytearray(sub_ip))) packet /= IPv6(src=src_ip6, dst=dst_ip6) else: if ip_type != self.EXACT_IP: sub_ip = ip_rule.split('.') if ip_type == self.WILD_IP: sub_ip[0] = str(random.randint(1, 49)) sub_ip[1] = str(random.randint(50, 99)) sub_ip[2] = str(random.randint(100, 199)) sub_ip[3] = str(random.randint(200, 255)) elif ip_type == self.SUBNET_IP: if denyIP: sub_ip[1] = str(int(sub_ip[1]) + 1) sub_ip[2] = str(random.randint(100, 199)) sub_ip[3] = str(random.randint(200, 255)) src_ip4 = ".".join(sub_ip) packet /= IP(src=src_ip4, dst=dst_ip4, frag=0, flags=0) packet /= UDP(sport=src_port, dport=dst_port) / Raw(payload) packet[Raw].load += " mac:" + src_mac size = self.pg_if_packet_sizes[p % len(self.pg_if_packet_sizes)] if isinstance(src_if, VppSubInterface): size = size + 4 if isinstance(src_if, VppDot1QSubint): if src_if is self.subifs[0]: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1q_layer(packet, 10) else: packet = src_if.add_dot1q_layer(packet, 11) else: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1q_layer(packet, 30) else: packet = src_if.add_dot1q_layer(packet, 33) elif isinstance(src_if, VppDot1ADSubint): if src_if is self.subifs[1]: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1ad_layer(packet, 300, 400) else: packet = src_if.add_dot1ad_layer(packet, 333, 444) else: if tags == self.PERMIT_TAGS: packet = src_if.add_dot1ad_layer(packet, 600, 700) else: packet = src_if.add_dot1ad_layer(packet, 666, 777) self.extend_packet(packet, size) packets.append(packet) # create suitable MACIP rule if mac_type == self.EXACT_MAC: mac_rule = src_mac mac_mask = "ff:ff:ff:ff:ff:ff" elif mac_type == self.WILD_MAC: mac_rule = "00:00:00:00:00:00" mac_mask = "00:00:00:00:00:00" elif mac_type == self.OUI_MAC: mac = src_mac.split(':') mac[3] = mac[4] = mac[5] = '00' mac_rule = ":".join(mac) mac_mask = "ff:ff:ff:00:00:00" if is_ip6: if ip_type == self.WILD_IP: ip = "0::0" else: ip = src_ip6 if ip_type == self.SUBNET_IP: sub_ip = list(unpack('<16B', inet_pton(AF_INET6, ip))) for i in range(8, 16): sub_ip[i] = 0 ip = inet_ntop(AF_INET6, str(bytearray(sub_ip))) else: if ip_type == self.WILD_IP: ip = "0.0.0.0" else: ip = src_ip4 if ip_type == self.SUBNET_IP: sub_ip = ip.split('.') sub_ip[2] = sub_ip[3] = '0' ip = ".".join(sub_ip) prefix_len = 128 if is_ip6 else 32 if ip_type == self.WILD_IP: prefix_len = 0 elif ip_type == self.SUBNET_IP: prefix_len = 64 if is_ip6 else 16 ip_rule = inet_pton(AF_INET6 if is_ip6 else AF_INET, ip) # create suitable ACL rule if is_permit: rule_l4_sport = packet[UDP].sport rule_l4_dport = packet[UDP].dport rule_family = AF_INET6 if packet.haslayer(IPv6) else AF_INET rule_prefix_len = 128 if packet.haslayer(IPv6) else 32 rule_l3_layer = IPv6 if packet.haslayer(IPv6) else IP if packet.haslayer(IPv6): rule_l4_proto = packet[UDP].overload_fields[IPv6]['nh'] else: rule_l4_proto = packet[IP].proto acl_rule = { 'is_permit': is_permit, 'is_ipv6': is_ip6, 'src_ip_addr': inet_pton(rule_family, packet[rule_l3_layer].src), 'src_ip_prefix_len': rule_prefix_len, 'dst_ip_addr': inet_pton(rule_family, packet[rule_l3_layer].dst), 'dst_ip_prefix_len': rule_prefix_len, 'srcport_or_icmptype_first': rule_l4_sport, 'srcport_or_icmptype_last': rule_l4_sport, 'dstport_or_icmpcode_first': rule_l4_dport, 'dstport_or_icmpcode_last': rule_l4_dport, 'proto': rule_l4_proto } acl_rules.append(acl_rule) if mac_type == self.WILD_MAC and ip_type == self.WILD_IP and p > 0: continue if is_permit: macip_rule = ({ 'is_permit': is_permit, 'is_ipv6': is_ip6, 'src_ip_addr': ip_rule, 'src_ip_prefix_len': prefix_len, 'src_mac': mac_rule.replace(':', '').decode('hex'), 'src_mac_mask': mac_mask.replace(':', '').decode('hex') }) macip_rules.append(macip_rule) # deny all other packets if not (mac_type == self.WILD_MAC and ip_type == self.WILD_IP): macip_rule = ({ 'is_permit': 0, 'is_ipv6': is_ip6, 'src_ip_addr': "", 'src_ip_prefix_len': 0, 'src_mac': "", 'src_mac_mask': "" }) macip_rules.append(macip_rule) acl_rule = {'is_permit': 0, 'is_ipv6': is_ip6} acl_rules.append(acl_rule) return { 'stream': packets, 'macip_rules': macip_rules, 'acl_rules': acl_rules }
def packet_out_process(self, topic, msg): def get_port_out(opo): for action in opo.actions: if action.type == OUTPUT: return action.output.port pb = Parse(loads(msg), ofp.PacketOut(), ignore_unknown_fields=True) logical_device_id = pb.id ofp_packet_out = pb.packet_out self.log.debug("received packet-out form kafka", logical_device_id=logical_device_id, ofp_packet_out=ofp_packet_out) egress_port = get_port_out(ofp_packet_out) msg = ofp_packet_out.data self.log.debug('rcv-packet-out', logical_device_id=logical_device_id, egress_port=egress_port, # adapter_name=self.adapter_name, data=hexify(msg)) pkt = Ether(msg) self.log.debug('packet out', egress_port=egress_port, packet=str(pkt).encode("HEX")) # Find port type egress_port_type = self.device.platform \ .intf_id_to_port_type_name(egress_port) if egress_port_type == Port.ETHERNET_UNI: if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): # If double tag, remove the outer tag payload = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload ) else: payload = pkt else: payload = pkt send_pkt = binascii.unhexlify(str(payload).encode("HEX")) self.log.debug( 'sending-packet-to-ONU', egress_port=egress_port, intf_id=self.device.platform.intf_id_from_uni_port_num( egress_port), onu_id=self.device.platform.onu_id_from_port_num(egress_port), uni_id=self.device.platform.uni_id_from_port_num(egress_port), port_no=egress_port, packet=str(payload).encode("HEX")) onu_pkt = openolt_pb2.OnuPacket( intf_id=self.device.platform.intf_id_from_uni_port_num( egress_port), onu_id=self.device.platform.onu_id_from_port_num(egress_port), port_no=egress_port, pkt=send_pkt) self.device.stub.OnuPacketOut(onu_pkt) elif egress_port_type == Port.ETHERNET_NNI: self.log.debug('sending-packet-to-uplink', egress_port=egress_port, packet=str(pkt).encode("HEX")) send_pkt = binascii.unhexlify(str(pkt).encode("HEX")) uplink_pkt = openolt_pb2.UplinkPacket( intf_id=self.device.platform.intf_id_from_nni_port_num( egress_port), pkt=send_pkt) self.device.stub.UplinkPacketOut(uplink_pkt) else: self.log.warn('Packet-out-to-this-interface-type-not-implemented', egress_port=egress_port, port_type=egress_port_type)