[PATCH] nc(1): print IP address in verbose mode (-v)

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] nc(1): print IP address in verbose mode (-v)

Job Snijders-2
Dear all,

Scratching a small itch: telnet(1) nicely prints what IP addresses it is
attempting to connect to, I'd like 'nc -v' to do the same, see below:

$ nc -v localhost 23
nc: connect to localhost (127.0.0.1) port 23 (tcp) failed: Connection refused
nc: connect to localhost (::1) port 23 (tcp) failed: Connection refused

$ # dont bother printing IPs when -n or host == ipaddr
$ nc -v -n 127.0.0.1 23
nc: connect to 127.0.0.1 port 23 (tcp) failed: Connection refused

$ dig a www.peeringdb.com +short
54.209.79.173
3.221.183.110
$ nc -v www.peeringdb.com 80
Connection to www.peeringdb.com (54.209.79.173) 80 port [tcp/www] succeeded!
^C

OK?

Kind regards,

Job

Index: netcat.c
===================================================================
RCS file: /cvs/src/usr.bin/nc/netcat.c,v
retrieving revision 1.207
diff -u -p -r1.207 netcat.c
--- netcat.c 17 Oct 2019 14:29:24 -0000 1.207
+++ netcat.c 23 Oct 2019 20:55:21 -0000
@@ -125,7 +125,7 @@ void help(void) __attribute__((noreturn)
 int local_listen(const char *, const char *, struct addrinfo);
 void readwrite(int, struct tls *);
 void fdpass(int nfd) __attribute__((noreturn));
-int remote_connect(const char *, const char *, struct addrinfo);
+int remote_connect(const char *, const char *, struct addrinfo, char *);
 int timeout_tls(int, struct tls *, int (*)(struct tls *));
 int timeout_connect(int, const struct sockaddr *, socklen_t);
 int socks_connect(const char *, const char *, struct addrinfo,
@@ -151,6 +151,7 @@ main(int argc, char *argv[])
 {
  int ch, s = -1, ret, socksv;
  char *host, *uport;
+ char ipaddr[NI_MAXHOST];
  struct addrinfo hints;
  struct servent *sv;
  socklen_t len;
@@ -677,7 +678,8 @@ main(int argc, char *argv[])
     proxy, proxyport, proxyhints, socksv,
     Pflag);
  else
- s = remote_connect(host, portlist[i], hints);
+ s = remote_connect(host, portlist[i], hints,
+    ipaddr);
 
  if (s == -1)
  continue;
@@ -701,10 +703,14 @@ main(int argc, char *argv[])
     uflag ? "udp" : "tcp");
  }
 
- fprintf(stderr,
-    "Connection to %s %s port [%s/%s] "
-    "succeeded!\n", host, portlist[i],
-    uflag ? "udp" : "tcp",
+ fprintf(stderr, "Connection to %s", host);
+
+ /* if there is something to report, print IP */
+ if (!nflag && (strcmp(host, ipaddr) != 0))
+ fprintf(stderr, " (%s)", ipaddr);
+
+ fprintf(stderr, " %s port [%s/%s] succeeded!\n",
+    portlist[i], uflag ? "udp" : "tcp",
     sv ? sv->s_name : "*");
  }
  if (Fflag)
@@ -916,10 +922,11 @@ unix_listen(char *path)
  * port or source address if needed. Returns -1 on failure.
  */
 int
