⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macbrspn.c

📁 以太网交换机协议平台stp协议的设计与实现源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
		else
			{
			stp_printf (STP_ALGORITHM_PRINTF,"STP: blocking port %02x\n\r",port_number);

			stp_class.port[port_number].configuration_pending = FALSE;
			stp_class.port[port_number].topology_change_acknowledgement = FALSE;

			make_blocking (port_number);
			}
		}
}
/****************************************************************************/
static void make_forwarding (USHORT port_number)
{
	if (stp_class.port[port_number].state == BLOCKING)
		{
		stp_class.port[port_number].state = LISTENING;

		stp_printf (STP_ALGORITHM_PRINTF,"STP: listening started %02x\n\r",port_number);

		set_timer (&stp_class.port[port_number].forward_delay,START_TIMER);
		}
}
/****************************************************************************/
static void make_blocking (USHORT port_number)
{
	if (stp_class.port[port_number].state != DISABLED &&
		stp_class.port[port_number].state != BLOCKING)
		{
		if (stp_class.port[port_number].state == FORWARDING || stp_class.port[port_number].state == LEARNING)
			{
			topology_change_detection ();
			}

		stp_printf (STP_ALGORITHM_PRINTF,"STP: blocking started %02x\n\r",port_number);

		stp_class.port[port_number].state = BLOCKING;

		set_timer  (&stp_class.port[port_number].forward_delay,STOP_TIMER);
		}
}
/****************************************************************************/
void topology_change_detection (void)
{
	stp_printf (STP_ALGORITHM_PRINTF,"STP: topology change detection\n\r");

	if (stp_class.fptr_topology_change_detection != NULL)
		{
		(*stp_class.fptr_topology_change_detection) ();
		}

	stp_class.this_bridge.aging_time_for_fd = FORWARD_DELAY_TIME / TIMER_GRANULARITY;

	if (root_bridge () == TRUE)
		{
		stp_class.this_bridge.topology_change = TRUE;

		set_timer (&stp_class.topology_change_timer,START_TIMER);
		}
	else if (stp_class.this_bridge.topology_change_detected == FALSE)
		{
		transmit_topology_change_notification ();

		set_timer (&stp_class.topology_change_notification_timer,START_TIMER);
		}

	stp_class.this_bridge.topology_change_detected = TRUE;

	/* below are for snmp */

	++stp_class.this_bridge.number_of_topology_changes;

	stp_class.this_bridge.timer_topology_tick = timer_ulong;
}
/****************************************************************************/
static void topology_change_acknowledgement (void)
{
	stp_printf (STP_ALGORITHM_PRINTF,"STP: topology change acknowledgement  \n\r");

	stp_class.this_bridge.topology_change_detected = FALSE;
	stp_class.this_bridge.topology_change = FALSE;

	set_timer (&stp_class.topology_change_notification_timer,STOP_TIMER);
}
/****************************************************************************/
static void acknowledge_topology_change (USHORT port_number)
{
	stp_printf (STP_ALGORITHM_PRINTF,"STP: acknowledgement topology change %02x\n\r",port_number);

	stp_class.port[port_number].topology_change_acknowledgement = TRUE;
	
	transmit_configuration (port_number);
}
/****************************************************************************/
void bridge_protocol_message_received (USHORT port_number,BRIDGE_CONFIGURATION_BPDU *sptr_bridge_configuration_BPDU)
{
	enum	BOOLEAN	previous_bridge_state;

	/* BPDUs with invalid values for protocol ID, version ID, type, and flags are ignored.
		ANSI/IEEE Std. 802.1d, section 5.3.1	*/
	if (check_for_invalid_bpdu_parameters (sptr_bridge_configuration_BPDU) == TRUE)
		{
		return;
		}

	previous_bridge_state = root_bridge ();

	if (sptr_bridge_configuration_BPDU->type == CONFIGURATION)
		{
		if (stp_class.port[port_number].state != DISABLED)
			{
			stp_printf (STP_ALGORITHM_PRINTF,"STP: Hello message received %02x\n\r",port_number);

			if (supercedes_port_info (port_number,sptr_bridge_configuration_BPDU) == TRUE)
				{
				record_configuration_port_information (port_number,sptr_bridge_configuration_BPDU);

				configuration_update ();

				port_state_selection ();

				if ((root_bridge () == FALSE) && previous_bridge_state)
					{
					set_timer (&stp_class.hello_timer,STOP_TIMER);

					if (stp_class.this_bridge.topology_change_detected == TRUE)
						{
						set_timer (&stp_class.topology_change_timer,STOP_TIMER);

						transmit_topology_change_notification ();

						set_timer (&stp_class.topology_change_notification_timer,START_TIMER);
						}
					}

				if (port_number == stp_class.this_bridge.root_port_id.number)
					{
					record_hello_timeout_values (sptr_bridge_configuration_BPDU);

					configuration_BPDU_generation ();

					if (sptr_bridge_configuration_BPDU->flags.topology_change_acknowledgement == TRUE)
						topology_change_acknowledgement ();
					}
				}
			else if (designated_port (port_number) == TRUE)
				{
				reply (port_number);
				}
			}
		}
	else if (sptr_bridge_configuration_BPDU->type == (enum BPDU_TYPE) TOPOLOGY_CHANGE)
		{
		stp_printf (STP_ALGORITHM_PRINTF,"STP: topology change received %02x\n\r",port_number);

		if (stp_class.port[port_number].state != DISABLED)
			{
			if (designated_port (port_number) == TRUE)
				{
				topology_change_detection ();

				acknowledge_topology_change (port_number);
				}
			}
		}
}
/****************************************************************************/
static enum BOOLEAN supercedes_port_info (USHORT port_number,BRIDGE_CONFIGURATION_BPDU *sptr_bridge_configuration_BPDU)
{
	enum SORT_RETURN sort_return_value;

