ethernet.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // Copyright 2012 Google, Inc. All rights reserved.
  2. // Copyright 2009-2011 Andreas Krennmair. All rights reserved.
  3. //
  4. // Use of this source code is governed by a BSD-style license
  5. // that can be found in the LICENSE file in the root of the source
  6. // tree.
  7. package layers
  8. import (
  9. "encoding/binary"
  10. "errors"
  11. "fmt"
  12. "github.com/google/gopacket"
  13. "net"
  14. )
  15. // EthernetBroadcast is the broadcast MAC address used by Ethernet.
  16. var EthernetBroadcast = net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
  17. // Ethernet is the layer for Ethernet frame headers.
  18. type Ethernet struct {
  19. BaseLayer
  20. SrcMAC, DstMAC net.HardwareAddr
  21. EthernetType EthernetType
  22. // Length is only set if a length field exists within this header. Ethernet
  23. // headers follow two different standards, one that uses an EthernetType, the
  24. // other which defines a length the follows with a LLC header (802.3). If the
  25. // former is the case, we set EthernetType and Length stays 0. In the latter
  26. // case, we set Length and EthernetType = EthernetTypeLLC.
  27. Length uint16
  28. }
  29. // LayerType returns LayerTypeEthernet
  30. func (e *Ethernet) LayerType() gopacket.LayerType { return LayerTypeEthernet }
  31. func (e *Ethernet) LinkFlow() gopacket.Flow {
  32. return gopacket.NewFlow(EndpointMAC, e.SrcMAC, e.DstMAC)
  33. }
  34. func (eth *Ethernet) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  35. if len(data) < 14 {
  36. return errors.New("Ethernet packet too small")
  37. }
  38. eth.DstMAC = net.HardwareAddr(data[0:6])
  39. eth.SrcMAC = net.HardwareAddr(data[6:12])
  40. eth.EthernetType = EthernetType(binary.BigEndian.Uint16(data[12:14]))
  41. eth.BaseLayer = BaseLayer{data[:14], data[14:]}
  42. eth.Length = 0
  43. if eth.EthernetType < 0x0600 {
  44. eth.Length = uint16(eth.EthernetType)
  45. eth.EthernetType = EthernetTypeLLC
  46. if cmp := len(eth.Payload) - int(eth.Length); cmp < 0 {
  47. df.SetTruncated()
  48. } else if cmp > 0 {
  49. // Strip off bytes at the end, since we have too many bytes
  50. eth.Payload = eth.Payload[:len(eth.Payload)-cmp]
  51. }
  52. // fmt.Println(eth)
  53. }
  54. return nil
  55. }
  56. // SerializeTo writes the serialized form of this layer into the
  57. // SerializationBuffer, implementing gopacket.SerializableLayer.
  58. // See the docs for gopacket.SerializableLayer for more info.
  59. func (eth *Ethernet) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  60. if len(eth.DstMAC) != 6 {
  61. return fmt.Errorf("invalid dst MAC: %v", eth.DstMAC)
  62. }
  63. if len(eth.SrcMAC) != 6 {
  64. return fmt.Errorf("invalid src MAC: %v", eth.SrcMAC)
  65. }
  66. payload := b.Bytes()
  67. bytes, err := b.PrependBytes(14)
  68. if err != nil {
  69. return err
  70. }
  71. copy(bytes, eth.DstMAC)
  72. copy(bytes[6:], eth.SrcMAC)
  73. if eth.Length != 0 || eth.EthernetType == EthernetTypeLLC {
  74. if opts.FixLengths {
  75. eth.Length = uint16(len(payload))
  76. }
  77. if eth.EthernetType != EthernetTypeLLC {
  78. return fmt.Errorf("ethernet type %v not compatible with length value %v", eth.EthernetType, eth.Length)
  79. } else if eth.Length > 0x0600 {
  80. return fmt.Errorf("invalid ethernet length %v", eth.Length)
  81. }
  82. binary.BigEndian.PutUint16(bytes[12:], eth.Length)
  83. } else {
  84. binary.BigEndian.PutUint16(bytes[12:], uint16(eth.EthernetType))
  85. }
  86. length := len(b.Bytes())
  87. if length < 60 {
  88. // Pad out to 60 bytes.
  89. padding, err := b.AppendBytes(60 - length)
  90. if err != nil {
  91. return err
  92. }
  93. copy(padding, lotsOfZeros[:])
  94. }
  95. return nil
  96. }
  97. func (eth *Ethernet) CanDecode() gopacket.LayerClass {
  98. return LayerTypeEthernet
  99. }
  100. func (eth *Ethernet) NextLayerType() gopacket.LayerType {
  101. return eth.EthernetType.LayerType()
  102. }
  103. func decodeEthernet(data []byte, p gopacket.PacketBuilder) error {
  104. eth := &Ethernet{}
  105. err := eth.DecodeFromBytes(data, p)
  106. if err != nil {
  107. return err
  108. }
  109. p.AddLayer(eth)
  110. p.SetLinkLayer(eth)
  111. return p.NextDecoder(eth.EthernetType)
  112. }