1 /*
2 Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 		* Redistributions of source code must retain the above copyright
8 			notice, this list of conditions and the following disclaimer.
9 		* Redistributions in binary form must reproduce the above
10 			copyright notice, this list of conditions and the following
11 			disclaimer in the documentation and/or other materials provided
12 			with the distribution.
13 		* Neither the name of The Linux Foundation nor the names of its
14 			contributors may be used to endorse or promote products derived
15 			from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #include <sys/ioctl.h>
31 #include <net/if.h>
32 
33 #include "IPACM_ConntrackListener.h"
34 #include "IPACM_ConntrackClient.h"
35 #include "IPACM_EvtDispatcher.h"
36 #include "IPACM_Iface.h"
37 #include "IPACM_Wan.h"
38 
IPACM_ConntrackListener()39 IPACM_ConntrackListener::IPACM_ConntrackListener()
40 {
41 	 IPACMDBG("\n");
42 
43 	 isNatThreadStart = false;
44 	 isCTReg = false;
45 	 WanUp = false;
46 	 nat_inst = NatApp::GetInstance();
47 
48 	 NatIfaceCnt = 0;
49 	 StaClntCnt = 0;
50 	 pNatIfaces = NULL;
51 	 pConfig = IPACM_Config::GetInstance();;
52 
53 	 memset(nat_iface_ipv4_addr, 0, sizeof(nat_iface_ipv4_addr));
54 	 memset(nonnat_iface_ipv4_addr, 0, sizeof(nonnat_iface_ipv4_addr));
55 	 memset(sta_clnt_ipv4_addr, 0, sizeof(sta_clnt_ipv4_addr));
56 
57 	 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, this);
58 	 IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, this);
59 	 IPACM_EvtDispatcher::registr(IPA_PROCESS_CT_MESSAGE, this);
60 	 IPACM_EvtDispatcher::registr(IPA_PROCESS_CT_MESSAGE_V6, this);
61 	 IPACM_EvtDispatcher::registr(IPA_HANDLE_WLAN_UP, this);
62 	 IPACM_EvtDispatcher::registr(IPA_HANDLE_LAN_UP, this);
63 	 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, this);
64 	 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, this);
65 
66 #ifdef CT_OPT
67 	 p_lan2lan = IPACM_LanToLan::getLan2LanInstance();
68 #endif
69 }
70 
event_callback(ipa_cm_event_id evt,void * data)71 void IPACM_ConntrackListener::event_callback(ipa_cm_event_id evt,
72 						void *data)
73 {
74 	 ipacm_event_iface_up *wan_down = NULL;
75 
76 	 if(data == NULL)
77 	 {
78 		 IPACMERR("Invalid Data\n");
79 		 return;
80 	 }
81 
82 	 switch(evt)
83 	 {
84 	 case IPA_PROCESS_CT_MESSAGE:
85 			IPACMDBG("Received IPA_PROCESS_CT_MESSAGE event\n");
86 			ProcessCTMessage(data);
87 			break;
88 
89 #ifdef CT_OPT
90 	 case IPA_PROCESS_CT_MESSAGE_V6:
91 			IPACMDBG("Received IPA_PROCESS_CT_MESSAGE_V6 event\n");
92 			ProcessCTV6Message(data);
93 			break;
94 #endif
95 
96 	 case IPA_HANDLE_WAN_UP:
97 			IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
98 			CreateConnTrackThreads();
99 			TriggerWANUp(data);
100 			break;
101 
102 	 case IPA_HANDLE_WAN_DOWN:
103 			IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN event\n");
104 			wan_down = (ipacm_event_iface_up *)data;
105 			if(isWanUp())
106 			{
107 				TriggerWANDown(wan_down->ipv4_addr);
108 			}
109 			break;
110 
111 	/* if wlan or lan comes up after wan interface, modify
112 		 tcp/udp filters to ignore local wlan or lan connections */
113 	 case IPA_HANDLE_WLAN_UP:
114 	 case IPA_HANDLE_LAN_UP:
115 			IPACMDBG_H("Received event: %d with ifname: %s and address: 0x%x\n",
116 							 evt, ((ipacm_event_iface_up *)data)->ifname,
117 							 ((ipacm_event_iface_up *)data)->ipv4_addr);
118 			if(isWanUp())
119 			{
120 				CreateConnTrackThreads();
121 				IPACM_ConntrackClient::UpdateUDPFilters(data, false);
122 				IPACM_ConntrackClient::UpdateTCPFilters(data, false);
123 			}
124 			break;
125 
126 	 case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
127 		 IPACMDBG("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT event\n");
128 		 HandleNonNatIPAddr(data, true);
129 		 break;
130 
131 	 case IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT:
132 		 IPACMDBG("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event\n");
133 		 HandleNonNatIPAddr(data, false);
134 		 break;
135 
136 	 default:
137 			IPACMDBG("Ignore cmd %d\n", evt);
138 			break;
139 	 }
140 }
141 
CheckNatIface(ipacm_event_data_all * data,bool * NatIface)142 int IPACM_ConntrackListener::CheckNatIface(
143    ipacm_event_data_all *data, bool *NatIface)
144 {
145 	int fd = 0, len = 0, cnt, i;
146 	struct ifreq ifr;
147 	*NatIface = false;
148 
149 	if (data->ipv4_addr == 0 || data->iptype != IPA_IP_v4)
150 	{
151 		IPACMDBG("Ignoring\n");
152 		return IPACM_FAILURE;
153 	}
154 
155 	IPACMDBG("Received interface index %d with ip type: %d", data->if_index, data->iptype);
156 	iptodot(" and ipv4 address", data->ipv4_addr);
157 
158 	if (pConfig == NULL)
159 	{
160 		pConfig = IPACM_Config::GetInstance();
161 		if (pConfig == NULL)
162 		{
163 			IPACMERR("Unable to get Config instance\n");
164 			return IPACM_FAILURE;
165 		}
166 	}
167 
168 	cnt = pConfig->GetNatIfacesCnt();
169 	NatIfaceCnt = cnt;
170 	IPACMDBG("Total Nat ifaces: %d\n", NatIfaceCnt);
171 	if (pNatIfaces != NULL)
172 	{
173 		free(pNatIfaces);
174 		pNatIfaces = NULL;
175 	}
176 
177 	len = (sizeof(NatIfaces) * NatIfaceCnt);
178 	pNatIfaces = (NatIfaces *)malloc(len);
179 	if (pNatIfaces == NULL)
180 	{
181 		IPACMERR("Unable to allocate memory for non nat ifaces\n");
182 		return IPACM_FAILURE;
183 	}
184 
185 	memset(pNatIfaces, 0, len);
186 	if (pConfig->GetNatIfaces(NatIfaceCnt, pNatIfaces) != 0)
187 	{
188 		IPACMERR("Unable to retrieve non nat ifaces\n");
189 		return IPACM_FAILURE;
190 	}
191 
192 	/* Search/Configure linux interface-index and map it to IPA interface-index */
193 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
194 	{
195 		PERROR("get interface name socket create failed");
196 		return IPACM_FAILURE;
197 	}
198 
199 	memset(&ifr, 0, sizeof(struct ifreq));
200 	ifr.ifr_ifindex = data->if_index;
201 	if (ioctl(fd, SIOCGIFNAME, &ifr) < 0)
202 	{
203 		PERROR("call_ioctl_on_dev: ioctl failed:");
204 		close(fd);
205 		return IPACM_FAILURE;
206 	}
207 	close(fd);
208 
209 	for (i = 0; i < NatIfaceCnt; i++)
210 	{
211 		if (strncmp(ifr.ifr_name,
212 					pNatIfaces[i].iface_name,
213 					sizeof(pNatIfaces[i].iface_name)) == 0)
214 		{
215 			IPACMDBG_H("Nat iface (%s), entry (%d), dont cache",
216 						pNatIfaces[i].iface_name, i);
217 			iptodot("with ipv4 address: ", nat_iface_ipv4_addr[i]);
218 			*NatIface = true;
219 			return IPACM_SUCCESS;
220 		}
221 	}
222 
223 	return IPACM_SUCCESS;
224 }
225 
HandleNonNatIPAddr(void * inParam,bool AddOp)226 void IPACM_ConntrackListener::HandleNonNatIPAddr(
227    void *inParam, bool AddOp)
228 {
229 	ipacm_event_data_all *data = (ipacm_event_data_all *)inParam;
230 	bool NatIface = false;
231 	int cnt, ret;
232 
233 	if (isStaMode)
234 	{
235 		IPACMDBG("In STA mode, don't add dummy rules for non nat ifaces\n");
236 		return;
237 	}
238 
239 	/* Handle only non nat ifaces, NAT iface should be handle
240 	   separately to avoid race conditions between route/nat
241 	   rules add/delete operations */
242 	if (AddOp)
243 	{
244 		ret = CheckNatIface(data, &NatIface);
245 		if (!NatIface && ret == IPACM_SUCCESS)
246 		{
247 			/* Cache the non nat iface ip address */
248 			for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
249 			{
250 				if (nonnat_iface_ipv4_addr[cnt] == 0)
251 				{
252 					nonnat_iface_ipv4_addr[cnt] = data->ipv4_addr;
253 					IPACMDBG("Add ip addr to non nat list (%d) ", cnt);
254 					iptodot("with ipv4 address", nonnat_iface_ipv4_addr[cnt]);
255 
256 					/* Add dummy nat rule for non nat ifaces */
257 					nat_inst->FlushTempEntries(data->ipv4_addr, true, true);
258 					return;
259 				}
260 			}
261 		}
262 	}
263 	else
264 	{
265 		/* for delete operation */
266 		for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
267 		{
268 			if (nonnat_iface_ipv4_addr[cnt] == data->ipv4_addr)
269 			{
270 				IPACMDBG("Reseting ct filters, entry (%d) ", cnt);
271 				iptodot("with ipv4 address", nonnat_iface_ipv4_addr[cnt]);
272 				nonnat_iface_ipv4_addr[cnt] = 0;
273 				nat_inst->FlushTempEntries(data->ipv4_addr, false);
274 				nat_inst->DelEntriesOnClntDiscon(data->ipv4_addr);
275 				return;
276 			}
277 		}
278 
279 	}
280 
281 	return;
282 }
283 
HandleNeighIpAddrAddEvt(ipacm_event_data_all * data)284 void IPACM_ConntrackListener::HandleNeighIpAddrAddEvt(
285    ipacm_event_data_all *data)
286 {
287 	bool NatIface = false;
288 	int j, ret;
289 
290 	ret = CheckNatIface(data, &NatIface);
291 	if (NatIface && ret == IPACM_SUCCESS)
292 	{
293 		for (j = 0; j < MAX_IFACE_ADDRESS; j++)
294 		{
295 			/* check if duplicate NAT ip */
296 			if (nat_iface_ipv4_addr[j] == data->ipv4_addr)
297 				break;
298 
299 			/* Cache the new nat iface address */
300 			if (nat_iface_ipv4_addr[j] == 0)
301 			{
302 				nat_iface_ipv4_addr[j] = data->ipv4_addr;
303 				iptodot("Nating connections of addr: ", nat_iface_ipv4_addr[j]);
304 				break;
305 			}
306 		}
307 
308 		/* Add the cached temp entries to NAT table */
309 		if (j != MAX_IFACE_ADDRESS)
310 		{
311 			nat_inst->ResetPwrSaveIf(data->ipv4_addr);
312 			nat_inst->FlushTempEntries(data->ipv4_addr, true);
313 		}
314 	}
315 	return;
316 }
317 
HandleNeighIpAddrDelEvt(uint32_t ipv4_addr)318 void IPACM_ConntrackListener::HandleNeighIpAddrDelEvt(
319    uint32_t ipv4_addr)
320 {
321 	int cnt;
322 
323 	if(ipv4_addr == 0)
324 	{
325 		IPACMDBG("Ignoring\n");
326 		return;
327 	}
328 
329 	iptodot("HandleNeighIpAddrDelEvt(): Received ip addr", ipv4_addr);
330 	for(cnt = 0; cnt<MAX_IFACE_ADDRESS; cnt++)
331 	{
332 		if (nat_iface_ipv4_addr[cnt] == ipv4_addr)
333 		{
334 			IPACMDBG("Reseting ct nat iface, entry (%d) ", cnt);
335 			iptodot("with ipv4 address", nat_iface_ipv4_addr[cnt]);
336 			nat_iface_ipv4_addr[cnt] = 0;
337 			nat_inst->FlushTempEntries(ipv4_addr, false);
338 			nat_inst->DelEntriesOnClntDiscon(ipv4_addr);
339 		}
340 	}
341 
342 	return;
343 }
344 
TriggerWANUp(void * in_param)345 void IPACM_ConntrackListener::TriggerWANUp(void *in_param)
346 {
347 	 ipacm_event_iface_up *wanup_data = (ipacm_event_iface_up *)in_param;
348 
349 	 IPACMDBG_H("Recevied below information during wanup,\n");
350 	 IPACMDBG_H("if_name:%s, ipv4_address:0x%x\n",
351 						wanup_data->ifname, wanup_data->ipv4_addr);
352 
353 	 if(wanup_data->ipv4_addr == 0)
354 	 {
355 		 IPACMERR("Invalid ipv4 address,ignoring IPA_HANDLE_WAN_UP event\n");
356 		 return;
357 	 }
358 
359 	 if(isWanUp())
360 	 {
361 		 if (wan_ipaddr != wanup_data->ipv4_addr)
362 			 TriggerWANDown(wan_ipaddr);
363 		 else
364 			 return;
365 	 }
366 
367 	 WanUp = true;
368 	 isStaMode = wanup_data->is_sta;
369 	 IPACMDBG("isStaMode: %d\n", isStaMode);
370 
371 	 wan_ipaddr = wanup_data->ipv4_addr;
372 	 memcpy(wan_ifname, wanup_data->ifname, sizeof(wan_ifname));
373 
374 	 if(nat_inst != NULL)
375 	 {
376 		 nat_inst->AddTable(wanup_data->ipv4_addr);
377 	 }
378 
379 	 IPACMDBG("creating nat threads\n");
380 	 CreateNatThreads();
381 }
382 
CreateConnTrackThreads(void)383 int IPACM_ConntrackListener::CreateConnTrackThreads(void)
384 {
385 	int ret;
386 	pthread_t tcp_thread = 0, udp_thread = 0;
387 
388 	if(isCTReg == false)
389 	{
390 		if(!tcp_thread)
391 		{
392 			ret = pthread_create(&tcp_thread, NULL, IPACM_ConntrackClient::TCPRegisterWithConnTrack, NULL);
393 			if(0 != ret)
394 			{
395 				IPACMERR("unable to create TCP conntrack event listner thread\n");
396 				PERROR("unable to create TCP conntrack\n");
397 				return -1;
398 			}
399 
400 			IPACMDBG("created TCP conntrack event listner thread\n");
401 			if(pthread_setname_np(tcp_thread, "tcp ct listener") != 0)
402 			{
403 				IPACMERR("unable to set thread name\n");
404 			}
405 		}
406 
407 		if(!udp_thread)
408 		{
409 			ret = pthread_create(&udp_thread, NULL, IPACM_ConntrackClient::UDPRegisterWithConnTrack, NULL);
410 			if(0 != ret)
411 			{
412 				IPACMERR("unable to create UDP conntrack event listner thread\n");
413 				PERROR("unable to create UDP conntrack\n");
414 				goto error;
415 			}
416 
417 			IPACMDBG("created UDP conntrack event listner thread\n");
418 			if(pthread_setname_np(udp_thread, "udp ct listener") != 0)
419 			{
420 				IPACMERR("unable to set thread name\n");
421 			}
422 		}
423 
424 		isCTReg = true;
425 	}
426 
427 	return 0;
428 
429 error:
430 	return -1;
431 }
CreateNatThreads(void)432 int IPACM_ConntrackListener::CreateNatThreads(void)
433 {
434 	int ret;
435 	pthread_t udpcto_thread = 0;
436 
437 	if(isNatThreadStart == false)
438 	{
439 		if(!udpcto_thread)
440 		{
441 			ret = pthread_create(&udpcto_thread, NULL, IPACM_ConntrackClient::UDPConnTimeoutUpdate, NULL);
442 			if(0 != ret)
443 			{
444 				IPACMERR("unable to create udp conn timeout thread\n");
445 				PERROR("unable to create udp conn timeout\n");
446 				goto error;
447 			}
448 
449 			IPACMDBG("created upd conn timeout thread\n");
450 			if(pthread_setname_np(udpcto_thread, "udp conn timeout") != 0)
451 			{
452 				IPACMERR("unable to set thread name\n");
453 			}
454 		}
455 
456 		isNatThreadStart = true;
457 	}
458 	return 0;
459 
460 error:
461 	return -1;
462 }
463 
TriggerWANDown(uint32_t wan_addr)464 void IPACM_ConntrackListener::TriggerWANDown(uint32_t wan_addr)
465 {
466 	int ret = 0;
467 	IPACMDBG_H("Deleting ipv4 nat table with");
468 	IPACMDBG_H(" public ip address(0x%x): %d.%d.%d.%d\n", wan_addr,
469 			((wan_addr>>24) & 0xFF), ((wan_addr>>16) & 0xFF),
470 			((wan_addr>>8) & 0xFF), (wan_addr & 0xFF));
471 
472 	 if(nat_inst != NULL)
473 	 {
474 		 ret = nat_inst->DeleteTable(wan_addr);
475 		 if (ret)
476 			 return;
477 
478 		 WanUp = false;
479 		 wan_ipaddr = 0;
480 	 }
481 }
482 
483 
ParseCTMessage(struct nf_conntrack * ct)484 void ParseCTMessage(struct nf_conntrack *ct)
485 {
486 	 uint32_t status, timeout;
487 	 IPACMDBG("Printing conntrack parameters\n");
488 
489 	 iptodot("ATTR_IPV4_SRC = ATTR_ORIG_IPV4_SRC:", nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC));
490 	 iptodot("ATTR_IPV4_DST = ATTR_ORIG_IPV4_DST:", nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST));
491 	 IPACMDBG("ATTR_PORT_SRC = ATTR_ORIG_PORT_SRC: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC));
492 	 IPACMDBG("ATTR_PORT_DST = ATTR_ORIG_PORT_DST: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST));
493 
494 	 iptodot("ATTR_REPL_IPV4_SRC:", nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC));
495 	 iptodot("ATTR_REPL_IPV4_DST:", nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST));
496 	 IPACMDBG("ATTR_REPL_PORT_SRC: 0x%x\n", nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC));
497 	 IPACMDBG("ATTR_REPL_PORT_DST: 0x%x\n", nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST));
498 
499 	 iptodot("ATTR_SNAT_IPV4:", nfct_get_attr_u32(ct, ATTR_SNAT_IPV4));
500 	 iptodot("ATTR_DNAT_IPV4:", nfct_get_attr_u32(ct, ATTR_DNAT_IPV4));
501 	 IPACMDBG("ATTR_SNAT_PORT: 0x%x\n", nfct_get_attr_u16(ct, ATTR_SNAT_PORT));
502 	 IPACMDBG("ATTR_DNAT_PORT: 0x%x\n", nfct_get_attr_u16(ct, ATTR_DNAT_PORT));
503 
504 	 IPACMDBG("ATTR_MARK: 0x%x\n", nfct_get_attr_u32(ct, ATTR_MARK));
505 	 IPACMDBG("ATTR_USE: 0x%x\n", nfct_get_attr_u32(ct, ATTR_USE));
506 	 IPACMDBG("ATTR_ID: 0x%x\n", nfct_get_attr_u32(ct, ATTR_ID));
507 
508 	 status = nfct_get_attr_u32(ct, ATTR_STATUS);
509 	 IPACMDBG("ATTR_STATUS: 0x%x\n", status);
510 
511 	 timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT);
512 	 IPACMDBG("ATTR_TIMEOUT: 0x%x\n", timeout);
513 
514 	 if(IPS_SRC_NAT & status)
515 	 {
516 			IPACMDBG("IPS_SRC_NAT set\n");
517 	 }
518 
519 	 if(IPS_DST_NAT & status)
520 	 {
521 			IPACMDBG("IPS_DST_NAT set\n");
522 	 }
523 
524 	 if(IPS_SRC_NAT_DONE & status)
525 	 {
526 			IPACMDBG("IPS_SRC_NAT_DONE set\n");
527 	 }
528 
529 	 if(IPS_DST_NAT_DONE & status)
530 	 {
531 			IPACMDBG(" IPS_DST_NAT_DONE set\n");
532 	 }
533 
534 	 IPACMDBG("\n");
535 	 return;
536 }
537 
ParseCTV6Message(struct nf_conntrack * ct)538 void ParseCTV6Message(struct nf_conntrack *ct)
539 {
540 	 uint32_t status, timeout;
541 	 struct nfct_attr_grp_ipv6 orig_params;
542 	 uint8_t l4proto, tcp_flags, tcp_state;
543 
544 	 IPACMDBG("Printing conntrack parameters\n");
545 
546 	 nfct_get_attr_grp(ct, ATTR_GRP_ORIG_IPV6, (void *)&orig_params);
547 	 IPACMDBG("Orig src_v6_addr: 0x%08x%08x%08x%08x\n", orig_params.src[0], orig_params.src[1],
548                 	orig_params.src[2], orig_params.src[3]);
549 	IPACMDBG("Orig dst_v6_addr: 0x%08x%08x%08x%08x\n", orig_params.dst[0], orig_params.dst[1],
550                 	orig_params.dst[2], orig_params.dst[3]);
551 
552 	 IPACMDBG("ATTR_PORT_SRC = ATTR_ORIG_PORT_SRC: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC));
553 	 IPACMDBG("ATTR_PORT_DST = ATTR_ORIG_PORT_DST: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST));
554 
555 	 IPACMDBG("ATTR_MARK: 0x%x\n", nfct_get_attr_u32(ct, ATTR_MARK));
556 	 IPACMDBG("ATTR_USE: 0x%x\n", nfct_get_attr_u32(ct, ATTR_USE));
557 	 IPACMDBG("ATTR_ID: 0x%x\n", nfct_get_attr_u32(ct, ATTR_ID));
558 
559 	 timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT);
560 	 IPACMDBG("ATTR_TIMEOUT: 0x%x\n", timeout);
561 
562 	 status = nfct_get_attr_u32(ct, ATTR_STATUS);
563 	 IPACMDBG("ATTR_STATUS: 0x%x\n", status);
564 
565 	 l4proto = nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO);
566 	 IPACMDBG("ATTR_ORIG_L4PROTO: 0x%x\n", l4proto);
567 	 if(l4proto == IPPROTO_TCP)
568 	 {
569 		tcp_state = nfct_get_attr_u8(ct, ATTR_TCP_STATE);
570 		IPACMDBG("ATTR_TCP_STATE: 0x%x\n", tcp_state);
571 
572 		tcp_flags =  nfct_get_attr_u8(ct, ATTR_TCP_FLAGS_ORIG);
573 		IPACMDBG("ATTR_TCP_FLAGS_ORIG: 0x%x\n", tcp_flags);
574 	 }
575 
576 	 IPACMDBG("\n");
577 	 return;
578 }
579 
580 #ifdef CT_OPT
ProcessCTV6Message(void * param)581 void IPACM_ConntrackListener::ProcessCTV6Message(void *param)
582 {
583 	ipacm_ct_evt_data *evt_data = (ipacm_ct_evt_data *)param;
584 	u_int8_t l4proto = 0;
585 	uint32_t status = 0;
586 	struct nf_conntrack *ct = evt_data->ct;
587 
588 #ifdef IPACM_DEBUG
589 	 char buf[1024];
590 
591 	 /* Process message and generate ioctl call to kernel thread */
592 	 nfct_snprintf(buf, sizeof(buf), evt_data->ct,
593 								 evt_data->type, NFCT_O_PLAIN, NFCT_OF_TIME);
594 	 IPACMDBG("%s\n", buf);
595 	 IPACMDBG("\n");
596 	 ParseCTV6Message(ct);
597 #endif
598 
599 	if(p_lan2lan == NULL)
600 	{
601 		IPACMERR("Lan2Lan Instance is null\n");
602 		goto IGNORE;
603 	}
604 
605 	status = nfct_get_attr_u32(ct, ATTR_STATUS);
606 	if((IPS_DST_NAT & status) || (IPS_SRC_NAT & status))
607 	{
608 		IPACMDBG("Either Destination or Source nat flag Set\n");
609 		goto IGNORE;
610 	}
611 
612 	l4proto = nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO);
613 	if(IPPROTO_UDP != l4proto && IPPROTO_TCP != l4proto)
614 	{
615 		 IPACMDBG("Received unexpected protocl %d conntrack message\n", l4proto);
616 		 goto IGNORE;
617 	}
618 
619 	IPACMDBG("Neither Destination nor Source nat flag Set\n");
620 	struct nfct_attr_grp_ipv6 orig_params;
621 	nfct_get_attr_grp(ct, ATTR_GRP_ORIG_IPV6, (void *)&orig_params);
622 
623 	ipacm_event_connection lan2lan_conn;
624 	lan2lan_conn.iptype = IPA_IP_v6;
625 	memcpy(lan2lan_conn.src_ipv6_addr, orig_params.src,
626 				 sizeof(lan2lan_conn.src_ipv6_addr));
627     IPACMDBG("Before convert, src_v6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.src_ipv6_addr[0], lan2lan_conn.src_ipv6_addr[1],
628                 	lan2lan_conn.src_ipv6_addr[2], lan2lan_conn.src_ipv6_addr[3]);
629     for(int cnt=0; cnt<4; cnt++)
630 	{
631 	   lan2lan_conn.src_ipv6_addr[cnt] = ntohl(lan2lan_conn.src_ipv6_addr[cnt]);
632 	}
633 	IPACMDBG("After convert src_v6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.src_ipv6_addr[0], lan2lan_conn.src_ipv6_addr[1],
634                 	lan2lan_conn.src_ipv6_addr[2], lan2lan_conn.src_ipv6_addr[3]);
635 
636 	memcpy(lan2lan_conn.dst_ipv6_addr, orig_params.dst,
637 				 sizeof(lan2lan_conn.dst_ipv6_addr));
638 	IPACMDBG("Before convert, dst_ipv6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.dst_ipv6_addr[0], lan2lan_conn.dst_ipv6_addr[1],
639                 	lan2lan_conn.dst_ipv6_addr[2], lan2lan_conn.dst_ipv6_addr[3]);
640     for(int cnt=0; cnt<4; cnt++)
641 	{
642 	   lan2lan_conn.dst_ipv6_addr[cnt] = ntohl(lan2lan_conn.dst_ipv6_addr[cnt]);
643 	}
644 	IPACMDBG("After convert, dst_ipv6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.dst_ipv6_addr[0], lan2lan_conn.dst_ipv6_addr[1],
645                 	lan2lan_conn.dst_ipv6_addr[2], lan2lan_conn.dst_ipv6_addr[3]);
646 
647 	if(((IPPROTO_UDP == l4proto) && (NFCT_T_NEW == evt_data->type)) ||
648 		 ((IPPROTO_TCP == l4proto) &&
649 			(nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_ESTABLISHED))
650 		 )
651 	{
652 			p_lan2lan->handle_new_connection(&lan2lan_conn);
653 	}
654 	else if((IPPROTO_UDP == l4proto && NFCT_T_DESTROY == evt_data->type) ||
655 					(IPPROTO_TCP == l4proto &&
656 					 nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_FIN_WAIT))
657 	{
658 			p_lan2lan->handle_del_connection(&lan2lan_conn);
659 	}
660 
661 IGNORE:
662 	/* Cleanup item that was allocated during the original CT callback */
663 	nfct_destroy(ct);
664 	return;
665 }
666 #endif
667 
ProcessCTMessage(void * param)668 void IPACM_ConntrackListener::ProcessCTMessage(void *param)
669 {
670 	 ipacm_ct_evt_data *evt_data = (ipacm_ct_evt_data *)param;
671 	 u_int8_t l4proto = 0;
672 
673 #ifdef IPACM_DEBUG
674 	 char buf[1024];
675 	 unsigned int out_flags;
676 
677 	 /* Process message and generate ioctl call to kernel thread */
678 	 out_flags = (NFCT_OF_SHOW_LAYER3 | NFCT_OF_TIME | NFCT_OF_ID);
679 	 nfct_snprintf(buf, sizeof(buf), evt_data->ct,
680 								 evt_data->type, NFCT_O_PLAIN, out_flags);
681 	 IPACMDBG_H("%s\n", buf);
682 
683 	 ParseCTMessage(evt_data->ct);
684 #endif
685 
686 	 l4proto = nfct_get_attr_u8(evt_data->ct, ATTR_ORIG_L4PROTO);
687 	 if(IPPROTO_UDP != l4proto && IPPROTO_TCP != l4proto)
688 	 {
689 			IPACMDBG("Received unexpected protocl %d conntrack message\n", l4proto);
690 	 }
691 	 else
692 	 {
693 			ProcessTCPorUDPMsg(evt_data->ct, evt_data->type, l4proto);
694 	 }
695 
696 	 /* Cleanup item that was allocated during the original CT callback */
697 	 nfct_destroy(evt_data->ct);
698 	 return;
699 }
700 
AddIface(nat_table_entry * rule,bool * isTempEntry)701 bool IPACM_ConntrackListener::AddIface(
702    nat_table_entry *rule, bool *isTempEntry)
703 {
704 	int cnt;
705 
706 	*isTempEntry = false;
707 
708 	/* Special handling for Passthrough IP. */
709 	if (IPACM_Iface::ipacmcfg->ipacm_ip_passthrough_mode)
710 	{
711 		if (rule->private_ip == IPACM_Wan::getWANIP())
712 		{
713 			IPACMDBG("In Passthrough mode and entry matched with Wan IP (0x%x)\n",
714 				rule->private_ip);
715 			return true;
716 		}
717 	}
718 
719 	/* check whether nat iface or not */
720 	for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
721 	{
722 		if (nat_iface_ipv4_addr[cnt] != 0)
723 		{
724 			if (rule->private_ip == nat_iface_ipv4_addr[cnt] ||
725 				rule->target_ip == nat_iface_ipv4_addr[cnt])
726 			{
727 				IPACMDBG("matched nat_iface_ipv4_addr entry(%d)\n", cnt);
728 				iptodot("AddIface(): Nat entry match with ip addr",
729 						nat_iface_ipv4_addr[cnt]);
730 				return true;
731 			}
732 		}
733 	}
734 
735 	if (!isStaMode)
736 	{
737 		/* check whether non nat iface or not, on Non Nat iface
738 		   add dummy rule by copying public ip to private ip */
739 		for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
740 		{
741 			if (nonnat_iface_ipv4_addr[cnt] != 0)
742 			{
743 				if (rule->private_ip == nonnat_iface_ipv4_addr[cnt] ||
744 					rule->target_ip == nonnat_iface_ipv4_addr[cnt])
745 				{
746 					IPACMDBG("matched non_nat_iface_ipv4_addr entry(%d)\n", cnt);
747 					iptodot("AddIface(): Non Nat entry match with ip addr",
748 							nonnat_iface_ipv4_addr[cnt]);
749 
750 					rule->private_ip = rule->public_ip;
751 					rule->private_port = rule->public_port;
752 					return true;
753 				}
754 			}
755 		}
756 		IPACMDBG_H("Not mtaching with non-nat ifaces\n");
757 	}
758 	else
759 		IPACMDBG("In STA mode, don't compare against non nat ifaces\n");
760 
761 	if(pConfig == NULL)
762 	{
763 		pConfig = IPACM_Config::GetInstance();
764 		if(pConfig == NULL)
765 		{
766 			IPACMERR("Unable to get Config instance\n");
767 			return false;
768 		}
769 	}
770 
771 	if (pConfig->isPrivateSubnet(rule->private_ip) ||
772 		pConfig->isPrivateSubnet(rule->target_ip))
773 	{
774 		IPACMDBG("Matching with Private subnet\n");
775 		*isTempEntry = true;
776 		return true;
777 	}
778 
779 	return false;
780 }
781 
AddORDeleteNatEntry(const nat_entry_bundle * input)782 void IPACM_ConntrackListener::AddORDeleteNatEntry(const nat_entry_bundle *input)
783 {
784 	u_int8_t tcp_state;
785 
786 	if (nat_inst == NULL)
787 	{
788 		IPACMERR("Nat instance is NULL, unable to add or delete\n");
789 		return;
790 	}
791 
792 	IPACMDBG_H("Below Nat Entry will either be added or deleted\n");
793 	iptodot("AddORDeleteNatEntry(): target ip or dst ip",
794 			input->rule->target_ip);
795 	IPACMDBG("target port or dst port: 0x%x Decimal:%d\n",
796 			 input->rule->target_port, input->rule->target_port);
797 	iptodot("AddORDeleteNatEntry(): private ip or src ip",
798 			input->rule->private_ip);
799 	IPACMDBG("private port or src port: 0x%x, Decimal:%d\n",
800 			 input->rule->private_port, input->rule->private_port);
801 	IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n",
802 			 input->rule->public_port, input->rule->public_port);
803 	IPACMDBG("Protocol: %d, destination nat flag: %d\n",
804 			 input->rule->protocol, input->rule->dst_nat);
805 
806 	if (IPPROTO_TCP == input->rule->protocol)
807 	{
808 		tcp_state = nfct_get_attr_u8(input->ct, ATTR_TCP_STATE);
809 		if (TCP_CONNTRACK_ESTABLISHED == tcp_state)
810 		{
811 			IPACMDBG("TCP state TCP_CONNTRACK_ESTABLISHED(%d)\n", tcp_state);
812 			if (!CtList->isWanUp())
813 			{
814 				IPACMDBG("Wan is not up, cache connections\n");
815 				nat_inst->CacheEntry(input->rule);
816 			}
817 			else if (input->isTempEntry)
818 			{
819 				nat_inst->AddTempEntry(input->rule);
820 			}
821 			else
822 			{
823 				nat_inst->AddEntry(input->rule);
824 			}
825 		}
826 		else if (TCP_CONNTRACK_FIN_WAIT == tcp_state ||
827 				   input->type == NFCT_T_DESTROY)
828 		{
829 			IPACMDBG("TCP state TCP_CONNTRACK_FIN_WAIT(%d) "
830 					 "or type NFCT_T_DESTROY(%d)\n", tcp_state, input->type);
831 
832 			nat_inst->DeleteEntry(input->rule);
833 			nat_inst->DeleteTempEntry(input->rule);
834 		}
835 		else
836 		{
837 			IPACMDBG("Ignore tcp state: %d and type: %d\n",
838 					 tcp_state, input->type);
839 		}
840 
841 	}
842 	else if (IPPROTO_UDP == input->rule->protocol)
843 	{
844 		if (NFCT_T_NEW == input->type)
845 		{
846 			IPACMDBG("New UDP connection at time %ld\n", time(NULL));
847 			if (!CtList->isWanUp())
848 			{
849 				IPACMDBG("Wan is not up, cache connections\n");
850 				nat_inst->CacheEntry(input->rule);
851 			}
852 			else if (input->isTempEntry)
853 			{
854 				nat_inst->AddTempEntry(input->rule);
855 			}
856 			else
857 			{
858 				nat_inst->AddEntry(input->rule);
859 			}
860 		}
861 		else if (NFCT_T_DESTROY == input->type)
862 		{
863 			IPACMDBG("UDP connection close at time %ld\n", time(NULL));
864 			nat_inst->DeleteEntry(input->rule);
865 			nat_inst->DeleteTempEntry(input->rule);
866 		}
867 	}
868 
869 	return;
870 }
871 
PopulateTCPorUDPEntry(struct nf_conntrack * ct,uint32_t status,nat_table_entry * rule)872 void IPACM_ConntrackListener::PopulateTCPorUDPEntry(
873 	 struct nf_conntrack *ct,
874 	 uint32_t status,
875 	 nat_table_entry *rule)
876 {
877 	if (IPS_DST_NAT == status)
878 	{
879 		IPACMDBG("Destination NAT\n");
880 		rule->dst_nat = true;
881 
882 		IPACMDBG("Parse reply tuple\n");
883 		rule->target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
884 		rule->target_ip = ntohl(rule->target_ip);
885 		iptodot("PopulateTCPorUDPEntry(): target ip", rule->target_ip);
886 
887 		/* Retriev target/dst port */
888 		rule->target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC);
889 		rule->target_port = ntohs(rule->target_port);
890 		if (0 == rule->target_port)
891 		{
892 			IPACMDBG("unable to retrieve target port\n");
893 		}
894 
895 		rule->public_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST);
896 		rule->public_port = ntohs(rule->public_port);
897 
898 		/* Retriev src/private ip address */
899 		rule->private_ip = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC);
900 		rule->private_ip = ntohl(rule->private_ip);
901 		iptodot("PopulateTCPorUDPEntry(): private ip", rule->private_ip);
902 		if (0 == rule->private_ip)
903 		{
904 			IPACMDBG("unable to retrieve private ip address\n");
905 		}
906 
907 		/* Retriev src/private port */
908 		rule->private_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC);
909 		rule->private_port = ntohs(rule->private_port);
910 		if (0 == rule->private_port)
911 		{
912 			IPACMDBG("unable to retrieve private port\n");
913 		}
914 	}
915 	else if (IPS_SRC_NAT == status)
916 	{
917 		IPACMDBG("Source NAT\n");
918 		rule->dst_nat = false;
919 
920 		/* Retriev target/dst ip address */
921 		IPACMDBG("Parse source tuple\n");
922 		rule->target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST);
923 		rule->target_ip = ntohl(rule->target_ip);
924 		iptodot("PopulateTCPorUDPEntry(): target ip", rule->target_ip);
925 		if (0 == rule->target_ip)
926 		{
927 			IPACMDBG("unable to retrieve target ip address\n");
928 		}
929 		/* Retriev target/dst port */
930 		rule->target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST);
931 		rule->target_port = ntohs(rule->target_port);
932 		if (0 == rule->target_port)
933 		{
934 			IPACMDBG("unable to retrieve target port\n");
935 		}
936 
937 		/* Retriev public port */
938 		rule->public_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST);
939 		rule->public_port = ntohs(rule->public_port);
940 		if (0 == rule->public_port)
941 		{
942 			IPACMDBG("unable to retrieve public port\n");
943 		}
944 
945 		/* Retriev src/private ip address */
946 		rule->private_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
947 		rule->private_ip = ntohl(rule->private_ip);
948 		iptodot("PopulateTCPorUDPEntry(): private ip", rule->private_ip);
949 		if (0 == rule->private_ip)
950 		{
951 			IPACMDBG("unable to retrieve private ip address\n");
952 		}
953 
954 		/* Retriev src/private port */
955 		rule->private_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC);
956 		rule->private_port = ntohs(rule->private_port);
957 		if (0 == rule->private_port)
958 		{
959 			IPACMDBG("unable to retrieve private port\n");
960 		}
961 	}
962 
963 	return;
964 }
965 
966 #ifdef CT_OPT
HandleLan2Lan(struct nf_conntrack * ct,enum nf_conntrack_msg_type type,nat_table_entry * rule)967 void IPACM_ConntrackListener::HandleLan2Lan(struct nf_conntrack *ct,
968 	enum nf_conntrack_msg_type type,
969 	 nat_table_entry *rule)
970 {
971 	ipacm_event_connection lan2lan_conn = { 0 };
972 
973 	if (p_lan2lan == NULL)
974 	{
975 		IPACMERR("Lan2Lan Instance is null\n");
976 		return;
977 	}
978 
979 	lan2lan_conn.iptype = IPA_IP_v4;
980 	lan2lan_conn.src_ipv4_addr = orig_src_ip;
981 	lan2lan_conn.dst_ipv4_addr = orig_dst_ip;
982 
983 	if (((IPPROTO_UDP == rule->protocol) && (NFCT_T_NEW == type)) ||
984 		((IPPROTO_TCP == rule->protocol) && (nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_ESTABLISHED)))
985 	{
986 		p_lan2lan->handle_new_connection(&lan2lan_conn);
987 	}
988 	else if ((IPPROTO_UDP == rule->protocol && NFCT_T_DESTROY == type) ||
989 			   (IPPROTO_TCP == rule->protocol &&
990 				nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_FIN_WAIT))
991 	{
992 		p_lan2lan->handle_del_connection(&lan2lan_conn);
993 	}
994 }
995 #endif
996 
CheckSTAClient(const nat_table_entry * rule,bool * isTempEntry)997 void IPACM_ConntrackListener::CheckSTAClient(
998    const nat_table_entry *rule, bool *isTempEntry)
999 {
1000 	int nCnt;
1001 
1002 	/* Check whether target is in STA client list or not
1003       if not ignore the connection */
1004 	 if(!isStaMode || (StaClntCnt == 0))
1005 	 {
1006 		return;
1007 	 }
1008 
1009 	 if((sta_clnt_ipv4_addr[0] & STA_CLNT_SUBNET_MASK) !=
1010 		 (rule->target_ip & STA_CLNT_SUBNET_MASK))
1011 	 {
1012 		IPACMDBG("STA client subnet mask not matching\n");
1013 		return;
1014 	 }
1015 
1016 	 IPACMDBG("StaClntCnt %d\n", StaClntCnt);
1017 	 for(nCnt = 0; nCnt < StaClntCnt; nCnt++)
1018 	 {
1019 		IPACMDBG("Comparing trgt_ip 0x%x with sta clnt ip: 0x%x\n",
1020 			 rule->target_ip, sta_clnt_ipv4_addr[nCnt]);
1021 		if(rule->target_ip == sta_clnt_ipv4_addr[nCnt])
1022 		{
1023 			IPACMDBG("Match index %d\n", nCnt);
1024 			return;
1025 		}
1026 	 }
1027 
1028 	IPACMDBG_H("Not matching with STA Clnt Ip Addrs 0x%x\n",
1029 		rule->target_ip);
1030 	*isTempEntry = true;
1031 }
1032 
1033 /* conntrack send in host order and ipa expects in host order */
ProcessTCPorUDPMsg(struct nf_conntrack * ct,enum nf_conntrack_msg_type type,u_int8_t l4proto)1034 void IPACM_ConntrackListener::ProcessTCPorUDPMsg(
1035 	 struct nf_conntrack *ct,
1036 	 enum nf_conntrack_msg_type type,
1037 	 u_int8_t l4proto)
1038 {
1039 	 nat_table_entry rule;
1040 	 uint32_t status = 0;
1041 	 uint32_t orig_src_ip, orig_dst_ip;
1042 	 bool isAdd = false;
1043 
1044 	 nat_entry_bundle nat_entry;
1045 	 nat_entry.isTempEntry = false;
1046 	 nat_entry.ct = ct;
1047 	 nat_entry.type = type;
1048 
1049  	 memset(&rule, 0, sizeof(rule));
1050 	 IPACMDBG("Received type:%d with proto:%d\n", type, l4proto);
1051 	 status = nfct_get_attr_u32(ct, ATTR_STATUS);
1052 
1053 	 /* Retrieve Protocol */
1054 	 rule.protocol = nfct_get_attr_u8(ct, ATTR_REPL_L4PROTO);
1055 
1056 	 if(IPS_DST_NAT & status)
1057 	 {
1058 		 status = IPS_DST_NAT;
1059 	 }
1060 	 else if(IPS_SRC_NAT & status)
1061 	 {
1062 		 status = IPS_SRC_NAT;
1063 	 }
1064 	 else
1065 	 {
1066 		 IPACMDBG("Neither Destination nor Source nat flag Set\n");
1067 		 orig_src_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
1068 		 orig_src_ip = ntohl(orig_src_ip);
1069 		 if(orig_src_ip == 0)
1070 		 {
1071 			 IPACMERR("unable to retrieve orig src ip address\n");
1072 			 return;
1073 		 }
1074 
1075 		 orig_dst_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST);
1076 		 orig_dst_ip = ntohl(orig_dst_ip);
1077 		 if(orig_dst_ip == 0)
1078 		 {
1079 			 IPACMERR("unable to retrieve orig dst ip address\n");
1080 			 return;
1081 		 }
1082 
1083 		if(orig_src_ip == wan_ipaddr)
1084 		{
1085 			IPACMDBG("orig src ip:0x%x equal to wan ip\n",orig_src_ip);
1086 			status = IPS_SRC_NAT;
1087 		}
1088 		else if(orig_dst_ip == wan_ipaddr)
1089 		{
1090 			IPACMDBG("orig Dst IP:0x%x equal to wan ip\n",orig_dst_ip);
1091 			status = IPS_DST_NAT;
1092 		}
1093 		else
1094 		{
1095 			IPACMDBG_H("Neither orig src ip:0x%x Nor orig Dst IP:0x%x equal to wan ip:0x%x\n",
1096 					   orig_src_ip, orig_dst_ip, wan_ipaddr);
1097 
1098 #ifdef CT_OPT
1099 			HandleLan2Lan(ct, type, &rule);
1100 #endif
1101 			return;
1102 		}
1103 	 }
1104 
1105 	 if(IPS_DST_NAT == status || IPS_SRC_NAT == status)
1106 	 {
1107 		 PopulateTCPorUDPEntry(ct, status, &rule);
1108 		 rule.public_ip = wan_ipaddr;
1109 	 }
1110 	 else
1111 	 {
1112 		 IPACMDBG("Neither source Nor destination nat\n");
1113 		 goto IGNORE;
1114 	 }
1115 
1116 	 if (rule.private_ip != wan_ipaddr)
1117 	 {
1118 		 isAdd = AddIface(&rule, &nat_entry.isTempEntry);
1119 		 if (!isAdd)
1120 		 {
1121 			 goto IGNORE;
1122 		 }
1123 	 }
1124 	 else
1125 	 {
1126 		 if (isStaMode)
1127 		 {
1128 			 IPACMDBG("In STA mode, ignore connections destinated to STA interface\n");
1129 			 goto IGNORE;
1130 		 }
1131 
1132 		 IPACMDBG("For embedded connections add dummy nat rule\n");
1133 		 IPACMDBG("Change private port %d to %d\n",
1134 				  rule.private_port, rule.public_port);
1135 		 rule.private_port = rule.public_port;
1136 	 }
1137 
1138 	 CheckSTAClient(&rule, &nat_entry.isTempEntry);
1139 	 nat_entry.rule = &rule;
1140 	 AddORDeleteNatEntry(&nat_entry);
1141 	 return;
1142 
1143 IGNORE:
1144 	IPACMDBG_H("ignoring below Nat Entry\n");
1145 	iptodot("ProcessTCPorUDPMsg(): target ip or dst ip", rule.target_ip);
1146 	IPACMDBG("target port or dst port: 0x%x Decimal:%d\n", rule.target_port, rule.target_port);
1147 	iptodot("ProcessTCPorUDPMsg(): private ip or src ip", rule.private_ip);
1148 	IPACMDBG("private port or src port: 0x%x, Decimal:%d\n", rule.private_port, rule.private_port);
1149 	IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n", rule.public_port, rule.public_port);
1150 	IPACMDBG("Protocol: %d, destination nat flag: %d\n", rule.protocol, rule.dst_nat);
1151 	return;
1152 }
1153 
HandleSTAClientAddEvt(uint32_t clnt_ip_addr)1154 void IPACM_ConntrackListener::HandleSTAClientAddEvt(uint32_t clnt_ip_addr)
1155 {
1156 	 int cnt;
1157 	 IPACMDBG_H("Received STA client 0x%x\n", clnt_ip_addr);
1158 
1159 	 if(StaClntCnt >= MAX_STA_CLNT_IFACES)
1160 	 {
1161 		IPACMDBG("Max STA client reached, ignore 0x%x\n", clnt_ip_addr);
1162 		return;
1163 	 }
1164 
1165 	 for(cnt=0; cnt<MAX_STA_CLNT_IFACES; cnt++)
1166 	 {
1167 		if(sta_clnt_ipv4_addr[cnt] != 0 &&
1168 		 sta_clnt_ipv4_addr[cnt] == clnt_ip_addr)
1169 		{
1170 			IPACMDBG("Ignoring duplicate one 0x%x\n", clnt_ip_addr);
1171 			break;
1172 		}
1173 
1174 		if(sta_clnt_ipv4_addr[cnt] == 0)
1175 		{
1176 			IPACMDBG("Adding STA client 0x%x at Index: %d\n",
1177 					clnt_ip_addr, cnt);
1178 			sta_clnt_ipv4_addr[cnt] = clnt_ip_addr;
1179 			StaClntCnt++;
1180 			IPACMDBG("STA client cnt %d\n", StaClntCnt);
1181 			break;
1182 		}
1183 
1184 	 }
1185 
1186 	 nat_inst->FlushTempEntries(clnt_ip_addr, true);
1187 	 return;
1188 }
1189 
HandleSTAClientDelEvt(uint32_t clnt_ip_addr)1190 void IPACM_ConntrackListener::HandleSTAClientDelEvt(uint32_t clnt_ip_addr)
1191 {
1192 	 int cnt;
1193 	 IPACMDBG_H("Received STA client 0x%x\n", clnt_ip_addr);
1194 
1195 	 for(cnt=0; cnt<MAX_STA_CLNT_IFACES; cnt++)
1196 	 {
1197 		if(sta_clnt_ipv4_addr[cnt] != 0 &&
1198 		 sta_clnt_ipv4_addr[cnt] == clnt_ip_addr)
1199 		{
1200 			IPACMDBG("Deleting STA client 0x%x at index: %d\n",
1201 					clnt_ip_addr, cnt);
1202 			sta_clnt_ipv4_addr[cnt] = 0;
1203 			nat_inst->DelEntriesOnSTAClntDiscon(clnt_ip_addr);
1204 			StaClntCnt--;
1205 			IPACMDBG("STA client cnt %d\n", StaClntCnt);
1206 			break;
1207 		}
1208 	 }
1209 
1210 	 nat_inst->FlushTempEntries(clnt_ip_addr, false);
1211    return;
1212 }
1213