Skip to content

Commit e98e36d

Browse files
committed
Improve IP parsing logic
1 parent 03c6942 commit e98e36d

File tree

1 file changed

+99
-56
lines changed

1 file changed

+99
-56
lines changed

src/netxduo/packet_filter_glue.c

Lines changed: 99 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -563,42 +563,85 @@ int wolfsentry_inet_pton(int af, const char* src, void* dst)
563563
return result;
564564
}
565565

566-
/* IP header structure for parsing */
567-
#pragma pack(push, 1)
568-
struct netx_ip_header {
569-
unsigned char version_ihl;
570-
unsigned char tos;
571-
unsigned short total_length;
572-
unsigned short identification;
573-
unsigned short fragment_offset;
574-
unsigned char ttl;
575-
unsigned char protocol;
576-
unsigned short checksum;
577-
unsigned long source_ip;
578-
unsigned long dest_ip;
566+
#ifndef PACKED_STRUCT
567+
#define PACKED_STRUCT __attribute__((__packed__))
568+
#endif
569+
570+
struct PACKED_STRUCT netx_ip_header {
571+
struct {
572+
uint8_t version : 4;
573+
uint8_t ihl : 4;
574+
};
575+
struct {
576+
uint8_t dscp : 6;
577+
uint8_t ecn : 2;
578+
};
579+
uint16_t total_length;
580+
uint16_t identification;
581+
struct {
582+
uint16_t flags : 3;
583+
uint16_t fragment_offset : 13;
584+
};
585+
uint8_t time_to_live;
586+
uint8_t protocol;
587+
uint16_t header_checksum;
588+
uint32_t source_ip;
589+
uint32_t dest_ip;
590+
};
591+
592+
struct PACKED_STRUCT netx_udp_header {
593+
uint16_t source_port;
594+
uint16_t dest_port;
595+
uint16_t length;
596+
uint16_t checksum;
597+
};
598+
599+
struct PACKED_STRUCT netx_tcp_header
600+
{
601+
uint16_t source_port;
602+
uint16_t dest_port;
603+
uint32_t sequence_number;
604+
uint32_t acknowledgement_number;
605+
struct {
606+
uint16_t data_offset : 4;
607+
uint16_t reserved : 3;
608+
uint16_t ns : 1;
609+
uint16_t cwr : 1;
610+
uint16_t ece : 1;
611+
uint16_t urg : 1;
612+
uint16_t ack : 1;
613+
uint16_t psh : 1;
614+
uint16_t rst : 1;
615+
uint16_t syn : 1;
616+
uint16_t fin : 1;
617+
};
618+
uint16_t window_size;
619+
uint16_t checksum;
620+
uint16_t urgent_pointer;
579621
};
580622

581-
/* TCP header structure for parsing */
582-
struct netx_tcp_header {
583-
unsigned short source_port;
584-
unsigned short dest_port;
585-
unsigned long seq_num;
586-
unsigned long ack_num;
587-
unsigned char data_offset_flags;
588-
unsigned char flags;
589-
unsigned short window;
590-
unsigned short checksum;
591-
unsigned short urgent_ptr;
623+
struct PACKED_STRUCT netx_arp_header
624+
{
625+
uint16_t arp_htype;
626+
uint16_t arp_ptype;
627+
uint8_t arp_hlen;
628+
uint8_t arp_plen;
629+
uint16_t arp_oper;
630+
uint8_t arp_sha[6];
631+
uint32_t arp_spa;
632+
uint8_t arp_tha[6];
633+
uint32_t arp_tpa;
592634
};
593635

594-
/* UDP header structure for parsing */
595-
struct netx_udp_header {
596-
unsigned short source_port;
597-
unsigned short dest_port;
598-
unsigned short length;
599-
unsigned short checksum;
636+
struct PACKED_STRUCT netx_icmp_header
637+
{
638+
uint8_t icmp_type;
639+
uint8_t icmp_code;
640+
uint16_t icmp_checksum;
641+
uint32_t icmp_header_extra;
600642
};
601-
#pragma pack(pop)
643+
644+
602645

603646
/**
604647
* @brief Parse IP packet and extract endpoint information
@@ -618,9 +661,9 @@ static int parse_ip_packet(unsigned char *packet_data, unsigned long data_length
618661
unsigned short *local_port, unsigned short *remote_port,
619662
unsigned char *protocol, int is_outbound)
620663
{
621-
struct netx_ip_header *ip_header;
622-
struct netx_tcp_header *tcp_header;
623-
struct netx_udp_header *udp_header;
664+
struct netx_ip_header *ip;
665+
struct netx_tcp_header *tcp;
666+
struct netx_udp_header *udp;
624667
unsigned long ip_addr;
625668

626669
if (!packet_data || !local_addr || !remote_addr || !local_port || !remote_port || !protocol) {
@@ -632,39 +675,39 @@ static int parse_ip_packet(unsigned char *packet_data, unsigned long data_length
632675
return -1;
633676
}
634677

635-
ip_header = (struct netx_ip_header *)packet_data;
678+
ip = (struct netx_ip_header*)packet_data;
636679

637680
/* Check IP version (IPv4 only) */
638-
if ((ip_header->version_ihl >> 4) != 4) {
681+
if (ip->version != 4) {
639682
return -1;
640683
}
641684

642685
/* Extract protocol */
643-
*protocol = ip_header->protocol;
686+
*protocol = ip->protocol;
644687

645688
/* Extract IP addresses (NetX uses host byte order) */
646689
if (is_outbound) {
647690
/* For outbound packets: source is local, destination is remote */
648-
ip_addr = ip_header->source_ip;
691+
ip_addr = ip->source_ip;
649692
local_addr[0] = (ip_addr >> 24) & 0xFF;
650693
local_addr[1] = (ip_addr >> 16) & 0xFF;
651694
local_addr[2] = (ip_addr >> 8) & 0xFF;
652695
local_addr[3] = ip_addr & 0xFF;
653696

654-
ip_addr = ip_header->dest_ip;
697+
ip_addr = ip->dest_ip;
655698
remote_addr[0] = (ip_addr >> 24) & 0xFF;
656699
remote_addr[1] = (ip_addr >> 16) & 0xFF;
657700
remote_addr[2] = (ip_addr >> 8) & 0xFF;
658701
remote_addr[3] = ip_addr & 0xFF;
659702
} else {
660703
/* For inbound packets: destination is local, source is remote */
661-
ip_addr = ip_header->dest_ip;
704+
ip_addr = ip->dest_ip;
662705
local_addr[0] = (ip_addr >> 24) & 0xFF;
663706
local_addr[1] = (ip_addr >> 16) & 0xFF;
664707
local_addr[2] = (ip_addr >> 8) & 0xFF;
665708
local_addr[3] = ip_addr & 0xFF;
666709

667-
ip_addr = ip_header->source_ip;
710+
ip_addr = ip->source_ip;
668711
remote_addr[0] = (ip_addr >> 24) & 0xFF;
669712
remote_addr[1] = (ip_addr >> 16) & 0xFF;
670713
remote_addr[2] = (ip_addr >> 8) & 0xFF;
@@ -677,29 +720,29 @@ static int parse_ip_packet(unsigned char *packet_data, unsigned long data_length
677720

678721
/* Extract port numbers for TCP and UDP */
679722
if (*protocol == IPPROTO_TCP || *protocol == IPPROTO_UDP) {
680-
unsigned int ip_header_len = (ip_header->version_ihl & 0x0F) * 4;
723+
unsigned int ip_header_len = ip->ihl;
681724

682725
if (data_length < ip_header_len + sizeof(struct netx_tcp_header)) {
683726
return -1;
684727
}
685728

686729
if (*protocol == IPPROTO_TCP) {
687-
tcp_header = (struct netx_tcp_header *)(packet_data + ip_header_len);
730+
tcp = (struct netx_tcp_header*)(packet_data + ip_header_len);
688731
if (is_outbound) {
689-
*local_port = ntohs(tcp_header->source_port);
690-
*remote_port = ntohs(tcp_header->dest_port);
732+
*local_port = ntohs(tcp->source_port);
733+
*remote_port = ntohs(tcp->dest_port);
691734
} else {
692-
*local_port = ntohs(tcp_header->dest_port);
693-
*remote_port = ntohs(tcp_header->source_port);
735+
*local_port = ntohs(tcp->dest_port);
736+
*remote_port = ntohs(tcp->source_port);
694737
}
695738
} else if (*protocol == IPPROTO_UDP) {
696-
udp_header = (struct netx_udp_header *)(packet_data + ip_header_len);
739+
udp = (struct netx_udp_header*)(packet_data + ip_header_len);
697740
if (is_outbound) {
698-
*local_port = ntohs(udp_header->source_port);
699-
*remote_port = ntohs(udp_header->dest_port);
741+
*local_port = ntohs(udp->source_port);
742+
*remote_port = ntohs(udp->dest_port);
700743
} else {
701-
*local_port = ntohs(udp_header->dest_port);
702-
*remote_port = ntohs(udp_header->source_port);
744+
*local_port = ntohs(udp->dest_port);
745+
*remote_port = ntohs(udp->source_port);
703746
}
704747
}
705748
}
@@ -763,12 +806,12 @@ int wolfsentry_netx_ip_packet_filter(struct wolfsentry_context* ctx, unsigned ch
763806
wolfsentry_route_flags_t inexact_matches;
764807

765808
/* Define sockaddr structures for local and remote endpoints */
766-
WOLFSENTRY_SOCKADDR(32) local_sockaddr_buf, remote_sockaddr_buf; /* 32 bits for IPv4 address */
809+
WOLFSENTRY_SOCKADDR(32) local_sockaddr_buf, remote_sockaddr_buf; /* 32 bits for IPv4 address */
767810
struct wolfsentry_sockaddr *local_sockaddr, *remote_sockaddr;
768811

769-
/* Initialize sockaddr structures */
770-
memset(&local_sockaddr_buf, 0, sizeof(local_sockaddr_buf));
771-
memset(&remote_sockaddr_buf, 0, sizeof(remote_sockaddr_buf));
812+
/* Initialize sockaddr structures */
813+
memset(&local_sockaddr_buf, 0, sizeof(local_sockaddr_buf));
814+
memset(&remote_sockaddr_buf, 0, sizeof(remote_sockaddr_buf));
772815

773816
local_sockaddr = (struct wolfsentry_sockaddr*)&local_sockaddr_buf;
774817
remote_sockaddr = (struct wolfsentry_sockaddr*)&remote_sockaddr_buf;

0 commit comments

Comments
 (0)