📄 ospf_hello.c
字号:
{ ULONG interface_mtu; ULONG number_of_neighbors; ULONG authentication_size; OSPF_NEIGHBOR *sptr_next_neighbor = NULL; OSPF_PRINTF_PROLOGUE (OSPF_PROLOGUE_PRINTF, "OSPF: Entering ospf_setup_to_send_to_all_neighbors_in_exchange_state\r\n"); *sptr_destination_router = OSPF_ALL_EXCHANGE_NEIGHBORS; if (goingdown == FALSE) { /* * There is less processing overhead in sending one packet with all neighbors listed. A large number of neighbors could require * more buffer space than is allowed on a socket. First build a packet with all neighbors listed. If this packet replicated by * the number of neighbors is greater than the available buffer space, or the packet is greater than the interface MTU, make a * packet for each neighbor with only it's ID listed. */ number_of_neighbors = 0x00000000L; for (sptr_neighbor = sptr_interface->sptr_neighbor; sptr_neighbor != NULL; sptr_neighbor = sptr_next_neighbor) { sptr_next_neighbor = sptr_neighbor->sptr_forward_link; if (sptr_neighbor->state > OSPF_NEIGHBOR_ATTEMPT) { ++number_of_neighbors; } } interface_mtu = ospf_get_interface_mtu (sptr_interface); authentication_size = ospf_get_authentication_size (sptr_interface); if ((*ulptr_length_of_packet + (number_of_neighbors * sizeof (ULONG)) + authentication_size) > interface_mtu) { /* Better to absorb the overhead of sending an individual packet to each neighbor */ for (sptr_neighbor = sptr_interface->sptr_neighbor; sptr_neighbor != NULL; sptr_neighbor = sptr_next_neighbor) { sptr_next_neighbor = sptr_neighbor->sptr_forward_link; if (sptr_neighbor->state > OSPF_NEIGHBOR_ATTEMPT) { ulptr_recently_seen_neighbor = &(sptr_packet->rest_of_packet.hello.neighbor); *ulptr_length_of_packet = OSPF_PACKET_SIZE + OSPF_HELLO_HEADER_SIZE; ulptr_recently_seen_neighbor = ospf_add_neighbor_to_end_of_hello_packet (ulptr_recently_seen_neighbor, sptr_neighbor->id, ulptr_length_of_packet); ospf_tx_packet (sptr_packet, sptr_interface, OSPF_HELLO_PACKET, *ulptr_length_of_packet, *sptr_destination_router, FALSE); } } ospf_free_an_ospf_send_packet (sptr_packet); *sptr_destination_router = 0x00000000L; /* done sending all hello packets, so clear the destination variable */ } else { for (sptr_neighbor = sptr_interface->sptr_neighbor; sptr_neighbor != NULL; sptr_neighbor = sptr_next_neighbor) { sptr_next_neighbor = sptr_neighbor->sptr_forward_link; if (sptr_neighbor->state > OSPF_NEIGHBOR_ATTEMPT) { ulptr_recently_seen_neighbor = ospf_add_neighbor_to_end_of_hello_packet (ulptr_recently_seen_neighbor, sptr_neighbor->id, ulptr_length_of_packet); } } } } return;}#endif /* __RFC_2328__ *//*************************************************************************** ospf_add_neighbor_to_end_of_hello_packet - add neighbor to end of hello packet** This routine will add a neighbor to the end of the hello packet.** <ulptr_end_of_hello_packet> Pointer to end of hello packet** <neighbor_id> Neighbor router** <ulptr_length_of_packet> Length of hello packet** RETURNS: ULONG *** ERRNO: N/A** NOMANUAL*/static ULONG* ospf_add_neighbor_to_end_of_hello_packet (ULONG *ulptr_end_of_hello_packet,ULONG neighbor_id,ULONG *ulptr_length_of_packet){ OSPF_PRINTF_PROLOGUE (OSPF_PROLOGUE_PRINTF, "OSPF: Entering ospf_add_neighbor_to_end_of_hello_packet\r\n"); if (neighbor_id != 0x00000000L) { *ulptr_end_of_hello_packet = host_to_net_long (neighbor_id); ++ulptr_end_of_hello_packet; *ulptr_length_of_packet += sizeof (ULONG); } return (ulptr_end_of_hello_packet);}/*************************************************************************** ospf_hello_packet_received - process hello packet received** This routine will call functions to validate and process a hello* packet when it received.** <sptr_hello> Hello packet header** <sptr_new_neighbor> New neighbor** <sptr_interface> OSPF interface** <source_address> Source address of hello packet** <router_id> Router id of hello packet** <size_of_packet> Size of hello packet** <cryptographic_sequence_number> Cryptographic sequence number** RETURNS: OSPF_PACKET_STATE** ERRNO: N/A** NOMANUAL*//****************************************************************************//* section 10.5 of OSPF specification (page 87) */enum OSPF_PACKET_STATE ospf_hello_packet_received (OSPF_HELLO_HEADER *sptr_hello,OSPF_NEIGHBOR *sptr_new_neighbor, OSPF_INTERFACE *sptr_interface,ULONG source_address,ULONG router_id,ULONG size_of_packet,ULONG cryptographic_sequence_number){ enum OSPF_PACKET_STATE return_type; ULONG current_system_time; PARAMETER_NOT_USED (size_of_packet); OSPF_PRINTF_PROLOGUE (OSPF_PROLOGUE_PRINTF, "OSPF: Entering ospf_hello_packet_received\r\n");#if defined (__OSPF_PASSIVE_INTERFACE__) if (sptr_interface->passive == TRUE) { OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: ospf_hello_packet_received:: interface %lx is passive!\r\n", sptr_interface->address); return GOOD_RECEIVE; }#endif /* __OSPF_PASSIVE_INTERFACE__ */ return_type = ospf_check_hello_packet_validity (sptr_hello, sptr_interface, router_id); if (return_type != GOOD_RECEIVE) { return (return_type); } sptr_new_neighbor = ospf_extract_neighbor_information_from_hello_packet (sptr_hello, sptr_new_neighbor, sptr_interface, source_address, router_id, cryptographic_sequence_number); /* Added change as per TMS PR # 1593 To make sure the sptr_new_neighbour will not be referenced if ospf_extract_neighbour_information_from_hello_packet() failed. */ if ( sptr_new_neighbor == NULL ) { return( STOP_PROCESSING_PACKET ); } /* SPR 84312 -- Begin */ /* SPR 85432 -- Begin */ current_system_time = ospf_get_system_elapsed_time_second (); sptr_new_neighbor->last_hello = current_system_time; /* SPR 85432 -- End */ /* SPR 84312 -- End */ sptr_new_neighbor->periodic_inactivity_time_counter = 0x00000000L; /* reset inactivity timer */ sptr_new_neighbor->inactivity_timer_enabled = TRUE; ospf_examine_rest_of_hello_packet_and_generate_events_as_necessary (sptr_hello, sptr_new_neighbor, sptr_interface, size_of_packet); /* take care of OSPF_NBMA networks - send hello packet in reply to this hello if this router is not eligible to become designated * router and this hello was received from an eligible neighbor other than the current designated router and backup * designated router. This is needed to establish an initial bidirectional relationship with any potential designated router */ if ((sptr_interface->type == OSPF_NBMA) && (sptr_interface->priority == 0x0000) && (sptr_new_neighbor->priority != 0x0000) && (sptr_interface->designated_router.address != sptr_new_neighbor->address) && (sptr_interface->backup_designated_router.address != sptr_new_neighbor->address)) { ospf_send_hello (sptr_interface, sptr_new_neighbor, FALSE); } /* SPR 85432 -- Begin */ /* * If hello timer has not replied in awhile (too busy) send the hello to * the neighbor who sent us one */ if ((current_system_time - sptr_interface->last_hello_time ) >= (sptr_interface->router_dead_interval / 2)) { ospf_send_hello (sptr_interface, sptr_new_neighbor, FALSE); } /* SPR 85432 -- End */ /* build_network or build_router may have been set during the above processing of the hello packet */ ospf_generate_network_and_router_link_state_advertisements (sptr_interface); return (GOOD_RECEIVE);}/*************************************************************************** ospf_check_hello_packet_validity - validate hello packet** This routine will validate the hello packet.** <sptr_hello> Hello packet header** <sptr_interface> OSPF interface** <router_id> Router id of hello packet** RETURNS: OSPF_PACKET_STATE** ERRNO: N/A** NOMANUAL*/static enum OSPF_PACKET_STATE ospf_check_hello_packet_validity (OSPF_HELLO_HEADER *sptr_hello,OSPF_INTERFACE *sptr_interface, ULONG router_id){ OSPF_AREA_ENTRY *sptr_area =NULL; ULONG network_mask =0; USHORT hello_interval =0; ULONG router_dead_interval =0; OSPF_PRINTF_PROLOGUE (OSPF_PROLOGUE_PRINTF, "OSPF: Entering ospf_check_hello_packet_validity\r\n"); if (sptr_interface->state == OSPF_INTERFACE_IS_DOWN) { if (sptr_interface->type == OSPF_VIRTUAL_LINK) { return (OSPF_ERROR_HELLO_VIRTUAL); /* wait until the virtual neighbor is brought up by the transit area running SPF */ } else { ospf_bring_up_interface (sptr_interface); return (OSPF_ERROR_OSPF_INTERFACE_DOWN); } } /* a few validity checks */ network_mask = net_to_host_long (sptr_hello->network_mask); if ((sptr_interface->type != OSPF_VIRTUAL_LINK) && (sptr_interface->type != OSPF_POINT_TO_POINT) && (network_mask != sptr_interface->netmask)) { OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: ERROR - network mask MISMATCH in Hello packet\r\n" ); return (OSPF_ERROR_HELLO_MASK); } hello_interval = net_to_host_short (sptr_hello->hello_interval); if (hello_interval != sptr_interface->hello_interval) { OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: ERROR - hello interval MISMATCH in Hello packet\r\n" ); return (OSPF_ERROR_HELLO_TIMER); } router_dead_interval = net_to_host_long (sptr_hello->router_dead_interval); if (router_dead_interval != sptr_interface->router_dead_interval) { OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: ERROR - router dead interval MISMATCH in Hello packet\r\n" ); return (OSPF_ERROR_HELLO_ROUTER_DEAD_INTERVAL); } sptr_area = sptr_interface->sptr_area;#if !defined(__NSSA__) /* E-bit validity check - if the area is a "stub", the E-bit must be clear, otherwise the E-bit must be set */ if (((sptr_hello->options._bit.externals == TRUE) && (sptr_area->flags._bit.stub == TRUE)) || ((sptr_hello->options._bit.externals == FALSE) && (sptr_area->flags._bit.stub == FALSE))) { OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: ERROR - E-bit MISMATCH in Hello packet\r\n"); return (OSPF_ERROR_HELLO_E_BIT); }#else /* E+N-bit validity check - if the area is a "not so stubby area", the E-bit must be clear, and the N-bit must be set*/ /* - if the area is a "stub", the E-bit must be clear, otherwise the E-bit must be set */ if ((((sptr_hello->options._bit.externals == TRUE) && (sptr_area->flags._bit.stub == TRUE)) || ((sptr_hello->options._bit.externals == TRUE) && (sptr_area->flags._bit.nssa == TRUE))) || ((sptr_hello->options._bit.externals == FALSE) && (sptr_area->flags._bit.stub == FALSE) &&(sptr_area->flags._bit.nssa == FALSE))) { OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: ERROR - N|E -bit MISMATCH in Hello packet\r\n"); return (OSPF_ERROR_HELLO_E_BIT); } if (((sptr_hello->options._bit.nssa == FALSE) && (sptr_area->flags._bit.nssa == TRUE)) || ((sptr_hello->options._bit.nssa == TRUE) && (sptr_area->flags._bit.nssa == FALSE))) { OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: ERROR - N-bit MISMATCH in Hello packet\r\n"); return (OSPF_ERROR_HELLO_N_BIT); }#endif /*__NSSA__*/ if (router_id == ospf.router_id) /* check to make sure this router didn't originate the hello packet */ { OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: ERROR - Hello packet received was originated by this router\r\n" ); return (OSPF_ERROR_HELLO_ID); } return (GOOD_RECEIVE);}/*************************************************************************** ospf_extract_neighbor_information_from_hello_packet - extract neighbor information from the hello packet** This routine will process the hello packet and extract the* neighbor information.** <sptr_hello> Hello packet header** <sptr_new_neighbor> New neighbor** <sptr_interface> OSPF interface** <source_address> Source address of hello packet** <router_id> Router id of hello packet** <cryptographic_sequence_number> Cryptographic sequence number** RETURNS: OSPF_NEIGHBOR * or NULL** ERRNO: N/A** NOMANUAL*/static OSPF_NEIGHBOR *ospf_extract_neighbor_information_from_hello_packet (OSPF_HELLO_HEADER *sptr_hello,OSPF_NEIGHBOR *sptr_new_neighbor, OSPF_INTERFACE *sptr_interface,ULONG source_address,ULONG router_id,ULONG cryptographic_sequence_number){ /* SPR 81628 Begin: We also need to initialize the array which holds LS request*/ int i=0; /* SPR 81628 end */ OSPF_PRINTF_PROLOGUE (OSPF_PROLOGUE_PRINTF, "OSPF: Entering ospf_extract_neighbor_information_from_hello_packet\r\n"); switch (sptr_interface->type) { case OSPF_POINT_TO_POINT: { if (sptr_new_neighbor == NULL) { sptr_new_neighbor = sptr_interface->sptr_neighbor; if (sptr_new_neighbor == NULL) { sptr_new_neighbor = (OSPF_NEIGHBOR *) table_malloc (1, sizeof (OSPF_NEIGHBOR)); if (sptr_new_neighbor == NULL) { ospf_print_memory_error_message_and_free_buffer_if_necessary ((void *) NULL, "OSPF_NEIGHBOR"); return (NULL); } memset (sptr_new_neighbor, 0x00, sizeof (OSPF_NEIGHBOR)); ospf_set_neighbor_fields (sptr_new_neighbor, router_id, source_address, cryptographic_sequence_number, sptr_interface, sptr_hello->router_priority, sptr_hello->options._byte, OSPF_NEIGHBOR_DOWN); ospf_add_neighbor (sptr_interface, sptr_new_neighbor); } else { ospf_set_neighbor_fields (sptr_new_neighbor, router_id, source_address, cryptographic_sequence_number, sptr_interface, sptr_hello->router_priority, sptr_hello->options._byte, OSPF_NEIGHBOR_DOWN); } } break; } case OSPF_VIRTUAL_LINK: { if (sptr_interface->sptr_neighbor != NULL) { sptr_interface->sptr_neighbor->options._byte = sptr_hello->options._byte; } break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -