ethernet.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. if eth.EthernetType < 0x0600 {
  43. eth.Length = uint16(eth.EthernetType)
  44. eth.EthernetType = EthernetTypeLLC
  45. if cmp := len(eth.Payload) - int(eth.Length); cmp < 0 {
  46. df.SetTruncated()
  47. } else if cmp > 0 {
  48. // Strip off bytes at the end, since we have too many bytes
  49. eth.Payload = eth.Payload[:len(eth.Payload)-cmp]
  50. }
  51. // fmt.Println(eth)
  52. }
  53. return nil
  54. }
  55. // SerializeTo writes the serialized form of this layer into the
  56. // SerializationBuffer, implementing gopacket.SerializableLayer.
  57. // See the docs for gopacket.SerializableLayer for more info.
  58. func (eth *Ethernet) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
  59. if len(eth.DstMAC) != 6 {
  60. return fmt.Errorf("invalid dst MAC: %v", eth.DstMAC)
  61. }
  62. if len(eth.SrcMAC) != 6 {
  63. return fmt.Errorf("invalid src MAC: %v", eth.SrcMAC)
  64. }
  65. payload := b.Bytes()
  66. bytes, err := b.PrependBytes(14)
  67. if err != nil {
  68. return err
  69. }
  70. copy(bytes, eth.DstMAC)
  71. copy(bytes[6:], eth.SrcMAC)
  72. if eth.Length != 0 || eth.EthernetType == EthernetTypeLLC {
  73. if opts.FixLengths {
  74. eth.Length = uint16(len(payload))
  75. }
  76. if eth.EthernetType != EthernetTypeLLC {
  77. return fmt.Errorf("ethernet type %v not compatible with length value %v", eth.EthernetType, eth.Length)
  78. } else if eth.Length > 0x0600 {
  79. return fmt.Errorf("invalid ethernet length %v", eth.Length)
  80. }
  81. binary.BigEndian.PutUint16(bytes[12:], eth.Length)
  82. } else {
  83. binary.BigEndian.PutUint16(bytes[12:], uint16(eth.EthernetType))
  84. }
  85. length := len(b.Bytes())
  86. if length < 60 {
  87. // Pad out to 60 bytes.
  88. padding, err := b.AppendBytes(60 - length)
  89. if err != nil {
  90. return err
  91. }
  92. copy(padding, lotsOfZeros[:])
  93. }
  94. return nil
  95. }
  96. func (eth *Ethernet) CanDecode() gopacket.LayerClass {
  97. return LayerTypeEthernet
  98. }
  99. func (eth *Ethernet) NextLayerType() gopacket.LayerType {
  100. return eth.EthernetType.LayerType()
  101. }
  102. func decodeEthernet(data []byte, p gopacket.PacketBuilder) error {
  103. eth := &Ethernet{}
  104. err := eth.DecodeFromBytes(data, p)
  105. if err != nil {
  106. return err
  107. }
  108. p.AddLayer(eth)
  109. p.SetLinkLayer(eth)
  110. return p.NextDecoder(eth.EthernetType)
  111. }