diff --git a/src/network/room.cpp b/src/network/room.cpp
index 3502264e1..3caa3aeae 100644
--- a/src/network/room.cpp
+++ b/src/network/room.cpp
@@ -98,6 +98,12 @@ public:
      * The first 3 bytes are the NintendoOUI 0x00, 0x1F, 0x32
      */
     MacAddress GenerateMacAddress();
+
+    /**
+     * Broadcasts this packet to all members except the sender.
+     * @param event The ENet event containing the data
+     */
+    void HandleWifiPacket(const ENetEvent* event);
 };
 
 // RoomImpl
@@ -111,7 +117,10 @@ void Room::RoomImpl::ServerLoop() {
                 case IdJoinRequest:
                     HandleJoinRequest(&event);
                     break;
-                    // TODO(B3N30): Handle the other message types
+                // TODO(B3N30): Handle the other message types
+                case IdWifiPacket:
+                    HandleWifiPacket(&event);
+                    break;
                 }
                 enet_packet_destroy(event.packet);
                 break;
@@ -247,6 +256,14 @@ MacAddress Room::RoomImpl::GenerateMacAddress() {
     return result_mac;
 }
 
+void Room::RoomImpl::HandleWifiPacket(const ENetEvent* event) {
+    for (auto it = members.begin(); it != members.end(); ++it) {
+        if (it->peer != event->peer)
+            enet_peer_send(it->peer, 0, event->packet);
+    }
+    enet_host_flush(server);
+}
+
 // Room
 Room::Room() : room_impl{std::make_unique<RoomImpl>()} {}
 
diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp
index 09573ee43..f919e4de0 100644
--- a/src/network/room_member.cpp
+++ b/src/network/room_member.cpp
@@ -62,6 +62,12 @@ public:
      * @param event The ENet event that was received.
      */
     void HandleRoomInformationPacket(const ENetEvent* event);
+
+    /**
+     * Extracts a WifiPacket from a received ENet packet.
+     * @param event The  ENet event that was received.
+     */
+    void HandleWifiPackets(const ENetEvent* event);
 };
 
 // RoomMemberImpl
@@ -174,6 +180,34 @@ void RoomMember::RoomMemberImpl::HandleJoinPacket(const ENetEvent* event) {
     // TODO(B3N30): Invoke callbacks
 }
 
+void RoomMember::RoomMemberImpl::HandleWifiPackets(const ENetEvent* event) {
+    WifiPacket wifi_packet{};
+    Packet packet;
+    packet.Append(event->packet->data, event->packet->dataLength);
+
+    // Ignore the first byte, which is the message id.
+    packet.IgnoreBytes(sizeof(MessageID));
+
+    // Parse the WifiPacket from the BitStream
+    uint8_t frame_type;
+    packet >> frame_type;
+    WifiPacket::PacketType type = static_cast<WifiPacket::PacketType>(frame_type);
+
+    wifi_packet.type = type;
+    packet >> wifi_packet.channel;
+    packet >> wifi_packet.transmitter_address;
+    packet >> wifi_packet.destination_address;
+
+    uint32_t data_length;
+    packet >> data_length;
+
+    std::vector<uint8_t> data(data_length);
+    packet >> data;
+
+    wifi_packet.data = std::move(data);
+    // TODO(B3N30): Invoke callbacks
+}
+
 // RoomMember
 RoomMember::RoomMember() : room_member_impl{std::make_unique<RoomMemberImpl>()} {
     room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0);
@@ -227,6 +261,18 @@ bool RoomMember::IsConnected() const {
     return room_member_impl->IsConnected();
 }
 
+void RoomMember::SendWifiPacket(const WifiPacket& wifi_packet) {
+    Packet packet;
+    packet << static_cast<MessageID>(IdWifiPacket);
+    packet << static_cast<uint8_t>(wifi_packet.type);
+    packet << wifi_packet.channel;
+    packet << wifi_packet.transmitter_address;
+    packet << wifi_packet.destination_address;
+    packet << static_cast<uint32_t>(wifi_packet.data.size());
+    packet << wifi_packet.data;
+    room_member_impl->Send(packet);
+}
+
 void RoomMember::Leave() {
     ASSERT_MSG(room_member_impl->receive_thread != nullptr, "Must be in a room to leave it.");
     {
diff --git a/src/network/room_member.h b/src/network/room_member.h
index f8bdbaea8..d23f5d4b6 100644
--- a/src/network/room_member.h
+++ b/src/network/room_member.h
@@ -12,6 +12,18 @@
 
 namespace Network {
 
+/// Information about the received WiFi packets.
+/// Acts as our own 802.11 header.
+struct WifiPacket {
+    enum class PacketType { Beacon, Data, Management };
+    PacketType type;           ///< The type of 802.11 frame, Beacon / Data.
+    std::vector<uint8_t> data; ///< Raw 802.11 frame data, starting at the management frame header
+                               /// for management frames.
+    MacAddress transmitter_address; ///< Mac address of the transmitter.
+    MacAddress destination_address; ///< Mac address of the receiver.
+    uint8_t channel;                ///< WiFi channel where this frame was transmitted.
+};
+
 /**
  * This is what a client [person joining a server] would use.
  * It also has to be used if you host a game yourself (You'd create both, a Room and a
@@ -69,6 +81,12 @@ public:
     void Join(const std::string& nickname, const char* server_addr = "127.0.0.1",
               const u16 serverPort = DefaultRoomPort, const u16 clientPort = 0);
 
+    /**
+     * Sends a WiFi packet to the room.
+     * @param packet The WiFi packet to send.
+     */
+    void SendWifiPacket(const WifiPacket& packet);
+
     /**
      * Leaves the current room.
      */