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

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

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

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

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

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

В интернете нашел примеры с библиотекой pcap.h, но как я понял это не стандартная, и чтобы с ней работать - нужно ее отдельно скачать и поставить.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.08.2017, 11:58
Ответы с готовыми решениями:

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

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

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

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
Любитель чаепитий
 Аватар для GbaLog-
3744 / 1800 / 566
Регистрация: 24.08.2014
Сообщений: 6,018
Записей в блоге: 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
Любитель чаепитий
 Аватар для GbaLog-
3744 / 1800 / 566
Регистрация: 24.08.2014
Сообщений: 6,018
Записей в блоге: 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
Любитель чаепитий
 Аватар для GbaLog-
3744 / 1800 / 566
Регистрация: 24.08.2014
Сообщений: 6,018
Записей в блоге: 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
Любитель чаепитий
 Аватар для GbaLog-
3744 / 1800 / 566
Регистрация: 24.08.2014
Сообщений: 6,018
Записей в блоге: 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
Любитель чаепитий
 Аватар для GbaLog-
3744 / 1800 / 566
Регистрация: 24.08.2014
Сообщений: 6,018
Записей в блоге: 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.08.2017, 16:37
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему

Редактор формул (кликните на картинку в правом углу, чтобы закрыть)
Новые блоги и статьи
Что нового в C# 14
UnmanagedCoder 10.03.2025
Предстоящая версия C# 14 обещает принести изменения, которые сделают разработку еще более приятной и эффективной. Что стоит отметить, так это влияние сообщества разработчиков на формирование новых. . .
Формулы поворота
Igor3D 10.03.2025
Добрый день Тема Эти формулы приводятся во множестве тьюториалов, часто под видом "матрица вращения на плоскости". x' = x * cos(a) - y * sin(a) y' = y * cos(a) + x * sin(a) Как бы Вы их. . .
Что нового в .NET 10
UnmanagedCoder 10.03.2025
. NET 10 выходит как релиз с длительной поддержкой (LTS), включающей три года обновлений. В этом обновлении Microsoft сфокусировались на нескольких направлениях: производительность, оптимизация. . .
Отложенное высвобождение, RCU и Hazard Pointer в C++26
NullReferenced 09.03.2025
Многопоточное программирование стало важной частью современной разработки. Когда несколько потоков одновременно работают с общими данными, возникает целый ряд проблем, связанных с синхронизацией и. . .
Неблокирующийся стек на C++26
NullReferenced 09.03.2025
Традиционные способы синхронизации в многопоточном программировании — мьютексы, семафоры, условные переменные — часто превращаются в узкое место в плане производительности. При этом неблокирующиеся. . .
Обработка строк в C++26: Новые возможности string и string_view
NullReferenced 09.03.2025
Новый стандарт C++26 предлагает много улучшений для работы с привычными string и относительно новыми string_view. string_view - это невладеющая ссылка на последовательность символов, появившаяся в. . .
Мой первый аддон для Blender 3D, с помощью нейронки (не зная даже азов пайтона, но это не значит что так и с остальным).
Hrethgir 09.03.2025
Потратил весь день. Пол-дня мне хватило, чтобы понять что с версией с 14B мне не одолеть написание функционального кода, на языке с которым я вообще никак не знаком - пайтон. Версия 22B от другого. . .
Einstein@Home сегодня исполняется двадцать лет!
Programma_Boinc 09.03.2025
Einstein@Home сегодня исполняется двадцать лет! Отправлено 19 февраля 2025 года в 17:20:21 UTC Я хочу поздравить всех наших волонтеров, разработчиков и ученых из Einstein@Home. Мы официально. . .
Заполнители и расширенный набор символов в C++26
NullReferenced 09.03.2025
C++26 представляет два важных обновления: заполнители и расширенный набор символов. Заполнители (placeholders) решают давнюю проблему лаконичности кода в шаблонных выражениях и лямбда-функциях. Они. . .
Контракты в C++26
NullReferenced 09.03.2025
Контракты – это механизм, позволяющий указывать предусловия, постусловия и инварианты для функций в коде. Эта функциональность должна была стать частью C++20, но была исключена на встрече комитета. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru