繁体   English   中英

Solaris 10 —从来自recvmsg()的UDP多播数据包获取IP源地址

[英]Solaris 10 — get IP source address from UDP multicast packet from recvmsg()

我有创建UDP套接字以接收多播数据包的项目代码。 该代码可移植到Linux和Solaris操作系统。 我的项目的扩展正在寻找使用recvmsg()函数时UDP数据包的源IP地址。 我曾问过一位与此有关的专家,她提到Linux似乎能够提供源IP地址,但是Solaris在使用recvmsg()函数时可能无法提供源IP地址。 因此,我在这里提出一个问题,我是否可以在Solaris 10上使用recvmsg()检索源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.

我还看到了以下文章,但它们似乎没有回答我的问题: 获取收到的UDP数据包的 目标地址 ,解决方法为: 获取收到的UDP数据包的目标地址。

有两个问题:一是您在任何地方都不使用caddr ,也不说它是什么,因此很难为您提供帮助。 另一个(很可能是您遇到的问题)是从recvmsg获得的地址不是字符串。

msg.msg_name应指向struct sockaddr_inmsg.msg_namelen应该sizeof(struct sockaddr_in) 然后,您从中获得地址。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM