コード例 #1
0
ファイル: ponsim_olt.py プロジェクト: vipul2690/voltha
    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)
コード例 #2
0
    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)
コード例 #3
0
    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))
コード例 #4
0
    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)
コード例 #5
0
ファイル: openolt_device.py プロジェクト: iecedge/voltha
    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)
コード例 #6
0
ファイル: ponsim_olt.py プロジェクト: vipul2690/voltha
    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))
コード例 #7
0
ファイル: ponsim_olt.py プロジェクト: divya2504/Vol1884
    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)
コード例 #8
0
    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)
コード例 #10
0
    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()
コード例 #11
0
    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
コード例 #12
0
ファイル: maple_olt.py プロジェクト: apoz/voltha
 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)
コード例 #13
0
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")
        '''
コード例 #14
0
    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)
コード例 #15
0
    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
コード例 #16
0
 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
コード例 #17
0
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]
コード例 #18
0
    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)
コード例 #19
0
    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}
コード例 #20
0
ファイル: tibit_olt.py プロジェクト: weibit/voltha
    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)
コード例 #21
0
ファイル: test_acl_plugin_macip.py プロジェクト: vpp-dev/vpp
    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}
コード例 #22
0
    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
        }
コード例 #23
0
ファイル: openolt_packet.py プロジェクト: shadansari/voltha
    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)