Exemplo n.º 1
0
    def _handle_open(self, msg):

        self.peer_as = msg.my_as
        peer_holdtime = msg.hold_time
        self.hold_time = min(peer_holdtime, self.hold_time)
        self.peer_id = msg.bgp_identifier
        self.peer_capabilities = msg.data
        for capability in self.peer_capabilities:
            if isinstance(capability, BGP4.multi_protocol_extension):
                if capability.addr_family == 1:
                    self._4or6 = 4
                elif capability.addr_family == 2:
                    self._4or6 = 6
                else:
                    self._4or6 = 0
            if isinstance(capability, BGP4.support_4_octets_as_num):
                self.peer_as = capability.as_num

        print '4/6:', self._4or6
        print 'peer_as:', self.peer_as
        print 'hold_time:', self.hold_time
        print 'peer_id:', convert.ipv4_to_str(self.peer_id)
        print 'capability:', self.peer_capabilities

        self.send_open_msg()

        if self.__check_capabilities(self.peer_capabilities):
            hub.spawn(self.keepalive)
            self.send_current_route_table()
        else:
            self.send_notification_msg()
Exemplo n.º 2
0
    def _handle_arp(self, msg, pkt, arp_pkt):
        '''
            1)
            handles ARP request from hosts, about their gateways;
            only works in IPv4 since IPv6 uses NDP(ICMPv6);
            e.g. when a host need to send a packet to the gateway, it will
                firstly send an ARP to get the MAC address of the gateway
            2)
            handles ARP reply from hosts, and try to send packets currently
            stored in switch.msg_buffer
        '''
        #print 'arp', arp_pkt

        if arp_pkt.opcode == arp.ARP_REPLY:
            self._handle_arp_reply(msg, pkt, arp_pkt)
            return

        if arp_pkt.opcode != arp.ARP_REQUEST:
            return

        switch = self.dpid_to_switch[msg.datapath.id]
        in_port_no = msg.in_port
        req_dst_ip = arp_pkt.dst_ip
        req_src_ip = arp_pkt.src_ip

        port = switch.ports[in_port_no]
        if port.gateway and req_dst_ip != port.gateway.gw_ip:
            return

        datapath = msg.datapath
        reply_src_mac = port.hw_addr
        ether_layer = self.find_packet(pkt, 'ethernet')

        e = ethernet.ethernet(dst=ether_layer.src,
                              src=reply_src_mac,
                              ethertype=ether.ETH_TYPE_ARP)
        a = arp.arp(hwtype=arp.ARP_HW_TYPE_ETHERNET,
                    proto=ether.ETH_TYPE_IP,
                    hlen=6,
                    plen=4,
                    opcode=arp.ARP_REPLY,
                    src_mac=reply_src_mac,
                    src_ip=req_dst_ip,
                    dst_mac=arp_pkt.src_mac,
                    dst_ip=req_src_ip)
        p = packet.Packet()
        p.add_protocol(e)
        p.add_protocol(a)
        p.serialize()

        datapath.send_packet_out(
            in_port=ofproto_v1_0.OFPP_NONE,
            actions=[datapath.ofproto_parser.OFPActionOutput(in_port_no)],
            data=p.data)

        print 'ARP replied:', convert.haddr_to_str(reply_src_mac), \
                convert.ipv4_to_str(req_dst_ip)
Exemplo n.º 3
0
    def _remember_mac_addr(self, switch, packet, _4or6):
        '''
            get ip <-> mac relationship from packets and 
            store them in dict ip_to_mac
        '''
        time_now = time.time()
        ether_layer = self.find_packet(packet, 'ethernet')
        if _4or6 == 4:
            ip_layer = self.find_packet(packet, 'ipv4')
            if ip_layer == None:
                ip_layer = self.find_packet(packet, 'arp')
                ip_layer.src = ip_layer.src_ip
                print 'ARP from ARP'

            print 'ARP entry:', convert.haddr_to_str(ether_layer.src),
            print convert.ipv4_to_str(ip_layer.src)
        else:
            ip_layer = self.find_packet(packet, 'ipv6')
        switch.ip_to_mac[ip_layer.src] = (ether_layer.src, time_now)
Exemplo n.º 4
0
    def _remember_mac_addr(self, switch, packet, _4or6):
        '''
            get ip <-> mac relationship from packets and 
            store them in dict ip_to_mac
        '''
        time_now = time.time()
        ether_layer = self.find_packet(packet, 'ethernet')
        if _4or6 == 4:
            ip_layer = self.find_packet(packet, 'ipv4')
            if ip_layer == None:
                ip_layer = self.find_packet(packet, 'arp')
                ip_layer.src = ip_layer.src_ip
                print 'ARP from ARP'

            print 'ARP entry:', convert.haddr_to_str(ether_layer.src),
            print convert.ipv4_to_str(ip_layer.src)
        else:
            ip_layer = self.find_packet(packet, 'ipv6')
        switch.ip_to_mac[ip_layer.src] = (ether_layer.src, time_now)
Exemplo n.º 5
0
    def parser(cls, buf, offset):
        (version, my_as, hold_time, bgp_identifier, opt_para_len) = \
                        struct.unpack_from(cls._PACK_STR, buf, offset)
        offset += cls._MIN_LEN

        bgp_identifier = convert.ipv4_to_str(bgp_identifier)
        '''
            There're two types of packet structure:
            1)
            Optional Parameters
                Optional Parameter: Capability
                    Capability 1
                    capability 2
                    ...
                    Capability n
            2)
            Optional Parameters
                Optional Parameter: Capability
                    Capability 1
                    ...
                    Capability n
                Optional Parameter: Capability
                    Capability
                ...
                Optional Parameter: Capability
                    Capability

            The second one is obselete but should be supported,
            as defined in RFC 5492
        '''
        if opt_para_len >= 2:
            (type_, para_len) = struct.unpack_from('!BB', buf, offset)
            msg = cls(version, my_as, hold_time, bgp_identifier, opt_para_len,
                      type_, para_len)
        else:
            msg = cls(version, my_as, hold_time, bgp_identifier, opt_para_len)
            return msg

        msg.data = []
        buf = buffer(buf[offset:])
        while len(buf) > 0:
            (type_, para_len) = struct.unpack_from('!BB', buf)
            sub_buf = buffer(buf[2:para_len + 2])
            while len(sub_buf) > 0:
                code, len_ = struct.unpack_from('!BB', sub_buf)
                cls_ = cls._CAPABILITY_ADVERTISEMENT.get(code, None)
                if cls_:
                    msg.data.append(cls_.parser(sub_buf, 0))
                sub_buf = buffer(sub_buf[len_ + 2:])
            buf = buffer(buf[para_len + 2:])

        return msg
Exemplo n.º 6
0
    def _handle_arp(self, msg, pkt, arp_pkt):
        '''
            1)
            handles ARP request from hosts, about their gateways;
            only works in IPv4 since IPv6 uses NDP(ICMPv6);
            e.g. when a host need to send a packet to the gateway, it will
                firstly send an ARP to get the MAC address of the gateway
            2)
            handles ARP reply from hosts, and try to send packets currently
            stored in switch.msg_buffer
        '''
        #print 'arp', arp_pkt

        if arp_pkt.opcode == arp.ARP_REPLY:
            self._handle_arp_reply(msg, pkt, arp_pkt)
            return

        if arp_pkt.opcode != arp.ARP_REQUEST:
            return

        switch = self.dpid_to_switch[msg.datapath.id]
        in_port_no = msg.in_port
        req_dst_ip = arp_pkt.dst_ip
        req_src_ip = arp_pkt.src_ip

        port = switch.ports[in_port_no]
        if port.gateway and req_dst_ip != port.gateway.gw_ip:
            return

        datapath = msg.datapath
        reply_src_mac = port.hw_addr
        ether_layer = self.find_packet(pkt, 'ethernet')

        e = ethernet.ethernet(dst = ether_layer.src, src = reply_src_mac,
                                ethertype = ether.ETH_TYPE_ARP)
        a = arp.arp(hwtype = arp.ARP_HW_TYPE_ETHERNET,
                    proto = ether.ETH_TYPE_IP,
                    hlen = 6, plen = 4, opcode = arp.ARP_REPLY,
                    src_mac = reply_src_mac, src_ip = req_dst_ip,
                    dst_mac = arp_pkt.src_mac, dst_ip = req_src_ip)
        p = packet.Packet()
        p.add_protocol(e)
        p.add_protocol(a)
        p.serialize()

        datapath.send_packet_out(in_port = ofproto_v1_0.OFPP_NONE,
                actions = [datapath.ofproto_parser.OFPActionOutput(in_port_no)],
                data = p.data)

        print 'ARP replied:', convert.haddr_to_str(reply_src_mac), \
                convert.ipv4_to_str(req_dst_ip)
