c - IP/UDP数据包头细节过滤

标签 c sockets networking udp pcap

嗨,我正在尝试解析 Ip/Udp 数据包的 header 详细信息,以实际获取时间戳、端口地址等。我知道我可以使用库来执行此操作。因此,经过大量谷歌搜索后,我找到了一个通过以下方法解析行数据包的代码

void dump_UDP_packet(const unsigned char *packet, struct timeval ts,
                     unsigned int capture_len)
{
    struct ip *ip;
    struct UDP_hdr *udp;
    unsigned int IP_header_length;

    /* For simplicity, we assume Ethernet encapsulation. */

    if (capture_len < sizeof(struct ether_header))
    {
        /* We didn't even capture a full Ethernet header, so we
         * can't analyze this any further.
         */
        too_short(ts, "Ethernet header");
        return;
    }

    /* Skip over the Ethernet header. */
    packet += sizeof(struct ether_header);
    capture_len -= sizeof(struct ether_header);

    if (capture_len < sizeof(struct ip))
    { /* Didn't capture a full IP header */
        too_short(ts, "IP header");
        return;
    }

    ip = (struct ip*) packet;
    IP_header_length = ip->ip_hl * 4;   /* ip_hl is in 4-byte words */

    if (capture_len < IP_header_length)
    { /* didn't capture the full IP header including options */
        too_short(ts, "IP header with options");
        return;
    }

    if (ip->ip_p != IPPROTO_UDP)
    {
        problem_pkt(ts, "non-UDP packet");
        return;
    }

    /* Skip over the IP header to get to the UDP header. */
    packet += IP_header_length;
    capture_len -= IP_header_length;

    if (capture_len < sizeof(struct UDP_hdr))
    {
        too_short(ts, "UDP header");
        return;
    }

    udp = (struct UDP_hdr*) packet;

    printf("%s UDP src_port=%d dst_port=%d length=%d\n",
           timestamp_string(ts),
           ntohs(udp->uh_sport),
           ntohs(udp->uh_dport),
           ntohs(udp->uh_ulen));
}

问题是我真的不知道应该使用哪些参数来调用这个函数,即数据包?时间值?等我通过监听端口并使用 recv() 函数使用套接字 api 接收数据包

for (;;)
    {
        len = sizeof(cliaddr);
        n = recvfrom(sockfd,mesg,1000,0,(struct sockaddr *)&cliaddr,&len);
        //sendto(sockfd,mesg,n,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
        printf("-------------------------------------------------------\n");

        printf("%s\n from:%s port number:%d",mesg,inet_ntoa(cliaddr.sin_addr),cliaddr.sin_port);
        printf("-------------------------------------------------------\n");
    }

现在我可以使用 mesg[] 传递给上述函数来获取数据包详细信息,否则是否有其他方法从特定端口接收数据包。我应该为 timeVal 使用什么值。任何帮助对我都会有用。提前致谢

最佳答案

这里最相关的是如何打开套接字。您是否使用 SOCK_RAW 标志创建套接字?如果是,那么 recvfrom 将收到 RAW 数据包,您可以将其直接发送到您的函数。我不确定 Windows 上的情况,但在 Linux 上创建原始套接字的代码如下::

sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));

timeval 参数与数据包没有直接关系。应该是你收到包裹的时间。您可以通过在 recvfrom 之后调用 gettimeofday 来获取它。

关于c - IP/UDP数据包头细节过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21429853/

相关文章:

c - 关于 CPU 利用率

c - 将字符串作为 case 条件传递

java - 使用BufferedOutputStream/BufferedInputStream的socket随机接收虚假数据

c - 网络编程中char数组的问题

c - 如何使用 qsort 对结构体数组中的数据进行排序 (C)

c - C 中的简单字符串运行时错误?

java - 将字符串转换为套接字

sockets - POSIX POLLOUT和阻止文件描述符

Java:地址已被使用

C# 网络打印