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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -9
  3. data/lib/packetgen/capture.rb +3 -6
  4. data/lib/packetgen/config.rb +1 -1
  5. data/lib/packetgen/deprecation.rb +7 -1
  6. data/lib/packetgen/header/arp.rb +7 -8
  7. data/lib/packetgen/header/asn1_base.rb +3 -2
  8. data/lib/packetgen/header/base.rb +39 -27
  9. data/lib/packetgen/header/bootp.rb +15 -15
  10. data/lib/packetgen/header/dhcp/option.rb +9 -9
  11. data/lib/packetgen/header/dhcp/options.rb +3 -3
  12. data/lib/packetgen/header/dhcp.rb +7 -8
  13. data/lib/packetgen/header/dhcpv6/duid.rb +3 -5
  14. data/lib/packetgen/header/dhcpv6/option.rb +38 -16
  15. data/lib/packetgen/header/dhcpv6/options.rb +4 -4
  16. data/lib/packetgen/header/dhcpv6/relay.rb +2 -1
  17. data/lib/packetgen/header/dhcpv6.rb +14 -15
  18. data/lib/packetgen/header/dns/name.rb +10 -9
  19. data/lib/packetgen/header/dns/opt.rb +4 -1
  20. data/lib/packetgen/header/dns/option.rb +8 -8
  21. data/lib/packetgen/header/dns/qdsection.rb +3 -3
  22. data/lib/packetgen/header/dns/question.rb +2 -1
  23. data/lib/packetgen/header/dns/rr.rb +2 -4
  24. data/lib/packetgen/header/dns/rrsection.rb +3 -3
  25. data/lib/packetgen/header/dns.rb +77 -61
  26. data/lib/packetgen/header/dot11/control.rb +6 -6
  27. data/lib/packetgen/header/dot11/data.rb +12 -11
  28. data/lib/packetgen/header/dot11/element.rb +2 -2
  29. data/lib/packetgen/header/dot11/management.rb +19 -16
  30. data/lib/packetgen/header/dot11/sub_mngt.rb +23 -22
  31. data/lib/packetgen/header/dot11.rb +39 -39
  32. data/lib/packetgen/header/dot1q.rb +6 -5
  33. data/lib/packetgen/header/dot1x.rb +9 -9
  34. data/lib/packetgen/header/eap/fast.rb +4 -4
  35. data/lib/packetgen/header/eap/md5.rb +12 -4
  36. data/lib/packetgen/header/eap/tls.rb +10 -9
  37. data/lib/packetgen/header/eap/ttls.rb +14 -11
  38. data/lib/packetgen/header/eap.rb +59 -34
  39. data/lib/packetgen/header/eth.rb +27 -13
  40. data/lib/packetgen/header/gre.rb +27 -3
  41. data/lib/packetgen/header/http/headers.rb +7 -6
  42. data/lib/packetgen/header/http/request.rb +25 -17
  43. data/lib/packetgen/header/http/response.rb +23 -16
  44. data/lib/packetgen/header/http/verbs.rb +1 -1
  45. data/lib/packetgen/header/http.rb +1 -1
  46. data/lib/packetgen/header/icmp.rb +11 -11
  47. data/lib/packetgen/header/icmpv6.rb +11 -10
  48. data/lib/packetgen/header/igmp.rb +22 -11
  49. data/lib/packetgen/header/igmpv3/group_record.rb +8 -3
  50. data/lib/packetgen/header/igmpv3/mq.rb +2 -2
  51. data/lib/packetgen/header/igmpv3/mr.rb +2 -2
  52. data/lib/packetgen/header/igmpv3.rb +12 -11
  53. data/lib/packetgen/header/ip/addr.rb +7 -3
  54. data/lib/packetgen/header/ip/option.rb +19 -6
  55. data/lib/packetgen/header/ip/options.rb +1 -1
  56. data/lib/packetgen/header/ip.rb +53 -36
  57. data/lib/packetgen/header/ipv6/addr.rb +15 -14
  58. data/lib/packetgen/header/ipv6/extension.rb +10 -8
  59. data/lib/packetgen/header/ipv6/hop_by_hop.rb +27 -8
  60. data/lib/packetgen/header/ipv6.rb +32 -23
  61. data/lib/packetgen/header/llc.rb +21 -14
  62. data/lib/packetgen/header/mdns.rb +10 -3
  63. data/lib/packetgen/header/mld.rb +12 -10
  64. data/lib/packetgen/header/mldv2/mcast_address_record.rb +7 -2
  65. data/lib/packetgen/header/mldv2/mlq.rb +9 -9
  66. data/lib/packetgen/header/mldv2/mlr.rb +5 -5
  67. data/lib/packetgen/header/mldv2.rb +2 -2
  68. data/lib/packetgen/header/ospfv2/db_description.rb +11 -11
  69. data/lib/packetgen/header/ospfv2/hello.rb +12 -11
  70. data/lib/packetgen/header/ospfv2/ls_ack.rb +6 -7
  71. data/lib/packetgen/header/ospfv2/ls_request.rb +8 -7
  72. data/lib/packetgen/header/ospfv2/ls_update.rb +8 -8
  73. data/lib/packetgen/header/ospfv2/lsa.rb +34 -11
  74. data/lib/packetgen/header/ospfv2/lsa_header.rb +4 -3
  75. data/lib/packetgen/header/ospfv2.rb +32 -27
  76. data/lib/packetgen/header/ospfv3/db_description.rb +13 -14
  77. data/lib/packetgen/header/ospfv3/hello.rb +11 -10
  78. data/lib/packetgen/header/ospfv3/ipv6_prefix.rb +7 -3
  79. data/lib/packetgen/header/ospfv3/ls_ack.rb +6 -7
  80. data/lib/packetgen/header/ospfv3/ls_request.rb +11 -11
  81. data/lib/packetgen/header/ospfv3/ls_update.rb +8 -8
  82. data/lib/packetgen/header/ospfv3/lsa.rb +24 -10
  83. data/lib/packetgen/header/ospfv3/lsa_header.rb +4 -3
  84. data/lib/packetgen/header/ospfv3.rb +39 -35
  85. data/lib/packetgen/header/sctp/chunk.rb +39 -18
  86. data/lib/packetgen/header/sctp/error.rb +170 -198
  87. data/lib/packetgen/header/sctp/padded32.rb +4 -4
  88. data/lib/packetgen/header/sctp/parameter.rb +86 -133
  89. data/lib/packetgen/header/sctp.rb +15 -4
  90. data/lib/packetgen/header/snmp.rb +111 -10
  91. data/lib/packetgen/header/tcp/option.rb +8 -1
  92. data/lib/packetgen/header/tcp/options.rb +12 -4
  93. data/lib/packetgen/header/tcp.rb +34 -27
  94. data/lib/packetgen/header/tftp.rb +17 -11
  95. data/lib/packetgen/header/udp.rb +16 -14
  96. data/lib/packetgen/header.rb +20 -14
  97. data/lib/packetgen/headerable.rb +10 -4
  98. data/lib/packetgen/inject.rb +1 -1
  99. data/lib/packetgen/inspect.rb +3 -8
  100. data/lib/packetgen/packet.rb +95 -37
  101. data/lib/packetgen/pcap.rb +1 -1
  102. data/lib/packetgen/pcapng/block.rb +3 -2
  103. data/lib/packetgen/pcapng/epb.rb +1 -1
  104. data/lib/packetgen/pcapng/file.rb +42 -15
  105. data/lib/packetgen/pcapng/idb.rb +3 -2
  106. data/lib/packetgen/pcapng/shb.rb +3 -2
  107. data/lib/packetgen/pcapng/spb.rb +2 -2
  108. data/lib/packetgen/pcapng/unknown_block.rb +1 -1
  109. data/lib/packetgen/pcapng.rb +3 -1
  110. data/lib/packetgen/pcaprub_wrapper.rb +1 -1
  111. data/lib/packetgen/proto.rb +5 -1
  112. data/lib/packetgen/unknown_packet.rb +4 -4
  113. data/lib/packetgen/utils/arp_spoofer.rb +1 -1
  114. data/lib/packetgen/utils.rb +4 -5
  115. data/lib/packetgen/version.rb +2 -2
  116. data/lib/packetgen.rb +9 -3
  117. 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://github.com/lemontree55/packetgen for more informations
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 +type+ field ({BinStruct::Int8} type),
19
- # * a +code+ field ({BinStruct::Int8} type),
20
- # * a +checksum+ field ({BinStruct::Int16} type),
21
- # * and a +body+.
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
- # == Create a ICMPv6 header
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 # => PacketGen::Header::ICMPv6
29
+ # pkt.icmpv6.class # => PacketGen::Header::ICMPv6
30
30
  #
