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