Example #1
0
def generate_trace_pkt(entries, color, r_id, my_domain, interdomain=False):
    '''
        Receives the REST/PUT to generate a PacketOut
        data needs to be serialized
        template_trace.json is an example
    '''
    trace = {}
    switch = {}
    eth = {}
    ip = {}
    tp = {}

    # TODO Validate for dl_vlan. If empty, return error.

    dpid, in_port = 0, 65532
    if interdomain:
        dl_src = color
    else:
        dl_src = "ee:ee:ee:ee:ee:%s" % int(color,2)
    dl_dst = "ca:fe:ca:fe:ca:fe"
    dl_vlan, dl_type = 100, 2048
    nw_src, nw_dst, nw_tos = '127.0.0.1', '127.0.0.1', 0
    tp_src, tp_dst = 1, 1

    try:
        trace = entries['trace']
        switch = trace['switch']
        eth = trace['eth']
    except:
        pass

    try:
        ip = trace['ip']
    except:
        pass

    try:
        tp = trace['tp']
    except:
        pass

    if len(switch) > 0:
        dpid, in_port = prepare_switch(switch, dpid, in_port)

    if len(eth) > 0:
        dl_src, dl_dst, dl_vlan, dl_type = prepare_ethernet(eth, dl_src, dl_dst,
                                                            dl_vlan, dl_type)
    # if len(ip) > 0:
    nw_src, nw_dst, nw_tos = prepare_ip(ip, nw_src, nw_dst, nw_tos)

    # if len(tp) > 0:
    tp_src, tp_dst = prepare_tp(tp, tp_src, tp_dst)

    pkt = packet.Packet()

    eth_pkt = ethernet.ethernet(dst=dl_dst, src=dl_src, ethertype=33024)
    vlan_pkt = vlan.vlan(vid=dl_vlan, ethertype=int(dl_type))

    pkt.add_protocol(eth_pkt)
    pkt.add_protocol(vlan_pkt)

    if int(dl_type) == 2048:

        ip_pkt = ipv4.ipv4(dst=str(nw_dst), src=str(nw_src), tos=nw_tos,
                           proto=6)
        pkt.add_protocol(ip_pkt)
        tp_pkt = tcp.tcp(dst_port=int(tp_dst), src_port=int(tp_src))
        pkt.add_protocol(tp_pkt)

    msg = TraceMsg(r_id, my_domain)
    if interdomain:
        msg.set_interdomain()
    pkt.add_protocol(msg.data())
    pkt.serialize()
    return in_port, pkt
Example #2
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        # self.logger.info("packet info - %s" , pkt)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # 忽略 LLDP 包
            return

        dst = eth.dst
        src = eth.src
        dpid = datapath.id

        # 检查ARP包和DHCP包
        pkt_arp = pkt.get_protocol(arp.arp)
        pkt_dhcp = pkt.get_protocol(dhcp.dhcp)

        # ARP 包, 调用 arp_handler
        if pkt_arp:
            self._arp_handler(pkt_arp, msg)
            return

        # DHCP 包, 调用 dhcp_handler
        if pkt_dhcp:
            self._dhcp_handler(pkt_dhcp, msg)

        self.mac_to_port.setdefault(dpid, {})

        # 学习一个mac地址,以避免下次洪范。
        self.mac_to_port[dpid][src] = in_port

        # 目标 MAC 是否在 MAC-IP 映射表中
        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        # if out_port != ofproto.OFPP_FLOOD:
        #     match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_src=src)
        #     # verify if we have a valid buffer_id, if yes avoid to send both
        #     # flow_mod & packet_out
        #     if msg.buffer_id != ofproto.OFP_NO_BUFFER:
        #         self.add_flow(datapath, 1, match, actions, msg.buffer_id)
        #         return
        #     else:
        #         self.add_flow(datapath, 1, match, actions)

        data = None

        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
Example #3
0
    def _packet_in_handler(self, ev):

        msg = ev.msg

        datapath = msg.datapath

        ofproto = datapath.ofproto

        parser = datapath.ofproto_parser

        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)

        eth = pkt.get_protocol(ethernet.ethernet)

        dst = eth.dst

        src = eth.src

        dpid = datapath.id

        self.mac_to_port.setdefault(dpid, {})

        #print "nodes"

        #print self.net.nodes()

        #print "edges"

        #print self.net.edges()

        #self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        if src not in self.net:

            self.net.add_node(src)

            self.net.add_edge(dpid, src, {'port': in_port})

            self.net.add_edge(src, dpid)

        if dst in self.net:

            #print (src in self.net)

            #print nx.shortest_path(self.net,1,4)

            #print nx.shortest_path(self.net,4,1)

            #print nx.shortest_path(self.net,src,4)

            path = nx.shortest_path(self.net, src, dst)

            next = path[path.index(dpid) + 1]

            out_port = self.net[dpid][next]['port']

        else:

            out_port = ofproto.OFPP_FLOOD

        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time

        if out_port != ofproto.OFPP_FLOOD:

            self.add_flow(datapath, in_port, dst, actions)

        out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath,
                                                   buffer_id=msg.buffer_id,
                                                   in_port=in_port,
                                                   actions=actions)

        datapath.send_msg(out)
Example #4
0
    def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)

        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        igmp_in = pkt.get_protocol(igmp.igmp)
        #udp = pkt.get_protocol(udp.udp)
        udp = pkt.protocols[2]

        print(self.grp_to_mac)

        print("\n")

        print(pkt)

        print(udp)

        print("\n")

        print(igmp_in)

        eth_type = eth.ethertype
        dst = eth.dst
        src = eth.src

        print("Ethertype", eth_type)

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        if (igmp_in):  #Check if pkt is IGMP control
            #grp_record = igmp_in.records[0]
            #grp_addr = grp_record.address
            grp_addr = igmp_in.address
            print(grp_addr)
            #mc = addrconv.ipv4.text_to_bin(grp_addr)
            #print(mc)
            #mac_grp_addr = get_mac_address(ip=grp_addr)
            #print(mac_grp_addr)
            #match = parser.OFPMatch(eth_dst=dst, eth_type=0x0800,ip_proto=17)
            actions = []
            #if(src=='00:00:00:00:00:01'):
            #    print("IGMPv2 query")
            #    return
            #if(igmp_in.msgtype==0x22 and grp_record.type_==4):
            if (igmp_in.msgtype == 0x16):
                print("IGMPv3 Report - Join")
                #Add in_port to grp_to_mac table
                if in_port not in self.grp_to_mac[grp_addr]:
                    self.grp_to_mac[grp_addr].append(in_port)
                    for port in self.grp_to_mac[grp_addr]:
                        #match = datapath.ofproto_parser.OFPMatch(ipv4_dst=grp_addr)
                        actions.append(parser.OFPActionOutput(port))
                        print(actions)
                    match = parser.OFPMatch(eth_type=0x0800, ipv4_dst=grp_addr)
                    print(match)
                    self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                    print("Flow added")
                    print(self.grp_to_mac)
                else:
                    print("Flow already added - duplicate message")
            #elif(igmp_in.msgtype==0x22 and grp_record.type_==3):
            elif (igmp_in.msgtype == 0x17):
                print("IGMPv3 Report - Leave")
                if in_port in self.grp_to_mac[grp_addr]:
                    #match = datapath.ofproto_parser.OFPMatch(in_port=in_port)
                    #actions.append(parser.OFPActionOutput(in_port))
                    match = datapath.ofproto_parser.OFPMatch(eth_type=0x0800,
                                                             ipv4_dst=grp_addr)
                    print(actions)
                    self.del_flow(datapath, 1, match, actions, msg.buffer_id)
                    print(actions)
                    #self.del_flow(datapath, 1, actions)
                    self.grp_to_mac[grp_addr].remove(in_port)
                    print(self.grp_to_mac.values())
                    if len(self.grp_to_mac[grp_addr]) == 0:
                        print("Empty")
                        del self.grp_to_mac[grp_addr]
                    else:
                        print("Still other clients")

                    print("Flow updated")
                    print(self.grp_to_mac)
        elif (not igmp_in
              and dst[:8] == '01:00:5e'):  #Check if pkt is IGMP data
            print("IGMP DATA!")
        else:  #Normal l2 switching
            #learn a mac address to avoid FLOOD next time.
            self.mac_to_port[dpid][src] = in_port
            print(self.mac_to_port)
            if dst in self.mac_to_port[dpid]:
                out_port = self.mac_to_port[dpid][dst]
            else:
                out_port = ofproto.OFPP_FLOOD
            actions = [parser.OFPActionOutput(out_port)]
            # install a flow to avoid packet_in next time
            if out_port != ofproto.OFPP_FLOOD:
                match = parser.OFPMatch(in_port=in_port,
                                        eth_dst=dst,
                                        eth_src=src)
                # verify if we have a valid buffer_id, if yes avoid to send both
                # flow_mod & packet_out
                if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                    self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                    return
                else:
                    self.add_flow(datapath, 1, match, actions)
            data = None
            if msg.buffer_id == ofproto.OFP_NO_BUFFER:
                data = msg.data
            out = parser.OFPPacketOut(datapath=datapath,
                                      buffer_id=msg.buffer_id,
                                      in_port=in_port,
                                      actions=actions,
                                      data=data)
            datapath.send_msg(out)
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        dpid = datapath.id
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        arp_pkt = pkt.get_protocol(arp.arp)
        ip_pkt = pkt.get_protocol(ipv4.ipv4)

        ip_pkt_6 = pkt.get_protocol(ipv6.ipv6)
        if isinstance(ip_pkt_6, ipv6.ipv6):
            actions = []
            match = parser.OFPMatch(eth_type=ether.ETH_TYPE_IPV6)
            self.add_flow(datapath, 0, 1, match, actions)
            return

        if isinstance(arp_pkt, arp.arp):
            self.logger.debug("ARP processing")
            if self.mac_learning(dpid, eth.src, in_port) is False:
                self.logger.debug("ARP packet enter in different ports")
                return

            self.arp_forwarding(msg, arp_pkt.src_ip, arp_pkt.dst_ip, eth)

        if isinstance(ip_pkt, ipv4.ipv4):
            self.logger.debug("IPV4 processing")
            mac_to_port_table = self.mac_to_port.get(dpid)
            if mac_to_port_table is None:
                self.logger.info("Dpid is not in mac_to_port")
                return

            out_port = None
            if eth.dst in mac_to_port_table:
                if dpid == 1 and in_port == 1:
                    if self.FLAGS is True:
                        self.send_group_mod(datapath)
                        self.logger.info("send_group_mod")
                        self.FLAGS = False

                    actions = [parser.OFPActionGroup(group_id=50)]
                    match = parser.OFPMatch(in_port=in_port,
                                            eth_type=eth.ethertype,
                                            ipv4_src=ip_pkt.src)
                    self.add_flow(datapath, 0, 3, match, actions)
                    # asign output at 2
                    self.send_packet_out(datapath, msg.buffer_id, in_port, 2,
                                         msg.data)
                else:
                    #Normal flows
                    out_port = mac_to_port_table[eth.dst]
                    actions = [parser.OFPActionOutput(out_port)]
                    match = parser.OFPMatch(in_port=in_port,
                                            eth_dst=eth.dst,
                                            eth_type=eth.ethertype)
                    self.add_flow(datapath, 0, 1, match, actions)
                    self.send_packet_out(datapath, msg.buffer_id, in_port,
                                         out_port, msg.data)
            else:
                if self.mac_learning(dpid, eth.src, in_port) is False:
                    self.logger.debug("IPV4 packet enter in different ports")
                    return
                else:
                    self.flood(msg)
