Exemplo n.º 1
0
 def port_add_acl(self, port_num):
     ofmsgs = []
     forwarding_table = self.dp.eth_src_table
     if port_num in self.dp.acl_in:
         acl_num = self.dp.acl_in[port_num]
         forwarding_table = self.dp.acl_table
         acl_rule_priority = self.dp.highest_priority
         acl_allow_inst = self.goto_table(self.dp.eth_src_table)
         for rule_conf in self.dp.acls[acl_num]:
             # default drop
             acl_inst = []
             match_dict = {}
             for attrib, attrib_value in rule_conf.iteritems():
                 if attrib == 'allow':
                     if attrib_value == 1:
                         acl_inst.append(acl_allow_inst)
                     continue
                 if attrib == 'in_port':
                     continue
                 match_dict[attrib] = attrib_value
             # override in_port always
             match_dict['in_port'] = port_num
             # to_match() needs to access parser via dp
             # this uses the old API, which is oh so convenient
             # (transparently handling masks for example).
             null_dp = namedtuple('null_dp', 'ofproto_parser')
             null_dp.ofproto_parser = parser
             acl_match = ofctl.to_match(null_dp, match_dict)
             ofmsgs.append(self.valve_flowmod(
                 self.dp.acl_table,
                 acl_match,
                 priority=acl_rule_priority,
                 inst=acl_inst))
             acl_rule_priority -= 1
     return ofmsgs, forwarding_table
Exemplo n.º 2
0
    def handler_datapath(self, ev):
        dp = ev.dp
        ofproto = dp.ofproto
        parser = dp.ofproto_parser

        if ev.enter:
            self.logger.info("MARI => Switch connected:%s", dp.id)
        else:
            self.logger.info("MARI => Switch disconnected:%s", dp.id)
            return

        self.logger.info("Configuring datapath")

        # clear flow table on datapath
        self.clear_flows(dp, self.cookie)

        # add catchall drop rule to datapath
        drop_act = []

        aclmatch = {}
        aclmatch['eth_type'] = 0x0800
        match = ofctl_v1_3.to_match(dp, aclmatch)
        self.add_flow(dp, match, drop_act, 10000, self.cookie)
        self.logger.info("Configured match")

        self.logger.info("Datapath configured")
Exemplo n.º 3
0
 def port_add_acl(self, port_num):
     ofmsgs = []
     forwarding_table = self.dp.eth_src_table
     if port_num in self.dp.acl_in:
         acl_num = self.dp.acl_in[port_num]
         forwarding_table = self.dp.acl_table
         acl_rule_priority = self.dp.highest_priority
         acl_allow_inst = self.goto_table(self.dp.eth_src_table)
         for rule_conf in self.dp.acls[acl_num]:
             # default drop
             acl_inst = []
             match_dict = {}
             for attrib, attrib_value in rule_conf.iteritems():
                 if attrib == 'allow':
                     if attrib_value == 1:
                         acl_inst.append(acl_allow_inst)
                     continue
                 if attrib == 'in_port':
                     continue
                 match_dict[attrib] = attrib_value
             # override in_port always
             match_dict['in_port'] = port_num
             # to_match() needs to access parser via dp
             # this uses the old API, which is oh so convenient
             # (transparently handling masks for example).
             null_dp = namedtuple('null_dp', 'ofproto_parser')
             null_dp.ofproto_parser = parser
             acl_match = ofctl.to_match(null_dp, match_dict)
             ofmsgs.append(self.valve_flowmod(
                 self.dp.acl_table,
                 acl_match,
                 priority=acl_rule_priority,
                 inst=acl_inst))
             acl_rule_priority -= 1
     return ofmsgs, forwarding_table
Exemplo n.º 4
0
    def create_firewall(self, filter_data):
        LOG.debug("Creating tap with filter = %s", str(filter_data))

        dpid = filter_data['dpid']
        if 'priority' in filter_data:
            priority = filter_data['priority']
        else:
            priority = 32768

        datapath = self.dpset.get(int(dpid, 16))
        if datapath is None:
            LOG.debug("Unable to get datapath for id = %s",
                      str(source['dpid']))
            return False
        ofproto = datapath.ofproto
        ofproto_parser = datapath.ofproto_parser

        ######## Create match
        match = ofctl_v1_3.to_match(datapath, filter_data['fields'])

        ######## Cookie might come handy
        cookie = 0x2222222222222222

        ######## init inst
        actions = []
        inst = []

        if 'normal' in filter_data['actions']:
            actions.append(
                ofproto_parser.OFPActionOutput(ofproto.OFPP_NORMAL, 0))

        if 'drop' in filter_data['actions']:
            actions = []

        inst.append(
            ofproto_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                                 actions))

        mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                        match=match,
                                        priority=priority,
                                        command=ofproto.OFPFC_ADD,
                                        idle_timeout=0,
                                        hard_timeout=0,
                                        instructions=inst,
                                        cookie=cookie)

        datapath.send_msg(mod)
Exemplo n.º 5
0
    def delete_tap(self, filter_data):
        LOG.debug("Deleting tap with filter %s", str(filter_data))

        # If dl_host, nw_host or tp_port are used, the recursively call the individual filters.
        # This causes the match to expand and more rules to be programmed.
        filter_data.setdefault('fields', {})
        filter_fields = filter_data['fields']

        for key, val in self.broadened_field.iteritems():
            if key in filter_fields:

                for new_val in val:
                    filter_data['fields'] = self.change_field(filter_fields, key, new_val)
                    self.delete_tap(filter_data)

                return

        # If match fields are exact, then proceed programming switches
        for source in filter_data['sources']:
            in_port = source['port_no']
            filter_fields = filter_data['fields'].copy()
            if in_port != 'all':  # If not sniffing on all in_ports
                filter_fields['in_port'] = in_port

            datapath = self.dpset.get(source['dpid'])

            # If dpid is invalid, return
            if datapath is None:
                continue

            ofproto = datapath.ofproto
            ofproto_parser = datapath.ofproto_parser
                    
            match = ofctl_v1_3.to_match(datapath, filter_fields)

            mod = ofproto_parser.OFPFlowMod(datapath=datapath, command=ofproto.OFPFC_DELETE,
                          match = match, out_port=ofproto.OFPP_ANY,out_group=ofproto.OFPG_ANY)

            datapath.send_msg(mod)
Exemplo n.º 6
0
    def handler_datapath(self, ev):
        dp = ev.dp
        ofproto = dp.ofproto
        parser = dp.ofproto_parser

        # Configure logging to include datapath id
        self.set_dpid_log_formatter(dp.id)

        if not ev.enter:
            # Datapath down message
            self.logger.info("Datapath gone away")
            self.set_default_log_formatter()
            return

        if dp.id not in self.dps:
            self.logger.error("Unknown dpid:%s", dp.id)
            self.set_default_log_formatter()
            return
        else:
            datapath = self.dps[dp.id]

        for k, port in dp.ports.items():
            # These are special port numbers
            if k > 0xF0000000:
                continue
            elif k not in datapath.ports:
                # Autoconfigure port
                self.logger.info(
                    "Autoconfiguring port:%s based on default config", k)
                datapath.add_port(k)

        self.logger.info("Configuring datapath")

        # clear flow table on datapath
        self.clear_flows(dp, datapath.config_default['cookie'])

        # add catchall drop rule to datapath
        drop_act = []
        if datapath.config_default['table_miss']:
            match_all = parser.OFPMatch()
            priority = datapath.config_default['lowest_priority']
            cookie = datapath.config_default['cookie']
            self.add_flow(dp, match_all, drop_act, priority, cookie)

        for vid, v in datapath.vlans.items():
            self.logger.info("Configuring %s", v)

            controller_act = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER)]

            # generate the output actions for each port
            tagged_act = self.tagged_output_action(parser, v.tagged)
            untagged_act = self.untagged_output_action(parser, v.untagged)

            # send rule for matching packets arriving on tagged ports
            strip_act = [parser.OFPActionPopVlan()]
            action = copy.copy(controller_act)
            if tagged_act:
                action += tagged_act
            if untagged_act:
                action += strip_act + untagged_act
            match = parser.OFPMatch(vlan_vid=v.vid
                                    | ofproto_v1_3.OFPVID_PRESENT)
            priority = datapath.config_default['low_priority']
            cookie = datapath.config_default['cookie']
            self.add_flow(dp, match, action, priority, cookie)

            # send rule for each untagged port
            push_act = [
                parser.OFPActionPushVlan(ether.ETH_TYPE_8021Q),
                parser.OFPActionSetField(vlan_vid=v.vid
                                         | ofproto_v1_3.OFPVID_PRESENT)
            ]

            for port in v.untagged:
                match = parser.OFPMatch(in_port=port.number)
                action = copy.copy(controller_act)
                if untagged_act:
                    action += untagged_act
                if tagged_act:
                    action += push_act + tagged_act
                priority = datapath.config_default['low_priority']
                cookie = datapath.config_default['cookie']
                self.add_flow(dp, match, action, priority, cookie)

        for nw_address, acls in datapath.acls.items():
            for acl in acls:
                if acl.action.lower() == "drop":
                    self.logger.info("Adding ACL:{%s} for nw_address:%s", acl,
                                     nw_address)

                    # Hacky method of detecting IPv4/IPv6
                    try:
                        socket.inet_aton(nw_address.split('/')[0])
                        acl.match['nw_dst'] = nw_address
                    except socket.error:
                        acl.match['ipv6_dst'] = nw_address

                    match = ofctl_v1_3.to_match(dp, acl.match)
                    priority = datapath.config_default['highest_priority']
                    cookie = datapath.config_default['cookie']
                    self.add_flow(dp, match, drop_act, priority, cookie)

        for k, port in datapath.ports.items():
            for acl in port.acls:
                if acl.action.lower() == "drop":
                    self.logger.info("Adding ACL:{%s} to port:%s", acl, port)
                    acl.match['in_port'] = port.number
                    match = ofctl_v1_3.to_match(dp, acl.match)
                    priority = datapath.config_default['highest_priority']
                    cookie = datapath.config_default['cookie']
                    self.add_flow(dp, match, drop_act, priority, cookie)

        # Mark datapath as fully configured
        datapath.running = True

        self.logger.info("Datapath configured")

        self.set_default_log_formatter()
Exemplo n.º 7
0
def match_from_dict(match_dict):
    null_dp = namedtuple('null_dp', 'ofproto_parser')
    null_dp.ofproto_parser = parser
    acl_match = ofctl.to_match(null_dp, match_dict)
    return acl_match
Exemplo n.º 8
0
    def handler_datapath(self, ev):
        dp = ev.dp
        ofproto = dp.ofproto
        parser = dp.ofproto_parser

        # Configure logging to include datapath id
        self.set_dpid_log_formatter(dp.id)

        if not ev.enter:
            # Datapath down message
            self.logger.info("Datapath gone away")
            self.set_default_log_formatter()
            return

        if dp.id not in self.dps:
            self.logger.error("Unknown dpid:%s", dp.id)
            self.set_default_log_formatter()
            return
        else:
            datapath = self.dps[dp.id]

        for k, port in dp.ports.items():
            # These are special port numbers
            if k > 0xF0000000:
                continue
            elif k not in datapath.ports:
                # Autoconfigure port
                self.logger.info("Autoconfiguring port:%s based on default config",
                        k)
                datapath.add_port(k)

        self.logger.info("Configuring datapath")

        # clear flow table on datapath
        self.clear_flows(dp, datapath.config_default['cookie'])

        # add catchall drop rule to datapath
        drop_act = []
        if datapath.config_default['table_miss']:
            match_all = parser.OFPMatch()
            priority = datapath.config_default['lowest_priority']
            cookie = datapath.config_default['cookie']
            self.add_flow(dp, match_all, drop_act, priority, cookie)

        for vid, v in datapath.vlans.items():
            self.logger.info("Configuring %s", v)

            controller_act = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER)]

            # generate the output actions for each port
            tagged_act = self.tagged_output_action(parser, v.tagged)
            untagged_act = self.untagged_output_action(parser, v.untagged)

            # send rule for matching packets arriving on tagged ports
            strip_act = [parser.OFPActionPopVlan()]
            action = copy.copy(controller_act)
            if tagged_act:
                action += tagged_act
            if untagged_act:
                action += strip_act + untagged_act
            match = parser.OFPMatch(vlan_vid=v.vid|ofproto_v1_3.OFPVID_PRESENT)
            priority = datapath.config_default['low_priority']
            cookie = datapath.config_default['cookie']
            self.add_flow(dp, match, action, priority, cookie)

            # send rule for each untagged port
            push_act = [
              parser.OFPActionPushVlan(ether.ETH_TYPE_8021Q),
              parser.OFPActionSetField(vlan_vid=v.vid|ofproto_v1_3.OFPVID_PRESENT)
              ]

            for port in v.untagged:
                match = parser.OFPMatch(in_port=port.number)
                action = copy.copy(controller_act)
                if untagged_act:
                    action += untagged_act
                if tagged_act:
                    action += push_act + tagged_act
                priority = datapath.config_default['low_priority']
                cookie = datapath.config_default['cookie']
                self.add_flow(dp, match, action, priority, cookie)

        for nw_address, acls in datapath.acls.items():
            for acl in acls:
                if acl.action.lower() == "drop":
                    self.logger.info("Adding ACL:{%s} for nw_address:%s",
                            acl, nw_address)

                    # Hacky method of detecting IPv4/IPv6
                    try:
                        socket.inet_aton(nw_address.split('/')[0])
                        acl.match['nw_dst'] = nw_address
                    except socket.error:
                        acl.match['ipv6_dst'] = nw_address

                    match = ofctl_v1_3.to_match(dp, acl.match)
                    priority = datapath.config_default['highest_priority']
                    cookie = datapath.config_default['cookie']
                    self.add_flow(dp, match, drop_act, priority, cookie)

        for k, port in datapath.ports.items():
            for acl in port.acls:
                if acl.action.lower() == "drop":
                    self.logger.info("Adding ACL:{%s} to port:%s", acl, port)
                    acl.match['in_port'] = port.number
                    match = ofctl_v1_3.to_match(dp, acl.match)
                    priority = datapath.config_default['highest_priority']
                    cookie = datapath.config_default['cookie']
                    self.add_flow(dp, match, drop_act, priority, cookie)

        # Mark datapath as fully configured
        datapath.running = True

        self.logger.info("Datapath configured")

        self.set_default_log_formatter()
Exemplo n.º 9
0
def match_from_dict(match_dict):
    null_dp = namedtuple('null_dp', 'ofproto_parser')
    null_dp.ofproto_parser = parser
    acl_match = ofctl.to_match(null_dp, match_dict)
    return acl_match
Exemplo n.º 10
0
    def start_security(self, dpid):
        datapath = self.dpset.get(int(dpid, 16))

        if datapath is None:
            LOG.debug("Unable to get datapath for id = %s",
                      str(source['dpid']))
            return False

        ofproto = datapath.ofproto
        ofproto_parser = datapath.ofproto_parser

        ######## Cookie might come handy
        cookie = 0x333333333333333
        ######## init inst
        actions = [ofproto_parser.OFPActionOutput(ofproto.OFPP_NORMAL, 0)]
        inst = [
            ofproto_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                                 actions)
        ]
        ######## Create tcp syc udf match & send flow
        tcp_match = {}
        tcp_match['udf0'] = '0x60000/0xff0000'
        tcp_match['udf2'] = '0x20000/0xfff0000'

        match = ofctl_v1_3.to_match(datapath, tcp_match)

        mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                        match=match,
                                        table_id=250,
                                        command=ofproto.OFPFC_ADD,
                                        idle_timeout=0,
                                        hard_timeout=0,
                                        instructions=inst,
                                        cookie=cookie)

        datapath.send_msg(mod)
        ######## Create dns query udf match & send flow
        dns_match = {}
        dns_match['udf0'] = '0x110000/0xff0000'
        dns_match['udf1'] = '0x00000035/0x0000ffff'

        match = ofctl_v1_3.to_match(datapath, dns_match)
        mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                        match=match,
                                        table_id=250,
                                        command=ofproto.OFPFC_ADD,
                                        idle_timeout=0,
                                        hard_timeout=0,
                                        instructions=inst,
                                        cookie=cookie)
        datapath.send_msg(mod)

        ######## Create http udf match & send flow
        http_match = {}
        http_match['udf0'] = '0x60000/0xff0000'
        http_match['udf1'] = '0x00000050/0x0000ffff'
        http_match['udf3'] = '0x47455400/0xffffff00'

        match = ofctl_v1_3.to_match(datapath, http_match)
        mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                        match=match,
                                        table_id=250,
                                        command=ofproto.OFPFC_ADD,
                                        idle_timeout=0,
                                        hard_timeout=0,
                                        instructions=inst,
                                        cookie=cookie)
        datapath.send_msg(mod)

        ######## Create icmp udf match & send flow
        icmp_match = {}
        icmp_match['udf0'] = '0x10000/0xff0000'
        match = ofctl_v1_3.to_match(datapath, icmp_match)
        mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                        match=match,
                                        table_id=250,
                                        command=ofproto.OFPFC_ADD,
                                        idle_timeout=0,
                                        hard_timeout=0,
                                        instructions=inst,
                                        cookie=cookie)
        datapath.send_msg(mod)

        ######## Create ntp attack udf match & send flow
        ntp_match = {}
        ntp_match['udf0'] = '0x110000/0xff0000'
        ntp_match['udf1'] = '0x0000607B/0x0000ffff'
        match = ofctl_v1_3.to_match(datapath, ntp_match)
        mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                        match=match,
                                        table_id=250,
                                        command=ofproto.OFPFC_ADD,
                                        idle_timeout=0,
                                        hard_timeout=0,
                                        instructions=inst,
                                        cookie=cookie)
        datapath.send_msg(mod)

        ######## Create udp/tcp udf match & send flow (2 flows)
        udp_tcp_match = {}
        udp_tcp_match['udf0'] = '0x110000/0xff0000'
        match = ofctl_v1_3.to_match(datapath, udp_tcp_match)
        mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                        match=match,
                                        table_id=250,
                                        priority=1000,
                                        command=ofproto.OFPFC_ADD,
                                        idle_timeout=0,
                                        hard_timeout=0,
                                        instructions=inst,
                                        cookie=cookie)
        datapath.send_msg(mod)

        udp_tcp_match = {}
        udp_tcp_match['udf0'] = '0x60000/0xff0000'
        match = ofctl_v1_3.to_match(datapath, udp_tcp_match)
        mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                        match=match,
                                        table_id=250,
                                        priority=1000,
                                        command=ofproto.OFPFC_ADD,
                                        idle_timeout=0,
                                        hard_timeout=0,
                                        instructions=inst,
                                        cookie=cookie)
        datapath.send_msg(mod)
