github.com/gopacket/gopacket@v1.1.0/layers/vrrp.go (about)

     1  // Copyright 2016 Google, Inc. 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  	"net"
    13  
    14  	"github.com/gopacket/gopacket"
    15  )
    16  
    17  /*
    18  	This layer provides decoding for Virtual Router Redundancy Protocol (VRRP) v2.
    19  	https://tools.ietf.org/html/rfc3768#section-5
    20      0                   1                   2                   3
    21      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
    22     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    23     |Version| Type  | Virtual Rtr ID|   Priority    | Count IP Addrs|
    24     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    25     |   Auth Type   |   Adver Int   |          Checksum             |
    26     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    27     |                         IP Address (1)                        |
    28     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    29     |                            .                                  |
    30     |                            .                                  |
    31     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    32     |                         IP Address (n)                        |
    33     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    34     |                     Authentication Data (1)                   |
    35     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    36     |                     Authentication Data (2)                   |
    37     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    38  */
    39  
    40  type VRRPv2Type uint8
    41  type VRRPv2AuthType uint8
    42  
    43  const (
    44  	VRRPv2Advertisement VRRPv2Type = 0x01 // router advertisement
    45  )
    46  
    47  // String conversions for VRRP message types
    48  func (v VRRPv2Type) String() string {
    49  	switch v {
    50  	case VRRPv2Advertisement:
    51  		return "VRRPv2 Advertisement"
    52  	default:
    53  		return ""
    54  	}
    55  }
    56  
    57  const (
    58  	VRRPv2AuthNoAuth    VRRPv2AuthType = 0x00 // No Authentication
    59  	VRRPv2AuthReserved1 VRRPv2AuthType = 0x01 // Reserved field 1
    60  	VRRPv2AuthReserved2 VRRPv2AuthType = 0x02 // Reserved field 2
    61  )
    62  
    63  func (v VRRPv2AuthType) String() string {
    64  	switch v {
    65  	case VRRPv2AuthNoAuth:
    66  		return "No Authentication"
    67  	case VRRPv2AuthReserved1:
    68  		return "Reserved"
    69  	case VRRPv2AuthReserved2:
    70  		return "Reserved"
    71  	default:
    72  		return ""
    73  	}
    74  }
    75  
    76  // VRRPv2 represents an VRRP v2 message.
    77  type VRRPv2 struct {
    78  	BaseLayer
    79  	Version      uint8          // The version field specifies the VRRP protocol version of this packet (v2)
    80  	Type         VRRPv2Type     // The type field specifies the type of this VRRP packet.  The only type defined in v2 is ADVERTISEMENT
    81  	VirtualRtrID uint8          // identifies the virtual router this packet is reporting status for
    82  	Priority     uint8          // specifies the sending VRRP router's priority for the virtual router (100 = default)
    83  	CountIPAddr  uint8          // The number of IP addresses contained in this VRRP advertisement.
    84  	AuthType     VRRPv2AuthType // identifies the authentication method being utilized
    85  	AdverInt     uint8          // The Advertisement interval indicates the time interval (in seconds) between ADVERTISEMENTS.  The default is 1 second
    86  	Checksum     uint16         // used to detect data corruption in the VRRP message.
    87  	IPAddress    []net.IP       // one or more IP addresses associated with the virtual router. Specified in the CountIPAddr field.
    88  }
    89  
    90  // LayerType returns LayerTypeVRRP for VRRP v2 message.
    91  func (v *VRRPv2) LayerType() gopacket.LayerType { return LayerTypeVRRP }
    92  
    93  func (v *VRRPv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
    94  
    95  	v.BaseLayer = BaseLayer{Contents: data[:len(data)]}
    96  	v.Version = data[0] >> 4 // high nibble == VRRP version. We're expecting v2
    97  
    98  	v.Type = VRRPv2Type(data[0] & 0x0F) // low nibble == VRRP type. Expecting 1 (advertisement)
    99  	if v.Type != 1 {
   100  		// rfc3768: A packet with unknown type MUST be discarded.
   101  		return errors.New("Unrecognized VRRPv2 type field.")
   102  	}
   103  
   104  	v.VirtualRtrID = data[1]
   105  	v.Priority = data[2]
   106  
   107  	v.CountIPAddr = data[3]
   108  	if v.CountIPAddr < 1 {
   109  		return errors.New("VRRPv2 number of IP addresses is not valid.")
   110  	}
   111  
   112  	v.AuthType = VRRPv2AuthType(data[4])
   113  	v.AdverInt = uint8(data[5])
   114  	v.Checksum = binary.BigEndian.Uint16(data[6:8])
   115  
   116  	// populate the IPAddress field. The number of addresses is specified in the v.CountIPAddr field
   117  	// offset references the starting byte containing the list of ip addresses
   118  	offset := 8
   119  	for i := uint8(0); i < v.CountIPAddr; i++ {
   120  		v.IPAddress = append(v.IPAddress, data[offset:offset+4])
   121  		offset += 4
   122  	}
   123  
   124  	//	any trailing packets here may be authentication data and *should* be ignored in v2 as per RFC
   125  	//
   126  	//			5.3.10.  Authentication Data
   127  	//
   128  	//			The authentication string is currently only used to maintain
   129  	//			backwards compatibility with RFC 2338.  It SHOULD be set to zero on
   130  	//	   		transmission and ignored on reception.
   131  	return nil
   132  }
   133  
   134  // CanDecode specifies the layer type in which we are attempting to unwrap.
   135  func (v *VRRPv2) CanDecode() gopacket.LayerClass {
   136  	return LayerTypeVRRP
   137  }
   138  
   139  // NextLayerType specifies the next layer that should be decoded. VRRP does not contain any further payload, so we set to 0
   140  func (v *VRRPv2) NextLayerType() gopacket.LayerType {
   141  	return gopacket.LayerTypeZero
   142  }
   143  
   144  // The VRRP packet does not include payload data. Setting byte slice to nil
   145  func (v *VRRPv2) Payload() []byte {
   146  	return nil
   147  }
   148  
   149  // decodeVRRP will parse VRRP v2
   150  func decodeVRRP(data []byte, p gopacket.PacketBuilder) error {
   151  	if len(data) < 8 {
   152  		return errors.New("Not a valid VRRP packet. Packet length is too small.")
   153  	}
   154  	v := &VRRPv2{}
   155  	return decodingLayerDecoder(v, data, p)
   156  }