152 |
/* Debug: squirt whatever message and sleep a bit so we can see it go by. */ |
/* Debug: squirt whatever message and sleep a bit so we can see it go by. */ |
153 |
/* Beware: writes to stdOUT... */ |
/* Beware: writes to stdOUT... */ |
154 |
#if 0 |
#if 0 |
155 |
#define Debug(...) do { printf(__VA_ARGS__); printf("\n"); fflush(stdout); sleep(1); } while (0) |
#define Debug(...) do { printf(__VA_ARGS__); printf("\n"); fflush_all(); sleep(1); } while (0) |
156 |
#else |
#else |
157 |
#define Debug(...) do { } while (0) |
#define Debug(...) do { } while (0) |
158 |
#endif |
#endif |
278 |
random unknown port is probably not very useful without "netstat". */ |
random unknown port is probably not very useful without "netstat". */ |
279 |
if (o_verbose) { |
if (o_verbose) { |
280 |
char *addr; |
char *addr; |
281 |
rr = getsockname(netfd, &ouraddr->u.sa, &ouraddr->len); |
getsockname(netfd, &ouraddr->u.sa, &ouraddr->len); |
282 |
if (rr < 0) |
//if (rr < 0) |
283 |
bb_perror_msg_and_die("getsockname after bind"); |
// bb_perror_msg_and_die("getsockname after bind"); |
284 |
addr = xmalloc_sockaddr2dotted(&ouraddr->u.sa); |
addr = xmalloc_sockaddr2dotted(&ouraddr->u.sa); |
285 |
fprintf(stderr, "listening on %s ...\n", addr); |
fprintf(stderr, "listening on %s ...\n", addr); |
286 |
free(addr); |
free(addr); |
340 |
rr = accept(netfd, &remend.u.sa, &remend.len); |
rr = accept(netfd, &remend.u.sa, &remend.len); |
341 |
if (rr < 0) |
if (rr < 0) |
342 |
bb_perror_msg_and_die("accept"); |
bb_perror_msg_and_die("accept"); |
343 |
if (themaddr && memcmp(&remend.u.sa, &themaddr->u.sa, remend.len) != 0) { |
if (themaddr) { |
344 |
/* nc 1.10 bails out instead, and its error message |
int sv_port, port, r; |
345 |
* is not suppressed by o_verbose */ |
|
346 |
if (o_verbose) { |
sv_port = get_nport(&remend.u.sa); /* save */ |
347 |
char *remaddr = xmalloc_sockaddr2dotted(&remend.u.sa); |
port = get_nport(&themaddr->u.sa); |
348 |
bb_error_msg("connect from wrong ip/port %s ignored", remaddr); |
if (port == 0) { |
349 |
free(remaddr); |
/* "nc -nl -p LPORT RHOST" (w/o RPORT!): |
350 |
|
* we should accept any remote port */ |
351 |
|
set_nport(&remend, 0); /* blot out remote port# */ |
352 |
|
} |
353 |
|
r = memcmp(&remend.u.sa, &themaddr->u.sa, remend.len); |
354 |
|
set_nport(&remend, sv_port); /* restore */ |
355 |
|
if (r != 0) { |
356 |
|
/* nc 1.10 bails out instead, and its error message |
357 |
|
* is not suppressed by o_verbose */ |
358 |
|
if (o_verbose) { |
359 |
|
char *remaddr = xmalloc_sockaddr2dotted(&remend.u.sa); |
360 |
|
bb_error_msg("connect from wrong ip/port %s ignored", remaddr); |
361 |
|
free(remaddr); |
362 |
|
} |
363 |
|
close(rr); |
364 |
|
goto again; |
365 |
} |
} |
|
close(rr); |
|
|
goto again; |
|
366 |
} |
} |
367 |
unarm(); |
unarm(); |
368 |
} else |
} else |
372 |
doing a listen-on-any on a multihomed machine. This allows one to |
doing a listen-on-any on a multihomed machine. This allows one to |
373 |
offer different services via different alias addresses, such as the |
offer different services via different alias addresses, such as the |
374 |
"virtual web site" hack. */ |
"virtual web site" hack. */ |
375 |
rr = getsockname(netfd, &ouraddr->u.sa, &ouraddr->len); |
getsockname(netfd, &ouraddr->u.sa, &ouraddr->len); |
376 |
if (rr < 0) |
//if (rr < 0) |
377 |
bb_perror_msg_and_die("getsockname after accept"); |
// bb_perror_msg_and_die("getsockname after accept"); |
378 |
} |
} |
379 |
|
|
380 |
if (o_verbose) { |
if (o_verbose) { |
390 |
socklen_t x = sizeof(optbuf); |
socklen_t x = sizeof(optbuf); |
391 |
|
|
392 |
rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); |
rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); |
393 |
if (rr < 0) |
if (rr >= 0 && x) { /* we've got options, lessee em... */ |
|
bb_perror_msg("getsockopt failed"); |
|
|
else if (x) { /* we've got options, lessee em... */ |
|
394 |
bin2hex(bigbuf_net, optbuf, x); |
bin2hex(bigbuf_net, optbuf, x); |
395 |
bigbuf_net[2*x] = '\0'; |
bigbuf_net[2*x] = '\0'; |
396 |
fprintf(stderr, "IP options: %s\n", bigbuf_net); |
fprintf(stderr, "IP options: %s\n", bigbuf_net); |
614 |
mobygrams are kinda fun and exercise the reassembler. */ |
mobygrams are kinda fun and exercise the reassembler. */ |
615 |
if (rr <= 0) { /* at end, or fukt, or ... */ |
if (rr <= 0) { /* at end, or fukt, or ... */ |
616 |
FD_CLR(STDIN_FILENO, &ding1); /* disable and close stdin */ |
FD_CLR(STDIN_FILENO, &ding1); /* disable and close stdin */ |
617 |
close(0); |
close(STDIN_FILENO); |
618 |
|
// Does it make sense to shutdown(net_fd, SHUT_WR) |
619 |
|
// to let other side know that we won't write anything anymore? |
620 |
|
// (and what about keeping compat if we do that?) |
621 |
} else { |
} else { |
622 |
rzleft = rr; |
rzleft = rr; |
623 |
zp = bigbuf_in; |
zp = bigbuf_in; |
686 |
|
|
687 |
/* main: now we pull it all together... */ |
/* main: now we pull it all together... */ |
688 |
int nc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
int nc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
689 |
int nc_main(int argc, char **argv) |
int nc_main(int argc UNUSED_PARAM, char **argv) |
690 |
{ |
{ |
691 |
char *str_p, *str_s; |
char *str_p, *str_s; |
692 |
USE_NC_EXTRA(char *str_i, *str_o;) |
IF_NC_EXTRA(char *str_i, *str_o;) |
693 |
char *themdotted = themdotted; /* gcc */ |
char *themdotted = themdotted; /* gcc */ |
694 |
char **proggie; |
char **proggie; |
695 |
int x; |
int x; |
715 |
while (*++proggie) { |
while (*++proggie) { |
716 |
if (strcmp(*proggie, "-e") == 0) { |
if (strcmp(*proggie, "-e") == 0) { |
717 |
*proggie = NULL; |
*proggie = NULL; |
|
argc = proggie - argv; |
|
718 |
proggie++; |
proggie++; |
719 |
goto e_found; |
goto e_found; |
720 |
} |
} |
724 |
|
|
725 |
// -g -G -t -r deleted, unimplemented -a deleted too |
// -g -G -t -r deleted, unimplemented -a deleted too |
726 |
opt_complementary = "?2:vv:w+"; /* max 2 params; -v is a counter; -w N */ |
opt_complementary = "?2:vv:w+"; /* max 2 params; -v is a counter; -w N */ |
727 |
getopt32(argv, "hnp:s:uvw:" USE_NC_SERVER("l") |
getopt32(argv, "hnp:s:uvw:" IF_NC_SERVER("l") |
728 |
USE_NC_EXTRA("i:o:z"), |
IF_NC_EXTRA("i:o:z"), |
729 |
&str_p, &str_s, &o_wait |
&str_p, &str_s, &o_wait |
730 |
USE_NC_EXTRA(, &str_i, &str_o, &o_verbose)); |
IF_NC_EXTRA(, &str_i, &str_o, &o_verbose)); |
731 |
argv += optind; |
argv += optind; |
732 |
#if ENABLE_NC_EXTRA |
#if ENABLE_NC_EXTRA |
733 |
if (option_mask32 & OPT_i) /* line-interval time */ |
if (option_mask32 & OPT_i) /* line-interval time */ |
781 |
setsockopt_reuseaddr(netfd); |
setsockopt_reuseaddr(netfd); |
782 |
if (o_udpmode) |
if (o_udpmode) |
783 |
socket_want_pktinfo(netfd); |
socket_want_pktinfo(netfd); |
784 |
xbind(netfd, &ouraddr->u.sa, ouraddr->len); |
if (!ENABLE_FEATURE_UNIX_LOCAL |
785 |
|
|| o_listen |
786 |
|
|| ouraddr->u.sa.sa_family != AF_UNIX |
787 |
|
) { |
788 |
|
xbind(netfd, &ouraddr->u.sa, ouraddr->len); |
789 |
|
} |
790 |
#if 0 |
#if 0 |
791 |
setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); |
setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); |
792 |
setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf); |
setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf); |