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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Что происходит при фрагментации пакетов 
:(
    Опции темы
konshyn
Дата 19.10.2013, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Всем доброго вечера. 
сразу скажу: ОС - UNIX.
Суть вопроса и создания темы вот в чем: на мой комп отправляют какой-то пакет, по проводам он идет в виде ethernet-кадра. Какой-то маршрутизатор решил, что его нужно фрагментировать. Поделил и отправил уже ко мне два таких кадра. На компе стоит анализатор трафика. Сокет сырой(принимает ethernet-кадры). Вопрос: на этот сокет придут ДВА пакета? Или система, прежде чем передать поделенный пакет, примет его, соберет и передаст уже готовый целый?

Это сообщение отредактировал(а) konshyn - 19.10.2013, 18:27


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
feodorv
Дата 19.10.2013, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Судя по "принимает ethernet-кадры" на сокет придут два кадра. Проверьте с помощью утилиты ping с размером данных в 2000 байт.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Олег2005
Дата 19.10.2013, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



В модуле IP есть таймер сборки фрагментов. В Юниксе это 30 сек.
Если за это время приходят все фрагменты, то модуль собирает их в один IP-пакет. RAW сокет завязан на уровень IP, поэтому придет один IP-пакет. Имхо. Теоретически это так...
PM MAIL WWW MSN   Вверх
feodorv
Дата 19.10.2013, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Вот и вопрос. Сокет AF_PACKET или AF_INET?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
o2n3e
Дата 19.10.2013, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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




Модератор: Сообщение скрыто.

PM MAIL   Вверх
konshyn
Дата 19.10.2013, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Олег2005 @  19.10.2013,  19:29 Найти цитируемый пост)
В модуле IP есть таймер сборки фрагментов. В Юниксе это 30 сек.
Если за это время приходят все фрагменты, то модуль собирает их в один IP-пакет. RAW сокет завязан на уровень IP, поэтому придет один IP-пакет. Имхо. Теоретически это так... 

Да. Получается так.


Цитата(feodorv @  19.10.2013,  19:47 Найти цитируемый пост)
Вот и вопрос. Сокет AF_PACKET или AF_INET? 


Сокет был PF_PACKET. Но теперь решил принимать только IP, поэтому AF_INET.
Но теперь вопрос немного не по теме...
Я создаю сокет вот так:
Код

eth0_if = socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW));


и мне нужно принимать ЛЮБОЙ IP-пакет с определенного интерфейса и с любых портов.

я привязал этот сокет к интерфейсу так:

Код

int rc = setsockopt(eth0_if, SOL_SOCKET, SO_BINDTODEVICE, "eth0\x00", strlen("eth0\x00") + 1);


можно сделать через bind() привязывая к ip-адресу, но там задается порт, который обязателен. а мне нужно считывать со всех портов, а не с конкретного

считываю так:

Код

rec = recvfrom(eth0_if, (char *)buff, ifp.mtu + 18, 0, NULL, NULL);


но как бы не работает. висит на этой функции recvfrom() и все.

Как мне принять любой IP-пакет?

Добавлено через 8 минут и 7 секунд
Цитата(o2n3e @  19.10.2013,  20:05 Найти цитируемый пост)
Сокет не принимает интернет кадры

Прости, но ты не прав
Код

eth0_if = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));


Создает сырой сокет, который принимает все кадры.

И в буфер считается все: eth-заголовок, ip-заголовок и т.д.


Цитата(o2n3e @  19.10.2013,  20:05 Найти цитируемый пост)
 ты не отличишь друг от друга - на неём не написанно, что он - разбитый другой

Отличу. В IP заголовке есть пункт, который показывает, что это фрагмент целого пакета. В разделе "флаги", третий бит. И есть поле - "смещение фрагмента", идет сразу после поля "флаги".


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
o2n3e
Дата 19.10.2013, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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




Модератор: Сообщение скрыто.

PM MAIL   Вверх
feodorv
Дата 19.10.2013, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(konshyn @  19.10.2013,  21:09 Найти цитируемый пост)
можно сделать через bind() привязывая к ip-адресу, но там задается порт, который обязателен. а мне нужно считывать со всех портов, а не с конкретного

Честно говоря, я даже не уверен, что на сырой сокет можно делать bind. К тому же IP-трафик - это не только UDP/TCP, но и другие протоколы, для которых понятие порта не определено.


Цитата(konshyn @  19.10.2013,  21:09 Найти цитируемый пост)
поэтому AF_INET

Если AF_INET, то, скорее всего, начальный пакет предварительно будет собран из фрагментов. Опять же нужно проверить  smile 


Цитата(konshyn @  19.10.2013,  21:09 Найти цитируемый пост)
Как мне принять любой IP-пакет?

А вот здесь правильно ли:
Цитата(konshyn @  19.10.2013,  21:09 Найти цитируемый пост)
socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW))

Вот зачем здесь htons?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
feodorv
Дата 19.10.2013, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(konshyn @  19.10.2013,  21:09 Найти цитируемый пост)
я привязал этот сокет к интерфейсу так

Эээ, нет, не правильно. Я Вам давал ссылку на правильный код smile 
Ссылка в явном виде: http://codingrelic.geekhold.com/2009/10/co...ndtodevice.html


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
konshyn
Дата 19.10.2013, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(feodorv @  19.10.2013,  21:20 Найти цитируемый пост)
Эээ, нет, не правильно.

В какой-то статье так было сделано. Я проверил, работает.
Но этой строкой я хотел сказать, что привязвал к физическому интерфейсу(по названию), а не к IP-адресу, как это делает функция bind().


