26#include "Ethernet_enum.h"
27#include "../Firewall/Firewall.h"
29#define ETHERNET_FRAME_HEADER_LEN 26
31NETSIM_ID find_forward_interface(ptrETH_LAN lan, NetSim_PACKET* packet)
33#pragma warning(disable:4189)
34 PNETSIM_MACADDRESS src = packet->pstruMacData->szSourceMac;
35#pragma warning(default:4189)
36 PNETSIM_MACADDRESS dest = packet->pstruMacData->szDestMac;
37 ptrSWITCHTABLE table = SWITCHTABLE_FIND(lan, dest);
38 return table ? table->outPort : 0;
41void send_to_phy(NETSIM_ID d, NETSIM_ID in, NetSim_PACKET* packet,
double time)
43 NetSim_EVENTDETAILS pevent;
44 memset(&pevent, 0,
sizeof pevent);
45 pevent.dEventTime = time;
46 pevent.dPacketSize = packet->pstruMacData->dPacketSize;
47 if (packet->pstruAppData)
49 pevent.nApplicationId = packet->pstruAppData->nApplicationId;
50 pevent.nSegmentId = packet->pstruAppData->nSegmentId;
53 pevent.nDeviceType = DEVICE_TYPE(d);
54 pevent.nEventType = PHYSICAL_OUT_EVENT;
55 pevent.nInterfaceId = in;
56 pevent.nPacketId = packet->nPacketId;
57 pevent.nProtocolId = MAC_PROTOCOL_IEEE802_3;
58 pevent.pPacket = packet;
62static void add_mac_header(NetSim_PACKET* packet,
double time)
64 packet->pstruMacData->dPayload = packet->pstruNetworkData->dPacketSize;
65 packet->pstruMacData->dOverhead = ETHERNET_FRAME_HEADER_LEN;
66 packet->pstruMacData->dPacketSize = packet->pstruMacData->dPayload +
67 packet->pstruMacData->dOverhead;
69 packet->pstruMacData->dArrivalTime = time;
70 packet->pstruMacData->dEndTime = time;
71 packet->pstruMacData->dStartTime = time;
73 packet->pstruMacData->nMACProtocol = MAC_PROTOCOL_IEEE802_3;
76static int packet_arrive_from_network_layer()
78 NETSIM_ID d = pstruEventDetails->nDeviceId;
79 NETSIM_ID in = pstruEventDetails->nInterfaceId;
80 double time = pstruEventDetails->dEventTime;
82 NetSim_PACKET* packet = fn_NetSim_Packet_GetPacketFromBuffer(DEVICE_ACCESSBUFFER(d, in), 1);
85 UINT16 vlanId = eth_get_incoming_vlanid(packet, d);
86 NETSIM_ID incoming = eth_get_incoming_port(packet, d);
87 clear_eth_incoming(packet);
91 vlan_macout_forward_packet(d, in, vlanId, incoming, packet, time);
93 packet = fn_NetSim_Packet_GetPacketFromBuffer(DEVICE_ACCESSBUFFER(d, in), 1);
98 ptrETH_LAN lan = GET_ETH_LAN(d, in, 0);
99 if (lan->interfaceCount > 1)
101 out = find_forward_interface(lan, packet);
105 add_mac_header(packet, time);
108 if (fn_NetSim_MAC_Firewall(d, out, packet, ACLTYPE_OUTBOUND) == ACLACTION_PERMIT)
110 clear_eth_incoming(packet);
111 send_to_phy(d, out, packet, time);
114 fn_NetSim_Packet_FreePacket(packet);
119 for (j = 0; j < lan->interfaceCount; j++)
121 if (lan->ethIfVar[j]->portState == PORTSTATE_BLOCKING)
124 NetSim_PACKET* p = fn_NetSim_Packet_CopyPacket(packet);
125 if (fn_NetSim_MAC_Firewall(d, lan->ethIfVar[j]->interfaceId, p, ACLTYPE_OUTBOUND) == ACLACTION_PERMIT &&
126 (lan->ethIfVar[j]->interfaceId != incoming || lan->switchingTechnique == SWITCHINGTECHNIQUE_NULL))
128 clear_eth_incoming(p);
129 send_to_phy(d, lan->ethIfVar[j]->interfaceId, p, time);
132 fn_NetSim_Packet_FreePacket(p);
135 vlan_forward_to_all_trunk(d, packet, lan, time);
136 fn_NetSim_Packet_FreePacket(packet);
140 packet = fn_NetSim_Packet_GetPacketFromBuffer(DEVICE_ACCESSBUFFER(d, in), 1);
145int fn_NetSim_Ethernet_HandleMacOut()
147 switch (pstruEventDetails->nSubEventType)
150 return packet_arrive_from_network_layer();
152 case SEND_CONFIG_BPDU:
153 return multicast_config_bpdu();
155 fnNetSimError(
"Unknown subevent %d for Ethernet in %s",
156 pstruEventDetails->nSubEventType,
162static bool validate_mac_frame(ptrETH_LAN lan, PNETSIM_MACADDRESS mac)
164 if (lan->ispromiscuousMode)
167 if (isBroadcastMAC(mac))
170 if (isMulticastMAC(mac))
173 if (lan->switchingTechnique)
177 for (i = 0; i < lan->interfaceCount; i++)
179 ptrETH_IF inter = lan->ethIfVar[i];
180 PNETSIM_MACADDRESS m = inter->macAddress;
181 if (!MAC_COMPARE(m, mac))
187void check_move_frame_up(NETSIM_ID d,
190 NetSim_PACKET* packet,
193 PNETSIM_MACADDRESS dest = packet->pstruMacData->szDestMac;
194 bool isforme = validate_mac_frame(lan, dest);
197 free_eth_hdr(packet);
198 NetSim_EVENTDETAILS pevent;
199 memset(&pevent, 0,
sizeof pevent);
200 pevent.dEventTime = time;
201 pevent.dPacketSize = packet->pstruNetworkData->dPacketSize;
202 if (packet->pstruAppData)
204 pevent.nApplicationId = packet->pstruAppData->nApplicationId;
205 pevent.nSegmentId = packet->pstruAppData->nSegmentId;
207 pevent.nDeviceId = d;
208 pevent.nDeviceType = DEVICE_TYPE(d);
209 pevent.nEventType = NETWORK_IN_EVENT;
210 pevent.nInterfaceId = in;
211 pevent.nPacketId = packet->nPacketId;
212 pevent.nProtocolId = NW_PROTOCOL_IPV4;
213 pevent.pPacket = packet;
214 fnpAddEvent(&pevent);
218 fn_NetSim_Packet_FreePacket(packet);
219 pstruEventDetails->pPacket = NULL;
223static void forward_packet_to_other_protocol(NETSIM_ID d,
225 NetSim_PACKET* packet,
228 NetSim_BUFFER* buffer = DEVICE_ACCESSBUFFER(d, in);
229 NetSim_PACKET* p = fn_NetSim_Packet_CopyPacket(packet);
231 if (!fn_NetSim_GetBufferStatus(buffer))
233 NetSim_EVENTDETAILS pevent;
234 memset(&pevent, 0,
sizeof pevent);
235 pevent.dEventTime = time;
236 pevent.dPacketSize = p->pstruNetworkData->dPacketSize;
239 pevent.nApplicationId = p->pstruAppData->nApplicationId;
240 pevent.nSegmentId = p->pstruAppData->nSegmentId;
242 pevent.nDeviceId = d;
243 pevent.nDeviceType = DEVICE_TYPE(d);
244 pevent.nEventType = MAC_OUT_EVENT;
245 pevent.nInterfaceId = in;
246 pevent.nPacketId = p->nPacketId;
247 pevent.nProtocolId = DEVICE_MACLAYER(d, in)->nMacProtocolId;
248 fnpAddEvent(&pevent);
250 fn_NetSim_Packet_AddPacketToList(buffer, p, 0);
253void forward_frame(NETSIM_ID d,
256 NetSim_PACKET* packet,
260 NETSIM_ID f = find_forward_interface(lan, packet);
264 if (fn_NetSim_MAC_Firewall(d, f, packet, ACLTYPE_OUTBOUND) == ACLACTION_PERMIT)
266 clear_eth_incoming(packet);
267 send_to_phy(d, f, packet, time);
270 fn_NetSim_Packet_FreePacket(packet);
274 if (DEVICE_TYPE(d) == SWITCH)
277 for (j = 0; j < lan->interfaceCount; j++)
279 if (lan->ethIfVar[j]->interfaceId == in)
282 if (lan->ethIfVar[j]->portState == PORTSTATE_BLOCKING)
285 NetSim_PACKET* p = fn_NetSim_Packet_CopyPacket(packet);
286 if (fn_NetSim_MAC_Firewall(d, lan->ethIfVar[j]->interfaceId, packet, ACLTYPE_OUTBOUND) == ACLACTION_PERMIT)
288 clear_eth_incoming(p);
289 send_to_phy(d, lan->ethIfVar[j]->interfaceId, p, time);
292 fn_NetSim_Packet_FreePacket(p);
295 vlan_forward_to_all_trunk(d, packet, lan, time);
301 for (j = 0; j < DEVICE(d)->nNumOfInterface; j++)
304 isVirtualInterface(d,j+1))
307 forward_packet_to_other_protocol(d, j+1, packet, time);
310 fn_NetSim_Packet_FreePacket(packet);
314static bool decide_move_up(ptrETH_LAN lan, PNETSIM_MACADDRESS destMAC, SWITCHING_TECHNIQUE sw)
316 if (isBroadcastMAC(destMAC) &&
317 sw != SWITCHINGTECHNIQUE_NULL)
return false;
325static void ethernet_mac_process_frame()
327 NETSIM_ID d = pstruEventDetails->nDeviceId;
328 NETSIM_ID in = pstruEventDetails->nInterfaceId;
329 double time = pstruEventDetails->dEventTime;
330 NetSim_PACKET* packet = pstruEventDetails->pPacket;
332 if (fn_NetSim_MAC_Firewall(d, in, packet, ACLTYPE_INBOUND) == ACLACTION_DENY)
334 fn_NetSim_Packet_FreePacket(packet);
338#pragma warning(disable:4189)
339 PNETSIM_MACADDRESS dest = packet->pstruMacData->szDestMac;
340#pragma warning(default:4189)
342 PNETSIM_MACADDRESS src = packet->pstruMacData->szSourceMac;
344 ptrETH_LAN lan = GET_ETH_LAN(d, in, 0);
345 if (lan->switchingTechnique)
346 SWITCHTABLE_NEW(lan, src, in);
348 bool isTag = isVLANTagPresent(packet);
349 store_eth_param_macin(packet, d, in, lan);
351 bool isMoveup = decide_move_up(lan, dest, lan->switchingTechnique);
354 check_move_frame_up(d, in, lan, packet, time);
359 vlan_macin_forward_packet();
361 forward_frame(d, in, lan, packet, time);
365int fn_NetSim_Ethernet_HandleMacIn()
367 NetSim_PACKET* packet = pstruEventDetails->pPacket;
368 if (packet->nControlDataType == ETH_CONFIGBPDU)
369 process_configbpdu();
371 ethernet_mac_process_frame();