Example #6
0
    def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            return
        dst = eth.dst
        src = eth.src

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:

            # check IP Protocol and create a match for IP
            if eth.ethertype == ether_types.ETH_TYPE_IP:
                ip = pkt.get_protocol(ipv4.ipv4)
                srcip = ip.src
                dstip = ip.dst
                protocol = ip.proto

                # if ICMP Protocol
                if protocol == in_proto.IPPROTO_ICMP:
                    t = pkt.get_protocol(icmp.icmp)
                    match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP,
                                            ipv4_src=srcip,
                                            ipv4_dst=dstip,
                                            ip_proto=protocol,
                                            icmpv4_code=t.code,
                                            icmpv4_type=t.type)

                #  if TCP Protocol
                elif protocol == in_proto.IPPROTO_TCP:
                    t = pkt.get_protocol(tcp.tcp)
                    match = parser.OFPMatch(
                        eth_type=ether_types.ETH_TYPE_IP,
                        ipv4_src=srcip,
                        ipv4_dst=dstip,
                        ip_proto=protocol,
                        tcp_src=t.src_port,
                        tcp_dst=t.dst_port,
                    )

                #  If UDP Protocol
                elif protocol == in_proto.IPPROTO_UDP:
                    u = pkt.get_protocol(udp.udp)
                    match = parser.OFPMatch(
                        eth_type=ether_types.ETH_TYPE_IP,
                        ipv4_src=srcip,
                        ipv4_dst=dstip,
                        ip_proto=protocol,
                        udp_src=u.src_port,
                        udp_dst=u.dst_port,
                    )

                # verify if we have a valid buffer_id, if yes avoid to send both
                # flow_mod & packet_out
                if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                    self.add_flow(datapath,
                                  1,
                                  match,
                                  actions,
                                  msg.buffer_id,
                                  idle=20,
                                  hard=100)
                    return
                else:
                    self.add_flow(datapath,
                                  1,
                                  match,
                                  actions,
                                  idle=20,
                                  hard=100)
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
Example #7
0
    def switch_features_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        ip = pkt.get_protocols(ipv4.ipv4)

        eth = pkt.get_protocol(ethernet.ethernet)

        mac_dst = eth.dst
        mac_src = eth.src

        dpid = format(datapath.id, "d").zfill(16)
        self.mac_to_port.setdefault(dpid, {})

        self.logger.info("packet in %s %s %s %s", dpid, mac_src, mac_dst,
                         in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][mac_src] = in_port
        pod = int(ip.dst[4])
        switch_no = int(ip.dst[6])
        host_no = int(ip.dst[8])
        switch_pod = int(dpid[11])
        switch_no_dpid = int(dpid[13])

        if mac_dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][mac_dst]
        else:
            if switch_pod == k:  # determine if it is core switch
                out_port = pod
            else:
                if switch_no_dpid == 2 or switch_no_dpid == 3:  # determine if it is aggregation switch
                    if switch_pod == pod:  # host in same pod
                        out_port = switch_no
                    else:  # host in different pod
                        out_port = ((host_no - 2 + switch_no_dpid) %
                                    (k / 2)) + (k / 2)
                else:  # it is edge switch
                    if switch_pod == pod:  # host in same pod
                        if switch_no == switch_no_dpid:  # host under same switch
                            out_port = switch_no
                        else:  # host under different switch
                            out_port = ((host_no - 2 + switch_no_dpid +
                                         (k / 2)) % (k / 2)) + (k / 2)
                    else:  # host in different pod
                        out_port = ((host_no - 2 + switch_no_dpid + (k / 2)) %
                                    (k / 2)) + (k / 2)

        actions = [parser.OFPActionOutput(out_port)]
        if out_port != ofproto.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port,
                                    eth_dst=mac_dst,
                                    eth_src=mac_src)
            # verify if we have a valid buffer_id, if yes avoid to send both
            # flow_mod & packet_out
            if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                return
            else:
                self.add_flow(datapath, 1, match, actions)
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
Example #8
0
    def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        #@Thien - testing
        #ipv4_test = pkt.get_protocols(ipv4.ipv4)

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return
        dst = eth.dst
        src = eth.src

        #@Thien - testing
        #ipv4_src_addr = ipv4_test.src
        #ipv4_dst_addr = ipv4_test.dst
        #

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        #self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)
        #@Thien - testing
        #self.logger.info("packet in %s %s %s %s", dpid, ipv4_src_addr, ipv4_dst_addr, in_port)
        #

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:

            #@Thien: 2016-05-22
            match = None

            #nw_tos=None
            nw_src = None
            nw_dst = None
            nw_proto = None
            tp_src = None
            tp_dst = None

            ip = pkt.get_protocol(ipv4.ipv4)
            if ip is not None:
                nw_src = ip.src
                nw_dst = ip.dst
                nw_proto = ip.proto

                #self.logger.info("ip_src=%s", nw_src)
                #self.logger.info("ip_dst=%s", nw_dst)
                #self.logger.info("ip_proto=%s", nw_proto)
                #nw_tos = ip.tos

                t = pkt.get_protocol(tcp.tcp)
                if t is not None:
                    tp_src = t.src_port
                    tp_dst = t.dst_port
                    match = parser.OFPMatch(
                        ipv4_src=nw_src,
                        ipv4_dst=nw_dst,
                        ip_proto=nw_proto,
                        tcp_src=tp_src,
                        tcp_dst=tp_dst,
                        eth_type=ether_types.ETH_TYPE_IP)  #eth.ethertype)
                    #self.logger.info("Added flow entry - IPv4 packet - TCP: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst)
                    #self.logger.info("Inserted flow entry: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst)

                u = pkt.get_protocol(udp.udp)
                if u is not None:
                    tp_src = u.src_port
                    tp_dst = u.dst_port
                    match = parser.OFPMatch(
                        ipv4_src=nw_src,
                        ipv4_dst=nw_dst,
                        ip_proto=nw_proto,
                        udp_src=tp_src,
                        udp_dst=tp_dst,
                        eth_type=ether_types.ETH_TYPE_IP)  #eth.ethertype)
                    #self.logger.info("Added flow entry - IPv4 packet - UDP: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst)
                    #self.logger.info("Inserted flow entry: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst)

                s = pkt.get_protocol(sctp.sctp)
                if s is not None:
                    tp_src = s.src_port
                    tp_dst = s.dst_port
                    match = parser.OFPMatch(
                        ipv4_src=nw_src,
                        ipv4_dst=nw_dst,
                        ip_proto=nw_proto,
                        udp_src=tp_src,
                        udp_dst=tp_dst,
                        eth_type=ether_types.ETH_TYPE_IP)  #eth.ethertype)
                    #self.logger.info("Added flow entry - IPv4 packet - SCTP: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst)
                    #self.logger.info("Inserted flow entry: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst)

                ic = pkt.get_protocol(icmp.icmp)
                if ic is not None:
                    tp_src = ic.type
                    tp_dst = ic.code
                    match = parser.OFPMatch(
                        ipv4_src=nw_src,
                        ipv4_dst=nw_dst,
                        ip_proto=nw_proto,
                        icmpv4_type=tp_src,
                        icmpv4_code=tp_dst,
                        eth_type=ether_types.ETH_TYPE_IP)  #eth.ethertype)
                    #self.logger.info("Added flow entry for IPv4 packet - ICMP: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst)
                    #self.logger.info("Inserted flow entry: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst)
#-------
#match = parser.OFPMatch(ipv4_src=nw_src, ipv4_dst=nw_dst, ip_proto=nw_proto, eth_type=eth.ethertype)

#match = parser.OFPMatch(in_port=in_port, ipv4_src=nw_src, ipv4_dst=nw_dst, ip_proto=nw_proto, eth_type=eth.ethertype)

#tcp_src=tp.src_port, tcp_dst=tp.dst_port)
#match = parser.OFPMatch(in_port=in_port, ipv4_dst='192.168.1.101')#in_port=in_port, eth_src=src, eth_dst=dst
                if match is not None:
                    #self.logger.info("IPv4 packet:")
                    self.n_flows += 1  #number of flow entries increased by 1.
                    if (self.n_flows % 100 == 0):
                        self.logger.info("#flow-entries installed: %d",
                                         self.n_flows)
                    ###

                    if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                        self.add_flow(datapath, 2, match, actions,
                                      msg.buffer_id)
                        return
                    else:
                        self.add_flow(datapath, 2, match, actions)
                    #self.logger.info("New flow entry added to switch")

            else:
                self.non_ipv4_packet_count += 1
                if (self.non_ipv4_packet_count % 10 == 0):
                    self.logger.info("Non-IPv4 packets (ignored): %d",
                                     self.non_ipv4_packet_count)

                #return
            #match = parser.OFPMatch(in_port=in_port, eth_src=src, eth_dst=dst)
            #Thien-testing
            #match = self.getFullMatch(msg)
            #match = self.getFullMatch(msg, in_port)

            # verify if we have a valid buffer_id, if yes avoid to send both
            # flow_mod & packet_out

            #if msg.buffer_id != ofproto.OFP_NO_BUFFER:
            #    self.add_flow(datapath, 1, match, actions, msg.buffer_id)
            #    return
            #else:
            #    self.add_flow(datapath, 1, match, actions)

            #self.logger.info("New flow entry added to switch")

        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
Example #9
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return

        dst = eth.dst
        src = eth.src
        pkt_arp = pkt.get_protocols(arp.arp)

        pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
        print "pkt_ip####", pkt_ipv4

        ipProto = None
        dstIp = None
        srcIp = None

        if pkt_ipv4:
            #            ip_str = pkt_ipv4[0]
            ipProto = pkt_ipv4.proto
            dstIp = pkt_ipv4.dst
            srcIp = pkt_ipv4.src
            self.logger.info("packet IP info %s %s %s", dstIp, srcIp, ipProto)

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        # learn a mac address to avoid FLOOD next time.

        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]
        actions_drop = []
        actions_forward = [parser.OFPActionOutput(out_port)]

        if pkt_ipv4:
            #matched_rule = self.comparison.compare(PROTOCOLS[ipProto], srcIp, dstIp)
            #print "matched_rule: ", matched_rule

            if ipProto == 2:
                # for igmp message
                pass

            elif ipProto == 6:
                #tcp pkt
                pkt_tcp = pkt.get_protocol(tcp.tcp)
                print "####pkt_tcp", pkt_tcp

                tcp_sport = pkt_tcp.src_port
                tcp_dport = pkt_tcp.dst_port

                matched_rule = self.comparison.compare(PROTOCOLS[ipProto],
                                                       srcIp, dstIp, tcp_sport,
                                                       tcp_dport)
                print "matched_rule: ", matched_rule
                if not matched_rule:
                    return

                if matched_rule['target'] == 'ACCEPT':
                    match = parser.OFPMatch(ipv4_src=srcIp,
                                            ipv4_dst=dstIp,
                                            ip_proto=ipProto,
                                            tcp_src=tcp_sport,
                                            tcp_dst=tcp_dport,
                                            eth_type=0x800)
                    self.add_flow(datapath, 1, match, actions_forward,
                                  LIFETIME_ROUTE)
                    #  accept, forward action
                elif matched_rule['target'] == 'DROP':
                    match = parser.OFPMatch(ipv4_src=srcIp,
                                            ipv4_dst=dstIp,
                                            ip_proto=ipProto,
                                            tcp_src=tcp_sport,
                                            tcp_dst=tcp_dport,
                                            eth_type=0x800)
                    self.add_flow(datapath, 1, match, actions_drop,
                                  LIFETIME_ROUTE)
                else:
                    # for pkts without a matched rule
                    return

            elif ipProto == 17:
                #tcp pkt
                pkt_tcp = pkt.get_protocol(udp.udp)
                print "####pkt_udp", pkt_udp

                udp_sport = pkt_udp.src_port
                udp_dport = pkt_udp.dst_port

                matched_rule = self.comparison.compare(PROTOCOLS[ipProto],
                                                       srcIp, dstIp, udp_sport,
                                                       tcp_dport)
                print "matched_rule: ", matched_rule
                if not matched_rule:
                    return

                if matched_rule['target'] == 'ACCEPT':
                    match = parser.OFPMatch(ipv4_src=srcIp,
                                            ipv4_dst=dstIp,
                                            ip_proto=ipProto,
                                            udp_src=udp_sport,
                                            udp_dst=tcp_dport,
                                            eth_type=0x800)
                    self.add_flow(datapath, 1, match, actions_forward,
                                  LIFETIME_ROUTE)
                    #  accept, forward action
                elif matched_rule['target'] == 'DROP':
                    match = parser.OFPMatch(ipv4_src=srcIp,
                                            ipv4_dst=dstIp,
                                            ip_proto=ipProto,
                                            udp_src=udp_sport,
                                            udp_dst=udp_dport,
                                            eth_type=0x800)
                    self.add_flow(datapath, 1, match, actions_drop,
                                  LIFETIME_ROUTE)
                else:
                    # for pkts without a matched rule
                    return

            else:
                matched_rule = self.comparison.compare(PROTOCOLS[ipProto],
                                                       srcIp, dstIp)
                print "matched_rule: ", matched_rule

                if matched_rule['target'] == 'ACCEPT':
                    match = parser.OFPMatch(ipv4_src=srcIp,
                                            ipv4_dst=dstIp,
                                            ip_proto=ipProto,
                                            eth_type=0x800)
                    self.add_flow(datapath, 1, match, actions_forward,
                                  LIFETIME_ROUTE)
                    #  accept, forward action
                elif matched_rule['target'] == 'DROP':
                    match = parser.OFPMatch(ipv4_src=srcIp,
                                            ipv4_dst=dstIp,
                                            ip_proto=ipProto,
                                            eth_type=0x800)
                    self.add_flow(datapath, 1, match, actions_drop,
                                  LIFETIME_ROUTE)
                else:
                    # for pkts without a matched rule
                    return

        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
Example #10
0
    def _packet_in_handler(self, ev):
        """
            Hanle the packet in packet, and register the access info.
        """
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
#        print "myapp"
        msg = ev.msg
        datapath = msg.datapath
        #        ofproto = datapath.ofproto
        #        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[
            0]  # pkt.get_protocols(ethernet.ethernet)是个列表,列表里只有一个元素,用[0]直接取出元素
        # 所有的包都有以太网头部,所以能直接get,但是ip等协议需要判断是否存在
        # 包过滤开始
        if eth.ethertype == ether_types.ETH_TYPE_LLDP or eth.ethertype == ether_types.ETH_TYPE_IPV6:
            # ignore lldp packet
            return

        dst = eth.dst
        src = eth.src
        #        dpid = datapath.id

        if dst == ETHERNET_GROUP_MULTICAST:
            # ignore mDNS packet
            return

        if eth.ethertype == ether_types.ETH_TYPE_IP and dst == ETHERNET_MULTICAST:  # DHCP广播包, IP=0x0800
            # drop DHCP packet
            self.logger.debug("Drop ip_type and eth_dst == ff:ff:ff:ff:ff:ff")
            out = datapath.ofproto_parser.OFPPacketOut(
                datapath=datapath,
                buffer_id=datapath.ofproto.OFP_NO_BUFFER,
                in_port=in_port,
                actions=[],
                data=None)
            datapath.send_msg(out)
            return

        header_list = dict(
            (p.protocol_name, p) for p in pkt.protocols if type(p) != str)
        #        print "header_list:", header_list
        if IPv4 in header_list:
            ipv4_packet = pkt.get_protocols(ipv4.ipv4)[0]
            #            print "pkt.get_protocols(ipv4.ipv4)[0]:", pkt.get_protocols(ipv4.ipv4)[0], '\n'
            if ipv4_packet.src == "0.0.0.0" or ipv4_packet.dst == "255.255.255.255":  # DHCP广播包
                self.logger.debug(
                    "Drop ip_src == 0.0.0.0 or ip_dst == 255.255.255.255")
                out = datapath.ofproto_parser.OFPPacketOut(
                    datapath=datapath,
                    buffer_id=datapath.ofproto.OFP_NO_BUFFER,
                    in_port=in_port,
                    actions=[],
                    data=None)
                datapath.send_msg(out)
                return
        # 包过滤结束

        # 获取access info
        arp_pkt = pkt.get_protocol(arp.arp)
        ip_pkt = pkt.get_protocol(ipv4.ipv4)  # 如果没有这个包就赋值None
        #        print "ip_pkt:", ip_pkt, '\n'
        if arp_pkt:
            #            print 'arp'
            arp_src_ip = arp_pkt.src_ip
            #            arp_dst_ip = arp_pkt.dst_ip
            mac = arp_pkt.src_mac
            # Record the access info
            self.register_access_info(datapath.id, in_port, arp_src_ip, mac)
        elif ip_pkt:
            #            print 'ipv4'
            src_ip = ip_pkt.src
            #            dst_ip = ip_pkt.dst
            mac = src
            # Record the access info
            self.register_access_info(datapath.id, in_port, src_ip, mac)
Example #11
0
    def getFullMatch(self, msg, in_port):
        datapath = msg.datapath
        parser = datapath.ofproto_parser

        #in_port=None
        dl_src = None
        dl_dst = None
        dl_vlan = None
        dl_vlan_pcp = None
        dl_type = None
        nw_tos = None
        nw_proto = None
        nw_src = None
        nw_dst = None
        tp_src = None
        tp_dst = None

        #in_port = msg.in_port
        #in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)

        #eth = pkt.get_protocol(ethernet.ethernet)
        eth = pkt.get_protocols(ethernet.ethernet)

        dl_src = eth.src
        dl_dst = eth.dst
        #dl_type = eth.ethertype

        vl = pkt.get_protocol(vlan.vlan)
        if vl is not None:
            dl_vlan = vl.vid
            dl_vlan_pcp = vl.pcp
            #dl_type = vl.ethertype

        ip = pkt.get_protocol(ipv4.ipv4)
        if ip is not None:
            nw_src = ip.src
            nw_dst = ip.dst
            nw_proto = ip.proto
            nw_tos = ip.tos

            t = pkt.get_protocol(tcp.tcp)
            if t is not None:
                tp_src = t.src_port
                tp_dst = t.dst_port

            u = pkt.get_protocol(udp.udp)
            if u is not None:
                tp_src = u.src_port
                tp_dst = u.dst_port

            ic = pkt.get_protocol(icmp.icmp)
            if ic is not None:
                tp_src = ic.type
                tp_dst = ic.code

        a = pkt.get_protocol(arp.arp)
        if a is not None:
            nw_src = a.src_ip
            nw_dst = a.dst_ip
            nw_proto = a.opcode

        match = parser.OFPMatch(
            dl_src=mac.haddr_to_bin(dl_src),  #dl_src,  
            dl_dst=mac.haddr_to_bin(dl_dst),  # dl_dst,
            #dl_vlan=dl_vlan,
            #dl_vlan_pcp=dl_vlan_pcp,
            #dl_type=dl_type,
            #nw_tos=nw_tos,
            #nw_proto=nw_proto,
            #nw_src=self.ipv4_to_int(nw_src),
            #nw_dst=self.ipv4_to_int(nw_dst),
            #tp_src=tp_src,
            #tp_dst=tp_dst,
            in_port=in_port)
        return match
Example #12
0
    def arp_forwarding(self, msg, arp_header, from_datapath, ether,
                       ethernet_src, ethernet_dst, in_port):
        ofproto = from_datapath.ofproto
        arp_src_ip = arp_header.src_ip
        arp_dst_ip = arp_header.dst_ip
        arp_src_mac = arp_header.src_mac
        arp_dst_mac = arp_header.dst_mac

        if ethernet_dst == mac.BROADCAST_STR:  # Handle ARP broadcast
            self.logger.info(
                'This is ARP broadcast received at port {} of switch {} from IP {}, ARP Src Mac {}, ethernet src {} to IP {}, ARP Destn Mac {}, ethernet dst {}'
                .format(in_port, from_datapath.id, arp_src_ip, arp_src_mac,
                        ethernet_src, arp_dst_ip, arp_dst_mac, ethernet_dst))

            if self.ip_mac_table.get(
                    arp_src_ip
            ) == None:  # No src ip found, so storing it in the table
                self.logger.info(
                    "****No mac entry found for IP. adding entry.....****")
                self._register_host_entry(arp_src_ip, arp_src_mac,
                                          from_datapath.id, in_port)

            if self.ip_mac_table.get(
                    arp_dst_ip
            ) != None:  #dst_ip exist in ip_mac_table, so proxy it
                ARP_Reply = packet.Packet()
                mac_from_table = self.ip_mac_table.get(arp_dst_ip)
                ARP_Reply.add_protocol(
                    ethernet.ethernet(ethertype=ether.ethertype,
                                      dst=ethernet_src,
                                      src=mac_from_table))
                ARP_Reply.add_protocol(
                    arp.arp(opcode=arp.ARP_REPLY,
                            src_mac=mac_from_table,
                            src_ip=arp_dst_ip,
                            dst_mac=arp_src_mac,
                            dst_ip=arp_src_ip))
                ARP_Reply.serialize()
                from_datapath.send_msg(
                    self._build_packet_out(from_datapath,
                                           ofproto.OFP_NO_BUFFER,
                                           ofproto.OFPP_CONTROLLER, in_port,
                                           ARP_Reply.data))
                self.logger.info("****Found mac entry for IP. Proxy-ing****")

            else:  #no dst_ip in ip_mac_table, flood
                for dpid_port_tup in self.dpid_port_set:
                    if dpid_port_tup not in self.ip_dpidport.values():
                        self.logger.info(
                            "********Flooding {}***********".format(
                                dpid_port_tup))
                        datapath = self.datapath_list[dpid_port_tup[0]]
                        datapath.send_msg(
                            self._build_packet_out(datapath,
                                                   ofproto.OFP_NO_BUFFER,
                                                   ofproto.OFPP_CONTROLLER,
                                                   dpid_port_tup[1], msg.data))

        else:  # if ARP packet and its a reply
            self.logger.info(
                'This is ARP reply received at port {} of switch {} from IP {}, ARP Src Mac {}, ethernet src {} to IP {}, ARP Destn Mac {}, ethernet dst {}'
                .format(in_port, from_datapath.id, arp_src_ip, arp_src_mac,
                        ethernet_src, arp_dst_ip, arp_dst_mac, ethernet_dst))
            self._register_host_entry(arp_src_ip, arp_src_mac,
                                      from_datapath.id, in_port)
            dpid_inport = self.ip_dpidport.get(arp_dst_ip)
            datapath = self.datapath_list[dpid_inport[0]]
            datapath.send_msg(
                self._build_packet_out(datapath, ofproto.OFP_NO_BUFFER,
                                       ofproto.OFPP_CONTROLLER, dpid_inport[1],
                                       msg.data))

        self.logger.info(
            "*********************************************************************************************"
        )
        return
Example #13
0
    def _packet_in_handler(self, ev):
        """
        Called every time, when the controller receives a PACKET_IN message
        :type ev: ryu.controller.ofp_event.EventOFPPacketIn
        :return: None
        :rtype: None
        """
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        dpid = datapath.id
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        # create a Packet object out of the payload
        # TODO: 1) Create a Packet from the message data
        pkt = packet.Packet(msg.data)

        # TODO: 1) Why do we need obtain the information for four different protocols?
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        ip_pkt = pkt.get_protocol(ipv4.ipv4)
        ip_pkt_6 = pkt.get_protocol(ipv6.ipv6)
        arp_pkt = pkt.get_protocol(arp.arp)

        # Don't do anything with IPV6 packets.
        if isinstance(ip_pkt_6, ipv6.ipv6):
            actions = []
            match = parser.OFPMatch(ether_types.ETH_TYPE_IPV6)
            self.add_flow(datapath, 0, 1, actions)
            return

        # ARP Protcol
        if isinstance(arp_pkt, arp.arp):
            if self.mac_learning(dpid, eth.src, in_port) is False:
                self.logger.debug("ARP packet enter in different ports")
                return
# Complete ARP protocol
            self.arp_forwarding(msg, arp_pkt.src_ip, arp_pkt.dst_ip, eth)

        # This is the focus of this workshop -> Process the IPv4 message
        if isinstance(ip_pkt, ipv4.ipv4):
            # find the switch in the mac_to_port table
            mac_to_port_table = self.mac_to_port.get(dpid)
            if mac_to_port_table is None:
                self.logger.info("Dpid is not in mac_to_port")
                return
            # source and destination mac address of the ethernet packet
            dst = eth.dst
            src = eth.src

            out_port = None
            # "Known destination MAC address" -> We have seen this before
            if dst in mac_to_port_table:
                #TODO: Final Questions - Why do we need the foolowing special cases?
                if dpid == 1 and in_port == 1:
                    # This is the special case for host 1 only do create create the group the first time
                    if self.FLAGS is True:
                        self.send_group_mod(datapath)
                        self.FLAGS = False
                    #TODO: Final Questions - Where is this group defined?
                    actions = [parser.OFPActionGroup(group_id=7)]
                    #TODO: Final Questions - Why do we need to create groups and flows in different steps?
                    match = parser.OFPMatch(in_port=in_port,
                                            eth_type=eth.ethertype,
                                            ipv4_src=ip_pkt.src)
                    self.add_flow(datapath, 0, 3, actions)
                    # asign output at 2
                    self.send_packet_out(datapath, msg.buffer_id, in_port, 2,
                                         msg.data)
                else:
                    #Normal flows
                    # "Install a flow to avoid packet_in next time">
                    out_port = mac_to_port_table[eth.dst]
                    actions = [parser.OFPActionOutput(out_port)]
                    match = parser.OFPMatch(in_port=in_port,
                                            eth_dst=eth.dst,
                                            eth_type=eth.ethertype)
                    #Add the flow to the switch
                    self.add_flow(datapath, 0, 1, actions)
                    #Send packet to its destination
                    self.send_packet_out(datapath, msg.buffer_id, in_port,
                                         out_port, msg.data)
            # "Unknown destination MAC address"
            else:
                # MAC is not Known
                if self.mac_learning(dpid, eth.src, in_port) is False:
                    self.logger.debug("IPV4 packet enter in different ports")
                    return
                else:
                    # we don't know anything, so flood the network
                    self.flood(msg)
Example #14
0
    def packet_in(self, event):
        """Process a packet-in event from the controller.

        :param event: The OpenFlow event.
        """
        msg = event.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        if msg.table_id != self._table_id_l2:
            # print "l2switch packet " + str( packet.Packet(msg.data))
            print(
                "l2switch not dealing with packet in messages from other tables. table id: "
                + str(msg.table_id))
            return

        pkt = packet.Packet(msg.data)
        eth_head = pkt.get_protocols(ethernet.ethernet)[0]

        eth_dst = eth_head.dst
        eth_src = eth_head.src

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        print("{0}: Packet in\t-\tData-path ID: {1}, Source Ethernet: "
              "{2}, Destination Ethernet: {3}, Ingress switch port: "
              "{4}".format(self._APP_NAME, dpid, eth_src, eth_dst, in_port))

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][eth_src] = in_port

        if eth_dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][eth_dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]
        inst = [
            parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)
        ]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port, eth_dst=eth_dst)

            print("{0}: New flow\t-\t{1}".format(self._APP_NAME, pkt))
            priority = 1000  # ofproto_v1_3.OFP_DEFAULT_PRIORITY

            # verify if we have a valid buffer_id, if yes avoid to send
            # both flow_mod & packet_out
            if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                self._contr.add_flow(datapath, priority, match, inst, 0,
                                     self._table_id_l2, msg.buffer_id)
                return
            else:
                self._contr.add_flow(datapath, priority, match, inst, 0,
                                     self._table_id_l2)
                pass

        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        self._contr.packet_out(datapath, out)
        print("l2switch packet out src: eth_src " + eth_src + ". eth_dst " +
              eth_dst)
Example #15
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocol(ethernet.ethernet)
        arp_pkt = pkt.get_protocol(arp.arp)
        ip_pkt = pkt.get_protocol(ipv4.ipv4)

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            return

        if pkt.get_protocol(ipv6.ipv6):
            match = parser.OFPMatch(eth_type=eth.ethertype)
            actions = []
            self.add_flow(datapath, 1, match, actions)
            return None

        dst = eth.dst
        src = eth.src
        dpid = datapath.id

        if src not in self.hosts:
            self.hosts[src] = (dpid, in_port)

        out_port = ofproto.OFPP_FLOOD

        if eth.ethertype == ether_types.ETH_TYPE_IP:
            nw = pkt.get_protocol(ipv4.ipv4)
            if nw.proto == inet.IPPROTO_UDP:
                l4 = pkt.get_protocol(udp.udp)
            elif nw.proto == inet.IPPROTO_TCP:
                l4 = pkt.get_protocol(tcp.tcp)

        if eth.ethertype == ether_types.ETH_TYPE_IP and nw.proto == inet.IPPROTO_UDP:
            src_ip = nw.src
            dst_ip = nw.dst

            self.arp_table[src_ip] = src
            h1 = self.hosts[src]
            h2 = self.hosts[dst]

            self.logger.info(f" IP Proto UDP from: {nw.src} to: {nw.dst}")

            out_port = self.install_paths(h1[0], h1[1], h2[0], h2[1], src_ip,
                                          dst_ip, 'UDP', pkt)
            self.install_paths(h2[0], h2[1], h1[0], h1[1], dst_ip, src_ip,
                               'UDP', pkt)

        elif eth.ethertype == ether_types.ETH_TYPE_IP and nw.proto == inet.IPPROTO_TCP:
            src_ip = nw.src
            dst_ip = nw.dst

            self.arp_table[src_ip] = src
            h1 = self.hosts[src]
            h2 = self.hosts[dst]

            self.logger.info(f" IP Proto TCP from: {nw.src} to: {nw.dst}")

            out_port = self.install_paths(h1[0], h1[1], h2[0], h2[1], src_ip,
                                          dst_ip, 'TCP', pkt)
            self.install_paths(h2[0], h2[1], h1[0], h1[1], dst_ip, src_ip,
                               'TCP', pkt)

        elif eth.ethertype == ether_types.ETH_TYPE_IP and nw.proto == inet.IPPROTO_ICMP:
            src_ip = nw.src
            dst_ip = nw.dst

            self.arp_table[src_ip] = src
            h1 = self.hosts[src]
            h2 = self.hosts[dst]

            self.logger.info(f" IP Proto ICMP from: {nw.src} to: {nw.dst}")

            out_port = self.install_paths(h1[0], h1[1], h2[0], h2[1], src_ip,
                                          dst_ip, 'ICMP', pkt)
            self.install_paths(h2[0], h2[1], h1[0], h1[1], dst_ip, src_ip,
                               'ICMP', pkt)
        elif eth.ethertype == ether_types.ETH_TYPE_ARP:
            src_ip = arp_pkt.src_ip
            dst_ip = arp_pkt.dst_ip

            if arp_pkt.opcode == arp.ARP_REPLY:
                self.arp_table[src_ip] = src
                h1 = self.hosts[src]
                h2 = self.hosts[dst]

                self.logger.info(
                    f" ARP Reply from: {src_ip} to: {dst_ip} H1: {h1} H2: {h2}"
                )

                out_port = self.install_paths(h1[0], h1[1], h2[0], h2[1],
                                              src_ip, dst_ip, 'ARP', pkt)
                self.install_paths(h2[0], h2[1], h1[0], h1[1], dst_ip, src_ip,
                                   'ARP', pkt)

            elif arp_pkt.opcode == arp.ARP_REQUEST:
                if dst_ip in self.arp_table:
                    self.arp_table[src_ip] = src
                    dst_mac = self.arp_table[dst_ip]
                    h1 = self.hosts[src]
                    h2 = self.hosts[dst_mac]

                    self.logger.info(
                        f" ARP Reply from: {src_ip} to: {dst_ip} H1: {h1} H2: {h2}"
                    )

                    out_port = self.install_paths(h1[0], h1[1], h2[0], h2[1],
                                                  src_ip, dst_ip, 'ARP', pkt)
                    self.install_paths(h2[0], h2[1], h1[0], h1[1], dst_ip,
                                       src_ip, 'ARP', pkt)

        actions = [parser.OFPActionOutput(out_port)]

        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
Example #16
0
    def packet_in_handler(self, ev):
        if self.virtual_ip == None or self.servers == None:
            return

        msg = ev.msg
        datapath = msg.datapath
        ofp = datapath.ofproto
        ofp_parser = datapath.ofproto_parser
        in_port = msg.match['in_port']
        dpid = datapath.id

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether.ETH_TYPE_ARP:
            arp_hdr = pkt.get_protocols(arp.arp)[0]

            if arp_hdr.dst_ip == self.virtual_ip and arp_hdr.opcode == arp.ARP_REQUEST:

                reply_pkt = self.formulate_arp_reply(arp_hdr.src_mac,
                                                     arp_hdr.src_ip)

                actions = [ofp_parser.OFPActionOutput(in_port)]
                out = ofp_parser.OFPPacketOut(datapath=datapath,
                                              in_port=ofp.OFPP_ANY,
                                              data=reply_pkt.data,
                                              actions=actions,
                                              buffer_id=UINT32_MAX)
                datapath.send_msg(out)

            return

        # Only handle IPv4 traffic going forward
        elif eth.ethertype != ether.ETH_TYPE_IP:
            return

        iphdr = pkt.get_protocols(ipv4.ipv4)[0]

        # Only handle traffic destined to virtual IP
        if (iphdr.dst != self.virtual_ip):
            return

        # Only handle TCP traffic
        if iphdr.proto != inet.IPPROTO_TCP:
            return

        tcphdr = pkt.get_protocols(tcp.tcp)[0]

        valid_servers = []
        for server in self.servers:
            outport = self.learning_switch.get_attachment_port(
                dpid, server['mac'])
            if outport != None:
                server['outport'] = outport
                valid_servers.append(server)

        total_servers = len(valid_servers)

        # If we there are no servers with location known, then skip
        if total_servers == 0:
            return

        # Round robin selection of servers
        index = self.server_index % total_servers
        selected_server_ip = valid_servers[index]['ip']
        selected_server_mac = valid_servers[index]['mac']
        selected_server_outport = valid_servers[index]['outport']
        self.server_index += 1
        print("Selected server %s" % selected_server_ip)

        ########### Setup route to server
        match = ofp_parser.OFPMatch(in_port=in_port,
                                    eth_type=eth.ethertype,
                                    eth_src=eth.src,
                                    eth_dst=eth.dst,
                                    ip_proto=iphdr.proto,
                                    ipv4_src=iphdr.src,
                                    ipv4_dst=iphdr.dst,
                                    tcp_src=tcphdr.src_port,
                                    tcp_dst=tcphdr.dst_port)

        if self.rewrite_ip_header:
            actions = [
                ofp_parser.OFPActionSetField(eth_dst=selected_server_mac),
                ofp_parser.OFPActionSetField(ipv4_dst=selected_server_ip),
                ofp_parser.OFPActionOutput(selected_server_outport)
            ]
        else:
            actions = [
                ofp_parser.OFPActionSetField(eth_dst=selected_server_mac),
                ofp_parser.OFPActionOutput(selected_server_outport)
            ]

        inst = [
            ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)
        ]

        cookie = random.randint(0, 0xffffffffffffffff)

        mod = ofp_parser.OFPFlowMod(datapath=datapath,
                                    match=match,
                                    idle_timeout=10,
                                    instructions=inst,
                                    buffer_id=msg.buffer_id,
                                    cookie=cookie)
        datapath.send_msg(mod)

        ########### Setup reverse route from server
        match = ofp_parser.OFPMatch(in_port=selected_server_outport,
                                    eth_type=eth.ethertype,
                                    eth_src=selected_server_mac,
                                    eth_dst=eth.src,
                                    ip_proto=iphdr.proto,
                                    ipv4_src=selected_server_ip,
                                    ipv4_dst=iphdr.src,
                                    tcp_src=tcphdr.dst_port,
                                    tcp_dst=tcphdr.src_port)

        if self.rewrite_ip_header:
            actions = ([
                ofp_parser.OFPActionSetField(eth_src=self.virtual_mac),
                ofp_parser.OFPActionSetField(ipv4_src=self.virtual_ip),
                ofp_parser.OFPActionOutput(in_port)
            ])
        else:
            actions = ([
                ofp_parser.OFPActionSetField(eth_src=self.virtual_mac),
                ofp_parser.OFPActionOutput(in_port)
            ])

        inst = [
            ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)
        ]

        cookie = random.randint(0, 0xffffffffffffffff)

        mod = ofp_parser.OFPFlowMod(datapath=datapath,
                                    match=match,
                                    idle_timeout=10,
                                    instructions=inst,
                                    cookie=cookie)
        datapath.send_msg(mod)
Example #17
0
    def _packet_in_handler(self, ev):

        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)

        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)

        eth = pkt.get_protocols(ethernet.ethernet)[0]

        dst = eth.dst
        src = eth.src
        #self.pcap_writer.write_pkt(ev.msg.data)
        #Tamanho Janela TCP
        if eth.ethertype == ether_types.ETH_TYPE_IP:
            ipv4_temp = pkt.get_protocol(ipv4.ipv4)
            tcp_temp = pkt.get_protocol(tcp.tcp)

            udp_temp = pkt.get_protocol(udp.udp)
            #Clinte-To-Server
            self.logger.debug("*** Desencaplusando... ")
            # Tamanho Payloada
            payload = sys.getsizeof(pkt.data)
            self.logger.debug("(PKT) Tamanho Payload Pacote :  %s ", payload)
            self.logger.debug("(IP):  %s ", ipv4_temp)
            self.logger.debug("(IP) Code Protocol:   %s ", ipv4_temp.proto)
            #comprimento Pacote Ip
            self.logger.debug("(IP) Comprimento :  %s ",
                              ipv4_temp.total_length)
            #Comprimento comp_cabecalho TCP
            self.logger.debug("(IP) Comprimento Cabecalho :  %s ",
                              ipv4_temp.header_length)
            self.logger.debug("============== /// ==============")
            self.logger.debug("(TCP):  %s ", tcp_temp)
            self.logger.debug("(UDP):  %s ", udp_temp)

            header_length_bytes = (ipv4_temp.header_length * 32) / 8

            #Web
            if tcp_temp != None and self.hasFlagsClientToServerTCP(
                    tcp_temp.bits,
                [TCP_SYN, TCP_ACK]) and ipv4_temp.proto == 6:
                self.logger.debug(
                    "*** Info  Extracting Attributes Choosen... ")
                self.logger.debug("(TCP) porta Origem:  %s ",
                                  tcp_temp.src_port)
                self.logger.debug("(TCP) Porta Destino :  %s ",
                                  tcp_temp.dst_port)

                self.logger.debug("(TCP) Tamanho Janela :  %s ",
                                  tcp_temp.window_size)

                #dpid = datapath.id
                #self.host2host_instance.setdefault(dpid, {})

                h2h = None
                key = src + dst
                if len(self.host2host_instance) > 0:
                    if key in self.host2host_instance:
                        h2h = self.host2host_instance[key]
                        h2h.updateStateHostToHostByPacket(
                            ipv4_temp.total_length, header_length_bytes)
                    else:
                        #self.host2host_instance.setdefault(src + dst, {})
                        h2h = host2host(tcp_temp.src_port, tcp_temp.dst_port,
                                        ipv4_temp.total_length,
                                        header_length_bytes, 6)
                        self.host2host_instance[key] = h2h
                else:
                    #self.host2host_instance.setdefault(src + dst, {})
                    h2h = host2host(tcp_temp.src_port, tcp_temp.dst_port,
                                    ipv4_temp.total_length,
                                    header_length_bytes, 6)
                    self.host2host_instance[key] = h2h

                self.printInstanceH2H()

                #Classificador J48 Tree
                #host2host = host2host(tcp_temp.src_port, tcp_temp.dst_port,payload,ipv4_temp.total_length,6 )
                #srcporta,dstporta, tamtotal_pacote_menor,tamtotal_pacote_maior,codigo_protocolo
                fluxo_classe = self.weka_decision_tree(h2h.src_port,
                                                       h2h.dst_port,
                                                       h2h.smaller_packet_size,
                                                       h2h.bigger_packet_size,
                                                       h2h.protocol_code)

                self.logger.debug("(Class):  %s", fluxo_classe)

            if udp_temp != None and ipv4_temp.proto == UDP_CODE:
                self.logger.debug(
                    "*** Info  Extracting Attributes (UDP) Choosen... ")
                self.logger.debug("(UDP) porta Origem:  %s ",
                                  udp_temp.src_port)
                self.logger.debug("(UDP) Porta Destino :  %s ",
                                  udp_temp.dst_port)

                self.logger.debug("============== /// ==============")

                #dpid = datapath.id
                #self.host2host_instance.setdefault(dpid, {})

                h2h = None
                key = src + dst
                if len(self.host2host_instance) > 0:
                    if key in self.host2host_instance:
                        h2h = self.host2host_instance[key]
                        h2h.updateStateHostToHostByPacket(
                            ipv4_temp.total_length, header_length_bytes)
                    else:
                        #self.host2host_instance.setdefault(src + dst, {})
                        h2h = host2host(udp_temp.src_port, udp_temp.dst_port,
                                        ipv4_temp.total_length,
                                        header_length_bytes, UDP_CODE)
                        self.host2host_instance[key] = h2h
                else:
                    #self.host2host_instance.setdefault(src + dst, {})
                    h2h = host2host(udp_temp.src_port, udp_temp.dst_port,
                                    ipv4_temp.total_length,
                                    header_length_bytes, UDP_CODE)
                    self.host2host_instance[key] = h2h

                self.printInstanceH2H()

                #Classificador J48 Tree
                #host2host = host2host(tcp_temp.src_port, tcp_temp.dst_port,payload,ipv4_temp.total_length,6 )
                #srcporta,dstporta, tamtotal_pacote_menor,tamtotal_pacote_maior,codigo_protocolo
                fluxo_classe = self.weka_decision_tree(h2h.src_port,
                                                       h2h.dst_port,
                                                       h2h.smaller_packet_size,
                                                       h2h.bigger_packet_size,
                                                       h2h.protocol_code)

                self.logger.debug("(Class):  %s", fluxo_classe)

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        #self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
            # verify if we have a valid buffer_id, if yes avoid to send both
            # flow_mod & packet_out
            if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                return
            else:
                self.add_flow(datapath, 1, match, actions)
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
    def _packet_in_handler(self, ev):
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return
        dst = eth.dst
        src = eth.src

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:

            # check IP Protocol and create a match for IP
            if eth.ethertype == ether_types.ETH_TYPE_IP:
                ip = pkt.get_protocol(ipv4.ipv4)
                srcip = ip.src
                dstip = ip.dst
                match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP,
                                        ipv4_src=srcip,
                                        ipv4_dst=dstip)
                # verify if we have a valid buffer_id, if yes avoid to send both
                # flow_mod & packet_out
                if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                    self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                    return
                else:
                    self.add_flow(datapath, 1, match, actions, 0)
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
Example #19
0
 def _packet_in_handler(self, ev):
  if ev.msg.msg_len < ev.msg.total_len:
   self.logger.info("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len)

  incrcounterIn(1)
  msg = ev.msg
  datapath = msg.datapath
  ofproto = datapath.ofproto
  parser = datapath.ofproto_parser
  in_port = msg.match['in_port']

  pkt = packet.Packet(msg.data)
  eth = pkt.get_protocols(ethernet.ethernet)[0]
  
  dst = eth.dst
  src = eth.src
  
  pkt_ip = pkt.get_protocol(ipv4.ipv4)
  pkt_tcp = pkt.get_protocol(tcp.tcp)
    
  dpid = datapath.id  
  self.mac_to_port.setdefault(dpid, {})

  self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)
  # learn a mac address to avoid FLOOD next time.
  self.mac_to_port[dpid][src] = in_port
  
  if dst in self.mac_to_port[dpid]:
   out_port = self.mac_to_port[dpid][dst]
  else:
   out_port = ofproto.OFPP_FLOOD

  actions = [parser.OFPActionOutput(out_port)]
  
  if out_port != ofproto.OFPP_FLOOD:
   match = parser.OFPMatch(in_port=in_port,eth_dst=dst)
   if pkt_tcp is not None:
    #self.logger.info("Teste 2 - tcp packet")
    if msg.buffer_id != ofproto.OFP_NO_BUFFER:
     incrcounterInR(1)
     self.logger.info("Existe buffer_id %s", msg.buffer_id)
     self.caracterizar_flow(datapath, in_port, out_port, actions, pkt_ip,
             eth, pkt_tcp=pkt_tcp, buffer_id = msg.buffer_id)
     return
    else:
     incrcounterInR(1)
     self.logger.info("Nao existe buffer_id")
     self.caracterizar_flow(datapath, in_port, out_port, actions, pkt_ip,
             eth, pkt_tcp=pkt_tcp)
  
  data = None
  if msg.buffer_id == ofproto.OFP_NO_BUFFER:
   print "buffer_id == OFP_NO_BUFFER"
   data = msg.data

  out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
          in_port=in_port, actions=actions, data=data)
  if out is None:
   self.logger.info("out is None")
  else:
   self.logger.info("out is not None")
  
  datapath.send_msg(out)
Example #20
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return

        dst = eth.dst
        src = eth.src
        pkt_arp = pkt.get_protocols(arp.arp)

        pkt_ipv4 = pkt.get_protocols(ipv4.ipv4)
        print "pkt_ip####", pkt_ipv4

        ipProto = None
        dstIp = None
        srcIp = None

        if pkt_ipv4:
            ip_str = pkt_ipv4[0]
            ipProto = ip_str.proto
            dstIp = ip_str.dst
            srcIp = ip_str.src
            self.logger.info("packet IP info %s %s %s", dstIp, srcIp, ipProto)

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        # learn a mac address to avoid FLOOD next time.

        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        match1 = parser.OFPMatch(ipv4_dst='10.3.255.242', eth_type=0x800)
        match3 = parser.OFPMatch(ipv4_dst='10.3.255.244', eth_type=0x800)
        match2 = parser.OFPMatch(ipv4_dst='10.3.255.243', eth_type=0x800)

        ##actions_forward = [parser.OFPActionOutput(45)]
        actions_drop = []

        actions = [parser.OFPActionOutput(out_port)]
        action1 = [parser.OFPActionOutput(45)]
        action2 = [parser.OFPActionOutput(46)]

        # install a flow to avoid packet_in next time
        #if out_port != ofproto.OFPP_FLOOD:
        if dstIp == '10.3.255.242':
            self.add_flow(datapath, 1, match1, action2)
            self.add_flow(datapath, 1, match3, action1)
            self.add_flow(datapath, 1, match2, actions_drop)
            #self.add_flow(datapath, 1, match2, actions_drop)
            #match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
            #self.add_flo   w(datapath, 1, match, actions)

        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
    def _packet_in_handler(self, ev):
        # get information
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocol(ethernet.ethernet)

        if eth.ethertype == ether_types.ETH_TYPE_IPV6:
            # ignore IPV6 packet
            return
        if eth.dst == "ff:ff:ff:ff:ff:ff":
            # ignore broadcast packet
            return
        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore LLDP packet
            return

        # DEBUG
        # monitor the packet sent to the controller.
        dst = eth.dst
        src = eth.src
        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})
        self.logger.info("%s packet in %s %s %s %s", eth.ethertype, dpid, src,
                         dst, in_port)

        # learn a mac address to avoid FLOOD next time.
        # self.mac_to_port[dpid][src] = in_port

        # DEBUG : for debug , not userd in this app
        # topo learning
        # if src not in self.net:
        #     self.net.add_node(src)
        #     self.net.add_edge(dpid,src,{'port':in_port})
        #     self.net.add_edge(src,dpid)
        """
        if dst in self.net:

            path=nx.shortest_path(self.net,src,dst)   
            next=path[path.index(dpid)+1]
            out_port=self.net[dpid][next]['port']
        
        else:
            out_port = ofproto.OFPP_FLOOD
        """

        # actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

        for tem_datapath in self.datapath_registered:
            tem_id = tem_datapath.id
            # add flow and group table1, 2 to all Aggregations & Edge layer switches.

            if list(str(tem_id))[0] == '2' or list(str(tem_id))[0] == '3':
                self.send_group_mod(tem_datapath)
                # print "send_group_mod to %d"%tem_id
                actions = [parser.OFPActionGroup(group_id=1)]
                match = parser.OFPMatch(in_port=3, eth_dst=dst)
                self.add_flow(tem_datapath, 4, match, actions)
                match = parser.OFPMatch(in_port=4, eth_dst=dst)
                self.add_flow(tem_datapath, 4, match, actions)

                actions = [parser.OFPActionGroup(group_id=2)]
                match = parser.OFPMatch(in_port=1, eth_dst=dst)
                self.add_flow(tem_datapath, 1, match, actions)
                match = parser.OFPMatch(in_port=2, eth_dst=dst)
                self.add_flow(tem_datapath, 1, match, actions)

        # send packet back to what it come from
        actions = []
        self.send_packet_out(msg, actions)
Example #22
0
    def _packet_in_handler(self, ev):

        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)

        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']
        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        if eth.ethertype != ether_types.ETH_TYPE_LLDP:

            #                print("Message")
            #                print(msg)
            print(
                "##################################################################################################################################################################################"
            )
            print("Datapath")
            print(datapath.id)
            #                print("Negotiated Protocol")
            #                print(ofproto)
            #                print("Parser")
            #                print(parser)
            print("in_port")
            print("Message Match ")
            print(msg.match)
            print(in_port)
            #                print("Message Data")
            #                print(msg.data)
            print("Packet")
            print(pkt)
            print("Packet Type")
            print(type(pkt))
            print("Eth")
            print(eth)

            if (pkt.get_protocols(arp.arp)):
                print("This is an ARP Message")
                pkt_arp = pkt.get_protocols(arp.arp)[0]
                arp_dst_ip = pkt_arp.dst_ip
                arp_src_ip = pkt_arp.src_ip
                arp_hlen = pkt_arp.hlen
                arp_hwtype = pkt_arp.hwtype
                arp_plen = pkt_arp.plen
                arp_proto = pkt_arp.proto
                arp_opcode = pkt_arp.opcode
                arp_src_mac = pkt_arp.src_mac
                if (eth.src not in self.topo.nodes()):
                    self.topo.add_node(eth.src, ip=arp_src_ip)
                    print("Chec############")
                    self.arp_list.append(self.topo.node[eth.src]['ip'])
                    self.topo.add_edge(datapath.id, eth.src)
                    self.list_link.append((datapath.id, eth.src, {
                        'out': in_port
                    }))
                print("Destined for ARP")
                print(arp_dst_ip)
                print(self.topo.nodes())
                print(self.topo.edges())
                print(self.list_link)

                if (eth.dst not in self.topo.nodes()):
                    out_port = ofproto.OFPP_FLOOD
                    actions_arp = [parser.OFPActionOutput(out_port)]
                    match_arp = parser.OFPMatch(in_port=in_port,
                                                eth_type=eth.ethertype,
                                                eth_dst=eth.dst,
                                                eth_src=eth.src)
                    ipInst_arp = [
                        parser.OFPInstructionActions(
                            ofproto.OFPIT_APPLY_ACTIONS, actions_arp)
                    ]
                    cookie_arp = random.randint(0, 0xffffffffffffffff)
                    flowMod_arp = parser.OFPFlowMod(datapath=datapath,
                                                    match=match_arp,
                                                    hard_timeout=3,
                                                    instructions=ipInst_arp,
                                                    cookie=cookie_arp)
                    datapath.send_msg(flowMod_arp)

            if ((pkt.get_protocols(arp.arp))
                    or (pkt.get_protocols(ipv4.ipv4))):
                if ((eth.dst in self.topo.nodes())
                        and (eth.src in self.topo.nodes())):
                    print("Calculate Shortest Path on the Fly")
                    sp = nx.shortest_path(self.topo,
                                          source=eth.src,
                                          target=eth.dst)
                    print(sp)
                    if (datapath.id in sp):
                        tem = sp[sp.index(datapath.id) + 1]
                        sd = [(k[0], k[1]) for k in self.list_link]
                        temp = sd.index((datapath.id, tem))
                        out_port = self.list_link[temp][2]['out']
                        print("We are going to add flows ")
                        print("From " + str(datapath.id) + " To " + str(tem) +
                              " Through " + str(out_port))
                        actions = [parser.OFPActionOutput(out_port)]
                        match = parser.OFPMatch(in_port=in_port,
                                                eth_dst=eth.dst,
                                                eth_src=eth.src)
                        #				 match = parser.OFPMatch(in_port=in_port, eth_type=eth.ethertype,  eth_dst=eth.dst, eth_src=eth.src)
                        ipInst = [
                            parser.OFPInstructionActions(
                                ofproto.OFPIT_APPLY_ACTIONS, actions)
                        ]
                        cookie = random.randint(0, 0xffffffffffffffff)
                        flowMod = parser.OFPFlowMod(datapath=datapath,
                                                    priority=100,
                                                    match=match,
                                                    idle_timeout=10,
                                                    instructions=ipInst,
                                                    cookie=cookie)
                        datapath.send_msg(flowMod)
	def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
		if ev.msg.msg_len < ev.msg.total_len:
			self.logger.debug("packet truncated: only %s of %s bytes",
	                              ev.msg.msg_len, ev.msg.total_len)
#		paths = [0, 0, 0, 0, 0]
#		nextLoad = 5
		global paths
		global nextLoad
		msg = ev.msg
		datapath = msg.datapath
		ofproto = datapath.ofproto
		parser = datapath.ofproto_parser
		in_port = msg.match['in_port']

		pkt = packet.Packet(msg.data)
		eth = pkt.get_protocols(ethernet.ethernet)[0]

		if eth.ethertype != ether_types.ETH_TYPE_ARP:
			return
		thisArp = pkt.get_protocols(arp.arp)[0]
		dst = eth.dst
		src = eth.src
		dstIP = thisArp.dst_ip
		srcIP = thisArp.src_ip

		if(dstIP != '10.0.0.10' or
	          (in_port != 1 and in_port != 2 and in_port != 3 and in_port != 4)):
			#handle arps from 5 and 6
			if dstIP == '10.0.0.1':
				mac = '00:00:00:00:00:01'
			elif dstIP == '10.0.0.2':
				mac = '00:00:00:00:00:02'
			elif dstIP == '10.0.0.3':
				mac = '00:00:00:00:00:03'
			else:
				mac = '00:00:00:00:00:04'
			e = ethernet.ethernet(dst=src, src=mac, ethertype=ether_types.ETH_TYPE_ARP)
			a = arp.arp(hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=2, src_mac=mac, 
			            src_ip=dstIP, dst_mac=src, dst_ip=srcIP)
			p = packet.Packet()
			p.add_protocol(e)
			p.add_protocol(a)
			p.serialize()

			actions = [parser.OFPActionOutput(ofproto.OFPP_IN_PORT)]
			out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER,
		                                  in_port=in_port, actions=actions, data=p.data)
			datapath.send_msg(out)
			return

		dpid = datapath.id
		self.mac_to_port.setdefault(dpid, {})

		print(dpid, src, dst, in_port, srcIP, dstIP)

		if paths[in_port] != 0:
			out_port = paths[in_port]
		else:
			out_port = nextLoad
			if nextLoad == 5:
				nextLoad = 6
			else:
				nextLoad = 5
#		out_port = 5
#		targIP = '10.0.0.5'
		targIP = '10.0.0.{}'.format(out_port)
		actions = [parser.OFPActionSetField(ipv4_dst=targIP)]
		actions += [parser.OFPActionOutput(out_port)]
		match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, in_port=in_port, ipv4_dst='10.0.0.10')
		self.add_flow(datapath, 1, match, actions)

		actions = [parser.OFPActionSetField(ipv4_src='10.0.0.10')]
		actions += [parser.OFPActionOutput(in_port)]
		match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, in_port=out_port, ipv4_dst=srcIP)
		self.add_flow(datapath, 1, match, actions)

#		targEth = '00:00:00:00:00:05'
		targEth = '00:00:00:00:00:0{}'.format(out_port)
		e = ethernet.ethernet(dst=src, src=targEth, ethertype=ether_types.ETH_TYPE_ARP)
		a = arp.arp(hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=2, src_mac=targEth, 
		            src_ip='10.0.0.10', dst_mac=src, dst_ip=srcIP)
		p = packet.Packet()
		p.add_protocol(e)
		p.add_protocol(a)
		p.serialize()

		actions = [parser.OFPActionOutput(ofproto.OFPP_IN_PORT)]
		out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER,
	                                  in_port=in_port, actions=actions, data=p.data)
		datapath.send_msg(out)
Example #24
0
    def _packet_in_handler(self, ev):
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        datapath = msg.datapath
        reason = msg.reason
        ofproto = datapath.ofproto
	dpid = datapath.id
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']
        pkt = packet.Packet(msg.data)
        #self.logger.info("packet-in %s" % (pkt,))
        pkt_ethernet = pkt.get_protocols(ethernet.ethernet)[0]
        if not pkt_ethernet:
            return

        if pkt_ethernet.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return

        if reason != ofproto.OFPR_INVALID_TTL:
            #self.logger.info("INVALID TTL %s" % (pkt))
            # self.logger.info("INVALID TTL")
            if(msg.cookie<10000):
            	return
            dst = pkt_ethernet.dst
            src = pkt_ethernet.src
            loss = msg.cookie-10000
            random.seed(random.random())
	    loss_test = random.randint(0,10000)
            pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
            pkt_icmp = pkt.get_protocol(icmp.icmp)
            if(loss_test < loss):
                if pkt_icmp:		# only print icmp pkt loss
                    self.logger.info("packet loss test [dpid 0x%x inport %d] rate %d/10000 test %d", dpid, in_port, loss, loss_test)
                    return 
            
            if pkt_icmp:
                ip_dst = pkt_ipv4.dst
                ip_ecn = (pkt_icmp.type-20)&0x3
                ips = ip_dst.split('.')
                pod = int(ips[1])
                lr  = int(ips[2])
                if_no = 0
                if dpid < 0x200 :
                    # core, ip
                    if_no = pod +1
                elif dpid < 0x300 :
                    # aggr
                    spod = (dpid&0xFF)/2
                    if pod == spod:
                        if_no = 1+lr
                    else :
                        if_no = 3+ ip_ecn%2
                else :
                    if in_port <3 :
                        if_no = 3+ ip_ecn/2
                    else :
                        if_no = 1
                actions = [parser.OFPActionOutput(if_no, 1000)]
                data = None
                if msg.buffer_id == ofproto.OFP_NO_BUFFER:
                    data = msg.data
                out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
                                  in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data)
                datapath.send_msg(out)

            return 

        pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
        pkt_icmp = pkt.get_protocol(icmp.icmp)
        if pkt_icmp:
            self._handle_icmp(datapath, in_port, pkt_ethernet, pkt_ipv4, pkt_icmp)
            return
Example #25
0
    def _arp_handler(self, pkt_arp, msg):
        # 解码数据包以获得 MAC 和 IP 地址
        # 源主机
        arp_src_ip = pkt_arp.src_ip
        arp_src_mac = pkt_arp.src_mac
        # 目的主机
        arp_dst_ip = pkt_arp.dst_ip
        arp_dst_mac = pkt_arp.dst_mac
        # 接入位置
        # 交换机 ID
        dpid = msg.datapath.id
        # 交换机的端口号
        port = msg.match['in_port']

        # 如果是 ARP 响应,并且,目的主机是自己
        if str(pkt_arp.opcode) == str(arp.ARP_REPLY):
            # 打印 ARP 包内容
            self.logger.info(
                "\033[1;34m" +
                "捕获到 ARP 响应数据包:\t 源 IP:%s\tMAC:%s\t目的 IP:%s\tMAC:%s\tSID:%s\tPORT:%s"
                + "\033[0m", arp_src_ip, arp_src_mac, arp_dst_ip, arp_dst_mac,
                dpid, port)
            if arp_src_mac in send_arp_table and arp_dst_mac == self.mac_addr and arp_dst_ip == self.ip_addr:
                # TODO
                pkt = packet.Packet(msg.data)
                data = pkt.data
                # self.logger.info("\033[1;31m" + "data:%s" + "\033[0m", data)
                try:
                    # 解密的验证数据
                    data = validation.aesdecrypt(data,
                                                 host_v[arp_src_mac]["seed"])
                    if data == validation.hash_key(host_v[arp_src_mac]["seed"],
                                                   host_v[arp_src_mac]["len"]):
                        # 解密完成后将哈希次数减 1
                        host_v[arp_src_mac][
                            "len"] = host_v[arp_src_mac]["len"] - 1
                        if host_c[str(arp_src_mac)][str("port")] == port:
                            # 攻击
                            self.handle_spoof(arp_src_mac,
                                              send_arp_table[arp_src_mac])
                        else:
                            # 更新主机物理信息表
                            host_c[arp_src_mac][str("sid")] = dpid
                            host_c[arp_src_mac][str("port")] = port
                    else:
                        # 攻击
                        self.handle_spoof(arp_src_mac, msg)
                        return
                except BaseException:
                    self.logger.info("\033[1;31m" + "验证失败" + "\033[0m")
                    # 攻击
                    self.handle_spoof(arp_src_mac, msg)
                send_arp_table.pop(arp_src_mac)
            return

        # 打印 ARP 包内容
        self.logger.info(
            "\033[1;34m" +
            "捕获到 ARP 请求数据包:\t 源 IP:%s\tMAC:%s\t目的 IP:%s\tMAC:%s\tSID:%s\tPORT:%s"
            + "\033[0m", arp_src_ip, arp_src_mac, arp_dst_ip, arp_dst_mac,
            dpid, port)

        if str(self.dhcp_ip) == str(arp_src_ip):
            self.dhcp_mac = arp_src_mac
            for key in host_c.keys():
                if str('ip') in host_c[key] and host_c[key][str('ip')] == str(
                        arp_dst_ip):
                    # 发送 ARP 回应数据包
                    self._send_arp_reply_handler(msg, arp_dst_ip, key,
                                                 self.dhcp_ip, self.dhcp_mac)
                    return

        if str(self.dhcp_ip) == str(arp_dst_ip):
            # 发送 ARP 回应数据包
            self._send_arp_reply_handler(msg, self.dhcp_ip, self.dhcp_mac,
                                         arp_src_ip, arp_src_mac)
            return

        # 已发送 ARP 请求,等待回应,对该主机的 ARP 请求数据包做丢弃处理
        if arp_src_mac in send_arp_table and host_c[str(arp_src_mac)][str(
                "port")] != port:
            self.logger.info("已为该主机发送验证信息,丢弃该 ARP 请求数据包!")
            return

        # 检查每个端口的 ARP 包的数量
        # if port not in PortCount:
        #     PortCount.update({port: 1})
        # else:
        #     if PortCount[port] > 40:
        #         self.logger.info("\033[1;31m" + "\n 检测到 ARP 洪泛攻击 !!!" + "\033[0m")
        #         # 在特定时间内阻塞攻击者
        #         self.handle_spoof(arp_src_mac, msg)
        #         return
        #     elif str(pkt_arp.opcode) == str(arp.ARP_REQUEST):
        #         PortCount[port] += 1

        # 源主机的 MAC-IP 映射是否真实, MAC 不在主机物理信息表中直接丢弃
        if arp_src_mac in host_c.keys():
            if str(host_c[arp_src_mac]['ip']) != str(
                    arp_src_ip):  # 源主机的 MAC-IP 映射是否和主机物理信息表中一样
                self.logger.info("\033[1;31m" +
                                 "\n****** ARP 欺骗检测: MAC 和 IP 映射不匹配 *****" +
                                 "\033[0m")
                self.handle_spoof(arp_src_mac, msg)
                # 盗用 IP 或者 MAC 的攻击方式
                return

        self.logger.info("\033[1;34m" + "源主机的 MAC-IP 映射真实" + "\033[0m")

        # MAC 地址是否真实
        if arp_src_mac in host_c.keys():  # 源主机 MAC 是否在配置验证信息表中
            if str(host_c[arp_src_mac]['sid']) != str(dpid) or str(
                    host_c[arp_src_mac]['port']) != str(port):
                # MAC 对应的接入位置和配置验证信息表中接入位置不一样,进一步验
                # 向主机发送待验证的 ICMP 请求包
                self.logger.info("源主机的 MAC 地址真实性待进步一验证,发送验证信息!")
                self._send_arp_handler(msg, self.ip_addr, self.mac_addr,
                                       arp_src_ip, arp_src_mac)
                send_arp_table.update({arp_src_mac: msg})
                return

        self.logger.info("\033[1;34m" + "源主机的 MAC 地址真实" + "\033[0m")

        for key in host_c.keys():
            if str('ip') in host_c[key] and host_c[key][str('ip')] == str(
                    arp_dst_ip):
                # 发送 ARP 回应数据包
                self._send_arp_reply_handler(msg, arp_dst_ip, key, arp_src_ip,
                                             arp_src_mac)
                return
        return
