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()
总长度字段。
目标: 从零开始制作一个数据包,包括以太网 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()
总长度字段。