github.com/vpnishe/netstack@v1.10.6/tcpip/header/eth.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package header 16 17 import ( 18 "encoding/binary" 19 20 "github.com/vpnishe/netstack/tcpip" 21 ) 22 23 const ( 24 dstMAC = 0 25 srcMAC = 6 26 ethType = 12 27 ) 28 29 // EthernetFields contains the fields of an ethernet frame header. It is used to 30 // describe the fields of a frame that needs to be encoded. 31 type EthernetFields struct { 32 // SrcAddr is the "MAC source" field of an ethernet frame header. 33 SrcAddr tcpip.LinkAddress 34 35 // DstAddr is the "MAC destination" field of an ethernet frame header. 36 DstAddr tcpip.LinkAddress 37 38 // Type is the "ethertype" field of an ethernet frame header. 39 Type tcpip.NetworkProtocolNumber 40 } 41 42 // Ethernet represents an ethernet frame header stored in a byte array. 43 type Ethernet []byte 44 45 const ( 46 // EthernetMinimumSize is the minimum size of a valid ethernet frame. 47 EthernetMinimumSize = 14 48 49 // EthernetAddressSize is the size, in bytes, of an ethernet address. 50 EthernetAddressSize = 6 51 52 // unspecifiedEthernetAddress is the unspecified ethernet address 53 // (all bits set to 0). 54 unspecifiedEthernetAddress = tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00") 55 56 // unicastMulticastFlagMask is the mask of the least significant bit in 57 // the first octet (in network byte order) of an ethernet address that 58 // determines whether the ethernet address is a unicast or multicast. If 59 // the masked bit is a 1, then the address is a multicast, unicast 60 // otherwise. 61 // 62 // See the IEEE Std 802-2001 document for more details. Specifically, 63 // section 9.2.1 of http://ieee802.org/secmail/pdfocSP2xXA6d.pdf: 64 // "A 48-bit universal address consists of two parts. The first 24 bits 65 // correspond to the OUI as assigned by the IEEE, expect that the 66 // assignee may set the LSB of the first octet to 1 for group addresses 67 // or set it to 0 for individual addresses." 68 unicastMulticastFlagMask = 1 69 70 // unicastMulticastFlagByteIdx is the byte that holds the 71 // unicast/multicast flag. See unicastMulticastFlagMask. 72 unicastMulticastFlagByteIdx = 0 73 ) 74 75 const ( 76 // EthernetProtocolAll is a catch-all for all protocols carried inside 77 // an ethernet frame. It is mainly used to create packet sockets that 78 // capture all traffic. 79 EthernetProtocolAll tcpip.NetworkProtocolNumber = 0x0003 80 81 // EthernetProtocolPUP is the PARC Universial Packet protocol ethertype. 82 EthernetProtocolPUP tcpip.NetworkProtocolNumber = 0x0200 83 ) 84 85 // Ethertypes holds the protocol numbers describing the payload of an ethernet 86 // frame. These types aren't necessarily supported by netstack, but can be used 87 // to catch all traffic of a type via packet endpoints. 88 var Ethertypes = []tcpip.NetworkProtocolNumber{ 89 EthernetProtocolAll, 90 EthernetProtocolPUP, 91 } 92 93 // SourceAddress returns the "MAC source" field of the ethernet frame header. 94 func (b Ethernet) SourceAddress() tcpip.LinkAddress { 95 return tcpip.LinkAddress(b[srcMAC:][:EthernetAddressSize]) 96 } 97 98 // DestinationAddress returns the "MAC destination" field of the ethernet frame 99 // header. 100 func (b Ethernet) DestinationAddress() tcpip.LinkAddress { 101 return tcpip.LinkAddress(b[dstMAC:][:EthernetAddressSize]) 102 } 103 104 // Type returns the "ethertype" field of the ethernet frame header. 105 func (b Ethernet) Type() tcpip.NetworkProtocolNumber { 106 return tcpip.NetworkProtocolNumber(binary.BigEndian.Uint16(b[ethType:])) 107 } 108 109 // Encode encodes all the fields of the ethernet frame header. 110 func (b Ethernet) Encode(e *EthernetFields) { 111 binary.BigEndian.PutUint16(b[ethType:], uint16(e.Type)) 112 copy(b[srcMAC:][:EthernetAddressSize], e.SrcAddr) 113 copy(b[dstMAC:][:EthernetAddressSize], e.DstAddr) 114 } 115 116 // IsValidUnicastEthernetAddress returns true if addr is a valid unicast 117 // ethernet address. 118 func IsValidUnicastEthernetAddress(addr tcpip.LinkAddress) bool { 119 // Must be of the right length. 120 if len(addr) != EthernetAddressSize { 121 return false 122 } 123 124 // Must not be unspecified. 125 if addr == unspecifiedEthernetAddress { 126 return false 127 } 128 129 // Must not be a multicast. 130 if addr[unicastMulticastFlagByteIdx]&unicastMulticastFlagMask != 0 { 131 return false 132 } 133 134 // addr is a valid unicast ethernet address. 135 return true 136 }