Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
1

Принять IP пакет

21.08.2017, 11:58. Показов 2956. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день.

Хочу сделать аналог сниффера (типа wireshark) и принимать полный IP пакет, а не только данные.

Подскажите, пожалуйста, можно ли это сделать на уровне сокетов?
Либо какими-то стандартными способами, без установки дополнительных библиотек.

В интернете нашел примеры с библиотекой pcap.h, но как я понял это не стандартная, и чтобы с ней работать - нужно ее отдельно скачать и поставить.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.08.2017, 11:58
Ответы с готовыми решениями:

Отправить/принять пакет UDP
Требуется решить такую задачу: Создать приложение Win32 с оконным интерфейсом. По нажатию кнопки...

Нужно принять пакет на сервере
С помощью VBS отправляется пакет на заданный URL: Set oHTTP =...

Программно сформировать и отправить IP пакет, принять ICMP сообщение
Необходимо (С, C++, Perl, Assembler или др) сформировать заголовок IP пакета. Данные: длина...

Не получается принять TCP/IP пакет более 2048 байт. Visual C++.
Использую MFC. Имеется UDP-сокет (CAsyncSocket). При приходе пакета длиной более 2048 байт функция...

17
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
21.08.2017, 12:23 2
Leardjiny,
На уровне сокетов думаю можно, посмотрите в сторону SOCK_RAW,
https://habrahabr.ru/post/164901/
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
21.08.2017, 12:57  [ТС] 3
Undisputed, Спасибо. Вроде похоже как раз на то, что нужно - попробую сделать.

Я правильно понимаю, что если я таким образом перехвачу данные, а потом запишу их в файл, то потом смогу их проиграть к примеру в wireshark, и получу то же самое, что если бы записывал им?

И второй вопрос, можно потом как-то сделать, чтобы данные можно было с другого сокета обычным способом уже перехватить? Или таким образом уже не выйдет? (Задачи сделать таким образом нет, поэтому способ в любом случае подойдет, но просто чтобы на будущее знать)
0
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
21.08.2017, 13:27 4
Leardjiny,
Whireshark-ом не пользовался, но если там есть возможность импортирования данных и вы будете соблюдать подходящий для этой операции формат, то полагаю проблем быть не должно...

Не встречал программ с двойной прослушкой в пределах одного процесса. Это может как работать, так и не работать по самым разным причинам, поэтому затрудняюсь что либо ответить по этому поводу...
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
21.08.2017, 13:31  [ТС] 5
Undisputed, Хорошо, значит на эту тему надо почитать.

А фильтры, по портам или IP там настроить я так понимаю не выйдет в таком формате?
Придется уже после ловли пакета лезть в заголовок и смотреть данные источника?
0
Любитель чаепитий
3743 / 1799 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
21.08.2017, 13:53 6
http://www.binarytides.com/pac... e-c-linux/
http://www.binarytides.com/pac... g-winsock/
Цитата Сообщение от Leardjiny Посмотреть сообщение
Я правильно понимаю, что если я таким образом перехвачу данные, а потом запишу их в файл, то потом смогу их проиграть к примеру в wireshark, и получу то же самое, что если бы записывал им?
только если в правильном формате запишите.
https://wiki.wireshark.org/Dev... FileFormat
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
21.08.2017, 13:56  [ТС] 7
GbaLog-, Спасибо. Для UDP я так понимаю надо IPPROTO_UDP поставить и все?
Либо IPPROTO_IP как в первом варианте?
0
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
21.08.2017, 14:01 8
Leardjiny,
Я думаю порты и айпи надо фильтровать после принятия пакета, других способов не знаю...
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
21.08.2017, 14:05  [ТС] 9
Undisputed, Я тоже так думаю, на уровне сокетов не могу настроек найти. А libpcap не хочу ставить
0
Любитель чаепитий
3743 / 1799 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
21.08.2017, 14:09 10
Цитата Сообщение от Leardjiny Посмотреть сообщение
Для UDP я так понимаю надо IPPROTO_UDP поставить и все?
Либо IPPROTO_IP как в первом варианте?
да.
Цитата Сообщение от Leardjiny Посмотреть сообщение
на уровне сокетов не могу настроек найти.
как вы себе это представляете?
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
21.08.2017, 14:13  [ТС] 11
GbaLog-, ну для pcap есть функции фильтрации.

Либо как для обычных данных указать порт, затем bind сделать или что-то подобное.

Но это не вариант - т.к. даже если можно, то привяжет к одному порту, а не к нескольким.
0
Любитель чаепитий
3743 / 1799 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
21.08.2017, 15:42 12
Цитата Сообщение от Leardjiny Посмотреть сообщение
ну для pcap есть функции фильтрации.
libpcap сама реализует их, их нет из коробки.
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
21.08.2017, 15:47  [ТС] 13
GbaLog-, понятно. Тогда сделаю фильтрацию вручную, если понадобится. Для начала так попробую сделать
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
29.08.2017, 12:16  [ТС] 14
GbaLog-, Сделал таким образом:
Поставил IPPROTO_UDP (пробовал IPPROTO_RAW, но при чтении выдавало ошибку).

