我正在尝试从端口6343捕获UDP数据时显示源IP地址和目标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;
}
我收到的输出是:
源端口:55600,目标端口:9162,UDP长度:7173,源IP:147.188.195.6,目标IP:147.188.195.6,协议:188,总长度: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));
在必须保存源和目标IP地址的情况下,最好使用strcpy函数。例如,>
strcpy(src_ipaddr,inet_ntoa(saddr.sin_addr));;strcpy(dst_ipaddr,inet_ntoa(daddr.sin_addr));
其中src_ipaddr和dst_ipaddr是char *。