📄 igmp_router_state.c
字号:
/*
$Log:: /OEM Source Code/igmp/igmp_router_state.c $
*
* 1 4/23/98 9:53p Release Engineer
* Initial release
* IGMP v4.1.0
*/
/************************************************************************/
/* Copyright (C) 1997-1998 RouterWare, Inc. */
/* Unpublished - rights reserved under the Copyright Laws of the */
/* United States. Use, duplication, or disclosure by the */
/* Government is subject to restrictions as set forth in */
/* subparagraph (c)(1)(ii) of the Rights in Technical Data and */
/* Computer Software clause at 252.227-7013. */
/* RouterWare, Inc., 3961 MacArthur Blvd. Suite 212, Newport Beach, CA */
/************************************************************************/
#include "igmp.h"
/********************************************************************************************/
static void igmp_router_process_querier_mode_group_state_transition (UINT port, ULONG group_ip_address, enum IGMP_ROUTER_GROUP_EVENT event);
static void igmp_router_process_non_querier_mode_group_state_transition (UINT port, ULONG group_ip_address, enum IGMP_ROUTER_GROUP_EVENT event);
static void igmp_router_manage_group_timers_and_state (UINT port, enum IGMP_ROUTER_PORT_STATE old_state_of_port,
enum IGMP_ROUTER_PORT_STATE new_state_of_port);
static enum BOOLEAN igmp_router_port_state_is_valid (enum IGMP_ROUTER_PORT_STATE state);
static enum BOOLEAN igmp_router_group_state_is_valid (enum IGMP_ROUTER_GROUP_STATE state);
/********************************************************************************************/
void igmp_process_router_port_state_transition (UINT port, ULONG group_ip_address,enum IGMP_ROUTER_PORT_EVENT event)
{
enum IGMP_ROUTER_PORT_STATE state;
enum IGMP_ROUTER_PORT_STATE next_state;
state = igmp.port_table[port].router_port.state;
next_state = (enum IGMP_ROUTER_PORT_STATE) igmp_router_port_state_transition_table [state][event].next_state;
if (igmp_router_port_state_is_valid (next_state) == FALSE)
{
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: Event: %s forces port %u from Current state: %s to UNKNOWN state.\n",
igmp_router_port_event_string [event], port,
igmp_router_port_state_string [state]);
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: No actions will be taken, state would not be changed.\n");
return ;
}
IGMP_PROTOCOL_TRACE (IGMP_TRACE, "IGMP Router: Processing state transition for port %u.\n", port);
IGMP_PROTOCOL_TRACE (IGMP_TRACE, "IGMP Router: Event: %s Current state: %s Next state: %s.\n",
igmp_router_port_event_string [event],
igmp_router_port_state_string [state],
igmp_router_port_state_string [next_state]);
IGMP_PROTOCOL_TRACE (IGMP_TRACE, "IGMP Router: Port state when event occured: %s.\n",
igmp_router_port_state_string [igmp.port_table[port].router_port.state]);
if (igmp_router_port_state_transition_table[state][event].fptr_action_1 != NULL)
{
igmp_router_port_state_transition_table[state][event].fptr_action_1 (port,group_ip_address);
}
if (igmp_router_port_state_transition_table[state][event].fptr_action_2 != NULL)
{
igmp_router_port_state_transition_table[state][event].fptr_action_2 (port,group_ip_address);
}
if (igmp_router_port_state_transition_table[state][event].fptr_action_3 != NULL)
{
igmp_router_port_state_transition_table[state][event].fptr_action_3 (port,group_ip_address);
}
igmp.port_table[port].router_port.state = next_state;
if (state != next_state)
{
igmp_router_manage_group_timers_and_state (port, state, next_state);
}
}
/********************************************************************************************/
static void igmp_router_process_non_querier_mode_group_state_transition (UINT port, ULONG group_ip_address, enum IGMP_ROUTER_GROUP_EVENT event)
{
enum IGMP_ROUTER_GROUP_STATE state;
enum IGMP_ROUTER_GROUP_STATE next_state;
IGMP_GROUP_CLASS *sptr_matching_group_node;
char ip_address[IP_ADDRESS_PRINT_BUFFER_SIZE];
/* note that this group must have been added earlier by igmp_router_process_received_message () */
sptr_matching_group_node = igmp_get_matching_group_node_on_port (group_ip_address, port);
if (sptr_matching_group_node == NULL)
{
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: Unable to locate group %s on port %u for state transition on event %s.\n",
convert_ip_address_to_dot_format (&ip_address[0], group_ip_address), port,
igmp_router_group_event_string [event]);
return;
}
state = sptr_matching_group_node->router_group.state;
next_state = igmp_router_non_querier_mode_group_state_transition_table [state][event].next_state;
if (igmp_router_group_state_is_valid (next_state) == FALSE)
{
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: Event: %s forces group %s on port %u from Current state: %s to UNKNOWN next state.\n",
igmp_router_group_event_string [event],
convert_ip_address_to_dot_format (&ip_address[0], group_ip_address), port,
igmp_router_group_state_string [state],
igmp_router_group_state_string [next_state]);
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: No actions will be taken, state would not be changed.\n");
return ;
}
IGMP_PROTOCOL_TRACE (IGMP_TRACE, "IGMP Router: Processing state transition for group %s on port %u.\n",
convert_ip_address_to_dot_format (&ip_address[0],group_ip_address), port);
IGMP_PROTOCOL_TRACE (IGMP_TRACE, "IGMP Router: Event: %s Current state: %s Next state: %s.\n",
igmp_router_group_event_string [event],
igmp_router_group_state_string [state],
igmp_router_group_state_string [next_state]);
IGMP_PROTOCOL_TRACE (IGMP_TRACE, "IGMP Router: Port state when event occured: %s.\n",
igmp_router_port_state_string [igmp.port_table[port].router_port.state]);
if (igmp_router_non_querier_mode_group_state_transition_table[state][event].fptr_action_1 != NULL)
{
igmp_router_non_querier_mode_group_state_transition_table[state][event].fptr_action_1 (port,group_ip_address);
}
if (igmp_router_non_querier_mode_group_state_transition_table[state][event].fptr_action_2 != NULL)
{
igmp_router_non_querier_mode_group_state_transition_table[state][event].fptr_action_2 (port,group_ip_address);
}
if (igmp_router_non_querier_mode_group_state_transition_table[state][event].fptr_action_3 != NULL)
{
igmp_router_non_querier_mode_group_state_transition_table[state][event].fptr_action_3 (port,group_ip_address);
}
sptr_matching_group_node->router_group.state = next_state;
}
/********************************************************************************************/
static void igmp_router_process_querier_mode_group_state_transition (UINT port, ULONG group_ip_address, enum IGMP_ROUTER_GROUP_EVENT event)
{
enum IGMP_ROUTER_GROUP_STATE state;
enum IGMP_ROUTER_GROUP_STATE next_state;
IGMP_GROUP_CLASS *sptr_matching_group_node;
char ip_address[IP_ADDRESS_PRINT_BUFFER_SIZE];
sptr_matching_group_node = igmp_get_matching_group_node_on_port (group_ip_address, port);
if (sptr_matching_group_node == NULL)
{
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: Unable to locate group %s on port %u for state transition on event %s.\n",
convert_ip_address_to_dot_format (&ip_address[0], group_ip_address), port,
igmp_router_group_event_string [event]);
return;
}
state = sptr_matching_group_node->router_group.state;
next_state = igmp_router_querier_mode_group_state_transition_table [state][event].next_state;
if (igmp_router_group_state_is_valid (next_state) == FALSE)
{
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: Event: %s forces group %s on port %u from Current state: %s to UNKNOWN next state.\n",
igmp_router_group_event_string [event],
convert_ip_address_to_dot_format (&ip_address[0], group_ip_address), port,
igmp_router_group_state_string [state],
igmp_router_group_state_string [next_state]);
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: No actions will be taken, state would not be changed.\n");
return ;
}
IGMP_PROTOCOL_TRACE (IGMP_TRACE, "IGMP Router: Processing state transition for group %s on port %u.\n",
convert_ip_address_to_dot_format (&ip_address[0],group_ip_address), port);
IGMP_PROTOCOL_TRACE (IGMP_TRACE, "IGMP Router: Event: %s Current state: %s Next state: %s.\n",
igmp_router_group_event_string [event],
igmp_router_group_state_string [state],
igmp_router_group_state_string [next_state]);
IGMP_PROTOCOL_TRACE (IGMP_TRACE, "IGMP Router: Port state when event occured: %s.\n",
igmp_router_port_state_string [igmp.port_table[port].router_port.state]);
if (igmp_router_querier_mode_group_state_transition_table[state][event].fptr_action_1 != NULL)
{
igmp_router_querier_mode_group_state_transition_table[state][event].fptr_action_1 (port,group_ip_address);
}
if (igmp_router_querier_mode_group_state_transition_table[state][event].fptr_action_2 != NULL)
{
igmp_router_querier_mode_group_state_transition_table[state][event].fptr_action_2 (port,group_ip_address);
}
if (igmp_router_querier_mode_group_state_transition_table[state][event].fptr_action_3 != NULL)
{
igmp_router_querier_mode_group_state_transition_table[state][event].fptr_action_3 (port,group_ip_address);
}
sptr_matching_group_node->router_group.state = next_state;
}
/********************************************************************************************/
void igmp_process_router_group_state_transition (UINT port, ULONG group_ip_address, enum IGMP_ROUTER_GROUP_EVENT event)
{
char ip_address[IP_ADDRESS_PRINT_BUFFER_SIZE];
switch (igmp.port_table[port].router_port.state)
{
case IGMP_ROUTER_PORT_QUERIER_STATE:
igmp_router_process_querier_mode_group_state_transition (port,group_ip_address,event);
break;
case IGMP_ROUTER_PORT_NON_QUERIER_STATE:
igmp_router_process_non_querier_mode_group_state_transition (port,group_ip_address,event);
break;
default:
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: Port %u in UNKNOWN state.\n", port);
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: Unable to process state transition for group %s on port %u.\n",
convert_ip_address_to_dot_format (&ip_address[0],group_ip_address), port);
break;
}
}
/********************************************************************************************/
void igmp_router_start_general_query_timer (UINT port, ULONG group_ip_address)
{
PARAMETER_NOT_USED (group_ip_address);
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: Starting general query timer on port %u.\n", port);
if (igmp.port_table[port].router_port.initializing != TRUE)
{
igmp_enable_timer (&igmp.port_table[port].router_port.general_query_timer, igmp.port_table[port].router_port.general_query_interval);
}
else
{
igmp.port_table[port].router_port.startup_query_interval = igmp.port_table[port].router_port.general_query_interval / 4;
igmp_enable_timer (&igmp.port_table[port].router_port.general_query_timer, igmp.port_table[port].router_port.startup_query_interval);
}
}
/********************************************************************************************/
void igmp_router_start_other_querier_present_timer (UINT port, ULONG group_ip_address)
{
UINT expiry_time;
PARAMETER_NOT_USED (group_ip_address);
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: Starting other querier present timer on port %u.\n", port);
expiry_time = ((igmp.port_table[port].robustness * igmp.port_table[port].router_port.general_query_interval) +
igmp.port_table[port].router_port.general_query_max_response_time/2);
igmp.port_table[port].router_port.other_querier_present_timeout = expiry_time;
igmp_enable_timer (&igmp.port_table[port].router_port.other_querier_present_timer, expiry_time);
}
/********************************************************************************************/
void igmp_router_notify_routing_of_group_addition (UINT port, ULONG group_ip_address)
{
char ip_address[IP_ADDRESS_PRINT_BUFFER_SIZE];
MCAST_SOURCE_GROUP_PAIR source_group_pair;
IGMP_PROTOCOL_ALARM_TRACE (IGMP_ALARM_TRACE, "IGMP Router: Notifying routing for adding group %s on port %u.\n",
convert_ip_address_to_dot_format (&ip_address[0], group_ip_address), port);
source_group_pair.source_address = 0x00000000L;
source_group_pair.group_address = group_ip_address;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -