packetgen 4.0.0 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -9
- data/lib/packetgen/capture.rb +3 -6
- data/lib/packetgen/config.rb +1 -1
- data/lib/packetgen/deprecation.rb +7 -1
- data/lib/packetgen/header/arp.rb +7 -8
- data/lib/packetgen/header/asn1_base.rb +3 -2
- data/lib/packetgen/header/base.rb +39 -27
- data/lib/packetgen/header/bootp.rb +15 -15
- data/lib/packetgen/header/dhcp/option.rb +9 -9
- data/lib/packetgen/header/dhcp/options.rb +3 -3
- data/lib/packetgen/header/dhcp.rb +7 -8
- data/lib/packetgen/header/dhcpv6/duid.rb +3 -5
- data/lib/packetgen/header/dhcpv6/option.rb +38 -16
- data/lib/packetgen/header/dhcpv6/options.rb +4 -4
- data/lib/packetgen/header/dhcpv6/relay.rb +2 -1
- data/lib/packetgen/header/dhcpv6.rb +14 -15
- data/lib/packetgen/header/dns/name.rb +10 -9
- data/lib/packetgen/header/dns/opt.rb +4 -1
- data/lib/packetgen/header/dns/option.rb +8 -8
- data/lib/packetgen/header/dns/qdsection.rb +3 -3
- data/lib/packetgen/header/dns/question.rb +2 -1
- data/lib/packetgen/header/dns/rr.rb +2 -4
- data/lib/packetgen/header/dns/rrsection.rb +3 -3
- data/lib/packetgen/header/dns.rb +77 -61
- data/lib/packetgen/header/dot11/control.rb +6 -6
- data/lib/packetgen/header/dot11/data.rb +12 -11
- data/lib/packetgen/header/dot11/element.rb +2 -2
- data/lib/packetgen/header/dot11/management.rb +19 -16
- data/lib/packetgen/header/dot11/sub_mngt.rb +23 -22
- data/lib/packetgen/header/dot11.rb +39 -39
- data/lib/packetgen/header/dot1q.rb +6 -5
- data/lib/packetgen/header/dot1x.rb +9 -9
- data/lib/packetgen/header/eap/fast.rb +4 -4
- data/lib/packetgen/header/eap/md5.rb +12 -4
- data/lib/packetgen/header/eap/tls.rb +10 -9
- data/lib/packetgen/header/eap/ttls.rb +14 -11
- data/lib/packetgen/header/eap.rb +59 -34
- data/lib/packetgen/header/eth.rb +27 -13
- data/lib/packetgen/header/gre.rb +27 -3
- data/lib/packetgen/header/http/headers.rb +7 -6
- data/lib/packetgen/header/http/request.rb +25 -17
- data/lib/packetgen/header/http/response.rb +23 -16
- data/lib/packetgen/header/http/verbs.rb +1 -1
- data/lib/packetgen/header/http.rb +1 -1
- data/lib/packetgen/header/icmp.rb +11 -11
- data/lib/packetgen/header/icmpv6.rb +11 -10
- data/lib/packetgen/header/igmp.rb +22 -11
- data/lib/packetgen/header/igmpv3/group_record.rb +8 -3
- data/lib/packetgen/header/igmpv3/mq.rb +2 -2
- data/lib/packetgen/header/igmpv3/mr.rb +2 -2
- data/lib/packetgen/header/igmpv3.rb +12 -11
- data/lib/packetgen/header/ip/addr.rb +7 -3
- data/lib/packetgen/header/ip/option.rb +19 -6
- data/lib/packetgen/header/ip/options.rb +1 -1
- data/lib/packetgen/header/ip.rb +53 -36
- data/lib/packetgen/header/ipv6/addr.rb +15 -14
- data/lib/packetgen/header/ipv6/extension.rb +10 -8
- data/lib/packetgen/header/ipv6/hop_by_hop.rb +27 -8
- data/lib/packetgen/header/ipv6.rb +32 -23
- data/lib/packetgen/header/llc.rb +21 -14
- data/lib/packetgen/header/mdns.rb +10 -3
- data/lib/packetgen/header/mld.rb +12 -10
- data/lib/packetgen/header/mldv2/mcast_address_record.rb +7 -2
- data/lib/packetgen/header/mldv2/mlq.rb +9 -9
- data/lib/packetgen/header/mldv2/mlr.rb +5 -5
- data/lib/packetgen/header/mldv2.rb +2 -2
- data/lib/packetgen/header/ospfv2/db_description.rb +11 -11
- data/lib/packetgen/header/ospfv2/hello.rb +12 -11
- data/lib/packetgen/header/ospfv2/ls_ack.rb +6 -7
- data/lib/packetgen/header/ospfv2/ls_request.rb +8 -7
- data/lib/packetgen/header/ospfv2/ls_update.rb +8 -8
- data/lib/packetgen/header/ospfv2/lsa.rb +34 -11
- data/lib/packetgen/header/ospfv2/lsa_header.rb +4 -3
- data/lib/packetgen/header/ospfv2.rb +32 -27
- data/lib/packetgen/header/ospfv3/db_description.rb +13 -14
- data/lib/packetgen/header/ospfv3/hello.rb +11 -10
- data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +7 -3
- data/lib/packetgen/header/ospfv3/ls_ack.rb +6 -7
- data/lib/packetgen/header/ospfv3/ls_request.rb +11 -11
- data/lib/packetgen/header/ospfv3/ls_update.rb +8 -8
- data/lib/packetgen/header/ospfv3/lsa.rb +24 -10
- data/lib/packetgen/header/ospfv3/lsa_header.rb +4 -3
- data/lib/packetgen/header/ospfv3.rb +39 -35
- data/lib/packetgen/header/sctp/chunk.rb +39 -18
- data/lib/packetgen/header/sctp/error.rb +170 -198
- data/lib/packetgen/header/sctp/padded32.rb +4 -4
- data/lib/packetgen/header/sctp/parameter.rb +86 -133
- data/lib/packetgen/header/sctp.rb +15 -4
- data/lib/packetgen/header/snmp.rb +111 -10
- data/lib/packetgen/header/tcp/option.rb +8 -1
- data/lib/packetgen/header/tcp/options.rb +12 -4
- data/lib/packetgen/header/tcp.rb +34 -27
- data/lib/packetgen/header/tftp.rb +17 -11
- data/lib/packetgen/header/udp.rb +16 -14
- data/lib/packetgen/header.rb +20 -14
- data/lib/packetgen/headerable.rb +10 -4
- data/lib/packetgen/inject.rb +1 -1
- data/lib/packetgen/inspect.rb +3 -8
- data/lib/packetgen/packet.rb +95 -37
- data/lib/packetgen/pcap.rb +1 -1
- data/lib/packetgen/pcapng/block.rb +3 -2
- data/lib/packetgen/pcapng/epb.rb +1 -1
- data/lib/packetgen/pcapng/file.rb +42 -15
- data/lib/packetgen/pcapng/idb.rb +3 -2
- data/lib/packetgen/pcapng/shb.rb +3 -2
- data/lib/packetgen/pcapng/spb.rb +2 -2
- data/lib/packetgen/pcapng/unknown_block.rb +1 -1
- data/lib/packetgen/pcapng.rb +3 -1
- data/lib/packetgen/pcaprub_wrapper.rb +1 -1
- data/lib/packetgen/proto.rb +5 -1
- data/lib/packetgen/unknown_packet.rb +4 -4
- data/lib/packetgen/utils/arp_spoofer.rb +1 -1
- data/lib/packetgen/utils.rb +4 -5
- data/lib/packetgen/version.rb +2 -2
- data/lib/packetgen.rb +9 -3
- metadata +8 -9
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -15,30 +15,31 @@ module PacketGen
|
|
15
15
|
# | Type | Code | Checksum |
|
16
16
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
17
17
|
# A ICMPv6 header consists of:
|
18
|
-
# * a
|
19
|
-
# * a
|
20
|
-
# * a
|
21
|
-
# * and a
|
18
|
+
# * a {#type #type} field (+BinStruct::Int8+ type),
|
19
|
+
# * a {#code #code} field (+BinStruct::Int8+ type),
|
20
|
+
# * a {#checksum #checksum} field (+BinStruct::Int16+ type),
|
21
|
+
# * and a {#body #body}.
|
22
22
|
#
|
23
|
-
#
|
23
|
+
# @example Create a ICMPv6 header
|
24
24
|
# # standalone
|
25
25
|
# icmpv6 = PacketGen::Header::ICMPv6.new
|
26
26
|
# # in a packet
|
27
27
|
# pkt = PacketGen.gen('IPv6').add('ICMPv6')
|
28
28
|
# # access to ICMPv6 header
|
29
|
-
# pkt.icmpv6
|
29
|
+
# pkt.icmpv6.class # => PacketGen::Header::ICMPv6
|
30
30
|
#
|
31
|
-
#
|
31
|
+
# @example ICMPv6 attributes
|
32
|
+
# icmpv6 = PacketGen::Header::ICMPv6.new
|
32
33
|
# icmpv6.code = 0
|
33
34
|
# icmpv6.type = 200
|
34
35
|
# icmpv6.checksum = 0x248a
|
35
|
-
# icmpv6.body
|
36
|
+
# icmpv6.body = 'this is a body'
|
36
37
|
# @author Sylvain Daubert
|
37
38
|
class ICMPv6 < ICMP
|
38
39
|
# ICMPv6 internet protocol number
|
39
40
|
IP_PROTOCOL = 58
|
40
41
|
|
41
|
-
# Compute checksum and set +checksum+ field
|
42
|
+
# Compute IPV6-style checksum and set +checksum+ field
|
42
43
|
# @return [Integer]
|
43
44
|
def calc_checksum
|
44
45
|
sum = ip_header(self).pseudo_header_checksum
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -20,25 +20,29 @@ module PacketGen
|
|
20
20
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
21
21
|
#
|
22
22
|
# A IGMP header consists of:
|
23
|
-
# * a {#type} field (
|
24
|
-
# * a {#max_resp_time} field (
|
25
|
-
# * a {#checksum} field (
|
23
|
+
# * a {#type} field (+BinStruct::Int8Enum+ type),
|
24
|
+
# * a {#max_resp_time} field (+BinStruct::Int8+ type),
|
25
|
+
# * a {#checksum} field (+BinStruct::Int16+ type),
|
26
26
|
# * a {#group_addr} field ({Header::IP::Addr} type),
|
27
27
|
# * and a {#body} (unused for IGMPv2).
|
28
28
|
#
|
29
|
-
#
|
29
|
+
# After adding a IGMP header to a packet, you have to call {#igmpize} to ensure
|
30
|
+
# resulting packet conforms to RFC 2236.
|
31
|
+
#
|
32
|
+
# @example Create a IGMP header
|
30
33
|
# # standalone
|
31
34
|
# igmp = PacketGen::Header::IGMP.new
|
32
35
|
# # in a packet
|
33
36
|
# pkt = PacketGen.gen('IP').add('IGMP')
|
34
37
|
# # access to IGMP header
|
35
|
-
# pkt.igmp
|
38
|
+
# pkt.igmp.class # => PacketGen::Header::IGMP
|
36
39
|
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
40
|
+
# @example IGMP attributes
|
41
|
+
# igmp = PacketGen::Header::IGMP.new
|
42
|
+
# igmp.type = 'MembershipQuery' # or 0x11
|
43
|
+
# igmp.max_resp_time = 20
|
44
|
+
# igmp.checksum = 0x248a
|
45
|
+
# igmp.group_addr = '224.0.0.1'
|
42
46
|
# @author Sylvain Daubert
|
43
47
|
# @since 2.4.0
|
44
48
|
class IGMP < Base
|
@@ -70,12 +74,14 @@ module PacketGen
|
|
70
74
|
# @return [IP::Addr]
|
71
75
|
define_attr :group_addr, IP::Addr, default: '0.0.0.0'
|
72
76
|
# @!attribute body
|
77
|
+
# IGMP body (not used in IGMPv2)
|
73
78
|
# @return [String,Base]
|
74
79
|
define_attr :body, BinStruct::String
|
75
80
|
|
76
81
|
# @api private
|
77
82
|
# @note This method is used internally by PacketGen and should not be
|
78
83
|
# directly called
|
84
|
+
# Define +#igmpize+ method onto +packet+. This method calls {#igmpize}.
|
79
85
|
def added_to_packet(packet)
|
80
86
|
igmp_idx = packet.headers.size
|
81
87
|
packet.instance_eval "def igmpize() @headers[#{igmp_idx}].igmpize; end" # def igmpize() @headers[2].igmpize; end
|
@@ -103,6 +109,11 @@ module PacketGen
|
|
103
109
|
# pkt.igmp.igmpize
|
104
110
|
# # second method
|
105
111
|
# pkt.igmpize
|
112
|
+
# @example
|
113
|
+
# pkt = PacketGen.gen('IP').add('IGMP', type: 'MembershipQuery', max_resp_time: 20, group_addr: '1.2.3.4')
|
114
|
+
# pkt.igmpize
|
115
|
+
# pkt.ip.ttl #=> 1
|
116
|
+
# pkt.ip.options.map(&:class) #=> [PacketGen::Header::IP::RA]
|
106
117
|
# @return [void]
|
107
118
|
def igmpize
|
108
119
|
iph = ip_header(self)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -11,7 +11,7 @@ module PacketGen
|
|
11
11
|
class IGMPv3
|
12
12
|
# Class to handle IGMPv3 Group Records.
|
13
13
|
#
|
14
|
-
# A Group Record is a block of attributes
|
14
|
+
# A Group Record is a block of attributes containing information
|
15
15
|
# pertaining to the sender's membership in a single multicast group on
|
16
16
|
# the interface from which the Report is sent.
|
17
17
|
#
|
@@ -76,14 +76,19 @@ module PacketGen
|
|
76
76
|
define_attr :source_addr, IP::ArrayOfAddr,
|
77
77
|
builder: ->(h, t) { t.new(counter: h[:number_of_sources]) }
|
78
78
|
# @!attribute aux_data
|
79
|
+
# Not used in IGMPv3
|
79
80
|
# @return [String]
|
80
81
|
define_attr :aux_data, BinStruct::String,
|
81
82
|
builder: ->(h, t) { t.new(length_from: -> { h[:aux_data_len].to_i * 4 }) }
|
82
83
|
|
84
|
+
# Human-readable type
|
85
|
+
# @return [String]
|
83
86
|
def human_type
|
84
87
|
self[:type].to_human
|
85
88
|
end
|
86
89
|
|
90
|
+
# Human-readable description of a group record
|
91
|
+
# @return [String]
|
87
92
|
def to_human
|
88
93
|
"#{human_type}(ma:#{multicast_addr}|src:#{source_addr.to_human})"
|
89
94
|
end
|
@@ -94,7 +99,7 @@ module PacketGen
|
|
94
99
|
class GroupRecords < BinStruct::Array
|
95
100
|
set_of GroupRecord
|
96
101
|
|
97
|
-
# Separator used in
|
102
|
+
# Separator used in +#to_human+.
|
98
103
|
HUMAN_SEPARATOR = ';'
|
99
104
|
end
|
100
105
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -49,7 +49,7 @@ module PacketGen
|
|
49
49
|
# First 8-bit field, composed of {#resv}, {#flag_s} and {#qrv}
|
50
50
|
# @return [Integer]
|
51
51
|
# @!attribute resv
|
52
|
-
# 4-bit reserved field
|
52
|
+
# 4-bit reserved field
|
53
53
|
# @return [Integer]
|
54
54
|
# @!attribute flag_s
|
55
55
|
# 1-bit S flag (Suppress Router-Side Processing)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -48,7 +48,7 @@ module PacketGen
|
|
48
48
|
class MR < Base
|
49
49
|
# @!attribute reserved
|
50
50
|
# 16-bit reserved field
|
51
|
-
#
|
51
|
+
# @return [Integer]
|
52
52
|
define_attr :reserved, BinStruct::Int16, default: 0
|
53
53
|
# @!attribute number_of_gr
|
54
54
|
# 16-bit Number of group records in {#group_records}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -18,23 +18,24 @@ module PacketGen
|
|
18
18
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
19
|
#
|
20
20
|
# A IGMP header consists of:
|
21
|
-
# * a {#type} field (
|
22
|
-
# * a {#max_resp_time} field (
|
23
|
-
# * a {#checksum} field (
|
24
|
-
# * and a {#body}, containing more fields (see below).
|
21
|
+
# * a {#type #type} field (+BinStruct::Int8Enum+ type),
|
22
|
+
# * a {#max_resp_time #max_resp_time} field (+BinStruct::Int8+ type),
|
23
|
+
# * a {#checksum #checksum} field (+BinStruct::Int16+ type),
|
24
|
+
# * and a {#body #body}, containing more fields (see below).
|
25
25
|
#
|
26
|
-
# A IGMPv3 header may have additionnal fields. These attributes
|
26
|
+
# A IGMPv3 header may have additionnal fields. These attributes are handled by
|
27
27
|
# additional headers (see {IGMPv3::MQ}).
|
28
28
|
#
|
29
|
-
#
|
29
|
+
# @example Create a IGMPv3 header
|
30
30
|
# # standalone
|
31
31
|
# igmp = PacketGen::Header::IGMPv3.new
|
32
32
|
# # in a packet
|
33
33
|
# pkt = PacketGen.gen('IP').add('IGMPv3')
|
34
34
|
# # access to IGMPv3 header
|
35
|
-
# pkt.
|
35
|
+
# pkt.igmpv3.class # => PacketGen::Header::IGMPv3
|
36
36
|
#
|
37
|
-
#
|
37
|
+
# @example IGMPv3 attributes
|
38
|
+
# igmp = PacketGen::Header::IGMPv3.new
|
38
39
|
# igmp.type = 'MembershipQuery' # or 0x11
|
39
40
|
# igmp.max_resp_time = 20
|
40
41
|
# igmp.checksum = 0x248a
|
@@ -50,14 +51,14 @@ module PacketGen
|
|
50
51
|
# igmp.max_resp_code #=> 9728 error due to encoding as a floating point value
|
51
52
|
#
|
52
53
|
# === IGMPv3 Membership Query
|
53
|
-
# With IGMPv3, a Membership Query packet has more attributes
|
54
|
+
# With IGMPv3, a Membership Query packet has more attributes than with IGMPv2. To
|
54
55
|
# handle those fields, an additional header should be used:
|
55
56
|
# pkt = PacketGen.gen('IP').add('IGMPv3', type: 'MembershipQuery').add('IGMPv3::MQ')
|
56
57
|
# pkt.igmpv3 #=> PacketGen::Header::IGMPv3
|
57
58
|
# pkt.igmpv3_mq #=> PacketGen::Header::IGMPv3::MQ
|
58
59
|
#
|
59
60
|
# === IGMPv3 Membership Report
|
60
|
-
# With IGMPv3, a Membership Report packet has more attributes
|
61
|
+
# With IGMPv3, a Membership Report packet has more attributes than with IGMPv2. To
|
61
62
|
# handle those fields, an additional header should be used:
|
62
63
|
# pkt = PacketGen.gen('IP').add('IGMPv3', type: 'MembershipQuery').add('IGMPv3::MR')
|
63
64
|
# pkt.igmpv3 #=> PacketGen::Header::IGMPv3
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -18,7 +18,7 @@ module PacketGen
|
|
18
18
|
# @return [Integer] IP address first byte
|
19
19
|
define_attr :a1, BinStruct::Int8
|
20
20
|
# @!attribute a2
|
21
|
-
# @return [Integer] IP address
|
21
|
+
# @return [Integer] IP address second byte
|
22
22
|
define_attr :a2, BinStruct::Int8
|
23
23
|
# @!attribute a3
|
24
24
|
# @return [Integer] IP address third byte
|
@@ -27,6 +27,7 @@ module PacketGen
|
|
27
27
|
# @return [Integer] IP address fourth byte
|
28
28
|
define_attr :a4, BinStruct::Int8
|
29
29
|
|
30
|
+
## Regex to match IPv4 addresses
|
30
31
|
IPV4_ADDR_REGEX = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
|
31
32
|
|
32
33
|
# Read a dotted address
|
@@ -51,7 +52,7 @@ module PacketGen
|
|
51
52
|
attributes.map { |f| self[f].to_i.to_s }.join('.')
|
52
53
|
end
|
53
54
|
|
54
|
-
# Addr as
|
55
|
+
# Addr as a 32-bit integer
|
55
56
|
# @return [Integer]
|
56
57
|
def to_i
|
57
58
|
(self.a1 << 24) | (self.a2 << 16) | (self.a3 << 8) |
|
@@ -64,6 +65,9 @@ module PacketGen
|
|
64
65
|
self.a1 >= 224 && self.a1 <= 239
|
65
66
|
end
|
66
67
|
|
68
|
+
# Check equality.
|
69
|
+
# Equal is other has same class and all attributes are equal.
|
70
|
+
# @return [Boolean]
|
67
71
|
def ==(other)
|
68
72
|
other.is_a?(self.class) &&
|
69
73
|
attributes.all? { |attr| self[attr].value == other[attr].value }
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -17,7 +17,11 @@ module PacketGen
|
|
17
17
|
# Push a IP address to the array
|
18
18
|
# @param [String,Addr] addr
|
19
19
|
# @return [self]
|
20
|
+
# @example
|
21
|
+
# array = PacketGen::Header::IP::ArrayOfAddr.new
|
22
|
+
# # #<< uses #push internally
|
20
23
|
# array << '192.168.1.12'
|
24
|
+
# array.push(PacketGen::Header::IP::Addr.new.from_human('192.18.1.13'))
|
21
25
|
def push(addr)
|
22
26
|
addr = Addr.new.from_human(addr) unless addr.is_a?(Addr)
|
23
27
|
super
|
@@ -46,7 +50,7 @@ module PacketGen
|
|
46
50
|
|
47
51
|
# @!attribute type
|
48
52
|
# 8-bit option type
|
49
|
-
#
|
53
|
+
# @return [Integer]
|
50
54
|
# @!attribute copied
|
51
55
|
# 1-bit copied flag from {#type} field
|
52
56
|
# @return [Integer]
|
@@ -60,15 +64,17 @@ module PacketGen
|
|
60
64
|
define_bit_attr :type, copied: 1, option_class: 2, number: 5
|
61
65
|
# @!attribute length
|
62
66
|
# 8-bit option length. If 0, there is no +length+ field in option
|
63
|
-
#
|
67
|
+
# @return [Integer]
|
64
68
|
define_attr :length, BinStruct::Int8, default: 0, optional: ->(h) { h.type > 1 }
|
65
69
|
# @!attribute data
|
66
70
|
# option data
|
67
|
-
#
|
71
|
+
# @return [String]
|
68
72
|
define_attr :data, BinStruct::String, optional: ->(h) { h.length > 2 },
|
69
73
|
builder: ->(h, t) { t.new(length_from: -> { h.length - 2 }) }
|
70
74
|
|
71
|
-
# @
|
75
|
+
# @private
|
76
|
+
# Return a cached hash associating type name to its value.
|
77
|
+
# @return [Hash{String => Integer}]
|
72
78
|
def self.types
|
73
79
|
return @types if defined? @types
|
74
80
|
|
@@ -83,6 +89,7 @@ module PacketGen
|
|
83
89
|
end
|
84
90
|
|
85
91
|
# Factory to build an option from its type
|
92
|
+
# @param [Hash] options
|
86
93
|
# @return [Option]
|
87
94
|
def self.build(options={})
|
88
95
|
type = options[:type]
|
@@ -96,6 +103,8 @@ module PacketGen
|
|
96
103
|
klass.new(options)
|
97
104
|
end
|
98
105
|
|
106
|
+
# Force type value for subclasses, if not specified
|
107
|
+
# @return [Option]
|
99
108
|
def initialize(options={})
|
100
109
|
options[:type] = class2type unless options[:type]
|
101
110
|
|
@@ -153,7 +162,7 @@ module PacketGen
|
|
153
162
|
remove_attr :data
|
154
163
|
|
155
164
|
# @!attribute pointer
|
156
|
-
# 8-bit
|
165
|
+
# 8-bit po+++inter on next address
|
157
166
|
# @return [Integer]
|
158
167
|
define_attr :pointer, BinStruct::Int8, default: 4
|
159
168
|
# @!attribute data
|
@@ -190,6 +199,8 @@ module PacketGen
|
|
190
199
|
# @return [Integer]
|
191
200
|
define_attr :id, BinStruct::Int16
|
192
201
|
|
202
|
+
# Return a human-readable string
|
203
|
+
# @return [String]
|
193
204
|
def to_human
|
194
205
|
super << ":#{self.id}"
|
195
206
|
end
|
@@ -204,6 +215,8 @@ module PacketGen
|
|
204
215
|
# @return [Integer]
|
205
216
|
define_attr :value, BinStruct::Int16, default: 0
|
206
217
|
|
218
|
+
# Return a human-readable string
|
219
|
+
# @return [String]
|
207
220
|
def to_human
|
208
221
|
super << ":#{self.value}"
|
209
222
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
data/lib/packetgen/header/ip.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# This file is part of PacketGen
|
4
|
-
# See https://
|
4
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
5
5
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
6
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
7
7
|
# This program is published under MIT license.
|
@@ -27,32 +27,33 @@ module PacketGen
|
|
27
27
|
# | Options | Padding |
|
28
28
|
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
29
29
|
# A IP header consists of:
|
30
|
-
# * a first byte ({#u8} of
|
30
|
+
# * a first byte ({#u8} of +BinStruct::Int8+ type) composed of:
|
31
31
|
# * a 4-bit {#version} field,
|
32
32
|
# * a 4-bit IP header length ({#ihl}) field,
|
33
|
-
# * a Type of Service field ({#tos},
|
34
|
-
# * a total length ({#length},
|
35
|
-
# * a ID ({#id}, +Int16+ type),
|
36
|
-
# * a {#frag} worg (+Int16+) composed of:
|
33
|
+
# * a Type of Service field ({#tos}, +BinStruct::Int8+ type),
|
34
|
+
# * a total length ({#length}, +BinStruct::Int16+ type),
|
35
|
+
# * a ID ({#id}, +BinStruct::Int16+ type),
|
36
|
+
# * a {#frag} worg (+BinStruct::Int16+) composed of:
|
37
37
|
# * 3 1-bit flags ({#flag_rsv}, {#flag_df} and {#flag_mf}),
|
38
38
|
# * a 13-bit {#fragment_offset} field,
|
39
39
|
# * a Time-to-Live ({#ttl}) field (+Int8+),
|
40
|
-
# * a {#protocol} field (+Int8+),
|
41
|
-
# * a {#checksum} field (+Int16+),
|
40
|
+
# * a {#protocol} field (+BinStruct::Int8+),
|
41
|
+
# * a {#checksum} field (+BinStruct::Int16+),
|
42
42
|
# * a source IP address ({#src}, {Addr} type),
|
43
|
-
# * a destination IP address ({#dst},
|
43
|
+
# * a destination IP address ({#dst}, {Addr} type),
|
44
44
|
# * an optional {#options} field ({Options} type),
|
45
|
-
# * and a {#body} (
|
45
|
+
# * and a {#body} (+BinStruct::String+ type).
|
46
46
|
#
|
47
|
-
#
|
47
|
+
# @example Create a IP header
|
48
48
|
# # standalone
|
49
49
|
# ip = PacketGen::Header::IP.new
|
50
50
|
# # in a packet
|
51
51
|
# pkt = PacketGen.gen('IP')
|
52
52
|
# # access to IP header
|
53
|
-
# pkt.ip # => PacketGen::Header::IP
|
53
|
+
# pkt.ip.class # => PacketGen::Header::IP
|
54
54
|
#
|
55
|
-
#
|
55
|
+
# @example IP attributes
|
56
|
+
# ip = PacketGen::Header::IP.new
|
56
57
|
# ip.u8 = 0x45
|
57
58
|
# # the same as
|
58
59
|
# ip.version = 4
|
@@ -66,21 +67,20 @@ module PacketGen
|
|
66
67
|
# ip.flag_mf = true
|
67
68
|
# ip.fragment_offset = 0x31
|
68
69
|
#
|
69
|
-
# ip.flag_rsv? # =>
|
70
|
-
# ip.flag_df? # =>
|
71
|
-
# ip.flag_mf? # =>
|
70
|
+
# ip.flag_rsv? # => false
|
71
|
+
# ip.flag_df? # => false
|
72
|
+
# ip.flag_mf? # => true
|
72
73
|
#
|
73
74
|
# ip.ttl = 0x40
|
74
75
|
# ip.protocol = 6
|
75
76
|
# ip.checksum = 0xffff
|
76
77
|
# ip.src = '127.0.0.1'
|
77
78
|
# ip.src # => "127.0.0.1"
|
78
|
-
# ip[:src]
|
79
|
+
# ip[:src].class # => PacketGen::Header::IP::Addr
|
79
80
|
# ip.dst = '127.0.0.2'
|
80
|
-
# ip.body
|
81
|
+
# ip.body = 'this is a body'
|
81
82
|
#
|
82
|
-
#
|
83
|
-
# IP has an {#options} attribute used to store datagram options.
|
83
|
+
# @example Add IP options
|
84
84
|
# pkt = PacketGen.gen('IP')
|
85
85
|
# # add option from class
|
86
86
|
# pkt.ip.options << PacketGen::Header::IP::RA.new
|
@@ -101,52 +101,68 @@ module PacketGen
|
|
101
101
|
# First byte of IP header. May be accessed through {#version} and {#ihl}.
|
102
102
|
# @return [Integer] first byte of IP header.
|
103
103
|
# @!attribute version
|
104
|
-
#
|
104
|
+
# 4-bit version attribute
|
105
|
+
# @return [Integer]
|
105
106
|
# @!attribute ihl
|
106
|
-
#
|
107
|
+
# 4-bit IP header length attribute, as 32-bit word count.
|
108
|
+
# Default to 5 (IP header without option).
|
109
|
+
# @return [Integer]
|
107
110
|
define_bit_attr :u8, default: 0x45, version: 4, ihl: 4
|
108
111
|
# @!attribute tos
|
109
112
|
# @return [Integer] 8-bit Type of Service self[attr]
|
110
113
|
define_attr :tos, BinStruct::Int8, default: 0
|
111
114
|
# @!attribute length
|
112
|
-
#
|
115
|
+
# 16-bit IP total length, including this header.
|
116
|
+
# @return [Integer]
|
113
117
|
define_attr :length, BinStruct::Int16, default: 20
|
114
118
|
# @!attribute id
|
115
119
|
# @return [Integer] 16-bit ID
|
116
120
|
define_attr :id, BinStruct::Int16, default: ->(_) { rand(65_535) }
|
117
121
|
# @!attribute frag
|
118
|
-
#
|
122
|
+
# 16-bit frag word
|
123
|
+
# @return [Integer]
|
119
124
|
# @!attribute flag_rsv
|
120
|
-
#
|
125
|
+
# reserved bit from flags
|
126
|
+
# @return [Boolean]
|
121
127
|
# @!attribute flag_df
|
122
|
-
#
|
128
|
+
# Don't Fragment flag
|
129
|
+
# @return [Boolean]
|
123
130
|
# @!attribute flag_mf
|
124
|
-
#
|
131
|
+
# More Fragment flags
|
132
|
+
# @return [Boolean]
|
125
133
|
# @!attribute fragment_offset
|
126
|
-
#
|
134
|
+
# 13-bit fragment offset
|
135
|
+
# @return [Integer]
|
127
136
|
define_bit_attr :frag, flag_rsv: 1, flag_df: 1, flag_mf: 1, fragment_offset: 13
|
128
137
|
# @!attribute ttl
|
129
|
-
#
|
138
|
+
# 8-bit Time To Live
|
139
|
+
# @return [Integer]
|
130
140
|
define_attr :ttl, BinStruct::Int8, default: 64
|
131
141
|
# @!attribute protocol
|
132
|
-
#
|
142
|
+
# 8-bit upper protocol
|
143
|
+
# @return [Integer]
|
133
144
|
define_attr :protocol, BinStruct::Int8
|
134
145
|
# @!attribute checksum
|
135
|
-
#
|
146
|
+
# 16-bit IP header checksum
|
147
|
+
# @return [Integer]
|
136
148
|
define_attr :checksum, BinStruct::Int16, default: 0
|
137
149
|
# @!attribute src
|
138
|
-
#
|
150
|
+
# source IP address
|
151
|
+
# @return [Addr]
|
139
152
|
define_attr :src, Addr, default: '127.0.0.1'
|
140
153
|
# @!attribute dst
|
141
|
-
#
|
154
|
+
# destination IP address
|
155
|
+
# @return [Addr]
|
142
156
|
define_attr :dst, Addr, default: '127.0.0.1'
|
143
157
|
# @!attribute options
|
158
|
+
# IP options
|
144
159
|
# @since 2.2.0
|
145
|
-
# @return [
|
160
|
+
# @return [Options]
|
146
161
|
define_attr :options, Options, optional: ->(h) { h.ihl > 5 },
|
147
162
|
builder: ->(h, t) { t.new(length_from: -> { (h.ihl - 5) * 4 }) }
|
148
163
|
# @!attribute body
|
149
|
-
#
|
164
|
+
# IP body
|
165
|
+
# @return [BinStruct::String,Headerable]
|
150
166
|
define_attr :body, BinStruct::String
|
151
167
|
|
152
168
|
# Helper method to compute sum of 16-bit words. Used to compute IP-style
|
@@ -224,7 +240,8 @@ module PacketGen
|
|
224
240
|
end
|
225
241
|
|
226
242
|
# Check version field
|
227
|
-
# @see
|
243
|
+
# @see Base#parse?
|
244
|
+
# @return [Boolean]
|
228
245
|
def parse?
|
229
246
|
(version == 4) && (ihl >= 5)
|
230
247
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# This file is part of PacketGen
|
5
|
-
# See https://
|
5
|
+
# See https://codeberg.org/lemontree55/packetgen for more informations
|
6
6
|
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
|
7
7
|
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
|
8
8
|
# This program is published under MIT license.
|
@@ -14,6 +14,7 @@ module PacketGen
|
|
14
14
|
class IPv6
|
15
15
|
# IPv6 address, as a group of 8 2-byte words
|
16
16
|
# @author Sylvain Daubert
|
17
|
+
# @author LemonTree55
|
17
18
|
class Addr < BinStruct::Struct
|
18
19
|
include BinStruct::Structable
|
19
20
|
|
@@ -50,11 +51,10 @@ module PacketGen
|
|
50
51
|
# @return [Integer]
|
51
52
|
define_attr :a8, BinStruct::Int16
|
52
53
|
|
53
|
-
# rubocop:disable Metrics/AbcSize
|
54
|
-
|
55
54
|
# Read a colon-delimited address
|
56
55
|
# @param [String] str
|
57
56
|
# @return [self]
|
57
|
+
# @raise [ArgumentError] not a colon-delimited IPv6 address
|
58
58
|
def from_human(str)
|
59
59
|
return self if str.nil?
|
60
60
|
|
@@ -62,19 +62,13 @@ module PacketGen
|
|
62
62
|
raise ArgumentError, 'string is not a IPv6 address' unless addr.ipv6?
|
63
63
|
|
64
64
|
addri = addr.to_i
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
self.a4 = addri >> 64 & 0xffff
|
69
|
-
self.a5 = addri >> 48 & 0xffff
|
70
|
-
self.a6 = addri >> 32 & 0xffff
|
71
|
-
self.a7 = addri >> 16 & 0xffff
|
72
|
-
self.a8 = addri & 0xffff
|
65
|
+
8.times do |i|
|
66
|
+
self.send(:"a#{i + 1}=", addri >> (16 * (7 - i)) & 0xffff)
|
67
|
+
end
|
73
68
|
self
|
74
69
|
end
|
75
|
-
# rubocop:enable Metrics/AbcSize
|
76
70
|
|
77
|
-
#
|
71
|
+
# Return IPv6 address in human readable form (colon-delimited hex string)
|
78
72
|
# @return [String]
|
79
73
|
def to_human
|
80
74
|
IPAddr.new(to_a.map { |a| a.to_i.to_s(16) }.join(':')).to_s
|
@@ -92,6 +86,9 @@ module PacketGen
|
|
92
86
|
self.a1 & 0xff00 == 0xff00
|
93
87
|
end
|
94
88
|
|
89
|
+
# Check equaliy to +other+.
|
90
|
+
# Equal if other has the same class, and all attributes are equal
|
91
|
+
# @return [Boolean]
|
95
92
|
def ==(other)
|
96
93
|
other.is_a?(self.class) &&
|
97
94
|
attributes.all? { |attr| self[attr].value == other[attr].value }
|
@@ -106,7 +103,11 @@ module PacketGen
|
|
106
103
|
# Push a IPv6 address to the array
|
107
104
|
# @param [String,Addr] addr
|
108
105
|
# @return [self]
|
109
|
-
#
|
106
|
+
# @example
|
107
|
+
# array = PacketGen::Header::IPv6::ArrayOfAddr.new
|
108
|
+
# # #<< uses #push internally
|
109
|
+
# array << '2001::1'
|
110
|
+
# array.push(PacketGen::Header::IPv6::Addr.new.from_human('1:2:3:abcd::1'))
|
110
111
|
def push(addr)
|
111
112
|
addr = Addr.new.from_human(addr) unless addr.is_a?(Addr)
|
112
113
|
super
|