Открытие порта:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
OpenPort()
{
    ClosePort();
    m_sock = -1;
    m_connection_state = false;
 
    double current_time = GetTickCount();
    if ( (current_time - m_last_connect_try) < m_read_timeout )
    {
        usleep(10000);  //мкс
        return false;
    }
 
 
 
    if ((m_sock = socket(AF_INET, SOCK_RAW , IPPROTO_UDP)) < 0) {
        return false;
    }
 
    timeval timeout = {0, 0};
    timeout.tv_usec = 0;
    timeout.tv_sec = (int)((double)m_read_timeout/1000);
 
    if (setsockopt(m_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0);{
 
    }
 
    int buffsize = MAX_UDP_BUFFER;
    if ( setsockopt(m_sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<const char*>(&buffsize), sizeof(buffsize)) < 0 )
    {
    }  
 
    m_connection_state = true;
    return true;
}
Чтение кадра:
C++
1
2
3
4
5
6
7
8
9
10
struct sockaddr_in echoclient;
    char buffer[MAX_UDP_BUFFER];
    unsigned int echolen, clientlen;
    clientlen = sizeof(echoclient);
    int nNumberOfBytesReaded = -1;
    if (m_connection_state == true )
    {
        nNumberOfBytesReaded = recvfrom(m_sock, buffer, MAX_UDP_BUFFER, 0,
                                (struct sockaddr *) &echoclient, &clientlen);
    }
Все читает, но записав в файл - вижу некоторые проблемы.
Wireshark отказывается читать. Когда сравниваю то, что видно в wireshark и в моем файле, то вижу что не хватает 14 байт, которые выглядят так: "ff ff ff ff ff ff 0a 0b 0c 0d 0e 0f 08 00"

Подскажите, что я делаю не так? И как их правильно считывать?
0
Любитель чаепитий
3743 / 1799 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
29.08.2017, 13:51 15
Цитата Сообщение от Leardjiny Посмотреть сообщение
то вижу что не хватает 14 байт
глобальный заголовок в файл пишете?
Цитата Сообщение от Leardjiny Посмотреть сообщение
(m_sock = socket(AF_INET, SOCK_RAW , IPPROTO_UDP))
может всё-таки (m_sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP))?
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
29.08.2017, 15:22  [ТС] 16
GbaLog-, я все что возвращает recvfrom - пишу в файл. Ничего с этим не делая и не добавляя.

По поводу IPPROTO_IP - я пробовал делать так. В контексте той же функции , что выше привел. Менял только эту строку.
В этом случае у меня почему-то не открывался порт (либо создание совета, либо установка опций не проходят)

Добавлено через 1 час 0 минут
GbaLog-,
Цитата Сообщение от GbaLog- Посмотреть сообщение
может всё-таки (m_sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP))?
Попробовал сделать так:
(m_sock = socket(AF_INET, SOCK_RAW , IPPROTO_IP))
не хочет создавать сокет

и так:
(m_sock = socket(AF_INET, SOCK_RAW , IPPROTO_RAW))
сокет открывает, но не работает recvfrom
0
Любитель чаепитий
3743 / 1799 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
29.08.2017, 16:17 17
Цитата Сообщение от Leardjiny Посмотреть сообщение
я все что возвращает recvfrom - пишу в файл. Ничего с этим не делая и не добавляя.
в .pcap-файле должен быть заголовок.
чтобы Wireshark понял, что это pcap-файл, а не текстовый.
я вам ссылку скидывал, вы читали?
https://wiki.wireshark.org/Dev... bal_Header
Цитата Сообщение от Leardjiny Посмотреть сообщение
Ничего с этим не делая и не добавляя.
так нельзя, к каждому пакету должен писаться хедер в таком формате:
https://wiki.wireshark.org/Dev... .29_Header
Цитата Сообщение от Leardjiny Посмотреть сообщение
не хочет создавать сокет
errno(Linux)/WSAGetLastError(Windows) что говорят?
0
2 / 2 / 0
Регистрация: 22.09.2013
Сообщений: 219
29.08.2017, 16:37  [ТС] 18
GbaLog-, а, я понял о чем Вы. Да, заголовок pcap файла я добавлю, он же не из сети берется вроде.
У меня само содержимое неполное.

Я наткнулся в интернете, что IPPROTO_RAW используется только для отправки, потому recvfrom не работает. Возможно конечно это не так.
Источник вот: https://www.experts-exchange.c... ckets.html

Там же наткнулся, на следующую инициализацию сокета:
C++
1
m_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
Это для приема всего что идет. Я у себя сделал так:
C++
1
m_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))
Вроде бы сейчас содержимое совпадает с тем что я вижу в Wireshark.

Теперь осталось разобраться с форматом pcap заголовков и добавить их перед данными.
0
29.08.2017, 16:37
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.08.2017, 16:37
Помогаю со студенческими работами здесь

Как принять и отправить один и тот же пакет. Перенаправление пакетов
Всем привет. Есть такая цель. Нужно принимать ВЕСЬ трафик, который приходит на интерфейс и не...

Защита с отсечением внешнего трафика. Блокирование работы программы при попытке принять пакет из внешней сети
Защита с отсечением внешнего трафика. Блокирование работы программы при попытке принять пакет из...

Почему если отправить пакет UDP и конечного адресата в сети не существует, то пакет не отправляется?
Добрый день! Вопрос для расширения кругозора. Мониторю свой трафик с помощью WireShark и...

Как определить, какой из подсетей принадлежит пакет IP-пакет?
То есть у Олиферов это всё подробно расписано. Если маршрутизация сделана на основе масок, то надо...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru