![]() |
Модераторы: xvr |
![]() ![]() ![]() |
|
null56 |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
Всем привет, не ясен процесс подготовки сокетного буфера (sk_buff), при передаче вышележащим протоколам
Собсвенно шаги: - регистрирую обработчик кадров канального уровня со своей сигнатурой
- получив кадр в колбаке, удаляю из заголовка кадра, все что мне нужно, оставляя лишь стандартные данные структуры
- отправляю вышележащим протоколам
Вопрос: я нахожусь на канальном уровне, должен ли я отделять данные канального уровня? или же я должен передавать вышележащему уровню полный кадр, а он сам отделит сетевой уровенЬ?
заранее благодарен за помощь |
||||||||
|
|||||||||
null56 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
другими словами, что нужно сделать перед отправкой
удалить полностью заголовок кадра ethernet
и выставить смещение протокола ip
или же достаточно только выставить смещение, в этом случае смещения протоколов канального и сетевого у нас будут совпадать Это сообщение отредактировал(а) null56 - 28.1.2011, 17:57 |
||||||
|
|||||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
есть NAPI и legacy драйвера сетевых устройств
legacy в контексте _аппаратного_ прерывания вызывают netif_rx затем backlog-устройство для данного cpu добаляется в poll-список, пакет - в входную очередь и генерируется NET_RX_SOFTIRQ затем в контексте NET_RX_SOFTIRQ обработчик process_backlog берет пакеты и дергает netif_receive_skb там, ВНИМАНИЕ, вызывается skb_reset_network_header и далее уже вызываются обработчики packet-сокетов т. е. в netif_rx _уже_ передается пакет с увеличенным data (на 14+ для ethernet или в зависимости от канального уровня) в NAPI аналогично за исключением того, что netif_receive_skb дергается драйвером в process_xxxx обрати внимание на это packet-сокеты обрабатываются _в контексте_ netif_rx (явном или неявном) поэтому нельзя из них вызывать netif_rx -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
да, спасибо, это уже нашел, смещение хранимое в поле network_header уже соответствует моему канальному уровню (14) + мой апендикс, убирая мой апендикс и перемещая eth_hdr, я работаю с data, поэтому трогать network_header, не нужно.
но вот в это меня смущает, вечерком поищу этот момент, где вызываются packet сокеты. просто как же тогда передать вышележащим протоколам? если знаешь где идет вызов, кинь ссылочку на исходник, я гляну.... буду очень благодарен Добавлено через 7 минут и 19 секунд ты это имеешь в виду? http://lxr.free-electrons.com/source/net/core/dev.c#L1548 Добавлено через 13 минут и 10 секунд я не вижу больше вызова колбака обработки в dev.c |
|||
|
||||
null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
хотя не, ты наверное имел в виду deliver_skb, оттуда вызываются колбаки
http://lxr.free-electrons.com/source/net/core/dev.c#L2715 но вопрос все равно остается, как же передать вышележащим уровням? |
|||
|
||||
null56 |
|
||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
MAKCim, я запутался....
да, netif_rx дергается из хардваре, да он добавляет в очередь poll и перепланирует NET_RX_SOFT. далее в netif_receive_skb рано или поздно дергается __netif_receive_skb, из него вызываются зарегистрированные колбаки и все? мне более не надо ничего делать, кроме как поправить протокол?
вышележащим уровням все будет передаваться в теле __netif_receive_skb? так как у вышележащих протоколов есть свои системные колбаки http://lxr.free-electrons.com/source/net/core/dev.c#L3001 поправлю вышесказанное мной...
так ли это? ведь в __netif_receive_skb происходит
получается, что data не изменяется, она как указывала, так и указывает на начало моего канального кадра? то есть после этих манипуляций я не могу использовать функцию
так как
мы получим смещение на мак, а там совсем другие данные? другими словами, я не вижу, где data смещается на заголовок сетевого уровня спасибо Это сообщение отредактировал(а) null56 - 30.1.2011, 02:01 |
||||||||||
|
|||||||||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
угу твой зарегистрированный packet-обработчик вызывается тут http://lxr.free-electrons.com/source/net/core/dev.c#L2953 а дальше в этой же функции тут http://lxr.free-electrons.com/source/net/core/dev.c#L3002 обработчики для протокола в частности для ipv4 тут http://lxr.free-electrons.com/ident?i=dev_add_pack идет регистрация обработчика для ipv4 так тут http://lxr.free-electrons.com/source/inclu.../skbuff.h#L1271 network header вычисляется как data - head head указывает на начало линейного буфера (=заголовок канального уровня) значит data при reset'е указывает на network header, смещение которого мы и устанавливаем (т. к. dev-уровень не знает и не должен ничего знать о том, через что пакет физически попал в ядро) вот ip_rcv http://lxr.free-electrons.com/source/net/i...ip_input.c#L375 обработчик packet-сокета для ipv4 там ip_hdr юзается вполне нормально -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
вот драйвер реалтековский r8169.c функция rtl8169_rx_interrupt (обработчик прерывания сетевой карты) http://lxr.free-electrons.com/source/drive...?v=2.6.25#L2831 skb_put(skb, pkt_size) формирует линейный буфер сокета eth_type_trans тут http://lxr.free-electrons.com/source/net/ethernet/eth.c#L158 в skb_reset_mac_header мы вычисляем mac header как data - head (data и head тут одинаковы) дальше skb_pull_inline на ETH_HLEN т. е. это и есть увеличение data иными словами, задача _каждого_ драйвера - увеличение data на нужный ему известный размер -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
null56 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
получается, что после обработчика прерывания сетевой мы уже имеем в обработчике packet_type:
data == network mac = data - (my_mac_size + ETH_SIZE) смещаюсь на мой мак, правлю, убирая мой апендикс и изменяю protocol, далее уже будет вызов в обработчике ip уровня
не факт, я про заголовок канального уровня... head указывает на начало зарезервированного headroom участка, который может быть куда больше заголовка канального уровня, на картинке это хорошо заметно, посмотри функцию push http://www.skbuff.net/skbbasic.html именно поэтому http://lxr.free-electrons.com/source/net/core/dev.c#L2936
в общем спасибо, что помог разобраться с последовательностью вызовов и изменением полей sk_buff, остальное увижу в отладчике или отладочной печати |
||||
|
|||||
ROKR |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 26.9.2009 Репутация: 1 Всего: 1 |
Если я правильно понимаю, о чем речь, то:
When setting up receive packets that an ethernet device will DMA into, we typically call skb_reserve(skb, NET_IP_ALIGN). By default NET_IP_ALIGN is defined to '2'. This makes it so that, after the ethernet header, the protocol header will be aligned on at least a 4-byte boundary. Nearly all of the IPV4 and IPV6 protocol processing assumes that the headers are properly aligned. Взято отсюда Вот пример того, что я делал:
В data уже лежал целиковый ethernet-пакет. Ну и указывать протокол: new_skb->protocol = eth_type_trans( new_skb, btmbnep_netdev ); тоже обязательно. |
|||
|
||||
null56 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
Продолжу тему, ибо столкнулся с проблемой....
1) при отправке пакета, изменяю идентификатор протокола на свой
2) на другой машине ставлю фильтр для этого типа пакетов
3) пакеты как и полагается попадают в колбак, где я пытаюсь изменить протокол и отправить вышележащим
и пакет уходит в неизвестном направлении для примера я использую устройства броадкасты. если посылать пакеты не изменяя h_proto в кадре ethernet и ставя фильтр соответственно на ETH_P_IP, то пакеты также попадают в мой колбак и достигают цели что не так? почему не достаточно просто поправить протокол? что еще нужно сделать? буду благодарен за помощь |
||||||
|
|||||||
null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
смотрю примеры и замечаю, что после определения протокола вызывают netif_rx
http://www.google.com/codesearch/p?hl=ru#M...cd=16&ct=rc поэтому вопрос пока не решен |
|||
|
||||
null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
пока не ясно, что еще нужно сделать с skb, чтобы сетевая подсистема отправила сама этот буфер вверх по протоколам... но можно попробовать это
но по идее не нужны такие костыли, ведь абсолютно идентичные пакеты, но с обычной ip сигнатурой отправляются, а мои нет... буду мучить, результаты экспериментов не ранее понедельника ![]() |
|||
|
||||
null56 |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: 4 Всего: 12 |
это правильный ответ... а теперь подробнее начать наверное лучше всего с регистрации своего обработчика, фукнция dev_add_pack, посмотрим ее исходный код
ключевой является функция ptype_head в строчке номер 400, вот она ниже
и так мы видим, что если мы регистрируем обработчик для любых езернет кадров (например мы делаем снифер) ETH_P_ALL, то получаем список ptype_all, иначе, как в моем случае, мы получаем список ptype_base. это ключевой момент, теперь можно вернуться к функции __netif_receive_skb первый раз идет вызов обработчиков для ETH_P_ALL http://lxr.free-electrons.com/source/net/core/dev.c#L2949
обращаем внимание, что используется список ptype_all, а второй раз мы как раз идем по списку с нашим обработчиком ptype_base http://lxr.free-electrons.com/source/net/core/dev.c#L3001
тут как раз идем по ptype_base И БОЛЬШЕ НИКТО НИЧЕГО В ЭТОЙ ФУНКЦИИ ВЫЗЫВАТЬ НЕ БУДЕТ. В итоге, как я понял, в нашем обработчике мы должны изменить протокол и вызвать netif_receive_skb, чтобы у меня вызвался обработчик ip кадров и пакет передался выше по стеку протоколов.... так что так Это сообщение отредактировал(а) null56 - 17.2.2011, 00:29 |
||||||||
|
|||||||||
![]() ![]() ![]() |
Правила форума "С/С++: Программирование под Unix/Linux" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |