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