Exemplo n.º 11
0
    def create_tap(self, filter_data):
        LOG.debug("Creating tap with filter = %s", str(filter_data))

        # If dl_host, nw_host or tp_port are used, the recursively call the individual filters.
        # This causes the match to expand and more rules to be programmed.
        result = True
        filter_data.setdefault('fields', {})
        filter_fields = filter_data['fields']

        for key, val in self.broadened_field.iteritems():
            if key in filter_fields:
                for new_val in val:
                    filter_data['fields'] = self.change_field(
                        filter_fields, key, new_val)
                    result = result and self.create_tap(filter_data)

                return result

        # If match fields are exact, then proceed programming switches

        # Iterate over all the sources and sinks, and collect the individual
        # hop information. It is possible that a switch is both a source,
        # a sink and an intermediate hop.
        for source in filter_data['sources']:
            for sink in filter_data['sinks']:

                # Handle error case
                if source == sink:
                    continue

                # In basic version, source and sink are same switch
                if source['dpid'] != sink['dpid']:
                    LOG.debug("Mismatching source and sink switch")
                    return False
                # ychen modify
                datapath = self.dpset.get(int(source['dpid'], 16))

                # If dpid is invalid, return
                if datapath is None:
                    LOG.debug("Unable to get datapath for id = %s",
                              str(source['dpid']))
                    return False

                ofproto = datapath.ofproto
                ofproto_parser = datapath.ofproto_parser

                in_port = source['port_no']
                out_port = sink['port_no']
                filter_fields = filter_data['fields'].copy()

                ######## Create action list
                if out_port == 'Normal':
                    actions = [
                        ofproto_parser.OFPActionOutput(ofproto.OFPP_NORMAL, 0)
                    ]
                else:
                    actions = [ofproto_parser.OFPActionOutput(out_port)]

                ######## Create match
                if in_port != 'all':  # If not sniffing on all in_ports
                    filter_fields['in_port'] = in_port

                match = ofctl_v1_3.to_match(datapath, filter_fields)

                ######## Cookie might come handy
                #cookie = random.randint(0, 0xffffffffffffffff)
                cookie = 0x1111111111111111

                ######## init inst
                inst = []
                ######## meter add
                if filter_data['qos']:

                    meter_id = int(filter_data['qos']['meter_id'])
                    meter_rate = int(filter_data['qos']['meter_rate'])

                    mod = ofproto_parser.OFPMeterMod(
                        datapath=datapath,
                        command=ofproto.OFPMC_DELETE,
                        flags=10,
                        meter_id=meter_id)

                    datapath.send_msg(mod)

                    band = ofproto_parser.OFPMeterBandDrop(rate=meter_rate,
                                                           burst_size=1000,
                                                           type_=1,
                                                           len_=16)

                    bands = [band]

                    mod = ofproto_parser.OFPMeterMod(datapath=datapath,
                                                     command=ofproto.OFPMC_ADD,
                                                     flags=5,
                                                     meter_id=meter_id,
                                                     bands=bands)

                    datapath.send_msg(mod)

                    inst.append(
                        ofproto_parser.OFPInstructionMeter(meter_id=meter_id))

                inst.append(
                    ofproto_parser.OFPInstructionActions(
                        ofproto.OFPIT_APPLY_ACTIONS, actions))

                # install the flow in the switch
                if 'udf0' in filter_data['fields']:
                    mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                                    match=match,
                                                    table_id=250,
                                                    command=ofproto.OFPFC_ADD,
                                                    idle_timeout=0,
                                                    hard_timeout=0,
                                                    instructions=inst,
                                                    cookie=cookie)
                else:
                    mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                                    match=match,
                                                    command=ofproto.OFPFC_ADD,
                                                    idle_timeout=0,
                                                    hard_timeout=0,
                                                    instructions=inst,
                                                    cookie=cookie)
                LOG.info("the content of filter is %s ", mod)

                datapath.send_msg(mod)

                LOG.debug(
                    "Flow inserted to switch %x: cookie=%s, out_port=%d, match=%s",
                    datapath.id, str(cookie), out_port, str(filter_fields))

        LOG.info("Created tap with filter = %s", str(filter_data))
        return True
