with open example c sockets broadcast datagram netcat

open - ¿Por qué netcat no puede recibir el segundo mensaje de difusión?



netcat use (1)

Al experimentar con mensajes de difusión (en una máquina virtual Debian 8.3 que se ejecuta en VirtualBox 5.0.14 en una computadora portátil con Windows 7) descubrí que netcat (nc) recibe solo el primer mensaje de difusión. No recibe el segundo mensaje de difusión.

Programas

Aquí está el programa del cliente.

// client.c #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netdb.h> int main() { int sockfd; int ret; char buffer[1024]; ssize_t bytes; int yes = 1; struct addrinfo hints, *ai, *aii; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; if ((ret = getaddrinfo("255.255.255.255", "9090", &hints, &ai)) == -1) { fprintf(stderr, "client: getaddrinfo() error: %s/n", gai_strerror(ret)); return EXIT_FAILURE; } for (aii = ai; aii != NULL; aii = aii->ai_next) { sockfd = socket(aii->ai_family, aii->ai_socktype, aii->ai_protocol); if (sockfd == -1) { perror("client: socket()"); continue; } break; } freeaddrinfo(ai); if (aii == NULL) { fprintf(stderr, "client: cannot create socket/n"); return EXIT_FAILURE; } if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof yes) == -1) { perror("client: setsockopt()"); return EXIT_FAILURE; } // 1st sendto(). strncpy(buffer, "hello from client/n", sizeof buffer); bytes = sendto(sockfd, buffer, strlen(buffer), 0, aii->ai_addr, aii->ai_addrlen); printf("client: sent %jd bytes/n", (intmax_t) bytes); // 2nd sendto(). strncpy(buffer, "bye from client/n", sizeof buffer); bytes = sendto(sockfd, buffer, strlen(buffer), 0, aii->ai_addr, aii->ai_addrlen); printf("client: sent %jd bytes/n", (intmax_t) bytes); close(sockfd); return EXIT_SUCCESS; }

Aquí está el programa de servidor.

// server.c #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netdb.h> int main() { int sockfd; int ret; struct addrinfo hints, *ai, *aii; char ip[INET_ADDRSTRLEN]; struct sockaddr_in *sa; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; if ((ret = getaddrinfo(NULL, "9090", &hints, &ai)) == -1) { fprintf(stderr, "server: getaddrinfo() error: %s/n", gai_strerror(ret)); return EXIT_FAILURE; } for (aii = ai; aii != NULL; aii = aii->ai_next) { sockfd = socket(aii->ai_family, aii->ai_socktype, aii->ai_protocol); if (sockfd == -1) { perror("socket()"); continue; } if (bind(sockfd, aii->ai_addr, aii->ai_addrlen) == -1) { perror("bind()"); close(sockfd); continue; } break; } if (aii == NULL) { fprintf(stderr, "server: error: could not bind to any address/n"); return EXIT_FAILURE; } sa = (struct sockaddr_in *) aii->ai_addr; inet_ntop(AF_INET, &sa->sin_addr, ip, sizeof ip); printf("Bound to %s:%d./n", ip, ntohs(sa->sin_port)); freeaddrinfo(ai); /* recvfrom() loop */ while (1) { struct sockaddr_storage conn_addr; socklen_t conn_addrlen = sizeof conn_addr; char buffer[1024]; ssize_t bytes; bytes = recvfrom(sockfd, buffer, sizeof buffer, 0, (struct sockaddr *) &conn_addr, &conn_addrlen); if (bytes <= 0) break; sa = (struct sockaddr_in *) &conn_addr; inet_ntop(AF_INET, &sa->sin_addr, ip, sizeof ip); printf("server: recvfrom() %jd bytes from %s:%d: %.*s", (intmax_t) bytes, ip, ntohs(sa->sin_port), (int) bytes, buffer); } close(sockfd); return EXIT_FAILURE; }

Los programas fueron compilados.

gcc -std=c99 -pedantic -Wall -Wextra -D_POSIX_C_SOURCE=200112L client.c -o client gcc -std=c99 -pedantic -Wall -Wextra -D_POSIX_C_SOURCE=200112L server.c -o server

Experimento 1: cliente => servidor (difusión)

El programa del cliente muestra la siguiente salida.

$ ./client client: sent 18 bytes client: sent 16 bytes

Ambos mensajes de difusión son recibidos por el programa del servidor.

$ ./server Bound to 0.0.0.0:9090. server: recvfrom() 18 bytes from 10.0.2.15:45807: hello from client server: recvfrom() 16 bytes from 10.0.2.15:45807: bye from client

Experimento 2: cliente => nc (difusión)

Sin embargo, si netcat se ejecuta como el oyente en el puerto 9090, recibe solo el primer mensaje de difusión.

Aquí está el resultado del programa cliente.

$ ./client client: sent 18 bytes client: sent 16 bytes

El programa de servidor no recibe el segundo mensaje de difusión.

$ nc -vvnulp 9090 listening on [any] 9090 ... connect to [10.0.2.15] from (UNKNOWN) [10.0.2.15] 39126 hello from client

Experimento 3: cliente => nc (unicast)

A continuación, se modifica el programa de cliente client.c para crear un nuevo programa client2.c de modo que lo haga unicast.

$ diff -u client.c client2.c --- client.c 2016-10-22 16:13:46.637123187 +0530 +++ client2.c 2016-10-22 16:13:41.313123187 +0530 @@ -16,14 +16,13 @@ int ret; char buffer[1024]; ssize_t bytes; - int yes = 1; struct addrinfo hints, *ai, *aii; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; - if ((ret = getaddrinfo("255.255.255.255", "9090", &hints, &ai)) == -1) { + if ((ret = getaddrinfo("10.0.2.15", "9090", &hints, &ai)) == -1) { fprintf(stderr, "client: getaddrinfo() error: %s/n", gai_strerror(ret)); return EXIT_FAILURE; } @@ -44,11 +43,6 @@ return EXIT_FAILURE; } - if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof yes) == -1) { - perror("client: setsockopt()"); - return EXIT_FAILURE; - } - // 1st sendto(). strncpy(buffer, "hello from client/n", sizeof buffer); bytes = sendto(sockfd, buffer, strlen(buffer), 0,

Aquí está el resultado del programa cliente.

$ gcc -std=c99 -pedantic -Wall -Wextra -D_POSIX_C_SOURCE=200112L client2.c -o client2 $ ./client2 client: sent 18 bytes client: sent 16 bytes

Esta vez, netcat recibe ambos mensajes de unidifusión.

$ nc -vvnulp 9090 listening on [any] 9090 ... connect to [10.0.2.15] from (UNKNOWN) [10.0.2.15] 55522 hello from client bye from client

Rastreo de llamadas del sistema

Aquí está el rastreo de llamadas al sistema para netcat en el experimento 2.

$ strace nc -vvnulp 9090 execve("/bin/nc", ["nc", "-vvnulp", "9090"], [/* 39 vars */]) = 0 brk(0) = 0xc19000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2fcd7ed000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=76016, ...}) = 0 mmap(NULL, 76016, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2fcd7da000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "/177ELF/2/1/1/3/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0P/34/2/0/0/0/0/0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1738176, ...}) = 0 mmap(NULL, 3844640, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2fcd224000 mprotect(0x7f2fcd3c6000, 2093056, PROT_NONE) = 0 mmap(0x7f2fcd5c5000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a1000) = 0x7f2fcd5c5000 mmap(0x7f2fcd5cb000, 14880, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2fcd5cb000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2fcd7d9000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2fcd7d8000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2fcd7d7000 arch_prctl(ARCH_SET_FS, 0x7f2fcd7d8700) = 0 mprotect(0x7f2fcd5c5000, 16384, PROT_READ) = 0 mprotect(0x605000, 4096, PROT_READ) = 0 mprotect(0x7f2fcd7ef000, 4096, PROT_READ) = 0 munmap(0x7f2fcd7da000, 76016) = 0 getpid() = 4161 brk(0) = 0xc19000 brk(0xc3a000) = 0xc3a000 open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=248, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2fcd7ec000 read(3, "# Generated by NetworkManager/nna"..., 4096) = 248 read(3, "", 4096) = 0 close(3) = 0 munmap(0x7f2fcd7ec000, 4096) = 0 uname({sys="Linux", node="debian1", ...}) = 0 rt_sigaction(SIGINT, {0x4025d0, [INT], SA_RESTORER|SA_RESTART, 0x7f2fcd2590e0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGQUIT, {0x4025d0, [QUIT], SA_RESTORER|SA_RESTART, 0x7f2fcd2590e0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGTERM, {0x4025d0, [TERM], SA_RESTORER|SA_RESTART, 0x7f2fcd2590e0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGURG, {SIG_IGN, [URG], SA_RESTORER|SA_RESTART, 0x7f2fcd2590e0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7f2fcd2590e0}, {SIG_DFL, [], 0}, 8) = 0 socket(PF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3 connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory) close(3) = 0 socket(PF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3 connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory) close(3) = 0 open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=529, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2fcd7ec000 read(3, "# /etc/nsswitch.conf/n#/n# Example"..., 4096) = 529 read(3, "", 4096) = 0 close(3) = 0 munmap(0x7f2fcd7ec000, 4096) = 0 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=76016, ...}) = 0 mmap(NULL, 76016, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2fcd7da000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/tls/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/x86_64-linux-gnu/tls/x86_64", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/tls/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/x86_64-linux-gnu/tls", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/x86_64-linux-gnu/x86_64", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0 open("/usr/lib/x86_64-linux-gnu/tls/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/x86_64-linux-gnu/tls/x86_64", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/usr/lib/x86_64-linux-gnu/tls/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/x86_64-linux-gnu/tls", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/usr/lib/x86_64-linux-gnu/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/x86_64-linux-gnu/x86_64", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/usr/lib/x86_64-linux-gnu/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=49152, ...}) = 0 open("/lib/tls/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/tls/x86_64", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/lib/tls/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/tls", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/lib/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/x86_64", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/lib/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 open("/usr/lib/tls/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/tls/x86_64", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/usr/lib/tls/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/tls", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/usr/lib/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/x86_64", 0x7ffe5c622430) = -1 ENOENT (No such file or directory) open("/usr/lib/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0 munmap(0x7f2fcd7da000, 76016) = 0 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=76016, ...}) = 0 mmap(NULL, 76016, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2fcd7da000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3 read(3, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0/240/"/0/0/0/0/0/0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=47712, ...}) = 0 mmap(NULL, 2144392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2fcd018000 mprotect(0x7f2fcd023000, 2093056, PROT_NONE) = 0 mmap(0x7f2fcd222000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xa000) = 0x7f2fcd222000 close(3) = 0 mprotect(0x7f2fcd222000, 4096, PROT_READ) = 0 munmap(0x7f2fcd7da000, 76016) = 0 open("/etc/services", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=19605, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2fcd7ec000 read(3, "# Network services, Internet sty"..., 4096) = 4096 read(3, "/t/t# IPX/nipx/t/t213/udp/nimap3/t/t220/"..., 4096) = 4096 read(3, "nessus/t/t1241/tcp/t/t/t# Nessus vuln"..., 4096) = 4096 read(3, "347/tcp/t/t/t# gnutella/ngnutella-rt"..., 4096) = 4096 read(3, "ureg/t779/udp/t/tmoira_ureg/t# Moira"..., 4096) = 3221 read(3, "", 4096) = 0 close(3) = 0 munmap(0x7f2fcd7ec000, 4096) = 0 socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 setsockopt(3, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0 bind(3, {sa_family=AF_INET, sin_port=htons(9090), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 getsockname(3, {sa_family=AF_INET, sin_port=htons(9090), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0 write(2, "listening on [any] 9090 ...", 27listening on [any] 9090 ...) = 27 write(2, "/n", 1 ) = 1 rt_sigaction(SIGALRM, {SIG_IGN, [ALRM], SA_RESTORER|SA_RESTART, 0x7f2fcd2590e0}, {SIG_DFL, [], 0}, 8) = 0 alarm(0) = 0 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 recvfrom(3, "hello from client/n", 8192, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(44926), sin_addr=inet_addr("10.0.2.15")}, [16]) = 18 rt_sigaction(SIGALRM, {SIG_IGN, [ALRM], SA_RESTORER|SA_RESTART, 0x7f2fcd2590e0}, {SIG_IGN, [ALRM], SA_RESTORER|SA_RESTART, 0x7f2fcd2590e0}, 8) = 0 alarm(0) = 0 connect(3, {sa_family=AF_INET, sin_port=htons(44926), sin_addr=inet_addr("10.0.2.15")}, 16) = 0 getsockopt(3, SOL_IP, IP_OPTIONS, "", [0]) = 0 getsockname(3, {sa_family=AF_INET, sin_port=htons(9090), sin_addr=inet_addr("10.0.2.15")}, [16]) = 0 write(2, "connect to [10.0.2.15] from (UNK"..., 55connect to [10.0.2.15] from (UNKNOWN) [10.0.2.15] 44926) = 55 write(2, "/n", 1 ) = 1 select(4, [0 3], NULL, NULL, NULL) = 1 (in [3]) read(3, "hello from client/n", 8192) = 18 write(1, "hello from client/n", 18hello from client ) = 18 select(4, [0 3], NULL, NULL, NULL

Aquí está el rastreo de llamadas al sistema para netcat en el experimento 3.

$ strace nc -vvnulp 9090 execve("/bin/nc", ["nc", "-vvnulp", "9090"], [/* 39 vars */]) = 0 brk(0) = 0x198e000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcec1035000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=76016, ...}) = 0 mmap(NULL, 76016, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcec1022000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "/177ELF/2/1/1/3/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0P/34/2/0/0/0/0/0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1738176, ...}) = 0 mmap(NULL, 3844640, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fcec0a6c000 mprotect(0x7fcec0c0e000, 2093056, PROT_NONE) = 0 mmap(0x7fcec0e0d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a1000) = 0x7fcec0e0d000 mmap(0x7fcec0e13000, 14880, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fcec0e13000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcec1021000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcec1020000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcec101f000 arch_prctl(ARCH_SET_FS, 0x7fcec1020700) = 0 mprotect(0x7fcec0e0d000, 16384, PROT_READ) = 0 mprotect(0x605000, 4096, PROT_READ) = 0 mprotect(0x7fcec1037000, 4096, PROT_READ) = 0 munmap(0x7fcec1022000, 76016) = 0 getpid() = 4181 brk(0) = 0x198e000 brk(0x19af000) = 0x19af000 open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=248, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcec1034000 read(3, "# Generated by NetworkManager/nna"..., 4096) = 248 read(3, "", 4096) = 0 close(3) = 0 munmap(0x7fcec1034000, 4096) = 0 uname({sys="Linux", node="debian1", ...}) = 0 rt_sigaction(SIGINT, {0x4025d0, [INT], SA_RESTORER|SA_RESTART, 0x7fcec0aa10e0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGQUIT, {0x4025d0, [QUIT], SA_RESTORER|SA_RESTART, 0x7fcec0aa10e0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGTERM, {0x4025d0, [TERM], SA_RESTORER|SA_RESTART, 0x7fcec0aa10e0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGURG, {SIG_IGN, [URG], SA_RESTORER|SA_RESTART, 0x7fcec0aa10e0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7fcec0aa10e0}, {SIG_DFL, [], 0}, 8) = 0 socket(PF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3 connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory) close(3) = 0 socket(PF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3 connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory) close(3) = 0 open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=529, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcec1034000 read(3, "# /etc/nsswitch.conf/n#/n# Example"..., 4096) = 529 read(3, "", 4096) = 0 close(3) = 0 munmap(0x7fcec1034000, 4096) = 0 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=76016, ...}) = 0 mmap(NULL, 76016, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcec1022000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/tls/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/x86_64-linux-gnu/tls/x86_64", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/tls/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/x86_64-linux-gnu/tls", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/x86_64-linux-gnu/x86_64", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0 open("/usr/lib/x86_64-linux-gnu/tls/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/x86_64-linux-gnu/tls/x86_64", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/usr/lib/x86_64-linux-gnu/tls/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/x86_64-linux-gnu/tls", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/usr/lib/x86_64-linux-gnu/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/x86_64-linux-gnu/x86_64", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/usr/lib/x86_64-linux-gnu/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=49152, ...}) = 0 open("/lib/tls/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/tls/x86_64", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/lib/tls/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/tls", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/lib/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib/x86_64", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/lib/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 open("/usr/lib/tls/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/tls/x86_64", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/usr/lib/tls/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/tls", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/usr/lib/x86_64/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib/x86_64", 0x7ffcde8fa140) = -1 ENOENT (No such file or directory) open("/usr/lib/libnss_db.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/usr/lib", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0 munmap(0x7fcec1022000, 76016) = 0 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=76016, ...}) = 0 mmap(NULL, 76016, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcec1022000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3 read(3, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0/240/"/0/0/0/0/0/0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=47712, ...}) = 0 mmap(NULL, 2144392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fcec0860000 mprotect(0x7fcec086b000, 2093056, PROT_NONE) = 0 mmap(0x7fcec0a6a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xa000) = 0x7fcec0a6a000 close(3) = 0 mprotect(0x7fcec0a6a000, 4096, PROT_READ) = 0 munmap(0x7fcec1022000, 76016) = 0 open("/etc/services", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=19605, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcec1034000 read(3, "# Network services, Internet sty"..., 4096) = 4096 read(3, "/t/t# IPX/nipx/t/t213/udp/nimap3/t/t220/"..., 4096) = 4096 read(3, "nessus/t/t1241/tcp/t/t/t# Nessus vuln"..., 4096) = 4096 read(3, "347/tcp/t/t/t# gnutella/ngnutella-rt"..., 4096) = 4096 read(3, "ureg/t779/udp/t/tmoira_ureg/t# Moira"..., 4096) = 3221 read(3, "", 4096) = 0 close(3) = 0 munmap(0x7fcec1034000, 4096) = 0 socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 setsockopt(3, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0 bind(3, {sa_family=AF_INET, sin_port=htons(9090), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 getsockname(3, {sa_family=AF_INET, sin_port=htons(9090), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0 write(2, "listening on [any] 9090 ...", 27listening on [any] 9090 ...) = 27 write(2, "/n", 1 ) = 1 rt_sigaction(SIGALRM, {SIG_IGN, [ALRM], SA_RESTORER|SA_RESTART, 0x7fcec0aa10e0}, {SIG_DFL, [], 0}, 8) = 0 alarm(0) = 0 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 recvfrom(3, "hello from client/n", 8192, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(50392), sin_addr=inet_addr("10.0.2.15")}, [16]) = 18 rt_sigaction(SIGALRM, {SIG_IGN, [ALRM], SA_RESTORER|SA_RESTART, 0x7fcec0aa10e0}, {SIG_IGN, [ALRM], SA_RESTORER|SA_RESTART, 0x7fcec0aa10e0}, 8) = 0 alarm(0) = 0 connect(3, {sa_family=AF_INET, sin_port=htons(50392), sin_addr=inet_addr("10.0.2.15")}, 16) = 0 getsockopt(3, SOL_IP, IP_OPTIONS, "", [0]) = 0 getsockname(3, {sa_family=AF_INET, sin_port=htons(9090), sin_addr=inet_addr("10.0.2.15")}, [16]) = 0 write(2, "connect to [10.0.2.15] from (UNK"..., 55connect to [10.0.2.15] from (UNKNOWN) [10.0.2.15] 50392) = 55 write(2, "/n", 1 ) = 1 select(4, [0 3], NULL, NULL, NULL) = 1 (in [3]) read(3, "hello from client/n", 8192) = 18 write(1, "hello from client/n", 18hello from client ) = 18 select(4, [0 3], NULL, NULL, NULL) = 1 (in [3]) read(3, "bye from client/n", 8192) = 16 write(1, "bye from client/n", 16bye from client ) = 16 select(4, [0 3], NULL, NULL, NULL

Pregunta

¿Por qué netcat no recibe los dos mensajes de difusión en el experimento 2?


A continuación se encuentra una copia modificada de su programa de cliente. Agregué algunas declaraciones de inclusión faltantes, eliminé algunos modelos, agregué más comprobación de errores y, el cambio importante, moví la llamada a freeaddrinfo () hacia abajo. Mucho. El puntero aii, que apuntaba a ai, se usó en las llamadas a sendto (), esa no es una buena idea.

Ahora, netcat ve ambos mensajes enviados, al menos en mi máquina, que ejecuta Fedora 24. El programa cliente original de hecho informó un error en la segunda llamada a sendto ().

HTH

PD: Cudos para una pregunta muy bien formulada.

#include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netdb.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(void) { int sockfd; int ret; ssize_t bytes; int yes = 1; struct addrinfo hints, *ai, *aii; char *msg; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; if ((ret = getaddrinfo("255.255.255.255", "9090", &hints, &ai)) == -1) { fprintf(stderr, "client: getaddrinfo() error: %s/n", gai_strerror(ret)); return EXIT_FAILURE; } for (aii = ai; aii != NULL; aii = aii->ai_next) { sockfd = socket(aii->ai_family, aii->ai_socktype, aii->ai_protocol); if (sockfd == -1) { perror("client: socket()"); continue; } break; } if (aii == NULL) { fprintf(stderr, "client: cannot create socket/n"); return EXIT_FAILURE; } if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof yes) == -1) { perror("client: setsockopt()"); return EXIT_FAILURE; } // 1st sendto(). msg = "hello from client/n"; bytes = sendto(sockfd, msg, strlen(msg), 0, aii->ai_addr, aii->ai_addrlen); if (bytes == -1) { perror("sendto 1"); return EXIT_FAILURE; } printf("client: sent %zd bytes/n", bytes); // 2nd sendto(). msg = "bye from client/n"; bytes = sendto(sockfd, msg, strlen(msg), 0, aii->ai_addr, aii->ai_addrlen); if (bytes == -1) { perror("sendto 2"); return EXIT_FAILURE; } printf("client: sent %zd bytes/n", bytes); close(sockfd); freeaddrinfo(ai); return EXIT_SUCCESS; }