?? ospf_receive_packet.c
字號:
swapped_auth_type = net_to_host_short (sptr_ospf_header->authentication_type); if (swapped_auth_type == OSPF_AUTHENTICATION_MD5) { if (sptr_ospf_header->checksum == 0x0000) { return (PASS); } else { OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Invalid checksum in ospf packet header\r\n"); return (FAIL); } } else { authentication_field = sptr_ospf_header->authentication_field; /* save the authentication field in a temporary buffer */ /* sptr_ospf_header->authentication_field.key[0] = sptr_ospf_header->authentication_field.key[1] = 0x00000000L; */ memset (sptr_ospf_header->authentication_field.key_or_plain_text_passwd, 0x0, OSPF_AUTHENTICATION_SIMPLE_SIZE); if ((calculate_ip_checksum (NULL, (BYTE *) sptr_ospf_header, (USHORT) size_of_ospf_packet) == 0x0000)) { return_type = PASS; } else { OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Invalid checksum in ospf packet header\r\n"); return_type = FAIL; } sptr_ospf_header->authentication_field = authentication_field; /* restore authentication field to it's original value */ return (return_type); }}/*****************************************//* section 8.2, second bullet item under verifying OSPF packet header (page 57-58) */static enum TEST ospf_verify_area_id_and_get_neighbor (OSPF_HEADER *sptr_ospf_header,OSPF_INTERFACE **ptr_to_sptr_interface, ULONG source_address, OSPF_NEIGHBOR **ptr_to_sptr_neighbor){ ULONG router_id; ULONG area_id; enum TEST test_result; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_verify_area_id_and_get_neighbor\r\n"); router_id = net_to_host_long (sptr_ospf_header->router_id); area_id = net_to_host_long (sptr_ospf_header->area_id); /* check if the Area ID of the packet matches the Area ID of the receiving interface */ if (( (*ptr_to_sptr_interface) != NULL ) && (area_id == (*ptr_to_sptr_interface)->sptr_area->area_id)) { /* * the packet has been sent over a single hop, and is not a virtual link, so make sure the packet's IP source address is on * the same network as the receiving interface */ if ( (*ptr_to_sptr_interface)->type != OSPF_POINT_TO_POINT) { if ((source_address & (*ptr_to_sptr_interface)->netmask) != ( (*ptr_to_sptr_interface)->address & (*ptr_to_sptr_interface)->netmask)) { OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Source address doesn't belong to this interface\r\n"); return (FAIL); } } /* Find the neighbor */ switch ( (*ptr_to_sptr_interface)->type) { case OSPF_BROADCAST: case OSPF_NBMA: { for (*ptr_to_sptr_neighbor = (*ptr_to_sptr_interface)->sptr_neighbor; *ptr_to_sptr_neighbor != NULL; *ptr_to_sptr_neighbor = (*ptr_to_sptr_neighbor)->sptr_forward_link) { if ((*ptr_to_sptr_neighbor)->id == router_id) { break; /* found the neighbor we're looking for */ } } break; } case OSPF_POINT_TO_POINT: case OSPF_POINT_TO_MULTIPOINT: /* __NBMA_PTMP__ */ { *ptr_to_sptr_neighbor = (*ptr_to_sptr_interface)->sptr_neighbor; if (*ptr_to_sptr_neighbor != NULL) { if (((*ptr_to_sptr_neighbor)->id == 0x00000000L) || ((*ptr_to_sptr_neighbor)->id != router_id)) { *ptr_to_sptr_neighbor = NULL; /* Unknown router ID, or unknown address */ } } break; } default: { break; } } if ((*ptr_to_sptr_neighbor == NULL) && (sptr_ospf_header->type != OSPF_HELLO_PACKET)) { OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: No neighbor found\r\n"); return (FAIL); } else { return (PASS); } } else { /* packet should be from a virtual link */ test_result = ospf_verify_area_id_and_virtual_neighbor (router_id, area_id, ptr_to_sptr_interface, ptr_to_sptr_neighbor); return (test_result); }}/****************************************************************************************************************/static enum TEST ospf_verify_area_id_and_virtual_neighbor (ULONG router_id, ULONG area_id, OSPF_INTERFACE **ptr_to_sptr_interface, OSPF_NEIGHBOR **ptr_to_sptr_neighbor){ OSPF_INTERFACE_NODE *sptr_virtual_interface_node; OSPF_INTERFACE *sptr_virtual_interface; enum BOOLEAN I_am_an_area_border_router; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_verify_area_id_and_virtual_neighbor\r\n"); I_am_an_area_border_router = ospf_check_if_area_border_router (); if (I_am_an_area_border_router == FALSE) /* make sure the receiving router is an area border router */ { return (FAIL); } for (sptr_virtual_interface_node = ospf.sptr_configured_virtual_links; sptr_virtual_interface_node != NULL; sptr_virtual_interface_node = sptr_virtual_interface_node->sptr_forward_link) { sptr_virtual_interface = sptr_virtual_interface_node->sptr_interface; if (sptr_virtual_interface == NULL) { continue; } if ((sptr_virtual_interface->sptr_neighbor != NULL) && (sptr_virtual_interface->sptr_transit_area != NULL) && (*ptr_to_sptr_interface != NULL) && ((*ptr_to_sptr_interface)->sptr_area)) { if ((sptr_virtual_interface->sptr_neighbor->id == router_id) && (area_id == OSPF_BACKBONE) && ( (*ptr_to_sptr_interface) != NULL) && (sptr_virtual_interface->sptr_transit_area->area_id == (*ptr_to_sptr_interface)->sptr_area->area_id)) { *ptr_to_sptr_interface = sptr_virtual_interface; *ptr_to_sptr_neighbor = sptr_virtual_interface->sptr_neighbor; return (PASS); } } } return (FAIL); /* Not found */}/*********************************//* section 8.2, fourth and fifth bullet items under verifying OSPF packet header (page 58) */static enum TEST ospf_authenticate_packet (USHORT packet_size,OSPF_HEADER *sptr_ospf_header,OSPF_INTERFACE *sptr_interface, OSPF_AUTHENTICATION *sptr_ospf_authentication,OSPF_NEIGHBOR *sptr_neighbor,ULONG *sptr_cryptographic_sequence_number){ enum TEST return_type; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_authenticate_packet\r\n"); switch (sptr_ospf_authentication->type) { case OSPF_AUTHENTICATION_NONE: { *sptr_cryptographic_sequence_number = (ULONG) 0x00000000L; return (PASS); } case OSPF_AUTHENTICATION_SIMPLE: { if (memcmp ( (void*) &(sptr_ospf_header->authentication_field.key_or_plain_text_passwd), (void*) &sptr_ospf_authentication->key_or_plain_text_passwd, OSPF_AUTHENTICATION_SIMPLE_SIZE) == 0 ) { *sptr_cryptographic_sequence_number = (ULONG) 0x00000000L; return (PASS); } else { OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Failed authentication\r\n"); return (FAIL); } } case OSPF_AUTHENTICATION_MD5: { return_type = ospf_do_md5_authentication (packet_size, sptr_ospf_header, sptr_interface, sptr_neighbor); if (return_type == PASS) { *sptr_cryptographic_sequence_number = sptr_ospf_header->authentication_field.md5.cryptographic_sequence_number; return (PASS); } else { OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Failed authentication\r\n"); return (FAIL); } } default: { OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Received Authentication Type is not supported by this implementation\r\n"); return (FAIL); } }}/******************************************************************************************************************************/static enum TEST ospf_do_md5_authentication (USHORT packet_size,OSPF_HEADER *sptr_ospf_header, OSPF_INTERFACE *sptr_interface,OSPF_NEIGHBOR *sptr_neighbor){ USHORT length; OSPF_AUTHENTICATION_KEY *sptr_authentication_key; enum TEST return_type; BYTE *bptr_packet; BYTE bptr_received_digest[OSPF_AUTHENTICATION_SIZE]; BYTE bptr_digest[OSPF_AUTHENTICATION_SIZE]; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_do_md5_authentication\r\n"); memset (bptr_received_digest, 0x0, OSPF_AUTHENTICATION_SIZE); memset (bptr_digest, 0x0, OSPF_AUTHENTICATION_SIZE); length = sptr_ospf_header->length; length = net_to_host_short (length); if (((ULONG) length + OSPF_AUTHENTICATION_MD5_SIZE) > (ULONG) packet_size) { return (FAIL); } /* locate the receiving interface's configured key having Key ID equal to that specified in the received packet */ sptr_authentication_key = NULL; return_type = ospf_find_matching_key_for_md5_authentication (sptr_interface, sptr_ospf_header->authentication_field.md5.key_ID, &sptr_authentication_key); if (return_type == FAIL) { return (FAIL); /* key was not found or was not valid for reception, so discard OSPF packet */ } /* verify validity of received cryptographic sequence number */ if (sptr_neighbor != NULL) { if (sptr_ospf_header->authentication_field.md5.cryptographic_sequence_number < sptr_neighbor->cryptographic_sequence_number) { return (FAIL); } } /* set aside the received digest */ bptr_packet = (BYTE *) sptr_ospf_header; bptr_packet = bptr_packet + length; memcpy ((void *) bptr_received_digest, (const void *) bptr_packet, (size_t) OSPF_AUTHENTICATION_MD5_SIZE); memcpy ((void *) bptr_packet, (const void *) &(sptr_authentication_key->md5_16byte_password), (size_t) OSPF_AUTHENTICATION_MD5_SIZE); /* Calculate the MD5 digest */ mdString ( (BYTE *) sptr_ospf_header, (ULONG) packet_size, bptr_digest, MD5); if (memcmp ( (void *) bptr_digest, (void *) bptr_received_digest, (size_t) OSPF_AUTHENTICATION_MD5_SIZE) == 0x0) { return (PASS); } else { return (FAIL); }}/**************************************************************************************************************************************/static enum TEST ospf_find_matching_key_for_md5_authentication (OSPF_INTERFACE *sptr_interface,BYTE received_key, OSPF_AUTHENTICATION_KEY **ptr_to_sptr_found_authentication_key){ OSPF_AUTHENTICATION_KEY *sptr_authentication_key; ULONG current_time; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_find_matching_key_for_md5_authentication\r\n"); *ptr_to_sptr_found_authentication_key = NULL; for (sptr_authentication_key = sptr_interface->sptr_authentication_key; sptr_authentication_key != NULL; sptr_authentication_key = sptr_authentication_key->sptr_forward_link) { if (sptr_authentication_key->key_ID == received_key) { *ptr_to_sptr_found_authentication_key = sptr_authentication_key; break; } } if (*ptr_to_sptr_found_authentication_key == NULL) { return (FAIL); /* key wasn't found */ } /* SPR 84312 -- Begin */ current_time = ospf_get_system_elapsed_time_second (); /* SPR 84312 -- End */ if ((current_time < (*ptr_to_sptr_found_authentication_key)->key_start_accept) || ((current_time >= (*ptr_to_sptr_found_authentication_key)->key_stop_accept) && ((*ptr_to_sptr_found_authentication_key)->key_stop_accept != 0x00000000L))) { return (FAIL); /* key is not valid for reception */ } return (PASS);}/******************************************************************************************************************************/static enum OSPF_PACKET_STATE ospf_process_specific_packet_type (OSPF_HEADER *sptr_ospf_header,OSPF_INTERFACE *sptr_interface, OSPF_NEIGHBOR *sptr_neighbor,ULONG source_address,ULONG destination_address,ULONG size_of_ospf_packet,ULONG cryptographic_sequence_number){ enum OSPF_PACKET_STATE return_type; ULONG router_id; OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_process_specific_packet_type\r\n"); router_id = sptr_ospf_header->router_id; router_id = net_to_host_long (router_id); switch (sptr_ospf_header->type) { case OSPF_HELLO_PACKET: OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "------=====>>>>> OSPF HELLO received from : source address %lx Interface type is: %d\r\n", source_address, sptr_interface->type); return_type = ospf_hello_packet_received (&sptr_ospf_header->rest_of_packet.hello, sptr_neighbor, sptr_interface, source_address, router_id, size_of_ospf_packet, cryptographic_sequence_number); break; case OSPF_DATABASE_DESCRIPTION_PACKET: return_type = ospf_database_packet_received (&sptr_ospf_header->rest_of_packet.database, sptr_neighbor, sptr_interface, size_of_ospf_packet); break; case OSPF_LINK_STATE_REQUEST_PACKET: return_type = ospf_ls_request_packet_received (&sptr_ospf_header->rest_of_packet.ls_request, sptr_neighbor, sptr_interface, size_of_ospf_packet); break; case OSPF_LINK_STATE_UPDATE_PACKET: OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "##### OSPF UPDATE received from : source address %lx and destination address:%lx Interface type is: %d\r\n", source_address, destination_address, sptr_interface->type); return_type = ospf_ls_update_packet_received (&sptr_ospf_header->rest_of_packet.ls_update, sptr_neighbor, sptr_interface, source_address, destination_address); break; case OSPF_LINK_STATE_ACKNOWLEDGEMENT_PACKET: return_type = ospf_ls_acknowledgement_packet_received (&sptr_ospf_header->rest_of_packet.ls_acknowledgement, sptr_neighbor, sptr_interface, size_of_ospf_packet); break; default: return_type = OSPF_ERROR_OSPF_PACKET_TYPE; break; } return (return_type);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -