如何同时使用2个PF_INET和PF_PACKET的插座
How to use 2 sockets PF_INET and PF_PACKET at the same time?
我有以下 2 个函数
int listen_socket(unsigned int ip, int port, char *inf)
{
struct ifreq interface;
int fd;
struct sockaddr_in addr;
int n = 1;
DEBUG(LOG_INFO, "Opening listen socket on 0x%08x:%d %sn", ip, port, inf);
if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
DEBUG(LOG_ERR, "socket call failed: %s", strerror(errno));
return -1;
}
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = ip;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1) {
close(fd);
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *) &n, sizeof(n)) == -1) {
close(fd);
return -1;
}
strncpy(interface.ifr_ifrn.ifrn_name, inf, IFNAMSIZ);
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,(char *)&interface, sizeof(interface)) < 0) {
close(fd);
return -1;
}
if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
close(fd);
return -1;
}
return fd;
}
int raw_socket(int ifindex)
{
int fd;
struct sockaddr_ll sock;
DEBUG(LOG_INFO, "Opening raw socket on ifindex %dn", ifindex);
if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
DEBUG(LOG_ERR, "socket call failed: %s", strerror(errno));
return -1;
}
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
sock.sll_family = AF_PACKET;
sock.sll_protocol = htons(ETH_P_IP);
sock.sll_ifindex = ifindex;
if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
DEBUG(LOG_ERR, "bind call failed: %s", strerror(errno));
close(fd);
return -1;
}
return fd;
}
两者都是套接字侦听器函数。
我以这种方式在我的应用程序中使用了这些功能
fd = listen_socket(INADDR_ANY, 67, client_config.interface);
fd2 = raw_socket(client_config.ifindex);
现在,如果我将数据包发送到我的应用程序(目标 = 接口的 ip,端口 = 67)。什么套接字应该捕获我的数据包?是fd2
还是fd
或两者兼而有之?
如果我向我的应用程序发送数据包(目的地 = broacast:255.255.255.0 和端口 = 67)。什么套接字应该捕获我的数据包?是fd2
还是fd
或两者兼而有之?
两个套接字都将接收该数据包。当每个数据包从网络驱动程序到达内核时,它将被复制并发送到所有PF_PACKET(第 2 层)套接字。数据包还会发送到第 3 层 (IP/TCP) 内核代码,然后从那里发送到寻址套接字。
如果没有发生这种情况,运行一个单独的程序进行原始数据包捕获(例如wireshark)将阻止网络上的任何其他通信。
相关文章:
- ostream& operator<< (ostream& (*pf)(ostream&));
- 无法将Omnetpp::cPacket强制转换为Inet::Packet
- 指向C++中函数的指针,(*pf)()和pf相同吗
- 什么是 'R(*pf)(void*, Args..)',函数指向方法的指针?
- RFID data packet
- Splitting a Netfilter packet
- Ubuntu的SFML"没有匹配的调用"sf:SocketUDP::Receive(sf::Packet&,sf::IPAddress&)"函数"
- Reading CF, PF, ZF, SF, OF
- C++"recv"函数在数据接收时如何起作用?它能收到部分"packet"吗?
- 为什么声明' void(*pf)(int) = bar; '会触发下面代码片段中的' static_assert