summaryrefslogtreecommitdiffstats
path: root/src/nat_check.cpp
diff options
context:
space:
mode:
authorIdo Barnea <ibarnea@cisco.com>2016-01-14 04:42:05 +0200
committerIdo Barnea <ibarnea@cisco.com>2016-01-19 04:13:53 +0200
commit62623efc5b700d58335fa994d2e2725863527575 (patch)
treef3140936cd979c7d609bbe91c539f681ddd8e552 /src/nat_check.cpp
parenteee866f42bd0fc8472e6295b4f26bd0697e59f1f (diff)
Adding option to pass NAT info in TCP ACK of first SYN
Diffstat (limited to 'src/nat_check.cpp')
-rwxr-xr-xsrc/nat_check.cpp77
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);
+}