Exemplo n.º 12
0
    def handle_security(self, dpid, mode, operation):
        datapath = self.dpset.get(int(dpid, 16))

        if datapath is None:
            LOG.debug("Unable to get datapath for id = %s",
                      str(source['dpid']))
            return False

        ofproto = datapath.ofproto
        ofproto_parser = datapath.ofproto_parser

        ##### create meter
        mode_id = {
            'tcp': 250,
            'http': 251,
            'icmp': 252,
            'dns': 253,
            'ntp': 254,
            'udp_tcp': 255
        }

        meter_id = mode_id[mode]
        LOG.error(meter_id)
        meter_rate = 1000

        mod = ofproto_parser.OFPMeterMod(datapath=datapath,
                                         command=ofproto.OFPMC_DELETE,
                                         flags=10,
                                         meter_id=meter_id)

        datapath.send_msg(mod)

        band = ofproto_parser.OFPMeterBandDrop(rate=meter_rate,
                                               burst_size=1000,
                                               type_=1,
                                               len_=16)

        bands = [band]

        mod = ofproto_parser.OFPMeterMod(datapath=datapath,
                                         command=ofproto.OFPMC_ADD,
                                         flags=5,
                                         meter_id=meter_id,
                                         bands=bands)
        datapath.send_msg(mod)

        #### send flow
        ######## Cookie might come handy
        cookie = 0x333333333333333
        ######## init inst
        if operation == 'protect':
            actions = [ofproto_parser.OFPActionOutput(ofproto.OFPP_NORMAL, 0)]
            inst = [
                ofproto_parser.OFPInstructionMeter(meter_id=meter_id),
                ofproto_parser.OFPInstructionActions(
                    ofproto.OFPIT_APPLY_ACTIONS, actions)
            ]
        if operation == 'clear':
            actions = [ofproto_parser.OFPActionOutput(ofproto.OFPP_NORMAL, 0)]
            inst = [
                ofproto_parser.OFPInstructionActions(
                    ofproto.OFPIT_APPLY_ACTIONS, actions)
            ]
        ######## Create tcp syc udf match & send flow
        if mode == 'tcp':
            tcp_match = {}
            tcp_match['udf0'] = '0x60000/0xff0000'
            tcp_match['udf2'] = '0x20000/0xfff0000'

            match = ofctl_v1_3.to_match(datapath, tcp_match)
            mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                            match=match,
                                            table_id=250,
                                            command=ofproto.OFPFC_ADD,
                                            idle_timeout=0,
                                            hard_timeout=0,
                                            instructions=inst,
                                            cookie=cookie)

            datapath.send_msg(mod)
        ######## Create dns query udf match & send flow
        if mode == 'dns':
            dns_match = {}
            dns_match['udf0'] = '0x110000/0xff0000'
            dns_match['udf1'] = '0x00000035/0x0000ffff'

            match = ofctl_v1_3.to_match(datapath, dns_match)
            mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                            match=match,
                                            table_id=250,
                                            command=ofproto.OFPFC_ADD,
                                            idle_timeout=0,
                                            hard_timeout=0,
                                            instructions=inst,
                                            cookie=cookie)
            datapath.send_msg(mod)

        ######## Create http udf match & send flow
        if mode == 'http':
            http_match = {}
            http_match['udf0'] = '0x60000/0xff0000'
            http_match['udf1'] = '0x00000050/0x0000ffff'
            http_match['udf3'] = '0x47455400/0xffffff00'

            match = ofctl_v1_3.to_match(datapath, http_match)
            mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                            match=match,
                                            table_id=250,
                                            command=ofproto.OFPFC_ADD,
                                            idle_timeout=0,
                                            hard_timeout=0,
                                            instructions=inst,
                                            cookie=cookie)
            datapath.send_msg(mod)

        ######## Create icmp udf match & send flow
        if mode == 'icmp':
            icmp_match = {}
            icmp_match['udf0'] = '0x10000/0xff0000'
            match = ofctl_v1_3.to_match(datapath, icmp_match)
            mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                            match=match,
                                            table_id=250,
                                            command=ofproto.OFPFC_ADD,
                                            idle_timeout=0,
                                            hard_timeout=0,
                                            instructions=inst,
                                            cookie=cookie)
            datapath.send_msg(mod)

        ######## Create ntp attack udf match & send flow
        if mode == 'ntp':
            ntp_match = {}
            ntp_match['udf0'] = '0x110000/0xff0000'
            ntp_match['udf1'] = '0x0000607B/0x0000ffff'
            match = ofctl_v1_3.to_match(datapath, ntp_match)
            mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                            match=match,
                                            table_id=250,
                                            command=ofproto.OFPFC_ADD,
                                            idle_timeout=0,
                                            hard_timeout=0,
                                            instructions=inst,
                                            cookie=cookie)
            datapath.send_msg(mod)

        ######## Create udp/tcp udf match & send flow (2 flows)
        if mode == 'udp/tcp':
            udp_tcp_match = {}
            udp_tcp_match['udf0'] = '0x110000/0xff0000'
            match = ofctl_v1_3.to_match(datapath, udp_tcp_match)
            mod = ofproto_parser.OFPFlowMod(datapath=datapath,
                                            match=match,
                                            table_id=250,
                                            priority=1000,
                                            command=ofproto.OFPFC_ADD,
                                            idle_timeout=0,
                                            hard_timeout=0,
                                            instructions=inst,
                                            cookie=cookie)
            datapath.send_msg(mod)
