Sha256: 3a7943f76ccdaa00b53bec97e726e498f2a2a07b675203447994420d88df5824

Contents?: true

Size: 1.91 KB

Versions: 3

Compression:

Stored size: 1.91 KB

Contents

# encoding: utf-8

require 'pio/type/ethernet_header'
require 'pio/type/ipv4_header'
require 'pio/type/udp_header'
require 'pio/dhcp/dhcp_field'
require 'pio/dhcp/field_util'
require 'pio/dhcp/csum_util'

module Pio
  class Dhcp
    # Dhcp frame parser.
    class Frame < BinData::Record
      extend Type::EthernetHeader
      extend Type::IPv4Header
      extend Type::UdpHeader
      include FieldUtil
      include CsumUtil

      ETHER_TYPE_IP = 0x0800
      IP_PROTOCOL_UDP = 17
      IP_HEADER_LENGTH = 20
      UDP_HEADER_LENGTH = 8
      DHCP_OPTION_FIELD_LENGTH = 60

      endian :big

      ethernet_header ether_type: ETHER_TYPE_IP
      ipv4_header ip_protocol: IP_PROTOCOL_UDP,
                  ip_header_checksum: -> { ip_sum },
                  ip_total_length: -> { ip_len }
      udp_header udp_length: -> { udp_len },
                 udp_checksum: -> { udp_sum }
      dhcp_field :dhcp

      def ip_sum
        ~((ip_csum & 0xffff) + (ip_csum >> 16)) & 0xffff
      end

      def udp_sum
        ~((udp_csum & 0xffff) + (udp_csum >> 16)) & 0xffff
      end

      def ip_len
        IP_HEADER_LENGTH + udp_len
      end

      def udp_len
        UDP_HEADER_LENGTH + dhcp_len
      end

      def to_binary
        to_binary_s + trail_data
      end

      private

      def dhcp_len
        dhcp.num_bytes + trail_data.bytesize
      end

      def dhcp_binary
        dhcp.to_binary_s
      end

      def should_padding?
        option_length < DHCP_OPTION_FIELD_LENGTH
      end

      def option_length
        dhcp.optional_tlvs.num_bytes + 1
      end

      def trail_data
        if should_padding?
          end_of_pdu + padding
        else
          end_of_pdu
        end
      end

      def end_of_pdu
        [0xff].pack('C*')
      end

      def padding
        [0x00].pack('C*') * padding_length
      end

      def padding_length
        DHCP_OPTION_FIELD_LENGTH - option_length
      end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
pio-0.8.1 lib/pio/dhcp/frame.rb
pio-0.8.0 lib/pio/dhcp/frame.rb
pio-0.7.0 lib/pio/dhcp/frame.rb