Skip to content

Latest commit

 

History

History
670 lines (523 loc) · 22 KB

packet_builder_yaml.asciidoc

File metadata and controls

670 lines (523 loc) · 22 KB

Packet Builder Language

1. change log

Version name meaning

0.01

hhaim

  • first version

0.02

hhaim

  • change the bool fields to properties

  • add external/internal property

  • add const property ( instead cant_change)

  • change TLV property - now learn the prev header

  • add choice of next protocol that is not base on a field ( TCP→IP→TCP)

0.03

ybrustin

  • add MAC address regexp

  • add gui_representation class with data_type, form_type, combobox_values, data_type_regexp items to describe GUI view of field

  • rename choice attribute to value_based_next_header

  • fixed some typos

0.04

ybrustin

  • change value_based_next_header, combobox_values (to be consistent with value_based_next_header) to dictionary

  • added value_based_next_class for options

  • move help attribute to gui_representation

  • add link to headers.yaml (references at bottom of the page)

2. A file format for GUI packet builder

2.1. Introduction

We would like a file that will be read by GUI and will give us the ability to build packets using GUI

The format should be YAML

2.2. High Level Requirement

  • Define a YAML object format for dynamic building of packets and a program that change various fields

  • Ability to parse back the same buffer that was created using this tool (reversibility)

    • Ability to load packet from a pcap file and parse it

  • Ability to save the packet to a pcap file

  • Ability to save the packet and program in JSON format (same JSON-RPC format)

  • Set a value for any field of any protocol

  • Vary packet fields across packets at run time e.g. changing IP/MAC addresses

  • Stack protocols in any arbitrary order define in YAML format

2.3. Header that should be supported (first phase)

2.3.1. L2

  • Ethernet

  • 802.3

  • LLC SNAP

  • VLAN (with QinQ) stack

  • MPLS stack

2.3.2. L3

  • ARP

  • IPv4

  • IPv6 (4x header)

  • IP-in-IP a.k.a IP Tunnelling (6over4, 4over6, 4over4, 6over6)

2.3.3. L4

  • TCP

  • UDP

  • ICMPv4

  • ICMPv6

  • IGMP

2.3.4. L7

  • Any text based protocol (HTTP, SIP, RTSP, NNTP etc.)

    • random string

    • repeat string

  • Pattern Binary

    • repeat of value (e.g 0x55)

    • random

    • seq (1,2,3,3,4)

    • User Hex Dump editor

2.4. YAML Format

2.4.1. Header section

Table 1. Default Types
Field Name meaning size in bits

bit

describe the header object e.g tcp

1

uint8

describe the header object e.g tcp

8

uint16

the name in the GUI

16

uint32

sub fields of this header

32

uint64

sub fields of this header

64

other class type

name of other class. for example, "c-mac-addr"; take fields from there, optionally overload them later

The size taken from that class

Payload

Payload

total packet size - all header until now

vlen_t

in case of varible size header this include the size to the end of varible size header see example Ipv4Option

total size of the object

Table 2. Default Data_Type
Field Name meaning

none

use Hex Editor as Types

ipv4_t

4 decimals 0-255 each

mac_addr_t

