TRex 学习(7)---- Stateless(STLS)

原创
2017/05/04 16:52
阅读数 6.1K

由于本文主要讲解的是Trex的Stateless中的STLS框架,但是stateless由两部分组成,一部分是构包(Scapy), 另一方面是发包,这个由Trex框架完成,因此Scapy一带而过

Scapy

Scapy 是python用于发包的一个库,它通过layer的叠加从而达到构包的目的,如果你只需要构二层包,那么Ether()则构了, 如果你需要构三层IP包,则需要Ether()/IP(),同理L4~L7层的包都可以通过这种方式进行迭代,每个层里面都会有不同的协议,Scapy支持了目前的大多数协议,因此从理论上说,Scapy可以构造任意类型的包
Scapy Packet Examples

# UDP header
 Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) 
# UDP over one vlan
 Ether()/Dot1Q(vlan=12)/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) 
# UDP QinQ
 Ether()/Dot1Q(vlan=12)/Dot1Q(vlan=12)/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)
#TCP over IP over VLAN
 Ether()/Dot1Q(vlan=12)/IP(src="16.0.0.1",dst="48.0.0.1")/TCP(dport=12,sport=1025) 
# IPv6 over vlan
 Ether()/Dot1Q(vlan=12)/IPv6(src="::5")/TCP(dport=12,sport=1025) 
#Ipv6 over UDP over IP
 Ether()/IP()/UDP()/IPv6(src="::5")/TCP(dport=12,sport=1025) 
#DNS packet
 Ether()/IP()/UDP()/DNS() #HTTP packet Ether()/IP()/TCP()/"GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n"

TRex Console Test

  1. simple udp
from trex_stl_lib.api import *
class STLS1(object):
    def create_stream (self):
        return STLStream(                                                                                     #流
            packet = 
                    STLPktBuilder(
                        pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/                      #scapy 构包
                                UDP(dport=12,sport=1025)/(10*'x')
                    ),
             mode = STLTXCont())                                                                         #发送模式
    def get_streams (self, direction = 0, **kwargs):
        # create 1 stream 
        return [ self.create_stream() ]
# dynamic load - used for trex console or simulator
def register():
    return STLS1()                                                                                          #需注册后才能在console中运用

在console中执行测试
trex>start -f stl/udp_1pkt_simple.py -d 10 -m 1pps -p 0
# - d 持续时间 # -m 发送速率 # -p 哪个端口发送

  1. simple multi stream interval
    def create_stream (self):
        # Create base packet and pad it to size
        size = self.fsize - 4; # HW will add 4 bytes ethernet FCS
        base_pkt =  Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        base_pkt1 =  Ether()/IP(src="16.0.0.2",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        base_pkt2 =  Ether()/IP(src="16.0.0.3",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        pad = max(0, size - len(base_pkt)) * 'x'
        return STLProfile( [ STLStream( isg = 0.0, # start in delay in usec 
                                        packet = STLPktBuilder(pkt = base_pkt/pad),
                                        mode = STLTXCont( pps = 10),
                                        ), 
                             STLStream( isg = 25000,
                                        packet  = STLPktBuilder(pkt = base_pkt1/pad),
                                        mode    = STLTXCont( pps = 20),
                                        ),
                             STLStream(  isg = 50000,
                                         packet = STLPktBuilder(pkt = base_pkt2/pad),
                                         mode    = STLTXCont( pps = 40)                                       
                                        )
                            ]).get_streams()

三条流分别以10/20/40pps的速度持续发,每条流在一开始都会有一定的延时,发包过程图

- 延迟单位是微秒,这是流在一开始固定时间推迟开始发
- 第一条流每100 ms 一个包 - 第二条流每 50 ms 一个包 - 第三条流每 25 ms一个包

  1. ** action next stream**
    def create_stream (self):
        # create a base packet and pad it to size
        size = self.fsize - 4 # no FCS
        base_pkt =  Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        base_pkt1 =  Ether()/IP(src="16.0.0.2",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        base_pkt2 =  Ether()/IP(src="16.0.0.3",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        pad = max(0, size - len(base_pkt)) * 'x'
        return STLProfile( [ STLStream( isg = 10.0, # star in delay
                                        name    ='S0',
                                        packet = STLPktBuilder(pkt = base_pkt/pad),
                                        mode = STLTXSingleBurst( pps = 10, total_pkts = 10),  1
                                        next = 'S1'), # point to next stream
                             STLStream( self_start = False, # stream is  disabled enable trow S0  2
                                        name    ='S1',
                                        packet  = STLPktBuilder(pkt = base_pkt1/pad),
                                        mode    = STLTXSingleBurst( pps = 10, total_pkts = 20),
                                        next    = 'S2' ),
                             STLStream(  self_start = False, # stream is  disabled enable trow S0 3
                                         name   ='S2',
                                         packet = STLPktBuilder(pkt = base_pkt2/pad),
                                         mode = STLTXSingleBurst( pps = 10, total_pkts = 30 )
                                        )
                            ]).get_streams()

第一条流发完后指定下一条流发送,这个必需是Burst,因为连续发包模式没有发完这个概念
4. Multi-Burst Mode

    def create_stream (self):

        # create a base packet and pad it to size
        size = self.fsize - 4 # no FCS
        base_pkt =  Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        base_pkt1 =  Ether()/IP(src="16.0.0.2",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        pad = max(0, size - len(base_pkt)) * 'x'
        return STLProfile( [ STLStream( isg = 10.0, # start in delay                                  1
                                        name    ='S0',
                                        packet = STLPktBuilder(pkt = base_pkt/pad),
                                        mode = STLTXSingleBurst( pps = 10, total_pkts = 10),
                                        next = 'S1'), # point to next stream
                             STLStream( self_start = False, # stream is disabled. Enabled by S0       2
                                        name    ='S1',
                                        packet  = STLPktBuilder(pkt = base_pkt1/pad),
                                        mode    = STLTXMultiBurst( pps = 10,
                                                                   pkts_per_burst = 4,
                                                                   ibg = 1000000.0,
                                                                   count = 5)
                                        )
                            ]).get_streams()
- 第一条流等待10us发送一次burst, 一次发送包的数量为10个包,以10PPS的速度进行发送  
- 第二条流等待第一条流burst 完后,发送5次burst, 每次burst的数量为4个包,发送速率为10PPS,每两次burst的间隔为1秒  
![](http://trex-tgn.cisco.com/trex/doc/images/stl_multiple_streams_01.png)    
  1. Loops of Streams
    def create_stream (self):

        # create a base packet and pad it to size
        size = self.fsize - 4 # no FCS
        base_pkt =  Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        base_pkt1 =  Ether()/IP(src="16.0.0.2",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        base_pkt2 =  Ether()/IP(src="16.0.0.3",dst="48.0.0.1")/UDP(dport=12,sport=1025)
        pad = max(0, size - len(base_pkt)) * 'x'

        return STLProfile( [ STLStream( isg = 10.0, # start in delay
                                        name    ='S0',
                                        packet = STLPktBuilder(pkt = base_pkt/pad),
                                        mode = STLTXSingleBurst( pps = 10, total_pkts = 1),
                                        next = 'S1'), # point to next stream
                             STLStream( self_start = False, # stream is disabled. Enabled by S0
                                        name    ='S1',
                                        packet  = STLPktBuilder(pkt = base_pkt1/pad),
                                        mode    = STLTXSingleBurst( pps = 10, total_pkts = 2),
                                        next    = 'S2' ),
                             STLStream(  self_start = False, # stream is disabled. Enabled by S1
                                         name   ='S2',
                                         packet = STLPktBuilder(pkt = base_pkt2/pad),
                                         mode = STLTXSingleBurst( pps = 10, total_pkts = 3 ),
                                         action_count = 2, # loop 2 times                       1
                                         next    = 'S0' # loop back to S0
                                        )
                            ]).get_streams()

S0->S1->S2->S0这个循环2次
6. Filed Engine

  • 通过上下文定位到stream中的字段
  • 改变stream中的字段
  • 改变包大小
  • 改变(src_ip, dst_ip, src_port,dst_port)
  • 更新checksum
    def create_stream (self):

        # TCP SYN
        base_pkt  = Ether()/IP(dst="48.0.0.1")/TCP(dport=80,flags="S")      # scapy 制造 Sync包

        # vm
        vm = STLScVmRaw( [ STLVmFlowVar(name="ip_src",    #取一个有语义的名字
                                              min_value="16.0.0.0",
                                              max_value="18.0.0.254",                # IP是4个字节
                                              size=4, op="random"),                     #操作方式是随机也可以定增(inc)  

                           STLVmFlowVar(name="src_port",
                                              min_value=1025,
                                              max_value=65000,                        # src_port是两个字节
                                              size=2, op="random"),                   #随机取源端口

                           STLVmWrFlowVar(fv_name="ip_src", pkt_offset= "IP.src" ), #把前面的变量运用到包的源IP上

                           STLVmFixIpv4(offset = "IP"), # fix checksum              #更新checksum 

                           STLVmWrFlowVar(fv_name="src_port",                   #把源端口的配置文件运用到包的源端口上
                                                pkt_offset= "TCP.sport") # U

                          ]
                       )

        pkt = STLPktBuilder(pkt = base_pkt,
                            vm = vm)
        return STLStream(packet = pkt,
                         random_seed = 0x1234,# can be removed. will give the same random value any run
                         mode = STLTXCont())
  • 执行
    trex>start -f stl/syn_attack.py -m 1mpps -d 10 -p 0
  • capture
    输入图片说明
    源IP源端口随机发送

参考

http://trex-tgn.cisco.com/trex/doc/trex_stateless.html

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部