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;
}