Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> извлечь data из ethernet пакета (TCP) 
:(
    Опции темы
lazycat2012
Дата 2.9.2012, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 2.9.2012

Репутация: нет
Всего: нет



Помогите разобрать на составляющие Ethernet пакет.

принимаю так: 
Код


    struct buffer {
    __u8  head_eth [14];
    __u8  head_ip [20];
    __u8  body [1484];
} buff_p;

raw_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
rec = recvfrom(raw_socket, (char *)buff, ETH_FRAME_LEN, 0, NULL, NULL);

        memcpy((void *)&buff_p, buff, ETH_FRAME_LEN);
        
        write(foutput2, buff_p.body, (rec-38)); 


получаю TCP пакет выделенный из Ethernet пакета (я надеюсь).

Но мне нучно выделить данные из  TCP, a там заголовок может быть разного размера, как быть? 

подскажите как эти пакеты разбирают (чистый Си - под линукс)
PM MAIL   Вверх
leniviy
Дата 2.9.2012, 19:04 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



переделай структуру:
Код

#include <sys/types.h>
struct buffer {
    u_int8_t  head_eth [14];
    u_int8_t  frame_data [1504];
} buff_p;

 

указатель на данные:
Код

#include <netinet/ip.h>

#define GET_DATA(p_iphdr) ( (u_int8_t*)(p_iphdr) + ((p_iphdr)->ihl*4) )

  struct iphdr* p_iphdr = (struct iphdr*)&buff_p.frame_data;
  // p_iphdr->ihl = 5;
  u_int8_t*pdata = GET_DATA(p_iphdr);
  printf("%u\n", pdata - (u_int8_t*)&buff_p.frame_data);


Это сообщение отредактировал(а) leniviy - 2.9.2012, 19:53
PM MAIL   Вверх
leniviy
Дата 2.9.2012, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



переделал
PM MAIL   Вверх
lazycat2012
Дата 3.9.2012, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 2.9.2012

Репутация: нет
Всего: нет



Использовал структуры заголовков IP и TCP, получилось так:

Код

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>


int main(void)
{
    extern int errno;
    int            foutput; // дескриптор файла дампа
    int            rec; // получено из сокета
    int            size_data; // объем полезных данных
    struct iphdr ip; // IP заголовок
    struct tcphdr tcp; // TCP заголовок
    int    raw_socket; // дескриптор сокета
    
    __u8 buff[ETH_FRAME_LEN]; // буфер ETH пакета
    __u8  buff_tcp[1460]; // буфер данных

    foutput = open("dump-rtmp", O_WRONLY | O_TRUNC | O_CREAT  , 0644);
    if (foutput < 0)
    {
        fprintf(stderr, "Cannot open file 'dump-rtmp' -%s\n", strerror(errno));
        exit(1);
    }

    if ((raw_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) <0)
    {
        fprintf(stderr,"Cannot open socket\n");
        exit(1);
    }

    for (;;)
    {
        rec = recvfrom(raw_socket, (char *)buff, ETH_FRAME_LEN, 0, NULL, NULL);
        
        if (rec < 0 || rec > ETH_FRAME_LEN)
        {
            fprintf(stderr,"recvfrom - error\n");
            return -1;
        }

        memcpy((void *)&ip, buff + ETH_HLEN, sizeof(struct iphdr));

        if ((ip.version) == 4)
        {
            memcpy((void *)&tcp, buff + ETH_HLEN + ip.ihl * 4, sizeof(struct tcphdr));

            if ((ip.protocol == IPPROTO_TCP) & (ntohs(tcp.dest) == 1935))
            {
                size_data = (rec-tcp.doff*4-ip.ihl*4-ETH_HLEN);
                memcpy((void *)&buff_tcp, (buff + ETH_HLEN + ip.ihl*4 + tcp.doff*4), size_data);

                if (size_data > 0)
                {
                    printf("TCP пакет - %u\n", size_data);
                    write(foutput, buff_tcp, size_data);
                }
            }
        }
    }
    exit(0);
}


работает, пишет что нужно.
PM MAIL   Вверх
leniviy
Дата 3.9.2012, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



по мне так, первые 2 memcpy - это лишнее, так как длина полей
ip.version,ip.protocol,ip.ihl,tcp.dest

не превышает 16 бит, то unaligned access не случится.
айпишники длиной 32+ бита действительно надо копировать с помощью memcpy, но здесь они не проверяются.

Оптимальнее всего в recvfrom() передавать указатель на буфер+ (offsetof(чего-нибудь)), чтобы начало ip пакета делилось на 4.


Код

size_data = (rec-tcp.doff*4-ip.ihl*4-ETH_HLEN);

Это работает? Если я правильно прочитал википедию, tcp.doff и ip.ihl - оба указывают на начало полезных данных, а длина пакета в другом поле
PM MAIL   Вверх
lazycat2012
Дата 3.9.2012, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 2.9.2012

Репутация: нет
Всего: нет



Цитата

Это работает? 

да работает 
size_data = (rec-tcp.doff*4-ip.ihl*4-ETH_HLEN)
tcp.doff*4   заголовок tcp
ip.ihl*4        заголовок ip
ETH_HLEN  заголовок ETH

в итоге размер "чистых данных"

Цитата

по мне так, первые 2 memcpy - это лишнее, так как длина полей


Иначе я не смогу получить параметры ip.version,  ip.protocol, tcp.dest, tcp.doff, ip.ihl,  а их надо.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0776 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.