/lib/packetgen/header/mld.rb

https://github.com/sdaubert/packetgen · Ruby · 102 lines · 29 code · 6 blank · 67 comment · 0 complexity · 940d19e20359590c06fe4cab53b0bab0 MD5 · raw file

  1. # frozen_string_literal: true
  2. # This file is part of PacketGen
  3. # See https://github.com/sdaubert/packetgen for more informations
  4. # Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
  5. # This program is published under MIT license.
  6. module PacketGen
  7. module Header
  8. # This class supports MLDv1 (RFC 2710).
  9. #
  10. # From RFC 2710, a MLD header has the following format:
  11. # 0 1 2 3
  12. # 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
  13. # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  14. # | Maximum Response delay | Reserved |
  15. # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  16. # | |
  17. # + +
  18. # | |
  19. # + Multicast Address +
  20. # | |
  21. # + +
  22. # | |
  23. # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  24. #
  25. # A MLD header consists of:
  26. # * a {#max_resp_delay} field ({Types::Int16} type),
  27. # * a {#reserved} field ({Types::Int16} type),
  28. # * a {#mcast_addr} field ({Header::IPv6::Addr} type),
  29. # * and a {#body} (unused for MLDv1).
  30. #
  31. # == Create a MLD header
  32. # # standalone
  33. # mld = PacketGen::Header::MLD.new
  34. # # in a packet
  35. # pkt = PacketGen.gen('IPv6').add('ICMPv6').add('MLD')
  36. # # access to MLD header
  37. # pkt.mld # => PacketGen::Header::MLD
  38. #
  39. # == MLD attributes
  40. # pkt.icmpv6.type = 130 # ICMPv6 type 130 is MLD Multicast Listener Query
  41. # pkt.mld.max_resp_delay = 20
  42. # pkt.mld.group_addr = '::'
  43. # @author Sylvain Daubert
  44. # @since 2.4.0
  45. class MLD < Base
  46. # @!attribute max_resp_delay
  47. # 16-bit MLD Max Response Delay
  48. # @return [Integer]
  49. define_field :max_resp_delay, Types::Int16
  50. alias max_resp_code max_resp_delay
  51. alias max_resp_code= max_resp_delay=
  52. # @!attribute reserved
  53. # 16-bit Reserved field
  54. # @return [Integer]
  55. define_field :reserved, Types::Int16
  56. # @!attribute mcast_addr
  57. # IPv6 Multicast address
  58. # @return [IPv6::Addr]
  59. define_field :mcast_addr, IPv6::Addr, default: '::'
  60. # @!attribute body
  61. # @return [String,Base]
  62. define_field :body, Types::String
  63. # @api private
  64. # @note This method is used internally by PacketGen and should not be
  65. # directly called
  66. def added_to_packet(packet)
  67. mld_idx = packet.headers.size
  68. packet.instance_eval "def mldize() @headers[#{mld_idx}].mldize; end" # def mldize() @headers[3].mldize; end
  69. end
  70. # Fixup IP header according to RFC 2710:
  71. # * set Hop limit to 1,
  72. # * add Router Alert option,
  73. # * recalculate checksum and length.
  74. # This method may be called as:
  75. # # first method
  76. # pkt.mld.mldize
  77. # # second method
  78. # pkt.mldize
  79. # @return [void]
  80. def mldize
  81. ipv6 = ip_header(self)
  82. ipv6.hop = 1
  83. ipv6.next = 0
  84. packet.insert(ipv6, 'IPv6::HopByHop', next: ICMPv6::IP_PROTOCOL)
  85. packet.ipv6_hopbyhop.options << { type: 'router_alert', value: [0].pack('n') }
  86. packet.calc
  87. end
  88. end
  89. end
  90. end
  91. # Add MLDv2::MLQ before MLD to priorize its decoding
  92. require_relative 'mldv2'
  93. PacketGen::Header.add_class PacketGen::Header::MLD
  94. PacketGen::Header::ICMPv6.bind PacketGen::Header::MLD, type: 130
  95. PacketGen::Header::ICMPv6.bind PacketGen::Header::MLD, type: 131
  96. PacketGen::Header::ICMPv6.bind PacketGen::Header::MLD, type: 132