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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ARP запрос через socket, учитывая routing table 
V
    Опции темы
slavayo7777
Дата 22.6.2011, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прогер



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

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



Добрый день.
Уже замучался рыть в интернете. Может подскажите...
В моем устройстве необходимо узнать мак адресс узла, ip адрес которого мне выдает сервер. На этот адресс необходимо слать пакеты с данными.
Устройство работает на Linux-2.6.10.
На сколько я знаю, для генерации ARP нужен SOCK_RAW и самому забивать пакет и все заголовки. Что я и сделал. 
Код

if((raw_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP)))== -1)
{
   perror("Error creating raw socket: ");
   return -1;
}
/* Set socket to non-blocking */
flags = fcntl(raw_sock, F_GETFL, 0);
if (0 > flags) {
    ENT_ERR("SetRawSockNonblock() - can't get socket flags");
    return -1;
}
flags |= O_NONBLOCK;
if (0 > fcntl(raw_sock, F_SETFL, flags)) {
    ENT_ERR("SetRawSockNonblock() - can't make socket non-blocking, errno %d", errno);
    return -1;
}
bzero(&sll, sizeof(sll));
bzero(&ifr, sizeof(ifr));
strncpy((char *)ifr.ifr_name, "eth0", IFNAMSIZ);
if((ioctl(raw_sock, SIOCGIFINDEX, &ifr)) == -1)
{
   printf("Error getting Interface index !\n");
   return -1;
}
/* Bind our raw socket to this interface */
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(ETH_P_ARP); 
if((bind(raw_sock, (struct sockaddr *)&sll, sizeof(sll)))== -1)
{
   perror("Error binding raw socket to interface\n");
   exit(-1);
}
/* Здесь формирую сам пакет packet */

/* Send the packet out ! */
if((len = write(raw_sock, packet, pkt_len)) != pkt_len)
{
/* Error */
   printf("Could only send %d bytes of packet of length %d\n", len, pkt_len);
   return -1;
}
/* Wait for ARP response */
in_pkt = (unsigned char *)malloc(MAX_RESP_LEN);
count = 100;
while(((len = read(raw_sock, in_pkt, pkt_len)) <= 0) && (count > 0))
{
   apps_tel_taskDelay(1);
   count--;
}
if ( len <= 0 )
{
   free(in_pkt);
   close(raw_sock);
   ENT_ERR("Socket read error, or no ARP response\n");
   return -1;
}
/*здесь расфасовываю ответ и узнаю адресс*/

Все прекрасно работает, пока не подключаешь устройство через шлюз к серверу.
Например мое устройство имеет айпи 10.60.20.2, шлюз 10.60.20.1 к серверу 10.80.1.1. И сервер может выдать произвольный айпи, к которому можно достучаться через этот же шлюз.
прописываю в своем устройстве шлюз 10.60.20.1: 
Код

route add -net 10.0.0.0 netmask 255.0.0.0 gw 10.60.20.1 dev eth0

Но так как я забиваю пакет сам, я в нем забиваю IP искомого узла, что в случае с gateway неверно (нужно подменить в теле ARP пакета искомый IP на IP гейта).
Но как узнать из routing table какой айпи подставлять?
утилита ping каким то образом это делает.
Есть ли другой способ генерации ARP? Чтоб система сама заботилась об IP и маршрутизации.
PM MAIL ICQ   Вверх
fish9370
Дата 22.6.2011, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(slavayo7777 @  22.6.2011,  14:57 Найти цитируемый пост)
В моем устройстве необходимо узнать мак адресс узла, ip адрес которого мне выдает сервер


это узнать невозможно.. ты можешь узнать мак только в той же зоне каллизии (не дальше ethernet-уровня)..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
fish9370
Дата 22.6.2011, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



хотя, если ты настроишь на маршрутизаторе (шлюзе) proxyarp.. то впринципе можно.. но это не по-дефолту в любом случае..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
slavayo7777
Дата 22.6.2011, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прогер



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

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