Цитата(feodorv @  19.10.2013,  21:05 Найти цитируемый пост)
сырой сокет можно делать bind

Можно. Для сырого сокета используется структура 
Код

struct sockaddr_ll



Цитата(feodorv @  19.10.2013,  21:05 Найти цитируемый пост)
Вот зачем здесь htons? 

По идее, нужно(у Стивенса так было написано с каким-то протоколом, если не ошибаюсь, то именно с сырым PF_PACKET. Но вообще, в поле протокол - значение должно быть в сетевом порядке вроде как). Но с ним или без него, не работает. 

Но допустим мы определились. IP -  пакет собирается на месте, а потом передается сокету. Т.е. я получаю целый пакет.
Сырой сокет для IP пакетов создается так

Код

socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW));


нужен htons или нет, неважно, это легко потом проверить.
допустим, у меня один интерфейс(сетевая карта) eth0. 

Как или через какую функцию мне начать принимать пакеты? 

потому что recvfrom - не работает, или я ее неправильно использую в данном случае.


--------------------
«Потому что ценность акта действия в этой стране возрастает в несколько раз».
PM MAIL Skype   Вверх
Олег2005
Дата 19.10.2013, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



Цитата(konshyn @  19.10.2013,  19:09 Найти цитируемый пост)
Как мне принять любой IP-пакет?

Ну, вообще-то работа с RAW- это работа без портов в принципе, и поэтому думаю, что все что будет приходить по этому сокету - должно бы поступать в него со всех интерфейсов как бы автоматически, именно этому приложению (если оно единственное кто работает с RAW). Впрочем, это только имхо... smile 
Цитата(konshyn @  19.10.2013,  20:44 Найти цитируемый пост)
нужен htons или нет, неважно, это легко потом проверить.

Да нет, это важно.
В порядок байтов сети должны быть преобразованы только те целые числа, которые обрабатываются маршрутизаторами (это IP-адрес) и конечной системой - а это порт. Поле протокола никогда не преобразуется - например TCP- номер 6, UDP- 17, а IP - это номер 0, и его как ни крути - будет 0. А потому и с htons и без него - один шиш.


Это сообщение отредактировал(а) Олег2005 - 19.10.2013, 22:11
PM MAIL WWW MSN   Вверх
feodorv
Дата 19.10.2013, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(konshyn @  19.10.2013,  22:44 Найти цитируемый пост)
нужен htons или нет, неважно, это легко потом проверить.

Потом - это когда? Почему не сейчас?

Цитата

Создание сокета. Код на языке Си

...
int i32SocketFD = socket( PF_INET, SOCK_RAW, IPPROTO_RAW );

Взято с википедии. В man'ах Вы найдёте то же самое. Можно изучить SOCK_RAW Demystified. И я как-то сомневаюсь, что у Стивенса было с htons. Приведите, пожалуйста, ссылку.

Передали неправильный параметр, получили ничего в recvfrom.


Цитата(konshyn @  19.10.2013,  22:44 Найти цитируемый пост)
Для сырого сокета используется структура 

Ну это несколько другой bind, не тот, о котором Вы говорили
Цитата(konshyn @  19.10.2013,  21:09 Найти цитируемый пост)
можно сделать через bind() привязывая к ip-адресу

И ещё нужно правильно определить индекс интерфейса.


Цитата(konshyn @  19.10.2013,  22:44 Найти цитируемый пост)
В какой-то статье так было сделано. Я проверил, работает.

Всё равно это не правильно. Статья - хакерская, не иначе. Правильный путь - через struct ifreq, как и написано в руководстве.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Олег2005
Дата 19.10.2013, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



Цитата(feodorv @  19.10.2013,  21:05 Найти цитируемый пост)
Можно изучить SOCK_RAW Demystified. 

Спасибо за ссылку!!! smile 
Вот нашел ссылку, откуда Ноги растут


Это сообщение отредактировал(а) Олег2005 - 19.10.2013, 22:15
PM MAIL WWW MSN   Вверх
feodorv
Дата 19.10.2013, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(konshyn @  19.10.2013,  22:44 Найти цитируемый пост)
у Стивенса так было написано с каким-то протоколом

Вы, наверное, имели в виду
Код

sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

Но при чём здесь IPPROTO_RAW?

Добавлено через 2 минуты и 1 секунду
Цитата(Олег2005 @  19.10.2013,  23:08 Найти цитируемый пост)
Спасибо за ссылку!!!

 smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Олег2005
Дата 19.10.2013, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

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



Нашел такое определение в хедере
#define ETH_P_ALL    0x0003    
Нашел и это
  sockaddr_ll является не зависимым  от  устройства  адресом
       физического уровня.
              struct sockaddr_ll {
                  unsigned short  sll_family;    /* Всегда AF_PACKET */
                  unsigned short  sll_protocol;  /* Протокол физического уровня */
                  int             sll_ifindex;   /* Hомер интерфейса */
                  unsigned short  sll_hatype;    /* Тип заголовка */
                  unsigned char   sll_pkttype;   /* Тип пакета */
                  unsigned char   sll_halen;     /* Длина адреса */
                  unsigned char   sll_addr[8];   /* Адрес физического уровня */
              };
       sll_protocol  -  тип  стандартного  протокола  ethernet  в
       сетевом   порядке    байтов, 
   определенный    в    файле
       linux/if_ether.h.    Он   определяет  протокол  сокета  по
       умолчанию.  
Кстати, вопрос к топикстартеру - ведь такую тему вы уже поднимали:
http://forum.vingrad.ru/topic-372076.html

Это сообщение отредактировал(а) Олег2005 - 19.10.2013, 22:43
PM MAIL WWW MSN   Вверх
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




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


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

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