【发布时间】:2020-02-27 00:18:31
【问题描述】:
如果我对recvfrom 的调用返回有效字节数(例如1400),我会在缓冲区的开头得到什么?
我会收到ethhdr 吗?例如,即使我应该接收 UDP 数据包,此代码也不起作用:
void read_packets(struct config *cfg) {
int64_t read_bytes = recvfrom(cfg->socket_fd, buffer, BUFFER_SIZE, 0, NULL, NULL);
if(read_bytes == -1) {
return;
}
cfg->stats.amnt_of_packets += 1;
cfg->stats.amnt_of_bytes += read_bytes;
struct ethhdr *eth = (struct ethhdr*)(buffer);
if(ntohs(eth->h_proto) == ETH_P_IP) {
struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));
if(iph->protocol == IPPROTO_UDP) {
/* doesn't work */
}
}
}
socket_fd 被创建为:
cfg->socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
【问题讨论】:
-
@JeremyFriesner 我将此信息添加到我的原始帖子中
-
SOCK_DGRAM 类型的套接字将仅获取 UDP 有效负载数据。如果您想访问较低级别的网络标头(在大多数情况下,您不需要),您需要实例化一个 SOCK_RAW 套接字。 (另见:stackoverflow.com/questions/26896944/…)
-
@JeremyFriesner 所以这意味着在我的情况下我得到一个
struct udphdr? -
不,在您的情况下,您只能获得发送程序传递给其
sendto()调用的任何 UDP 有效负载数据。任何类型的系统定义的标头数据都不会暴露给正常的网络程序(使用原始套接字时除外)。