I have project code which creates a UDP socket to receive multicast packets. The code is portable for Linux and Solaris operating systems. An extension of my project is looking to retrieve the source IP address of the UDP packet when using the recvmsg() function. I had asked a fellow expert on the matter, and she mentioned that Linux appears to be able to provide the source IP address, but Solaris may not when using the recvmsg() function. So I pose the question here, am I able to retrieve the source IP address using recvmsg() on Solaris 10?
OS: Solaris 10, Sunstudio 12 cc (no U1 or U2). Code base: C/C++
//Socket initially opened with the following options from a different function.
// This connects the socket to receive multicast:
setsockopt(data->fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
(char *)&mregs, sizeof(mregs) ) < 0)
//A different function performs an infinite loop reading from the socket:
struct iovec vector;
vector.iov_base = buf; //passed in param
vector.iov_len = len; //passed in param
struct msghdr msg;
char caddr[100] ;
msg.msg_name = caddr;
msg.msg_namelen = 100;
msg.msg_iov = &vector;
msg.msg_iovlen = 1;
int flags = 0;
char controlBuffer[1024];
msg.msg_control = controlBuffer;
msg.msg_controllen = 1024;
bytes = ::recvmsg(data->fd, &msg, flags);
//removed error checking
struct cmsghdr *cmsg;
struct in_pktinfo *dest_ip_ptr;
rrcp_u32_t dest_ip = 0;
cmsg = CMSG_FIRSTHDR(&msg);
for ( cmsg = CMSG_FIRSTHDR(&msg);
cmsg != NULL;
cmsg = CMSG_NXTHDR( &msg, cmsg ) )
{
//if ( cmsg->cmsg_type == IPPROTO_IP && cmsg->cmsg_level == IP_PKTINFO )
{
#ifdef Linux
struct in_pktinfo *dest_ip_ptr = (struct in_pktinfo*)CMSG_DATA(cmsg);
dest_ip = dest_ip_ptr->ipi_addr.s_addr;
#else
//in_addr only has 1 address
struct in_addr * dest_ip_ptr = (struct in_addr *)CMSG_DATA(cmsg);
dest_ip = dest_ip_ptr->_S_un._S_addr;
#endif
}
}
if( ipaddr )
ipaddr->IP = dest_ip;
//according to the Linux article mentioned below, the caddr should have the source
//socket address. In my case, the caddr field is not filled with any coherent data,
//so this does not seem to be the source address. Then again, "source socket" could
//be the interface IP on the local machine, which isn't what I need.
I also saw the following articles, but they didn't seem to answer my questions: Get destination address of a received UDP packet, solution at: Get destination address of a received UDP packet