Цитата(fish9370 @ 22.6.2011,  15:10)
это узнать невозможно.. ты можешь узнать мак только в той же зоне каллизии (не дальше ethernet-уровня)..


Я наверное неправильно выразился. Мне не нужен мак адресс конечного узла. Мне нужно узнать мак шлюза, чтобы слать через него пакеты на сервер. Моей программе заранее не известно, через что она работает: напрямую с сервером или через шлюз. Ну так вот, не охото добавлять в программу дополнительную настройку шлюза, хочется чтобы прописав маршрут в route, она могла сама понять, через что ей работать. И из настроек в программе был бы только IP сервера. А как до последнего дойдут пакеты, будет решать ОС. 
PM MAIL ICQ   Вверх
fish9370
Дата 22.6.2011, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(slavayo7777 @  22.6.2011,  15:46 Найти цитируемый пост)
напрямую с сервером или через шлюз


это вопрос маршрутизиции, зачем связываться с канальным уровнем? почему не работать на сетевом?


--------------------
undefined
PM MAIL WWW ICQ   Вверх
slavayo7777
Дата 22.6.2011, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прогер



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

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



Цитата(fish9370 @ 22.6.2011,  15:52)
это вопрос маршрутизиции, зачем связываться с канальным уровнем? почему не работать на сетевом?

Как тогда сделать ARP запрос на сетевом уровне?
В общем, задача узнать мак адресс шлюза, чтобы слать пакеты.
PM MAIL ICQ   Вверх
fish9370
Дата 22.6.2011, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(slavayo7777 @  22.6.2011,  16:08 Найти цитируемый пост)
Как тогда сделать ARP запрос на сетевом уровне?


на сетевом уровне ARP'а нет, там есть IP..

Цитата(slavayo7777 @  22.6.2011,  16:08 Найти цитируемый пост)
В общем, задача узнать мак адресс шлюза, чтобы слать пакеты.


вообще слать пакеты ты хочешь куда? на шлюз или на целевую машину за шлюзом?



--------------------
undefined
PM MAIL WWW ICQ   Вверх
fish9370
Дата 22.6.2011, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



я понял, что ты хочешь (мне кажется, что понял)..

ну тогда схема такая:
посылаешь широковещательный пакет типа - у кого ip = xxx.xxx.xxx.xxx, ловишь ответ
если ответ получен, значит машина в твоей подсети и можно слать пакет по тому маку, который получен
        иначе посылаешь широковещательный запрос - у кого ip = ipшлюза (его ip берешь из таблицы маршрутизации), ловишь ответ
                 если ответ получен направляешь пакет по тому маку


--------------------
undefined
PM MAIL WWW ICQ   Вверх
slavayo7777
Дата 23.6.2011, 07:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прогер



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

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



Цитата(fish9370 @ 22.6.2011,  16:55)
я понял, что ты хочешь (мне кажется, что понял)..

ну тогда схема такая:
посылаешь широковещательный пакет типа - у кого ip = xxx.xxx.xxx.xxx, ловишь ответ
если ответ получен, значит машина в твоей подсети и можно слать пакет по тому маку, который получен
        иначе посылаешь широковещательный запрос - у кого ip = ipшлюза (его ip берешь из таблицы маршрутизации), ловишь ответ
                 если ответ получен направляешь пакет по тому маку

Да, да. Именно это я и хочу. Я так это себе и представлял. Ну так весь вопрос был как посмотреть в эту таблицу маршрутизации?
Я думаю лучше сразу смотреть в таблицу маршрутизации и если его там нет, слать широковещательный пакет типа - у кого ip.
Весь нет перерыл и так и не нашел как туда смотреть. Нашел только как добавлять и убирать записи от туда (с помощью ioctl).
PM MAIL ICQ   Вверх
fish9370
Дата 23.6.2011, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(slavayo7777 @  23.6.2011,  07:04 Найти цитируемый пост)
Ну так весь вопрос был как посмотреть в эту таблицу маршрутизации?


/proc/net/route

Код

Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask            MTU     Window  IRTT
eth1    00000000       6964784F       0003   0           0         0         00000000    0          0            0


где, destenation = 00000000, mask = 000000000 - это дефолтный маршрут
gateway соответственно во внутреннем представлении айпишника..



Цитата(slavayo7777 @  23.6.2011,  07:04 Найти цитируемый пост)
Я думаю лучше сразу смотреть в таблицу маршрутизации и если его там нет, слать широковещательный пакет


нет, так лучше не делать, иначе ты не узнаешь, что машина находится не за шлюзом, а рядом.. и такой пакет не дойдет до назначения..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
slavayo7777
Дата 23.6.2011, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прогер



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

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



Цитата(fish9370 @ 23.6.2011,  09:49)

/proc/net/route

Код

Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask            MTU     Window  IRTT
eth1    00000000       6964784F       0003   0           0         0         00000000    0          0            0


где, destenation = 00000000, mask = 000000000 - это дефолтный маршрут
gateway соответственно во внутреннем представлении айпишника..

про шеловскую команду route я знаю  smile 
ты предлагаешь делать шеловский вызов, а потом парсить stdout в программе и от туда выковыривать маршрут?
нет ли другого способа, какими нибудь вызовами достать эту информацию?
идеально было бы что нить типа функции, которая возвращает правильный маршрут, если укажешь ей нужный айпишник.
Цитата(fish9370 @ 23.6.2011,  09:49)

нет, так лучше не делать, иначе ты не узнаешь, что машина находится не за шлюзом, а рядом.. и такой пакет не дойдет до назначения..

ну например:
1. сервер находится в моей подсети без шлюза:
я смотрю в таблицу маршрутизацию и узнаю, что к серверу можно стучаться напрямую,
отправляю ARP, узнаю мак сервера.
2. сервер находится не в моей подсети за шлюзом:
я смотрю в таблицу маршрутизацию и узнаю, что к серверу можно стучаться через шлюз,
отправляю ARP, узнаю мак шлюза.

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

PM MAIL ICQ   Вверх
fish9370
Дата 23.6.2011, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(slavayo7777 @  23.6.2011,  10:18 Найти цитируемый пост)

1. сервер находится в моей подсети без шлюза:я смотрю в таблицу маршрутизацию и узнаю, что к серверу можно стучаться напрямую,отправляю ARP, узнаю мак сервера.
2. сервер находится не в моей подсети за шлюзом:я смотрю в таблицу маршрутизацию и узнаю, что к серверу можно стучаться через шлюз,отправляю ARP, узнаю мак шлюза.


тогда я предлагаю, еще усовершенствовать метод, и смотреть сначала в арп-таблицу (это избавит нас от лишнего широковещательного запроса)

что касается proc, то это не совсем шелл-метод.. хотя я с тобой согласен системный вызов, было бы получше.. поищем..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
xvr
Дата 23.6.2011, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(slavayo7777 @  23.6.2011,  10:18 Найти цитируемый пост)
про шеловскую команду route я знаю

Это не шеловская команда, это файл такой - /proc/net/route. Открываешь его fopen'ом и читаешь построчно

PM MAIL   Вверх
slavayo7777
Дата 23.6.2011, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прогер



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

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



Цитата(xvr @ 23.6.2011,  10:49)
Цитата(slavayo7777 @  23.6.2011,  10:18 Найти цитируемый пост)
про шеловскую команду route я знаю

Это не шеловская команда, это файл такой - /proc/net/route. Открываешь его fopen'ом и читаешь построчно

Вот оно чо!!
Спасибо!!! блин, все так просто оказываеца)) 
если есть конечно путь попроще, типа функции, которая автоматом выдает маршрут, было бы неплохо...
PM MAIL ICQ   Вверх
fish9370
Дата 23.6.2011, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(slavayo7777 @  23.6.2011,  11:00 Найти цитируемый пост)
Спасибо!!! блин, все так просто оказываеца)) 


я думал, ты это понял..

вот еще интерфейс для получения arp-таблицы

/proc/net/arp


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

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

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


 




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


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

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