Example #26
0
    def packet_in_handler(self, ev):
        
        # Blehhhh
        self.logger.info("")
        self.logger.info("Begin the packet_in_handler")
        
        msg = ev.msg  # instance of OpenFlow messages
        # self.logger.info("Got message: " + str(msg))
        
        # represent a datapath(switch) which corresponding to OpenFlow that issued the message
        dp = msg.datapath
        # self.logger.info("Got datapath: " + str(dp))
        
        ofp = dp.ofproto  # the protocol that Openflow version in use
        ofp_parser = dp.ofproto_parser

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocol(ethernet.ethernet)
        # print(pkt)

        src_mac = eth.src
        dst_mac = eth.dst
        # self.logger.info("Packet is flowing from %s to %s", src, dst)
        
        in_port = msg.match['in_port']
        # self.logger.info("Packet is coming in on port: " + str(in_port))
        
        self.remember_mac(src_mac, in_port)
        
        # Try to figure out what port to send the packet out on
        if self.do_we_know_mac(dst_mac):
            # self.logger.info("We already knew this port")
            out_port = self.get_macs_port(dst_mac)
        else:
            self.logger.info("Didn't know where " + dst_mac + " is plugged in; Will flood")
            out_port = ofp.OFPP_FLOOD
        
        # construct packet_out message and send it.
        actions = [ofp_parser.OFPActionOutput(out_port)]
        
        # switch already knew this port, modify table flow to avoid packet_in next time
        if out_port != ofp.OFPP_FLOOD:
            
            self.logger.info("Didn't flood; Trying to modify the table flow to avoid packet_in next time")
            self.logger.info("Packet is flowing from %s to %s", src_mac, dst_mac)
            
            # match = ofp_parser.OFPMatch(in_port=in_port, eth_dst=dst_mac)
            # self.send_flow_mod(dp, match, actions, 1)

            # pkt = packet.Packet(array.array('B', ev.msg.data))
            # self.logger.info(pkt)
            # print(pkt.get_protocol(ipv6))
            # self.logger.info(pkt.get_protocol(ipv6))
            # ip6 = pkt.get_protocol(ipv6.ipv6)
            # self.logger.info('ipv6 %s', ip6)
            # self.logger.info(ip6.nxt)
            # eth = pkt.get_protocols(ethernet.ethernet)
            # self.logger.info('ethernet %s', eth)

            # ip4 = pkt.get_protocol(ipv4.ipv4)
            # self.logger.info('ipv4: %s', ip4)

            # tcp_pkt = tcp.tcp(bits=(tcp.TCP_SYN | tcp.TCP_ACK))
            # self.logger.info(tcp_pkt)
            # x = pkt.get_protocol(tcp.tcp)
            # self.logger.info(x)

            # eth = pkt.get_protocol(ethernet.ethernet)
            # self.logger.info(eth)
            # self.logger.info('Ethernet Type: %s', eth.ethertype)
            # self.logger.info('IP Type: %s', ether_types.ETH_TYPE_IP)

            # inspired from https://github.com/knetsolutions/learn-sdn-with-ryu/blob/master/ryu-exercises/ex3_L4Match_switch.py
            if eth.ethertype == ether_types.ETH_TYPE_IP:
    
                self.logger.info("Got an IP type of ether packet")
                
                ip4 = pkt.get_protocol(ipv4.ipv4)
                
                self.logger.info('ipv4: %s', ip4)
                
                ip4_scr = ip4.src
                ip4_dst = ip4.dst
                protocol = ip4.proto
                # self.logger.info(in_proto)
                t = u = None
                if protocol == in_proto.IPPROTO_TCP:
                    self.logger.info('This packet is using TCP!')
                    t = pkt.get_protocol(tcp.tcp)
                    match = ofp_parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=ip4.src, ipv4_dst=ip4.dst, ip_proto=protocol, tcp_src=t.src_port, tcp_dst=t.dst_port)
                elif protocol == in_proto.IPPROTO_ICMP:
                    match = ofp_parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=ip4.src, ipv4_dst=ip4.dst, ip_proto=protocol)
                elif protocol == in_proto.IPPROTO_UDP:
                    self.logger.info('This packet is using UDP!')
                    u = pkt.get_protocol(udp.udp)
                    match = ofp_parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=ip4.src, ipv4_dst=ip4.dst, ip_proto=protocol, udp_src=u.src_port, udp_dst=u.dst_port)
                else:
                    self.logger.info("Don't know how to handle protocol: " + str(protocol) + "; Won't add any rules")
                    match = None
                # self.logger.info(pkt.get_protocol(tcp.tcp))
                # if pkt.get_protocol(tcp.tcp):
                #     self.logger.info('TCP!')
                
                if msg.buffer_id == ofp.OFP_NO_BUFFER:
                    self.logger.info("This message doesn't reference a buffer")
                else:
                    self.logger.info('Buffer ID: %s', msg.buffer_id)
                
                if match is not None:
                    
                    self.logger.info("Match was not none; Proceeding to possibly add flow")

                    # set priority for tcp and udp
                    if t:
                        priority = 1
                    elif u:
                        priority = 2
                    else:
                        priority = 3
                    
                    # Debug
                    priority = 1

                    self.send_flow_mod(
                        dp, match, actions,
                        new_priority=priority
                    )
                    
                    """
                    if msg.buffer_id != ofp.OFP_NO_BUFFER:
                        
                        self.logger.info("Message buffer ID was not \"no buffer\"; Proceeding to add a flow")

                        self.send_flow_mod(
                            dp, match, actions,
                            new_priority=priority,
                            new_buffer_id=msg.buffer_id
                        )
                        
                    else:
                        self.logger.info(
                            "Message buffer ID was \"no buffer\"; Proceeding to add flow without specifying buffer"
                        )
                        self.send_flow_mod(
                            dp, match, actions,
                            new_priority=priority
                        )
                    """
            
            # for p in pkt:
            #     # print(p.protocol_name, p)
            #     self.logger.info(p)
        
        # Switch didn't already know this port
        else:
            pass
        
        # out = ofp_parser.OFPPacketOut(
        #     datapath=dp,
        #     buffer_id=ofp.OFP_NO_BUFFER,
        #     in_port=in_port, actions=actions,
        #     data=msg.data
        # )
        # dp.send_msg(out)

        data = None
        if msg.buffer_id == ofp.OFP_NO_BUFFER:
            data = msg.data

        out = ofp_parser.OFPPacketOut(
            datapath=dp, buffer_id=msg.buffer_id,
            in_port=in_port, actions=actions, data=data
        )
        dp.send_msg(out)
        
        self.logger.info("End packet_in_handler")
Example #27
0
 def _block_packet(self, data):
     data_packet = packet.Packet(data)
     for protocol in data_packet.protocols:
         if (protocol.protocol_name == 'ipv4' and ((ipv4_to_str(protocol.src) == SimpleSwitch.ipv4_host2 and ipv4_to_str(protocol.dst) == SimpleSwitch.ipv4_host3) or (ipv4_to_str(protocol.src) == SimpleSwitch.ipv4_host3 and ipv4_to_str(protocol.dst) == SimpleSwitch.ipv4_host2))):
             return True
     return False
Example #28
0
    def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        # print "_packet_in_handler"
        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return
        dst = eth.dst
        src = eth.src

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
            # verify if we have a valid buffer_id, if yes avoid to send both
            # flow_mod & packet_out
            if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                return
            else:
                self.add_flow(datapath, 1, match, actions)
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
        tmp = (int(time_linger.time()) % 3)
        if (tmp == 0):
            if (self.abc == 0):
                try:
                    ftmp = open('tree.csv', 'rb')
                    tree = ftmp.readline()
                    # print tree
                except Exception:
                    print 'tree.csv open failed'
                if tree != "":
                    self.abc = -1
                    print "------------------------------------------------------------------"
                    print tree
                    self.install_experimental_flow(tree, ev)
        else:
            self.abc = 0
Example #29
0
    def _packet_in_handler(self, ev):
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)

        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        etherFrame = pkt.get_protocol(ethernet.ethernet)

        eth = pkt.get_protocols(ethernet.ethernet)[0]
        pkt_arp = pkt.get_protocol(arp.arp)
        pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
        # pkt_tcp = pkt.get_protocol(tcp.tcp)

        if etherFrame.ethertype == ether_types.ETH_TYPE_LLDP:
            return

        dst = eth.dst
        src = eth.src
        dpid = datapath.id

        self.mac_to_port.setdefault(dpid, {})
        self.mac_to_port[dpid][src] = in_port

        # arp handle
        if pkt_arp and pkt_arp.opcode == arp.ARP_REQUEST:
            if pkt_arp.src_ip not in self.ip_to_mac:
                self.ip_to_mac[pkt_arp.src_ip] = src
                self.mac_to_dpid[src] = (dpid, in_port)
                self.ip_to_port[pkt_arp.src_ip] = (dpid, in_port)

            if pkt_arp.dst_ip in self.ip_to_mac:
                self.logger.info("[PACKET] ARP packet_in.")
                self.handle_arpre(datapath=datapath,
                                  port=in_port,
                                  src_mac=self.ip_to_mac[pkt_arp.dst_ip],
                                  dst_mac=src,
                                  src_ip=pkt_arp.dst_ip,
                                  dst_ip=pkt_arp.src_ip)
            else:
                # to avoid flood when the dst ip not in the network
                if datapath.id not in self.check_ip_dpid[pkt_arp.dst_ip]:
                    self.check_ip_dpid[pkt_arp.dst_ip].append(datapath.id)
                    out_port = ofproto.OFPP_FLOOD
                    actions = [parser.OFPActionOutput(out_port)]
                    data = None

                    if msg.buffer_id == ofproto.OFP_NO_BUFFER:
                        data = msg.data
                    out = parser.OFPPacketOut(datapath=datapath,
                                              buffer_id=msg.buffer_id,
                                              in_port=in_port,
                                              actions=actions,
                                              data=data)
                    datapath.send_msg(out)
            return

        elif pkt_arp and pkt_arp.opcode == arp.ARP_REPLY:
            if pkt_arp.src_ip not in self.ip_to_mac:
                self.ip_to_mac[pkt_arp.src_ip] = src
                self.mac_to_dpid[src] = (dpid, in_port)
                self.ip_to_port[pkt_arp.src_ip] = (dpid, in_port)
                dst_mac = self.ip_to_mac[pkt_arp.dst_ip]
                (dst_dpid, dst_port) = self.mac_to_dpid[dst_mac]
                self.logger.info("[PACKET] ARP packet_in.")
                self.handle_arpre(datapath=self.datapaths[dst_dpid],
                                  port=dst_port,
                                  src_mac=src,
                                  dst_mac=dst_mac,
                                  src_ip=pkt_arp.src_ip,
                                  dst_ip=pkt_arp.dst_ip)
            return

        if etherFrame.ethertype == ether.ETH_TYPE_IP:
            self.logger.info("[PACKET] IPv4 packet_in.")
            self.handle_ping_ipv4(datapath, pkt, etherFrame, in_port)
            return
Example #30
0
def get_vlan_from_pkt(data):
    pkt = packet.Packet(data)
    pkt_vlan = pkt.get_protocols(vlan.vlan)[0]
    return pkt_vlan.vid