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