A IPv6 header consists of a set of fields:
Copy 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-------+---------------+---------------------------------------+
|VERSION| Traffic Class | Flow Label |
+-------+---------------+-------+---------------+---------------+
| Payload Length | Next Header | Hop-Limit |
+-------------------------------+---------------+---------------+
| |
| Source Address |
| (128 bits) |
| |
+---------------------------------------------------------------+
| |
| Destination Address |
| (128 bits) |
| |
+---------------------------------------------------------------+
4-bit protocol version (IPV6#version
). Attended value is 6 for IPv6,
8-bit traffic class (`IPV6#traffic_class),
20-bit flow label (IPv6#flow_label
),
16-bit payload length (IPV6#length
), size of IPV6 payload, excluding the header,
8-bit next header (IPV6#next
) to indicate upper protocol (6 for TCP, and 17 for UDP
by example, but this may also be IPv6 options),
8-bit hop-limit (IPV6#hop
),
128-bit source IPV6 address (IPV6#src
),
128-bit destination IPV6 address (IPV6#dst
),
a body (IPV6#body
) containing data conveyed by IPv6.
A IPV6 header may be built this way:
Copy pg> PacketGen::Header::IPv6.new(hop: 32, src: '::1', dst: '::1')
=> ---- PacketGen::Header::IPv6 -----------------------------------------
Int32 u32: 1610612736 (0x60000000)
version: 6
tclass: 0 (0x00)
flow_label: 0 (0x00000)
Int16 length: 0 (0x0000)
Int8 next: 0 (0x00)
Int8 hop: 32 (0x20)
Addr src: ::1
Addr dst: ::1
IPv6 Packet
A IPv6 packet may be created this way:
Copy pkt = PacketGen . gen( 'IPV6' , ttl: 32 , src: '10.0.0.1' , dst: '20.0.0.1' , flag_df: true )
pkt . is? 'IPVv' # => true
pkt . ipv6 # => PacketGen::Header::IPv6
pkt . ipv6 . version # => 6
pkt . ipv6 . tclass # => Integer
pkt . ipv6 . flow_label # => Integer
pkt . ipv6 . length # => 0
pkt . ipv6 . next # => Integer
pkt . ipv6 . hop # => 32
pkt . ipv6 . dst # => '::1'
pkt . ipv6 . src = '::2'
pkt . ipv6 . src # => '::2'
pkt . body = 'This is a body'
pkt . length # => 0
As you can see, length
is not automatically set to correct value. But it may be set easily with IPv6#calc_length
. Packet#calc
may be used too: it automatically call #calc_sum
and #calc_length
on all headers responding to them:
Copy pg> pkt.calc
pg> pkt
=> -- PacketGen::Packet -------------------------------------------------
---- PacketGen::Header::IPv6 -----------------------------------------
Int32 u32: 1610612736 (0x60000000)
version: 6
tclass: 0 (0x00)
flow_label: 0 (0x00000)
Int16 length: 14 (0x000e)
Int8 next: 0 (0x00)
Int8 hop: 32 (0x20)
Addr src: ::2
Addr dst: ::1
---- Body ------------------------------------------------------------
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
----------------------------------------------------------------------
54 68 69 73 20 69 73 20 61 20 62 6f 64 79 This is a body
----------------------------------------------------------------------
TCP and UDP headers over IPv6
TCP and UDP headers may be added to a IPv6 packet:
Copy pg > pkt = PacketGen . gen( 'IPv6' , src: '::1' , dst: '::1' )
pg > pkt . add( 'TCP' , dport: 80 , sport: 51234 )
pg > pkt
=> -- PacketGen :: Packet -------------------------------------------------
---- PacketGen :: Header :: IPv6 -----------------------------------------
Int32 u32: 1610612736 ( 0x60000000 )
version: 6
tclass: 0 ( 0x00 )
flow_label: 0 ( 0x00000 )
Int16 length: 0 ( 0x0000 )
Int8 next: 6 ( 0x06 )
Int8 hop: 64 ( 0x40 )
Addr src: :: 1
Addr dst: :: 1
---- PacketGen :: Header :: TCP ------------------------------------------
Int16 sport: 51234 ( 0xc822 )
Int16 dport: 80 ( 0x0050 )
Int32 seqnum: 6082437 ( 0x005ccf85 )
Int32 acknum: 0 ( 0x00000000 )
Int16 u16: 20480 ( 0x5000 )
data_offset: 5 ( 0x5 )
reserved: 0
flags: .........
Int16 window: 0 ( 0x0000 )
Int16 checksum: 0 ( 0x0000 )
Int16 urg_pointer: 0 ( 0x0000 )
Options options:
See also http://rubydoc.info/gems/packetgen/PacketGen/Header/IPv6 .