15#define _NETSIM_FIREWALL_CODE_
16#pragma comment(lib,"NetworkStack.lib")
21#include "NetSim_utility.h"
27 NETSIM_ID nInterfaceId;
29 NETSIM_IPAddress source;
30 NETSIM_IPAddress dest;
31 NETSIM_IPAddress srcSubnet;
32 NETSIM_IPAddress destSubnet;
35 IP_PROTOCOL_NUMBER protocol;
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)
46static ACL_ACTION action_from_str(
char* s)
48 if (!_stricmp(s,
"permit"))
49 return ACLACTION_PERMIT;
50 if (!_stricmp(s,
"deny"))
51 return ACLACTION_DENY;
53 fnNetSimError(
"Unknown acl action %s. It must be either permit or deny.", s);
54 return ACLACTION_PERMIT;
57static NETSIM_IPAddress num_to_subnet(
int num)
61 for (i = 0; i < 4; i++)
72 char bin[9] =
"00000000";
73 for (
int j = 0; j < num; j++)
77 sprintf(s,
"%lld", binary_to_decimal(bin));
82 for (
int k = i+1; k < 4; k++)
92 return STR_TO_IP(strip, 4);
95static int perfix_from_mask(NETSIM_IPAddress mask)
98 while (mask->bin_ip[i] ==
'1')
103static void ip_from_str(
char* s, NETSIM_IPAddress* ip, NETSIM_IPAddress* subnet)
105 if (!_stricmp(s,
"any"))
125 *ip = STR_TO_IP(sip, 4);
126 *subnet = num_to_subnet(atoi(ssub));
129static IP_PROTOCOL_NUMBER ipprotocol_from_str(
char* pro)
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;
143 fnNetSimError(
"Unknown IP protocol %s", pro);
144 return IPPROTOCOL_NULL;
148static char* str_from_proto(IP_PROTOCOL_NUMBER num)
153 return _strdup(
"TCP");
155 return _strdup(
"UDP");
157 return _strdup(
"ANY");
161static ACL_TYPE type_from_str(
char* str)
163 if (!_stricmp(str,
"INBOUND"))
164 return ACLTYPE_INBOUND;
165 else if (!_stricmp(str,
"OUTBOUND"))
166 return ACLTYPE_OUTBOUND;
171static bool check_mac_block(NETSIM_ID d, NETSIM_ID in)
173 NETSIM_IPAddress ip = DEVICE_NWADDRESS(d, in);
175 for (i = 0; i < DEVICE(d)->nNumOfInterface; i++)
179 if (!IP_COMPARE(DEVICE_NWADDRESS(d, i + 1), ip))
185_declspec(dllexport)
void acl_add_new_line(NETSIM_ID d,
char* s)
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);
196 ptrACL acl = ACL_ALLOC();
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);
203 acl->srcPort = (UINT16)atoi(sport);
205 acl->destPort = (UINT16)atoi(dport);
207 acl->protocol = ipprotocol_from_str(pro);
210 acl->nInterfaceId = atoi(i);
211 if(acl->nInterfaceId)
212 acl->isMacBlock = check_mac_block(d, acl->nInterfaceId);
214 ACL_ADD(&ACL_GET(d), acl);
217static NETSIM_IPAddress get_dest_ip(NetSim_PACKET* packet)
219 NETSIM_IPAddress dest = packet->pstruNetworkData->szDestIP;
220 if (isMulticastIP(dest))
222 if (isBroadcastIP(dest))
225 NETSIM_ID* d = get_dest_from_packet(packet, &c);
229 return fn_NetSim_Stack_GetFirstIPAddressAsId(d[0], 0);
235_declspec(dllexport)
int fn_NetSim_FirewallConfig(NETSIM_ID nDeviceId)
237 IP_DEVVAR* ip = GET_IP_DEVVAR(nDeviceId);
238 if (!ip->isFirewallConfigured)
241 sprintf(p,
"%s%s%s", pszIOPath, pathSeperator, ip->firewallConfig);
242 FILE* fp = fopen(p,
"r");
245 fnSystemError(
"Unable to open %s file", p);
246 perror(ip->firewallConfig);
250 while (fgets(buf, BUFSIZ, fp))
257 if (*s ==
'\n' || *s == 0)
260 acl_add_new_line(nDeviceId, s);
267static ACL_ACTION fn_NetSim_Firewall(NETSIM_ID nDeviceId, NETSIM_ID interfaceId, NetSim_PACKET* packet, ACL_TYPE type,
bool isMAC)
269 if (!GET_IP_DEVVAR(nDeviceId))
270 return ACLACTION_PERMIT;
272 if (!GET_IP_DEVVAR(nDeviceId)->isFirewallConfigured)
273 return ACLACTION_PERMIT;
275 bool ismatched =
true;
276 ptrACL acl = ACL_GET(nDeviceId);
277 NETSIM_IPAddress src = packet->pstruNetworkData->szSourceIP;
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;
281 IP_PROTOCOL_NUMBER pro = packet->pstruNetworkData->IPProtocol;
286 if (acl->isMacBlock && !isMAC)
292 if ((acl->nInterfaceId && acl->nInterfaceId != interfaceId) ||
293 (acl->type != ACLTYPE_BOTH && acl->type != type))
299 if (ismatched && acl->source)
301 if (IP_COMPARE(acl->source, IP_NETWORK_ADDRESS(src,acl->srcSubnet,0)))
305 if (ismatched && acl->dest)
307 if (IP_COMPARE(acl->dest, IP_NETWORK_ADDRESS(dest,acl->destSubnet,0)))
311 if(ismatched && acl->destPort && acl->destPort!=dport)
314 if(ismatched && acl->srcPort && acl->srcPort != sport)
317 if(ismatched && acl->protocol && acl->protocol != pro)
325 return ACLACTION_PERMIT;
328_declspec(dllexport) ACL_ACTION fn_NetSim_MAC_Firewall(NETSIM_ID nDeviceId, NETSIM_ID interfaceId, NetSim_PACKET* packet, ACL_TYPE type)
330 return fn_NetSim_Firewall(nDeviceId, interfaceId, packet, type,
true);
333_declspec(dllexport) ACL_ACTION fn_NetSim_NETWORK_Firewall(NETSIM_ID nDeviceId, NETSIM_ID interfaceId, NetSim_PACKET* packet, ACL_TYPE type)
335 return fn_NetSim_Firewall(nDeviceId, interfaceId, packet, type,
false);
338_declspec(dllexport)
void fn_NetSim_Firewall_Free(NETSIM_ID d)
340 ptrACL acl = ACL_GET(d);
342 LIST_FREE(&acl, acl);
346_declspec(dllexport)
char* acl_print(NETSIM_ID d)
351 ptrACL acl = ACL_GET(d);
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"),
360 acl->source?acl->source->str_ip:
"ANY",
361 acl->srcSubnet?perfix_from_mask(acl->srcSubnet):0,
362 acl->dest?acl->dest->str_ip:
"ANY",
363 acl->destSubnet?perfix_from_mask(acl->destSubnet):0,
366 (
int)acl->nInterfaceId);
370 ret = realloc(ret, (size + strlen(s) + 1) *
sizeof(
char));
375 ret = calloc(strlen(s) + 1,
sizeof(
char));
379 size += (UINT)strlen(s);