我正在尝试建立一个简单的icmp echo请求,但是我无法得到很好的答复。
我尝试使用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,数据已发送,但没有回复全部 对于具有HDRINCL的IPPROTO_ICMP,我使用icmp ECHO(类型8)而不是echo_reply(类型1)进行答复 对于没有HDRINCL的IPPROTO_ICMP(并且struct ip到处都有注释),有icmp 69作为答复。
我认为,当我第一次尝试这些“配置”时,它们不会造成任何差异,但确实会造成差异。为什么?
有人看到什么问题了,我该如何解决我的问题?如果是,怎么办?
非常感谢