я не знаю, но предполагаю, что аналогично пингу. то есть где в пинге открываем сокет: socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) в случае с tcp надо так: socket(AF_INET, SOCK_RAW, IPPROTO_TCP) в этом случае система сама собирает ip пакет, а в ту часть заголовка ip заголовка, где определяется вложенный протокол, ставится номер протокола, определнный константой IPPROTO_TCP или IPPROTO_ICMP или любой другой константой из <netinet/in.h> далее мы можем на самом деле послать любой мусор в том месте, где должен быть tcp заголовок с данными, а можем сами сделать нужный нам заголовок и отправить его вызовом: sendto(conn->send_sock, send_frame, sizeof(struct s_frame), 0, (struct sockaddr *)&conn-> send_sockaddr, sizeof(struct sockaddr_in)) в моем пинге делается пакет icvp: struct s_frame { struct icmphdr _icmphdr; char payload[LOAD_SIZ]; }; ... ... send_frame = malloc(sizeof(struct s_frame)); if (!send_frame) { perror("malloc: "); goto end; } ... ... send_frame->_icmphdr.type = ICMP_ECHO; send_frame->_icmphdr.code = ICMP_ECHOREPLY; send_frame->_icmphdr.un.echo.id = rand() % (USHRT_MAX + 1); send_frame->_icmphdr.un.echo.sequence = htons(1); ... ... send_frame->_icmphdr.checksum = 0; send_frame->_icmphdr.checksum = in_cksum((unsigned short *)send_frame, sizeof(struct s_frame)); и далее по коду идет вызов sendto определение icmphdr находится в <netinet/ip_icmp.h> найти структуру tcp заголовка можно тут: <netinet/tcp.h> struct tcphdr надо так же инициализировать необходимый для заголовка tcp буфер памяти, посмотреть по rfc или в википедии, каким должен быть пакет syn, можно вообще в wireshark посмотреть и заполнить все необходимые поля буфера, потом отправить в сеть этот буфер и можно посмотреть опять же в wireshark, если на пакет придет какой-то ответ, тоо значит пакет собран верно, если ничего не придет, значит не верно. с ipv6 все сложнее, я сам толком не разобрался, как там надо делать, пинг у меня так и не получилось послать. Сейчас как-то не до того, может на выходных напишу рабочую программу, но не уверен. 10.12.14, Alex Naumov<alexander_naumov@opensuse.org> написал(а):
2014-11-24 11:43 GMT+01:00 Ivan Riabtsov <ivriabtsov@gmail.com>:
точно так же, как в случае с программой ping, надо открыть пару raw сокетов, "смастерить" tcp syn пакет, только при открытии сокета надо указывать IPPROTO_TCP и нужно привязывать сокет к определенному tcp порту, ответ распарсить так же, как ответ на пинг.
Как именно смастерить tcp syn? Был бы тебе признателен за пример.