重建数据包以通过 pcap 注入
情况是这样的:在我的场景中,我有 3 台计算机,A、B 和 C。
计算机 A 将数据发送到计算机 B。计算机 B 使用 pcap 捕获这些数据包,附加标头,重做校验和,并将其从另一个以太网注入到计算机 C 的接口。所以基本上 A 发送到 C,尽管从 C 的角度来看,数据来自计算机 B。
我的问题是这样的:按照 TCPDUMP 的关于解析捕获的数据包的教程,我学会了计算偏移量并使用类型转换来获取以太网、ip 和 tcp 标头结构。这样做的方法如下所示:
ethernet = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
size_ip = IP_HL(ip)*4;
if (size_ip < 20) {
printf(" * Invalid IP header length: %u bytes\n", size_ip);
return;
}
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20) {
printf(" * Invalid TCP header length: %u bytes\n", size_tcp);
return;
}
payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);
因为我想注入捕获的数据包以将其从计算机 B 发送到计算机 C,所以我必须修改一些源/目标信息并在完成后重新计算校验和。然而,我的问题是,由于这些数据现在被分成以太网标头、IP 标头和 TCP 标头的结构,我如何将其重新组合到 u_char
中,pcap_inject
可以用吗?
是否可以在这里进行某种串联?
Here is the situation: in my scenario I have, 3 computers, A, B and C.
Computer A sends data to computer B. Computer B captures these packets with pcap, appends the headers, redoes the checksums, and injects it out another ethernet interface to computer C. So basically A sends to C, though through C's point of view, the data is coming from computer B.
My problem is this: following TCPDUMP's tutorial on dissecting a captured packet, I've learned to calculate offsets and using typecasting to obtain ethernet, ip, and tcp header structures. The method of doing so is shown below:
ethernet = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
size_ip = IP_HL(ip)*4;
if (size_ip < 20) {
printf(" * Invalid IP header length: %u bytes\n", size_ip);
return;
}
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20) {
printf(" * Invalid TCP header length: %u bytes\n", size_tcp);
return;
}
payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);
Because I want to inject the captured packet to send it from computer B to computer C, I must modify some of the source/destination information and recalculate the checksum when I'm done. However, my issue is, since this data is now separated into structures of ethernet header, IP header, and TCP headers, how do I put it back together into a u_char
that pcap_inject
can use?
Is it possible to do some sort of concatenation here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从我在这里看到的代码来看,您实际上并没有剖析
libpcap
为您捕获的内存。每个转换操作只是告诉编译器您打算如何处理从指针开始的字节——这些对象的大小、查找数据片段的偏移量以及它们的长度。如果您通过这些指针修改此内存,那么您就修改了进程内存中它的唯一副本 - 并且可以使用一些“更基本”的指针将整个内存块传递给 sendmsg( 2) 或任何不需要重新组装数据的东西——你从来没有把它拆开过。
更新
要将数据包注入回网络,您需要使用
raw(7)
套接字类型;通过raw(7)
套接字发送 TCP 数据包需要IPPROTO_RAW
套接字选项 - 否则,所有 TCP 数据包将被定向到您打开的raw(7)
套接字,使得机器上的网络难以使用。raw(7)
套接字将为您执行一些重新计算任务:让内核重新计算它愿意为您做的任何事情。
From the code I see here, you're not actually dissecting the memory that
libpcap
captured for you. Each of the casting operations simply tells the compiler how you intend to treat the bytes starting from a pointer -- what size those objects are, what offsets to find which pieces of data and how long they are.If you modify this memory through those pointers, you've modified the one and only copy of it in the process memory -- and can use some of the "more basic" pointers to hand the entire block of memory to
sendmsg(2)
or whatever without needing to reassemble the data -- you never took it apart.Update
To inject the packets back on the network you need to use the
raw(7)
socket type; theIPPROTO_RAW
socket option is required to send TCP packets through araw(7)
socket -- otherwise, all TCP packets would be directed to theraw(7)
socket you open, making networking on the machine difficult to use.The
raw(7)
sockets will perform some re-calculation tasks for you:Let the kernel re-calculate whatever it is willing to do for you.