Подтвердить что ты не робот

Как создать пакеты RAW TCP/IP на С++?

Я начинаю программист на С++/администратор сети, но я полагаю, что могу научиться делать это, если кто-то указывает мне в правильном направлении. Большинство учебных пособий демонстрируются с использованием старого кода, который по какой-то причине больше не работает.

Поскольку я нахожусь в Linux, все, что мне нужно, - это объяснение того, как писать сырые сокеты Berkeley. Может кто-нибудь дать мне быстрый прогон?

4b9b3361

Ответ 1

Начните с чтения Руководство Beej по программированию сокетов. Это ускорит процесс написания сетевого кода. После этого вы сможете получать все больше и больше информации от чтения man-страниц.

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

Ответ 2

Для начала было бы полезно, если бы вы уточнили, что вы подразумеваете под "raw". Традиционно это означает, что вы хотите создать весь заголовок уровня 4 (заголовок TCP/UDP/ICMP...) и, возможно, часть заголовка IP по своему усмотрению. Для этого вам понадобится больше, чем урок beej, о котором уже упоминалось мною. В этом случае вам нужны сырые IP-сокеты, полученные с помощью аргумента SOCK_RAW в вашем вызове в сокет (см. http://mixter.void.ru/rawip.html для некоторых основ).

Если вам действительно нужно только установить TCP-соединение с каким-то удаленным хостом, таким как порт 80 на stackoverflow.com, то вам, вероятно, не нужны "сырые" сокеты, и руководство beej хорошо послужит вам.

Для получения авторитетной справки по этому вопросу вы должны действительно подобрать Unix Network Programming, том 1: Сетевой интерфейс Sockets (3-е издание) от Stevens и др.

Ответ 3

Для клиентской стороны TCP:

Используйте gethostbyname для поиска имени DNS для IP, он вернет структуру хоста. Позвольте называть этот хост возвращаемого значения.

hostent *host = gethostbyname(HOSTNAME_CSTR);

Заполните структуру адреса сокета:

sockaddr_in sock;
sock.sin_family = AF_INET;
sock.sin_port = htons(REMOTE_PORT);
sock.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;

Создайте сокет и вызовите connect:

s = socket(AF_INET, SOCK_STREAM, 0); 
connect(s, (struct sockaddr *)&sock, sizeof(sock))

Для сервера TCP:

Настройка сокета

Свяжите свой адрес с этим сокетом с помощью bind.

Начните слушать этот сокет с помощью прослушивания

Принять вызов, чтобы получить подключенного клиента. < - в этот момент вы создаете новый поток для обработки соединения, пока вы принимаете другой вызов, чтобы получить следующий подключенный клиент.

Общая связь:

Используйте send и recv для чтения и записи между клиентом и сервером.

Пример исходного кода сокетов BSD:

Вы можете найти хороший пример этого кода в wikipedia.

Дальнейшее чтение:

Я очень рекомендую эту книгу и этот онлайн-учебник:

alt text

4:

Ответ 4

Хорошим местом для начала было бы использовать Asio, который является отличной кросс-платформенной (включая Linux) библиотекой для сетевой связи.

Ответ 5

Вы делаете это точно так же, как и в обычном C, в стандартной библиотеке не существует специального способа С++.

Учебник, который я использовал для изучения этого, был http://beej.us/guide/bgnet/. Это был лучший учебник, который я нашел после осмотра, он дал ясные примеры и хорошие объяснения всех функций, которые он описывает.

Ответ 6

Я развиваю libtins за последний год. Это высокоуровневая библиотека обработки пакетов и нюхания на С++.

Если вы не хотите изобретать колесо и внедрять все внутренние протоколы, я бы рекомендовал вам использовать библиотеку более высокого уровня, которая уже делает это для вас.

Ответ 7

Есть много ссылок на это (конечно, книга Стивенса приходит на ум), но я нашел Beej guide, чтобы быть невероятно полезно для начала работы. Это достаточно мясисто, что вы можете понять, что на самом деле происходит, но это достаточно просто, что вам не требуется несколько дней, чтобы написать "hello world" udp client/server.

Ответ 8

легко:

#include <sys/socket.h>
#include <sys/types.h>

int socket(int protocolFamily, int Type, int Protocol)
// returns a socket descriptor

int bind(int socketDescriptor, struct sockaddr* localAddress, unsigned int addressLength)
// returns 0 

... и т.д..

все это в sys/socket.h

Ответ 9

Плакат, пожалуйста, уточните свой вопрос.

Почти все ответы, похоже, думают, что вы запрашиваете учебник по сокетам; Я прочитал ваш вопрос, чтобы иметь в виду, что вам нужно создать сырой сокет, способный отправлять произвольные IP-пакеты. Как я уже сказал в своем предыдущем ответе, некоторые ОС ограничивают использование сырых сокетов.

http://linux.die.net/man/7/raw "Только для процессов с эффективным идентификатором пользователя 0 или CAP_NET_RAW разрешено открывать сырые сокеты".

Ответ 10

Прочитайте Unix Network Programming от Ричарда Стивенса. Это необходимо. Он объясняет, как все это работает, дает вам код и даже дает вам вспомогательные методы. Возможно, вы захотите проверить некоторые из его других книг. Расширенное программирование в Unix Enviernment является обязательным условием для программирования нижнего уровня в Unix. Я больше ничего не делаю в стеке Unix, и stuf из этих книг по-прежнему помогает мне кодировать.

Ответ 11

Libpcap позволит вам создавать полные пакеты (от уровня 2 до уровня 7) и отправлять их по кабелю. Как весело, как это звучит, есть некоторые предостережения с ним. Вам нужно создать все соответствующие заголовки и выполнить все контрольные суммы. Libnet может помочь с этим.

Если вы хотите выйти из пула программирования на С++, для python существует scapy. Это делает тривиальным создание и передачу пакетов TCP/IP.