summaryrefslogtreecommitdiffstats
path: root/src/rx_check_header.h
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2015-06-24 14:03:29 +0300
committerHanoh Haim <hhaim@cisco.com>2015-06-24 14:03:29 +0300
commit8b52a31ed2c299b759f330c4f976b9c70f5765f4 (patch)
tree9d6da5438b5b56b1d2d57e6c13494b4e65d000e7 /src/rx_check_header.h
first version
Diffstat (limited to 'src/rx_check_header.h')
-rwxr-xr-xsrc/rx_check_header.h212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/rx_check_header.h b/src/rx_check_header.h
new file mode 100755
index 00000000..3ac5dd1f
--- /dev/null
+++ b/src/rx_check_header.h
@@ -0,0 +1,212 @@
+#ifndef RX_CHECK_HEADER
+#define RX_CHECK_HEADER
+/*
+ Hanoh Haim
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 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.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+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.
+*/
+
+
+#include <stdint.h>
+#include <stdio.h>
+#include <common/bitMan.h>
+#include <common/Network/Packet/CPktCmn.h>
+
+
+#include "os_time.h"
+
+#define RX_CHECK_LEN (sizeof(struct CRx_check_header))
+
+// IPv4 option type:
+// bit[0] = copy flag (0=do not copy to fragment)
+// bit[1:2] = option class (2=debugging)
+// bit[3:7] = option number (23=TRex)
+#define RX_CHECK_V4_OPT_TYPE 0x57
+#define RX_CHECK_V4_OPT_LEN RX_CHECK_LEN
+
+// IPv6 extension header:
+// type = 60 (destination options)
+#define RX_CHECK_V6_OPT_TYPE 0x3c
+#define RX_CHECK_V6_OPT_LEN ((RX_CHECK_LEN - 8) / 8)
+
+// IPv6 subfield option type:
+// bit[0:1] = unrecognied option action (00=skip option)
+// bit[2] = change allowed flag (0=no changes enroute)
+// bit[3:7] = option number (23=TRex)
+#define RX_CHECK_V6_SF_OPT_TYPE 0x17
+#define RX_CHECK_V6_SF_OPT_LEN (RX_CHECK_LEN - 2)
+
+// Magic field overlays IPv6 subfield option type
+#define RX_CHECK_MAGIC (((RX_CHECK_V6_SF_OPT_LEN & 0xff) << 8) | \
+ RX_CHECK_V6_SF_OPT_TYPE)
+
+struct CRx_check_header {
+ // 24 bytes, watch alignment and keep this in 8 byte increments
+ uint8_t m_option_type;
+ uint8_t m_option_len;
+ uint16_t m_magic;
+
+ uint32_t m_time_stamp;
+ uint64_t m_flow_id; // include thread_id , template_id
+ uint16_t m_pkt_id; /* pkt_id inside the flow - zero base 0,1,2*/
+ uint16_t m_flow_size; /* how many packets in flow */
+
+ uint8_t m_flags;
+ uint8_t m_template_id;
+ uint16_t m_aging_sec;
+
+public:
+ bool is_fif_dir(void){
+ return (m_pkt_id==0?true:false);
+ }
+ bool is_eof_dir(void){
+ return ( (m_pkt_id==m_flow_size-1)?true:false);
+ }
+
+ void set_dir(int dir){
+ btSetMaskBit8(m_flags,0,0,dir?1:0);
+ }
+
+ int get_dir(void){
+ return (btGetMaskBit8(m_flags,0,0) ? 1:0);
+ }
+
+ /* need to mark if we expect to see both sides of the flow, this is know offline */
+ void set_both_dir(int both){
+ btSetMaskBit8(m_flags,1,1,both?1:0);
+ }
+
+ int get_both_dir(void){
+ return (btGetMaskBit8(m_flags,1,1) ? 1:0);
+ }
+
+
+
+ void dump(FILE *fd);
+};
+
+
+class CNatOption {
+public:
+ enum {
+ noIPV4_OPTION = 0x10, /* dummy IPV4 option */
+ noOPTION_LEN = 0x8,
+ noIPV4_MAGIC = 0xEE,
+ noIPV4_MAGIC_RX = 0xED,
+
+ noIPV6_OPTION_LEN = (noOPTION_LEN/8)-1,
+ noIPV6_OPTION = 0x3C, /*IPv6-Opts Destination Options for IPv6 RFC 2460*/
+ };
+ void set_option_type(uint8_t id){
+ u.m_data[0]=id;
+ }
+ uint8_t get_option_type(){
+ return (u.m_data[0]);
+ }
+
+ void set_option_len(uint8_t len){
+ u.m_data[1]=len;
+ }
+ uint8_t get_option_len(){
+ return ( u.m_data[1]);
+ }
+
+ void set_thread_id(uint8_t thread_id){
+ u.m_data[3]=thread_id;
+ }
+ uint8_t get_thread_id(){
+ return (u.m_data[3]);
+ }
+
+ void set_magic(uint8_t magic){
+ u.m_data[2]=magic;
+ }
+
+ uint8_t get_magic(){
+ return (u.m_data[2]);
+ }
+
+ void set_rx_check(bool enable){
+ if (enable) {
+ set_magic(CNatOption::noIPV4_MAGIC_RX);
+ }else{
+ set_magic(CNatOption::noIPV4_MAGIC);
+ }
+ }
+ bool is_rx_check(){
+ if (get_magic() ==CNatOption::noIPV4_MAGIC_RX) {
+ return(true);
+ }else{
+ return (false);
+ }
+ }
+
+
+ void set_fid(uint32_t fid){
+ u.m_data_uint32[1]=fid;
+ }
+ uint32_t get_fid(){
+ return (u.m_data_uint32[1]);
+ }
+
+ bool is_valid_ipv4_magic_op0(void){
+ return ( ( PKT_NTOHL( u.m_data_uint32[0] )& 0xFFFFFF00 ) ==
+ (CNatOption::noIPV4_OPTION <<24) + (CNatOption::noOPTION_LEN<<16) + (CNatOption::noIPV4_MAGIC<<8) ?true:false);
+ }
+
+ bool is_valid_ipv4_magic_op1(void){
+ return ( ( PKT_NTOHL( u.m_data_uint32[0] )& 0xFFFFFF00 ) ==
+ (CNatOption::noIPV4_OPTION <<24) + (CNatOption::noOPTION_LEN<<16) + (CNatOption::noIPV4_MAGIC_RX<<8) ?true:false);
+ }
+
+ bool is_valid_ipv4_magic(void){
+ return (is_valid_ipv4_magic_op0() ||is_valid_ipv4_magic_op1() );
+ }
+
+
+ bool is_valid_ipv6_magic(void){
+ return ( ( PKT_NTOHL( u.m_data_uint32[0] )& 0x00FFFF00 ) ==
+ (CNatOption::noIPV6_OPTION_LEN<<16) + (CNatOption::noIPV4_MAGIC<<8) ?true:false);
+
+ }
+
+ void set_init_ipv4_header(){
+ set_option_type(CNatOption::noIPV4_OPTION);
+ set_option_len(CNatOption::noOPTION_LEN);
+ set_magic(CNatOption::noIPV4_MAGIC);
+ }
+
+ void set_init_ipv6_header(void){
+ set_option_len(noIPV6_OPTION_LEN);
+ set_magic(CNatOption::noIPV4_MAGIC);
+ }
+
+ void dump(FILE *fd);
+
+
+private:
+ union u_ {
+ uint8_t m_data[8];
+ uint32_t m_data_uint32[2];
+ } u;
+};
+
+
+#endif
+
+