Exemplo n.º 1
0
Arquivo: nat.py Projeto: yapkke/yapc
    def _process_outbound(self, pktin, intfs, iport, lointf):
        """Event handler for outbound ARP packets

        @param pktin packet in event to handle
        @param intfs dictionary of interfaces (with ip range)
        @param iport port no of local interface
        @param lointf local interface address (ip, mac)
        @return false
        """
        for portno, ipr in intfs.items():
            if (ipr[0] & ipr[1]) == (pktin.match.nw_dst & ipr[1]):
                flow = flows.exact_entry(pktin.match)
                if flow.buffer_id != pktin.pktin.buffer_id:
                    output.warn("Buffered outbound ARP packet (cannot be rewritten properly)!", self.__class__.__name__)
                else:
                    flow.add_output(portno)
                    ofpkt.dl_rewrite(pktin.dpkt, True, ipr[2])
                    ofpkt.nw_rewrite(pktin.dpkt, True, ipr[0])
                    self.get_conn().send(flow.get_packet_out().pack() + pktin.dpkt.pack())
                    output.vdbg(
                        "ARP to " + pu.ip_val2string(pktin.match.nw_dst) + " sent to port " + str(portno),
                        self.__class__.__name__,
                    )
                return False
        output.warn("ARP for " + pu.ip_val2string(pktin.match.nw_dst) + " unknown subnet", self.__class__.__name__)
        return False
Exemplo n.º 2
0
    def processevent(self, event):
        """Process event
        """
        if (isinstance(event, ofevents.pktin)):
            ##Allow flow to authenticate even when yet authenticated
            if ((event.match.nw_dst == AUTH_DST_IP and
                 (event.match.tp_dst == AUTH_DST_PORT1 or event.match.tp_dst == AUTH_DST_PORT2)) or
                (event.match.nw_src == AUTH_DST_IP and
                 (event.match.tp_src == AUTH_DST_PORT1 or event.match.tp_src == AUTH_DST_PORT2))):
                if (event.match.nw_dst == AUTH_DST_IP and event.match.tp_dst == 8080):
                    owglobal.last_host_redirect = (self.conn.db[event.sock].dpid,
                                                   event.match.dl_src)
                output.dbg("Approving "+\
                               pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\
                               "=>"+\
                               pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst),
                           self.__class__.__name__)
                return True

            #Authenticated host
            if (host_authenticated(event.match.dl_src) or 
                host_authenticated(event.match.dl_dst)):
                output.vdbg("Authenticated host flow "+\
                                pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\
                                "=>"+\
                                pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst),
                            self.__class__.__name__)
                return True

            ##Allow special website access without authentication
            if (event.match.nw_dst in BYPASS_IP or
                event.match.nw_src in BYPASS_IP):
                output.dbg("Allow bypass for special server",
                           self.__class__.__name__)
                return True

            ##Allow 
            # (1) ARP
            # (2) ICMP
            # (3) DHCP
            # (4) DNS
            if ((event.match.dl_type == dpkt.ethernet.ETH_TYPE_ARP) or 
                (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and
                 event.match.nw_proto == dpkt.ip.IP_PROTO_ICMP) or 
                (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and 
                 event.match.nw_proto == dpkt.ip.IP_PROTO_UDP and
                 (event.match.tp_dst == 67 or 
                  event.match.tp_dst == 68)) or
                (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and 
                 event.match.nw_proto == dpkt.ip.IP_PROTO_UDP and
                 (event.match.tp_dst == 53 or event.match.tp_src == 53))):
                return True

            ##Allow route to OpenID provider (should be in HTTPS)
            if (event.match.tp_dst == HTTPS_PORT or 
                event.match.tp_dst == 8080 or 
                event.match.tp_dst == 80 or
                event.match.tp_src == HTTPS_PORT or 
                event.match.tp_src == 8080 or 
                event.match.tp_src == 80):
                auth_s = None
                if (event.match.tp_dst == HTTPS_PORT or 
                    event.match.tp_dst == 8080 or 
                    event.match.tp_dst == 80):
                    auth_s = mcutil.get(host_auth.get_auth_key(event.match.dl_src))
                else:
                    auth_s = mcutil.get(host_auth.get_auth_key(event.match.dl_dst))

                if (auth_s != None):
                    output.dbg(pu.ip_val2string(event.match.nw_dst)+" associated with "+\
                                   " auth server "+str(auth_s)+" "+str(event.match.dl_src),
                               self.__class__.__name__)
                    return True
                
            ##Redirect unauthenticated host if HTTP
            if (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and 
                event.match.nw_proto == dpkt.ip.IP_PROTO_TCP and
                (event.match.tp_dst == 80 or event.match.tp_dst == 8080)):
                output.dbg("Redirecting %x to authenticate" % pu.array2val(event.match.dl_src),
                           self.__class__.__name__)

                #Forward flow
                flow = flows.exact_entry(event.match)
                key = swhost.mac2sw_binding.get_key(event.sock,
                                                    event.match.dl_dst)
                port = mcutil.get(key)
                if (port != None):
                    flow.set_buffer(event.pktin.buffer_id)
                    flow.add_nw_rewrite(False, AUTH_DST_IP)
                    flow.add_output(port)
                    self.conn.send(event.sock,flow.get_flow_mod(pyof.OFPFC_MODIFY).pack())
                    
                    #Reverse flow
                    rflow = flow.reverse(port)
                    rflow.match.nw_src = AUTH_DST_IP
                    rflow.add_nw_rewrite(True, event.match.nw_dst)
                    rflow.add_output(event.pktin.in_port)
                    self.conn.send(event.sock,rflow.get_flow_mod(pyof.OFPFC_MODIFY).pack())
                
                return False
           
            #Drop remaining flows
            flow = flows.exact_entry(event.match)
            flow.set_buffer(event.pktin.buffer_id)
            self.conn.send(event.sock,flow.get_flow_mod(pyof.OFPFC_ADD).pack())
            output.dbg("Dropping "+\
                           pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\
                           "=>"+pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst),
                       self.__class__.__name__)
            return False

        return True
