IPv4 总长度超过了精心制作的数据包的数据包长度(64 字节)

IPv4 total length exceeds packet length (64 bytes) on crafted packet

目标: 从零开始制作一个数据包,包括以太网 header、ip header、udp header 和 seccomp_data结构作为数据。 问题:我正在努力正确制作数据包,事实上,目前当我嗅探流量时,wireshark 给我专家信息(Error/Protocol):IPv4 总长度超过数据包长度( 64 字节),其中数据包的结果长度为 23552。我错过了什么?

#include <sys/socket.h>
#include <linux/if_packet.h>
#include <net/ethernet.h> /* the L2 protocols */
#include <netinet/ip.h> 
#include <netinet/udp.h> 
#include <stdio.h>
#include <arpa/inet.h> /* htons */
#include <sys/ioctl.h> 
#include <net/if.h> /* ifreq */
#include <string.h> 
#include <stdlib.h>


#include <linux/seccomp.h> /* seccomp_data */

#define BUF_SIZE 1024 
int main(){

    const char IF[] = "lo"; // modify to change interface
    int sockfd, ifindex, tx_len=ETH_HLEN;
    struct ifreq ifr;
    size_t if_name_len;
    char buf[BUF_SIZE];
    struct ether_header *eh = (struct ether_header *) buf;
    struct iphdr *iph = (struct iphdr *) (buf + sizeof(struct ether_header));
    struct udphdr *udph = (struct udphdr *) (buf + sizeof(struct ether_header) + sizeof(struct iphdr));
    unsigned char *data = buf + sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct udphdr);
    struct sockaddr_ll dst_addr;
    struct seccomp_data sec_payload;
    const char dmac[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
    const char smac[] = {0xff, 0x99, 0x88, 0x77, 0x66, 0x55};

    // create raw socket to send/receive ethernet frames that transport ip packet
    if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP))) == -1) {
        perror("socket");
    }

    // get interface name length
    if_name_len = strlen(IF);
    if(if_name_len < IF_NAMESIZE) {
        strncpy(ifr.ifr_name, IF, strlen(IF));
        ifr.ifr_name[if_name_len]=0;
    }

    // get the interface index number
    if(ioctl(sockfd, SIOCGIFINDEX, &ifr) == -1){
        perror("ioctl");
    }
        ifindex = ifr.ifr_ifindex;

    // build ethernet header    
        memcpy(eh->ether_dhost, dmac, ETHER_ADDR_LEN);  
        memcpy(eh->ether_shost, smac, ETHER_ADDR_LEN);  
    eh->ether_type = htons(ETH_P_IP);

    // add a struct seccomp_data as data 
        memset(&sec_payload,0,sizeof(struct seccomp_data)); 
    data = (char*)malloc(sizeof(struct seccomp_data));
    memcpy(data, (const unsigned char *)&sec_payload, sizeof(struct seccomp_data));

    int i;
    for(i=0;i<sizeof(sec_payload);i++){
        buf[tx_len++] = data[i];
        printf("%02X ",data[i]);
        }

    // build ip header
    iph->ihl = 5;
    iph->version = 4;
    iph->tos = 0;
    iph->tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(sec_payload);
    iph->id = htons(54321);
    iph->frag_off = 0;
    iph->ttl = 64;
    iph->protocol = IPPROTO_UDP;
    iph->saddr = inet_addr("127.0.0.1");
    iph->daddr = inet_addr("127.0.0.1");


        memset(&dst_addr,0,sizeof(struct sockaddr_ll)); 
    dst_addr.sll_ifindex = ifr.ifr_ifindex; 
    dst_addr.sll_halen = ETH_ALEN;
    memcpy(dst_addr.sll_addr, dmac, ETH_ALEN);
    printf("tx_len %d\n, tot_len %d\n", tx_len, iph->tot_len);

        if (sendto(sockfd, buf, tx_len, 0, (struct sockaddr*)&dst_addr, sizeof(struct sockaddr_ll)) < 0)
        printf("Send failed\n");
    return 0;




}

网络字节顺序(字节通常在 Internet 协议上传输的顺序)是大端字节序,首先传输最重要的字节。特别是,您需要 htons() 总长度字段。