Network or UNIX-domain socket

OpenBSD‘s netcat can support both network(based on TCP/IP or UDP/IP) and UNIX-domain sockets. netcat will use network sockets by default except you specify -U option. E.g, create and listen on a UNIX-domain socket:

  1. nc -lU /var/tmp/unix-socket

-l option lets netcat work in server mode. There is a lflag which identifies netcat launched as server or client:

  1. int lflag; /* Bind to local port */

Regarding to network socket, netcat has 2 options to specify using IPv4 only or IPv6 only:

  1. -4 Use IPv4 addresses only.
  2. -6 Use IPv6 addresses only.

Netcat program has a family variable which denotes using IPv4, IPv6 or UNIX-domain socket:

  1. int family = AF_UNSPEC;

During parsing options, lflag and family will be assigned different values accordingly:

  1. while ((ch = getopt(argc, argv, ...))) {
  2. ......
  3. switch (ch) {
  4. case '4':
  5. family = AF_INET;
  6. break;
  7. case '6':
  8. family = AF_INET6;
  9. break;
  10. case 'U':
  11. family = AF_UNIX;
  12. break;
  13. ......
  14. case 'l':
  15. lflag = 1;
  16. break;
  17. ......
  18. }
  19. }

Netcat will accept one or two arguments:

  1. argc -= optind;
  2. argv += optind;
  3. ......
  4. /* Cruft to make sure options are clean, and used properly. */
  5. if (argv[0] && !argv[1] && family == AF_UNIX) {
  6. host = argv[0];
  7. uport = NULL;
  8. } else if (argv[0] && !argv[1]) {
  9. if (!lflag)
  10. usage(1);
  11. uport = argv[0];
  12. host = NULL;
  13. } else if (argv[0] && argv[1]) {
  14. host = argv[0];
  15. uport = argv[1];
  16. } else
  17. usage(1);

If it is UNIX-domain, netcat only needs one argument which is the UNIX-domain socket file. If it is network socket, client must have two arguments: server IP address and port; server can omit IP address and only has port.

What IP protocol version will be used by TCP/IP server if neither -4 nor -6 is provided in option? The answer is IPv4. In local_listen function:

  1. /*
  2. * In the case of binding to a wildcard address
  3. * default to binding to an ipv4 address.
  4. */
  5. if (host == NULL && hints.ai_family == AF_UNSPEC)
  6. hints.ai_family = AF_INET;

host == NULL“ means you don’t designate an IP address for server, like following example:

  1. # nc -l 3003