Skip to content

Commit 00c6fe0

Browse files
committed
Generate random MAC addresses for soft MACs
1 parent ae62f21 commit 00c6fe0

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

lib/firewall/firewall.cc

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <debug.hh>
88
//#include <fail-simulator-on-error.h>
99
#include <locks.hh>
10+
#include <platform-entropy.hh>
1011
#include <platform-ethernet.hh>
1112
#include <timeout.h>
1213
#include <timeout.hh>
@@ -86,6 +87,44 @@ namespace
8687
*/
8788
using MACAddress = std::array<uint8_t, 6>;
8889

90+
/**
91+
* Returns the MAC address for the network interface.
92+
*/
93+
MACAddress &mac_address()
94+
{
95+
static MACAddress macAddress = []() {
96+
auto &ethernet = lazy_network_interface();
97+
if constexpr (EthernetDevice::has_unique_mac_address())
98+
{
99+
return ethernet.mac_address_default();
100+
}
101+
else
102+
{
103+
std::array<uint8_t, 6> macAddress;
104+
EntropySource entropy;
105+
for (auto &byte : macAddress)
106+
{
107+
byte = entropy();
108+
}
109+
// Set the local bit (second bit transmitted from first byte) to
110+
// 1 to indicate a locally administered MAC
111+
macAddress[0] |= 0b01;
112+
// Make sure that the broadcast bit is 0
113+
macAddress[0] &= ~0b1;
114+
Debug::log(
115+
"MAC address: {}:{}:{}:{}:{}:{}",
116+
macAddress[0],
117+
macAddress[1],
118+
macAddress[2],
119+
macAddress[3],
120+
macAddress[4],
121+
macAddress[5]);
122+
return macAddress;
123+
}
124+
}();
125+
return macAddress;
126+
}
127+
89128
/**
90129
* Ethernet header.
91130
*/
@@ -499,6 +538,7 @@ namespace
499538

500539
bool packet_filter_ingress(const uint8_t *data, size_t length)
501540
{
541+
static constinit MACAddress broadcastMAC = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
502542
// Not a valid Ethernet frame (64 bytes including four-byte FCS, which
503543
// is stripped by this point).
504544
if (length < 60)
@@ -508,6 +548,19 @@ namespace
508548
}
509549
EthernetHeader *ethernetHeader =
510550
reinterpret_cast<EthernetHeader *>(const_cast<uint8_t *>(data));
551+
if ((ethernetHeader->destination != mac_address()) &&
552+
(ethernetHeader->destination != broadcastMAC))
553+
{
554+
Debug::log(
555+
"Dropping frame with destination MAC address {}:{}:{}:{}:{}:{}",
556+
ethernetHeader->destination[0],
557+
ethernetHeader->destination[1],
558+
ethernetHeader->destination[2],
559+
ethernetHeader->destination[3],
560+
ethernetHeader->destination[4],
561+
ethernetHeader->destination[5]);
562+
return false;
563+
}
511564
switch (ethernetHeader->etherType)
512565
{
513566
#ifdef ENABLE_IPV6
@@ -550,7 +603,9 @@ bool ethernet_driver_start()
550603
}
551604
Debug::log("Initialising network interface");
552605
auto &ethernet = lazy_network_interface();
553-
ethernet.mac_address_set();
606+
// If the device has a unique MAC address, use it. Otherwise, generate a
607+
// random locally administered one.
608+
ethernet.mac_address_set(mac_address());
554609
// Poke the barrier and make the driver thread start.
555610
barrier = 2;
556611
barrier.notify_one();
@@ -761,3 +816,11 @@ void firewall_remove_udpipv6_remote_endpoint(uint8_t *remoteAddress,
761816
}
762817

763818
#endif
819+
820+
uint8_t *firewall_mac_address_get()
821+
{
822+
CHERI::Capability ret{mac_address().data()};
823+
ret.permissions() &= {CHERI::Permission::Load, CHERI::Permission::Global};
824+
ret.bounds() = 6;
825+
return ret;
826+
}

lib/firewall/firewall.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,10 @@ void __cheri_compartment("Firewall")
151151
firewall_remove_udpipv6_remote_endpoint(uint8_t *remoteAddress,
152152
uint16_t localPort,
153153
uint16_t remotePort);
154+
155+
/**
156+
* Get the MAC address of the ethernet device.
157+
*
158+
* Returns a read-only capability to the MAC address.
159+
*/
160+
uint8_t *__cheri_compartment("Firewall") firewall_mac_address_get();

lib/tcpip/startup.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void __cheri_compartment("TCPIP") network_start()
9090
NetMask,
9191
GatewayAddress,
9292
DNSServerAddress,
93-
KunyanEthernet::mac_address_default().data());
93+
firewall_mac_address_get());
9494
// Enable DHCP
9595
endpointIPv4.bits.bWantDHCP = pdTRUE;
9696

0 commit comments

Comments
 (0)