вопрос программирования сокетов Linux - PullRequest
1 голос
/ 22 октября 2009

Я пытаюсь создать необработанный сокет, который отправляет и получает сообщение с заголовком ip / tcp под linux. Я могу успешно привязать к порту и получить tcp-сообщение (то есть: syn) Тем не менее, сообщение, кажется, обрабатывается ОС, но не мое. Я просто читатель этого (как Wireshark). Мой необработанный сокет привязывается к порту 8888, а затем я пытаюсь подключиться к этому порту через telnet. В wireshark он показывает, что порт 8888 отвечает «первым подтверждением» при получении запроса «syn». В моей программе он показывает, что получает новое сообщение и не отвечает ни на какое сообщение.

Есть ли способ связывания с этим портом? (Не обрабатывайте его)

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

sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);

int tmp = 1;
const int *val = &tmp;
setsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, val, sizeof (tmp));

servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8888);
bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));

//call recv in loop 

Ответы [ 4 ]

4 голосов
/ 28 апреля 2011

Когда ваше ядро ​​получает SYN / ACK от удаленного хоста, оно не находит записи о том, что оно отправило SYN в эту комбинацию IP: PORT (которая была отправлена ​​из вашего необработанного сокета), поэтому оно предполагает, что ошибка и отправляет RST на удаленный хост. Эту проблему можно решить, настроив IP-фильтр, который блокирует весь трафик TCP на этом порту (проверьте страницу справки iptables для этого). Таким образом, вам не нужно программировать в пространстве ядра, и это не повлияет на уже существующие модули TCP ядра.

3 голосов
/ 22 октября 2009

man 7 raw говорит:

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

Я полагаю, это означает, что вы не можете "делать TCP" на сыром сокете без вмешательства со стороны ядра, если ваше ядро ​​не поддерживает TCP - что, конечно, не то, что вам нужно. Для использования сырых сокетов нужны другие протоколы IP, которые ядро ​​ не не обрабатывает, или для специальных приложений, таких как отправка специально сформированных пакетов ICMP.

2 голосов
/ 12 марта 2012

Чтобы получить доступ к необработанным заголовкам, вы не привязываете необработанный сокет к порту. Это не сделано.

Просто напишите сниффер, чтобы «забрать» все входящие пакеты и выяснить «ВАШИ». Это также даст вам доступ ко всему содержимому пакетов и т. Д.

Вот как вы это делаете:

int sock_raw = socket( AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ;

while(true)
{
    saddr_size = sizeof saddr;
    //Receive a packet
    data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , (socklen_t*)&saddr_size);
    if(data_size <0 )
    {
        printf("Recvfrom error , failed to get packets\n");
        return 1;
    }
    //Now process the packet
    ProcessPacket(buffer , data_size);
}

В функции ProcessPacket проанализируйте пакет и посмотрите, принадлежат ли они вашему приложению.

1 голос
/ 22 октября 2009

Edit: Если вы собираетесь программировать необработанные сокеты, отметьте this .

В нем есть несколько примеров того, как отправлять и получать необработанные пакеты.

В случае, если вы хотите использовать SOCK_STREAM и SOCK_SEQPACKET сокеты ориентированного на соединение типа:

Вы должны указать прослушивать его после привязки к указанному адресу: порт.

int connectionQueue = 10;
if ( -1 == listen(sockfd, connectionQueue) )
{
  // Error occurred
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...