Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C原始套接字仅接收或嗅探传入的数据包_C_Sockets - Fatal编程技术网

C原始套接字仅接收或嗅探传入的数据包

C原始套接字仅接收或嗅探传入的数据包,c,sockets,C,Sockets,我只需要在特定接口上为传入的数据包设置一个原始套接字(只有eth0和eth1,eth1)。换句话说,我只需要一个特定接口上的传入数据包 与其他嗅探器相比 在ifconfig中,每个接口都有一个RX Packets字段。虽然这保持不变,但此嗅探器仍将注册为接收数据包。也许RX数据包仅限于某些协议?我还将其与python嗅探器进行了比较——同样的问题也存在。python嗅探器返回的数据包不会像这个c嗅探器返回的那么多。我无法将其与wireshark进行比较,因为我无法将其安装在系统上,因为它是嵌入式

我只需要在特定接口上为传入的数据包设置一个原始套接字(只有eth0和eth1,eth1)。换句话说,我只需要一个特定接口上的传入数据包

与其他嗅探器相比

在ifconfig中,每个接口都有一个RX Packets字段。虽然这保持不变,但此嗅探器仍将注册为接收数据包。也许RX数据包仅限于某些协议?我还将其与python嗅探器进行了比较——同样的问题也存在。python嗅探器返回的数据包不会像这个c嗅探器返回的那么多。我无法将其与wireshark进行比较,因为我无法将其安装在系统上,因为它是嵌入式的

绑定

我想也许我把它装订错了,但这似乎起作用了。运行其中两个,一个在eth0上,另一个在eth1上,会得到不同的结果/

可疑问题

在我看来,问题出在recvfrom命令中,它不只是过滤传入的数据包,而是从缓冲区读取数据,不管是传入的还是传出的。也许有一种方法可以查看地址,看看数据包是传入的还是传出的,就像在python中一样,或者recvfrom已经在这样做了

注意

接近尾声时,程序将打印嗅探到的数据包大小以及接收到的数据包大小的时间。这是精简后的代码。提前谢谢

#include<errno.h>  //error codes
#include<linux/if_packet.h>
#include<linux/if_ether.h>
#include<time.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<netinet/in.h>
#include<stdio.h>
#include<stdlib.h>
#include<net/if.h>
const int TIME_INTERVAL = 2;
const int BUF_LENGTH = 65534;
int main()
{
    int sock_errno(void), data_size=0, raw_sock;
    long recv_count = 0, last_count = 0, rate = 0;
    time_t start;
    socklen_t clilen;
    struct sockaddr_in cliaddr, servaddr; 
    char buffer[BUF_LENGTH];
    int hist[BUF_LENGTH];
    int i;
    for (i = 0; i < BUF_LENGTH; i++)
        hist[i] = 0;
    int table[BUF_LENGTH];
    int index = 0;

    //Create a raw socket that shall sniff
    raw_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    //bind to interface
    clilen = sizeof(struct sockaddr_in);
    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth1");
    setsockopt(raw_sock, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
    start = time(NULL);
    while (1)
    {
        data_size = recvfrom(raw_sock, buffer, BUF_LENGTH, 0, (struct sockaddr*)&cliaddr, &clilen);
        recv_count = recv_count + data_size;

        hist[data_size] = hist[data_size] + 1;

        if (time(NULL) - start > TIME_INTERVAL) // display data every time interval
        {
            start = time(NULL);
            rate = (float)(recv_count - last_count) / TIME_INTERVAL;
            printf("(I) Bytes received: %d\n", recv_count);

            for (i=0; i<BUF_LENGTH; i++) {
                if (hist[i] > 0) //only print received packet sizes
                {
                    printf("%d - ", i); //print packet size
                    printf("%d\n", hist[i]); //print received counter
                }
            }
            printf("\n\n");

        }
    }
    close(raw_sock);
    return 0;
}
#包括//错误代码
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
const int TIME_INTERVAL=2;
const int BUF_LENGTH=65534;
int main()
{
int sock_errno(void),数据大小=0,原始sock;
长记录计数=0,最后一次计数=0,比率=0;
时间没有开始;
socklen_t clilen;
cliaddr、servaddr中的结构sockaddr\u;
字符缓冲区[BUF_长度];
int hist[BUF_LENGTH];
int i;
对于(i=0;itime\u INTERVAL)//每个时间间隔显示数据
{
开始=时间(空);
速率=(浮动)(记录计数-上次计数)/时间间隔;
printf(“(I)接收的字节数:%d\n”,recv\u计数);
for(i=0;i 0)//仅打印收到的数据包大小
{
printf(“%d-”,i);//打印数据包大小
printf(“%d\n”,hist[i]);//打印接收计数器
}
}
printf(“\n\n”);
}
}
关闭(未加工的袜子);
返回0;
}
请参阅的答案

查看将cliaddr的类型更改为struct sockaddr\u ll,然后可以查看cliaddr.sll\u pkttype来确定传入或传出

struct sockaddr_ll {
           unsigned short sll_family;   /* Always AF_PACKET */
           unsigned short sll_protocol; /* Physical layer protocol */
           int            sll_ifindex;  /* Interface number */
           unsigned short sll_hatype;   /* ARP hardware type */
           unsigned char  sll_pkttype;  /* Packet type */
           unsigned char  sll_halen;    /* Length of address */
           unsigned char  sll_addr[8];  /* Physical layer address */
       };
sll_pkttype包含数据包类型。 对于发往本地主机的数据包,有效类型为数据包\主机, 包\用于物理层广播包的广播, 数据包\发送到物理层多播的数据包的多播 地址,数据包\u其他主机,用于将数据包发送到具有 在混乱模式下被设备驱动程序捕获,以及 数据包\来自本地主机的数据包的传出,该本地主机是
循环回数据包套接字

当然,在两个不同的接口上运行时,您会得到不同的结果,因为两个接口将得到不同的包。确切地说,这是为了确认我确实正确绑定了它们。那么,您能详细说明一下您的问题吗?无论问题是什么,你都试图做些什么来解决?它是如何工作的?它是嗅探没有被ifconfig命令或另一个用python编写的嗅探器拾取的数据包。该命令不是数据包嗅探器,而是配置接口。还有,有没有比专业的嗅探员如?