Class: Xlat::Protocols::Ip
- Inherits:
-
Object
- Object
- Xlat::Protocols::Ip
- Defined in:
- lib/xlat/protocols/ip.rb,
lib/xlat/protocols/ip/ipv4.rb,
lib/xlat/protocols/ip/ipv6.rb
Defined Under Namespace
Instance Attribute Summary collapse
-
#bytes ⇒ Object
IO::Buffer containing L3 header.
-
#bytes_length ⇒ Object
Length of L3 datagram within ‘bytes`.
-
#bytes_offset ⇒ Object
Offset where L3 header begins within ‘bytes`.
-
#cs_delta ⇒ Object
Accumulated changes to be applied to L4 checksum.
-
#l4 ⇒ Object
Returns the value of attribute l4.
-
#l4_bytes ⇒ Object
IO::Buffer containing L4 packet.
-
#l4_bytes_length ⇒ Object
Length of L4 datagram within ‘l4_bytes`, possibly truncated.
-
#l4_bytes_offset ⇒ Object
Offset where L4 header begins within ‘l4_bytes`.
-
#l4_length ⇒ Object
Length of L4 packet, as specified in L3 header.
-
#l4_start ⇒ Object
L3 header length.
-
#proto ⇒ Object
L4 protocol ID.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Class Method Summary collapse
- .addr_to_s(addr) ⇒ Object
- .checksum(bytes, from = nil, len = nil) ⇒ Object
-
.checksum_adjust(checksum, delta) ⇒ Object
this function assumes 0 <= sum <= 65534.
- .checksum_list(buffers) ⇒ Object
- .parse(bytes) ⇒ Object
Instance Method Summary collapse
- #apply_changes ⇒ Object
-
#convert_version!(version, new_header_bytes, cs_delta) ⇒ Ip
Convert this packet into different IP version using the supplied buffer as header.
-
#initialize(icmp_payload: false) ⇒ Ip
constructor
A new instance of Ip.
- #parse(bytes:, bytes_offset: 0, bytes_length: bytes.size - bytes_offset, l4_bytes: nil, l4_bytes_offset: nil) ⇒ Object
-
#set_l4_region(start, length) ⇒ true, false
Whether the given range is valid.
- #tuple ⇒ Object
Constructor Details
Instance Attribute Details
#bytes ⇒ Object
IO::Buffer containing L3 header
29 30 31 |
# File 'lib/xlat/protocols/ip.rb', line 29 def bytes @bytes end |
#bytes_length ⇒ Object
Length of L3 datagram within ‘bytes`
31 32 33 |
# File 'lib/xlat/protocols/ip.rb', line 31 def bytes_length @bytes_length end |
#bytes_offset ⇒ Object
Offset where L3 header begins within ‘bytes`
30 31 32 |
# File 'lib/xlat/protocols/ip.rb', line 30 def bytes_offset @bytes_offset end |
#cs_delta ⇒ Object
Accumulated changes to be applied to L4 checksum
39 40 41 |
# File 'lib/xlat/protocols/ip.rb', line 39 def cs_delta @cs_delta end |
#l4 ⇒ Object
Returns the value of attribute l4.
35 36 37 |
# File 'lib/xlat/protocols/ip.rb', line 35 def l4 @l4 end |
#l4_bytes ⇒ Object
IO::Buffer containing L4 packet
36 37 38 |
# File 'lib/xlat/protocols/ip.rb', line 36 def l4_bytes @l4_bytes end |
#l4_bytes_length ⇒ Object
Length of L4 datagram within ‘l4_bytes`, possibly truncated
38 39 40 |
# File 'lib/xlat/protocols/ip.rb', line 38 def l4_bytes_length @l4_bytes_length end |
#l4_bytes_offset ⇒ Object
Offset where L4 header begins within ‘l4_bytes`
37 38 39 |
# File 'lib/xlat/protocols/ip.rb', line 37 def l4_bytes_offset @l4_bytes_offset end |
#l4_length ⇒ Object
Length of L4 packet, as specified in L3 header
34 35 36 |
# File 'lib/xlat/protocols/ip.rb', line 34 def l4_length @l4_length end |
#l4_start ⇒ Object
L3 header length
33 34 35 |
# File 'lib/xlat/protocols/ip.rb', line 33 def l4_start @l4_start end |
#proto ⇒ Object
L4 protocol ID
32 33 34 |
# File 'lib/xlat/protocols/ip.rb', line 32 def proto @proto end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
41 42 43 |
# File 'lib/xlat/protocols/ip.rb', line 41 def version @version end |
Class Method Details
.addr_to_s(addr) ⇒ Object
190 191 192 193 194 195 196 197 198 199 |
# File 'lib/xlat/protocols/ip.rb', line 190 def self.addr_to_s(addr) case addr.length when 4 addr.unpack('C4').join('.') when 16 addr.unpack('n8').map { |f| format '%x', f }.join(':').gsub(/(:0)+(?=:)/, ':') else raise "unexpected address length of #{addr.length}" end end |
.checksum(bytes, from = nil, len = nil) ⇒ Object
150 151 152 153 154 155 156 157 158 159 |
# File 'lib/xlat/protocols/ip.rb', line 150 def self.checksum(bytes, from = nil, len = nil) from = 0 if from.nil? len = bytes.size - from if len.nil? to = from + len - 1 sum = Common.sum16be(bytes.slice(from, len)) sum += bytes.get_value(:U8, to) * 256 if len.odd? sum = (sum & 0xffff) + (sum >> 16) while sum > 65535 ~sum & 0xffff end |
.checksum_adjust(checksum, delta) ⇒ Object
this function assumes 0 <= sum <= 65534
182 183 184 185 186 187 188 |
# File 'lib/xlat/protocols/ip.rb', line 182 def self.checksum_adjust(checksum, delta) delta %= 65535 mod65535 = 65534 - checksum mod65535 = (mod65535 + delta) % 65535 65534 - mod65535 end |
.checksum_list(buffers) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/xlat/protocols/ip.rb', line 161 def self.checksum_list(buffers) sum = 0 offset = 0 buffers.each do |buf| if offset.odd? sum += buf.get_value(:U8, 0) buf = buf.slice(1) offset += 1 end sum += Common.sum16be(buf) len = buf.size if len.odd? sum += buf.get_value(:U8, len - 1) << 8 end offset += len end sum = (sum & 0xffff) + (sum >> 16) while sum > 65535 ~sum & 0xffff end |
.parse(bytes) ⇒ Object
49 50 51 |
# File 'lib/xlat/protocols/ip.rb', line 49 def self.parse(bytes) new.parse(bytes:) end |
Instance Method Details
#apply_changes ⇒ Object
143 144 145 146 147 148 |
# File 'lib/xlat/protocols/ip.rb', line 143 def apply_changes cs_delta = @cs_delta @version.apply(@bytes, @bytes_offset, cs_delta, @icmp_payload) @l4&.apply(cs_delta) @cs_delta = 0 end |
#convert_version!(version, new_header_bytes, cs_delta) ⇒ Ip
Convert this packet into different IP version using the supplied buffer as header.
129 130 131 132 133 134 135 136 137 |
# File 'lib/xlat/protocols/ip.rb', line 129 def convert_version!(version, new_header_bytes, cs_delta) @bytes = new_header_bytes @bytes_offset = 0 @bytes_length = new_header_bytes.size @version = version @l4_start = new_header_bytes.size @cs_delta += cs_delta self end |
#parse(bytes:, bytes_offset: 0, bytes_length: bytes.size - bytes_offset, l4_bytes: nil, l4_bytes_offset: nil) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/xlat/protocols/ip.rb', line 53 def parse(bytes:, bytes_offset: 0, bytes_length: bytes.size - bytes_offset, l4_bytes: nil, l4_bytes_offset: nil) @bytes = bytes @bytes_offset = bytes_offset @bytes_length = bytes_length @proto = nil @version = nil @l4_start = nil @l4_length = nil @l4 = nil @l4_bytes = l4_bytes @l4_bytes_offset = l4_bytes_offset @l4_bytes_length = nil @cs_delta = 0 # mimimum size for IPv4 return nil if bytes_length < 20 b0 = bytes.get_value(:U8, bytes_offset) case b0 >> 4 when 4 @version = Ipv4 when 6 @version = Ipv6 else return nil end return nil unless @version.parse(self, b0) case @proto when Protocols::Udp::PROTOCOL_ID @l4 = @_udp.parse when Protocols::Tcp::PROTOCOL_ID @l4 = @_tcp.parse when @version.icmp_protocol_id @l4 = Protocols::Icmp.parse(self) end self end |
#set_l4_region(start, length) ⇒ true, false
Returns Whether the given range is valid.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/xlat/protocols/ip.rb', line 97 def set_l4_region(start, length) @l4_start = start @l4_length = length unless @l4_bytes @l4_bytes = @bytes @l4_bytes_offset = @bytes_offset + start @l4_bytes_length = @bytes_length - start end if @l4_bytes_length < length if @icmp_payload # allow truncation in ICMP payload length = @l4_bytes_length return false if length < 0 else return false end end @l4_bytes_length = length true end |
#tuple ⇒ Object
139 140 141 |
# File 'lib/xlat/protocols/ip.rb', line 139 def tuple @version.tuple(@bytes, @bytes_offset) end |