123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- package layers
- import (
- "encoding/binary"
- "errors"
- "fmt"
- "math"
- "net"
- "time"
- "github.com/google/gopacket"
- )
- type MLDv1Message struct {
- BaseLayer
-
- MaximumResponseDelay time.Duration
-
-
-
- MulticastAddress net.IP
- }
- func (m *MLDv1Message) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
- if len(data) < 20 {
- df.SetTruncated()
- return errors.New("ICMP layer less than 20 bytes for Multicast Listener Query Message V1")
- }
- m.MaximumResponseDelay = time.Duration(binary.BigEndian.Uint16(data[0:2])) * time.Millisecond
-
- m.MulticastAddress = data[4:20]
- return nil
- }
- func (*MLDv1Message) NextLayerType() gopacket.LayerType {
- return gopacket.LayerTypeZero
- }
- func (m *MLDv1Message) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
- buf, err := b.PrependBytes(20)
- if err != nil {
- return err
- }
- if m.MaximumResponseDelay < 0 {
- return errors.New("maximum response delay must not be negative")
- }
- dms := m.MaximumResponseDelay / time.Millisecond
- if dms > math.MaxUint16 {
- return fmt.Errorf("maximum response delay %dms is more than the allowed 65535ms", dms)
- }
- binary.BigEndian.PutUint16(buf[0:2], uint16(dms))
- copy(buf[2:4], []byte{0x0, 0x0})
- ma16 := m.MulticastAddress.To16()
- if ma16 == nil {
- return fmt.Errorf("invalid multicast address '%s'", m.MulticastAddress)
- }
- copy(buf[4:20], ma16)
- return nil
- }
- func (m *MLDv1Message) String() string {
- return fmt.Sprintf(
- "Maximum Response Delay: %dms, Multicast Address: %s",
- m.MaximumResponseDelay/time.Millisecond,
- m.MulticastAddress)
- }
- type MLDv1MulticastListenerQueryMessage struct {
- MLDv1Message
- }
- func (m *MLDv1MulticastListenerQueryMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
- err := m.MLDv1Message.DecodeFromBytes(data, df)
- if err != nil {
- return err
- }
- if len(data) > 20 {
- m.Payload = data[20:]
- }
- return nil
- }
- func (*MLDv1MulticastListenerQueryMessage) LayerType() gopacket.LayerType {
- return LayerTypeMLDv1MulticastListenerQuery
- }
- func (*MLDv1MulticastListenerQueryMessage) CanDecode() gopacket.LayerClass {
- return LayerTypeMLDv1MulticastListenerQuery
- }
- func (m *MLDv1MulticastListenerQueryMessage) IsGeneralQuery() bool {
- return net.IPv6zero.Equal(m.MulticastAddress)
- }
- func (m *MLDv1MulticastListenerQueryMessage) IsSpecificQuery() bool {
- return !m.IsGeneralQuery()
- }
- type MLDv1MulticastListenerReportMessage struct {
- MLDv1Message
- }
- func (*MLDv1MulticastListenerReportMessage) LayerType() gopacket.LayerType {
- return LayerTypeMLDv1MulticastListenerReport
- }
- func (*MLDv1MulticastListenerReportMessage) CanDecode() gopacket.LayerClass {
- return LayerTypeMLDv1MulticastListenerReport
- }
- type MLDv1MulticastListenerDoneMessage struct {
- MLDv1Message
- }
- func (*MLDv1MulticastListenerDoneMessage) LayerType() gopacket.LayerType {
- return LayerTypeMLDv1MulticastListenerDone
- }
- func (*MLDv1MulticastListenerDoneMessage) CanDecode() gopacket.LayerClass {
- return LayerTypeMLDv1MulticastListenerDone
- }
- func decodeMLDv1MulticastListenerReport(data []byte, p gopacket.PacketBuilder) error {
- m := &MLDv1MulticastListenerReportMessage{}
- return decodingLayerDecoder(m, data, p)
- }
- func decodeMLDv1MulticastListenerQuery(data []byte, p gopacket.PacketBuilder) error {
- m := &MLDv1MulticastListenerQueryMessage{}
- return decodingLayerDecoder(m, data, p)
- }
- func decodeMLDv1MulticastListenerDone(data []byte, p gopacket.PacketBuilder) error {
- m := &MLDv1MulticastListenerDoneMessage{}
- return decodingLayerDecoder(m, data, p)
- }
|