// IPV6
auto ipv6 = getIPv6Header();
std::swap(ipv6.daddr, ipv6.saddr);
- assert(ipv6.nexthdr == IPPROTO_UDP);
+ ipv6.nexthdr = IPPROTO_UDP;
auto udp = getUDPHeader();
std::swap(udp.dest, udp.source);
/* needed to get the correct checksum */
setIPv6Header(ipv6);
setUDPHeader(udp);
- udp.check = tcp_udp_v6_checksum(&ipv6);
+ // do not bother setting the UDP checksum: 0 is a valid value and most AF_XDP
+ // implementations do the same
+ // udp.check = tcp_udp_v6_checksum(&ipv6);
rewriteIpv6Header(&ipv6, getFrameLen());
setIPv6Header(ipv6);
setUDPHeader(udp);
}
- else {
+ else if (ethHeader.h_proto == htons(ETH_P_IP)) {
// IPV4
auto ipv4 = getIPv4Header();
std::swap(ipv4.daddr, ipv4.saddr);
- assert(ipv4.protocol == IPPROTO_UDP);
+ ipv4.protocol = IPPROTO_UDP;
auto udp = getUDPHeader();
std::swap(udp.dest, udp.source);
/* needed to get the correct checksum */
setIPv4Header(ipv4);
setUDPHeader(udp);
- udp.check = tcp_udp_v4_checksum(&ipv4);
+ // do not bother setting the UDP checksum: 0 is a valid value and most AF_XDP
+ // implementations do the same
+ // udp.check = tcp_udp_v4_checksum(&ipv4);
rewriteIpv4Header(&ipv4, getFrameLen());
setIPv4Header(ipv4);
setUDPHeader(udp);
auto ipHeader = getIPv4Header();
ipHeader.daddr = to.sin4.sin_addr.s_addr;
ipHeader.saddr = from.sin4.sin_addr.s_addr;
+ ipHeader.protocol = IPPROTO_UDP;
auto udpHeader = getUDPHeader();
- ipHeader.protocol = IPPROTO_UDP;
udpHeader.source = from.sin4.sin_port;
udpHeader.dest = to.sin4.sin_port;
udpHeader.len = htons(getDataSize() + sizeof(udpHeader));
/* needed to get the correct checksum */
setIPv4Header(ipHeader);
setUDPHeader(udpHeader);
+ // do not bother setting the UDP checksum: 0 is a valid value and most AF_XDP
+ // implementations do the same
// udpHeader.check = tcp_udp_v4_checksum(&ipHeader);
rewriteIpv4Header(&ipHeader, getFrameLen());
setIPv4Header(ipHeader);
auto ipHeader = getIPv6Header();
memcpy(&ipHeader.daddr, &to.sin6.sin6_addr, sizeof(ipHeader.daddr));
memcpy(&ipHeader.saddr, &from.sin6.sin6_addr, sizeof(ipHeader.saddr));
+ ipHeader.nexthdr = IPPROTO_UDP;
auto udpHeader = getUDPHeader();
- ipHeader.nexthdr = IPPROTO_UDP;
udpHeader.source = from.sin6.sin6_port;
udpHeader.dest = to.sin6.sin6_port;
udpHeader.len = htons(getDataSize() + sizeof(udpHeader));
/* needed to get the correct checksum */
setIPv6Header(ipHeader);
setUDPHeader(udpHeader);
- udpHeader.check = tcp_udp_v6_checksum(&ipHeader);
+ // do not bother setting the UDP checksum: 0 is a valid value and most AF_XDP
+ // implementations do the same
+ // udpHeader.check = tcp_udp_v6_checksum(&ipHeader);
setIPv6Header(ipHeader);
setUDPHeader(udpHeader);
}
public:
enum Flags : uint32_t
{
+ /* whether the payload has been modified */
UPDATE = 1 << 0,
DELAY = 1 << 1,
+ /* whether the headers have already been updated */
REWRITE = 1 << 2
};
void setIPv6Header(const ipv6hdr& ipv6Header) noexcept;
[[nodiscard]] udphdr getUDPHeader() const noexcept;
void setUDPHeader(const udphdr& udpHeader) noexcept;
+ /* exchange the source and destination addresses (ethernet and IP) */
void changeDirectAndUpdateChecksum() noexcept;
constexpr static uint8_t DefaultTTL = 64;
[[nodiscard]] PacketBuffer cloneHeaderToPacketBuffer() const;
void setAddr(const ComboAddress& from_, MACAddr fromMAC, const ComboAddress& to_, MACAddr toMAC) noexcept;
bool setPayload(const PacketBuffer& buf);
+ /* rewrite the headers, usually after setAddr() and setPayload() have been called */
void rewrite() noexcept;
void setHeader(PacketBuffer& buf);
XskPacket(uint8_t* frame, size_t dataSize, size_t frameSize);
void addDelay(int relativeMilliseconds) noexcept;
+ /* if the payload have been updated, and the headers have not been rewritten, exchange the source
+ and destination addresses (ethernet and IP) and rewrite the headers */
void updatePacket() noexcept;
// parse IP and UDP payloads
bool parse(bool fromSetHeader);