void
test_copy_mac_address(void) {
  lagopus_result_t rc;

  const mac_address_t src_mac_addr = {0x11, 0x22, 0x33, 0xAA, 0xBB, 0xCC};
  mac_address_t actual_mac_addr = {0, 0, 0, 0, 0, 0};
  mac_address_t expected_mac_addr = {0x11, 0x22, 0x33, 0xAA, 0xBB, 0xCC};

  rc = copy_mac_address(src_mac_addr, actual_mac_addr);
  TEST_ASSERT_EQUAL(LAGOPUS_RESULT_OK, rc);
  TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_mac_addr, actual_mac_addr, 6);
}
Beispiel #2
0
int main()
{
	topology_init();
	topology_ops_init();
	struct topology_vport vport1;
	struct topology_vport vport2;

	copy_mac_address(vport1.vport_id,"\x12\x12\x12\x12\x12\x12");
	copy_mac_address(vport2.vport_id,"\x12\x12\x12\x12\x12\x13");
	int rc=add_vport_node_pairs_into_topology(vport_stub,domain_stub,device_stub,&device_head,&domain_head,&vport1,0x5555,&vport2,0x5556,0x12);

	copy_mac_address(vport1.vport_id,"\x12\x12\x12\x12\x12\x11");
	copy_mac_address(vport2.vport_id,"\x12\x12\x12\x12\x12\x14");
	rc=add_vport_node_pairs_into_topology(vport_stub,domain_stub,device_stub,&device_head,&domain_head,&vport1,0x5555,&vport2,0x5557,0x13);

	copy_mac_address(vport1.vport_id,"\x12\x12\x12\x12\x12\x16");
	copy_mac_address(vport2.vport_id,"\x12\x12\x12\x12\x12\x13");
	rc=add_vport_node_pairs_into_topology(vport_stub,domain_stub,device_stub,&device_head,&domain_head,&vport1,0x5558,&vport2,0x5556,0x12);

	copy_mac_address(vport1.vport_id,"\x12\x12\x12\x12\x12\x15");
	copy_mac_address(vport2.vport_id,"\x12\x12\x12\x12\x12\x14");
	rc=add_vport_node_pairs_into_topology(vport_stub,domain_stub,device_stub,&device_head,&domain_head,&vport1,0x5558,&vport2,0x5557,0x13);


	struct topology_vport *vport1_ptr;
	struct topology_vport *vport2_ptr;
	struct topology_vport *vport3_ptr;
	struct topology_vport *vport4_ptr;
	
	copy_mac_address(vport1.vport_id,"\x12\x12\x12\x12\x12\x12");
	vport1_ptr=index_hash_element(vport_stub,&vport1,STUB_TYPE_VPORT);
	copy_mac_address(vport1.vport_id,"\x12\x12\x12\x12\x12\x13");
	vport2_ptr=index_hash_element(vport_stub,&vport1,STUB_TYPE_VPORT);
	copy_mac_address(vport1.vport_id,"\x12\x12\x12\x12\x12\x11");
	vport3_ptr=index_hash_element(vport_stub,&vport1,STUB_TYPE_VPORT);
	copy_mac_address(vport1.vport_id,"\x12\x12\x12\x12\x12\x14");
	vport4_ptr=index_hash_element(vport_stub,&vport1,STUB_TYPE_VPORT);
	
	dijstra_find_short_ecmp_path(vport2_ptr,vport4_ptr);
	printf("%d\n",debug_cnt);
	return 0;
}
Beispiel #3
0
static int process_received_frame ( const int frame_len )
{
    // At the moment, we can only reply to a single ARP query for our MAC address.
    // Use a command like this to make this routine generate an answer:
    //   With Ubuntu's arping:
    //     arping -c 1 -f -w 10 -I dpi-tap1 192.168.254.1
    //   With Thomas Habets' arping:
    //     sudo ./arping -w 10000000 -c 1 -i dpi-tap1 192.168.254.1

    const int ARP_FRAME_LENGTH = 42;

    if ( frame_len < ARP_FRAME_LENGTH )
    {
        uart_print( UART1_BASE_ADDR, "The frame is too short to be the kind of ARP frame we are looking for." EOL );
        return 0;
    }

    int pos = 0;

    if ( eth_rx_packet[ pos + 0 ] != BROADCAST_ADDRESS_5 ||
         eth_rx_packet[ pos + 1 ] != BROADCAST_ADDRESS_4 ||
         eth_rx_packet[ pos + 2 ] != BROADCAST_ADDRESS_3 ||
         eth_rx_packet[ pos + 3 ] != BROADCAST_ADDRESS_2 ||
         eth_rx_packet[ pos + 4 ] != BROADCAST_ADDRESS_1 ||
         eth_rx_packet[ pos + 5 ] != BROADCAST_ADDRESS_0 )
    {
        uart_print( UART1_BASE_ADDR, "The target MAC address is not broadcast." EOL );
        return 0;
    }

    pos += MAC_ADDR_LEN;

    const int src_mac_addr_pos = pos;

    uart_print( UART1_BASE_ADDR, "Received broadcast frame from MAC address " );
    print_mac_address( &eth_rx_packet[ pos ] );
    uart_print( UART1_BASE_ADDR, EOL );

    pos += MAC_ADDR_LEN;

    const unsigned char ARP_PROTOCOL_HI = 0x08;
    const unsigned char ARP_PROTOCOL_LO = 0x06;
    if ( eth_rx_packet[ pos + 0 ] != ARP_PROTOCOL_HI ||
         eth_rx_packet[ pos + 1 ] != ARP_PROTOCOL_LO )
    {
        uart_print( UART1_BASE_ADDR, "The frame does not contain ARP protocol data." EOL );
        return 0;
    }

    pos += 2;

    const unsigned char ETHERNET_HARDWARE_TYPE_HI = 0x00;
    const unsigned char ETHERNET_HARDWARE_TYPE_LO = 0x01;

    if ( eth_rx_packet[ pos + 0 ] != ETHERNET_HARDWARE_TYPE_HI ||
         eth_rx_packet[ pos + 1 ] != ETHERNET_HARDWARE_TYPE_LO )
    {
        uart_print( UART1_BASE_ADDR, "The ARP frame does not contain the Ethernet hardware type." EOL );
        return 0;
    }

    pos += 2;

    const unsigned char IP_PROTOCOL_HI = 0x08;
    const unsigned char IP_PROTOCOL_LO = 0x00;

    if ( eth_rx_packet[ pos + 0 ] != IP_PROTOCOL_HI ||
         eth_rx_packet[ pos + 1 ] != IP_PROTOCOL_LO )
    {
        uart_print( UART1_BASE_ADDR, "The ARP frame is not about the IP protocol." EOL );
        return 0;
    }

    pos += 2;

    const unsigned char HARDWARE_SIZE = MAC_ADDR_LEN;

    if ( eth_rx_packet[ pos ] != HARDWARE_SIZE )
    {
        uart_print( UART1_BASE_ADDR, "The ARP frame has an invalid hardware size." EOL );
        return 0;
    }

    pos += 1;

    const unsigned char PROTOCOL_SIZE = IP_ADDR_LEN;

    if ( eth_rx_packet[ pos ] != PROTOCOL_SIZE )
    {
        uart_print( UART1_BASE_ADDR, "The ARP frame has an invalid protocol size." EOL );
        return 0;
    }

    pos += 1;

    const unsigned char OPCODE_REQUEST_HI = 0x00;
    const unsigned char OPCODE_REQUEST_LO = 0x01;
    const unsigned char OPCODE_REPLY_HI = 0x00;
    const unsigned char OPCODE_REPLY_LO = 0x02;

    if ( eth_rx_packet[ pos + 0 ] != OPCODE_REQUEST_HI ||
         eth_rx_packet[ pos + 1 ] != OPCODE_REQUEST_LO )
    {
        uart_print( UART1_BASE_ADDR, "The ARP frame is not an ARP request." EOL );
        return 0;
    }

    pos += 2;

    uart_print( UART1_BASE_ADDR, "The ARP sender MAC address is " );
    print_mac_address( &eth_rx_packet[ pos ] );
    uart_print( UART1_BASE_ADDR, EOL );

    pos += MAC_ADDR_LEN;

    const int src_ip_addr_pos = pos;

    uart_print( UART1_BASE_ADDR, "The ARP sender IP address is " );
    print_ip_address( &eth_rx_packet[ pos ] );
    uart_print( UART1_BASE_ADDR, EOL );

    pos += IP_ADDR_LEN;

    uart_print( UART1_BASE_ADDR, "The target MAC address is " );
    print_mac_address( &eth_rx_packet[ pos ] );
    uart_print( UART1_BASE_ADDR, EOL );

    // Linux uses 0x000000 here, but arping uses 0xFFFFFF.
    const int is_zero = eth_rx_packet[ pos + 0 ] == 0 &&
                        eth_rx_packet[ pos + 1 ] == 0 &&
                        eth_rx_packet[ pos + 2 ] == 0 &&
                        eth_rx_packet[ pos + 3 ] == 0 &&
                        eth_rx_packet[ pos + 4 ] == 0 &&
                        eth_rx_packet[ pos + 5 ] == 0;

    const int is_bcast   = eth_rx_packet[ pos + 0 ] == BROADCAST_ADDRESS_5 &&
                           eth_rx_packet[ pos + 1 ] == BROADCAST_ADDRESS_4 &&
                           eth_rx_packet[ pos + 2 ] == BROADCAST_ADDRESS_3 &&
                           eth_rx_packet[ pos + 3 ] == BROADCAST_ADDRESS_2 &&
                           eth_rx_packet[ pos + 4 ] == BROADCAST_ADDRESS_1 &&
                           eth_rx_packet[ pos + 5 ] == BROADCAST_ADDRESS_0;

    if ( !is_zero && !is_bcast  )
    {
        uart_print( UART1_BASE_ADDR, "The target MAC address is neither zero nor 0xFF." EOL );
        return 0;
    }

    pos += MAC_ADDR_LEN;

    uart_print( UART1_BASE_ADDR, "The target IP address is " );
    print_ip_address( &eth_rx_packet[ pos ] );
    uart_print( UART1_BASE_ADDR, EOL );

    if ( eth_rx_packet[ pos + 0 ] != OWN_IP_ADDRESS_0 ||
         eth_rx_packet[ pos + 1 ] != OWN_IP_ADDRESS_1 ||
         eth_rx_packet[ pos + 2 ] != OWN_IP_ADDRESS_2 ||
         eth_rx_packet[ pos + 3 ] != OWN_IP_ADDRESS_3 )
    {
        uart_print( UART1_BASE_ADDR, "The target IP address is not ours." EOL );
        return 0;
    }

    pos += IP_ADDR_LEN;

    if ( pos != ARP_FRAME_LENGTH )
    {
        uart_print( UART1_BASE_ADDR, "Internal error parsing the frame." EOL );
        return 0;
    }


    // Build the ARP reply.

    pos = 0;

    copy_mac_address( &eth_rx_packet[ src_mac_addr_pos ], &eth_tx_packet[ pos ] );
    pos += MAC_ADDR_LEN;

    write_own_mac_addr( &eth_tx_packet[ pos ] );
    pos += MAC_ADDR_LEN;

    eth_tx_packet[ pos + 0 ] = ARP_PROTOCOL_HI;
    eth_tx_packet[ pos + 1 ] = ARP_PROTOCOL_LO;
    pos += 2;

    eth_tx_packet[ pos + 0 ] = ETHERNET_HARDWARE_TYPE_HI;
    eth_tx_packet[ pos + 1 ] = ETHERNET_HARDWARE_TYPE_LO;
    pos += 2;

    eth_tx_packet[ pos + 0 ] = IP_PROTOCOL_HI;
    eth_tx_packet[ pos + 1 ] = IP_PROTOCOL_LO;
    pos += 2;

    eth_tx_packet[ pos + 0 ] = HARDWARE_SIZE;
    pos += 1;

    eth_tx_packet[ pos + 0 ] = PROTOCOL_SIZE;
    pos += 1;

    eth_tx_packet[ pos + 0 ] = OPCODE_REPLY_HI;
    eth_tx_packet[ pos + 1 ] = OPCODE_REPLY_LO;
    pos += 2;

    write_own_mac_addr( &eth_tx_packet[ pos ] );
    pos += MAC_ADDR_LEN;

    eth_tx_packet[ pos + 0 ] = OWN_IP_ADDRESS_0;
    eth_tx_packet[ pos + 1 ] = OWN_IP_ADDRESS_1;
    eth_tx_packet[ pos + 2 ] = OWN_IP_ADDRESS_2;
    eth_tx_packet[ pos + 3 ] = OWN_IP_ADDRESS_3;
    pos += IP_ADDR_LEN;

    copy_mac_address( &eth_rx_packet[ src_mac_addr_pos ], &eth_tx_packet[ pos ] );
    pos += MAC_ADDR_LEN;

    copy_ip_address( &eth_rx_packet[ src_ip_addr_pos ], &eth_tx_packet[ pos ] );
    pos += IP_ADDR_LEN;

    if ( pos != ARP_FRAME_LENGTH )
    {
        uart_print( UART1_BASE_ADDR, "Internal error building the ARP reply frame." EOL );
        return 0;
    }

    // After the ARP information, at the end of the Ethernet packet, comes the dummy CRC,
    // which should be 4 bytes with value 0xDEADF00D.

    uart_print( UART1_BASE_ADDR, "Sending the ARP reply..." EOL );

    start_ethernet_send( ARP_FRAME_LENGTH );
    wait_until_frame_was_sent();

    uart_print( UART1_BASE_ADDR, "Reply sent." EOL );

    return 1;
}