NetSim Source Code Help
Loading...
Searching...
No Matches
firewall.c
Go to the documentation of this file.
1/************************************************************************************
2 * Copyright (C) 2020 *
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
15#define _NETSIM_FIREWALL_CODE_
16#pragma comment(lib,"NetworkStack.lib")
17
18#include "main.h"
19#include "List.h"
20#include "../IP/IP.h"
21#include "NetSim_utility.h"
22#include "Firewall.h"
23
24typedef struct stru_IP_ACL
25{
40#define ACL_ALLOC() (ptrACL)list_alloc(sizeof(NETSIM_ACL),offsetof(NETSIM_ACL,ele))
41#define ACL_NEXT(acl) acl=(ptrACL)LIST_NEXT(acl)
42#define ACL_ADD(lacl,acl) LIST_ADD_LAST((void**)lacl,acl)
43#define ACL_GET(d) ((ptrACL)(GET_IP_DEVVAR(d)->ACL))
44#define ACL_SET(d,acl) (GET_IP_DEVVAR(d)->ACL = (void*)acl)
45
47{
48 if (!_stricmp(s, "permit"))
49 return ACLACTION_PERMIT;
50 if (!_stricmp(s, "deny"))
51 return ACLACTION_DENY;
52
53 fnNetSimError("Unknown acl action %s. It must be either permit or deny.", s);
54 return ACLACTION_PERMIT;
55}
56
58{
59 int i = 0;
60 char strip[50]="";
61 for (i = 0; i < 4; i++)
62 {
63 if (num > 8)
64 {
65 strcat(strip, "255");
66 if (i != 3)
67 strcat(strip, ".");
68 num -= 8;
69 }
70 else
71 {
72 char bin[9] = "00000000";
73 for (int j = 0; j < num; j++)
74 bin[j] = '1';
75
76 char s[4];
77 sprintf(s,"%lld", binary_to_decimal(bin));
78 strcat(strip, s);
79 if (i != 3)
80 {
81 strcat(strip, ".");
82 for (int k = i+1; k < 4; k++)
83 {
84 strcat(strip, "0");
85 if (k != 3)
86 strcat(strip, ".");
87 }
88 }
89 break;
90 }
91 }
92 return STR_TO_IP(strip, 4);
93}
94
96{
97 int i = 0;
98 while (mask->bin_ip[i] == '1')
99 i++;
100 return i;
101}
102
103static void ip_from_str(char* s, NETSIM_IPAddress* ip, NETSIM_IPAddress* subnet)
104{
105 if (!_stricmp(s, "any"))
106 {
107 *ip = NULL;
108 *subnet = NULL;
109 return;
110 }
111
112 char* sip = s;
113 char* ssub = NULL;
114 while (*s)
115 {
116 if (*s == '/')
117 {
118 *s = 0;
119 ssub = s + 1;
120 break;
121 }
122 s++;
123 }
124
125 *ip = STR_TO_IP(sip, 4);
126 *subnet = num_to_subnet(atoi(ssub));
127}
128
130{
131 if (!_stricmp(pro, "any"))
132 return IPPROTOCOL_NULL;
133 else if (!_stricmp(pro, "TCP"))
134 return IPPROTOCOL_TCP;
135 else if (!_stricmp(pro, "UDP"))
136 return IPPROTOCOL_UDP;
137 else if (!_stricmp(pro, "IGMP"))
138 return IPPROTOCOL_IGMP;
139 else if (!_stricmp(pro, "ICMP"))
140 return IPPROTOCOL_ICMP;
141 else
142 {
143 fnNetSimError("Unknown IP protocol %s", pro);
144 return IPPROTOCOL_NULL;
145 }
146}
147
149{
150 switch (num)
151 {
152 case IPPROTOCOL_TCP:
153 return _strdup("TCP");
154 case IPPROTOCOL_UDP:
155 return _strdup("UDP");
156 default:
157 return _strdup("ANY");
158 }
159}
160
161static ACL_TYPE type_from_str(char* str)
162{
163 if (!_stricmp(str, "INBOUND"))
164 return ACLTYPE_INBOUND;
165 else if (!_stricmp(str, "OUTBOUND"))
166 return ACLTYPE_OUTBOUND;
167 else
168 return ACLTYPE_BOTH;
169}
170
172{
174 NETSIM_ID i;
175 for (i = 0; i < DEVICE(d)->nNumOfInterface; i++)
176 {
177 if (i + 1 == in)
178 continue;
179 if (!IP_COMPARE(DEVICE_NWADDRESS(d, i + 1), ip))
180 return true;
181 }
182 return false;
183}
184
185_declspec(dllexport) void acl_add_new_line(NETSIM_ID d, char* s)
186{
187 char* act = find_word(&s);
188 char* type = find_word(&s);
189 char* pro = find_word(&s);
190 char* src = find_word(&s);
191 char* dest = find_word(&s);
192 char* sport = find_word(&s);
193 char* dport = find_word(&s);
194 char* i = find_word(&s);
195
196 ptrACL acl = ACL_ALLOC();
197 acl->nDeviceId = d;
198 acl->action = action_from_str(act);
199 acl->type = type_from_str(type);
200 ip_from_str(src, &acl->source, &acl->srcSubnet);
201 ip_from_str(dest, &acl->dest, &acl->destSubnet);
202 if (sport)
203 acl->srcPort = (UINT16)atoi(sport);
204 if (dport)
205 acl->destPort = (UINT16)atoi(dport);
206 if(pro)
207 acl->protocol = ipprotocol_from_str(pro);
208 if (i)
209 {
210 acl->nInterfaceId = atoi(i);
211 if(acl->nInterfaceId)
213 }
214 ACL_ADD(&ACL_GET(d), acl);
215}
216
218{
220 if (isMulticastIP(dest))
221 return dest;
222 if (isBroadcastIP(dest))
223 return dest;
224 UINT c;
225 NETSIM_ID* d = get_dest_from_packet(packet, &c);
226 if (c > 1)
227 return dest;
228
230}
231
232/**
233 This function is to configure the firewall.
234*/
236{
237 IP_DEVVAR* ip = GET_IP_DEVVAR(nDeviceId);
238 if (!ip->isFirewallConfigured)
239 return -1;
240 char p[BUFSIZ];
241 sprintf(p, "%s%s%s", pszIOPath, pathSeperator, ip->firewallConfig);
242 FILE* fp = fopen(p, "r");
243 if (!fp)
244 {
245 fnSystemError("Unable to open %s file", p);
246 perror(ip->firewallConfig);
247 return -2;
248 }
249 char buf[BUFSIZ];
250 while (fgets(buf, BUFSIZ, fp))
251 {
252 char* s;
253 s = lskip(buf);
254 if (*s == '#')
255 continue; //Comment line
256
257 if (*s == '\n' || *s == 0)
258 continue; //empty line
259
260 acl_add_new_line(nDeviceId, s);
261 }
262 return 0;
263}
264/**
265 This function is to check whether the particular packet is blocked or allowed by firewall
266*/
267static ACL_ACTION fn_NetSim_Firewall(NETSIM_ID nDeviceId, NETSIM_ID interfaceId, NetSim_PACKET* packet, ACL_TYPE type, bool isMAC)
268{
269 if (!GET_IP_DEVVAR(nDeviceId))
270 return ACLACTION_PERMIT; // IP is not configured
271
272 if (!GET_IP_DEVVAR(nDeviceId)->isFirewallConfigured)
273 return ACLACTION_PERMIT; // Firewall is not configured
274
275 bool ismatched = true;
276 ptrACL acl = ACL_GET(nDeviceId);
278 NETSIM_IPAddress dest = get_dest_ip(packet);
279 UINT16 sport = packet->pstruTransportData ? packet->pstruTransportData->nSourcePort : 0;
280 UINT16 dport = packet->pstruTransportData ? packet->pstruTransportData->nDestinationPort : 0;
282 while (acl)
283 {
284 ismatched = true;
285
286 if (acl->isMacBlock && !isMAC)
287 {
288 ACL_NEXT(acl);
289 continue;
290 }
291
292 if ((acl->nInterfaceId && acl->nInterfaceId != interfaceId) ||
293 (acl->type != ACLTYPE_BOTH && acl->type != type))
294 {
295 ACL_NEXT(acl);
296 continue;
297 }
298
299 if (ismatched && acl->source)
300 {
301 if (IP_COMPARE(acl->source, IP_NETWORK_ADDRESS(src,acl->srcSubnet,0)))
302 ismatched = false;
303 }
304
305 if (ismatched && acl->dest)
306 {
307 if (IP_COMPARE(acl->dest, IP_NETWORK_ADDRESS(dest,acl->destSubnet,0)))
308 ismatched = false;
309 }
310
311 if(ismatched && acl->destPort && acl->destPort!=dport)
312 ismatched = false;
313
314 if(ismatched && acl->srcPort && acl->srcPort != sport)
315 ismatched = false;
316
317 if(ismatched && acl->protocol && acl->protocol != pro)
318 ismatched = false;
319
320 if (ismatched)
321 return acl->action;
322
323 ACL_NEXT(acl);
324 }
325 return ACLACTION_PERMIT;
326}
327
328_declspec(dllexport) ACL_ACTION fn_NetSim_MAC_Firewall(NETSIM_ID nDeviceId, NETSIM_ID interfaceId, NetSim_PACKET* packet, ACL_TYPE type)
329{
330 return fn_NetSim_Firewall(nDeviceId, interfaceId, packet, type, true);
331}
332
334{
335 return fn_NetSim_Firewall(nDeviceId, interfaceId, packet, type, false);
336}
337
339{
340 ptrACL acl = ACL_GET(d);
341 while (acl)
342 LIST_FREE(&acl, acl);
343 ACL_SET(d, NULL);
344}
345
346_declspec(dllexport) char* acl_print(NETSIM_ID d)
347{
348 UINT size = 0;
349 char* ret = NULL;
350 char* curr;
351 ptrACL acl = ACL_GET(d);
352 while (acl)
353 {
354 char s[BUFSIZ];
355 char* p = str_from_proto(acl->protocol);
356 sprintf(s, "%s %s %s %s/%d %s/%d %d %d %d\n",
357 acl->action == ACLACTION_PERMIT ? "PERMIT" : "DENY",
358 acl->type == ACLTYPE_BOTH ? "BOTH" : (acl->type == ACLTYPE_INBOUND ? "INBOUND" : "OUTBOUND"),
359 p,
360 acl->source?acl->source->str_ip:"ANY",
362 acl->dest?acl->dest->str_ip:"ANY",
364 (int)acl->srcPort,
365 (int)acl->destPort,
366 (int)acl->nInterfaceId);
367 free(p);
368 if (size)
369 {
370 ret = realloc(ret, (size + strlen(s) + 1) * sizeof(char));
371 curr = ret + size;
372 }
373 else
374 {
375 ret = calloc(strlen(s) + 1, sizeof(char));
376 curr = ret;
377 }
378 strcpy(curr, s);
379 size += (UINT)strlen(s);
380 ACL_NEXT(acl);
381 }
382 return ret;
383}
unsigned int NETSIM_ID
Definition: Animation.h:45
ACL_ACTION
Definition: Firewall.h:32
@ ACLACTION_DENY
Definition: Firewall.h:34
@ ACLACTION_PERMIT
Definition: Firewall.h:33
ACL_TYPE
Definition: Firewall.h:25
@ ACLTYPE_INBOUND
Definition: Firewall.h:27
@ ACLTYPE_OUTBOUND
Definition: Firewall.h:28
@ ACLTYPE_BOTH
Definition: Firewall.h:26
#define GET_IP_DEVVAR(d)
Definition: IP.h:49
NETSIM_IPAddress STR_TO_IP(char *ipStr, int type)
bool isBroadcastIP(NETSIM_IPAddress ip)
NETSIM_IPAddress IP_NETWORK_ADDRESS(NETSIM_IPAddress ip, NETSIM_IPAddress subnet, unsigned int prefix_len)
#define IP_COMPARE(ip1, ip2)
Definition: IP_Addressing.h:67
bool isMulticastIP(NETSIM_IPAddress ip)
#define c
#define _stricmp
Definition: Linux.h:127
#define UINT
Definition: Linux.h:38
#define _strdup(x)
Definition: Linux.h:126
#define _declspec(dllexport)
This function is used to trigger the update.
Definition: Linux.h:41
#define fnNetSimError(x,...)
Definition: Linux.h:56
static const char pathSeperator[5]
Definition: Linux.h:71
#define fnSystemError(x,...)
Definition: Linux.h:55
#define UINT16
Definition: Linux.h:33
#define LIST_FREE(ls, mem)
Definition: List.h:32
#define realloc(p, s)
Definition: Memory.h:32
#define free(p)
Definition: Memory.h:31
#define calloc(c, s)
Definition: Memory.h:29
UINT64 binary_to_decimal(char bin[])
char * find_word(char **s)
char * lskip(const char *s)
NETSIM_ID * get_dest_from_packet(NetSim_PACKET *packet, UINT *count)
IP_PROTOCOL_NUMBER
Definition: Packet.h:125
@ IPPROTOCOL_ICMP
Definition: Packet.h:127
@ IPPROTOCOL_UDP
Definition: Packet.h:130
@ IPPROTOCOL_IGMP
Definition: Packet.h:128
@ IPPROTOCOL_TCP
Definition: Packet.h:129
@ IPPROTOCOL_NULL
Definition: Packet.h:126
#define DEVICE(DeviceId)
Definition: Stack.h:769
EXPORTED char * pszIOPath
Definition: Stack.h:842
#define DEVICE_NWADDRESS(DeviceId, InterfaceId)
Definition: Stack.h:805
NETSIM_IPAddress fn_NetSim_Stack_GetFirstIPAddressAsId(NETSIM_ID nDeviceId, unsigned int type)
void acl_add_new_line(NETSIM_ID d, char *s)
Definition: firewall.c:185
static ACL_ACTION action_from_str(char *s)
Definition: firewall.c:46
#define ACL_GET(d)
Definition: firewall.c:43
static char * str_from_proto(IP_PROTOCOL_NUMBER num)
Definition: firewall.c:148
static ACL_TYPE type_from_str(char *str)
Definition: firewall.c:161
static void ip_from_str(char *s, NETSIM_IPAddress *ip, NETSIM_IPAddress *subnet)
Definition: firewall.c:103
static bool check_mac_block(NETSIM_ID d, NETSIM_ID in)
Definition: firewall.c:171
static int perfix_from_mask(NETSIM_IPAddress mask)
Definition: firewall.c:95
int fn_NetSim_FirewallConfig(NETSIM_ID nDeviceId)
Definition: firewall.c:235
static NETSIM_IPAddress get_dest_ip(NetSim_PACKET *packet)
Definition: firewall.c:217
ACL_ACTION fn_NetSim_MAC_Firewall(NETSIM_ID nDeviceId, NETSIM_ID interfaceId, NetSim_PACKET *packet, ACL_TYPE type)
Definition: firewall.c:328
ACL_ACTION fn_NetSim_NETWORK_Firewall(NETSIM_ID nDeviceId, NETSIM_ID interfaceId, NetSim_PACKET *packet, ACL_TYPE type)
Definition: firewall.c:333
static IP_PROTOCOL_NUMBER ipprotocol_from_str(char *pro)
Definition: firewall.c:129
#define ACL_ADD(lacl, acl)
Definition: firewall.c:42
void fn_NetSim_Firewall_Free(NETSIM_ID d)
Definition: firewall.c:338
struct stru_IP_ACL NETSIM_ACL
#define ACL_ALLOC()
Definition: firewall.c:40
static NETSIM_IPAddress num_to_subnet(int num)
Definition: firewall.c:57
struct stru_IP_ACL * ptrACL
char * acl_print(NETSIM_ID d)
Definition: firewall.c:346
static ACL_ACTION fn_NetSim_Firewall(NETSIM_ID nDeviceId, NETSIM_ID interfaceId, NetSim_PACKET *packet, ACL_TYPE type, bool isMAC)
Definition: firewall.c:267
#define ACL_SET(d, acl)
Definition: firewall.c:44
#define ACL_NEXT(acl)
Definition: firewall.c:41
Definition: List.h:43
NETSIM_IPAddress srcSubnet
Definition: firewall.c:31
ACL_TYPE type
Definition: firewall.c:28
IP_PROTOCOL_NUMBER protocol
Definition: firewall.c:35
UINT16 destPort
Definition: firewall.c:34
NETSIM_IPAddress dest
Definition: firewall.c:30
UINT16 srcPort
Definition: firewall.c:33
NETSIM_IPAddress source
Definition: firewall.c:29
ACL_ACTION action
Definition: firewall.c:36
NETSIM_ID nDeviceId
Definition: firewall.c:26
_ele * ele
Definition: firewall.c:38
NETSIM_IPAddress destSubnet
Definition: firewall.c:32
NETSIM_ID nInterfaceId
Definition: firewall.c:27
bool isMacBlock
Definition: firewall.c:37
Structure to store the device ip details.
Definition: IP.h:226
bool isFirewallConfigured
Definition: IP.h:232
char * firewallConfig
Definition: IP.h:233
IP_PROTOCOL_NUMBER IPProtocol
Definition: Packet.h:203
NETSIM_IPAddress szDestIP
Definition: Packet.h:199
NETSIM_IPAddress szSourceIP
Definition: Packet.h:198
unsigned short int nSourcePort
Definition: Packet.h:184
unsigned short int nDestinationPort
Definition: Packet.h:185
struct stru_NetSim_Packet_NetworkLayer * pstruNetworkData
Definition: Packet.h:275
struct stru_NetSim_Packet_TransportLayer * pstruTransportData
Definition: Packet.h:274
char str_ip[_NETSIM_IP_LEN]
Definition: IP_Addressing.h:54
char bin_ip[130]
Definition: IP_Addressing.h:55