struct msghdr msg;
struct iovec iov;
unsigned char buf[BUFSIZE] = { '\0', };
ssize n;
int fd;
...
fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
...
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_flags = 0;
iov.iov_base = buf;
iov.iov_len = sizeof(buf);
...
n = recvmsg(sockfd, &msg, 0);
...
parse_pkt(buf, BUFSIZE);
到目前為止一切順利,資料包已收到,現在我需要決議它:
static int parse_packet(unsigned char *pkt, int len)
{
struct iphdr *ip = (struct iphdr *)(pkt 14);
struct udphdr *udp;
/* ip has valid pointer and we can explore IP header fields, ip pointer is NOT modified. */
...
udp = (struct udphdr *)(ip (ip->ihl << 2));
/* at this point I'm expecting udp to point past IP header space. */
...
}
我看到的問題是udp
它沒有指向我期望的位置,我不明白為什么:pkt
包含整個資料包(包括Ethernet
標頭,沒有 VLAN),因此ip
獲得了一個通過 ether_header 的指標,所以udp = (struct udphdr *)(ip (ip->ihl << 2))
應該跳過 IP 標頭大小,但它沒有!
什么是有效的:
struct iphdr *ip = (struct iphdr *)(pkt 14);
...
udp = (struct udphdr *)(pkt 14 (ip->ihl << 2));
這是怎么回事,我做錯了什么?
uj5u.com熱心網友回復:
當你這樣做時:
udp = (struct udphdr *)(ip (ip->ihl << 2));
您正在以sizeof(*ip)
而不是 1 為單位進行指標運算。
你的替代作品:
udp = (struct udphdr *)(pkt 14 (ip->ihl << 2));
因為pkt
是一個unsigned char *
所以指標算術是以單位元組為單位完成的。
這也可以:
udp = (struct udphdr *)((unsigned char *)ip (ip->ihl << 2));
因為它允許您以單位元組為單位執行指標運算。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/507337.html
上一篇:給定位元組序讀取數字的問題(C到Javascript)
下一篇:我想知道在C中如何使用雙引號