# This file is part of PacketGen # See https://github.com/sdaubert/packetgen for more informations # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net> # This program is published under MIT license. # frozen_string_literal: true module PacketGen module Header # Dynamic Host Configuration Protocol for IPv6, {https://tools.ietf.org/html/rfc3315 # RFC 3315} # # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | msg-type | transaction-id | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | | # . options . # . (variable) . # | | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # A DHCPv6 header is made of: # * a {#msg_type} field ({Types::Int8Enum}), # * a {#transaction_id} field ({Types::Int24}), # * and an {#options} field ({DHCPv6::Options}). # # == Create a DHCPv6 header # # standalone # dhcpv6 = PacketGen::Header::DHCPv6.new(msg_type: 'SOLLICIT') # # in a packet # pkt = PacketGen.gen('IPv6').add('DHCPv6', msg_type: 'SOLLICIT') # # access to DHCPv6 header from packet # pkt.dhcpv6 #=> PacketGen::Header::DHCPv6 # # == Add options # DHCPv6 options are defined by subclasses of {DHCPv6::Option}. # # Options may be added by pushing a hash to {#options}: # dhcpv6 = PacketGen::Header::DHCPv6.new(msg_type: 'SOLLICIT') # dhcpv6.options << { type: 'Preference', value: 1 } # @author Sylvain Daubert class DHCPv6 < Base;end require_relative 'dhcpv6/duid' require_relative 'dhcpv6/option' require_relative 'dhcpv6/options' class DHCPv6 # DHCPv6 UDP client port UDP_CLIENT_PORT = 546 # DHCPv6 UDP client port UDP_SERVER_PORT = 547 # DHCPv6 message types MESSAGE_TYPES = { 'SOLLICIT' => 1, 'ADVERTISE' => 2, 'REQUEST' => 3, 'CONFIRM' => 4, 'RENEW' => 5, 'REBIND' => 6, 'REPLY' => 7, 'RELEASE' => 8, 'DECLINE' => 9, 'RECONFIGURE' => 10, 'INFORMATION-REQUEST' => 11 } # @!attribute msg_type # 8-bit message type # @return [Integer] define_field :msg_type, Types::Int8Enum, enum: MESSAGE_TYPES # @!attribute transaction_id # 24-bit transaction ID # @return [Integer] define_field :transaction_id, Types::Int24 # @!attribute options # @return [DHCPv6::Options] define_field :options, DHCPv6::Options # Populate object from string # @param [String] str # @return [DHCPv6,DHCPv6::Relay] def read(str) msg_type = Types::Int8.new.read(str) case msg_type when 12, 13 DHCPv6::Relay.new.read(str) else super end end # Get human readable message type # @return [String] def human_msg_type self[:msg_type].to_human end end UDP.bind_header DHCPv6, sport: DHCPv6::UDP_CLIENT_PORT, dport: DHCPv6::UDP_SERVER_PORT UDP.bind_header DHCPv6, sport: DHCPv6::UDP_SERVER_PORT, dport: DHCPv6::UDP_CLIENT_PORT end end require_relative 'dhcpv6/relay'