Ниже приведен собственный код утилиты ICMP, который я использую в своем приложении для Android для целей проверки связи.
Я решил добавить функцию трассировки маршрута и попытался использовать тот же код с ttl=1. , ttl=2 и так далее.
Однако на моем реальном устройстве IP-адрес ответа из этого кода для ttl=1, ttl=2, ttl=3 всегда равен 123.0.0.0.
Чтобы проверить правильно это или нет - взял другое приложение "ping" из Play Market, поставил ttl=1, ttl=2, ttl=3 и для каждого из них оно показывает законный ответный IP-адрес, например 192.168.0.1, 100.101.101.2 и т. д.
Знаете ли вы причину? что не так с этим кодом?
#pragma clang diagnostic push
#pragma ide diagnostic ignored "cppcoreguidelines-avoid-magic-numbers"
#include "icmp_util.h"
#include
#include
#include
#include
#include
#include
#include
#include
std::map addr_map;
#pragma clang diagnostic push
#pragma ide diagnostic ignored "hicpp-signed-bitwise"
#pragma ide diagnostic ignored "readability-magic-numbers"
u_short checksum(u_short *buf, int len) {
u_long sum = 0;
while (len > 1) {
sum += *buf++;
len -= sizeof(u_short);
}
if (len)
sum += *(u_char *) buf;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (u_short) (~sum);
}
#pragma clang diagnostic pop
int create_icmp_socket(const char *host, int timeout_ms, int ttl) {
struct timeval t_out;
t_out.tv_sec = MS_TO_SEC(timeout_ms);
t_out.tv_usec = MS_TO_USEC(timeout_ms);
struct sockaddr_in addr;
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); // NOLINT(android-cloexec-socket)
if (sock < 0) {
return SOCKET_ERROR;
}
if (setsockopt(sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)) != 0) {
close(sock);
return SOCKET_ERROR;
}
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *) &t_out, sizeof(t_out)) != 0) {
close(sock);
return SOCKET_ERROR;
}
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
if (inet_pton(AF_INET, host, &(addr.sin_addr)) < 0) {
close(sock);
return SOCKET_ERROR;
}
addr_map[sock] = addr;
return sock;
}
void close_icmp_socket(int sock) {
shutdown(sock, SHUT_RDWR);
close(sock);
addr_map.erase(sock);
}
#pragma clang diagnostic push
#pragma ide diagnostic ignored "misc-non-private-member-variables-in-classes"
int ping(int sock, u_short sequence, const int size, jbyte *pattern, jsize pattern_len, char *ip_address) {
char packet_data[size + sizeof(icmphdr)];
struct icmphdr *hdr = (struct icmphdr *) &packet_data;
struct timespec time_start, time_end;
struct sockaddr_in addr = addr_map[sock], r_addr;
socklen_t addr_len;
bzero(packet_data, sizeof(packet_data));
hdr->type = ICMP_ECHO;
hdr->un.echo.id = htons(getpid());
hdr->un.echo.sequence = htons(sequence);
if (pattern_len > 0) {
for (int i = 0; i < size; i = i + pattern_len) {
int chunk_size = size - i;
if (chunk_size > pattern_len)
chunk_size = pattern_len;
memcpy(packet_data + i + sizeof(icmphdr), pattern, (size_t) chunk_size);
}
}
hdr->checksum = checksum((u_short *) &packet_data, sizeof(packet_data));
clock_gettime(CLOCK_MONOTONIC, &time_start);
if (sendto(sock, packet_data, sizeof(packet_data), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
return SEND_ERROR;
}
addr_len = sizeof(r_addr);
int resp = recvfrom(sock, packet_data, sizeof(packet_data), 0, (struct sockaddr *) &r_addr, &addr_len);
clock_gettime(CLOCK_MONOTONIC, &time_end);
// Extract IP address from r_addr
inet_ntop(AF_INET, &(r_addr.sin_addr), ip_address, INET_ADDRSTRLEN); // here ip_address will contain 123.0.0.0
if (resp
Подробнее здесь: https://stackoverflow.com/questions/790 ... -on-androi
Получение неправильного исходного IP-адреса для пакетов icmp с превышением времени жизни на Android ⇐ Linux
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение