【发布时间】:2015-02-02 11:00:24
【问题描述】:
我正在尝试解析一个 tcp 数据包,然后分配一个指向有效负载开头的指针。
我正在使用 C,这是我目前的代码:
void dump(const unsigned char *data, int length) { //*data contains the raw packet data
unsigned int i;
static unsigned long pcount = 0;
// Decode Packet Header
struct ether_header *eth_header = (struct ether_header *) data;
printf("\n\n === PACKET %ld HEADER ===\n", pcount);
printf("\nSource MAC: ");
for (i = 0; i < 6; ++i) {
printf("%02x", eth_header->ether_shost[i]); //? Why don't i use nthos here?
if (i < 5) printf(":");
}
unsigned short ethernet_type = ntohs(eth_header->ether_type);
printf("\nType: %hu\n", ethernet_type);
if (ethernet_type == ETHERTYPE_IP) { //IP Header
printf("\n == IP HEADER ==\n");
struct ip *ip_hdr = (struct ip*) data + sizeof(struct ether_header);
unsigned int size_ip = ip_hdr->ip_hl * 4;
printf("\nIP Version: %u", ip_hdr->ip_v); //? Nthos or no nthos
printf("\nHeader Length: %u", ip_hdr->ip_hl); //? Nthos or no nthos
printf("\nTotal Length: %hu", ntohs(ip_hdr->ip_len)); //? Nthos or no nthos
// TCP Header
printf("\n== TCP HEADER ==\n");
struct tcphdr *tcp_hdr = (struct tcphdr*) data + sizeof(struct ether_header) + size_ip;
printf("\n Source Port: %" PRIu16, nthos(tcp_hdr->th_sport));
printf("\n Destination Port: %" PRIu16, nthos(tcp_hdr->th_dport));
printf("\n fin: %" PRIu16, tcp_hdr->fin);
printf("\n urg: %" PRIu16, tcp_hdr->urg);
printf("\n ack_seq: %" PRIu32, ntohl(tcp_hdr->ack_seq));
//Transport payload! i.e. rest of the data
const unsigned char *payload = data + ETH_HLEN + size_ip + sizeof(struct tcphdr) + tcp_hdr->doff;
}
我确定这段代码有错误,因为端口号都很奇怪。没有一个分配给 80。输出的 Ip 版本也可能非常奇怪(如版本 11)。我究竟做错了什么?谢谢!
我也不确定何时使用 nthos,何时不使用。我知道 nthos 用于 16 位无符号整数,我知道 nthol 用于 32 位无符号整数,但我知道您并不打算将它们用于这些数据包中的所有内容(例如:tcp_hdr->fin)。为什么是某些事情而不是他们?
非常感谢!
编辑:
感谢 Art 解决了大部分问题。我编辑了我的 tcp_hdr 和 ip_hdr 所以括号现在是正确的!
我还有两个问题:
- 有效载荷的前 10 个字节有奇怪的符号(所以我认为我没有正确分配有效载荷)。
- 我仍然不确定何时使用 nthos/nthol。我知道 u_int16_t 是 ntohs 而 u_int32_t 是 ntohl。但是那些有符号整数或无符号短整数的东西呢?例如,我没有使用 ntohs 或 nthol 来让 ip_v 工作。为什么不?是“ip_hdr->ip_hl”吗?等等……
EDIT2
我已经修复了为什么我的有效负载没有正确输出(这是因为我计算的 TCP_header 大小错误)。
虽然我仍然对何时使用 nthos 感到困惑,但我将把它作为一个单独的问题提出,因为我认为我在这 1 个帖子上问了太多问题!
【问题讨论】:
-
你知道端口号之类的东西是按network字节顺序排列的吗?使用
ntohs将短(16 位)值从网络字节顺序转换为主机字节顺序。 -
我都试过了,但是 eitehr 的数字很奇怪。无论如何现在更新代码!
-
还有其他看起来正确的字段吗?喜欢源/目标地址?以太网头?与例如相同的数据包相比,它看起来如何线鲨?而您确实在原始套接字上接收到这个?并接收所有的数据包?
标签: c tcp packet packet-capture packet-sniffers