([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}

ipv4_mask_t

should match uint32 type

ipv6_t

should have 16 bytes field size 8x16

ipv6_mask_t

should have 16 bytes field size 8x16

another header class

sub fields of this header

char_t

array of bytes , look into the array_size of cost string

var_char_t

array based on a field value look into

regexp_t

define a Java function that converts a reg exp string to a buffer see here RegExp

Table 3. Default Form_Type
Field Name meaning

none

simple editing field

combo_with_edit

combo box with predefined choices, can edit the field value manually

combo_without_edit

combo box with predefined choices, can not edit the field value manually

checkbox

toggle bits values, if item is array of bits, display several checkboxes per number of bits

Table 4. Default Gui_Representation
Field Name value type meaning Link Additional info

help

string

the name in the GUI

data_type

string

how to represent data

Data_Type

data_type could get data_type_regexp e.g data_type = "ipv4"; data_type = "regexp" data_type_regexp = "string that define regexp and Java function"

form_type

string

which editing form to use

Form_Type

for example for ip address use combobox with option to edit value manually or choose: key "localhost" value "127.0.0.1" etc.

combobox_values

dictionary

pairs of key - value for combo_with/without_edit

data_type_regexp

string

in case it is reg_exp the name of the function

GenRegExp

Table 5. Default Properties
Field Name meaning

ipv4_checksum

auto calculates checksum on this header Ipv4 type

tcp_checksum

calculate TCP checksum

udp_checksum

calculate UDP checksum

ipv4_total_length

calculate ipv4 total length this pkt_size = header + reset of packet

tlv

TLV length of the header (inlcudes the prev field length) example ip-option, tcp-option

le

little endian. deault is big

const

const field for example the 4 version of ipv4 header - this GUI won’t give option to change this field

external

marks the header as an external header for the GUI. for example IPv4 is external header and mac-addr is internal header ( compose external header)

Table 6. Field_Type
Field Name value type meaning Default Value Link Example

class

string

describe the class type

in case class is defined no need to have name and vise versa

class : tcp

name

string

describe the instance name

in case class is defined no need to have name and vise versa

name : tcp

array_size

integer

how many objects of this type, default value is 1

1

array_size : 6 in case of mac-addr

type

string

type, see Types define the size

"uint8_t"

Types

type : "uint32_t" type : "mac_addr"

gui_representation

dictionary

description of how to view/edit data in GUI

Gui_Representation

Gui_Representation_Example

default

array/value

default value in the packets , you can override value for subfields in parent see example

[0 ]x header size

Overide_Subfields_Example

properies

array of string like masks

properies of this fields

[]

Properties

["le","external"] , ["tlv","le","const"]

value_based_next_header

dictionary

define the next protocol based on a field value

none

Value_Based_Next_Header

value_based_next_class

dictionary

define the next class based on a field value (useful for options)

none

Value_Based_Next_Class

next_headers

string or type

a name of class that define the next or just an array

"none"

Next_headers

fields

array

array of Field_Type

[]

fields : [ ]

offset

integer/string

offset into the packet in bits, in case of auto add base of prev fields

"auto"

option

string

a java code that define a way to calculate varible size

"none"

Table 7. Field_Type
Field Name value type

"root"

the root pointer to the start of blocks L2/802.3 etc

"end"

end TLV headers

"payload"

the rest of the packets as buffer/string etc

Next_headers

Example of Next_headers

 - class : "next-example-t-1"
   gui_representation:
       help : "next-example-t-1"
   next_headers : ["ipv4", "ipv6, "tcp"]

# option 1 define in the header itself
 - class : "tcp"
   gui_representation:
       help : "TCP header"
   properies : ["external"]
   next_headers : ["ipv4", "ipv6, "tcp"]
   fields :
        - name : "ver"

# option 2 define throw a class
 - class : "tcp"
   gui_representation:
       help : "TCP header"
   properies : ["external"]
   next_headers : "next-example-t-1" #
   fields :
        - name : "ver"
Value_Based_Next_Header

Example of value_based_next_header

        value_based_next_header:
            0x0800: 'ipv4'# name of an external or internal class , the GUI should distinct betwean internal and external
            0x0806: 'arp'
            0x86DD: 'ipv6'
            0x8100: 'vlan'
            0x8847: 'mpls unicast'
            default: 'payload' # if no match for any of above
Generic RegExp Edit Field

This will define a regexp that match for user input and how to converts it to buffer of bytes

class MyClass : public RegExpBase {
  public:


  string get_reg_exp_string( ) {
    return ((\d){1-3})[.]((\d){1-3})[.]((\d){1-3})[.]((\d){1-3}))
  }

  # in case of match
  buffer get_buffer(){
     g= [get_group()[1].to_int()*256,get_group()[1].to_int()]
     # return list
     return (g)
  }

}

2.4.2. Relations between object headers

There would be a root object to point to possible starting headers

-  class : "root"
   gui_representation:
       help  : "Root"
   next_headers  : [ "ethernet", "llc", "_802-3"]

So in a way you could define a tree like this

root -> L2 (  Ethernet   , 802.3 , LLC SNAP  )
                |( by field )
                |
                  ------------------------------------- ( VLAN (with QinQ), MPLS , ipv4, ipv6,     ARP , ICMP )
                                                                                  |   |               |     |
                                                                                  |   ipv4/ipv6       -     -
                                                                                  |     |
                                                                                  |    |
  [Possibility - Ethernet/802.3/LLC SNAP)                                          |    UDP/TCP/Pyload
 Object                                                                            |     |
  for each option there tree of all the option                                      --- -

2.4.3. Rules

  • The size of the header and offset is automatically defined in default by the order of the fields ( inc by type size multiply by array_size)

  • It can be overrided by offset field ( put offset in the object ) and then an more advanced field can be shown earlier in the GUI

  • The packet size is defined before the headers. Header Should not be allowed to be added if the size + header size is bigger than packet size

  • "Payload" is predefined Fields that take the reset of the packet and user can edit it ( see Payload )

  • There would be a spare field in the Stream object so GUI could add more metadata for reconstructing the builder types for example in this example Ethrenet/IP/TCP/IP/TCP you can’t extrac from buffer alone that Payload is IP/TCP only the builder known that in build time.

  • Ip total length need to keep the total_pkt_size - this ip header . this should work for internal header too.

  • When GUI add header ("external") the total size of this header should be calculated ( varible size should be given a default - ipv4)

2.5. Examples

2.5.1. TLV (Ip option) , value_based_next_class

IP-option see ip_option

0 : END

1 : Length 1

other : Byte : Length ( +first) |option

 - class : "ip_option_131"
   gui_representation:
       help  : "ip_option"
   fields :
         - name : "length"    # tree with leaf of bits
           gui_representation:
               help : "length"
           type : uint8
           properties : ["tlv"] # the length include the prev field size (8 byte)

         - name : "pointer"    # tree with leaf of bits
           type : uint8

         - name : "buffer"    # tree with leaf of bits
           type : "tlv_reset"

 - class : "default_ip4_option_tlv"
   gui_representation:
       help  : "ip_option"
   fields :
         - name : "length"    # tree with leaf of bits
           gui_representation:
               help : "length"
           type : uint8
           properties : "tlv" # the length include the prev field size (8 byte)

         - name : "buffer"    # tree with leaf of bits
           type : "vlen_t"


 - class : "ip_option"
   gui_representation:
       help  : "ip_option"
   type : uint8
   default : [0x01]
   value_based_next_class :
       0x00  : "end"   # reserve name for ending the loop
       0x01  : "ip_option"   # back to this header
       0x131 : "ip_option_131"
       0x0812: "gre"
       default : "default_ip4_option_tlv"
  • case of varible length field ip_option example

2.5.2. Example TCP/IP

 - class : "c-mac-addr"
   type : "uint8"
   array_size : 6
   default : [0x00, 0x00, 0x01, 0x00, 0x00, 0x00]
   gui_representation:
      data_type  : "mac-addr_t" # format ([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}
      help  : "Mac addrees"


 - class : "ethernet"
   gui_representation:
       help : "Ethernet-L2"
   properties: ['external']
   fields :
        - name : "Dst"
          gui_representation:
              help : "destination mac"
          type : "c-mac-addr"

        - name : "Src"
          gui_representation:
              help : "source mac"
          type : "c-mac-addr"

        - name: "Ethertype"
          gui_representation:
              help: "Ethertype"
          type: "uint16"
          default: [0x0800]
          value_based_next_header :
                0x0800  : "ipv4"
                0x86DD  : "ipv6"
                0x8100  : "vlan"
                0x8847  : "mpls" #unicast
                default : "payload"


 - class : "ipv4"
   gui_representation:
       help : "Ipv4"
   fields :
        - name : "ver"
          gui_representation:
              help : "Version"
          type : "bit"
          array_size : 4
          default : [0, 1, 0, 0]
          properties : ["const"]

         - name : "ihl"
          type : "bit"
          array_size : 4
          default : [0, 1, 1, 1]
          properties : ["ipv4_ihl"]
          gui_representation:
              help : "IHL"
              form_type: "checkbox"

          ..

         - name : "hdr_chsum"
          gui_representation:
              help : "Header Checksum"
          default : [0x00,0x00]
          properties : ["ipv4_check_sum", "const"]

         - name : "total_len"
          gui_representation:
              help : "Total Length"
          default : [0x00,0x00]
          properties : ["ipv4_total_len", "const"] # auto calculate total_size-offset_header

         - name : "protocol"
          type : uint8
          default : 0x06
          value_based_next_header : &ipv4_next_header
               0x06  : "tcp"
               0x11  : "udp"
               0x29  : "ipv6"
               0x2F  : "gre"
               default : "payload"
          gui_representation:
              help : "IPv4 next Protocol"
              form_type: "combo_without_edit"
              combobox_values:
                <<: *ipv4_next_header # take same choices as value_based_next_header

         - name : "src_addr"
          type : uint32
          default : [16, 0, 0, 0]
          gui_representation:
              help : "Source Address"
              data_type  : "ipv4" # reserve

         - name : "dst_addr"
          default : [48, 0, 0, 0]
          type : uint32
          gui_representation:
              help : "Destination Address"
              data_type  : "ipv4" # reserve
              form_type : "combo_with_edit"
              combobox_values:
                    [127, 0, 0, 1]: 'localhost'
                    [255, 255, 255, 255]: 'broadcast'


 - class : "tcp"
   gui_representation:
       help : "TCP"
   properties : ["external"]
   fields :
         - name : "src_port"
          gui_representation:
              help : "Source Port"
          default : [0x30,0x00]
          type : uint16

         - name : "dest_port"
          gui_representation:
              help : "Source Port"
          default : [0x30,0x00]
          type : uint16

         - name : "seq"
          gui_representation:
              help : "Seq Number"
          type : uint32
          default : [0x30,0x00,00,00]

         - name : "ack"
          gui_representation:
              help : "Ack Number"
          type : uint32
          default : [0x30,0x00,00,00]

        ...

         - name : "flags"    # tree with leaf of bits
          gui_representation:
              help : "Ack Number"
          type : uint8
          default : [0x30]
          fields :
                 - name : "urg"
                  help : "URG"
                  type  : bit
                  default : [0x0]

                 - name : "ack"
                  help : "ACK"
                  type  : bit
                  default : [0x1]
                  ..

         - name : "checksum"
          gui_representation:
              help : "TCP Checksum"
          type : uint16
          default : [0x00,0x00]
          properties : ["tcp_checksum"] # auto calculate total_size-offset_header


-  class : "root" # reserve
   gui_representation:
       help  : "Root"
   next_headers : [ "ethrenet" ,"llc","_802-3"]
---------------------------


==== Overide subfields example anchor:Overide_Subfields_Example[]

In this example parent class default value overrides default values of sub-fields ( 2 different mac-addr)

[source,python]
  • class : "c-mac-addr" type : "uint8" array_size : 6 gui_representation: help : "Mac addrees" data_type : "mac-addr_t" # format ([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} default : [0x00,0x00,0x01,0x00,0x00,0x00]

  • class : "ethernet" gui_representation: help : "Ethernet-L2" properties : ["external"] default : [0x00,0x01,0x01,0x00,0x00,0x00, 0x00,0x02,0x02,0x00,0x00,0x00 ,0x08,00] # change the default of sub-fields . it is const size fields :

  • name : "Dst" gui_representation: help : "destination mac" type : "c-mac-addr"

  • name : "Src" gui_representation: help : "source mac" type : "c-mac-addr"

  • name : "ip_protocol" type : "uint16_t" default : [0x08,0x00] value_based_next_header : 0x0800 : "ipv4" 0x86DD : "ipv6" 0x8100 : "vlan" 0x8847 : "mpls unicast" default : "payload"

==== Gui Representation example anchor:Gui_Representation_Example[]
[underline]#In YAML:#
[source,python]
  • name: Flags type: bit array_size: 3 gui_representation: help: IPv4 Flags form_type: checkbox # can check each bit

  • name: dst_addr default: [48, 0, 0, 0] type: uint32 gui_representation: help: IPv4 Destination Address data_type: ipv4_t # special representation case, show as 4 decimal numbers form_type: combo_with_edit # can choose from pre-defined values or edit manually combobox_values: [127, 0, 0, 1]: localhost [255, 255, 255, 255]: broadcast

  • name: protocol type: uint8 default: 0x06 value_based_next_header: &ipv4_next_header 0x06: tcp 0x11: udp default : "payload" gui_representation: help: IPv4 Protocol Field form_type: combo_without_edit # choose from supported protocols, no manual edit combobox_values: <<: *ipv4_next_header # take same choices as value_based_next_header

[underline]#In GUI:#

checkbox for bits:

image:images/checkbox.jpg[]

editing in combo-box:

image:images/combo_button_editing.jpg[]

choosing from predefined values:

image:images/combo_button_choosing.jpg[]

==== Union base

TBD



=== Resource
*  link:yaml/headers.yaml[headers.yaml]
*  link:https://wireedit.com/[WireEdit]
*  link:http://ostinato.org/[ostinato]
*  link:http://www.slideshare.net/nlekh/ixiaexplorer[IxExplorer]