реализация Python icmp raw сокета - PullRequest
0 голосов
/ 13 декабря 2011

Я относительно новичок в Python, поэтому, пожалуйста, будьте внимательны ...

Я реализую сервер и клиента через raw_sockets. У меня есть необходимые привилегии.

сейчас сервер я определил так:

host = socket.gethostbyname(socket.gethostname())
address = (host, 22224)
sockSer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
sockSer.bind(address)
sockSer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
packet, addr = sockSer .recvfrom(4096)   # wait for packet from client

Q1) почему я не могу просто набрать: hosts = 'localhost'. если я это сделаю, это не позволит мне написать строку: sockSer.ioctl (socket.SIO_RCVALL, socket.RCVALL_ON). и тогда сервер не получает сообщения моего клиента. только при выполнении gethostbyname (socket.gethostname ()) я получаю 192.168.1.101 и тогда это работает.

в другом классе: клиент сокет:

host = socket.gethostbyname(socket.gethostname())
address = (host, 22224)
sockCli = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)

Q2) мне также нужно набрать: sockCli.ioctl (socket.SIO_RCVALL, socket.RCVALL_ON) или, может быть, sockCli.connect (адрес)? Кажется, что это работает без команды подключения. для клиентского сокета?

сейчас проблемы возникают, когда я делаю следующее: 1) отправить пакет с клиента на сервер:

header=...
payload='a'
sockCli.sendto(header + payload, address)

2) получить пакет на сервере и отправить обратно клиенту:

while(true):
    data, addr = sockSer.recvfrom(4096)
    header2=...
    payload2='b'
    sockSer.sendto(header2 + payload2, addr)

Теперь мой важный вопрос: Q3) сервер отправил клиенту только 1 пакет с полезной нагрузкой 'b'. что происходит, мой клиент фактически получает 2 пакета в цикле while: первый пакет - это то, что клиент отправляет на сервер , а другой пакет - то, что клиент получает от сервера. следовательно, мой вывод «ab» вместо просто «b» почему это происходит ???

ПРИМЕЧАНИЕ: я не набрал весь код, но я думаю, что мой синтаксис, синтаксический анализ, состав заголовка и т. Д. Верны. есть ли очевидная проблема в моем коде? при необходимости я загружу весь код.

спасибо

Ответы [ 2 ]

0 голосов
/ 18 марта 2014

Q1: я смог привязаться к localhost и вызвать IOCTL с обоими параметрами просто отлично. Предполагая, что ваш клиент также работает в той же системе, убедитесь, что клиент отправляет «localhost», иначе ваш сервер никогда не получит пакеты. Если ваш клиент находится в другой системе, очевидно, что ваш сервер никогда не получит пакеты.

Q2: вам не нужен IOCTL для отправки пакета. Просто отправьте его через sendto ().

В3: Причина, по которой вы видите два ответа, заключается в том, что ядро ​​также обрабатывает эхо-запрос, в дополнение к вашему собственному коду пользовательского пространства.

Несмотря на то, что вы можете использовать ICMP для произвольной передачи сообщений, как кто-то еще заметил, это не его предназначение. Вы можете обнаружить, что ваша часть данных обрезана в ответах на сообщения. Например, при отправке эхо-запросов ваш ответ, скорее всего, будет содержать все, что вы отправили; однако ответ типа 3 с кодом 3 может содержать не ваши данные, а только первые 8 байтов заголовка ICMP.

0 голосов
/ 03 сентября 2013

Я тоже это получил. мое решение заключается в добавлении судьи в код получения, например, если я отправляю пакет Ping, поэтому мне нужен только ECHO Reply (введите 0 code 0), я пишу

if type != 0:
     continue

и вы также можете написать как if addr == my_ip: продолжение

Кажется, не имеет плавного решения

...