gpt4 book ai didi

c - 使用 C 套接字的接口(interface)上的环回数据包

转载 作者:行者123 更新时间:2023-11-30 16:36:40 25 4
gpt4 key购买 nike

我正在尝试环回网络接口(interface)上收到的数据包。因此,对于我在 nf2 接口(interface)中收到的每个数据包,我希望通过 nf2 接口(interface)传输相同的数据包。我不想交换地址或 nat。我下面是我在网上获得的代码,旨在实现我的相同目标。

只要不启用传输部分,我就可以毫无问题地接收数据包。一旦我添加传输部分 write(sock,buffer,data_size),设计就会无限期地运行。我已经注释掉了 Tx 部分(Tx 部分 Start 和 Tx 部分 Stop 之间)。

#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <unistd.h>

int main()
{
int saddr_size , data_size, daddr_size, bytes_sent;
struct sockaddr_ll saddr, daddr;
unsigned char *buffer=malloc(65535);
int n = 0;
int count = 0;

// Opening the socket

int sock_raw = socket( AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ; //For receiving
int sock = socket( PF_PACKET , SOCK_RAW , IPPROTO_RAW) ; //For sending

// Initializing the memory address and variables for the sockets
memset(&saddr, 0, sizeof(struct sockaddr_ll));
saddr.sll_family = AF_PACKET;
saddr.sll_protocol = htons(ETH_P_ALL);
saddr.sll_ifindex = if_nametoindex("nf2");

// Binding the socket to the address
if (bind(sock_raw, (struct sockaddr*) &saddr, sizeof(saddr)) < 0) {
perror("bind failed\n");
close(sock_raw);
}

// Initializing the memory address
memset(&daddr, 0, sizeof(struct sockaddr_ll));
daddr.sll_family = AF_PACKET;
daddr.sll_protocol = htons(ETH_P_ALL);
daddr.sll_ifindex = if_nametoindex("nf2");

// Binding the socket to the address
if (bind(sock, (struct sockaddr*) &daddr, sizeof(daddr)) < 0) {
perror("bind failed\n");
close(sock);
}

struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "nf2");
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
perror("bind to nf2");
}

while(1)
//while((n = read(sock_raw, &saddr, sizeof(&saddr)-1)) > 0)
{
saddr_size = sizeof (struct sockaddr);
daddr_size = sizeof (struct sockaddr);
//Receive a packet
data_size = recvfrom(sock_raw , buffer , 65536 , 0 ,(struct sockaddr *) &saddr , (socklen_t*)&saddr_size);

if(data_size <0 )
{
printf("Recvfrom error , failed to get packets\n");
return 1;
}
else{
printf("%d Received %d bytes\n", count, data_size);
count++;

// Tx part -starts
// The following section runs indefinitely

//Send the same packet out
//bytes_sent=write(sock,buffer,data_size);
//printf("Sent %d bytes\n",bytes_sent);
// if (bytes_sent < 0) {
// perror("sendto");
// exit(1);
// }

// Tx part - ends
}
}
close(sock_raw);
return 0;
}

非常感谢任何帮助

最佳答案

问题是您正在接收发送的每个数据包,然后再次重新复制它。 IOW:回应自己。

使用struct sockaddr_ll 中的sll_pkttype 来区分传出的数据包并忽略它们。您可以在循环内执行类似的操作:

while (1) {
saddr_size = sizeof (struct sockaddr_ll);
//Receive a packet
data_size = recvfrom(sock_raw, buffer, 65536, 0, (struct sockaddr *)&saddr, &saddr_size);

if (saddr.sll_pkttype == PACKET_OUTGOING) {
printf("Ignoring outgoing packet\n");
continue;
}

有关数据包类型的说明,请参阅 packet(7)

关于c - 使用 C 套接字的接口(interface)上的环回数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48322659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com