Exemplo n.º 7
0
    def parser(cls, buf, offset):
        (flag, code) = struct.unpack_from('!BB', buf, offset)

        if ((flag & 0x10) == 0x10):
            cls._PACK_STR = '!BBH'
            cls._MIN_LEN = struct.calcsize(cls._PACK_STR)
        else:
            cls._PACK_STR = '!BBB'
            cls._MIN_LEN = struct.calcsize(cls._PACK_STR)

        (flag, code, length) = struct.unpack_from(cls._PACK_STR, buf, offset)
        offset += cls._MIN_LEN

        if length >= 4:
            (addr_family, sub_addr_family,
             next_hop_len) = struct.unpack_from('!HBB', buf, offset)
            offset += 4

        next_hop = []
        if next_hop_len == 4:
            (temp_next_hop, ) = struct.unpack_from('!I', buf, offset)
            offset += 4
            next_hop.append(convert.ipv4_to_str(temp_next_hop))
        else:
            if next_hop_len / 16 != 0:
                for i in range(next_hop_len / 16):
                    (temp_next_hop, ) = struct.unpack_from('!16s', buf, offset)
                    offset += 16
                    next_hop.append(convert.bin_to_ipv6(temp_next_hop))

        if len(buf) > offset:
            # as SNPA is obselete, jump over this field
            (num_of_snpas, ) = struct.unpack_from('!B', buf, offset)
            offset += 1
            if num_of_snpas != 0:
                for i in range(num_of_snpas):
                    (len_of_snap, ) = struct.unpack_from('!B', buf, offset)
                    offset += 1 + len_of_snap

        # the "5" includes AF(2), SAFI(1), len of next_hop_len(1),
        # and reserved(1)
        nlri_len = length - 5 - next_hop_len
        # we could safely assume it's IPv6 here
        nlri = NLRI.parser(buf, offset, nlri_len, 6)

        msg = cls(flag, code, length, addr_family, sub_addr_family,
                  next_hop_len, next_hop, nlri)
        return msg
Exemplo n.º 8
0
    def __str__(self):
        return 'Gateway<name=%s,gw_ip=%s,gw_ipv6=%s,port_num=%s,\
prefixLen=%s,ipv6prefixlen=%s,border=%s>' % (
            self.port_name, convert.ipv4_to_str(self.gw_ip),
            convert.bin_to_ipv6(self.gw_ipv6),
            self.port_num, self.prefixlen, self.ipv6prefixlen, self.border)
Exemplo n.º 9
0
def get_flow_stats(dp, waiters):
    
    rule = nx_match.ClsRule()
    stats = dp.ofproto_parser.NXFlowStatsRequest(datapath = dp,
            flags = 0, out_port = dp.ofproto.OFPP_NONE, table_id = 0xff)
    msgs = []

    send_stats_request(dp, stats, waiters, msgs)
    flows =[]
    for msg in msgs:        
        for body in msg.body:
            actions = actions_to_str(body.actions)   
            s = {'cookie':hex(body.cookie),
                 'duration': str(body.duration_sec) +'.'+ str(body.duration_nsec),
                 'table_id':body.table_id,
                 'n_packets':body.packet_count,
                 'n_bytes':body.byte_count,
                 'idle_age':body.idle_age,
                 'priority':body.priority,
                 'nx_match':[],
                 'actions':actions
            }
            _dict = {} 
            for field in body.fields:

                if field.nxm_header == ofproto_v1_0.NXM_OF_IN_PORT:
                    _dict['in_port'] = hex(field.value)
                elif field.nxm_header ==  ofproto_v1_0.NXM_OF_ETH_SRC:
                    _dict['dl_src'] = haddr_to_str(field.value)
                elif field.nxm_header ==  ofproto_v1_0.NXM_OF_ETH_DST:
                    _dict['dl_dst'] = haddr_to_str(field.value)

                elif field.nxm_header ==  ofproto_v1_0.NXM_OF_ETH_TYPE:
                    _dict['dl_type'] = hex(field.value)
                    

                elif field.nxm_header == ofproto_v1_0.NXM_OF_IP_SRC:
                    _dict['nw_src'] = convert.ipv4_to_str(field.value)
                    
                elif field.nxm_header == ofproto_v1_0.NXM_OF_IP_SRC_W:
                    _dict['nw_src'] = convert.ipv4_to_str(field.value)
                    _dict['nw_src_masked'] = convert.bin_to_ipv4_prefix(field.mask)
                    
                elif field.nxm_header == ofproto_v1_0.NXM_OF_IP_DST:
                    _dict['nw_dst'] = convert.ipv4_to_str(field.value)
                    
                elif field.nxm_header == ofproto_v1_0.NXM_OF_IP_DST_W:
                    _dict['nw_dst'] = convert.ipv4_to_str(field.value)
                    _dict['nw_dst_masked'] = convert.ipv4_to_str(field.mask)

                elif field.nxm_header == ofproto_v1_0.NXM_NX_TUN_ID :
                    _dict['tun_id'] = hex(field.value)

                elif field.nxm_header == ofproto_v1_0.NXM_OF_TCP_SRC:
                    _dict['tp_src'] = field.value

                elif field.nxm_header == ofproto_v1_0.NXM_OF_TCP_DST:
                    _dict['tp_dst'] = field.value

                elif field.nxm_header == ofproto_v1_0.NXM_OF_IP_PROTO:
                    _dict['nw_proto'] = field.value 


                elif field.nxm_header == ofproto_v1_0.NXM_NX_IPV6_SRC:
                    #print '****',field.value
                    _dict['ipv6_src'] = ipv6_add_to_str(field.value)

                elif field.nxm_header == ofproto_v1_0.NXM_NX_IPV6_SRC_W:                    
                    _dict['ipv6_src'] = ipv6_add_to_str(field.value)
                    _dict['ipv6_src_masked'] = convert.arg_list_to_ipv6_prefix(field.mask)
                    
                elif field.nxm_header == ofproto_v1_0.NXM_NX_IPV6_DST:
                    _dict['ipv6_dst'] = ipv6_add_to_str(field.value) 

                elif field.nxm_header == ofproto_v1_0.NXM_NX_IPV6_DST_W:
                    _dict['ipv6_dst'] = ipv6_add_to_str(field.value)
                    _dict['ipv6_dst_masked'] = convert.arg_list_to_ipv6_prefix(field.mask)         
                else:
		    pass
		"""
                    try:
                        _dict['value'] =  hex(field.value)
                    except:
                        _dict['value'] = ''.join(c for c in field.value)
                """
            s['nx_match'].append(_dict)
            flows.append(s)
    flows = {str(dp.id): flows}                   
    return flows
Exemplo n.º 10
0
 def __str__(self):
     ans = 'Next hop: '
     ans += convert.ipv4_to_str(self._next_hop)
     return '<%s>' % ans
Exemplo n.º 11
0
    def __str__(self):
        return 'Gateway<name=%s,gw_ip=%s,gw_ipv6=%s,port_num=%s,\
prefixLen=%s,ipv6prefixlen=%s,border=%s>' % (
            self.port_name, convert.ipv4_to_str(
                self.gw_ip), convert.bin_to_ipv6(self.gw_ipv6), self.port_num,
            self.prefixlen, self.ipv6prefixlen, self.border)