我看不到我的网络原始数据包在C中

huangapple go评论64阅读模式
英文:

I can not see my networks raw packets in C

问题

I have two virtual machines in VMware Infrastructure (Workstation) running Ubuntu 22.04, which are in the same network. With one program, I am sending raw packets from one virtual machine with a MAC address that does not match any of the computers on the network (as a requirement). In the other virtual machine, I can see the raw packets in Wireshark, but my C program cannot see them. I checked the IP tables rules, and there are no denials for raw packets. Below is the code I use to open the raw socket and read:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <arpa/inet.h>
#include <linux/filter.h>
#include <fcntl.h>

int main(int argc, char *argv[]) {
    int s, stat, cc;
    unsigned char buf[ETH_FRAME_LEN];
    struct sockaddr_ll saddr;
    struct ifreq ifr;
    char *interface = "ens33";

    s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (s < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    strncpy(ifr.ifr_name, interface, IFNAMSIZ);
    if (ioctl(s, SIOGIFINDEX, &ifr)) {
        perror("ioctl");
        close(s);
        exit(EXIT_FAILURE);
    }

    saddr.sll_family = AF_PACKET;
    saddr.sll_ifindex = ifr.ifr_ifindex;
    saddr.sll_protocol = htons(ETH_P_ALL);

    if (bind(s, (struct sockaddr *)&saddr, sizeof(saddr))) {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    stat = fcntl(s, F_SETFL, O_NONBLOCK);
    if (stat < 0)
        perror("non-blocking");

    while (1) {
        cc = read(s, buf, sizeof(buf));
        // Process the information
    }
}

I tried to use libpcap, and it works, but due to the system's infrastructure, I am unable to change how the functions are used. I have one function to open the socket and another to read. These functions are used by other modules, and it's not possible to change them.

I changed the MAC address, but I still encounter the same problems. The virtual machines can see each other.

英文:

I have two virtual machines in vmware infrastructure (workstation) running Ubuntu 22.04, that are in the same network. With one program I am sending in one virtual machine raw packets, with a MAC that does not fit with any of the computers in the network (is a requirement). In the other virtual machine I can see the raw packets in Wireshark but my C program can not see it. I check the Iptables rules and there is no denied to raw packets. Here is the code I use to open the raw socket and read:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/ioctl.h&gt;
#include &lt;net/if.h&gt;
#include &lt;linux/if_packet.h&gt;
#include &lt;net/ethernet.h&gt;
#include &lt;arpa/inet.h&gt;
#include &lt;linux/filter.h&gt;
#include &lt;fcntl.h&gt;

int main(int arg, char** argv[])
{
    int s, stat, cc;                         
    unsigned char buf[ETH_FRAME_LEN];                                          
    struct sockaddr_ll saddr;
    struct ifreq ifr;
    char *interface = &quot;ens33&quot;;

    s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (s &lt; 0) {
        perror(&quot;socket&quot;);
        exit(EXIT_FAILURE);
    }

    strncpy(ifr.ifr_name, interface, IFNAMSIZ);
    if(ioctl(s, SIOGIFINDEX, &amp;ifr))
    {
        perror(&quot;ioctl&quot;);
        close(s);
        exit(EXIT_FAILURE);
    }

    saddr.sll_family = AF_PACKET;
    saddr.sll_ifindex = ifr.ifr_ifindex;
    saddr.sll_protocol = htons(ETH_P_ALL);

    if (bind(s, (struct sockaddr *)&amp;saddr, sizeof(saddr)))
    {
    perror(&quot;bind&quot;);
    exit(EXIT_FAILURE);
    }

    stat = fcntl (s, F_SETFL, O_NONBLOCK);
    if (stat &lt; 0)
    perror (&quot;bloqueante&quot;);

        while(1)
    {
        cc = read (s, buf, sizeof(buf));
        // Process the information
    }
}

I tried to use libpcap and works, but because of the infrastructure of the system I am not able to change the way the functions are used. I have one function to open the socket and another to read. This functions are used for other modules and it is not a possibility.

I change the MAC and the same problems. The virtual machines can see each other.

答案1

得分: 0

将接口设置为混杂模式,以接收非其MAC地址绑定的数据包。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <arpa/inet.h>
#include <linux/filter.h>
#include <fcntl.h>

int main(int arg, char* argv[])
{
    int s, stat;
    size_t cc;
    unsigned char buf[ETH_FRAME_LEN];
    struct sockaddr_ll saddr = {};
    struct ifreq ifopts;    //for promiscuous mode 
    struct ifreq ifr = {};
    const char *interface = "ens33";

    s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (s < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }
    
    //设置混杂模式
    strncpy(ifopts.ifr_name, interface, IFNAMSIZ-1);
    ioctl(s, SIOCGIFFLAGS, &ifopts);
    ifopts.ifr_flags |= IFF_PROMISC;
    ioctl(s, SIOCSIFFLAGS, &ifopts);

    strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);
    if(ioctl(s, SIOGIFINDEX, &ifr))
    {
        perror("ioctl");
        close(s);
        exit(EXIT_FAILURE);
    }

    saddr.sll_family = AF_PACKET;
    saddr.sll_ifindex = ifr.ifr_ifindex;
    saddr.sll_protocol = htons(ETH_P_ALL);

    if (bind(s, (struct sockaddr *)&saddr, sizeof(saddr)))
    {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    stat = fcntl (s, F_SETFL, O_NONBLOCK);
    if (stat < 0)
        perror ("bloqueante");

    while(true)
    {
        cc = read (s, buf, sizeof(buf));
        //处理信息
    }
}
英文:

Set interface to promiscuous mode to receive packets not bound for it's MAC address.

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/ioctl.h&gt;
#include &lt;net/if.h&gt;
#include &lt;linux/if_packet.h&gt;
#include &lt;net/ethernet.h&gt;
#include &lt;arpa/inet.h&gt;
#include &lt;linux/filter.h&gt;
#include &lt;fcntl.h&gt;

int main(int arg, char* argv[])
{
    int s, stat;
    size_t cc;
    unsigned char buf[ETH_FRAME_LEN];
    struct sockaddr_ll saddr = {};
    struct ifreq ifopts;	//for promiscuous mode 
    struct ifreq ifr = {};
    const char *interface = &quot;ens33&quot;;

    s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (s &lt; 0) {
        perror(&quot;socket&quot;);
        exit(EXIT_FAILURE);
    }
    
    //Set Promiscuous Mode
    strncpy(ifopts.ifr_name, interface, IFNAMSIZ-1);
    ioctl(s, SIOCGIFFLAGS, &amp;ifopts);
    ifopts.ifr_flags |= IFF_PROMISC;
    ioctl(s, SIOCSIFFLAGS, &amp;ifopts);

    strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);
    if(ioctl(s, SIOGIFINDEX, &amp;ifr))
    {
        perror(&quot;ioctl&quot;);
        close(s);
        exit(EXIT_FAILURE);
    }

    saddr.sll_family = AF_PACKET;
    saddr.sll_ifindex = ifr.ifr_ifindex;
    saddr.sll_protocol = htons(ETH_P_ALL);

    if (bind(s, (struct sockaddr *)&amp;saddr, sizeof(saddr)))
    {
        perror(&quot;bind&quot;);
        exit(EXIT_FAILURE);
    }

    stat = fcntl (s, F_SETFL, O_NONBLOCK);
    if (stat &lt; 0)
        perror (&quot;bloqueante&quot;);

    while(true)
    {
        cc = read (s, buf, sizeof(buf));
        // Process the information
    }
}

huangapple
  • 本文由 发表于 2023年5月13日 16:09:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76241715.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定