Home | History | Annotate | Download | only in src
      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;
     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 
     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 
    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 
    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 
    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 
    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 */
    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 */
    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 */
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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