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