#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h> // call to exit()
#define CONNECTED_PORT 29000
#define EXAMPLE_REMOTE_IP "8.8.8.8"
#define EXAMPLE_REMOTE_PORT 33222
void die( const char * msg) {
}
void grep( int port) {
char command[ 64 ] ;
char buffer[ 256 ] ;
sprintf ( command
, "lsof | grep -o 'UDP.*%d'" , port
) ; FILE * output = popen( command, "r" ) ;
printf ( " --> Output from lsof | grep -o 'UDP.*%d'\n " , port
) ; while ( fgets ( buffer
, 256 , output
) != NULL
) pclose( output) ;
sprintf ( command
, "netstat -anu | grep %d" , port
) ; output = popen( command, "r" ) ;
printf ( " --> Output from netstat -anu | grep %d\n " , port
) ; while ( fgets ( buffer
, 256 , output
) != NULL
) pclose( output) ;
}
int main( void ) {
struct sockaddr_in co_sockaddr, remote_sockaddr;
int co_s;
memset ( ( char * ) & co_sockaddr
, 0 , sizeof ( co_sockaddr
) ) ; memset ( ( char * ) & remote_sockaddr
, 0 , sizeof ( remote_sockaddr
) ) ;
puts ( "--> Creating socket" ) ; if ( ( co_s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP) ) == - 1 )
die( "connected socket()\n " ) ;
co_sockaddr.sin_family = AF_INET;
co_sockaddr.sin_port = htons( CONNECTED_PORT) ;
co_sockaddr.sin_addr .s_addr = htonl( INADDR_ANY) ;
printf ( "--> Binding socket to INADDR_ANY:%d (aka *:%d or 0.0.0.0:%d)\n " , CONNECTED_PORT
, CONNECTED_PORT
, CONNECTED_PORT
) ; if ( bind( co_s, ( struct sockaddr * ) & co_sockaddr, sizeof ( co_sockaddr) ) == - 1 )
die( "connected bind()\n " ) ;
/* At this point, the socket is correctly shown as accepting on all interfaces,
as shown by the following output of lsof and netstat */
grep( CONNECTED_PORT) ;
remote_sockaddr.sin_family = AF_INET;
remote_sockaddr.sin_port = htons( EXAMPLE_REMOTE_PORT) ;
if ( inet_aton( EXAMPLE_REMOTE_IP, & remote_sockaddr.sin_addr ) == 0 )
die( "remote inet_aton()\n " ) ;
printf ( "--> Connecting socket to %s:%d (no data will be sent)\n " , EXAMPLE_REMOTE_IP
, EXAMPLE_REMOTE_PORT
) ; if ( connect( co_s, ( struct sockaddr * ) & remote_sockaddr, sizeof ( remote_sockaddr) ) == - 1 )
die( "connect()\n " ) ;
/* Here, the socket is not bound to * or 0.0.0.0 anymore, but to one of the interfaces only. Why?
The manual pages for bind() or connect() do not provide any helpful information */
grep( CONNECTED_PORT) ;
close( co_s) ;
}
I2luY2x1ZGUgPGFycGEvaW5ldC5oPgojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPiAvLyBjYWxsIHRvIGV4aXQoKQoKI2RlZmluZSBDT05ORUNURURfUE9SVCAyOTAwMAojZGVmaW5lIEVYQU1QTEVfUkVNT1RFX0lQICI4LjguOC44IgojZGVmaW5lIEVYQU1QTEVfUkVNT1RFX1BPUlQgMzMyMjIKCnZvaWQgZGllKGNvbnN0IGNoYXIgKiBtc2cpIHsKCXBlcnJvcihtc2cpOwoJZXhpdCgxKTsKfQoKdm9pZCBncmVwKGludCBwb3J0KSB7CgljaGFyIGNvbW1hbmRbNjRdOwoJY2hhciBidWZmZXJbMjU2XTsKCglzcHJpbnRmKGNvbW1hbmQsICJsc29mIHwgZ3JlcCAtbyAnVURQLiolZCciLCBwb3J0KTsKCUZJTEUgKiBvdXRwdXQgPSBwb3Blbihjb21tYW5kLCAiciIpOwoJcHJpbnRmKCIgIC0tPiBPdXRwdXQgZnJvbSBsc29mIHwgZ3JlcCAtbyAnVURQLiolZCdcbiIsIHBvcnQpOwoJd2hpbGUgKGZnZXRzKGJ1ZmZlciwgMjU2LCBvdXRwdXQpICE9IE5VTEwpCgkJcHV0cyhidWZmZXIpOwoJcGNsb3NlKG91dHB1dCk7CgoJc3ByaW50Zihjb21tYW5kLCAibmV0c3RhdCAtYW51IHwgZ3JlcCAlZCIsIHBvcnQpOwoJb3V0cHV0ID0gcG9wZW4oY29tbWFuZCwgInIiKTsKCXByaW50ZigiICAtLT4gT3V0cHV0IGZyb20gbmV0c3RhdCAtYW51IHwgZ3JlcCAlZFxuIiwgcG9ydCk7Cgl3aGlsZSAoZmdldHMoYnVmZmVyLCAyNTYsIG91dHB1dCkgIT0gTlVMTCkKCQlwdXRzKGJ1ZmZlcik7CglwY2xvc2Uob3V0cHV0KTsKfQoKaW50IG1haW4odm9pZCkgewoJc3RydWN0IHNvY2thZGRyX2luIGNvX3NvY2thZGRyLCByZW1vdGVfc29ja2FkZHI7CglpbnQgY29fczsKCgltZW1zZXQoKGNoYXIgKikgJmNvX3NvY2thZGRyLCAwLCBzaXplb2YoY29fc29ja2FkZHIpKTsKCW1lbXNldCgoY2hhciAqKSAmcmVtb3RlX3NvY2thZGRyLCAwLCBzaXplb2YocmVtb3RlX3NvY2thZGRyKSk7CgoJcHV0cygiLS0+IENyZWF0aW5nIHNvY2tldCIpOwoJaWYgKChjb19zID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfREdSQU0sIElQUFJPVE9fVURQKSkgPT0gLTEpCgkJZGllKCJjb25uZWN0ZWQgc29ja2V0KClcbiIpOwoKCWNvX3NvY2thZGRyLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwoJY29fc29ja2FkZHIuc2luX3BvcnQgPSBodG9ucyhDT05ORUNURURfUE9SVCk7Cgljb19zb2NrYWRkci5zaW5fYWRkci5zX2FkZHIgPSBodG9ubChJTkFERFJfQU5ZKTsKCglwcmludGYoIi0tPiBCaW5kaW5nIHNvY2tldCB0byBJTkFERFJfQU5ZOiVkIChha2EgKjolZCBvciAwLjAuMC4wOiVkKVxuIiwgQ09OTkVDVEVEX1BPUlQsIENPTk5FQ1RFRF9QT1JULCBDT05ORUNURURfUE9SVCk7CglpZiAoYmluZChjb19zLCAoc3RydWN0IHNvY2thZGRyICopICZjb19zb2NrYWRkciwgc2l6ZW9mKGNvX3NvY2thZGRyKSkgPT0gLTEpCgkJZGllKCJjb25uZWN0ZWQgYmluZCgpXG4iKTsKCgkvKiBBdCB0aGlzIHBvaW50LCB0aGUgc29ja2V0IGlzIGNvcnJlY3RseSBzaG93biBhcyBhY2NlcHRpbmcgb24gYWxsIGludGVyZmFjZXMsCgkgICBhcyBzaG93biBieSB0aGUgZm9sbG93aW5nIG91dHB1dCBvZiBsc29mIGFuZCBuZXRzdGF0ICovCgoJZ3JlcChDT05ORUNURURfUE9SVCk7CgoJcmVtb3RlX3NvY2thZGRyLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwoJcmVtb3RlX3NvY2thZGRyLnNpbl9wb3J0ID0gaHRvbnMoRVhBTVBMRV9SRU1PVEVfUE9SVCk7CglpZiAoaW5ldF9hdG9uKEVYQU1QTEVfUkVNT1RFX0lQLCAmcmVtb3RlX3NvY2thZGRyLnNpbl9hZGRyKSA9PSAwKQoJCWRpZSgicmVtb3RlIGluZXRfYXRvbigpXG4iKTsKCglwcmludGYoIi0tPiBDb25uZWN0aW5nIHNvY2tldCB0byAlczolZCAobm8gZGF0YSB3aWxsIGJlIHNlbnQpXG4iLCBFWEFNUExFX1JFTU9URV9JUCwgRVhBTVBMRV9SRU1PVEVfUE9SVCk7CglpZiAoY29ubmVjdChjb19zLCAoc3RydWN0IHNvY2thZGRyICopICZyZW1vdGVfc29ja2FkZHIsIHNpemVvZihyZW1vdGVfc29ja2FkZHIpKSA9PSAtMSkKCQlkaWUoImNvbm5lY3QoKVxuIik7CgoJLyogSGVyZSwgdGhlIHNvY2tldCBpcyBub3QgYm91bmQgdG8gKiBvciAwLjAuMC4wIGFueW1vcmUsIGJ1dCB0byBvbmUgb2YgdGhlIGludGVyZmFjZXMgb25seS4gV2h5PwoJICAgVGhlIG1hbnVhbCBwYWdlcyBmb3IgYmluZCgpIG9yIGNvbm5lY3QoKSBkbyBub3QgcHJvdmlkZSBhbnkgaGVscGZ1bCBpbmZvcm1hdGlvbiAqLwoKCWdyZXAoQ09OTkVDVEVEX1BPUlQpOwoKCWNsb3NlKGNvX3MpOwoJCn0K