c-IPv4总长度超过特制数据包的数据包长度(64字节)



目标:从零开始制作一个数据包,包括以太网头、ip头、udp头和seccomp_data结构作为数据。问题:我正在努力正确地处理数据包,事实上,目前当我嗅探流量时,wireshark向我提供了专家信息(错误/协议(: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 %dn, tot_len %dn", tx_len, iph->tot_len);
if (sendto(sockfd, buf, tx_len, 0, (struct sockaddr*)&dst_addr, sizeof(struct sockaddr_ll)) < 0)
printf("Send failedn");
return 0;


}

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

最新更新