【问题标题】:Displaying content of the Link Layer Header显示 Link Layer Header 的内容
【发布时间】:2015-01-05 05:37:08
【问题描述】:

是否有任何 debian Linux 程序可以在 C 程序中调用其命令,表达数据包的元数据(例如协议、数据包长度、源端口和目标端口)?我会使用 readFrom 和 sockaddr* 结构,但我也希望能够接收 TCP 流量。

有没有什么方法可以使用 tcpdump 来创建包含这些信息的字符串?

另外,这个问题的表达或内容在概念上是否有任何错误?

【问题讨论】:

    标签: c tcp network-programming udp debian


    【解决方案1】:

    您可以使用多种替代方案: Jewel Thief 提到的 1-PCAP。示例代码:

    int datalink;
    char *device;
    pcap_t *pd;
    int snaplen = MAX_MSG_LEN;
    #define CMD "tcp and dst port %d"
    
    void open_pcap()
    {
        uint32_t localnet;
        uint32_t netmask;
        char cmd[300];
        char errbuf[PCAP_ERRBUF_SIZE];
        struct bpf_program fcode;
    
        device = pcap_lookupdev(errbuf);
        if (device == NULL)
        {
            printf("ERROR-1: open_pcap:%s\n", errbuf);
            exit(3);
        }
    
        printf("DEVICE: %s\n", device);
    
        pd = pcap_open_live(device, snaplen, 0, 500, errbuf);
    
        if (pd == NULL)
        {
            printf("ERROR-2-%s\n", errbuf);
            exit(4);
        }
    
        if (pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0)
        {
            printf("ERROR-3-%s\n", errbuf);
            exit(5);
        }
    
        snprintf(cmd, sizeof(cmd), CMD, 80);
    
        if (pcap_compile(pd, &fcode, cmd, 0, netmask) < 0)
        {
            printf("ERROR-4-%s\n", pcap_geterr(pd));
            exit(6);
        }
    
        if (pcap_setfilter(pd, &fcode) < 0)
        {
            printf("ERROR-5-%s\n", pcap_geterr(pd));
            exit(7);
        }
    
        datalink = pcap_datalink(pd);
    
        if (datalink < 0)
        {
            printf("ERROR-6-%s\n", pcap_geterr(pd));
            exit(8);
        }
    
        printf("DATALINK: %d\n", datalink);
    }
    
    int getNext(char *msg)
    {
        struct pcap_pkthdr hdr;
        char *ptr = NULL;
    
        while(ptr == NULL)
        {
            ptr = (char *)pcap_next(pd, &hdr);
        }
    
        printf("LEN: %d - CAPLEN: %d\n", hdr.len, hdr.caplen);
        memcpy(msg, ptr, hdr.caplen);
    
        return hdr.caplen;
    }
    

    2-您可以使用数据包套接字

    #include <sys/socket.h>
    #include <linux/if_packet.h>
    #include <net/ethernet.h> /* the L2 protocols */
    
    packet_socket = socket(AF_PACKET, int socket_type, int protocol);
    

    3-如果您不想编码,可以使用 shell 调用命令 tcpdump,这足以满足您的需求(查看 man 获取参数)

    【讨论】:

    • 我必须包含哪些库才能使用 pcap?此外,我尝试在我的程序中使用带有参数 -e 的 tcpdump,但结果不一。如何仅打印来自特定客户端的数据包?如何将命令的打印输出转换为可以在代码中使用的字符串?
    • 所有这些你都可以用谷歌搜索。在 gcc 中使用 libpcap(选项 -lpcap)。对于其他问题,您可以在 stackoverflow 或其他网站上找到很多很好的回答。
    【解决方案2】:

    您可以在 C 程序中使用像 PCAP 这样的数据包捕获库。您可以捕获整个数据包并分析其内容。您甚至可以应用数据包过滤。

    就读取而言,您可以像任何其他设备或文件一样通过读取系统调用通过提供套接字的文件描述符从套接字读取数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-18
      • 1970-01-01
      • 1970-01-01
      • 2016-12-13
      • 1970-01-01
      • 1970-01-01
      • 2018-01-18
      • 1970-01-01
      相关资源
      最近更新 更多