mldv1.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright 2018 GoPacket Authors. All rights reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style license
  4. // that can be found in the LICENSE file in the root of the source
  5. // tree.
  6. package layers
  7. import (
  8. "encoding/binary"
  9. "errors"
  10. "fmt"
  11. "math"
  12. "net"
  13. "time"
  14. "github.com/google/gopacket"
  15. )
  16. // MLDv1Message represents the common structure of all MLDv1 messages
  17. type MLDv1Message struct {
  18. BaseLayer
  19. // 3.4. Maximum Response Delay
  20. MaximumResponseDelay time.Duration
  21. // 3.6. Multicast Address
  22. // Zero in general query
  23. // Specific IPv6 multicast address otherwise
  24. MulticastAddress net.IP
  25. }
  26. // DecodeFromBytes decodes the given bytes into this layer.
  27. func (m *MLDv1Message) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  28. if len(data) < 20 {
  29. df.SetTruncated()
  30. return errors.New("ICMP layer less than 20 bytes for Multicast Listener Query Message V1")
  31. }
  32. m.MaximumResponseDelay = time.Duration(binary.BigEndian.Uint16(data[0:2])) * time.Millisecond
  33. // data[2:4] is reserved and not used in mldv1
  34. m.MulticastAddress = data[4:20]
  35. return nil
  36. }
  37. // NextLayerType returns the layer type contained by this DecodingLayer.
  38. func (*MLDv1Message) NextLayerType() gopacket.LayerType {
  39. return gopacket.LayerTypeZero
  40. }
  41. // SerializeTo writes the serialized form of this layer into the
  42. // SerializationBuffer, implementing gopacket.SerializableLayer.
  43. // See the docs for gopacket.SerializableLayer for more info.
  44. func (m *MLDv1Message) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  45. buf, err := b.PrependBytes(20)
  46. if err != nil {
  47. return err
  48. }
  49. if m.MaximumResponseDelay < 0 {
  50. return errors.New("maximum response delay must not be negative")
  51. }
  52. dms := m.MaximumResponseDelay / time.Millisecond
  53. if dms > math.MaxUint16 {
  54. return fmt.Errorf("maximum response delay %dms is more than the allowed 65535ms", dms)
  55. }
  56. binary.BigEndian.PutUint16(buf[0:2], uint16(dms))
  57. copy(buf[2:4], []byte{0x0, 0x0})
  58. ma16 := m.MulticastAddress.To16()
  59. if ma16 == nil {
  60. return fmt.Errorf("invalid multicast address '%s'", m.MulticastAddress)
  61. }
  62. copy(buf[4:20], ma16)
  63. return nil
  64. }
  65. // Sums this layer up nicely formatted
  66. func (m *MLDv1Message) String() string {
  67. return fmt.Sprintf(
  68. "Maximum Response Delay: %dms, Multicast Address: %s",
  69. m.MaximumResponseDelay/time.Millisecond,
  70. m.MulticastAddress)
  71. }
  72. // MLDv1MulticastListenerQueryMessage are sent by the router to determine
  73. // whether there are multicast listeners on the link.
  74. // https://tools.ietf.org/html/rfc2710 Page 5
  75. type MLDv1MulticastListenerQueryMessage struct {
  76. MLDv1Message
  77. }
  78. // DecodeFromBytes decodes the given bytes into this layer.
  79. func (m *MLDv1MulticastListenerQueryMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  80. err := m.MLDv1Message.DecodeFromBytes(data, df)
  81. if err != nil {
  82. return err
  83. }
  84. if len(data) > 20 {
  85. m.Payload = data[20:]
  86. }
  87. return nil
  88. }
  89. // LayerType returns LayerTypeMLDv1MulticastListenerQuery.
  90. func (*MLDv1MulticastListenerQueryMessage) LayerType() gopacket.LayerType {
  91. return LayerTypeMLDv1MulticastListenerQuery
  92. }
  93. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  94. func (*MLDv1MulticastListenerQueryMessage) CanDecode() gopacket.LayerClass {
  95. return LayerTypeMLDv1MulticastListenerQuery
  96. }
  97. // IsGeneralQuery is true when this is a general query.
  98. // In a Query message, the Multicast Address field is set to zero when
  99. // sending a General Query.
  100. // https://tools.ietf.org/html/rfc2710#section-3.6
  101. func (m *MLDv1MulticastListenerQueryMessage) IsGeneralQuery() bool {
  102. return net.IPv6zero.Equal(m.MulticastAddress)
  103. }
  104. // IsSpecificQuery is true when this is not a general query.
  105. // In a Query message, the Multicast Address field is set to a specific
  106. // IPv6 multicast address when sending a Multicast-Address-Specific Query.
  107. // https://tools.ietf.org/html/rfc2710#section-3.6
  108. func (m *MLDv1MulticastListenerQueryMessage) IsSpecificQuery() bool {
  109. return !m.IsGeneralQuery()
  110. }
  111. // MLDv1MulticastListenerReportMessage is sent by a client listening on
  112. // a specific multicast address to indicate that it is (still) listening
  113. // on the specific multicast address.
  114. // https://tools.ietf.org/html/rfc2710 Page 6
  115. type MLDv1MulticastListenerReportMessage struct {
  116. MLDv1Message
  117. }
  118. // LayerType returns LayerTypeMLDv1MulticastListenerReport.
  119. func (*MLDv1MulticastListenerReportMessage) LayerType() gopacket.LayerType {
  120. return LayerTypeMLDv1MulticastListenerReport
  121. }
  122. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  123. func (*MLDv1MulticastListenerReportMessage) CanDecode() gopacket.LayerClass {
  124. return LayerTypeMLDv1MulticastListenerReport
  125. }
  126. // MLDv1MulticastListenerDoneMessage should be sent by a client when it ceases
  127. // to listen to a multicast address on an interface.
  128. // https://tools.ietf.org/html/rfc2710 Page 7
  129. type MLDv1MulticastListenerDoneMessage struct {
  130. MLDv1Message
  131. }
  132. // LayerType returns LayerTypeMLDv1MulticastListenerDone.
  133. func (*MLDv1MulticastListenerDoneMessage) LayerType() gopacket.LayerType {
  134. return LayerTypeMLDv1MulticastListenerDone
  135. }
  136. // CanDecode returns the set of layer types that this DecodingLayer can decode.
  137. func (*MLDv1MulticastListenerDoneMessage) CanDecode() gopacket.LayerClass {
  138. return LayerTypeMLDv1MulticastListenerDone
  139. }
  140. func decodeMLDv1MulticastListenerReport(data []byte, p gopacket.PacketBuilder) error {
  141. m := &MLDv1MulticastListenerReportMessage{}
  142. return decodingLayerDecoder(m, data, p)
  143. }
  144. func decodeMLDv1MulticastListenerQuery(data []byte, p gopacket.PacketBuilder) error {
  145. m := &MLDv1MulticastListenerQueryMessage{}
  146. return decodingLayerDecoder(m, data, p)
  147. }
  148. func decodeMLDv1MulticastListenerDone(data []byte, p gopacket.PacketBuilder) error {
  149. m := &MLDv1MulticastListenerDoneMessage{}
  150. return decodingLayerDecoder(m, data, p)
  151. }