Расположение ip-заголовка и сетевое программирование

Я беру урок по компьютерной и сетевой безопасности. Мы пишем пакетный спуфер. Я мог бы просто скачать один из Интернета и использовать его, но я предпочитаю писать материал сам. Ниже приведена структура, которую я использую для представления заголовка ip, который я основываю на статье в Википедии. Я пытаюсь отправить пинг-пакет icmp. Я сделал это успешно, но только после присвоения значения длины заголовка ip полю версии и наоборот. Каким-то образом я неправильно настроил структуру или неправильно присваиваю значения, и я не уверен, что делаю неправильно.

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
};

Если я назначу version а также ihlкак показано ниже, wireshark сообщает об ошибке с заголовком "Bogus IPV4 version (0, должно быть 4)".

char buffer[1024];
struct ip_header* ip = (struct ip_header*) buffer;
ip->version = 4;
ip->ihl = 5;

Однако после перехода к следующему списку ICMP-запрос проходит нормально.

char buffer[1024];
struct ip_header* ip = (struct ip_header*) buffer;
ip->version = 5;
ip->ihl = 4;

Я пытался разместить htons вокруг чисел, но это, кажется, не делает ничего полезного. Что мне здесь не хватает?

1 ответ

Решение

Вам просто нужно исправить порядковый номер вашей структуры. Посмотрите на структуру IP-заголовка, определенную в <netinet/ip.h> файл:

  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. */
  };
Другие вопросы по тегам