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)
{
address[0] = u32_address >> 24;
address[1] = u32_address >> 16;
address[2] = u32_address >> 8;
address[3] = u32_address >> 0;
raw = u32_address;
}
constexpr uint32_t as_u32() const
constexpr IPv4Address(uint8_t oct1, uint8_t oct2, uint8_t oct3, uint8_t oct4)
{
return
((uint32_t)address[0] << 24) |
((uint32_t)address[1] << 16) |
((uint32_t)address[2] << 8) |
((uint32_t)address[3] << 0);
octets[0] = oct1;
octets[1] = oct2;
octets[2] = oct3;
octets[3] = oct4;
}
constexpr bool operator==(const IPv4Address& other) const
{
return
address[0] == other.address[0] &&
address[1] == other.address[1] &&
address[2] == other.address[2] &&
address[3] == other.address[3];
return raw == other.raw;
}
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);
@ -44,7 +45,7 @@ namespace BAN
{
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,
};
print_argument(putc, ipv4.address[0], format);
print_argument(putc, ipv4.octets[0], format);
for (size_t i = 1; i < 4; i++)
{
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))
return BAN::Error::from_errno(EINVAL);
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)
@ -58,7 +59,7 @@ namespace Kernel
auto* destination = reinterpret_cast<const sockaddr_in*>(arguments->dest_addr);
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)
return BAN::Error::from_errno(EINVAL);
@ -140,33 +141,33 @@ namespace Kernel
{
case SIOCGIFADDR:
{
auto ipv4_address = m_interface->get_ipv4_address();
ifreq->ifr_ifru.ifru_addr.sa_family = AF_INET;
memcpy(ifreq->ifr_ifru.ifru_addr.sa_data, &ipv4_address, sizeof(ipv4_address));
auto& ifru_addr = *reinterpret_cast<sockaddr_in*>(&ifreq->ifr_ifru.ifru_addr);
ifru_addr.sin_family = AF_INET;
ifru_addr.sin_addr.s_addr = m_interface->get_ipv4_address().raw;
return 0;
}
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);
BAN::IPv4Address ipv4_address { *reinterpret_cast<uint32_t*>(ifreq->ifr_ifru.ifru_addr.sa_data) };
m_interface->set_ipv4_address(ipv4_address);
m_interface->set_ipv4_address(BAN::IPv4Address { ifru_addr.sin_addr.s_addr });
dprintln("IPv4 address set to {}", m_interface->get_ipv4_address());
return 0;
}
case SIOCGIFNETMASK:
{
auto netmask_address = m_interface->get_netmask();
ifreq->ifr_ifru.ifru_netmask.sa_family = AF_INET;
memcpy(ifreq->ifr_ifru.ifru_netmask.sa_data, &netmask_address, sizeof(netmask_address));
auto& ifru_netmask = *reinterpret_cast<sockaddr_in*>(&ifreq->ifr_ifru.ifru_netmask);
ifru_netmask.sin_family = AF_INET;
ifru_netmask.sin_addr.s_addr = m_interface->get_netmask().raw;
return 0;
}
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);
BAN::IPv4Address netmask { *reinterpret_cast<uint32_t*>(ifreq->ifr_ifru.ifru_netmask.sa_data) };
m_interface->set_netmask(netmask);
m_interface->set_netmask(BAN::IPv4Address { ifru_netmask.sin_addr.s_addr });
dprintln("Netmask set to {}", m_interface->get_netmask());
return 0;
}

View File

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

View File

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