Ошибка разбора IP-заголовка - PullRequest
1 голос
/ 22 февраля 2010

У меня есть небольшая функция, которая пытается напечатать смещение фрагмента заголовка IP.

ParseIpHeader(unsigned char *packet, int len)
{
    struct ethhdr *ethernet_header;
    struct iphdr *ip_header;

    /* First Check if the packet contains an IP header using
       the Ethernet header                                */

    ethernet_header = (struct ethhdr *)packet;

    if(ntohs(ethernet_header->h_proto) == ETH_P_IP)
    {
            /* The IP header is after the Ethernet header  */

            if(len >= (sizeof(struct ethhdr) + sizeof(struct iphdr)))
            {
                    ip_header = (struct iphdr*)(packet + sizeof(struct ethhdr));

                    /* print the Source and Destination IP address */

                    //printf("Dest IP address: %s\n", inet_ntoa(ip_header->daddr));
                    //printf("Source IP address: %s\n", inet_ntoa(ip_header->saddr));
                    printf("protocol %d\n", ip_header->protocol);
                    printf("Fragment off is %d\n", ntohs(ip_header->frag_off));

            }

}

Мои пакеты TCP (протокол ip_header-> всегда 6. Проблема в том, что frag_off всегда 16384. Я посылаю много данных, почему frag_off всегда постоянен?

Спасибо.

1 Ответ

3 голосов
/ 22 февраля 2010

Смещение фрагмента используется совместно с флагами. У вас установлен бит "DF" (не фрагмент).

Что дает 16384 для всего 16-битного поля, учитывая смещение фрагмента 0.

Взгляните на http://www.ietf.org/rfc/rfc791.txt,, начиная со страницы 10.

EDIT

Бит DF в получаемых вами сегментах TCP устанавливается удаленной стороной, чтобы в двух словах выполнить обнаружение Path MTU - в двух словах, чтобы попытаться избежать фрагментации. В этом случае отправляющая сторона узнает самый большой MTU, который может обработать общий путь, и разбивает сегменты TCP так, чтобы они не превышали его после инкапсуляции в IP.

EDIT2

относительно использования recvfrom () и TCP: TCP является протоколом, ориентированным на соединение, и все детали сегментации / фрагментации уже обрабатываются им (фрагментация явно обрабатывается нижним уровнем, IP) - так что вы делаете не надо с этим бороться. Все, что вы пишете () на отправляющей стороне, в конечном итоге будет прочитано () на другой стороне - возможно, , а не в одних и тех же чанках - т.е. две записи 4K могут иногда приводить к одному чтению 8K, а иногда к два чтения 4K - в зависимости от поведения промежуточных носителей относительно переупорядочения / потерь.

Фрагментация и повторная сборка IP прозрачно обрабатывается операционной системой, поэтому вам не нужно об этом беспокоиться, так же как и о пакетах, вышедших из строя и т. Д. (Вы просто увидите снижение производительности как влияние на приложение) .

Одно хорошее чтение, которое я мог бы порекомендовать, это: Сетевое программирование в UNIX . Учитывая участие Стивена в TCP, это хорошая книга, независимо от того, какую ОС вы используете.

EDIT3:

И если вы делаете что-то, чтобы быть «человеком посередине» (если у вас есть веские и законные причины для этого :-) - тогда вы можете оценить предстоящую работу, взглянув на уровень техники: chaosreader (подход с одним сценарием, работающий с файлами pcap, но адаптируемый к чему-то другому), или LibNIDS - который эмулирует дефрагментацию IP и повторную сборку потока TCP; и, возможно, просто использовать их в своих целях.

...