diff --git a/src/handle_packets.c b/src/handle_packets.c index 2606499..bddce3a 100644 --- a/src/handle_packets.c +++ b/src/handle_packets.c @@ -57,6 +57,10 @@ static inline struct SwiftNetPacketQueueNode* construct_node(const uint32_t data return node; } +static inline bool valid_ip_header(const struct SwiftNetNetworkData* restrict const network_data, const struct ReceiverPacketData* const restrict packet_data) { + return ip_checksum(packet_data->data + GET_PREPEND_SIZE(network_data)) == 0; +} + static inline void swiftnet_handle_packets( struct SwiftNetPacketQueue* const packet_queue, pthread_mutex_t* const process_packets_mtx, @@ -73,6 +77,10 @@ static inline void swiftnet_handle_packets( addr_type = GET_ADDR_TYPE(network_data); + if (!valid_ip_header(network_data, &packet_data)) { + goto exit; + } + if (unlikely(packet_data.data_len == 0)) { goto exit; } diff --git a/src/internal/internal.h b/src/internal/internal.h index d34efee..eefc060 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -230,6 +230,20 @@ CRC_TARGET MAYBE_UNUSED static uint32_t crc32(const uint8_t* const data, const u return ~crc; } + +static uint16_t ip_checksum(const uint8_t* header) { + uint32_t sum = 0; + + for(uint16_t i = 0; i < 20; i+=2) { + sum += (uint16_t)((header[0] << 8u) | header[1]); // big-endian 16-bit word + header += 2; + } + + while (sum >> 16) sum = (sum & 0xFFFF) + (sum >> 16); + + return (uint16_t)~sum; +} + enum StackCreatingState { STACK_CREATING_LOCKED = 0, STACK_CREATING_UNLOCKED = 1 diff --git a/src/internal/networking.h b/src/internal/networking.h index 3b92620..72a53f7 100644 --- a/src/internal/networking.h +++ b/src/internal/networking.h @@ -15,8 +15,10 @@ // Simple crc16 call with proper memory order #define HANDLE_CHECKSUM(buffer, size, network_data, packet_metadata) \ { \ + const uint16_t ip_sum = htons(ip_checksum(buffer + GET_PREPEND_SIZE(network_data))); \ const uint32_t checksum = crc32(buffer + GET_PREPEND_SIZE(network_data) + sizeof(struct ip), size + sizeof(struct SwiftNetChunkMetadata) + (packet_metadata ? sizeof(struct SwiftNetPacketMetadata) : 0)); \ memcpy(buffer + GET_PREPEND_SIZE(network_data) + sizeof(struct ip) + offsetof(struct SwiftNetChunkMetadata, checksum), &checksum, sizeof(checksum)); \ + memcpy(buffer + GET_PREPEND_SIZE(network_data) + offsetof(struct ip, ip_sum), &ip_sum, SIZEOF_FIELD(struct ip, ip_sum)); \ } #define GET_ADDR_TYPE(network_data) (network_data)->addr_type @@ -91,8 +93,10 @@ #define HANDLE_CHECKSUM(buffer, size, network_data, packet_metadata) \ { \ + const uint16_t ip_sum = htons(ip_checksum(buffer + GET_PREPEND_SIZE(network_data))); \ const uint32_t checksum = crc32(buffer + GET_PREPEND_SIZE(network_data) + sizeof(struct ip), size + sizeof(struct SwiftNetChunkMetadata) + (packet_metadata ? sizeof(struct SwiftNetPacketMetadata) : 0)); \ memcpy(buffer + GET_PREPEND_SIZE(network_data) + sizeof(struct ip) + offsetof(struct SwiftNetChunkMetadata, checksum), &checksum, sizeof(checksum)); \ + memcpy(buffer + GET_PREPEND_SIZE(network_data) + offsetof(struct ip, ip_sum), &ip_sum, SIZEOF_FIELD(struct ip, ip_sum)); \ } #define GET_ADDR_TYPE(network_data) (network_data)->addr_type