Exemplo n.º 3
0
    def processevent(self, event):
        """Process event
        """
        if (isinstance(event, ofevents.pktin)):
            ##Allow flow to authenticate even when yet authenticated
            if ((event.match.nw_dst == AUTH_DST_IP and
                 (event.match.tp_dst == AUTH_DST_PORT1
                  or event.match.tp_dst == AUTH_DST_PORT2))
                    or (event.match.nw_src == AUTH_DST_IP and
                        (event.match.tp_src == AUTH_DST_PORT1
                         or event.match.tp_src == AUTH_DST_PORT2))):
                if (event.match.nw_dst == AUTH_DST_IP
                        and event.match.tp_dst == 8080):
                    owglobal.last_host_redirect = (
                        self.conn.db[event.sock].dpid, event.match.dl_src)
                output.dbg("Approving "+\
                               pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\
                               "=>"+\
                               pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst),
                           self.__class__.__name__)
                return True

            #Authenticated host
            if (host_authenticated(event.match.dl_src)
                    or host_authenticated(event.match.dl_dst)):
                output.vdbg("Authenticated host flow "+\
                                pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\
                                "=>"+\
                                pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst),
                            self.__class__.__name__)
                return True

            ##Allow special website access without authentication
            if (event.match.nw_dst in BYPASS_IP
                    or event.match.nw_src in BYPASS_IP):
                output.dbg("Allow bypass for special server",
                           self.__class__.__name__)
                return True

            ##Allow
            # (1) ARP
            # (2) ICMP
            # (3) DHCP
            # (4) DNS
            if ((event.match.dl_type == dpkt.ethernet.ETH_TYPE_ARP)
                    or (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP
                        and event.match.nw_proto == dpkt.ip.IP_PROTO_ICMP)
                    or (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP
                        and event.match.nw_proto == dpkt.ip.IP_PROTO_UDP and
                        (event.match.tp_dst == 67 or event.match.tp_dst == 68))
                    or
                (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP
                 and event.match.nw_proto == dpkt.ip.IP_PROTO_UDP and
                 (event.match.tp_dst == 53 or event.match.tp_src == 53))):
                return True

            ##Allow route to OpenID provider (should be in HTTPS)
            if (event.match.tp_dst == HTTPS_PORT or event.match.tp_dst == 8080
                    or event.match.tp_dst == 80
                    or event.match.tp_src == HTTPS_PORT
                    or event.match.tp_src == 8080 or event.match.tp_src == 80):
                auth_s = None
                if (event.match.tp_dst == HTTPS_PORT
                        or event.match.tp_dst == 8080
                        or event.match.tp_dst == 80):
                    auth_s = mcutil.get(
                        host_auth.get_auth_key(event.match.dl_src))
                else:
                    auth_s = mcutil.get(
                        host_auth.get_auth_key(event.match.dl_dst))

                if (auth_s != None):
                    output.dbg(pu.ip_val2string(event.match.nw_dst)+" associated with "+\
                                   " auth server "+str(auth_s)+" "+str(event.match.dl_src),
                               self.__class__.__name__)
                    return True

            ##Redirect unauthenticated host if HTTP
            if (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP
                    and event.match.nw_proto == dpkt.ip.IP_PROTO_TCP and
                (event.match.tp_dst == 80 or event.match.tp_dst == 8080)):
                output.dbg(
                    "Redirecting %x to authenticate" %
                    pu.array2val(event.match.dl_src), self.__class__.__name__)

                #Forward flow
                flow = flows.exact_entry(event.match)
                key = swhost.mac2sw_binding.get_key(event.sock,
                                                    event.match.dl_dst)
                port = mcutil.get(key)
                if (port != None):
                    flow.set_buffer(event.pktin.buffer_id)
                    flow.add_nw_rewrite(False, AUTH_DST_IP)
                    flow.add_output(port)
                    self.conn.send(event.sock,
                                   flow.get_flow_mod(pyof.OFPFC_MODIFY).pack())

                    #Reverse flow
                    rflow = flow.reverse(port)
                    rflow.match.nw_src = AUTH_DST_IP
                    rflow.add_nw_rewrite(True, event.match.nw_dst)
                    rflow.add_output(event.pktin.in_port)
                    self.conn.send(
                        event.sock,
                        rflow.get_flow_mod(pyof.OFPFC_MODIFY).pack())

                return False

            #Drop remaining flows
            flow = flows.exact_entry(event.match)
            flow.set_buffer(event.pktin.buffer_id)
            self.conn.send(event.sock,
                           flow.get_flow_mod(pyof.OFPFC_ADD).pack())
            output.dbg("Dropping "+\
                           pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\
                           "=>"+pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst),
                       self.__class__.__name__)
            return False

        return True