summaryrefslogtreecommitdiffstats
path: root/src/bp_sim.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/bp_sim.h')
-rwxr-xr-xsrc/bp_sim.h114
1 files changed, 73 insertions, 41 deletions
diff --git a/src/bp_sim.h b/src/bp_sim.h
index d2812688..49e0e8dc 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -65,8 +65,6 @@ limitations under the License.
class CGenNodePCAP;
-#undef NAT_TRACE_
-
#define FORCE_NO_INLINE __attribute__ ((noinline))
#define FORCE_INLINE __attribute__((always_inline))
@@ -84,10 +82,6 @@ typedef struct {
*/
#define INET_PORTSTRLEN 5
-
-
-
-
/* VM commands */
class CMiniVMCmdBase {
@@ -757,7 +751,10 @@ public:
LEARN_MODE_DISABLED=0,
LEARN_MODE_TCP_ACK=1,
LEARN_MODE_IP_OPTION=2,
- LEARN_MODE_MAX=LEARN_MODE_IP_OPTION
+ LEARN_MODE_TCP_ACK_NO_SERVER_SEQ_RAND=3,
+ LEARN_MODE_MAX=LEARN_MODE_TCP_ACK_NO_SERVER_SEQ_RAND,
+ // This is used to check if 1 or 3 exist
+ LEARN_MODE_TCP=100
};
public:
@@ -1246,7 +1243,11 @@ public:
}
static inline bool is_learn_mode(CParserOption::trex_learn_mode_e mode){
- return ( (m_options.m_learn_mode == mode));
+ if (mode == CParserOption::LEARN_MODE_TCP) {
+ return ((m_options.m_learn_mode == CParserOption::LEARN_MODE_TCP_ACK_NO_SERVER_SEQ_RAND)
+ || (m_options.m_learn_mode == CParserOption::LEARN_MODE_TCP_ACK));
+ } else
+ return (m_options.m_learn_mode == mode);
}
static inline bool is_ipv6_enable(void){
@@ -1558,11 +1559,11 @@ public:
CTupleGeneratorSmart *m_tuple_gen;
// cache line 1 - 64bytes waste of space !
- uint32_t m_nat_external_ipv4; /* client */
- uint32_t m_nat_external_ipv4_server;
- uint16_t m_nat_external_port;
-
- uint16_t m_nat_pad[3];
+ uint32_t m_nat_external_ipv4; // NAT client IP
+ uint32_t m_nat_tcp_seq_diff_client; // support for firewalls that do TCP seq num randomization
+ uint32_t m_nat_tcp_seq_diff_server; // And some do seq num randomization for server->client also
+ uint16_t m_nat_external_port; // NAT client port
+ uint16_t m_nat_pad[1];
const ClientCfg *m_client_cfg;
uint32_t m_src_idx;
uint32_t m_dest_idx;
@@ -1699,6 +1700,15 @@ public:
return (btGetMaskBit16(m_flags,4,3)==2?true:false) ;
}
+ // We saw first TCP SYN. Waiting for SYN+ACK
+ inline void set_nat_wait_ack_state() {
+ btSetMaskBit16(m_flags, 4, 3, 3);
+ }
+
+ inline bool is_nat_wait_ack_state(){
+ return (btGetMaskBit16(m_flags,4,3) == 3) ? true : false;
+ }
+
inline void set_nat_learn_state(){
m_type=FLOW_PKT; /* normal operation .. repeat might work too */
}
@@ -1712,14 +1722,21 @@ public:
return (m_thread_id);
}
- inline void set_nat_ipv4_addr_server(uint32_t ip){
- m_nat_external_ipv4_server =ip;
+ inline void set_nat_tcp_seq_diff_client(uint32_t diff) {
+ m_nat_tcp_seq_diff_client = diff;
+ }
+
+ inline uint32_t get_nat_tcp_seq_diff_client() {
+ return m_nat_tcp_seq_diff_client;
}
- inline uint32_t get_nat_ipv4_addr_server(){
- return ( m_nat_external_ipv4_server );
+ inline void set_nat_tcp_seq_diff_server(uint32_t diff) {
+ m_nat_tcp_seq_diff_server = diff;
}
+ inline uint32_t get_nat_tcp_seq_diff_server() {
+ return m_nat_tcp_seq_diff_server;
+ }
inline void set_nat_ipv4_addr(uint32_t ip){
m_nat_external_ipv4 =ip;
@@ -1740,8 +1757,7 @@ public:
bool is_external_is_eq_to_internal_ip(){
/* this API is used to check TRex itself */
if ( (get_nat_ipv4_addr() == m_src_ip ) &&
- (get_nat_ipv4_port()==m_src_port) &&
- ( get_nat_ipv4_addr_server() == m_dest_ip) ) {
+ (get_nat_ipv4_port()==m_src_port)) {
return (true);
}else{
return (false);
@@ -3004,6 +3020,8 @@ inline void CFlowPktInfo::update_pkt_info(char *p,
(void)et;
uint16_t src_port = node->m_src_port;
+ uint32_t tcp_seq_diff_client = 0;
+ uint32_t tcp_seq_diff_server = 0;
pkt_dir_t ip_dir = node->cur_pkt_ip_addr_dir();
pkt_dir_t port_dir = node->cur_pkt_port_addr_dir();
@@ -3024,7 +3042,6 @@ inline void CFlowPktInfo::update_pkt_info(char *p,
}else{
if ( unlikely ( CGlobalInfo::is_learn_mode() ) ){
-
if (m_pkt_indication.m_desc.IsLearn()) {
/* might be done twice */
#ifdef NAT_TRACE_
@@ -3033,42 +3050,48 @@ inline void CFlowPktInfo::update_pkt_info(char *p,
ipv4->setTimeToLive(TTL_RESERVE_DUPLICATE);
/* first ipv4 option add the info in case of learn packet, usualy only the first packet */
- if (CGlobalInfo::is_learn_mode(CParserOption::LEARN_MODE_IP_OPTION)) {
- CNatOption *lpNat =(CNatOption *)ipv4->getOption();
- lpNat->set_fid(node->get_short_fid());
- lpNat->set_thread_id(node->get_thread_id());
- } else {
- // This method only work on first TCP SYN
- if (ipv4->getProtocol() == IPPROTO_TCP) {
- TCPHeader *tcp = (TCPHeader *)(((uint8_t *)ipv4) + ipv4->getHeaderLength());
- if (tcp->getSynFlag()) {
- tcp->setAckNumber(CNatRxManager::calc_tcp_ack_val(node->get_short_fid(), node->get_thread_id()));
- }
+ if (CGlobalInfo::is_learn_mode(CParserOption::LEARN_MODE_IP_OPTION)) {
+ CNatOption *lpNat =(CNatOption *)ipv4->getOption();
+ lpNat->set_fid(node->get_short_fid());
+ lpNat->set_thread_id(node->get_thread_id());
+ } else {
+ // This method only work on first TCP SYN
+ if (ipv4->getProtocol() == IPPROTO_TCP) {
+ TCPHeader *tcp = (TCPHeader *)(((uint8_t *)ipv4) + ipv4->getHeaderLength());
+ if (tcp->getSynFlag()) {
+ tcp->setAckNumber(CNatRxManager::calc_tcp_ack_val(node->get_short_fid(), node->get_thread_id()));
+ }
#ifdef NAT_TRACE_
- printf(" %.3f : flow_id: %x thread_id %x TCP ack %x\n",now_sec(), node->get_short_fid(), node->get_thread_id(), tcp->getAckNumber());
+ printf(" %.3f : flow_id: %x thread_id %x TCP ack %x seq %x\n"
+ ,now_sec(), node->get_short_fid(), node->get_thread_id(), tcp->getAckNumber()
+ , tcp->getSeqNumber());
#endif
- }
- }
+ }
+ }
}
/* in all cases update the ip using the outside ip */
if ( m_pkt_indication.m_desc.IsInitSide() ) {
#ifdef NAT_TRACE_
if (node->m_flags != CGenNode::NODE_FLAGS_LATENCY ) {
- printf(" %.3f : DP : i %x:%x -> %x flow_id: %lx\n",now_sec(),node->m_src_ip,node->m_src_port,node->m_dest_ip,node->m_flow_id);
+ printf(" %.3f : DP : i %x:%x -> %x flow_id: %lx\n",now_sec(), node->m_src_ip
+ , node->m_src_port, node->m_dest_ip, node->m_flow_id);
}
#endif
+ tcp_seq_diff_server = node->get_nat_tcp_seq_diff_server();
ipv4->updateIpSrc(node->m_src_ip);
ipv4->updateIpDst(node->m_dest_ip);
- }else{
+ } else {
#ifdef NAT_TRACE_
if (node->m_flags != CGenNode::NODE_FLAGS_LATENCY ) {
- printf(" %.3f : r %x -> %x:%x flow_id: %lx \n",now_sec(),node->m_dest_ip,node->m_src_ip,node->m_src_port,node->m_flow_id);
+ printf(" %.3f : r %x -> %x:%x flow_id: %lx \n", now_sec(), node->m_dest_ip
+ , node->m_src_ip, node->m_src_port, node->m_flow_id);
}
#endif
src_port = node->get_nat_ipv4_port();
- ipv4->updateIpSrc(node->get_nat_ipv4_addr_server());
+ tcp_seq_diff_client = node->get_nat_tcp_seq_diff_client();
+ ipv4->updateIpSrc(node->m_dest_ip);
ipv4->updateIpDst(node->get_nat_ipv4_addr());
}
@@ -3076,7 +3099,7 @@ inline void CFlowPktInfo::update_pkt_info(char *p,
#ifdef NAT_TRACE_
if (node->m_flags != CGenNode::NODE_FLAGS_LATENCY ) {
if ( m_pkt_indication.m_desc.IsInitSide() ==false ){
- printf(" %.3f : pkt ==> %x:%x %x:%x \n",now_sec(),node->get_nat_ipv4_addr(),node->get_nat_ipv4_addr_server(),
+ printf(" %.3f : pkt ==> %x %x:%x \n",now_sec(),node->get_nat_ipv4_addr(),
node->get_nat_ipv4_port(),node->m_src_port);
}else{
printf(" %.3f : pkt ==> init pkt sent \n",now_sec());
@@ -3116,8 +3139,10 @@ inline void CFlowPktInfo::update_pkt_info(char *p,
/* replace port */
if ( port_dir == CLIENT_SIDE ) {
m_tcp->setSourcePort(src_port);
+ m_tcp->setAckNumber(m_tcp->getAckNumber() + tcp_seq_diff_server);
}else{
m_tcp->setDestPort(src_port);
+ m_tcp->setAckNumber(m_tcp->getAckNumber() + tcp_seq_diff_client);
}
}else {
if ( m_pkt_indication.m_desc.IsUdp() ){
@@ -3352,6 +3377,8 @@ public:
class CCapFileFlowInfo {
public:
+ const int LEARN_MODE_MIN_IPG = 10; // msec
+
enum load_cap_file_err {
kOK = 0,
kFileNotExist,
@@ -3359,9 +3386,14 @@ public:
kNoSyn,
kTCPOffsetTooBig,
kNoTCPFromServer,
+ kNoTCPSynAck,
+ kTCPLearnModeBadFlow,
kPktNotSupp,
kPktProcessFail,
- kCapFileErr
+ kCapFileErr,
+ kPlugInWithLearn,
+ kIPOptionNotAllowed,
+ kTCPIpgTooLow
};
bool Create();
@@ -3378,7 +3410,7 @@ public:
/* update flow info */
void update_info();
- bool is_valid_template_load_time(std::string & err);
+ enum CCapFileFlowInfo::load_cap_file_err is_valid_template_load_time();
void save_to_erf(std::string cap_file_name,int pcap);