Kernel/BAN: Fix network strucute endianness

This commit is contained in:
Bananymous 2024-02-05 17:35:54 +02:00
parent c35ed6570b
commit b2291ce162
4 changed files with 61 additions and 56 deletions

View File

@ -11,31 +11,32 @@ namespace BAN
{ {
constexpr IPv4Address(uint32_t u32_address) constexpr IPv4Address(uint32_t u32_address)
{ {
address[0] = u32_address >> 24; raw = u32_address;
address[1] = u32_address >> 16;
address[2] = u32_address >> 8;
address[3] = u32_address >> 0;
} }
constexpr uint32_t as_u32() const constexpr IPv4Address(uint8_t oct1, uint8_t oct2, uint8_t oct3, uint8_t oct4)
{ {
return octets[0] = oct1;
((uint32_t)address[0] << 24) | octets[1] = oct2;
((uint32_t)address[1] << 16) | octets[2] = oct3;
((uint32_t)address[2] << 8) | octets[3] = oct4;
((uint32_t)address[3] << 0);
} }
constexpr bool operator==(const IPv4Address& other) const constexpr bool operator==(const IPv4Address& other) const
{ {
return return raw == other.raw;
address[0] == other.address[0] &&
address[1] == other.address[1] &&
address[2] == other.address[2] &&
address[3] == other.address[3];
} }
uint8_t address[4]; constexpr IPv4Address mask(const IPv4Address& other) const
{
return IPv4Address(raw & other.raw);
}
union
{
uint8_t octets[4];
uint32_t raw;
} __attribute__((packed));
}; };
static_assert(sizeof(IPv4Address) == 4); static_assert(sizeof(IPv4Address) == 4);
@ -44,7 +45,7 @@ namespace BAN
{ {
constexpr hash_t operator()(IPv4Address ipv4) const constexpr hash_t operator()(IPv4Address ipv4) const
{ {
return hash<uint32_t>()(ipv4.as_u32()); return hash<uint32_t>()(ipv4.raw);
} }
}; };
@ -63,11 +64,11 @@ namespace BAN::Formatter
.upper = false, .upper = false,
}; };
print_argument(putc, ipv4.address[0], format); print_argument(putc, ipv4.octets[0], format);
for (size_t i = 1; i < 4; i++) for (size_t i = 1; i < 4; i++)
{ {
putc('.'); putc('.');
print_argument(putc, ipv4.address[i], format); print_argument(putc, ipv4.octets[i], format);
} }
} }

View File

@ -39,7 +39,8 @@ namespace Kernel
if (address_len != sizeof(sockaddr_in)) if (address_len != sizeof(sockaddr_in))
return BAN::Error::from_errno(EINVAL); return BAN::Error::from_errno(EINVAL);
auto* addr_in = reinterpret_cast<const sockaddr_in*>(address); auto* addr_in = reinterpret_cast<const sockaddr_in*>(address);
return NetworkManager::get().bind_socket(addr_in->sin_port, this); uint16_t dst_port = BAN::host_to_network_endian(addr_in->sin_port);
return NetworkManager::get().bind_socket(dst_port, this);
} }
BAN::ErrorOr<ssize_t> NetworkSocket::sendto_impl(const sys_sendto_t* arguments) BAN::ErrorOr<ssize_t> NetworkSocket::sendto_impl(const sys_sendto_t* arguments)
@ -58,7 +59,7 @@ namespace Kernel
auto* destination = reinterpret_cast<const sockaddr_in*>(arguments->dest_addr); auto* destination = reinterpret_cast<const sockaddr_in*>(arguments->dest_addr);
auto message = BAN::ConstByteSpan((const uint8_t*)arguments->message, arguments->length); auto message = BAN::ConstByteSpan((const uint8_t*)arguments->message, arguments->length);
uint16_t dst_port = destination->sin_port; uint16_t dst_port = BAN::host_to_network_endian(destination->sin_port);
if (dst_port == PORT_NONE) if (dst_port == PORT_NONE)
return BAN::Error::from_errno(EINVAL); return BAN::Error::from_errno(EINVAL);
@ -140,33 +141,33 @@ namespace Kernel
{ {
case SIOCGIFADDR: case SIOCGIFADDR:
{ {
auto ipv4_address = m_interface->get_ipv4_address(); auto& ifru_addr = *reinterpret_cast<sockaddr_in*>(&ifreq->ifr_ifru.ifru_addr);
ifreq->ifr_ifru.ifru_addr.sa_family = AF_INET; ifru_addr.sin_family = AF_INET;
memcpy(ifreq->ifr_ifru.ifru_addr.sa_data, &ipv4_address, sizeof(ipv4_address)); ifru_addr.sin_addr.s_addr = m_interface->get_ipv4_address().raw;
return 0; return 0;
} }
case SIOCSIFADDR: case SIOCSIFADDR:
{ {
if (ifreq->ifr_ifru.ifru_addr.sa_family != AF_INET) auto& ifru_addr = *reinterpret_cast<const sockaddr_in*>(&ifreq->ifr_ifru.ifru_addr);
if (ifru_addr.sin_family != AF_INET)
return BAN::Error::from_errno(EADDRNOTAVAIL); return BAN::Error::from_errno(EADDRNOTAVAIL);
BAN::IPv4Address ipv4_address { *reinterpret_cast<uint32_t*>(ifreq->ifr_ifru.ifru_addr.sa_data) }; m_interface->set_ipv4_address(BAN::IPv4Address { ifru_addr.sin_addr.s_addr });
m_interface->set_ipv4_address(ipv4_address);
dprintln("IPv4 address set to {}", m_interface->get_ipv4_address()); dprintln("IPv4 address set to {}", m_interface->get_ipv4_address());
return 0; return 0;
} }
case SIOCGIFNETMASK: case SIOCGIFNETMASK:
{ {
auto netmask_address = m_interface->get_netmask(); auto& ifru_netmask = *reinterpret_cast<sockaddr_in*>(&ifreq->ifr_ifru.ifru_netmask);
ifreq->ifr_ifru.ifru_netmask.sa_family = AF_INET; ifru_netmask.sin_family = AF_INET;
memcpy(ifreq->ifr_ifru.ifru_netmask.sa_data, &netmask_address, sizeof(netmask_address)); ifru_netmask.sin_addr.s_addr = m_interface->get_netmask().raw;
return 0; return 0;
} }
case SIOCSIFNETMASK: case SIOCSIFNETMASK:
{ {
if (ifreq->ifr_ifru.ifru_netmask.sa_family != AF_INET) auto& ifru_netmask = *reinterpret_cast<const sockaddr_in*>(&ifreq->ifr_ifru.ifru_netmask);
if (ifru_netmask.sin_family != AF_INET)
return BAN::Error::from_errno(EADDRNOTAVAIL); return BAN::Error::from_errno(EADDRNOTAVAIL);
BAN::IPv4Address netmask { *reinterpret_cast<uint32_t*>(ifreq->ifr_ifru.ifru_netmask.sa_data) }; m_interface->set_netmask(BAN::IPv4Address { ifru_netmask.sin_addr.s_addr });
m_interface->set_netmask(netmask);
dprintln("Netmask set to {}", m_interface->get_netmask()); dprintln("Netmask set to {}", m_interface->get_netmask());
return 0; return 0;
} }

View File

@ -91,8 +91,8 @@ namespace Kernel
if (sender_addr) if (sender_addr)
{ {
sender_addr->sin_family = AF_INET; sender_addr->sin_family = AF_INET;
sender_addr->sin_port = packet_info.sender_port; sender_addr->sin_port = BAN::NetworkEndian(packet_info.sender_port);
sender_addr->sin_addr.s_addr = packet_info.sender_addr.as_u32(); sender_addr->sin_addr.s_addr = packet_info.sender_addr.raw;
} }
return nread; return nread;

View File

@ -4,6 +4,7 @@
#include <BAN/MAC.h> #include <BAN/MAC.h>
#include <BAN/Vector.h> #include <BAN/Vector.h>
#include <arpa/inet.h>
#include <fcntl.h> #include <fcntl.h>
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -24,10 +25,10 @@ struct DHCPPacket
BAN::NetworkEndian<uint32_t> xid { 0x3903F326 }; BAN::NetworkEndian<uint32_t> xid { 0x3903F326 };
BAN::NetworkEndian<uint16_t> secs { 0x0000 }; BAN::NetworkEndian<uint16_t> secs { 0x0000 };
BAN::NetworkEndian<uint16_t> flags { 0x0000 }; BAN::NetworkEndian<uint16_t> flags { 0x0000 };
BAN::NetworkEndian<uint32_t> ciaddr { 0 }; BAN::IPv4Address ciaddr { 0 };
BAN::NetworkEndian<uint32_t> yiaddr { 0 }; BAN::IPv4Address yiaddr { 0 };
BAN::NetworkEndian<uint32_t> siaddr { 0 }; BAN::IPv4Address siaddr { 0 };
BAN::NetworkEndian<uint32_t> giaddr { 0 }; BAN::IPv4Address giaddr { 0 };
BAN::MACAddress chaddr; BAN::MACAddress chaddr;
uint8_t padding[10] {}; uint8_t padding[10] {};
uint8_t legacy[192] {}; uint8_t legacy[192] {};
@ -76,8 +77,9 @@ void update_ipv4_info(int socket, BAN::IPv4Address address, BAN::IPv4Address sub
{ {
{ {
ifreq ifreq; ifreq ifreq;
ifreq.ifr_ifru.ifru_addr.sa_family = AF_INET; auto& ifru_addr = *reinterpret_cast<sockaddr_in*>(&ifreq.ifr_ifru.ifru_addr);
*(uint32_t*)ifreq.ifr_ifru.ifru_addr.sa_data = address.as_u32(); ifru_addr.sin_family = AF_INET;
ifru_addr.sin_addr.s_addr = address.raw;
if (ioctl(socket, SIOCSIFADDR, &ifreq) == -1) if (ioctl(socket, SIOCSIFADDR, &ifreq) == -1)
{ {
perror("ioctl"); perror("ioctl");
@ -87,8 +89,9 @@ void update_ipv4_info(int socket, BAN::IPv4Address address, BAN::IPv4Address sub
{ {
ifreq ifreq; ifreq ifreq;
ifreq.ifr_ifru.ifru_netmask.sa_family = AF_INET; auto& ifru_netmask = *reinterpret_cast<sockaddr_in*>(&ifreq.ifr_ifru.ifru_netmask);
*(uint32_t*)ifreq.ifr_ifru.ifru_netmask.sa_data = subnet.as_u32(); ifru_netmask.sin_family = AF_INET;
ifru_netmask.sin_addr.s_addr = netmask.raw;
if (ioctl(socket, SIOCSIFNETMASK, &ifreq) == -1) if (ioctl(socket, SIOCSIFNETMASK, &ifreq) == -1)
{ {
perror("ioctl"); perror("ioctl");
@ -101,8 +104,8 @@ void send_dhcp_packet(int socket, const DHCPPacket& dhcp_packet, BAN::IPv4Addres
{ {
sockaddr_in server_addr; sockaddr_in server_addr;
server_addr.sin_family = AF_INET; server_addr.sin_family = AF_INET;
server_addr.sin_port = 67; server_addr.sin_port = htons(67);
server_addr.sin_addr.s_addr = server_ipv4.as_u32();; server_addr.sin_addr.s_addr = server_ipv4.raw;
if (sendto(socket, &dhcp_packet, sizeof(DHCPPacket), 0, (sockaddr*)&server_addr, sizeof(server_addr)) == -1) if (sendto(socket, &dhcp_packet, sizeof(DHCPPacket), 0, (sockaddr*)&server_addr, sizeof(server_addr)) == -1)
{ {
@ -138,7 +141,7 @@ void send_dhcp_request(int socket, BAN::MACAddress mac_address, BAN::IPv4Address
{ {
DHCPPacket dhcp_packet; DHCPPacket dhcp_packet;
dhcp_packet.op = 0x01; dhcp_packet.op = 0x01;
dhcp_packet.siaddr = server_ipv4.as_u32(); dhcp_packet.siaddr = server_ipv4.raw;
dhcp_packet.chaddr = mac_address; dhcp_packet.chaddr = mac_address;
size_t idx = 0; size_t idx = 0;
@ -149,10 +152,10 @@ void send_dhcp_request(int socket, BAN::MACAddress mac_address, BAN::IPv4Address
dhcp_packet.options[idx++] = RequestedIPv4Address; dhcp_packet.options[idx++] = RequestedIPv4Address;
dhcp_packet.options[idx++] = 0x04; dhcp_packet.options[idx++] = 0x04;
dhcp_packet.options[idx++] = offered_ipv4.address[0]; dhcp_packet.options[idx++] = offered_ipv4.octets[0];
dhcp_packet.options[idx++] = offered_ipv4.address[1]; dhcp_packet.options[idx++] = offered_ipv4.octets[1];
dhcp_packet.options[idx++] = offered_ipv4.address[2]; dhcp_packet.options[idx++] = offered_ipv4.octets[2];
dhcp_packet.options[idx++] = offered_ipv4.address[3]; dhcp_packet.options[idx++] = offered_ipv4.octets[3];
dhcp_packet.options[idx++] = 0xFF; dhcp_packet.options[idx++] = 0xFF;
@ -189,7 +192,7 @@ DHCPPacketInfo parse_dhcp_packet(const DHCPPacket& packet)
fprintf(stderr, "Subnet mask with invalid length %hhu\n", length); fprintf(stderr, "Subnet mask with invalid length %hhu\n", length);
break; break;
} }
uint32_t raw = *reinterpret_cast<const BAN::NetworkEndian<uint32_t>*>(options); uint32_t raw = *reinterpret_cast<const uint32_t*>(options);
packet_info.subnet = BAN::IPv4Address(raw); packet_info.subnet = BAN::IPv4Address(raw);
break; break;
} }
@ -202,7 +205,7 @@ DHCPPacketInfo parse_dhcp_packet(const DHCPPacket& packet)
} }
for (int i = 0; i < length; i += 4) for (int i = 0; i < length; i += 4)
{ {
uint32_t raw = *reinterpret_cast<const BAN::NetworkEndian<uint32_t>*>(options + i); uint32_t raw = *reinterpret_cast<const uint32_t*>(options + i);
MUST(packet_info.routers.emplace_back(raw)); MUST(packet_info.routers.emplace_back(raw));
} }
break; break;
@ -216,7 +219,7 @@ DHCPPacketInfo parse_dhcp_packet(const DHCPPacket& packet)
} }
for (int i = 0; i < length; i += 4) for (int i = 0; i < length; i += 4)
{ {
uint32_t raw = *reinterpret_cast<const BAN::NetworkEndian<uint32_t>*>(options + i); uint32_t raw = *reinterpret_cast<const uint32_t*>(options + i);
MUST(packet_info.dns.emplace_back(raw)); MUST(packet_info.dns.emplace_back(raw));
} }
break; break;
@ -245,7 +248,7 @@ DHCPPacketInfo parse_dhcp_packet(const DHCPPacket& packet)
fprintf(stderr, "Server identifier with invalid length %hhu\n", length); fprintf(stderr, "Server identifier with invalid length %hhu\n", length);
break; break;
} }
uint32_t raw = *reinterpret_cast<const BAN::NetworkEndian<uint32_t>*>(options); uint32_t raw = *reinterpret_cast<const uint32_t*>(options);
packet_info.server = BAN::IPv4Address(raw); packet_info.server = BAN::IPv4Address(raw);
break; break;
} }
@ -294,8 +297,8 @@ int main()
sockaddr_in client_addr; sockaddr_in client_addr;
client_addr.sin_family = AF_INET; client_addr.sin_family = AF_INET;
client_addr.sin_port = 68; client_addr.sin_port = htons(68);
client_addr.sin_addr.s_addr = 0x00000000; client_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(socket, (sockaddr*)&client_addr, sizeof(client_addr)) == -1) if (bind(socket, (sockaddr*)&client_addr, sizeof(client_addr)) == -1)
{ {