Kernel/BAN: Fix network strucute endianness
This commit is contained in:
parent
c35ed6570b
commit
b2291ce162
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue