add min/max to repeatable random inst
authorHanoh Haim <[email protected]>
Tue, 13 Sep 2016 10:08:10 +0000 (13:08 +0300)
committerHanoh Haim <[email protected]>
Tue, 13 Sep 2016 16:37:29 +0000 (19:37 +0300)
scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
src/gtest/trex_stateless_gtest.cpp
src/rpc-server/commands/trex_rpc_cmd_stream.cpp
src/rpc-server/commands/trex_rpc_cmds.h
src/stateless/cp/trex_stream_vm.cpp
src/stateless/cp/trex_stream_vm.h

index b97cc5f..b6744d6 100755 (executable)
@@ -664,6 +664,66 @@ class STLVmFlowVar(CTRexVmDescBase):
     def get_var_name(self):
         return [self.name]
 
+class STLVmFlowVarRepetableRandom(CTRexVmDescBase):
+
+    def __init__(self, name,  size=4, limit=100, seed=None):
+        """
+        Flow variable instruction for repeatable random with limit number of generating numbers. Allocates memory on a stream context. 
+        The size argument determines the variable size. Could be 1,2,,4 or 8
+
+        :parameters:
+             name : string 
+                Name of the stream variable 
+
+             size  : int
+                Number of bytes of the variable. Possible values: 1,2,4,8 for uint8_t, uint16_t, uint32_t, uint64_t
+
+             limit  : int 
+                The number of distinct repetable random number 
+
+             seed   : int 
+                For deterministic result, you can set this to a uint16_t number
+
+        .. code-block:: python
+            :caption: Example1
+
+
+            # input , 1 byte or random with limit of 5 
+            STLVmFlowVarRepetableRandom("var1",size=1,limit=5)
+
+            # output 255,1,7,129,8,255,1,7,129,8
+
+        """
+        super(STLVmFlowVar, self).__init__()
+        self.name = name;
+        validate_type('name', name, str)
+        self.size =size
+        valid_fv_size(size)
+        self.limit =limit
+
+        if seed == None:
+            self.seed = random.randint(1, 32000)
+        else:
+            self.seed = seed
+
+        # choose default value for init val
+        if init_value == None:
+            init_value = max_value if op == "dec" else min_value
+
+        self.init_value = convert_val (init_value)
+        self.min_value  = convert_val (min_value);
+        self.max_value  = convert_val (max_value)
+        self.step       = convert_val (step)
+
+        if self.min_value > self.max_value :
+            raise CTRexPacketBuildException(-11,("max %d is lower than min %d ") % (self.max_value,self.min_value)  );
+
+    def get_obj (self):
+        return CTRexVmInsFlowVar(self.name,self.size,self.op,self.init_value,self.min_value,self.max_value,self.step);
+
+    def get_var_name(self):
+        return [self.name]
+
 
 class STLVmFixIpv4(CTRexVmDescBase):
     def __init__(self, offset):
index d8c2e1f..a6bbc6f 100644 (file)
@@ -184,7 +184,7 @@ TEST_F(basic_vm, vm_rand_limit0) {
 
     StreamVm vm;
 
-    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,100,0x1234) );
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,100,0,200,0x1234) );
 
     vm.Dump(stdout);
 }
@@ -193,7 +193,7 @@ TEST_F(basic_vm, vm_rand_limit1) {
 
     StreamVm vm;
 
-    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,100,0x1234) );
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,100,0,200,0x1234) );
     vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
                         );
     vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
@@ -214,10 +214,10 @@ TEST_F(basic_vm, vm_rand_limit2) {
 
     StreamVm vm;
 
-    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,100,0x1234) );
-    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var2",2,100,0x1234) );
-    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var3",4,100,0x1234) );
-    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var4",8,100,0x1234) );
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,100,0,100,0x1234) );
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var2",2,100,0,100,0x1234) );
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var3",4,100,0,100,0x1234) );
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var4",8,100,0,100,0x1234) );
     vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
                         );
     vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
@@ -676,7 +676,7 @@ TEST_F(basic_vm, vm_rand_len) {
 
     StreamVm vm;
 
-    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,10,0x1234) );
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,10,0,255,0x1234) );
 
 
     /* change TOS */
@@ -716,7 +716,6 @@ TEST_F(basic_vm, vm_rand_len) {
 
     StreamDPVmInstructionsRunner runner;
 
-
          uint8_t ex_tos[]={
              0x98,          
              0xbd,          
@@ -761,11 +760,101 @@ TEST_F(basic_vm, vm_rand_len) {
     }
 }
 
+TEST_F(basic_vm, vm_rand_len_l0) {
+
+    StreamVm vm;
+
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,10,1,10,0x1234) );
+
+
+    /* change TOS */
+    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",15, 0,true));
+
+
+    vm.compile(128);
+
+
+    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
+
+    printf (" program size : %lu \n",(ulong)program_size);
+
+
+    vm.Dump(stdout);
+
+    #define PKT_TEST_SIZE (14+20+4+4)
+    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
+        0x00,0x00,0x00,0x01,0x00,0x00,
+        0x00,0x00,0x00,0x01,0x00,0x00,
+        0x08,0x00,
+
+        0x45,0x00,0x00,0x81, /*14 */
+        0xaf,0x7e,0x00,0x00, /*18 */
+        0x12,0x11,0xd9,0x23, /*22 */
+        0x01,0x01,0x01,0x01, /*26 */
+        0x3d,0xad,0x72,0x1b, /*30 */
+
+        0x11,0x11,           /*34 */
+        0x11,0x11,
+
+        0x00,0x6d,
+        0x00,0x00,
+    };
+
+
+
+    StreamDPVmInstructionsRunner runner;
+
+         uint8_t ex_tos[]={
+         0x7,    
+         0xa,    
+         0xa,    
+         0x4,    
+         0x7,    
+         0x5,    
+         0x2,    
+         0x3,    
+         0x8,    
+         0x9,    
+          0x7,   
+          0xa,   
+          0xa,   
+          0x4,   
+          0x7,   
+          0x5,   
+          0x2,   
+          0x3,   
+          0x8,   
+          0x9,
+             
+         };
+
+
+    uint32_t random_per_thread=0;
+
+    int i;
+    for (i=0; i<20; i++) {
+        runner.run(&random_per_thread,
+                   program_size,
+                   vm.get_dp_instruction_buffer()->get_program(),
+                   vm.get_bss_ptr(),
+                   test_udp_pkt);
+
+        fprintf(stdout," %d :",i);
+        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
+        /* not big */
+        printf(" %x \n",test_udp_pkt[15]);
+
+        /* check tos */
+        EXPECT_EQ(test_udp_pkt[15],ex_tos[i]);
+    }
+}
+
+
 TEST_F(basic_vm, vm_rand_len1) {
 
     StreamVm vm;
 
-    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",2,10,0x1234) );
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",2,10,0,((1<<16)-1),0x1234) );
 
 
     /* change TOS */
@@ -854,7 +943,7 @@ TEST_F(basic_vm, vm_rand_len2) {
 
     StreamVm vm;
 
-    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",4,10,0x1234) );
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",4,10,0,((1UL<<32)-1),0x1234) );
 
 
     /* change TOS */
@@ -942,7 +1031,7 @@ TEST_F(basic_vm, vm_rand_len3) {
 
     StreamVm vm;
 
-    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",8,10,0x1234) );
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",8,10,0,UINT64_MAX,0x1234) );
 
 
     /* change TOS */
@@ -1029,6 +1118,97 @@ TEST_F(basic_vm, vm_rand_len3) {
 }
 
 
+TEST_F(basic_vm, vm_rand_len3_l0) {
+
+    StreamVm vm;
+
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",8,10,0x1234567,0x2234567,0x1234) );
+
+
+    /* change TOS */
+    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",15, 0,true));
+
+
+    vm.compile(128);
+
+
+    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
+
+    printf (" program size : %lu \n",(ulong)program_size);
+
+
+    vm.Dump(stdout);
+
+    #define PKT_TEST_SIZE (14+20+4+4)
+    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
+        0x00,0x00,0x00,0x01,0x00,0x00,
+        0x00,0x00,0x00,0x01,0x00,0x00,
+        0x08,0x00,
+
+        0x45,0x00,0x00,0x81, /*14 */
+        0xaf,0x7e,0x00,0x00, /*18 */
+        0x12,0x11,0xd9,0x23, /*22 */
+        0x01,0x01,0x01,0x01, /*26 */
+        0x3d,0xad,0x72,0x1b, /*30 */
+
+        0x11,0x11,           /*34 */
+        0x11,0x11,
+
+        0x00,0x6d,
+        0x00,0x00,
+    };
+
+
+
+    StreamDPVmInstructionsRunner runner;
+
+#if 0
+         uint32_t ex_tos[]={
+             0xbd64983b,        
+             0x715b512 ,        
+             0xd6641410,        
+             0x90580371,        
+             0x884d5d3b,        
+             0x8e0f8212,        
+             0xf00b2f39,        
+             0xa015ee4e,        
+             0x540b390e,        
+             0xdb778538,        
+             0xbd64983b,       
+             0x715b512 ,       
+             0xd6641410,       
+             0x90580371,       
+             0x884d5d3b,       
+             0x8e0f8212,       
+             0xf00b2f39,       
+             0xa015ee4e,       
+             0x540b390e,       
+             0xdb778538       
+         };
+#endif
+
+
+    uint32_t random_per_thread=0;
+
+    int i;
+    for (i=0; i<20; i++) {
+        runner.run(&random_per_thread,
+                   program_size,
+                   vm.get_dp_instruction_buffer()->get_program(),
+                   vm.get_bss_ptr(),
+                   test_udp_pkt);
+
+        fprintf(stdout," %d :",i);
+        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
+        /* not big */
+        printf(" %" PRIx64 " \n",pal_ntohl64(*((uint64_t*)&test_udp_pkt[15])));
+
+        /* check tos */
+        //EXPECT_EQ(*((uint64_t*)&test_udp_pkt[15]),ex_tos[i]);
+    }
+}
+
+
 /* -load file, write to file  */
 TEST_F(basic_vm, vm6) {
 
@@ -1096,6 +1276,98 @@ TEST_F(basic_vm, vm6) {
     EXPECT_EQ(1, res1?1:0);
 }
 
+
+TEST_F(basic_vm, vm_rand_len3_l1) {
+
+    StreamVm vm;
+
+    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",4,10,0x01234567,0x02234567,0x1234) );
+
+
+    /* change TOS */
+    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",15, 0,true));
+
+
+    vm.compile(128);
+
+
+    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
+
+    printf (" program size : %lu \n",(ulong)program_size);
+
+
+    vm.Dump(stdout);
+
+    #define PKT_TEST_SIZE (14+20+4+4)
+    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
+        0x00,0x00,0x00,0x01,0x00,0x00,
+        0x00,0x00,0x00,0x01,0x00,0x00,
+        0x08,0x00,
+
+        0x45,0x00,0x00,0x81, /*14 */
+        0xaf,0x7e,0x00,0x00, /*18 */
+        0x12,0x11,0xd9,0x23, /*22 */
+        0x01,0x01,0x01,0x01, /*26 */
+        0x3d,0xad,0x72,0x1b, /*30 */
+
+        0x11,0x11,           /*34 */
+        0x11,0x11,
+
+        0x00,0x6d,
+        0x00,0x00,
+    };
+
+
+
+    StreamDPVmInstructionsRunner runner;
+
+#if 0
+         uint32_t ex_tos[]={
+             0xbd64983b,        
+             0x715b512 ,        
+             0xd6641410,        
+             0x90580371,        
+             0x884d5d3b,        
+             0x8e0f8212,        
+             0xf00b2f39,        
+             0xa015ee4e,        
+             0x540b390e,        
+             0xdb778538,        
+             0xbd64983b,       
+             0x715b512 ,       
+             0xd6641410,       
+             0x90580371,       
+             0x884d5d3b,       
+             0x8e0f8212,       
+             0xf00b2f39,       
+             0xa015ee4e,       
+             0x540b390e,       
+             0xdb778538       
+         };
+#endif
+
+
+    uint32_t random_per_thread=0;
+
+    int i;
+    for (i=0; i<20; i++) {
+        runner.run(&random_per_thread,
+                   program_size,
+                   vm.get_dp_instruction_buffer()->get_program(),
+                   vm.get_bss_ptr(),
+                   test_udp_pkt);
+
+        fprintf(stdout," %d :",i);
+        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
+        /* not big */
+        printf(" %x \n",PAL_NTOHL(*((uint64_t*)&test_udp_pkt[15])));
+
+        /* check tos */
+        //EXPECT_EQ(*((uint64_t*)&test_udp_pkt[15]),ex_tos[i]);
+    }
+}
+
+
 /* test client command */
 TEST_F(basic_vm, vm7) {
 
index 8875027..f057749 100644 (file)
@@ -251,6 +251,28 @@ TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, std:
                                                                 ));
 }
 
+void 
+TrexRpcCmdAddStream::parse_vm_instr_flow_var_rand_limit(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
+    std::string  flow_var_name = parse_string(inst, "name", result);
+
+    auto sizes = {1, 2, 4, 8};
+    uint8_t      flow_var_size = parse_choice(inst, "size", sizes, result);
+    uint64_t seed    = parse_uint64(inst, "seed", result);
+    uint64_t limit   = parse_uint64(inst, "limit", result);
+
+    if (limit < 1 ) {
+        std::stringstream ss;
+        ss << "VM: request random flow var variable with limit of zero '";
+        generate_parse_err(result, ss.str());
+    }
+
+    stream->m_vm.add_instruction(new StreamVmInstructionFlowRandLimit(flow_var_name,
+                                                                      flow_var_size,
+                                                                      (int)limit,
+                                                                      0,0,
+                                                                      seed)
+                                 );
+}
 
 void 
 TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
@@ -373,6 +395,9 @@ TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, std::unique_ptr<TrexStream>
         } else if (vm_type == "flow_var") {
             parse_vm_instr_flow_var(inst, stream, result);
 
+        } else if (vm_type == "flow_var_rand_limit") {
+            parse_vm_instr_flow_var(inst, stream, result);
+
         } else if (vm_type == "write_flow_var") {
             parse_vm_instr_write_flow_var(inst, stream, result);
 
index 24b9522..94aa2a5 100644 (file)
@@ -105,6 +105,8 @@ void validate_stream(const std::unique_ptr<TrexStream> &stream, Json::Value &res
 void parse_vm(const Json::Value &vm, std::unique_ptr<TrexStream> &stream, Json::Value &result);
 void parse_vm_instr_checksum(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
 void parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_flow_var_rand_limit(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+
 void parse_vm_instr_tuple_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
 void parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
 void parse_rate(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
index 0f1ea68..bdfca36 100644 (file)
@@ -26,6 +26,7 @@ limitations under the License.
 #include <trex_stateless.h>
 #include <common/Network/Packet/IPHeader.h>
 #include <common/basic_utils.h>
+#include <inttypes.h>
 
 /**
  * provides some tools for the fast rand function 
@@ -170,7 +171,7 @@ void StreamVmInstructionFlowMan::sanity_check(uint32_t ins_id,StreamVm *lp){
 
 void StreamVmInstructionFlowRandLimit::Dump(FILE *fd){
     fprintf(fd," flow_var_rand_limit  , %s ,%lu,   ",m_var_name.c_str(),(ulong)m_size_bytes);
-    fprintf(fd," (%lu:%lu:%lu) \n",m_limit,(ulong)m_size_bytes,(ulong)m_seed);
+    fprintf(fd," (%lu:%lu:%lu) (min:%lu,max:%lu) \n",m_limit,(ulong)m_size_bytes,(ulong)m_seed,m_min_value,m_max_value);
 }
 
 void StreamVmInstructionFlowRandLimit::sanity_check(uint32_t ins_id,StreamVm *lp){
@@ -195,21 +196,29 @@ uint8_t  StreamVmInstructionFlowRandLimit::bss_init_value(uint8_t *p){
     case 1:
         u.lpv8=(RandMemBss8 *)p;
         u.lpv8->m_seed=m_seed;
+        u.lpv8->m_cnt=0;
+        u.lpv8->m_val=0;
         res=sizeof(RandMemBss8);
         break;
     case 2:
         u.lpv16=(RandMemBss16 *)p;
         u.lpv16->m_seed=m_seed;
+        u.lpv16->m_cnt=0;
+        u.lpv16->m_val=0;
         res=sizeof(RandMemBss16);
         break;
     case 4:
         u.lpv32=(RandMemBss32 *)p;
         u.lpv32->m_seed=m_seed;
+        u.lpv32->m_cnt=0;
+        u.lpv32->m_val=0;
         res=sizeof(RandMemBss32);
         break;
     case 8:
         u.lpv64=(RandMemBss64 *)p;
         u.lpv64->m_seed=m_seed;
+        u.lpv64->m_cnt=0;
+        u.lpv64->m_val=0;
         res=sizeof(RandMemBss64);
         break;
     default:
@@ -671,6 +680,8 @@ void StreamVm::build_program(){
                 fv8.m_flow_offset = get_var_offset(lpMan->m_var_name);
                 fv8.m_limit     = (uint8_t)lpMan->m_limit;
                 fv8.m_seed      = (uint32_t)lpMan->m_seed;
+                fv8.m_min_val = (uint8_t)lpMan->m_min_value;
+                fv8.m_max_val = (uint8_t)lpMan->m_max_value;
                 m_instructions.add_command(&fv8,sizeof(fv8));
             }
 
@@ -680,6 +691,9 @@ void StreamVm::build_program(){
                 fv16.m_flow_offset = get_var_offset(lpMan->m_var_name);
                 fv16.m_limit     = (uint16_t)lpMan->m_limit;
                 fv16.m_seed      = (uint32_t)lpMan->m_seed;
+                fv16.m_min_val   = (uint16_t)lpMan->m_min_value;
+                fv16.m_max_val   = (uint16_t)lpMan->m_max_value;
+
                 m_instructions.add_command(&fv16,sizeof(fv16));
             }
 
@@ -689,6 +703,9 @@ void StreamVm::build_program(){
                 fv32.m_flow_offset = get_var_offset(lpMan->m_var_name);
                 fv32.m_limit     = (uint32_t)lpMan->m_limit;
                 fv32.m_seed      = (uint32_t)lpMan->m_seed;
+                fv32.m_min_val   = (uint32_t)lpMan->m_min_value;
+                fv32.m_max_val   = (uint32_t)lpMan->m_max_value;
+
                 m_instructions.add_command(&fv32,sizeof(fv32));
             }
 
@@ -698,6 +715,8 @@ void StreamVm::build_program(){
                 fv64.m_flow_offset = get_var_offset(lpMan->m_var_name);
                 fv64.m_limit     = lpMan->m_limit;
                 fv64.m_seed      = (uint32_t)lpMan->m_seed;
+                fv64.m_min_val   = lpMan->m_min_value;
+                fv64.m_max_val   = lpMan->m_max_value;
                 m_instructions.add_command(&fv64,sizeof(fv64));
             }
         }
@@ -1578,19 +1597,19 @@ void StreamDPOpPktSizeChange::dump(FILE *fd,std::string opt){
 
 
 void StreamDPOpFlowRandLimit8::dump(FILE *fd,std::string opt){
-    fprintf(fd," %10s, flow_offset: %lu  limit :%lu seed:%x \n",  opt.c_str(),(ulong)m_flow_offset,(ulong)m_limit,m_seed);
+    fprintf(fd," %10s, flow_offset: %lu  limit :%lu seed:%x (%x-%x) \n",  opt.c_str(),(ulong)m_flow_offset,(ulong)m_limit,m_seed,m_min_val,m_max_val);
 }
 
 void StreamDPOpFlowRandLimit16::dump(FILE *fd,std::string opt){
-    fprintf(fd," %10s, flow_offset: %lu  limit :%lu seed:%x \n",  opt.c_str(),(ulong)m_flow_offset,(ulong)m_limit,m_seed);
+    fprintf(fd," %10s, flow_offset: %lu  limit :%lu seed:%x (%x-%x) \n",  opt.c_str(),(ulong)m_flow_offset,(ulong)m_limit,m_seed,m_min_val,m_max_val);
 }
 
 void StreamDPOpFlowRandLimit32::dump(FILE *fd,std::string opt){
-    fprintf(fd," %10s, flow_offset: %lu  limit :%lu seed:%x \n",  opt.c_str(),(ulong)m_flow_offset,(ulong)m_limit,m_seed);
+    fprintf(fd," %10s, flow_offset: %lu  limit :%lu seed:%x (%x-%x) \n",  opt.c_str(),(ulong)m_flow_offset,(ulong)m_limit,m_seed,m_min_val,m_max_val);
 }
 
 void StreamDPOpFlowRandLimit64::dump(FILE *fd,std::string opt){
-    fprintf(fd," %10s, flow_offset: %lu  limit :%lu seed:%x \n",  opt.c_str(),(ulong)m_flow_offset,(ulong)m_limit,m_seed);
+    fprintf(fd," %10s, flow_offset: %lu  limit :%lu seed:%x  \n",  opt.c_str(),(ulong)m_flow_offset,(ulong)m_limit,m_seed);
 }
 
 
index 6a83c5e..5e3665c 100644 (file)
@@ -106,7 +106,10 @@ struct StreamDPOpFlowRandLimit8 {
     uint8_t m_op;
     uint8_t m_flow_offset;
     uint8_t m_limit;
+    uint8_t m_min_val;
+    uint8_t m_max_val;
     uint32_t m_seed;
+
 public:
     void dump(FILE *fd,std::string opt);
     inline void run(uint8_t * flow_var) {
@@ -115,7 +118,7 @@ public:
             p->m_seed = m_seed;
             p->m_cnt=0;
         }
-        uint32_t val = vm_rand16(&p->m_seed);
+        uint32_t val = m_min_val + (vm_rand16(&p->m_seed)  % (int)(m_max_val - m_min_val + 1));
         p->m_val= (uint8_t)(val);
         p->m_cnt++;
     }
@@ -125,6 +128,9 @@ struct StreamDPOpFlowRandLimit16 {
     uint8_t m_op;
     uint8_t m_flow_offset;
     uint16_t m_limit;
+    uint16_t m_min_val;
+    uint16_t m_max_val;
+
     uint32_t m_seed;
 public:
     void dump(FILE *fd,std::string opt);
@@ -134,7 +140,7 @@ public:
             p->m_seed = m_seed;
             p->m_cnt=0;
         }
-        uint32_t val = vm_rand16(&p->m_seed);
+        uint32_t val = m_min_val + (vm_rand16(&p->m_seed)  % (int)(m_max_val - m_min_val + 1)); 
         p->m_val= (uint16_t)(val);
         p->m_cnt++;
     }
@@ -145,6 +151,9 @@ struct StreamDPOpFlowRandLimit32 {
     uint8_t m_op;
     uint8_t m_flow_offset;
     uint32_t m_limit;
+    uint32_t m_min_val;
+    uint32_t m_max_val;
+
     uint32_t m_seed;
 public:
     void dump(FILE *fd,std::string opt);
@@ -154,7 +163,7 @@ public:
             p->m_seed = m_seed;
             p->m_cnt=0;
         }
-        uint32_t val = vm_rand32(&p->m_seed);
+        uint32_t val = m_min_val + (vm_rand32(&p->m_seed)  % ((uint64_t)m_max_val - m_min_val + 1)); 
         p->m_val= val;
         p->m_cnt++;
     }
@@ -164,6 +173,9 @@ struct StreamDPOpFlowRandLimit64 {
     uint8_t m_op;
     uint8_t m_flow_offset;
     uint64_t m_limit;
+    uint64_t m_min_val;
+    uint64_t m_max_val;
+
     uint32_t m_seed;
 public:
     void dump(FILE *fd,std::string opt);
@@ -173,7 +185,13 @@ public:
             p->m_seed = m_seed;
             p->m_cnt=0;
         }
-        uint64_t val = vm_rand64(&p->m_seed);
+        uint64_t val;
+        if ((m_max_val - m_min_val) == UINT64_MAX) {
+            val = vm_rand64(&p->m_seed);
+        } else {
+            val = m_min_val + ( vm_rand64(&p->m_seed)  % ( (uint64_t)m_max_val - m_min_val + 1) );
+        }
+        
         p->m_val= val;
         p->m_cnt++;
     }
@@ -1170,12 +1188,16 @@ public:
     StreamVmInstructionFlowRandLimit(const std::string &var_name,
                                      uint8_t  size,
                                      uint64_t limit,
+                                     uint64_t min_value,
+                                     uint64_t max_value,
                                      int       seed
                                      ) : StreamVmInstructionVar(var_name) {
 
         m_size_bytes = size;
         m_seed       = seed;
         m_limit      = limit;
+        m_min_value  = min_value;
+        m_max_value  = max_value;
     }
 
     virtual void Dump(FILE *fd);
@@ -1188,6 +1210,8 @@ public:
         return new StreamVmInstructionFlowRandLimit(m_var_name,
                                                     m_size_bytes,
                                                     m_limit,
+                                                    m_min_value,
+                                                    m_max_value,
                                                     m_seed);
     }
 
@@ -1197,6 +1221,9 @@ private:
 public:
 
     uint64_t       m_limit;
+    uint64_t       m_min_value;
+    uint64_t       m_max_value;
+
     int            m_seed;
     uint8_t        m_size_bytes;
 };