Exemplo n.º 1
0
Arquivo: nat.py Projeto: yapkke/yapc
    def _process_inbound(self, pktin, intfs, iport, lointf):
        """Event handler for inbound 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
        """
        try:
            ipr = intfs[pktin.match.in_port]
        except KeyError:
            output.vdbg("ARP packet received on unknown/uninitialized interface", self.__class__.__name__)
            return False

        flow = flows.exact_entry(pktin.match)
        if flow.buffer_id != pktin.pktin.buffer_id:
            output.warn("Buffered inbound ARP packet (cannot be rewritten properly)!", self.__class__.__name__)
        elif flow.match.nw_dst != ipr[0]:
            output.vdbg("Inbound ARP packet not destined for this host, ignored.", self.__class__.__name__)
        else:
            flow.add_output(iport)
            if pu.array2val(pktin.match.dl_dst) != 0xFFFFFFFFFFFF:
                ofpkt.dl_rewrite(pktin.dpkt, False, lointf[1])
            ofpkt.nw_rewrite(pktin.dpkt, False, lointf[0])
            self.get_conn().send(flow.get_packet_out().pack() + pktin.dpkt.pack())
        return False
Exemplo n.º 2
0
def get_flow_id(ofp_match, ignore_l2=False):
    """Generate flow id based on ofp_match

    id has the following properties:
    * is the same for packets of the same TCP/UDP flow
    * is the same for packets for the same bidirectional flow
    """
    t1 = ofp_match.dl_type
    t2 = ofp_match.nw_proto
    daddr = [pu.array2val(ofp_match.dl_src), pu.array2val(ofp_match.dl_src)]
    d1 = min(daddr)
    d2 = max(daddr)
    naddr = [ofp_match.nw_src, ofp_match.nw_dst]
    n1 = min(naddr)
    n2 = max(naddr)
    taddr = [ofp_match.tp_src, ofp_match.tp_dst]
    t1 = min(taddr)
    t2 = max(taddr)
    if (ignore_l2):
        return hash((t1,t2,n1,n2,t1,t2))
    else:
        return hash((t1,t2,d1,d2,n1,n2,t1,t2))
Exemplo n.º 3
0
    def processevent(self, event):
        """Event handler

        @param event event to handle
        """
        key = self.get_key(event.sock, event.match.dl_src)

        #Broadcast mac
        if (pu.is_multicast_mac(event.match.dl_src)):
            return True

        mc.set(key, event.pktin.in_port, mac2sw_binding.TIMEOUT)
        output.vdbg("Learn that %x " % pu.array2val(event.match.dl_src) +\
                       "is connected to port " + \
                       str(event.pktin.in_port)+" of switch with "+\
                       str(event.sock),
                   self.__class__.__name__)

        return True
Exemplo n.º 4
0
    def processevent(self, event):
        """Event handler

        @param event event to handle
        @return false if flow can be installed, else true
        """
        if (isinstance(event, ofevents.pktin)):
            #Forward packet/flow
            if (pu.is_multicast_mac(event.match.dl_dst)):
                return True
            
            key = swhost.mac2sw_binding.get_key(event.sock,
                                                event.match.dl_dst)
            port = mc.get(key)
            if (port != None):
                self.installflow(event, port)
                return False
            else:
                output.dbg("No binding found for mac %x"  % pu.array2val(event.match.dl_dst),
                           self.__class__.__name__)
            
        return True     
Exemplo n.º 5
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.º 6
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.º 7
0
 def get_key(sock, mac):
     """Get key to retrieve binding between switch and mac
     """
     return mac2sw_binding.MAC2SW_BINDING_PREFIX +\
         mc.socket_str(sock) +\
         "%x" % pu.array2val(mac)