	/* all return (TRUE)s cause the configuration bpdu received to update the current root bridge information in
		stp_class.port[port_number] */

	/* check the designated root */

	sort_return_value = compare_identifiers (&sptr_bridge_configuration_BPDU->root_id,
		&stp_class.port[port_number].designated_root_id);

	if (sort_return_value == LESS_THAN)
		{
		return (TRUE); /* root value is better in new config bpdu */
		}
	else if (sort_return_value == GREATER_THAN)
		{
		return (FALSE); /* root value is worse in new config bpdu */
		}

	if (sptr_bridge_configuration_BPDU->root_path_cost < stp_class.port[port_number].designated_root_path_cost)
		{
		return (TRUE); /* root path cost is better in new config bpdu */
		}
	else if (sptr_bridge_configuration_BPDU->root_path_cost > stp_class.port[port_number].designated_root_path_cost)
		{
		return (FALSE); /* root path cost is worse in new config bpdu */
		}

	/* check the designated bridge for the port */

	sort_return_value = compare_identifiers (&sptr_bridge_configuration_BPDU->bridge_id,
		&stp_class.port[port_number].designated_bridge_id);

	if (sort_return_value == LESS_THAN)
		{
		return (TRUE); /* bridge value is better in new config bpdu */
		}
	else if (sort_return_value == GREATER_THAN)
		{
		return (FALSE); /* bridge value is worse in new config bpdu */
		}

	/* check to see if I am not the designated bridge for the port */

	if (compare_identifiers (&sptr_bridge_configuration_BPDU->bridge_id,&stp_class.this_bridge.bridge_id) != EQUAL_TO)
		{
		return (TRUE); /* bridge (myself) receiving the BPDU is not the designated bridge for the port */
		}

 	if (sptr_bridge_configuration_BPDU->port_id.number <= stp_class.port[port_number].designated_port_id.number)
		{
		return (TRUE); /* port id is the same or better in new config bpdu */
		}
	else
		{
	  	return (FALSE);
		}
}
/****************************************************************************/
static enum BOOLEAN check_for_invalid_bpdu_parameters (BRIDGE_CONFIGURATION_BPDU *sptr_bridge_configuration_BPDU)
{
	/*Check BPDU for invalid values in protocol ID, version ID, type, and flags.*/
	USHORT protocol_ID_value;
	BYTE version_or_type_or_flags_value;
	BYTE invalid_version_or_type_or_flags_minimum_value;
	BYTE invalid_version_or_type_or_flags_maximum_value;

	protocol_ID_value = sptr_bridge_configuration_BPDU->protocol_ID;

	if ((protocol_ID_value == swap (0x0001) ) || ( protocol_ID_value == 0xFFFF ) )
		{
		return (TRUE);
		}

	version_or_type_or_flags_value = sptr_bridge_configuration_BPDU->protocol_version_ID;

	invalid_version_or_type_or_flags_minimum_value = 0x01;
	invalid_version_or_type_or_flags_maximum_value = 0xFF;

	if ((version_or_type_or_flags_value == invalid_version_or_type_or_flags_minimum_value) ||
	    (version_or_type_or_flags_value == invalid_version_or_type_or_flags_maximum_value) )
		{
		return (TRUE);
		}

	version_or_type_or_flags_value = sptr_bridge_configuration_BPDU->type;

	if ((version_or_type_or_flags_value == invalid_version_or_type_or_flags_minimum_value) ||
	    (version_or_type_or_flags_value == invalid_version_or_type_or_flags_maximum_value) )
		{
		return (TRUE);
		}

	version_or_type_or_flags_value = sptr_bridge_configuration_BPDU->flags.not_used;

	invalid_version_or_type_or_flags_maximum_value = 0x00;

	if ((version_or_type_or_flags_value != invalid_version_or_type_or_flags_maximum_value))
		{
		return (TRUE);
		}

	return (FALSE);
}

/****************************************************************************/
static void set_stp_port_default_values (USHORT port_number)
{

	if (stp_class.port[port_number].maximum_packet_size == 0x0000 )
		{

		stp_class.port[port_number].maximum_packet_size = DEFAULT_PORT_MAXIMUM_FRAME_SIZE;

		}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -