- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我对 AF_PACKET
套接字系列(用于 SOCK_RAW
套接字)与以太网 (IEEE 802.3) 的具体关系感到非常困惑。
目前我的理解:
我了解 OSI 模型,以及第 2 层技术如何像以太网适合该模型。
我知道 AF_PACKET
可以与 SOCK_RAW
套接字一起使用接收包含 14 字节以太网报头的数据报,后跟一些其他高层协议(protocol)报头,例如 IPv4、IPv6 等,其次是可选的传输层协议(protocol),如 TCP,以及终于是一个有效载荷。
我知道您可以将 ETH_P_ALL
或 ETH_P_IP
等标志作为socket
的协议(protocol)参数让内核过滤数据包对你来说,只向你发送包含特定标题的数据包类型。
AF_PACKET
系列创建的套接字可以接收或发送到类型为 sockaddr_ll
的端点,该类型与特定 MAC 地址(EUI-48 地址)相关联,以及特定的网络接口(interface)(例如 eth0
或其他)。我不明白的地方:
我不明白 AF_PACKET
是否应该专门用于以太网设备,而不是其他第 2 层技术,例如 Wifi、蓝牙、 token 环、Infiniband 等。
我不明白以太网设备与使用 14 字节以太网 header 的第 2 层协议(protocol)之间的关系。以太网 header 为 14 字节,可以定义如下: struct eth_hdr { char dest_address[6];字符源地址[6]; uint16_t 以太类型; };
换句话说,这个 header 是否仅用于物理以太网设备?似乎答案是否,因为如果我在环回接口(interface)上使用AF_PACKET
,我仍然会收到包含14 字节以太网 header 的数据包。但是环回不是以太网设备。那么为什么它会收到包含以太网 header 的数据包呢?
如果 AF_PACKET
可以与非以太网设备一起使用,ETH_P_ALL
协议(protocol)标志是否指示仅接受专门具有 14 字节以太网 header 的数据包?
我的问题:
使用 AF_PACKET
是否意味着您保证总是接收带有 14 字节以太网 header 的数据包?
如果是这样,是否也意味着 AF_PACKET
只能用于以太网设备(与其他第 2 层技术相反,如 Wifi、 token 环、蓝牙、Infiniband 等) ?
如果这些问题中的任何一个的答案是NO,那么应用程序如何以编程方式确定在 AF_PACKET
上接收数据报时预期的第 2 层报头类型 socket ?
最佳答案
警告:这是因为我对使用 PF_PACKET
的生产软件编写的一些代码进行了蚕食,它仅适用于以太网,所以它可能不完整/不准确。
您正在使用 ETH_P_ALL
,将给您任何东西。但是,有许多 ETH_P_*
符号可供选择(例如 ETH_P_802_3_MIN
)。
绑定(bind)/选择不仅基于 socket
调用,还基于给定的接口(interface)。
首先您需要您想要的接口(interface)名称(例如eth0
),您可以从ifconfig
获得列表。
然后,使用 ioctl(SIOCGIFINDEX,...)
从接口(interface)名称获取接口(interface) index [或者,您可以将其硬编码为 ifconfig
将按索引顺序打印出来]。
然后,根据接口(interface)索引绑定(bind)
到该接口(interface)。
既然你知道接口(interface)的类型(例如你选择了eth0
或wifi等),之后你应该能够消化物理层头,因为你知道它是否是是否构造 eth_hdr
。
请注意,还有许多其他 SIOCGIF*
ioctl,您可以使用它们来获取接口(interface)列表和其他信息,这些信息可以让您辨别接口(interface)类型 [以及因此,什么物理期望的 header ]。
无论如何,这是我所做的一些示例代码:
int
init(const char *intf)
// intf -- interface name (e.g. eth0, etc. -- whatever comes from ifconfig)
{
int err;
#if 1
int styp = SOCK_RAW;
#else
int styp = SOCK_DGRAM;
#endif
int netsock = socket(PF_PACKET,styp,htons(ETH_P_ALL));
struct ifreq ifr;
memset(&ifr,0,sizeof(ifr));
strncpy(ifr.ifr_name,intf,sizeof(ifr.ifr_name));
// get the index number of the interface
err = ioctl(netsock,SIOCGIFINDEX,&ifr);
if (err < 0)
do_whatever;
printf("init: IFRIDX ifr_ifindex=%d\n",ifr.ifr_ifindex);
int ifidx = ifr.ifr_ifindex;
struct sockaddr_ll addr;
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_ifindex = ifidx;
err = bind(netsock,(struct sockaddr *) &addr,
sizeof(struct sockaddr_ll));
if (err < 0)
do_whatever;
return netsock;
}
关于c - AF_PACKET 和以太网,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54056426/
我对 AF_PACKET 套接字系列(用于 SOCK_RAW 套接字)与以太网 (IEEE 802.3) 的具体关系感到非常困惑。 目前我的理解: 我了解 OSI 模型,以及第 2 层技术如何像以太网
sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER,
在 Linux 上,可以使用 AF_PACKET 创建一个套接字,以从套接字接收原始数据并在应用程序中进行 IP 过滤。但是 OSX 的手册页没有这个: PF_LOCAL
我在尝试让 wpa_supplicant 在运行自定义嵌入式 Linux 发行版的板上运行时遇到了问题。经过一些调试,原来是因为内核不支持域类型PF_PACKET: drv->eapol_tx_soc
如何在不指定数据绑定(bind)到哪个主机的情况下在 SOCK_PACKET 套接字上发送数据?我已经构建了 IP header 以显示它应该去哪里,但是 write() 不起作用。 最佳答案 不要。
正如 this question 所暗示的那样,似乎校验和是由以太网硬件计算和验证的,因此当使用 AF_PACKET 套接字发送帧时,它似乎不太可能必须由软件生成,看起来 here和 here .另外
我试图使用 AF_PACKET 原始套接字嗅探网络流量。我能够获取所有 IP/ARP 数据包,但根本无法获取任何 IPv6 数据包。我需要做什么才能获得 IPv6 流量吗? unsigned c
我想不通。当我运行我的代码时......即使我绑定(bind)成功,我也会看到来自所有以太网类型和所有接口(interface)的数据。运行几分钟后……它会自行修复。然后我只从一个特定的接口(inte
使用以下方法使用 AF_PACKET 和环形缓冲区(伪 C)捕获数据包: // Set up socket fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_A
我正在使用 Python 构建数据包嗅探程序,但是我遇到了减速带。出于某种原因,我认为套接字没有正确导入,因为我在程序运行时收到以下消息:AttributeError: module 'socket'
关闭创建为AF_PACKET 和AF_INET 的套接字之间存在这种时间差异的原因是什么?如何减少 AF_PACKET 的关闭时间? sockfd = socket(AF_PACKET, SOCK_R
我想编写一个应用程序,它应该接收所有传入的数据包,而不管数据包是发往我的机器并假设被转发还是发往本地主机。 为此,我打开了一个 AF_PACKET 套接字。但是,由于我的机器有多个接口(interfa
在两台 PC 上,我正在打开一个 AF_PACKET/PF_PACKET 套接字,原始协议(protocol)。 sock = socket(AF_PACKET, SOCK_RAW, htons(PR
下面的 Linux 代码应该搜索所有接口(interface),直到它使用 ETHERNET 类型 2 帧从特定 MAC 地址获得响应。 尚未完成。 我希望 select() 阻止超时值。问题是没有数
我正在尝试在 Linux (Ubuntu 18.04) 上的 C 中创建一个测试程序,该程序使用 SOCK_RAW 通过 AF_PACKET/PF_PACKET 套接字发送一个空的 UDP 数据包.在
我是一名优秀的程序员,十分优秀!