gpt4 book ai didi

c - 使用 C 程序在 Linux 中捕获 UDP 数据时接收相同的源地址和目标 IP 地址

转载 作者:太空宇宙 更新时间:2023-11-04 03:37:12 24 4
gpt4 key购买 nike

我试图在从端口 6343 捕获 UDP 数据时显示源和目标 IP 地址。我观察到的是我为这两个字段显示了相同的 IP 地址。以下是我正在运行的代码,

#include<stdio.h> //For standard things
#include<stdlib.h> //malloc
#include<string.h> //memset
#include<netinet/ip_icmp.h> //Provides declarations for icmp header
#include<netinet/udp.h> //Provides declarations for udp header
#include<netinet/tcp.h> //Provides declarations for tcp header
#include<netinet/ip.h> //Provides declarations for ip header
#include<sys/socket.h>
#include<arpa/inet.h>
#define PORT 6343
int sockt;
int i,j;

struct sockaddr_in source,dest;

int main()
{
int saddr_size,data_size;
struct sockaddr_in saddr;
struct sockaddr_in daddr;

//struct in_addr in;
unsigned char *buffer = (unsigned char *)malloc(65536); // Its Big ! Malloc allocates a block of size bytes of memory,returning a pointer to the begining of the block

struct udphdr *udph = (struct udphdr*)(buffer + sizeof(struct iphdr));
struct iphdr *iph = (struct iphdr *)buffer;
memset(&source,0,sizeof(source));
source.sin_addr.s_addr = iph ->saddr;
memset(&dest,0,sizeof(dest));
dest.sin_addr.s_addr = iph->daddr;
unsigned short iphdrlen = iph->ihl*4;


printf("Starting...\n");
//Create a socket
sockt = socket(AF_INET ,SOCK_DGRAM ,0);
if(sockt < 0)
{
printf("Socket Error\n");
return 1;
}
memset((char *)&saddr,0,sizeof(saddr));

//prepare the sockaddr_in structure
daddr.sin_family = AF_INET;
daddr.sin_addr.s_addr = htonl(INADDR_ANY);
daddr.sin_port = htons(PORT);

//Bind
if(bind(sockt,(struct sockaddr *)&daddr, sizeof(daddr))<0)
{
printf("bind failed");
return 1;
}
printf("bind done");

while(1)
{
saddr_size = sizeof saddr;
printf("waiting for data...");

//Receive a packet
data_size = recvfrom(sockt , buffer ,65536 , 0 , (struct sockaddr*) &saddr , (socklen_t*)&saddr_size);
if(data_size <0)
{
printf("Packets not recieved \n");
return 1;
}

printf("Packets arrived from %d \n",ntohs(daddr.sin_port));
printf("\t Source Port : %d , Destination Port : %d, UDP Length : %d, Source IP : %s, Destination IP : %s, Protocol : %d, total length : %d \n", ntohs(udph->source), ntohs(udph->dest), ntohs(data_size), inet_ntoa(saddr.sin_addr),inet_ntoa(daddr.sin_addr), (unsigned int)iph->protocol, ntohs(iph->tot_len));
ProcessPacket(buffer,data_size);
}
close(sockt);
printf("Finished");
return 0;
}

我收到的输出是:

Source Port : 55600 , Destination Port : 9162, UDP Length : 7173, Source IP : 147.188.195.6, Destination IP : 147.188.195.6, Protocol : 188, total length : 5

我是在显示 IP 地址时出错了,还是没有指向正确的位置来获取地址?

最佳答案

inet_ntoa() 是一个不可重入函数。它会在您每次调用它时返回指向同一缓冲区的指针,因此当您在一条语句中调用它两次时,其中一个调用会覆盖另一个调用生成的缓冲区的内容。

而是分几个步骤来做:

printf("\t Source Port : %d , Destination Port : %d, UDP Length :%d, ",
ntohs(udph->source), ntohs(udph->dest), ntohs(data_size));
printf("Source IP : %s, ", inet_ntoa(saddr.sin_addr));
printf("Destination IP : %s, ", inet_ntoa(daddr.sin_addr));
printf("Protocol : %d, total length : %d \n",
(unsigned int)iph->protocol, ntohs(iph->tot_len));

关于c - 使用 C 程序在 Linux 中捕获 UDP 数据时接收相同的源地址和目标 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31681873/

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