Forum Stats

  • 3,855,570 Users
  • 2,264,523 Discussions
  • 7,906,069 Comments

Discussions

How to get the dest. IP and Port of a datagram packet

I have a computer with many IP address, and run a UDP server on it. When the data arrives, I want to know which IP address is used. I created the following program as a demo. It works well in FreeBSD. But in Solaris 2.6, it does not.

#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>

main(){
int sock, length, count;
int on=1;
struct sockaddr_in addr;
struct msghdr msg;
struct sockaddr_in from[2];
struct iovec aiov[1];

struct cmsghdr{
u_int len;
int level;
int name;
struct in_addr addr;
unsigned short port;
} cmsg;

char buff[1000];

sock=socket(AF_INET, SOCK_DGRAM,0);
if(setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, (char *)&on, sizeof(on)) != 0){
perror("Setsockopt");
exit(1);
}

if(sock < 0){
perror("Opening datagram socket");
exit(1);
}

bzero(&addr, sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(6000);
if(bind(sock, (struct sockaddr *)&addr, sizeof addr) == -1){
perror("Binding datagram socket");
exit(1);
};

length=sizeof(addr);
if(getsockname(sock, (struct sockaddr *)&addr, &length) == -1){
perror("Getting socket name");
exit(1);
}

aiov[0].iov_base=buff;
aiov[0].iov_len= sizeof(buff);
msg.msg_name=(char *)&from[0];
msg.msg_namelen=sizeof(struct sockaddr_in);
msg.msg_iov=aiov;
msg.msg_iovlen=1;
msg.msg_control=(char *)&cmsg;
msg.msg_controllen=sizeof(cmsg);

while(1){
count=recvmsg(sock, &msg, 0);
if(count>=0) buff[count]=0;
printf("%x[%d] recieves %d bytes from [%x:d]: %s\n",
from[0].sin_addr.s_addr,
ntohs(from[0].sin_port),
count,
cmsg.addr.s_addr, ntohs(cmsg.port), buff);
}
close(sock);
}
This discussion has been closed.