2008-09-21 7 views
15

Хорошо, я понимаю, что эта ситуация несколько необычна, но мне нужно установить TCP-соединение (трехстороннее рукопожатие), используя только сырые сокеты (в C, в Linux) - т.е. мне нужно самостоятельно создавайте заголовки IP и заголовки TCP. Я пишу сервер (поэтому я должен сначала ответить на входящий пакет SYN), и по какой-то причине я не могу понять, что это правильно. Да, я понимаю, что SOCK_STREAM справится с этим для меня, но по причинам, которые я не хочу вдаваться в это, это не вариант.TCP-соединение с гнездом SOCK_RAW

В учебниках, которые я нашел в Интернете, используя исходные сокеты, все описывают, как создать SYN-флудер, но это несколько проще, чем фактически устанавливать TCP-соединение, поскольку вам не нужно создавать ответ на основе оригинала пакет. Я получил примеры сценариев SYN, и я могу читать входящий SYN-пакет просто отлично от сырого сокета, но мне все еще не удается создать корректный ответ SYN/ACK на входящий SYN от клиента.

Итак, кто-нибудь знает хороший учебник по использованию сырых сокетов, который выходит за рамки создания SYN-флудера, или у кого-нибудь есть код, который мог бы это сделать (используя SOCK_RAW, а не SOCK_STREAM)? Я буду очень признателен.


MarkR абсолютно правы - проблема в том, что ядро ​​посылает пакеты сброса в ответ на начальный пакет, потому что он считает, что порт закрыт. Ядро отбивает меня от ответа, и соединение умирает. Я использовал tcpdump для мониторинга соединения уже - я должен был быть более наблюдательным и заметил, что были ответы TWO, один из которых был сбросом, который искажал вещи, а также ответ, который моя программа создала. D'OH!

Решение, которое, как представляется, лучше всего работает с использованием правила iptables, как это было предложено MarkR, для блокировки исходящих пакетов. Однако есть более простой способ сделать это, чем использовать параметр метки, как это было предложено. Я просто сопоставляю, установлен ли флаг сброса TCP. В ходе обычного подключения это вряд ли понадобится, и это не имеет большого значения для моего приложения, если я блокирую все исходящие пакеты сброса из используемого порта. Это эффективно блокирует нежелательный ответ ядра, но не мои собственные пакеты. Если порт моя программа прослушивает 9999, то правило Iptables выглядит следующим образом:

iptables -t filter -I OUTPUT -p tcp --sport 9999 --tcp-flags RST RST -j DROP 

ответ

1

У меня нет учебника, но недавно я использовал Wireshark для хорошего эффекта для отладки некоторых сырых сокетов программирования я делал , Если вы захватите пакеты, которые вы отправляете, wirehark сделает хорошую работу, чтобы показать вам, если они неверные. Это полезно для сравнения с обычным подключением.

2

Я не могу помочь вам в любых учебниках.

Но я могу дать вам несколько советов по инструментам, которые можно использовать для помощи в отладке.

Прежде всего, поскольку bmdhacks предложил, сделайте себе копию wireshark (или tcpdump - но wirehark проще в использовании). Захватите хорошее рукопожатие. Убедитесь, что вы сохранили это.

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

Далее, сделайте себе копию tcpreplay. Это также должно включать инструмент под названием «tcprewrite». tcprewrite позволит вам разбить ранее сохраненные файлы захвата на два - по одному для каждой стороны рукопожатия. Затем вы можете использовать tcpreplay для воспроизведения одной стороны рукопожатия, чтобы у вас был последовательный набор пакетов для воспроизведения.

Затем вы используете wirehark (снова), чтобы проверить свои ответы.

9

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

Одна из проблем, с которой вы столкнетесь, заключается в том, что ядро ​​будет отправлять (в целом отрицательные, бесполезные) ответы на входящие пакеты. Это приведет к испорчению любого сообщения, которое вы пытаетесь инициировать.

Один из способов избежать этого - использовать IP-адрес и интерфейс, в которых ядро ​​не имеет своего собственного стека IP, что прекрасно, но вам нужно будет иметь дело с файлом link-layer (в частности, arp) самостоятельно. Для этого потребуется сокет ниже IPPROTO_IP, SOCK_RAW - вам нужен пакетный сокет (я думаю).

Может быть также возможно заблокировать ответы ядра с помощью правила iptables, но я скорее подозреваю, что правила будут применяться и к вашим собственным пакетам так или иначе, если только вам не удастся заставить их обращаться по-разному (возможно, используя сетевой фильтр "метка" для ваших собственных пакетов?)

Читайте человек страницы

гнездо (7) ф (7) пакет (7)

, которые объясняют о различных вариантах и ​​IOCTLs, которые применяются к типам сокетов.

Конечно, вам понадобится такой инструмент, как Wireshark, чтобы проверить, что происходит. Для тестирования вам понадобятся несколько машин, я рекомендую использовать vmware (или подобное), чтобы уменьшить количество требуемого оборудования.

Извините, я не могу рекомендовать конкретный учебник.

Удачи.

0

Существуют структуры для заголовков IP и TCP, объявленных в netinet/ip.h & netinet/tcp.h соответственно. Вы можете посмотреть другие заголовки в этом каталоге для дополнительных макросов &, которые могут быть полезны.

Вы отправляете пакет с установленным флагом SYN и случайным порядковым номером (x). Вы должны получить SYN + ACK с другой стороны. Этот пакет будет иметь номер подтверждения (y), который указывает следующий порядковый номер, который ожидает другая сторона, а также другой порядковый номер (z). Вы отправляете обратно пакет ACK с порядковым номером x + 1 и номером z + 1 для завершения соединения.

Вам также необходимо убедиться, что вы подсчитали соответствующие контрольные суммы TCP/IP. & заполнить оставшуюся часть заголовка для отправляемых вами пакетов. Кроме того, не забывайте о таких вещах, как хост & сетевой порядок байтов.

TCP определен в RFC 793, доступно здесь: http://www.faqs.org/rfcs/rfc793.html

0

В зависимости от того, что вы пытаетесь сделать это, возможно, будет легче получить существующее программное обеспечение для обработки TCP рукопожатия для вас.

Один IP-стек с открытым исходным кодом - lwIP (http://savannah.nongnu.org/projects/lwip/), который обеспечивает полный стек tcp/ip. Очень легко запустить его в пользовательском режиме, используя SOCK_RAW или pcap.

0

Если вы используете сырые сокеты, если вы отправляете с использованием другого исходного MAC-адреса на фактический, то Linux проигнорирует пакет ответа и не отправит первый.

+0

Я знаю, что это вопрос 4 года, но ваше предложение выглядит довольно интересно, поэтому я решил попросить вас разъяснить. Возникает вопрос: есть ли какие-либо проблемы с маршрутизатором при передаче пакета ответа на определенную машину с MAC-адресом неправильного устройства? Будет ли пакет фильтроваться через брандмауэр или антивирус? – 2016-01-10 10:44:58

Смежные вопросы