31
- # == ICMPv6 attributes
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.read 'this is a 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://github.com/lemontree55/packetgen for more informations
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 ({BinStruct::Int8Enum} type),
24
- # * a {#max_resp_time} field ({BinStruct::Int8} type),
25
- # * a {#checksum} field ({BinStruct::Int16} type),
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
- # == Create a IGMP header
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 # => PacketGen::Header::IGMP
38
+ # pkt.igmp.class # => PacketGen::Header::IGMP
36
39
  #
37
- # == IGMP attributes
38
- # icmp.type = 'MembershipQuery' # or 0x11
39
- # icmp.max_resp_time = 20
40
- # icmp.checksum = 0x248a
41
- # icmp.group_addr = '224.0.0.1'
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://github.com/lemontree55/packetgen for more informations
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.containing information
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 {#to_human}.
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://github.com/lemontree55/packetgen for more informations
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 in
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://github.com/lemontree55/packetgen for more informations
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
- # @return [Integer]
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://github.com/lemontree55/packetgen for more informations
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 ({BinStruct::Int8Enum} type),
22
- # * a {#max_resp_time} field ({BinStruct::Int8} type),
23
- # * a {#checksum} field ({BinStruct::Int16} type),
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.are handled by
26
+ # A IGMPv3 header may have additionnal fields. These attributes are handled by
27
27
  # additional headers (see {IGMPv3::MQ}).
28
28
  #
29
- # == Create a IGMPv3 header
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.igmp # => PacketGen::Header::IGMPv3
35
+ # pkt.igmpv3.class # => PacketGen::Header::IGMPv3
36
36
  #
37
- # == IGMPv3 attributes
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.than with IGMPv2. To
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.than with IGMPv2. To
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://github.com/lemontree55/packetgen for more informations
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 seconf byte
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 an integer
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://github.com/lemontree55/packetgen for more informations
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
- # @return [Integer]
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
- # @return [Integer]
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
- # @return [String]
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
- # @return [Hash]
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 pointer on next address
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://github.com/lemontree55/packetgen for more informations
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.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # This file is part of PacketGen
4
- # See https://github.com/lemontree55/packetgen for more informations
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 {BinStruct::Int8} type) composed 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}, {BinStruct::Int8} type),
34
- # * a total length ({#length}, {BinStruct::Int16} type),
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}, +Addr+ type),
43
+ # * a destination IP address ({#dst}, {Addr} type),
44
44
  # * an optional {#options} field ({Options} type),
45
- # * and a {#body} ({BinStruct::String} type).
45
+ # * and a {#body} (+BinStruct::String+ type).
46
46
  #
47
- # == Create a IP header
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
- # == IP attributes
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? # => Boolean
70
- # ip.flag_df? # => Boolean
71
- # ip.flag_mf? # => Boolean
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] # => PacketGen::Header::IP::Addr
79
+ # ip[:src].class # => PacketGen::Header::IP::Addr
79
80
  # ip.dst = '127.0.0.2'
80
- # ip.body.read 'this is a body'
81
+ # ip.body = 'this is a body'
81
82
  #
82
- # == Add IP options
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
- # @return [Integer] 4-bit version attribute
104
+ # 4-bit version attribute
105
+ # @return [Integer]
105
106
  # @!attribute ihl
106
- # @return [Integer] 4-bit IP header length attribute
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
- # @return [Integer] 16-bit IP total length
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
- # @return [Integer] 16-bit frag word
122
+ # 16-bit frag word
123
+ # @return [Integer]
119
124
  # @!attribute flag_rsv
120
- # @return [Boolean] reserved bit from flags
125
+ # reserved bit from flags
126
+ # @return [Boolean]
121
127
  # @!attribute flag_df
122
- # @return [Boolean] Don't Fragment flag
128
+ # Don't Fragment flag
129
+ # @return [Boolean]
123
130
  # @!attribute flag_mf
124
- # @return [Boolean] More Fragment flags
131
+ # More Fragment flags
132
+ # @return [Boolean]
125
133
  # @!attribute fragment_offset
126
- # @return [Integer] 13-bit fragment offset
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
- # @return [Integer] 8-bit Time To Live self[attr]
138
+ # 8-bit Time To Live
139
+ # @return [Integer]
130
140
  define_attr :ttl, BinStruct::Int8, default: 64
131
141
  # @!attribute protocol
132
- # @return [Integer] 8-bit upper protocol self[attr]
142
+ # 8-bit upper protocol
143
+ # @return [Integer]
133
144
  define_attr :protocol, BinStruct::Int8
134
145
  # @!attribute checksum
135
- # @return [Integer] 16-bit IP header checksum
146
+ # 16-bit IP header checksum
147
+ # @return [Integer]
136
148
  define_attr :checksum, BinStruct::Int16, default: 0
137
149
  # @!attribute src
138
- # @return [Addr] source IP address
150
+ # source IP address
151
+ # @return [Addr]
139
152
  define_attr :src, Addr, default: '127.0.0.1'
140
153
  # @!attribute dst
141
- # @return [Addr] destination IP address
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 [BinStruct::String]
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
- # @return [BinStruct::String,Header::Base]
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 [Base#parse?]
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://github.com/lemontree55/packetgen for more informations
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
- self.a1 = addri >> 112
66
- self.a2 = addri >> 96 & 0xffff
67
- self.a3 = addri >> 80 & 0xffff
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
- # Addr6 in human readable form (colon-delimited hex string)
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
- # array << '2001:1234::125'
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