diff --git a/BAN/include/BAN/IPv4.h b/BAN/include/BAN/IPv4.h index b72949d64a..325f0c4775 100644 --- a/BAN/include/BAN/IPv4.h +++ b/BAN/include/BAN/IPv4.h @@ -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()(ipv4.as_u32()); + return hash()(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); } } diff --git a/kernel/kernel/Networking/NetworkSocket.cpp b/kernel/kernel/Networking/NetworkSocket.cpp index e39b530ed7..5c5618bd7b 100644 --- a/kernel/kernel/Networking/NetworkSocket.cpp +++ b/kernel/kernel/Networking/NetworkSocket.cpp @@ -39,7 +39,8 @@ namespace Kernel if (address_len != sizeof(sockaddr_in)) return BAN::Error::from_errno(EINVAL); auto* addr_in = reinterpret_cast(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 NetworkSocket::sendto_impl(const sys_sendto_t* arguments) @@ -58,7 +59,7 @@ namespace Kernel auto* destination = reinterpret_cast(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(&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(&ifreq->ifr_ifru.ifru_addr); + if (ifru_addr.sin_family != AF_INET) return BAN::Error::from_errno(EADDRNOTAVAIL); - BAN::IPv4Address ipv4_address { *reinterpret_cast(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(&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(&ifreq->ifr_ifru.ifru_netmask); + if (ifru_netmask.sin_family != AF_INET) return BAN::Error::from_errno(EADDRNOTAVAIL); - BAN::IPv4Address netmask { *reinterpret_cast(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; } diff --git a/kernel/kernel/Networking/UDPSocket.cpp b/kernel/kernel/Networking/UDPSocket.cpp index 3fea655a70..35d19f8214 100644 --- a/kernel/kernel/Networking/UDPSocket.cpp +++ b/kernel/kernel/Networking/UDPSocket.cpp @@ -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; diff --git a/userspace/dhcp-client/main.cpp b/userspace/dhcp-client/main.cpp index b781c3d6d4..88a522029e 100644 --- a/userspace/dhcp-client/main.cpp +++ b/userspace/dhcp-client/main.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -24,10 +25,10 @@ struct DHCPPacket BAN::NetworkEndian xid { 0x3903F326 }; BAN::NetworkEndian secs { 0x0000 }; BAN::NetworkEndian flags { 0x0000 }; - BAN::NetworkEndian ciaddr { 0 }; - BAN::NetworkEndian yiaddr { 0 }; - BAN::NetworkEndian siaddr { 0 }; - BAN::NetworkEndian 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(&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(&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*>(options); + uint32_t raw = *reinterpret_cast(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*>(options + i); + uint32_t raw = *reinterpret_cast(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*>(options + i); + uint32_t raw = *reinterpret_cast(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*>(options); + uint32_t raw = *reinterpret_cast(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) {