Exemplo n.º 13
0
    def create_tap(self, filter_data):
        LOG.debug("Creating tap with filter = %s", str(filter_data))

        # If dl_host, nw_host or tp_port are used, the recursively call the individual filters.
        # This causes the match to expand and more rules to be programmed.
        result = True
        filter_data.setdefault('fields', {})
        filter_fields = filter_data['fields']

        for key, val in self.broadened_field.iteritems():
            if key in filter_fields:
                for new_val in val:
                    filter_data['fields'] = self.change_field(filter_fields, key, new_val)
                    result = result and self.create_tap(filter_data)

                return result

        # If match fields are exact, then proceed programming switches

        # Iterate over all the sources and sinks, and collect the individual
        # hop information. It is possible that a switch is both a source,
        # a sink and an intermediate hop.
        for source in filter_data['sources']:
            for sink in filter_data['sinks']:

                # Handle error case
                if source == sink:
                    continue

                # In basic version, source and sink are same switch
                if source['dpid'] != sink['dpid']:
                    LOG.debug("Mismatching source and sink switch")
                    return False

                datapath = self.dpset.get(source['dpid'])

                # If dpid is invalid, return
                if datapath is None:
                    LOG.debug("Unable to get datapath for id = %s", str(source['dpid']))
                    return False

                ofproto = datapath.ofproto
                ofproto_parser = datapath.ofproto_parser

                in_port = source['port_no']
                out_port = sink['port_no']
                filter_fields = filter_data['fields'].copy()

                ######## Create action list
                actions = [ofproto_parser.OFPActionOutput(out_port)]

                ######## Create match
                if in_port != 'all':  # If not sniffing on all in_ports
                    filter_fields['in_port'] = in_port
                match = ofctl_v1_3.to_match(datapath, filter_fields)

                ######## Cookie might come handy
                cookie = random.randint(0, 0xffffffffffffffff)

                inst = [ofproto_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]

                # install the flow in the switch
                mod = ofproto_parser.OFPFlowMod(
                            datapath=datapath, match=match, 
                            command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0,
                            instructions=inst, cookie=cookie)

                datapath.send_msg(mod)

                LOG.debug("Flow inserted to switch %x: cookie=%s, out_port=%d, match=%s",
                                  datapath.id, str(cookie), out_port, str(filter_fields))

        LOG.info("Created tap with filter = %s", str(filter_data))
        return True
Exemplo n.º 14
0
    def handler_datapath(self, ev):
        dp = ev.dp
        ofproto = dp.ofproto
        parser = dp.ofproto_parser

        if ev.enter:
            self.logger.info("Fireswitch: Switch connected:%s", dp.id)
        else:
            self.logger.info("Fireswitch: Switch disconnected:%s", dp.id)
            return

        self.logger.info("Configuring datapath")

        # Make all packet to flow normallyW
        aclmatch = {}
        match = ofctl_v1_3.to_match(dp, aclmatch)
        act_normal = [parser.OFPActionOutput(ofproto.OFPP_NORMAL)]
        self.add_flow(dp, 0, match, act_normal)

        # add catchall drop rule to datapath
        drop_act = []

        # Drop ICMP packets
        aclmatch = {}
        aclmatch['eth_type'] = ether_types.ETH_TYPE_IP
        aclmatch['ip_proto'] = 0x1
        match = ofctl_v1_3.to_match(dp, aclmatch)
        self.add_flow(dp, 10000, match, drop_act)

        act_redirect = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER)]

        # Redirect UDP and TCP packets
        aclmatch = {}
        aclmatch['eth_type'] = ether_types.ETH_TYPE_IP
        aclmatch['ip_proto'] = in_proto.IPPROTO_UDP
        match = ofctl_v1_3.to_match(dp, aclmatch)
        self.add_flow(dp, 1000, match, act_redirect)

        aclmatch = {}
        aclmatch['eth_type'] = ether_types.ETH_TYPE_IP
        aclmatch['ip_proto'] = in_proto.IPPROTO_TCP
        match = ofctl_v1_3.to_match(dp, aclmatch)
        self.add_flow(dp, 1000, match, act_redirect)

        # Redirect DNS packets
        aclmatch = {}
        aclmatch['eth_type'] = ether_types.ETH_TYPE_IP
        aclmatch['ip_proto'] = in_proto.IPPROTO_UDP
        aclmatch['udp_src'] = 53
        match = ofctl_v1_3.to_match(dp, aclmatch)
        self.add_flow(dp, 1000, match, act_redirect)

        aclmatch = {}
        aclmatch['eth_type'] = ether_types.ETH_TYPE_IP
        aclmatch['ip_proto'] = in_proto.IPPROTO_UDP
        aclmatch['udp_dst'] = 53
        match = ofctl_v1_3.to_match(dp, aclmatch)
        self.add_flow(dp, 1000, match, act_redirect)

        # Redirect SNMP packets
        aclmatch = {}
        aclmatch['eth_type'] = ether_types.ETH_TYPE_IP
        aclmatch['ip_proto'] = in_proto.IPPROTO_UDP
        aclmatch['udp_src'] = 161
        match = ofctl_v1_3.to_match(dp, aclmatch)
        self.add_flow(dp, 1000, match, act_redirect)

        aclmatch = {}
        aclmatch['eth_type'] = ether_types.ETH_TYPE_IP
        aclmatch['ip_proto'] = in_proto.IPPROTO_UDP
        aclmatch['udp_dst'] = 161
        match = ofctl_v1_3.to_match(dp, aclmatch)
        self.add_flow(dp, 1000, match, act_redirect)

        aclmatch = {}
        aclmatch['eth_type'] = ether_types.ETH_TYPE_IP
        aclmatch['ip_proto'] = in_proto.IPPROTO_TCP
        aclmatch['tcp_src'] = 161
        match = ofctl_v1_3.to_match(dp, aclmatch)
        self.add_flow(dp, 1000, match, act_redirect)

        aclmatch = {}
        aclmatch['eth_type'] = ether_types.ETH_TYPE_IP
        aclmatch['ip_proto'] = in_proto.IPPROTO_TCP
        aclmatch['tcp_dst'] = 161
        match = ofctl_v1_3.to_match(dp, aclmatch)
        self.add_flow(dp, 1000, match, act_redirect)

        self.logger.info("Datapath configured")
Exemplo n.º 15
0
Arquivo: exam.py Projeto: KitL/ofexam
 def create_match(self, dp, match):
     return ofctl_v1_3.to_match(dp, match)