The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Пакетный RAW Сокет и sendmsg"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Пакетный RAW Сокет и sendmsg"
Сообщение от Alexzy emailИскать по авторуВ закладки(ok) on 03-Сен-04, 12:13  (MSK)
(Извините за откровенно ламерский вопрос, но это мой первый опыт программирования сокетов в Linux'e и как следствие первые непроходимые грабли)
Пробовал тут посылать пакет сформированый собственноручно с помощью
pcksck=socket(PF_PACKET,SOCK_RAW,ETH_P_ALL)
а затем отсылать его методом
sendmsg(psksck,hdr,0)
но сендмсг возвращает -1 и еррно = EINVAL (22), подозреваю, что дело в неправильно сформированном hdr. Заполнил я его согласно man'u, хотя возникли вопросы относительно полей msg_control и msg_name - пробовал подставлять в них мак карточки и названия девайса(ака /dev/eth).Не могли бы вы мне объяснить для чего предназначены данные поля и как их правильно заполнять, а может для моей задачи они и вовсе не нужны и грабли лежат где-то еще? Работаю под root'ом, создание самого сокета вроде проходит нормально (не возвращает -1).  
Заранее благодарен за любую конструктивную помощь :)
  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "Пакетный RAW Сокет и sendmsg"
Сообщение от Cadaver Искать по авторуВ закладки(ok) on 07-Сен-04, 12:12  (MSK)
>(Извините за откровенно ламерский вопрос, но это мой первый опыт программирования сокетов
>в Linux'e и как следствие первые непроходимые грабли)
>Пробовал тут посылать пакет сформированый собственноручно с помощью
>pcksck=socket(PF_PACKET,SOCK_RAW,ETH_P_ALL)
>а затем отсылать его методом
>sendmsg(psksck,hdr,0)
>но сендмсг возвращает -1 и еррно = EINVAL (22), подозреваю, что дело
>в неправильно сформированном hdr. Заполнил я его согласно man'u, хотя возникли
>вопросы относительно полей msg_control и msg_name - пробовал подставлять в них
>мак карточки и названия девайса(ака /dev/eth).Не могли бы вы мне объяснить
>для чего предназначены данные поля и как их правильно заполнять, а
>может для моей задачи они и вовсе не нужны и грабли
>лежат где-то еще? Работаю под root'ом, создание самого сокета вроде проходит
>нормально (не возвращает -1).
>Заранее благодарен за любую конструктивную помощь :)


Мне нужно было принимать/посылать только с одного интерфейса, поэтому я вначале сокет биндил к /dev/ethx, а EINVAL - это точно hdr, у меня такое было, надо проверить, заполнить ВСЕ поля, в том числе те, которые не знаешь как - поставить NULL и нули, память где надо аллоцировать. У меня было:

msg_name = NULL;
msg_namelen = 0;
msg_control = NULL;
msg_controllen = 0;
msg_iov = (struct iovec *) malloc (тратата);
msg_iov.base = malloc (сколько надо под пакет);
msg_iov.len = сколько надо под пакет;
msg_iovlen = 1;
msg_flags = 0;


После этого все работало. У меня инвал был потому что я имя не заполнял, то есть нулл не присваивал, а это надо

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "Пакетный RAW Сокет и sendmsg"
Сообщение от Alexzy emailИскать по авторуВ закладки(ok) on 07-Сен-04, 17:59  (MSK)
Методом чтения Man'ов/исходников/научного тыка я заставил это дело пахать прописав следующее
msg_name = &sockaddr_ll_obj;
msg_namelen = sizeof(sockaddr_ll_obj);
при этом необходимо заполнить
sockaddr_ll_obj.sll_family = AF_PACKET;
sockaddr_ll_obj.sll_ifindex = 2; //Это я установил методом тыка т.к. не знаю как можно получить индекс eth0
А как байндить я так и не разобрался - SOBINDTODEVICE все время ругается на неправильное устройство :(
Может кто научит как получать индекс сетевого интерфейса и байндить на него сокет?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "Пакетный RAW Сокет и sendmsg"
Сообщение от jd Искать по авторуВ закладки on 07-Сен-04, 23:22  (MSK)
>Методом чтения Man'ов/исходников/научного тыка я заставил это дело пахать прописав следующее
> msg_name = &sockaddr_ll_obj;
> msg_namelen = sizeof(sockaddr_ll_obj);
>при этом необходимо заполнить
> sockaddr_ll_obj.sll_family = AF_PACKET;
> sockaddr_ll_obj.sll_ifindex = 2; //Это я установил методом тыка т.к. не знаю
>как можно получить индекс eth0
>А как байндить я так и не разобрался - SOBINDTODEVICE все время
>ругается на неправильное устройство :(
>Может кто научит как получать индекс сетевого интерфейса и байндить на него
>сокет?


Примерно так:

struct ifreq ifr;
struct sockaddr_ll sa;
int s=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));
ioctl(sock_fd, SIOCGIFINDEX, &ifr); /* ifr.ifr_index теперь содержит номер интерфейса eth0 */
sa.sll_family=AF_PACKET;
sa.sll_ifindex=ifr.ifr_index;
/* Остальные поля в sa тоже нужно заполнить */
bind(s, (struct sockaddr*)&sa, sizeof(sa)); /* теперь сокет привязан к eth0 */

Разумеется нужно ещё проверять, что возвращают все функции. Также неплохо почитать man packet(7), посмотреть заголовочники etc...

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру