diff options
Diffstat (limited to 'src/nat_check.cpp')
-rwxr-xr-x | src/nat_check.cpp | 77 |
1 files changed, 59 insertions, 18 deletions
diff --git a/src/nat_check.cpp b/src/nat_check.cpp index 170d2de6..7e224430 100755 --- a/src/nat_check.cpp +++ b/src/nat_check.cpp @@ -1,13 +1,10 @@ -#include <stdint.h> -#include "nat_check.h" -#include "bp_sim.h" /* Hanoh Haim Cisco Systems, Inc. */ /* -Copyright (c) 2015-2015 Cisco Systems, Inc. +Copyright (c) 2015-2016 Cisco Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,6 +18,21 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +/* +This file is for testing devices implementing NAT. +For each flow, we need to learn the NAT translation in order to send server responses. +Algorithm is as described below: +We send first packet from client, and look at it on other side to see how it was changed. Then we configure +the server flow with the appropriate change. To keep track of which flow the packet belongs to, we attach to the +first packet of each flow, flow id and thread id (thread handling the flow). +Information attaching method can be chosen be using --learn-mode option. +The information is attached either in special IP option, or in ACK number of first SYN packet. +*/ + +#include <stdint.h> +#include <common/basic_utils.h> +#include "nat_check.h" +#include "bp_sim.h" void CGenNodeNatInfo::dump(FILE *fd){ @@ -122,14 +134,24 @@ void CNatRxManager::flush_node(CNatPerThreadInfo * thread_info){ thread_info->m_cur_nat_msg=0; } +void CNatRxManager::get_info_from_tcp_ack(uint32_t tcp_ack, uint32_t &fid, uint8_t &thread_info) { + thread_info = (uint8_t) tcp_ack; + fid = (tcp_ack >> 8) & NAT_FLOW_ID_MASK; +} -void CNatRxManager::handle_packet_ipv4(CNatOption * option, - IPHeader * ipv4){ +/* + * We handle NAT info. Extracting IP src/dst and protocol from the packet. + * Adding the information to a msg to be sent to the thread handling this flow. + * Thread and flow info is extracted from IP packet. Either from IP option or TCP ACK. + * Parameters: + * option - pointer to our proprietary NAT info IP option. + * If it is NULL, the NAT info is in the TCP ACK number + * ipv4 - pointer to ipv4 header to extract info from. + */ +void CNatRxManager::handle_packet_ipv4(CNatOption *option, IPHeader *ipv4) { + CNatPerThreadInfo * thread_info; + uint32_t fid=0; - CNatPerThreadInfo * thread_info=get_thread_info(option->get_thread_id()); - if (!thread_info) { - return; - } /* Extract info from the packet ! */ uint32_t ext_ip = ipv4->getSourceIp(); uint32_t ext_ip_server = ipv4->getDestIp(); @@ -140,12 +162,25 @@ void CNatRxManager::handle_packet_ipv4(CNatOption * option, return; } /* we support only TCP/UDP so take the source port , post IP header */ - UDPHeader * udp= (UDPHeader *) (((char *)ipv4)+ ipv4->getHeaderLength()); - uint16_t ext_port = udp->getSourcePort(); - #ifdef NAT_TRACE_ - printf("rx msg ext ip : %08x:%08x ext port : %04x flow_id : %d \n",ext_ip,ext_ip_server,ext_port,option->get_fid()); - #endif + TCPHeader *tcp = (TCPHeader *) (((char *)ipv4)+ ipv4->getHeaderLength()); + uint16_t ext_port = tcp->getSourcePort(); + + if (option) { + thread_info = get_thread_info(option->get_thread_id()); + fid = option->get_fid(); + } else { + uint8_t thread_id; + get_info_from_tcp_ack(tcp->getAckNumber(), fid, thread_id); + thread_info = get_thread_info(thread_id); + } + if (unlikely(!thread_info)) { + return; + } + +#ifdef NAT_TRACE_ + printf("rx msg ext ip : %08x:%08x ext port : %04x flow_id : %d \n",ext_ip,ext_ip_server,ext_port, fid); +#endif CGenNodeNatInfo * node=thread_info->m_cur_nat_msg; if ( !node ){ @@ -162,7 +197,7 @@ void CNatRxManager::handle_packet_ipv4(CNatOption * option, msg->m_external_ip = ext_ip; msg->m_external_ip_server = ext_ip_server; msg->m_external_port = ext_port; - msg->m_fid = option->get_fid(); + msg->m_fid = fid; msg->m_pad = 0xee; if ( node->is_full() ){ @@ -193,5 +228,11 @@ void CNatRxManager::DumpShort(FILE *fd){ fprintf(fd,"nat check msgs: %lu, errors: %lu \n",m_stats.m_total_msg,m_stats.get_errs() ); } - - +void CNatOption::dump(FILE *fd) { + fprintf(fd," op : %x \n",get_option_type()); + fprintf(fd," ol : %x \n",get_option_len()); + fprintf(fd," thread_id : %x \n",get_thread_id()); + fprintf(fd," magic : %x \n",get_magic()); + fprintf(fd," fid : %x \n",get_fid()); + utl_DumpBuffer(stdout,(void *)&u.m_data[0],8,0); +} |