<ol>
<li>You have multiple network adapters.</li>
<li>Bind a UDP socket to an local port, without specifying an address.</li>
<li>Receive packets on one of the adapters.</li>
</ol>

<p>How do you get the local ip address of the adapter which received the packet?</p>

<p>The question is, "What is the ip address from the receiver adapter?" not the address from the sender which we get in the </p>

<pre><code>receive_from( ..., &amp;senderAddr, ... );
</code></pre>

<p>call.</p>

[{'answer_id': 29912, 'author': 'diciu', 'author_id': 2811, 'author_profile': 'https://Stackoverflow.com/users/2811', 'pm_score': -1, 'selected': False, 'text': '<pre>\nssize_t\n     recvfrom(int socket, void *restrict buffer, size_t length, int flags,\n         struct sockaddr *restrict address, socklen_t *restrict address_len);\n\n     ssize_t\n     recvmsg(int socket, struct msghdr *message, int flags);\n\n[..]\n     If address is not a null pointer and the socket is not connection-oriented, the\n     source address of the message is filled in.\n</pre> \n\n<p>Actual code:</p>\n\n<p><code>\nint nbytes = recvfrom(sock, buf, MAXBUFSIZE, MSG_WAITALL, (struct sockaddr *)&amp;bindaddr, &amp;addrlen);</p>\n\n<p>fprintf(stdout, "Read %d bytes on local address %s\\n", nbytes, inet_ntoa(bindaddr.sin_addr.s_addr));\n</code></p>\n\n<p>hope this helps.</p>\n'}, {'answer_id': 29916, 'author': 'Timbo', 'author_id': 1810, 'author_profile': 'https://Stackoverflow.com/users/1810', 'pm_score': 3, 'selected': True, 'text': "<p>You could enumerate all the network adapters, get their IP addresses and compare the part covered by the subnet mask with the sender's address.</p>\n\n<p>Like:</p>\n\n<pre><code>IPAddress FindLocalIPAddressOfIncomingPacket( senderAddr )\n{\n    foreach( adapter in EnumAllNetworkAdapters() )\n    {\n        adapterSubnet = adapter.subnetmask &amp; adapter.ipaddress;\n        senderSubnet = adapter.subnetmask &amp; senderAddr;\n        if( adapterSubnet == senderSubnet )\n        {\n            return adapter.ipaddress;\n        }\n    }\n}\n</code></pre>\n"}, {'answer_id': 29919, 'author': 'Rob Wells', 'author_id': 2974, 'author_profile': 'https://Stackoverflow.com/users/2974', 'pm_score': 2, 'selected': False, 'text': "<p>G'day,</p>\n\n<p>I assume that you've done your bind using INADDR_ANY to specify the address.</p>\n\n<p>If this is the case, then the semantics of INADDR_ANY is such that a UDP socket is created on the port specified on all of your interfaces. The socket is going to get all packets sent to all interfaces on the port specified.</p>\n\n<p>When sending using this socket, the lowest numbered interface is used. The outgoing sender's address field is set to the IP address of that first outgoing interface used.</p>\n\n<p>First outgoing interface is defined as the sequence when you do an ifconfig -a. It will probably be eth0.</p>\n\n<p>HTH.</p>\n\n<p>cheers,\nRob</p>\n"}, {'answer_id': 108075, 'author': 'Andrew Edgecombe', 'author_id': 11694, 'author_profile': 'https://Stackoverflow.com/users/11694', 'pm_score': 2, 'selected': False, 'text': '<p>The solution provided by <a href="https://stackoverflow.com/users/1810/timbo">timbo</a> assumes that the address ranges are unique and not overlapping. While this is usually the case, it isn\'t a generic solution.</p>\n\n<p>There is an excellent implementation of a function that does exactly what you\'re after provided in the Steven\'s book "Unix network programming" (section 20.2)\nThis is a function based on recvmsg(), rather than recvfrom(). If your socket has the IP_RECVIF option enabled then recvmsg() will return the index of the interface on which the packet was received. This can then be used to look up the destination address.</p>\n\n<p>The source code is available <a href="http://www.kohala.com/start/unp.tar.Z" rel="nofollow noreferrer">here</a>. The function in question is \'recvfrom_flags()\'</p>\n'}, {'answer_id': 3946022, 'author': 'Chris Evans', 'author_id': 477458, 'author_profile': 'https://Stackoverflow.com/users/477458', 'pm_score': -1, 'selected': False, 'text': '<p>Try this:</p>\n\n<pre><code>gethostbyname("localhost");\n</code></pre>\n'}, {'answer_id': 38937608, 'author': 'plugwash', 'author_id': 5083516, 'author_profile': 'https://Stackoverflow.com/users/5083516', 'pm_score': 1, 'selected': False, 'text': '<p>Unfortunately the sendto and recvfrom API calls are fundamentally broken when used with sockets bound to "Any IP" because they have no field for local IP information. </p>\n\n<p>So what can you do about it? </p>\n\n<ol>\n<li>You can guess (for example based on the routing table).</li>\n<li>You can get a list of local addresses and bind a seperate socket to each local address. </li>\n<li>You can use newer APIs that support this information. There are two parts to this, firstly you have to use the relavent socket option (ip_recvif for IPv4, ipv6_recvif for IPv6) to tell the stack you want this information. Then you have to use a different function (recvmsg on linux and several other unix-like systems, WSArecvmsg on windows) to receive the packet. </li>\n</ol>\n\n<p>None of these options are great. Guessing will obviously produce wrong answers soemtimes. Binding seperate sockets increases the complexity of your software and causes problems if the list of local addresses changes will your program is running. The newer APIs are the correct techical soloution but may reduce portability <s>(in particular it looks like WSArecvmsg is not available on windows XP)</s> and may require modifications to the socket wrapper library you are using.</p>\n\n<p>Edit looks like I was wrong, it seems the MS documentation is misleading and that WSArecvmsg is available on windows XP. See <a href="https://stackoverflow.com/a/37334943/5083516">https://stackoverflow.com/a/37334943/5083516</a></p>\n'}, {'answer_id': 63698826, 'author': 'xyanping', 'author_id': 14206102, 'author_profile': 'https://Stackoverflow.com/users/14206102', 'pm_score': 0, 'selected': False, 'text': '<p>In Linux environment, you can use <strong>recvmsg</strong> to get local ip address.</p>\n<pre class="lang-cpp prettyprint-override"><code>    //create socket and bind to local address:INADDR_ANY:\n    int s = socket(PF_INET,SOCK_DGRAM,0);\n    bind(s,(struct sockaddr *)&amp;myAddr,sizeof(myAddr)) ;\n    // set option\n    int onFlag=1;\n    int ret = setsockopt(s,IPPROTO_IP,IP_PKTINFO,&amp;onFlag,sizeof(onFlag));\n    // prepare buffers\n    // receive data buffer\n    char dataBuf[1024] ;\n    struct iovec iov = {\n        .iov_base=dataBuf,\n        .iov_len=sizeof(dataBuf)\n    } ;\n    // control buffer\n    char cBuf[1024] ;\n    // message\n    struct msghdr  msg = {\n        .msg_name=NULL, // to receive peer addr with struct sockaddr_in\n        .msg_namelen=0, // sizeof(struct sockaddr_in)\n        .msg_iov=&amp;iov,\n        .msg_iovlen=1,\n        .msg_control=cBuf,\n        .msg_controllen=sizeof(cBuf)\n    } ;\n    while(1) {\n        // reset buffers\n        msg.msg_iov[0].iov_base = dataBuf ;\n        msg.msg_iov[0].iov_len = sizeof(dataBuf) ;\n        msg.msg_control = cBuf ;\n        msg.msg_controllen = sizeof(cBuf) ;\n        // receive\n        recvmsg(s,&amp;msg,0);\n        for( struct cmsghdr* pcmsg=CMSG_FIRSTHDR(&amp;msg);\n             pcmsg!=NULL; pcmsg=CMSG_NXTHDR(&amp;msg,pcmsg) ) {\n            if(pcmsg-&gt;cmsg_level==IPPROTO_IP &amp;&amp; pcmsg-&gt;cmsg_type==IP_PKTINFO) {\n                struct in_pktinfo * pktinfo=(struct in_pktinfo *)CMSG_DATA(pcmsg);\n                printf(&quot;ifindex=%d ip=%s\\n&quot;, pktinfo-&gt;ipi_ifindex, inet_ntoa(pktinfo-&gt;ipi_addr)) ;\n            }\n        }\n    }\n</code></pre>\n<hr />\n<p><strong>The following does not work in asymmetric routing environment.</strong></p>\n<p>you can first set SO_REUSEADDR to true</p>\n<pre><code>BOOL bOptVal = 1;\nsetsockopt(so, SOL_SOCKET, SO_REUSEADDR, (char *)&amp;boOptVal, sizeof(bOptVal));\n</code></pre>\n<p>after <code>receive_from( ..., &amp;remoteAddr, ... );</code> create another socket, and connect back to  remoteAddr. Then call getsockname can get the ip address.</p>\n<pre><code>SOCKET skNew = socket( )\n// Same local address and port as that of your first socket \n// INADDR_ANY\nbind(skNew, ,  )\n// set SO_REUSEADDR to true again\nsetsockopt(skNew, SOL_SOCKET, SO_REUSEADDR, (char *)&amp;boOptVal, sizeof(bOptVal));\n\n// connect back  \nconnect(skNew, remoteAddr)\n\n// get local address of the socket\ngetsocketname(skNew, )\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/29890', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3186/']