RAW icmp socket: как правильно ответить - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь создать простой эхо-запрос icmp, но не могу получить хороший ответ.

Я пытался отправить запрос с сокетом RAW и с протоколом IPPROTO_ICMP или IPPROTO_RAW, и я получаю разные результаты, от отсутствия ответа на все это до ответа с помощью icmp типа 69 или типа 8.

ctx.socket_fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); // OR IPPROTO_ICMP
if (ctx.socket_fd == -1)
{
    perror("socket:");
    exit(EXIT_FAILURE);
}
int on = 1;
setsockopt(ctx.socket_fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)); // IF IPPROTO_ICMP and struct ip not sent

Первая инициализация:

    struct s_ping       packet = {
    .ip = { // == struct ip if IPPROTO_RAW or if setsockoptionned IP_HDRINCL
        .ip_hl = BYTE_TO_WORD(sizeof(struct iphdr)),
        .ip_v = 4,
        /* tos */
        .ip_len = htons(sizeof(packet)),
        .ip_id = (u_short)getpid(),
        .ip_off = htons(IP_DF),
        .ip_ttl = TTL,
        .ip_p = IPPROTO_ICMP,
    },
    .icmp = { // == struct icmp
        .icmp_type = ICMP_ECHO,
        .icmp_code = 0,
        .icmp_id = (u_int16_t)getpid(),
    },
};
memset(&packet.icmp.icmp_data, 0, DATA_LEN);
inet_pton(AF_INET, "0.0.0.0", &packet.ip.ip_src.s_addr);
inet_pton(AF_INET, ctx->addr /* == "127.0.0.1", &packet.ip.ip_dst.s_addr);

А затем последние данные ICMP:

packet.icmp.icmp_seq = htons(sequence);
packet.icmp.icmp_cksum = 0;
packet.icmp.icmp_cksum = htons(checksum(&packet, sizeof(packet)));

Для IPPROTO_RAW данные отправляются, но ответа на них нет. Для IPPROTO_ICMP с HDRINCL у меня есть ответ с ECHO icmp (тип 8), а не echo_reply (тип 1) Для IPPROTO_ICMP без HDRINCL (и везде с комментариями struct ip) в качестве ответа используется icmp 69.

Когда я впервые попробовал эти «конфигурации», я подумал, что они не вызовут никакой разницы, но это так. Почему?

Кто-нибудь видит, что не так и как я могу исправить свои проблемы? Если да, то как?

Большое спасибо

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