2012-06-06 36 views
1

我有创建UDP套接字以接收多播数据包的项目代码。该代码适用于Linux和Solaris操作系统。我的项目的一个扩展是使用recvmsg()函数来查找UDP数据包的源IP地址。我曾就此问过一位专家,她提到Linux似乎能够提供源IP地址,但Solaris在使用recvmsg()函数时可能不会。所以我在这里提出问题,我能否在Solaris 10上使用recvmsg()检索源IP地址?Solaris 10 - 从recvmsg的UDP多播数据包获取IP源地址()

操作系统:Solaris 10,Sunstudio 12 cc(无U1或U2)。 代码库: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. 

我也看了下面的文章,但他们似乎并没有回答我的问题: Get destination address of a received UDP packet,解决方案在:Get destination address of a received UDP packet

回答

0

有两个问题:一个是你不会在任何地方使用caddr,你也不会说它是什么,所以它很难帮助你;其他(可能是你遇到的问题)是你从recvmsg得到的地址是而不是的一个字符串。

msg.msg_name应指向struct sockaddr_inmsg.msg_namelen应该sizeof(struct sockaddr_in)。然后你从那里得到地址。

+0

看起来像msg结构中使用的sockaddr_in将从套接字中检索源IP信息。我能够验证这一点。 – Jenner