Sha256: bb4f220fd2b1b95c3cf14f9b63bdacfad3b733d78f21e9e7e894dc8d0299468d

Contents?: true

Size: 1.94 KB

Versions: 6

Compression:

Stored size: 1.94 KB

Contents

require 'pio/payload'
require 'pio/type/ip_address'

module Pio
  # IP Version 4 Header Format
  module IPv4Header
    # Internet protocol numbers for ipv4_header.ip_protocol
    module ProtocolNumber
      ICMP = 1
      UDP = 17
    end

    include Payload

    # rubocop:disable MethodLength
    # rubocop:disable AbcSize
    # This method smells of :reek:TooManyStatements
    def self.included(klass)
      def klass.ipv4_header(options = {})
        bit4 :ip_version, value: 0x4
        bit4 :ip_header_length, initial_value: 0x5
        uint8 :ip_type_of_service, initial_value: 0
        uint16be :ip_total_length, initial_value: :calculate_ip_length
        uint16be :ip_identifier, initial_value: 0
        bit3 :ip_flag, initial_value: 0
        bit13 :ip_fragment, initial_value: 0
        uint8 :ip_ttl, initial_value: 128
        uint8 :ip_protocol, initial_value: options[:ip_protocol] || 0
        uint16be :ip_header_checksum, initial_value: :calculate_ip_checksum
        ip_address :ip_source_address
        ip_address :ip_destination_address
        string :ip_option, read_length: :ip_option_length
      end
    end
    # rubocop:enable MethodLength
    # rubocop:enable AbcSize

    private

    def calculate_ip_length
      ip_header_length * 4 + ip_payload_binary.length
    end

    # rubocop:disable AbcSize
    def calculate_ip_checksum
      sum = [ip_version << 12 | ip_header_length << 8 | ip_type_of_service,
             ip_total_length,
             ip_identifier,
             ip_flag << 13 | ip_fragment,
             ip_ttl << 8 | ip_protocol,
             ip_source_address >> 16,
             ip_source_address & 0xffff,
             ip_destination_address >> 16,
             ip_destination_address & 0xffff].reduce(:+)
      ~((sum & 0xffff) + (sum >> 16)) & 0xffff
    end
    # rubocop:enable AbcSize

    def ip_payload_binary
      binary_after(:ip_option)
    end

    def ip_option_length
      20 - ip_header_length * 4
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
pio-0.20.0 lib/pio/ipv4_header.rb
pio-0.19.0 lib/pio/ipv4_header.rb
pio-0.18.2 lib/pio/ipv4_header.rb
pio-0.18.1 lib/pio/ipv4_header.rb
pio-0.18.0 lib/pio/ipv4_header.rb
pio-0.17.0 lib/pio/ipv4_header.rb