2

マルチキャストパケットを受信するためのUDPソケットを作成するプロジェクトコードがあります。このコードは、LinuxおよびSolarisオペレーティングシステムに移植可能です。私のプロジェクトの拡張機能は、recvmsg()関数を使用するときに、UDPパケットの送信元IPアドレスを取得しようとしています。私はこの問題について仲間の専門家に尋ねたところ、彼女はLinuxが送信元IPアドレスを提供できるように見えるが、Solarisはrecvmsg()関数を使用している場合は提供できない可能性があると述べました。そこで、ここで質問をします。Solaris10でrecvmsg()を使用して送信元IPアドレスを取得できますか?

OS: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パケットの宛先アドレスを取得します。

4

1 に答える 1

1

2つの問題があります。1つは、caddrどこでも使用しないことと、それが何であるかを言わないことです。そのため、あなたを助けるのは難しいです。もう1つ(そしておそらくあなたが抱えている問題)は、あなたが取得するアドレスが文字列でrecvmsgないということです。

msg.msg_nameaを指す必要がstruct sockaddr_inありmsg.msg_namelenますsizeof(struct sockaddr_in)。次に、そこからアドレスを取得します。

于 2012-06-07T05:16:57.863 に答える