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 #include "IPACM_Conntrack_NATApp.h"
30 #include "IPACM_ConntrackClient.h"
31 #ifdef FEATURE_IPACM_HAL
32 #include "IPACM_OffloadManager.h"
33 #endif
34 
35 #define INVALID_IP_ADDR 0x0
36 
37 /* NatApp class Implementation */
38 NatApp *NatApp::pInstance = NULL;
NatApp()39 NatApp::NatApp()
40 {
41 	max_entries = 0;
42 	cache = NULL;
43 
44 	nat_table_hdl = 0;
45 	pub_ip_addr = 0;
46 
47 	curCnt = 0;
48 
49 	pALGPorts = NULL;
50 	nALGPort = 0;
51 
52 	ct = NULL;
53 	ct_hdl = NULL;
54 
55 	memset(temp, 0, sizeof(temp));
56 }
57 
Init(void)58 int NatApp::Init(void)
59 {
60 	IPACM_Config *pConfig;
61 	int size = 0;
62 
63 	pConfig = IPACM_Config::GetInstance();
64 	if(pConfig == NULL)
65 	{
66 		IPACMERR("Unable to get Config instance\n");
67 		return -1;
68 	}
69 
70 	max_entries = pConfig->GetNatMaxEntries();
71 
72 	size = (sizeof(nat_table_entry) * max_entries);
73 	cache = (nat_table_entry *)malloc(size);
74 	if(cache == NULL)
75 	{
76 		IPACMERR("Unable to allocate memory for cache\n");
77 		goto fail;
78 	}
79 	IPACMDBG("Allocated %d bytes for config manager nat cache\n", size);
80 	memset(cache, 0, size);
81 
82 	nALGPort = pConfig->GetAlgPortCnt();
83 	if(nALGPort > 0)
84 	{
85 		pALGPorts = (ipacm_alg *)malloc(sizeof(ipacm_alg) * nALGPort);
86 		if(pALGPorts == NULL)
87 		{
88 			IPACMERR("Unable to allocate memory for alg prots\n");
89 			goto fail;
90 		}
91 		memset(pALGPorts, 0, sizeof(ipacm_alg) * nALGPort);
92 
93 		if(pConfig->GetAlgPorts(nALGPort, pALGPorts) != 0)
94 		{
95 			IPACMERR("Unable to retrieve ALG prots\n");
96 			goto fail;
97 		}
98 
99 		IPACMDBG("Printing %d alg ports information\n", nALGPort);
100 		for(int cnt=0; cnt<nALGPort; cnt++)
101 		{
102 			IPACMDBG("%d: Proto[%d], port[%d]\n", cnt, pALGPorts[cnt].protocol, pALGPorts[cnt].port);
103 		}
104 	}
105 
106 	return 0;
107 
108 fail:
109 	free(cache);
110 	free(pALGPorts);
111 	return -1;
112 }
113 
GetInstance()114 NatApp* NatApp::GetInstance()
115 {
116 	if(pInstance == NULL)
117 	{
118 		pInstance = new NatApp();
119 
120 		if(pInstance->Init())
121 		{
122 			delete pInstance;
123 			return NULL;
124 		}
125 	}
126 
127 	return pInstance;
128 }
129 
130 /* NAT APP related object function definitions */
131 
AddTable(uint32_t pub_ip)132 int NatApp::AddTable(uint32_t pub_ip)
133 {
134 	int ret;
135 	int cnt = 0;
136 	ipa_nat_ipv4_rule nat_rule;
137 	IPACMDBG_H("%s() %d\n", __FUNCTION__, __LINE__);
138 
139 	/* Not reset the cache wait it timeout by destroy event */
140 #if 0
141 	if (pub_ip != pub_ip_addr_pre)
142 	{
143 		IPACMDBG("Reset the cache because NAT-ipv4 different\n");
144 		memset(cache, 0, sizeof(nat_table_entry) * max_entries);
145 		curCnt = 0;
146 	}
147 #endif
148 	ret = ipa_nat_add_ipv4_tbl(pub_ip, max_entries, &nat_table_hdl);
149 	if(ret)
150 	{
151 		IPACMERR("unable to create nat table Error:%d\n", ret);
152 		return ret;
153 	}
154 
155 	/* Add back the cached NAT-entry */
156 	if (pub_ip == pub_ip_addr_pre)
157 	{
158 		IPACMDBG("Restore the cache to ipa NAT-table\n");
159 		for(cnt = 0; cnt < max_entries; cnt++)
160 		{
161 			if(cache[cnt].private_ip !=0)
162 			{
163 				memset(&nat_rule, 0 , sizeof(nat_rule));
164 				nat_rule.private_ip = cache[cnt].private_ip;
165 				nat_rule.target_ip = cache[cnt].target_ip;
166 				nat_rule.target_port = cache[cnt].target_port;
167 				nat_rule.private_port = cache[cnt].private_port;
168 				nat_rule.public_port = cache[cnt].public_port;
169 				nat_rule.protocol = cache[cnt].protocol;
170 
171 				if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
172 				{
173 					IPACMERR("unable to add the rule delete from cache\n");
174 					memset(&cache[cnt], 0, sizeof(cache[cnt]));
175 					curCnt--;
176 					continue;
177 				}
178 				cache[cnt].enabled = true;
179 
180 				IPACMDBG("On wan-iface reset added below rule successfully\n");
181 				iptodot("Private IP", nat_rule.private_ip);
182 				iptodot("Target IP", nat_rule.target_ip);
183 				IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port);
184 				IPACMDBG("Public Port:%d\n", nat_rule.public_port);
185 				IPACMDBG("protocol: %d\n", nat_rule.protocol);
186 			}
187 		}
188 	}
189 
190 	pub_ip_addr = pub_ip;
191 	return 0;
192 }
193 
Reset()194 void NatApp::Reset()
195 {
196 	int cnt = 0;
197 
198 	nat_table_hdl = 0;
199 	pub_ip_addr = 0;
200 	/* NAT tbl deleted, reset enabled bit */
201 	for(cnt = 0; cnt < max_entries; cnt++)
202 	{
203 		cache[cnt].enabled = false;
204 	}
205 }
206 
DeleteTable(uint32_t pub_ip)207 int NatApp::DeleteTable(uint32_t pub_ip)
208 {
209 	int ret;
210 	IPACMDBG_H("%s() %d\n", __FUNCTION__, __LINE__);
211 
212 	CHK_TBL_HDL();
213 
214 	if(pub_ip_addr != pub_ip)
215 	{
216 		IPACMDBG("Public ip address is not matching\n");
217 		IPACMERR("unable to delete the nat table\n");
218 		return -1;
219 	}
220 
221 	ret = ipa_nat_del_ipv4_tbl(nat_table_hdl);
222 	if(ret)
223 	{
224 		IPACMERR("unable to delete nat table Error: %d\n", ret);;
225 		return ret;
226 	}
227 
228 	pub_ip_addr_pre = pub_ip_addr;
229 	Reset();
230 	return 0;
231 }
232 
233 /* Check for duplicate entries */
ChkForDup(const nat_table_entry * rule)234 bool NatApp::ChkForDup(const nat_table_entry *rule)
235 {
236 	int cnt = 0;
237 	IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
238 
239 	for(; cnt < max_entries; cnt++)
240 	{
241 		if(cache[cnt].private_ip == rule->private_ip &&
242 			 cache[cnt].target_ip == rule->target_ip &&
243 			 cache[cnt].private_port ==  rule->private_port  &&
244 			 cache[cnt].target_port == rule->target_port &&
245 			 cache[cnt].protocol == rule->protocol)
246 		{
247 			log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
248 			rule->target_port,"Duplicate Rule\n");
249 			return true;
250 		}
251 	}
252 
253 	return false;
254 }
255 
256 /* Delete the entry from Nat table on connection close */
DeleteEntry(const nat_table_entry * rule)257 int NatApp::DeleteEntry(const nat_table_entry *rule)
258 {
259 	int cnt = 0;
260 	IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
261 
262 	log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
263 	rule->target_port,"for deletion\n");
264 
265 
266 	for(; cnt < max_entries; cnt++)
267 	{
268 		if(cache[cnt].private_ip == rule->private_ip &&
269 			 cache[cnt].target_ip == rule->target_ip &&
270 			 cache[cnt].private_port ==  rule->private_port  &&
271 			 cache[cnt].target_port == rule->target_port &&
272 			 cache[cnt].protocol == rule->protocol)
273 		{
274 
275 			if(cache[cnt].enabled == true)
276 			{
277 				if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
278 				{
279 					IPACMERR("%s() %d deletion failed\n", __FUNCTION__, __LINE__);
280 				}
281 
282 				IPACMDBG_H("Deleted Nat entry(%d) Successfully\n", cnt);
283 			}
284 			else
285 			{
286 				IPACMDBG_H("Deleted Nat entry(%d) only from cache\n", cnt);
287 			}
288 
289 			memset(&cache[cnt], 0, sizeof(cache[cnt]));
290 			curCnt--;
291 			break;
292 		}
293 	}
294 
295 	return 0;
296 }
297 
298 /* Add new entry to the nat table on new connection */
AddEntry(const nat_table_entry * rule)299 int NatApp::AddEntry(const nat_table_entry *rule)
300 {
301 	int cnt = 0;
302 	ipa_nat_ipv4_rule nat_rule;
303 
304 	IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
305 
306 	CHK_TBL_HDL();
307 	log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
308 	rule->target_port,"for addition\n");
309 	if(isAlgPort(rule->protocol, rule->private_port) ||
310 		 isAlgPort(rule->protocol, rule->target_port))
311 	{
312 		IPACMERR("connection using ALG Port, ignore\n");
313 		return -1;
314 	}
315 
316 	if(rule->private_ip == 0 ||
317 		 rule->target_ip == 0 ||
318 		 rule->private_port == 0  ||
319 		 rule->target_port == 0 ||
320 		 rule->protocol == 0)
321 	{
322 		IPACMERR("Invalid Connection, ignoring it\n");
323 		return 0;
324 	}
325 
326 	if(!ChkForDup(rule))
327 	{
328 		for(; cnt < max_entries; cnt++)
329 		{
330 			if(cache[cnt].private_ip == 0 &&
331 				 cache[cnt].target_ip == 0 &&
332 				 cache[cnt].private_port == 0  &&
333 				 cache[cnt].target_port == 0 &&
334 				 cache[cnt].protocol == 0)
335 			{
336 				break;
337 			}
338 		}
339 
340 		if(max_entries == cnt)
341 		{
342 			IPACMERR("Error: Unable to add, reached maximum rules\n");
343 			return -1;
344 		}
345 		else
346 		{
347 			nat_rule.private_ip = rule->private_ip;
348 			nat_rule.target_ip = rule->target_ip;
349 			nat_rule.target_port = rule->target_port;
350 			nat_rule.private_port = rule->private_port;
351 			nat_rule.public_port = rule->public_port;
352 			nat_rule.protocol = rule->protocol;
353 
354 			if(isPwrSaveIf(rule->private_ip) ||
355 				 isPwrSaveIf(rule->target_ip))
356 			{
357 				IPACMDBG("Device is Power Save mode: Dont insert into nat table but cache\n");
358 				cache[cnt].enabled = false;
359 				cache[cnt].rule_hdl = 0;
360 			}
361 			else
362 			{
363 
364 				if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
365 				{
366 					IPACMERR("unable to add the rule\n");
367 					return -1;
368 				}
369 
370 				cache[cnt].enabled = true;
371 			}
372 
373 			cache[cnt].private_ip = rule->private_ip;
374 			cache[cnt].target_ip = rule->target_ip;
375 			cache[cnt].target_port = rule->target_port;
376 			cache[cnt].private_port = rule->private_port;
377 			cache[cnt].protocol = rule->protocol;
378 			cache[cnt].timestamp = 0;
379 			cache[cnt].public_port = rule->public_port;
380 			cache[cnt].dst_nat = rule->dst_nat;
381 			curCnt++;
382 		}
383 
384 	}
385 	else
386 	{
387 		IPACMERR("Duplicate rule. Ignore it\n");
388 		return -1;
389 	}
390 
391 	if(cache[cnt].enabled == true)
392 	{
393 		IPACMDBG_H("Added rule(%d) successfully\n", cnt);
394 	}
395   else
396   {
397     IPACMDBG_H("Cached rule(%d) successfully\n", cnt);
398   }
399 
400 	return 0;
401 }
402 
UpdateCTUdpTs(nat_table_entry * rule,uint32_t new_ts)403 void NatApp::UpdateCTUdpTs(nat_table_entry *rule, uint32_t new_ts)
404 {
405 #ifdef FEATURE_IPACM_HAL
406 	IOffloadManager::ConntrackTimeoutUpdater::natTimeoutUpdate_t entry;
407 	IPACM_OffloadManager* OffloadMng;
408 #endif
409 	iptodot("Private IP:", rule->private_ip);
410 	iptodot("Target IP:",  rule->target_ip);
411 	IPACMDBG("Private Port: %d, Target Port: %d\n", rule->private_port, rule->target_port);
412 
413 #ifndef FEATURE_IPACM_HAL
414 	int ret;
415 	if(!ct_hdl)
416 	{
417 		ct_hdl = nfct_open(CONNTRACK, 0);
418 		if(!ct_hdl)
419 		{
420 			PERROR("nfct_open");
421 			return;
422 		}
423 	}
424 
425 	if(!ct)
426 	{
427 		ct = nfct_new();
428 		if(!ct)
429 		{
430 			PERROR("nfct_new");
431 			return;
432 		}
433 	}
434 
435 	nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
436 	if(rule->protocol == IPPROTO_UDP)
437 	{
438 		nfct_set_attr_u8(ct, ATTR_L4PROTO, rule->protocol);
439 		nfct_set_attr_u32(ct, ATTR_TIMEOUT, udp_timeout);
440 	}
441 	else
442 	{
443 		nfct_set_attr_u8(ct, ATTR_L4PROTO, rule->protocol);
444 		nfct_set_attr_u32(ct, ATTR_TIMEOUT, tcp_timeout);
445 	}
446 
447 	if(rule->dst_nat == false)
448 	{
449 		nfct_set_attr_u32(ct, ATTR_IPV4_SRC, htonl(rule->private_ip));
450 		nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(rule->private_port));
451 
452 		nfct_set_attr_u32(ct, ATTR_IPV4_DST, htonl(rule->target_ip));
453 		nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(rule->target_port));
454 
455 		IPACMDBG("dst nat is not set\n");
456 	}
457 	else
458 	{
459 		nfct_set_attr_u32(ct, ATTR_IPV4_SRC, htonl(rule->target_ip));
460 		nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(rule->target_port));
461 
462 		nfct_set_attr_u32(ct, ATTR_IPV4_DST, htonl(pub_ip_addr));
463 		nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(rule->public_port));
464 
465 		IPACMDBG("dst nat is set\n");
466 	}
467 
468 	iptodot("Source IP:", nfct_get_attr_u32(ct, ATTR_IPV4_SRC));
469 	iptodot("Destination IP:",  nfct_get_attr_u32(ct, ATTR_IPV4_DST));
470 	IPACMDBG("Source Port: %d, Destination Port: %d\n",
471 					 nfct_get_attr_u16(ct, ATTR_PORT_SRC), nfct_get_attr_u16(ct, ATTR_PORT_DST));
472 
473 	IPACMDBG("updating %d connection with time: %d\n",
474 					 rule->protocol, nfct_get_attr_u32(ct, ATTR_TIMEOUT));
475 
476 	ret = nfct_query(ct_hdl, NFCT_Q_UPDATE, ct);
477 	if(ret == -1)
478 	{
479 		IPACMERR("unable to update time stamp");
480 		DeleteEntry(rule);
481 	}
482 	else
483 	{
484 		rule->timestamp = new_ts;
485 		IPACMDBG("Updated time stamp successfully\n");
486 	}
487 #else
488 	if(rule->protocol == IPPROTO_UDP)
489 	{
490 		entry.proto = IOffloadManager::ConntrackTimeoutUpdater::UDP;;
491 	}
492 	else
493 	{
494 		entry.proto = IOffloadManager::ConntrackTimeoutUpdater::TCP;
495 	}
496 
497 	if(rule->dst_nat == false)
498 	{
499 		entry.src.ipAddr = htonl(rule->private_ip);
500 		entry.src.port = rule->private_port;
501 		entry.dst.ipAddr = htonl(rule->target_ip);
502 		entry.dst.port = rule->target_port;
503 		IPACMDBG("dst nat is not set\n");
504 	}
505 	else
506 	{
507 		entry.src.ipAddr = htonl(rule->target_ip);
508 		entry.src.port = rule->target_port;
509 		entry.dst.ipAddr = htonl(pub_ip_addr);
510 		entry.dst.port = rule->public_port;
511 		IPACMDBG("dst nat is set\n");
512 	}
513 
514 	iptodot("Source IP:", entry.src.ipAddr);
515 	iptodot("Destination IP:",  entry.dst.ipAddr);
516 	IPACMDBG("Source Port: %d, Destination Port: %d\n",
517 					entry.src.port, entry.dst.port);
518 
519 	OffloadMng = IPACM_OffloadManager::GetInstance();
520 	if (OffloadMng->touInstance == NULL) {
521 		IPACMERR("OffloadMng->touInstance is NULL, can't forward to framework!\n");
522 	} else {
523 		OffloadMng->touInstance->updateTimeout(entry);
524 		IPACMDBG("Updated time stamp successfully\n");
525 		rule->timestamp = new_ts;
526 	}
527 #endif
528 	return;
529 }
530 
UpdateUDPTimeStamp()531 void NatApp::UpdateUDPTimeStamp()
532 {
533 	int cnt;
534 	uint32_t ts;
535 	bool read_to = false;
536 
537 	for(cnt = 0; cnt < max_entries; cnt++)
538 	{
539 		ts = 0;
540 		if(cache[cnt].enabled == true &&
541 		   (cache[cnt].private_ip != cache[cnt].public_ip))
542 		{
543 			IPACMDBG("\n");
544 			if(ipa_nat_query_timestamp(nat_table_hdl, cache[cnt].rule_hdl, &ts) < 0)
545 			{
546 				IPACMERR("unable to retrieve timeout for rule hanle: %d\n", cache[cnt].rule_hdl);
547 				continue;
548 			}
549 
550 			if(cache[cnt].timestamp == ts)
551 			{
552 				IPACMDBG("No Change in Time Stamp: cahce:%d, ipahw:%d\n",
553 								                  cache[cnt].timestamp, ts);
554 				continue;
555 			}
556 
557 			if (read_to == false) {
558 				read_to = true;
559 				Read_TcpUdp_Timeout();
560 			}
561 
562 			UpdateCTUdpTs(&cache[cnt], ts);
563 		} /* end of outer if */
564 
565 	} /* end of for loop */
566 
567 }
568 
isAlgPort(uint8_t proto,uint16_t port)569 bool NatApp::isAlgPort(uint8_t proto, uint16_t port)
570 {
571 	int cnt;
572 	for(cnt = 0; cnt < nALGPort; cnt++)
573 	{
574 		if(proto == pALGPorts[cnt].protocol &&
575 			 port == pALGPorts[cnt].port)
576 		{
577 			return true;
578 		}
579 	}
580 
581 	return false;
582 }
583 
isPwrSaveIf(uint32_t ip_addr)584 bool NatApp::isPwrSaveIf(uint32_t ip_addr)
585 {
586 	int cnt;
587 
588 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
589 	{
590 		if(0 != PwrSaveIfs[cnt] &&
591 			 ip_addr == PwrSaveIfs[cnt])
592 		{
593 			return true;
594 		}
595 	}
596 
597 	return false;
598 }
599 
UpdatePwrSaveIf(uint32_t client_lan_ip)600 int NatApp::UpdatePwrSaveIf(uint32_t client_lan_ip)
601 {
602 	int cnt;
603 	IPACMDBG_H("Received IP address: 0x%x\n", client_lan_ip);
604 
605 	if(client_lan_ip == INVALID_IP_ADDR)
606 	{
607 		IPACMERR("Invalid ip address received\n");
608 		return -1;
609 	}
610 
611 	/* check for duplicate events */
612 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
613 	{
614 		if(PwrSaveIfs[cnt] == client_lan_ip)
615 		{
616 			IPACMDBG("The client 0x%x is already in power save\n", client_lan_ip);
617 			return 0;
618 		}
619 	}
620 
621 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
622 	{
623 		if(PwrSaveIfs[cnt] == 0)
624 		{
625 			PwrSaveIfs[cnt] = client_lan_ip;
626 			break;
627 		}
628 	}
629 
630 	for(cnt = 0; cnt < max_entries; cnt++)
631 	{
632 		if(cache[cnt].private_ip == client_lan_ip &&
633 			 cache[cnt].enabled == true)
634 		{
635 			if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
636 			{
637 				IPACMERR("unable to delete the rule\n");
638 				continue;
639 			}
640 
641 			cache[cnt].enabled = false;
642 			cache[cnt].rule_hdl = 0;
643 		}
644 	}
645 
646 	return 0;
647 }
648 
ResetPwrSaveIf(uint32_t client_lan_ip)649 int NatApp::ResetPwrSaveIf(uint32_t client_lan_ip)
650 {
651 	int cnt;
652 	ipa_nat_ipv4_rule nat_rule;
653 
654 	IPACMDBG_H("Received ip address: 0x%x\n", client_lan_ip);
655 
656 	if(client_lan_ip == INVALID_IP_ADDR)
657 	{
658 		IPACMERR("Invalid ip address received\n");
659 		return -1;
660 	}
661 
662 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
663 	{
664 		if(PwrSaveIfs[cnt] == client_lan_ip)
665 		{
666 			PwrSaveIfs[cnt] = 0;
667 			break;
668 		}
669 	}
670 
671 	for(cnt = 0; cnt < max_entries; cnt++)
672 	{
673 		IPACMDBG("cache (%d): enable %d, ip 0x%x\n", cnt, cache[cnt].enabled, cache[cnt].private_ip);
674 
675 		if(cache[cnt].private_ip == client_lan_ip &&
676 			 cache[cnt].enabled == false)
677 		{
678 			memset(&nat_rule, 0 , sizeof(nat_rule));
679 			nat_rule.private_ip = cache[cnt].private_ip;
680 			nat_rule.target_ip = cache[cnt].target_ip;
681 			nat_rule.target_port = cache[cnt].target_port;
682 			nat_rule.private_port = cache[cnt].private_port;
683 			nat_rule.public_port = cache[cnt].public_port;
684 			nat_rule.protocol = cache[cnt].protocol;
685 
686 			if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
687 			{
688 				IPACMERR("unable to add the rule delete from cache\n");
689 				memset(&cache[cnt], 0, sizeof(cache[cnt]));
690 				curCnt--;
691 				continue;
692 			}
693 			cache[cnt].enabled = true;
694 
695 			IPACMDBG("On power reset added below rule successfully\n");
696 			iptodot("Private IP", nat_rule.private_ip);
697 			iptodot("Target IP", nat_rule.target_ip);
698 			IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port);
699 			IPACMDBG("Public Port:%d\n", nat_rule.public_port);
700 			IPACMDBG("protocol: %d\n", nat_rule.protocol);
701 
702 		}
703 	}
704 
705 	return -1;
706 }
707 
GetTableHdl(uint32_t in_ip_addr)708 uint32_t NatApp::GetTableHdl(uint32_t in_ip_addr)
709 {
710 	if(in_ip_addr == pub_ip_addr)
711 	{
712 		return nat_table_hdl;
713 	}
714 
715 	return -1;
716 }
717 
AddTempEntry(const nat_table_entry * new_entry)718 void NatApp::AddTempEntry(const nat_table_entry *new_entry)
719 {
720 	int cnt;
721 
722 	IPACMDBG("Received below Temp Nat entry\n");
723 	iptodot("Private IP", new_entry->private_ip);
724 	iptodot("Target IP", new_entry->target_ip);
725 	IPACMDBG("Private Port: %d\t Target Port: %d\t", new_entry->private_port, new_entry->target_port);
726 	IPACMDBG("protocolcol: %d\n", new_entry->protocol);
727 
728 	if(isAlgPort(new_entry->protocol, new_entry->private_port) ||
729 		 isAlgPort(new_entry->protocol, new_entry->target_port))
730 	{
731 		IPACMDBG("connection using ALG Port. Dont insert into nat cache\n");
732 		return;
733 	}
734 
735 	if(ChkForDup(new_entry))
736 	{
737 		return;
738 	}
739 
740 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
741 	{
742 		if(temp[cnt].private_ip == new_entry->private_ip &&
743 			 temp[cnt].target_ip == new_entry->target_ip &&
744 			 temp[cnt].private_port ==  new_entry->private_port  &&
745 			 temp[cnt].target_port == new_entry->target_port &&
746 			 temp[cnt].protocol == new_entry->protocol)
747 		{
748 			IPACMDBG("Received duplicate Temp entry\n");
749 			return;
750 		}
751 	}
752 
753 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
754 	{
755 		if(temp[cnt].private_ip == 0 &&
756 			 temp[cnt].target_ip == 0)
757 		{
758 			memcpy(&temp[cnt], new_entry, sizeof(nat_table_entry));
759 			IPACMDBG("Added Temp Entry\n");
760 			return;
761 		}
762 	}
763 
764 	IPACMDBG("Unable to add temp entry, cache full\n");
765 	return;
766 }
767 
DeleteTempEntry(const nat_table_entry * entry)768 void NatApp::DeleteTempEntry(const nat_table_entry *entry)
769 {
770 	int cnt;
771 
772 	IPACMDBG("Received below nat entry\n");
773 	iptodot("Private IP", entry->private_ip);
774 	iptodot("Target IP", entry->target_ip);
775 	IPACMDBG("Private Port: %d\t Target Port: %d\n", entry->private_port, entry->target_port);
776 	IPACMDBG("protocol: %d\n", entry->protocol);
777 
778 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
779 	{
780 		if(temp[cnt].private_ip == entry->private_ip &&
781 			 temp[cnt].target_ip == entry->target_ip &&
782 			 temp[cnt].private_port ==  entry->private_port  &&
783 			 temp[cnt].target_port == entry->target_port &&
784 			 temp[cnt].protocol == entry->protocol)
785 		{
786 			memset(&temp[cnt], 0, sizeof(nat_table_entry));
787 			IPACMDBG("Delete Temp Entry\n");
788 			return;
789 		}
790 	}
791 
792 	IPACMDBG("No Such Temp Entry exists\n");
793 	return;
794 }
795 
FlushTempEntries(uint32_t ip_addr,bool isAdd,bool isDummy)796 void NatApp::FlushTempEntries(uint32_t ip_addr, bool isAdd,
797 		bool isDummy)
798 {
799 	int cnt;
800 	int ret;
801 
802 	IPACMDBG_H("Received below with isAdd:%d ", isAdd);
803 	iptodot("IP Address: ", ip_addr);
804 
805 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
806 	{
807 		if(temp[cnt].private_ip == ip_addr ||
808 			 temp[cnt].target_ip == ip_addr)
809 		{
810 			if(isAdd)
811 			{
812 				if(temp[cnt].public_ip == pub_ip_addr)
813 				{
814 					if (isDummy) {
815 						/* To avoild DL expections for non IPA path */
816 						temp[cnt].private_ip = temp[cnt].public_ip;
817 						temp[cnt].private_port = temp[cnt].public_port;
818 						IPACMDBG("Flushing dummy temp rule");
819 						iptodot("Private IP", temp[cnt].private_ip);
820 					}
821 
822 					ret = AddEntry(&temp[cnt]);
823 					if(ret)
824 					{
825 						IPACMERR("unable to add temp entry: %d\n", ret);
826 						continue;
827 					}
828 				}
829 			}
830 			memset(&temp[cnt], 0, sizeof(nat_table_entry));
831 		}
832 	}
833 
834 	return;
835 }
836 
DelEntriesOnClntDiscon(uint32_t ip_addr)837 int NatApp::DelEntriesOnClntDiscon(uint32_t ip_addr)
838 {
839 	int cnt, tmp = 0;
840 	IPACMDBG_H("Received IP address: 0x%x\n", ip_addr);
841 
842 	if(ip_addr == INVALID_IP_ADDR)
843 	{
844 		IPACMERR("Invalid ip address received\n");
845 		return -1;
846 	}
847 
848 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
849 	{
850 		if(PwrSaveIfs[cnt] == ip_addr)
851 		{
852 			PwrSaveIfs[cnt] = 0;
853 			IPACMDBG("Remove %d power save entry\n", cnt);
854 			break;
855 		}
856 	}
857 
858 	for(cnt = 0; cnt < max_entries; cnt++)
859 	{
860 		if(cache[cnt].private_ip == ip_addr)
861 		{
862 			if(cache[cnt].enabled == true)
863 			{
864 				if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
865 				{
866 					IPACMERR("unable to delete the rule\n");
867 					continue;
868 				}
869 				else
870 				{
871 					IPACMDBG("won't delete the rule\n");
872 					cache[cnt].enabled = false;
873 					tmp++;
874 				}
875 			}
876 			IPACMDBG("won't delete the rule for entry %d, enabled %d\n",cnt, cache[cnt].enabled);
877 		}
878 	}
879 
880 	IPACMDBG("Deleted (but cached) %d entries\n", tmp);
881 	return 0;
882 }
883 
DelEntriesOnSTAClntDiscon(uint32_t ip_addr)884 int NatApp::DelEntriesOnSTAClntDiscon(uint32_t ip_addr)
885 {
886 	int cnt, tmp = curCnt;
887 	IPACMDBG_H("Received IP address: 0x%x\n", ip_addr);
888 
889 	if(ip_addr == INVALID_IP_ADDR)
890 	{
891 		IPACMERR("Invalid ip address received\n");
892 		return -1;
893 	}
894 
895 
896 	for(cnt = 0; cnt < max_entries; cnt++)
897 	{
898 		if(cache[cnt].target_ip == ip_addr)
899 		{
900 			if(cache[cnt].enabled == true)
901 			{
902 				if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
903 				{
904 					IPACMERR("unable to delete the rule\n");
905 					continue;
906 				}
907 			}
908 
909 			memset(&cache[cnt], 0, sizeof(cache[cnt]));
910 			curCnt--;
911 		}
912 	}
913 
914 	IPACMDBG("Deleted %d entries\n", (tmp - curCnt));
915 	return 0;
916 }
917 
CacheEntry(const nat_table_entry * rule)918 void NatApp::CacheEntry(const nat_table_entry *rule)
919 {
920 	int cnt;
921 
922 	if(rule->private_ip == 0 ||
923 		 rule->target_ip == 0 ||
924 		 rule->private_port == 0  ||
925 		 rule->target_port == 0 ||
926 		 rule->protocol == 0)
927 	{
928 		IPACMERR("Invalid Connection, ignoring it\n");
929 		return;
930 	}
931 
932 	if(!ChkForDup(rule))
933 	{
934 		for(cnt=0; cnt < max_entries; cnt++)
935 		{
936 			if(cache[cnt].private_ip == 0 &&
937 				 cache[cnt].target_ip == 0 &&
938 				 cache[cnt].private_port == 0  &&
939 				 cache[cnt].target_port == 0 &&
940 				 cache[cnt].protocol == 0)
941 			{
942 				break;
943 			}
944 		}
945 
946 		if(max_entries == cnt)
947 		{
948 			IPACMERR("Error: Unable to add, reached maximum rules\n");
949 			return;
950 		}
951 		else
952 		{
953 			cache[cnt].enabled = false;
954 			cache[cnt].rule_hdl = 0;
955 			cache[cnt].private_ip = rule->private_ip;
956 			cache[cnt].target_ip = rule->target_ip;
957 			cache[cnt].target_port = rule->target_port;
958 			cache[cnt].private_port = rule->private_port;
959 			cache[cnt].protocol = rule->protocol;
960 			cache[cnt].timestamp = 0;
961 			cache[cnt].public_port = rule->public_port;
962 			cache[cnt].public_ip = rule->public_ip;
963 			cache[cnt].dst_nat = rule->dst_nat;
964 			curCnt++;
965 		}
966 
967 	}
968 	else
969 	{
970 		IPACMERR("Duplicate rule. Ignore it\n");
971 		return;
972 	}
973 
974 	IPACMDBG("Cached rule(%d) successfully\n", cnt);
975 	return;
976 }
977 
Read_TcpUdp_Timeout(void)978 void NatApp::Read_TcpUdp_Timeout(void) {
979 #ifdef FEATURE_IPACM_HAL
980 	tcp_timeout = 432000;
981 	udp_timeout = 180;
982 	IPACMDBG_H("udp timeout value: %d\n", udp_timeout);
983 	IPACMDBG_H("tcp timeout value: %d\n", tcp_timeout);
984 #else
985 	FILE *udp_fd = NULL, *tcp_fd = NULL;
986 	/* Read UDP timeout value */
987 	udp_fd = fopen(IPACM_UDP_FULL_FILE_NAME, "r");
988 	if (udp_fd == NULL) {
989 		IPACMERR("unable to open %s\n", IPACM_UDP_FULL_FILE_NAME);
990 		goto fail;
991 	}
992 
993 	if (fscanf(udp_fd, "%d", &udp_timeout) != 1) {
994 		IPACMERR("Error reading udp timeout\n");
995 	}
996 	IPACMDBG_H("udp timeout value: %d\n", udp_timeout);
997 
998 
999 	/* Read TCP timeout value */
1000 	tcp_fd = fopen(IPACM_TCP_FULL_FILE_NAME, "r");
1001 	if (tcp_fd == NULL) {
1002 		IPACMERR("unable to open %s\n", IPACM_TCP_FULL_FILE_NAME);
1003 		goto fail;
1004 	}
1005 
1006 
1007 	if (fscanf(tcp_fd, "%d", &tcp_timeout) != 1) {
1008 		IPACMERR("Error reading tcp timeout\n");
1009 	}
1010 	IPACMDBG_H("tcp timeout value: %d\n", tcp_timeout);
1011 
1012 fail:
1013 	if (udp_fd) {
1014 		fclose(udp_fd);
1015 	}
1016 	if (tcp_fd) {
1017 		fclose(tcp_fd);
1018 	}
1019 #endif
1020 	return;
1021 }
1022