📄 macbrrx.c
字号:
/*
* $Log:: /OEM Source Code/Spantree/macbrr $
*
* 1 12/04/98 2:36p Release Engineer
* code cleanup, bug fixes, code style
* changes, linted, system level test
* STP v4.3.0
*
* 1 2/06/96 11:06p Ross
* Adding new version control
*/
/* $Modname: macbrrx.c$ $version: 1.38$ $date: 06/27/95$ */
/*
* $lgb$
1.0 01/05/92 ross
1.1 01/25/92 ross changed return (PACKET_HAS_NOT_BEEN_TXED) to HAS in unicast and multicast cases (first 2). This is to cover the case where a packet is not wanted by anybody (filtering case)
1.2 01/25/92 ross
1.3 01/26/92 ross
1.4 01/26/92 ross made frames_discarded and frames_forwarded an array of port_numbers
1.5 04/22/92 ross
1.6 07/30/92 ross checking in for adding broadcast packet support.
1.7 07/30/92 ross added send_broadcast_packet routine.
1.8 07/30/92 ross
1.9 07/30/92 ross
1.10 07/30/92 ross
1.11 07/31/92 ross checking in
1.12 08/05/92 ross
1.13 08/21/92 ross
1.14 08/21/92 ross
1.15 08/22/92 ross Added support for multiple instances of stp_class
1.16 11/23/92 ross changed ETHERNET_ADDRESS to MAC_ADDRESS to appear more generic (cosmetic)
1.17 01/10/93 ross adding dlci parameters for frame relay.
1.18 01/10/93 ross added frame relay function to store dlci's in the transmitted frame.
1.19 01/18/93 ross added SPANNING_TREE_FILTERING #ifdef.
1.20 01/20/93 ross
1.21 01/23/93 ross changed store_dlci to use port_number.
1.22 01/24/93 ross
1.23 01/25/93 ross moved stp_filter routine.
1.24 01/29/93 ross delete reference to store_dlci and moved it into vmacbstr.h
1.25 01/29/93 ross changed constants in macbrrx.c and macbrdb.c to better match snmp, fixed frame relay bug.
1.26 01/30/93 ross delete references to stp dlci
1.27 07/16/93 ross added some mib statistics
1.28 07/23/93 ross added mtu check and statistic. Courtesy of Teresa.
1.29 10/07/93 ross accidently removed frame relay header stuff.
1.30 10/28/93 ross added parameter to convert tr to ethernet header.
1.31 11/29/93 ross delete line that have number_of_packets forwarded incremented twice.
1.32 01/28/94 ross had frame relay header subtractions in for test, that should have been removed.
1.33 02/02/94 ross took out frame relay header and fixed big endian problems. Courtesy of Rick.
1.34 02/25/94 ross added multi port broadcast support for wans.
1.35 05/09/94 ross added changes for configuring forwarding state for SRT
1.36 06/15/94 ross cosmetic changes and snmp access routines.
1.37 03/31/95 ross Changes for new rwutils library.
1.38 06/27/95 ross fixed allocation problem.
* $lge$
*/
/************************************************************************/
/* Copyright (C) 1989-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 <stdlib.h>
#include <string.h>
#include "macbridg.h"
/****************************************************************************/
static enum RX_PACKET_STATE send_broadcast_packet (USHORT rx_port_number,ETHERNET_BUFFER *sptr_rx_buffer,USHORT size_of_buffer);
static enum RX_PACKET_STATE send_mac_bridge_packet (USHORT rx_port_number,USHORT tx_port_number,ETHERNET_BUFFER *sptr_rx_buffer,
USHORT size_of_packet,void (*fptr_tx_completion) (USHORT port_number,void *sptr_ethernet_packet));
static void send_mac_bridge_completion_routine (USHORT port_number,void *sptr_ethernet_packet);
MAC_ADDRESS broadcast_address = {0xffffffffL,0xffff};
/****************************************************************************/
enum RX_PACKET_STATE mac_bridge_rx (USHORT port_number,ETHERNET_BUFFER *sptr_rx_buffer,USHORT size_of_buffer)
{
STP_PORT_CLASS *sptr_port;
enum FD_TABLE_ENTRY_TYPE forwarding_status;
USHORT destination_mac_address_ushort;
ULONG destination_mac_address_ulong;
FILTERING_DATABASE_ENTRY *sptr_database_entry;
enum RX_PACKET_STATE return_rx_state;
++port_number;
sptr_port = &stp_class.port[port_number];
if (sptr_port->state == DISABLED)
{
return (PACKET_NOT_RECOGNIZED);
}
#if defined (DEBUG)
display_spanning_tree_packet (port_number,sptr_rx_buffer,size_of_buffer);
#endif
if (sptr_port->token_ring == TRUE)
{
convert_token_ring_header_to_ethernet (sptr_rx_buffer,size_of_buffer);
}
destination_mac_address_ushort = sptr_rx_buffer->mac_header.destination_address._ushort;
destination_mac_address_ulong = sptr_rx_buffer->mac_header.destination_address._ulong;
#if defined (SPANNING_TREE_FILTERING)
if (stp_filter (port_number,sptr_rx_buffer) == TRUE)
{
++stp_class.port[port_number].number_of_rx_frames_filtered;
return (PACKET_RECOGNIZED_BUT_NOT_FORWARDED);
}
#endif
++stp_class.port[port_number].dot1dTpPortInFrames;
#if defined (SIMPLE_BRIDGE)
sptr_port->state = FORWARDING; /* uncomment to bypass spanning tree */
--port_number;
send_packet (port_number ^ 0x01,sptr_rx_buffer,size_of_buffer,TRUE,TRUE,NULL); /* set port number back to zero based */
return (PACKET_NOT_RECOGNIZED);
#endif
if ((stp_class.port[port_number].token_ring == FALSE) &&
(destination_mac_address_ushort == bridge_group_address._ushort &&
destination_mac_address_ulong == bridge_group_address._ulong))
{
if (stp_class.stp_algorithm_enabled == TRUE)
{
little_endianize_packet ((BRIDGE_CONFIGURATION_BPDU *) sptr_rx_buffer);
bridge_protocol_message_received (port_number,(BRIDGE_CONFIGURATION_BPDU *) sptr_rx_buffer);
}
return (PACKET_RECOGNIZED_BUT_NOT_FORWARDED);
}
else if ((stp_class.port[port_number].token_ring == TRUE) &&
(destination_mac_address_ushort == token_ring_bridge_group_address._ushort &&
destination_mac_address_ulong == token_ring_bridge_group_address._ulong))
{
little_endianize_packet ((BRIDGE_CONFIGURATION_BPDU *) sptr_rx_buffer);
bridge_protocol_message_received (port_number,(BRIDGE_CONFIGURATION_BPDU *) sptr_rx_buffer);
return (PACKET_RECOGNIZED_BUT_NOT_FORWARDED);
}
else if (stp_class.mac_bridge_enabled == TRUE &&
(sptr_port->state == LEARNING || sptr_port->state == FORWARDING))
{
if ((sptr_rx_buffer->mac_header.source_address._ulong & MULTICAST_BROADCAST_MASK_BIT) == NO_MULTICAST_OR_BROADCAST)
{
forwarding_status = add_entry_to_filtering_database (sptr_rx_buffer->mac_header.source_address._ushort,
sptr_rx_buffer->mac_header.source_address._ulong,port_number,DELETE_ENTRY_ON_TIMEOUT);
}
else
forwarding_status = NOT_IN_DATABASE;
return_rx_state = PACKET_NOT_RECOGNIZED;
if (sptr_port->state == FORWARDING)
{
if (forwarding_status != PERMANENT_TABLE_ENTRY)
{
if (destination_mac_address_ushort == 0xffff && destination_mac_address_ulong == 0xffffffffL) /* broadcast */
{
return_rx_state = send_broadcast_packet (port_number,sptr_rx_buffer,size_of_buffer);
}
else
{
sptr_database_entry = get_destination_address_database_entry (destination_mac_address_ushort,
destination_mac_address_ulong);
if (sptr_database_entry == NULL)
{
return_rx_state = send_broadcast_packet (port_number,sptr_rx_buffer,size_of_buffer);
}
else /* entry found in table, send it to known port */
{
if (sptr_database_entry->port_number != port_number &&
stp_class.port[sptr_database_entry->port_number].state == FORWARDING)
{
/* set port number back to zero based */
return_rx_state = send_mac_bridge_packet (port_number,sptr_database_entry->port_number,sptr_rx_buffer,
size_of_buffer,NULL);
}
}
}
return (return_rx_state);
}
else
{
++stp_class.port[port_number].number_of_frames_discarded;
}
}
}
return (PACKET_NOT_RECOGNIZED);
}
/****************************************************************************/
static enum RX_PACKET_STATE send_broadcast_packet (USHORT rx_port_number,ETHERNET_BUFFER *sptr_rx_buffer,USHORT size_of_buffer)
{
USHORT broadcast_port_number;
enum RX_PACKET_STATE return_value;
/* send to all ports */
return_value = PACKET_NOT_RECOGNIZED;
if (lsl_control (SET_DEVICE_DRIVER_BUFFER_REFERENCE_COUNT,sptr_rx_buffer,stp_class.number_of_spanning_tree_ports) == FAIL)
{
return (PACKET_NOT_RECOGNIZED);
}
for (broadcast_port_number = 0x0001; broadcast_port_number < stp_class.number_of_spanning_tree_ports + 1;
++broadcast_port_number)
{
if (broadcast_port_number != rx_port_number && stp_class.port[broadcast_port_number].state == FORWARDING)
{
return_value = send_mac_bridge_packet (rx_port_number,broadcast_port_number,sptr_rx_buffer,size_of_buffer,
send_mac_bridge_completion_routine);
}
else
{
lsl_control (DECREMENT_DEVICE_DRIVER_BUFFER_REFERENCE_COUNT,sptr_rx_buffer);
}
}
return (return_value);
}
/****************************************************************************/
static void send_mac_bridge_completion_routine (USHORT port_number,void *sptr_txed_packet)
{
PARAMETER_NOT_USED (port_number);
if (lsl_control (DECREMENT_DEVICE_DRIVER_BUFFER_REFERENCE_COUNT,sptr_txed_packet) == 0x0000)
{
lsl_control (RETURN_DEVICE_DRIVER_RX_BUFFER,sptr_txed_packet);
}
}
/****************************************************************************/
static enum RX_PACKET_STATE send_mac_bridge_packet (USHORT rx_port_number,USHORT tx_port_number,ETHERNET_BUFFER *sptr_rx_buffer,
USHORT size_of_packet,void (*fptr_tx_completion) (USHORT port_number,void *sptr_ethernet_packet))
{
if (stp_class.port[tx_port_number].token_ring == TRUE)
{
convert_ethernet_header_to_token_ring ((ETHERNET_HEADER *) sptr_rx_buffer);
}
else if (stp_class.port[tx_port_number].wan_port == TRUE && stp_class.port[rx_port_number].token_ring == TRUE)
{
convert_ethernet_header_to_token_ring ((ETHERNET_HEADER *) sptr_rx_buffer);
}
#if defined (DEBUG)
display_spanning_tree_packet (tx_port_number,sptr_rx_buffer,size_of_packet);
#endif
if (size_of_packet > stp_class.port[tx_port_number].maximum_packet_size)
{
++stp_class.port[tx_port_number].dot1dBasePortMtuExceededDiscards;
return (PACKET_NOT_RECOGNIZED);
}
else
{
++stp_class.port[tx_port_number].number_of_frames_forwarded;
}
if (fptr_tx_completion == NULL)
{
send_packet (stp_class.stack_id,(USHORT) (tx_port_number - 1),sptr_rx_buffer,
(USHORT) (size_of_packet + sizeof (CRC)),TRUE,TRUE,fptr_tx_completion);
}
else
{
send_packet (stp_class.stack_id,(USHORT) (tx_port_number - 1),sptr_rx_buffer,
(USHORT) (size_of_packet + sizeof (CRC)),TRUE,FALSE,fptr_tx_completion);
}
return (PACKET_RECOGNIZED_AND_FORWARDED);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -