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); }
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; }
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( ð_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( ð_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( ð_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( ð_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( ð_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( ð_rx_packet[ src_mac_addr_pos ], ð_tx_packet[ pos ] ); pos += MAC_ADDR_LEN; write_own_mac_addr( ð_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( ð_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( ð_rx_packet[ src_mac_addr_pos ], ð_tx_packet[ pos ] ); pos += MAC_ADDR_LEN; copy_ip_address( ð_rx_packet[ src_ip_addr_pos ], ð_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; }