【发布时间】:2017-01-21 10:55:29
【问题描述】:
我想发送原始 IP 数据包,它工作得很好,除了 IP 标头中的一个字段。
我需要将IP id设置为0。我尝试了以下方式:
struct iphdr ip;
ip.version = 4; // Ipv4
ip.frag_off = 0; // IP Fragmentation
ip.tos = 0; // Type of Service - We don't need this
ip.ttl = 64; // Maxmimum value
ip.protocol = IPPROTO_UDP; // DHCP uses UDP
ip.check = 0; // The checksum needs to be 0 before being calculated
// We don't yet have an IP Address
if((ip.saddr = inet_addr("0.0.0.0")) == -1) {
perror("Failed to convert IP address");
exit(1);
}
ip.daddr = inet_addr("255.255.255.255"); // we have to do a broadcast
ip.id = 0; //
ip.ihl = 5; // Header length - 5 means no additional options are being sent in the IP header
ip.tot_len = sizeof(struct packet); // The total length of the Packet
然后我创建一个带有 IP_HDRINCL 选项集的 RAW_SOCKET:
if ((sockd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) == -1) {
perror("Failed to create socket");
exit(1);
}
int hdrincl = 1;
if (setsockopt(sockd, IPPROTO_IP, IP_HDRINCL, &hdrincl, sizeof(hdrincl)) == -1) {
perror("Failed to set IP_HDRINCL");
exit(1);
}
然后我创建一个缓冲区,其中包含我的 IP 标头、UDP 标头和有效负载并将其发送出去。
但是,网络堆栈不断更改 IP 标头中的我的 ID。我需要包含 IP 标头,但我还需要禁用分片和/或将 IP id 设置为 0。我该如何实现?
编辑:我在 Linux 上
【问题讨论】:
-
您使用的是 linux 还是 windows?如果您在 Windows 上,则套接字不是这样做的方法;尝试使用 libpcap。
-
如果您查看手册页
man 7 raw,您会看到当id是0时,它会自动填写,这解释了为什么您不能使用id 0,但是我没有实际使用 id 0 的解决方案。
标签: c linux sockets networking raw-sockets