NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
Vlan.c
1/************************************************************************************
2* Copyright (C) 2023 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* Author: Shashi Kant Suman *
12* *
13* ---------------------------------------------------------------------------------*/
14#include "main.h"
15#include "Ethernet.h"
16#include "../Firewall/Firewall.h"
17
18static ptrETH_LAN get_vlan(NETSIM_ID d, UINT16 vlanId)
19{
20 ptrETH_VAR eth = GET_ETH_VAR(d);
21 if (!eth->isVLAN)
22 return NULL;
23
24 UINT i;
25 for (i = 0; i < eth->lanCount; i++)
26 {
27 ptrETH_LAN lan = eth->lanVar[i];
28 if (lan->vlanId == vlanId)
29 return lan;
30 }
31 return NULL;
32}
33
34bool isVLANTagPresent(NetSim_PACKET* packet)
35{
36 ptrIEEE801_1Q_TAG tag = get_eth_hdr_var(packet);
37 if (tag)
38 return tag->TPId == VLAN_TPID;
39 else
40 return false;
41}
42
43VLANPORT vlan_port_type_from_str(char* val)
44{
45 if (!_stricmp(val, "ACCESS_PORT"))
46 return VLANPORT_ACCESS;
47 else if (!_stricmp(val, "TRUNK_PORT"))
48 return VLANPORT_TRUNK;
49 else
50 return VLANPORT_NONE;
51}
52
53void vlan_add_trunk_port(ptrETH_VAR eth, NETSIM_ID in)
54{
55 if (eth->trunkPortCount)
56 eth->trunkPortIds = realloc(eth->trunkPortIds,
57 (eth->trunkPortCount + 1) * sizeof* eth->trunkPortIds);
58 else
59 eth->trunkPortIds = calloc(1, sizeof* eth->trunkPortIds);
60 eth->trunkPortIds[eth->trunkPortCount] = in;
61 eth->trunkPortCount++;
62}
63
64static bool is_port_present_in_lan(ptrETH_LAN lan, NETSIM_ID in)
65{
66 UINT i;
67 for (i = 0; i < lan->interfaceCount; i++)
68 {
69 if (lan->interfaceId[i] == in)
70 return true;
71 }
72 return false;
73}
74
75void free_vtag(void* tag)
76{
77 free((ptrIEEE801_1Q_TAG)tag);
78}
79
80void* copy_vtag(void* tag)
81{
82 ptrIEEE801_1Q_TAG t = calloc(1, sizeof* t);
83 memcpy(t, tag, sizeof* t);
84 return t;
85}
86
87static void add_vlan_tag(NetSim_PACKET* packet, UINT16 vlanId)
88{
89 ptrIEEE801_1Q_TAG tag = calloc(1, sizeof* tag);
90 tag->TPId = VLAN_TPID;
91 tag->VID = vlanId;
92 set_eth_hdr(packet, ETH_HDR_VID, tag, copy_vtag, free_vtag);
93 packet->pstruMacData->dOverhead += IEEE801_1Q_TAG_LEN;
94 packet->pstruMacData->dPacketSize = packet->pstruMacData->dOverhead +
95 packet->pstruMacData->dPayload;
96}
97
98static void remove_vlan_tag(NetSim_PACKET* packet)
99{
100 free_eth_hdr(packet);
101 packet->pstruMacData->dOverhead -= IEEE801_1Q_TAG_LEN;
102 packet->pstruMacData->dPacketSize = packet->pstruMacData->dOverhead +
103 packet->pstruMacData->dPayload;
104}
105
106void vlan_forward_to_all_trunk(NETSIM_ID d,
107 NetSim_PACKET* packet,
108 ptrETH_LAN lan,
109 double time)
110{
111 ptrETH_VAR eth = GET_ETH_VAR(d);
112 if (!eth->isVLAN)
113 return; // VLAN is not configured
114
115 NETSIM_ID incoming = eth_get_incoming_port(packet, d);
116 UINT16 vlanId = eth_get_incoming_vlanid(packet, d);
117
118 UINT i;
119 for (i = 0; i < eth->trunkPortCount; i++)
120 {
121 NETSIM_ID inter = eth->trunkPortIds[i];
122
123 if (is_port_present_in_lan(lan, inter))
124 continue;
125
126 if(inter == incoming)
127 continue; //Incoming port
128
129 ptrETH_LAN l = GET_ETH_LAN(d, inter, 0);
130 ptrETH_IF iif = GET_ETH_IF(l, inter);
131
132 if (iif->portState == PORTSTATE_BLOCKING)
133 continue;
134
135 if (fn_NetSim_MAC_Firewall(d, inter, packet, ACLTYPE_OUTBOUND) == ACLACTION_PERMIT)
136 {
137 NetSim_PACKET* p = fn_NetSim_Packet_CopyPacket(packet);
138 clear_eth_incoming(p);
139 add_vlan_tag(p, vlanId);
140 send_to_phy(d, inter, p, time);
141 }
142 }
143}
144
145void vlan_forward_to_trunk(NETSIM_ID d,
146 NETSIM_ID in,
147 UINT16 vlanId,
148 NetSim_PACKET* packet,
149 double time)
150{
151 ptrETH_VAR eth = GET_ETH_VAR(d);
152 if (!eth->isVLAN)
153 return; // VLAN is not configured
154
155 UINT i;
156 for (i = 0; i < eth->trunkPortCount; i++)
157 {
158 NETSIM_ID inter = eth->trunkPortIds[i];
159
160 if (inter == in)
161 continue;
162
163 ptrETH_LAN l = GET_ETH_LAN(d, inter, 0);
164 ptrETH_IF iif = GET_ETH_IF(l, inter);
165
166 if (iif->portState == PORTSTATE_BLOCKING)
167 continue;
168
169 if (fn_NetSim_MAC_Firewall(d, inter, packet, ACLTYPE_OUTBOUND) == ACLACTION_PERMIT)
170 {
171 NetSim_PACKET* p = fn_NetSim_Packet_CopyPacket(packet);
172 clear_eth_incoming(p);
173 add_vlan_tag(p, vlanId);
174 send_to_phy(d, inter, p, time);
175 }
176 }
177}
178
179void vlan_macin_forward_packet()
180{
181 NETSIM_ID d = pstruEventDetails->nDeviceId;
182 NETSIM_ID in = pstruEventDetails->nInterfaceId;
183 double time = pstruEventDetails->dEventTime;
184 NetSim_PACKET* packet = pstruEventDetails->pPacket;
185 ptrETH_LAN lan;
186
187 UINT16 vlanId = eth_get_incoming_vlanid(packet, d);
188 lan = GET_ETH_LAN(d, in, 0);
189 if (lan->lanIP)
190 {
191 check_move_frame_up(d, in, lan, packet, time);
192 return;
193 }
194
195 lan = get_vlan(d, vlanId);
196 if (!lan)
197 {
198 // No vlan is found
199 vlan_forward_to_trunk(d, in, vlanId, packet, time);
200 fn_NetSim_Packet_FreePacket(packet);
201 pstruEventDetails->pPacket = NULL;
202 return;
203 }
204
205 NETSIM_ID f = find_forward_interface(lan, packet);
206
207 if (f)
208 {
209 //Forward interface found
210 if (fn_NetSim_MAC_Firewall(d, f, packet, ACLTYPE_OUTBOUND) == ACLACTION_PERMIT &&
211 f != in)
212 {
213 clear_eth_incoming(packet);
214 send_to_phy(d, f, packet, time);
215 return;
216 }
217 else
218 {
219 fn_NetSim_Packet_FreePacket(packet);
220 pstruEventDetails->pPacket = NULL;
221 return;
222 }
223 }
224 else
225 {
226 //Forward to all other trunk
227 vlan_forward_to_trunk(d, in, vlanId, packet, time);
228
229 //Forward to all interface
230 UINT j;
231 for (j = 0; j < lan->interfaceCount; j++)
232 {
233 if (lan->ethIfVar[j]->interfaceId == in)
234 continue;
235
236 if (lan->ethIfVar[j]->portState == PORTSTATE_BLOCKING)
237 continue;
238
239 if (fn_NetSim_MAC_Firewall(d, lan->ethIfVar[j]->interfaceId, packet, ACLTYPE_OUTBOUND) == ACLACTION_PERMIT)
240 {
241 NetSim_PACKET* p = fn_NetSim_Packet_CopyPacket(packet);
242 clear_eth_incoming(p);
243 send_to_phy(d, lan->ethIfVar[j]->interfaceId, p, time);
244 }
245 }
246
247 fn_NetSim_Packet_FreePacket(packet);
248 pstruEventDetails->pPacket = NULL;
249 }
250}
251
252void vlan_macout_forward_packet(NETSIM_ID d,
253 NETSIM_ID in,
254 UINT16 vlanId,
255 NETSIM_ID incoming,
256 NetSim_PACKET* packet,
257 double time)
258{
259 NETSIM_ID out = 0;
260 ptrETH_LAN lan = GET_ETH_LAN(d, in, 0);
261
262 out = find_forward_interface(lan, packet);
263
264 if (out)
265 {
266 if (fn_NetSim_MAC_Firewall(d, out, packet, ACLTYPE_OUTBOUND) == ACLACTION_PERMIT &&
267 out != incoming)
268 {
269 clear_eth_incoming(packet);
270 send_to_phy(d, out, packet, time);
271 }
272 else
273 fn_NetSim_Packet_FreePacket(packet);
274 }
275 else
276 {
277 vlan_forward_to_trunk(d, incoming, vlanId, packet, time);
278
279 UINT j;
280 for (j = 0; j < lan->interfaceCount; j++)
281 {
282 if (lan->ethIfVar[j]->portState == PORTSTATE_BLOCKING)
283 continue;
284
285 if (fn_NetSim_MAC_Firewall(d, lan->ethIfVar[j]->interfaceId, packet, ACLTYPE_OUTBOUND) == ACLACTION_PERMIT &&
286 lan->ethIfVar[j]->interfaceId != incoming)
287 {
288 NetSim_PACKET* p = fn_NetSim_Packet_CopyPacket(packet);
289 clear_eth_incoming(p);
290 send_to_phy(d, lan->ethIfVar[j]->interfaceId, p, time);
291 }
292 }
293 fn_NetSim_Packet_FreePacket(packet);
294 }
295}