Reputation: 1005
I am taking a class on computer and network security. We are writing a packet spoofer. I could just download one from the internet and use it, but I prefer writing the stuff myself. Below is the struct that I use to represent the ip header which I am basing off of the wikipedia article. I am attempting to send an icmp ping packet. I have done it successfully, but only after assigning the value of the ip header length to the version field, and vice versa. Somehow I have setup my struct wrong, or I am assigning the values wrong, and I am not sure what I am doing incorrectly.
struct ip_header
{
uint8_t version : 4 // version
, ihl : 4; // ip header length
uint8_t dscp : 6 // differentiated services code point
, ecn : 2; // explicit congestion notification
uint16_t total_length; // entire packet size in bytes
uint16_t identification; // a unique identifier
uint16_t flags : 3 // control and identify fragments
, frag_offset : 13; // offset of fragment relative to the original
uint8_t ttl; // how many hops the packet is allowd to travel
uint8_t protocol; // what protocol is in use
uint16_t checksum; // value used to determine bad packets
uint32_t src_ip; // where the packet is form
uint32_t dest_ip; // where the packet is going
};
If I assign the version
and ihl
, like below, wireshark reports an error with the header, "Bogus IPV4 version (0, must be 4)".
char buffer[1024];
struct ip_header* ip = (struct ip_header*) buffer;
ip->version = 4;
ip->ihl = 5;
However, after changing to the following listing, the ICMP request goes through just fine.
char buffer[1024];
struct ip_header* ip = (struct ip_header*) buffer;
ip->version = 5;
ip->ihl = 4;
I have tried placing htons
around the numbers, but that doesn't seem to do anything useful. What am I missing here?
Upvotes: 0
Views: 1048
Reputation: 91
You simply need to correct your structure's endianness. Look at the IP header structure defined in the <netinet/ip.h>
file:
struct iphdr
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int ihl:4;
unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
unsigned int version:4;
unsigned int ihl:4;
#else
# error "Please fix <bits/endian.h>"
#endif
uint8_t tos;
uint16_t tot_len;
uint16_t id;
uint16_t frag_off;
uint8_t ttl;
uint8_t protocol;
uint16_t check;
uint32_t saddr;
uint32_t daddr;
/*The options start here. */
};
Upvotes: 3