-remote_connect(const char *host, const char *port, struct addrinfo hints)
+remote_connect(const char *host, const char *port, struct addrinfo hints,
+    char *ipaddr)
 {
  struct addrinfo *res, *res0;
- int s = -1, error, on = 1, save_errno;
+ int s = -1, error, herr, on = 1, save_errno;
 
  if ((error = getaddrinfo(host, port, &hints, &res0)))
  errx(1, "getaddrinfo for host \"%s\" port %s: %s", host,
@@ -952,11 +959,26 @@ remote_connect(const char *host, const c
 
  set_common_sockopts(s, res->ai_family);
 
+ if ((herr = getnameinfo(res->ai_addr, res->ai_addrlen, ipaddr,
+    NI_MAXHOST, NULL, 0, NI_NUMERICHOST)) != 0) {
+ if (herr == EAI_SYSTEM)
+ err(1, "getnameinfo");
+ else
+ errx(1, "getnameinfo: %s", gai_strerror(herr));
+ }
+
  if (timeout_connect(s, res->ai_addr, res->ai_addrlen) == 0)
  break;
- if (vflag)
- warn("connect to %s port %s (%s) failed", host, port,
-    uflag ? "udp" : "tcp");
+
+ if (vflag) {
+ /* only print IP if there is something to report */
+ if (nflag || (strncmp(host, ipaddr, NI_MAXHOST) == 0))
+ warn("connect to %s port %s (%s) failed", host,
+    port, uflag ? "udp" : "tcp");
+ else
+ warn("connect to %s (%s) port %s (%s) failed",
+    host, ipaddr, port, uflag ? "udp" : "tcp");
+ }
 
  save_errno = errno;
  close(s);

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] nc(1): print IP address in verbose mode (-v)

Theo de Raadt-2
Similar behaviour seems more sensible to me.

The messaging is really verbose, but it remains largely compatible
with the original netcat and we haven't chosen to deviate from
that yet I guess.

Job Snijders <[hidden email]> wrote:

> Dear all,
>
> Scratching a small itch: telnet(1) nicely prints what IP addresses it is
> attempting to connect to, I'd like 'nc -v' to do the same, see below:
>
> $ nc -v localhost 23
> nc: connect to localhost (127.0.0.1) port 23 (tcp) failed: Connection refused
> nc: connect to localhost (::1) port 23 (tcp) failed: Connection refused
>
> $ # dont bother printing IPs when -n or host == ipaddr
> $ nc -v -n 127.0.0.1 23
> nc: connect to 127.0.0.1 port 23 (tcp) failed: Connection refused
>
> $ dig a www.peeringdb.com +short
> 54.209.79.173
> 3.221.183.110
> $ nc -v www.peeringdb.com 80
> Connection to www.peeringdb.com (54.209.79.173) 80 port [tcp/www] succeeded!
> ^C
>
> OK?
>
> Kind regards,
>
> Job
>
> Index: netcat.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/nc/netcat.c,v
> retrieving revision 1.207
> diff -u -p -r1.207 netcat.c
> --- netcat.c 17 Oct 2019 14:29:24 -0000 1.207
> +++ netcat.c 23 Oct 2019 20:55:21 -0000
> @@ -125,7 +125,7 @@ void help(void) __attribute__((noreturn)
>  int local_listen(const char *, const char *, struct addrinfo);
>  void readwrite(int, struct tls *);
>  void fdpass(int nfd) __attribute__((noreturn));
> -int remote_connect(const char *, const char *, struct addrinfo);
> +int remote_connect(const char *, const char *, struct addrinfo, char *);
>  int timeout_tls(int, struct tls *, int (*)(struct tls *));
>  int timeout_connect(int, const struct sockaddr *, socklen_t);
>  int socks_connect(const char *, const char *, struct addrinfo,
> @@ -151,6 +151,7 @@ main(int argc, char *argv[])
>  {
>   int ch, s = -1, ret, socksv;
>   char *host, *uport;
> + char ipaddr[NI_MAXHOST];
>   struct addrinfo hints;
>   struct servent *sv;
>   socklen_t len;
> @@ -677,7 +678,8 @@ main(int argc, char *argv[])
>      proxy, proxyport, proxyhints, socksv,
>      Pflag);
>   else
> - s = remote_connect(host, portlist[i], hints);
> + s = remote_connect(host, portlist[i], hints,
> +    ipaddr);
>  
>   if (s == -1)
>   continue;
> @@ -701,10 +703,14 @@ main(int argc, char *argv[])
>      uflag ? "udp" : "tcp");
>   }
>  
> - fprintf(stderr,
> -    "Connection to %s %s port [%s/%s] "
> -    "succeeded!\n", host, portlist[i],
> -    uflag ? "udp" : "tcp",
> + fprintf(stderr, "Connection to %s", host);
> +
> + /* if there is something to report, print IP */
> + if (!nflag && (strcmp(host, ipaddr) != 0))
> + fprintf(stderr, " (%s)", ipaddr);
> +
> + fprintf(stderr, " %s port [%s/%s] succeeded!\n",
> +    portlist[i], uflag ? "udp" : "tcp",
>      sv ? sv->s_name : "*");
>   }
>   if (Fflag)
> @@ -916,10 +922,11 @@ unix_listen(char *path)
>   * port or source address if needed. Returns -1 on failure.
>   */
>  int
> -remote_connect(const char *host, const char *port, struct addrinfo hints)
> +remote_connect(const char *host, const char *port, struct addrinfo hints,
> +    char *ipaddr)
>  {
>   struct addrinfo *res, *res0;
> - int s = -1, error, on = 1, save_errno;
> + int s = -1, error, herr, on = 1, save_errno;
>  
>   if ((error = getaddrinfo(host, port, &hints, &res0)))
>   errx(1, "getaddrinfo for host \"%s\" port %s: %s", host,
> @@ -952,11 +959,26 @@ remote_connect(const char *host, const c
>  
>   set_common_sockopts(s, res->ai_family);
>  
> + if ((herr = getnameinfo(res->ai_addr, res->ai_addrlen, ipaddr,
> +    NI_MAXHOST, NULL, 0, NI_NUMERICHOST)) != 0) {
> + if (herr == EAI_SYSTEM)
> + err(1, "getnameinfo");
> + else
> + errx(1, "getnameinfo: %s", gai_strerror(herr));
> + }
> +
>   if (timeout_connect(s, res->ai_addr, res->ai_addrlen) == 0)
>   break;
> - if (vflag)
> - warn("connect to %s port %s (%s) failed", host, port,
> -    uflag ? "udp" : "tcp");
> +
> + if (vflag) {
> + /* only print IP if there is something to report */
> + if (nflag || (strncmp(host, ipaddr, NI_MAXHOST) == 0))
> + warn("connect to %s port %s (%s) failed", host,
> +    port, uflag ? "udp" : "tcp");
> + else
> + warn("connect to %s (%s) port %s (%s) failed",
> +    host, ipaddr, port, uflag ? "udp" : "tcp");
> + }
>  
>   save_errno = errno;
>   close(s);
>

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] nc(1): print IP address in verbose mode (-v)

Klemens Nanni-2
In reply to this post by Job Snijders-2
On Wed, Oct 23, 2019 at 09:11:47PM +0000, Job Snijders wrote:
> Scratching a small itch: telnet(1) nicely prints what IP addresses it is
> attempting to connect to, I'd like 'nc -v' to do the same, see below:
Yes, please;  I had an almost identical diff but shelved it for later.
Also thought about putting this behind a second `-v' but with the IP
being the only difference it seemed unjustified.

> $ nc -v localhost 23
> nc: connect to localhost (127.0.0.1) port 23 (tcp) failed: Connection refused
> nc: connect to localhost (::1) port 23 (tcp) failed: Connection refused
Same format here.

> $ # dont bother printing IPs when -n or host == ipaddr
> $ nc -v -n 127.0.0.1 23
> nc: connect to 127.0.0.1 port 23 (tcp) failed: Connection refused
I did not bother comparing host and IP because it quickly breaks for
unshortened IPv6 addresses, e.g.

        $ ./obj/nc -w1 -v 2001:0db8::1 22
        nc: connect to 2001:0db8::1 (2001:db8::1) port 22 (tcp) failed: Operation timed out

That seems inconsistent;  user requested verbosity, so no need to try
saving some characters.

> OK?
OK kn

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] nc(1): print IP address in verbose mode (-v)

Klemens Nanni-2
On Wed, Oct 23, 2019 at 11:56:13PM +0200, Klemens Nanni wrote:

> I did not bother comparing host and IP because it quickly breaks for
> unshortened IPv6 addresses, e.g.
>
> $ ./obj/nc -w1 -v 2001:0db8::1 22
> nc: connect to 2001:0db8::1 (2001:db8::1) port 22 (tcp) failed: Operation timed out
>
> That seems inconsistent;  user requested verbosity, so no need to try
> saving some characters.
>
> > OK?
> OK kn
That is to say I do prefer always printing the IP with `-v', but am OK
with both ways really.  Not sure if my example really matters.