mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Extract multicast IP to Ethernet address mapping
Test: header.TestEthernetAddressFromMulticastIPAddress PiperOrigin-RevId: 292604649
This commit is contained in:
committed by
gVisor bot
parent
bc3a24d627
commit
528dd1ec72
@@ -134,3 +134,44 @@ func IsValidUnicastEthernetAddress(addr tcpip.LinkAddress) bool {
|
||||
// addr is a valid unicast ethernet address.
|
||||
return true
|
||||
}
|
||||
|
||||
// EthernetAddressFromMulticastIPv4Address returns a multicast Ethernet address
|
||||
// for a multicast IPv4 address.
|
||||
//
|
||||
// addr MUST be a multicast IPv4 address.
|
||||
func EthernetAddressFromMulticastIPv4Address(addr tcpip.Address) tcpip.LinkAddress {
|
||||
var linkAddrBytes [EthernetAddressSize]byte
|
||||
// RFC 1112 Host Extensions for IP Multicasting
|
||||
//
|
||||
// 6.4. Extensions to an Ethernet Local Network Module:
|
||||
//
|
||||
// An IP host group address is mapped to an Ethernet multicast
|
||||
// address by placing the low-order 23-bits of the IP address
|
||||
// into the low-order 23 bits of the Ethernet multicast address
|
||||
// 01-00-5E-00-00-00 (hex).
|
||||
linkAddrBytes[0] = 0x1
|
||||
linkAddrBytes[2] = 0x5e
|
||||
linkAddrBytes[3] = addr[1] & 0x7F
|
||||
copy(linkAddrBytes[4:], addr[IPv4AddressSize-2:])
|
||||
return tcpip.LinkAddress(linkAddrBytes[:])
|
||||
}
|
||||
|
||||
// EthernetAddressFromMulticastIPv6Address returns a multicast Ethernet address
|
||||
// for a multicast IPv6 address.
|
||||
//
|
||||
// addr MUST be a multicast IPv6 address.
|
||||
func EthernetAddressFromMulticastIPv6Address(addr tcpip.Address) tcpip.LinkAddress {
|
||||
// RFC 2464 Transmission of IPv6 Packets over Ethernet Networks
|
||||
//
|
||||
// 7. Address Mapping -- Multicast
|
||||
//
|
||||
// An IPv6 packet with a multicast destination address DST,
|
||||
// consisting of the sixteen octets DST[1] through DST[16], is
|
||||
// transmitted to the Ethernet multicast address whose first
|
||||
// two octets are the value 3333 hexadecimal and whose last
|
||||
// four octets are the last four octets of DST.
|
||||
linkAddrBytes := []byte(addr[IPv6AddressSize-EthernetAddressSize:])
|
||||
linkAddrBytes[0] = 0x33
|
||||
linkAddrBytes[1] = 0x33
|
||||
return tcpip.LinkAddress(linkAddrBytes[:])
|
||||
}
|
||||
|
||||
@@ -66,3 +66,37 @@ func TestIsValidUnicastEthernetAddress(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEthernetAddressFromMulticastIPv4Address(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
addr tcpip.Address
|
||||
expectedLinkAddr tcpip.LinkAddress
|
||||
}{
|
||||
{
|
||||
name: "IPv4 Multicast without 24th bit set",
|
||||
addr: "\xe0\x7e\xdc\xba",
|
||||
expectedLinkAddr: "\x01\x00\x5e\x7e\xdc\xba",
|
||||
},
|
||||
{
|
||||
name: "IPv4 Multicast with 24th bit set",
|
||||
addr: "\xe0\xfe\xdc\xba",
|
||||
expectedLinkAddr: "\x01\x00\x5e\x7e\xdc\xba",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if got := EthernetAddressFromMulticastIPv4Address(test.addr); got != test.expectedLinkAddr {
|
||||
t.Fatalf("got EthernetAddressFromMulticastIPv4Address(%s) = %s, want = %s", got, test.expectedLinkAddr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEthernetAddressFromMulticastIPv6Address(t *testing.T) {
|
||||
addr := tcpip.Address("\xff\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x1a")
|
||||
if got, want := EthernetAddressFromMulticastIPv6Address(addr), tcpip.LinkAddress("\x33\x33\x0d\x0e\x0f\x1a"); got != want {
|
||||
t.Fatalf("got EthernetAddressFromMulticastIPv6Address(%s) = %s, want = %s", addr, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,24 +178,9 @@ func (*protocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bo
|
||||
return broadcastMAC, true
|
||||
}
|
||||
if header.IsV4MulticastAddress(addr) {
|
||||
// RFC 1112 Host Extensions for IP Multicasting
|
||||
//
|
||||
// 6.4. Extensions to an Ethernet Local Network Module:
|
||||
//
|
||||
// An IP host group address is mapped to an Ethernet multicast
|
||||
// address by placing the low-order 23-bits of the IP address
|
||||
// into the low-order 23 bits of the Ethernet multicast address
|
||||
// 01-00-5E-00-00-00 (hex).
|
||||
return tcpip.LinkAddress([]byte{
|
||||
0x01,
|
||||
0x00,
|
||||
0x5e,
|
||||
addr[header.IPv4AddressSize-3] & 0x7f,
|
||||
addr[header.IPv4AddressSize-2],
|
||||
addr[header.IPv4AddressSize-1],
|
||||
}), true
|
||||
return header.EthernetAddressFromMulticastIPv4Address(addr), true
|
||||
}
|
||||
return "", false
|
||||
return tcpip.LinkAddress([]byte(nil)), false
|
||||
}
|
||||
|
||||
// SetOption implements NetworkProtocol.
|
||||
|
||||
@@ -441,23 +441,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.
|
||||
// ResolveStaticAddress implements stack.LinkAddressResolver.
|
||||
func (*protocol) ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool) {
|
||||
if header.IsV6MulticastAddress(addr) {
|
||||
// RFC 2464 Transmission of IPv6 Packets over Ethernet Networks
|
||||
//
|
||||
// 7. Address Mapping -- Multicast
|
||||
//
|
||||
// An IPv6 packet with a multicast destination address DST,
|
||||
// consisting of the sixteen octets DST[1] through DST[16], is
|
||||
// transmitted to the Ethernet multicast address whose first
|
||||
// two octets are the value 3333 hexadecimal and whose last
|
||||
// four octets are the last four octets of DST.
|
||||
return tcpip.LinkAddress([]byte{
|
||||
0x33,
|
||||
0x33,
|
||||
addr[header.IPv6AddressSize-4],
|
||||
addr[header.IPv6AddressSize-3],
|
||||
addr[header.IPv6AddressSize-2],
|
||||
addr[header.IPv6AddressSize-1],
|
||||
}), true
|
||||
return header.EthernetAddressFromMulticastIPv6Address(addr), true
|
||||
}
|
||||
return "", false
|
||||
return tcpip.LinkAddress([]byte(nil)), false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user