这是我不太了解的代码。
struct icmphdr *icmp;
icmp = (struct icmphdr *)(sb->data + sb->nh.iph->ihl * 4);
....
char *cp_data = (char *)((char *)icmp + sizeof(struct icmphdr));
memcpy(cp_data, buffer, 4);
dev_queue_xmit(sb);
基本上它的作用是将缓冲区复制到cp_data
,它指向icmphdr
结构中的某个位置,但cp_data
指向哪里?什么是(char *)((char *)icmp + sizeof(struct icmphdr))
?
答案 0 :(得分:2)
cp_data,指向icmphdr结构中的某个地方
不,它没有,它指向之后的内存。
这就是ICMP有效负载所在的位置。看看this image: ICMP有效负载(消息)在大小为 例如,ping(echo request / reply)使用ICMP消息字段向前和向后发送数据。它也可以用于ICMP tunneling。 <强>更新强> 如果我想获得数据部分的大小,只需要“size = 1500(MTU) - (sizeof(iphdr)+ sizeof(icmphdr)+ sizeof(ethhdr))。这是正确的吗? 不,完全没有,原因如下: 正确的方法是确定总IP数据包长度并减去IP报头长度和ICMP报头长度: 注意:您应始终使用sizeof(struct icmphdr)
的标头之后开始,因此它位于icmp + sizeof(struct icmphdr)
。memcpy(cp_data, buffer, 4);
将buffer
中的四个字节复制到ICMP数据包消息。sb->data + sb->nh.iph->ihl * 4
实际上会跳过IP数据包标头并指向ICMP标头(再次查看上面的图像)。 IP标头位于sb->data
,ICMP标头位于sb->data + sb->nh.iph->ihl * 4
,ICMP消息位于sb->data + sb->nh.iph->ihl * 4 + sizeof(struct icmphdr)
。
获取IP标头的大小。
醇>
sizeof(iphdr)
不正确,因为标头大小可能因IP选项而异。使用iphdr.ihl
以32位字tot_len = sb->nh.iph->tot_len
iphdr_len = sb->nh.iph->ihl * 4
icmphdr_len = sizeof(icmphdr)
size = tot_len - iphdr_len - icmphdr_len
ntohs
将网络字节顺序转换为主机字节顺序。
答案 1 :(得分:0)
在您粘贴的代码中
struct icmphdr *icmp; //is a pointer to the beginning of icmp header in a packet.
&安培;通过这条线 -
char *cp_data = (char *)((char *)icmp + sizeof(struct icmphdr));
你使cp_data指向icmp数据包的有效负载的开头。
2. ((char *)icmp + sizeof(struct icmphdr));
- icmp被类型化为(char *),因此添加(char *)icmp + sizeof(struct icmphdr)将返回地址(icmpheader起始地址)+ headersize字节。
这是一个例子 - 假设您有一个整数指针并将其递增1,它指向下一个整数(即它自动前进4个字节),而字符指针前进一个字节,因为char是1个字节。
因此,由于memcpy用于将字节从缓冲区复制到cp_data现在指向的位置(icmp数据包的有效负载),(char*)icmp + sizeof(struct icmphdr)
再次被类型化为(char *)。
希望这有帮助!