--- src/usr.bin/nc/netcat.c +++ src/usr.bin/nc/netcat.c @@ -344,6 +344,8 @@ main(int argc, char *argv[]) len = sizeof(cliaddr); connfd = accept(s, (struct sockaddr *)&cliaddr, &len); + if (connfd < 0) + err(1, "accept"); } readwrite(connfd); @@ -376,6 +378,15 @@ main(int argc, char *argv[]) if (s) close(s); + /* Don't lookup port if -n */ + if (nflag) + sv = NULL; + else { + sv = getservbyport( + ntohs(atoi(portlist[i])), + uflag ? "udp" : "tcp"); + } + if (xflag) s = socks_connect(host, portlist[i], hints, proxyhost, proxyport, proxyhints, socksv, @@ -383,35 +394,34 @@ main(int argc, char *argv[]) else s = remote_connect(host, portlist[i], hints); - if (s < 0) - continue; - ret = 0; - if (vflag || zflag) { - /* For UDP, make sure we are connected. */ - if (uflag) { - if (udptest(s) == -1) { - ret = 1; - continue; - } - } - /* Don't look up port if -n. */ - if (nflag) - sv = NULL; - else { - sv = getservbyport( - ntohs(atoi(portlist[i])), - uflag ? "udp" : "tcp"); + if (s >= 0) { + if (uflag && zflag) + ret = (udptest(s) == -1) ? 1 : 0; + } else + ret = 1; + + if (vflag) { + if (ret) { + fprintf(stderr, + "Connection to %s %s port " + "[%s/%s] failed : %s\n", + host, portlist[i], + uflag ? "udp" : "tcp", + sv ? sv->s_name : "*", + strerror(errno)); + } else { + fprintf(stderr, + "Connection to %s %s port " + "[%s/%s] succeeded!\n", + host, portlist[i], + uflag ? "udp" : "tcp", + sv ? sv->s_name : "*"); } - - fprintf(stderr, - "Connection to %s %s port [%s/%s] " - "succeeded!\n", host, portlist[i], - uflag ? "udp" : "tcp", - sv ? sv->s_name : "*"); } - if (!zflag) + + if (!zflag && !ret) readwrite(s); } } @@ -433,7 +443,7 @@ unix_connect(char *path) int s; if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) - return (-1); + err(1, "socket"); (void)fcntl(s, F_SETFD, 1); memset(&sun, 0, sizeof(struct sockaddr_un)); @@ -444,8 +454,7 @@ unix_connect(char *path) strcpy(sun.sun_path, path); if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { - close(s); - return (-1); + err(1, "connect"); } return (s); @@ -463,7 +472,7 @@ unix_listen(char *path) /* Create unix domain socket. */ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) - return (-1); + err(1, "socket"); memset(&sun, 0, sizeof(struct sockaddr_un)); sun.sun_family = AF_UNIX; @@ -473,13 +482,11 @@ unix_listen(char *path) strcpy(sun.sun_path, path); if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { - close(s); - return (-1); + err(1, "bind"); } if (listen(s, 5) < 0) { - close(s); - return (-1); + err(1, "listen"); } return (s); } @@ -494,6 +501,7 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) { struct addrinfo *res, *res0; int s, error, on = 1; + int saved_errno = 0; if ((error = getaddrinfo(host, port, &hints, &res))) errx(1, "getaddrinfo: %s", gai_strerror(error)); @@ -525,8 +533,13 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) errx(1, "getaddrinfo: %s", gai_strerror(error)); if (bind(s, (struct sockaddr *)ares->ai_addr, - ares->ai_addrlen) < 0) - errx(1, "bind failed: %s", strerror(errno)); + ares->ai_addrlen) < 0) { + warn("bind"); + freeaddrinfo(ares); + close(s); + s = -1; + continue; + } freeaddrinfo(ares); } @@ -534,7 +547,11 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0) break; - else if (vflag) + + if (!saved_errno) + saved_errno = errno; + + if (vflag) warn("connect to %s port %s (%s) failed", host, port, uflag ? "udp" : "tcp"); @@ -544,6 +561,9 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) freeaddrinfo(res); + if (!errno && saved_errno) + errno = saved_errno; + return (s); } @@ -586,25 +606,26 @@ local_listen(char *host, char *port, struct addrinfo hints) ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); if (ret == -1) - err(1, NULL); + err(1, "setsockopt"); set_common_sockopts(s); if (bind(s, (struct sockaddr *)res0->ai_addr, res0->ai_addrlen) == 0) break; + warn("bind"); close(s); s = -1; } while ((res0 = res0->ai_next) != NULL); + freeaddrinfo(res); + if (!uflag && s != -1) { if (listen(s, 1) < 0) err(1, "listen"); } - freeaddrinfo(res); - return (s); } @@ -643,7 +664,7 @@ readwrite(int nfd) if (n == 0) return; - if (pfd[0].revents & POLLIN) { + if (pfd[0].revents & (POLLIN | POLLERR)) { if ((n = read(nfd, buf, plen)) < 0) return; else if (n == 0) { @@ -769,24 +790,14 @@ build_ports(char *p) } } -/* - * udptest() - * Do a few writes to see if the UDP port is there. - * XXX - Better way of doing this? Doesn't work for IPv6. - * Also fails after around 100 ports checked. - */ int udptest(int s) { - int i, ret; + write(s, "X", 1); - for (i = 0; i <= 3; i++) { - if (write(s, "X", 1) == 1) - ret = 1; - else - ret = -1; - } - return (ret); + sleep(3); + + return (write(s, "X", 1) == 1) ? 1 : -1; } void