gpt4 book ai didi

c - 为什么 recvfrom 创建额外的 IP header ?

转载 作者:太空宇宙 更新时间:2023-11-04 04:33:51 26 4
gpt4 key购买 nike

为什么 recvfrom 创建额外的 IP header ?

我要发送:

-------------
- IP header -
-------------
- Data -
-------------

但是当我尝试接收数据时,看起来好像有

-------------
- IP header -
-------------
- IP header -
-------------
- Data -
-------------

客户端代码:

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <netinet/ip.h>

#define DEBUG 1


int main(void) {

// Create File descrptor for socket
int socket_fd;
if ((socket_fd = socket(AF_INET, SOCK_RAW, IPPROTO_IPV6)) < 0) {
perror("ERROR Socket");
exit(2);
}

char *srcIP = "127.0.0.1";
char *dstIP = "127.0.0.1";

// Create address structure
struct sockaddr_in daddr;
daddr.sin_family = AF_INET;
daddr.sin_port = 0; // Raw sockets can't use ports
inet_pton(AF_INET, "127.0.0.1", &daddr.sin_addr);
memset(daddr.sin_zero, 0, sizeof(daddr.sin_zero));

// Create a Packet
char packet[50];
memset(packet, 0, sizeof(packet));

// Structure packet
struct iphdr *ip_header = (struct iphdr *) packet;
// Data to be appended at the end of the ip header
char *data = (char *) (packet + (sizeof(struct iphdr)));
ip_header->version = 4; // IPv4
ip_header->tos = 0; // Type of service
ip_header->ihl = 5; // 5 x 32-bit words
// ip_header->tot_len = htons(sizeof(struct iphdr) + strlen(data)); // Total IP packet length
ip_header->tot_len = sizeof(packet); // Total IP packet length
ip_header->protocol = IPPROTO_IPV6; // 6in4 protocol
ip_header->frag_off = 0x00; //16 bit field = [0:2] flags + [3:15] offset = 0x0
ip_header->ttl = 0xFF; // Max number of hops 16bit
// ip_header->id = htons(54321); // 0x00; //16 bit id
ip_header->check = 0; //16 bit checksum of IP header. Can't calculate at this point
ip_header->saddr = inet_addr(srcIP);
ip_header->daddr = inet_addr(dstIP);
data[0] = 'T';
data[1] = 'E';
data[2] = 'S';
data[3] = 'T';
data[4] = '7';
data[5] = '\0';

// ip_header->check = csum((unsigned short *) packet, ip_header->tot_len);
#if DEBUG
printf("\nIP header checksum: %d\n", ip_header->check);
#endif

while (1) {
sleep(1);
if (sendto(socket_fd, (char *) packet, sizeof(packet), 0,
(struct sockaddr *) &daddr, (socklen_t) sizeof(daddr)) < 0)
perror("Packet send error");
}

return 0;
}

服务器代码:

/*** IPPROTO_RAW receiver ***/
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int socket_fd;
struct sockaddr_in saddr;
char packet[50];

if ((socket_fd = socket(AF_INET, SOCK_RAW, IPPROTO_IPV6)) < 0) {
perror("socket_fd");
exit(EXIT_FAILURE);
}

memset(packet, 0, sizeof(packet));
socklen_t len = (socklen_t) sizeof(saddr);

while(1) {
if (recvfrom(socket_fd, packet, sizeof(packet), 0,
(struct sockaddr *)&saddr, &len) < 0)
perror("recvfrom");

int i = sizeof(struct iphdr); ////// WHY IS DATA PAYLOAD ON packet[sizeof(struct iphdr) * 2]
while (i < sizeof(packet)) {
fprintf(stderr, "%c", packet[i]);
i++;
}
printf("\n");
}
exit(EXIT_SUCCESS);
}

最佳答案

在您的发件人中,您需要设置IP_HDRINCL 套接字选项。这告诉 API 您正在手动提供 IP header 。因为您没有设置此选项,所以您实际上是在系统添加的 IP header 之后放置了您自己的 IP header 副本。

关于c - 为什么 recvfrom 创建额外的 IP header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33288379/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com