bash network interface

  sonic0002        2013-07-20 00:57:52       4,412        0         

Some of us may have seen /dev/tcp/<host>/<port> before, is this a special file system implemented in some BSD kernel? Because there is no /dev/tcp in Linux. Actually, this one is implemented in bash. We no need to rely on wget,nc to do network connection.

It's very easy to use this interface:

bash-4.2$ cat </dev/tcp/time.nist.gov/13

56188 12-09-18 15:34:26 50 0 0 733.5 UTC(NIST) * 

bash-4.2$ exec 3<>/dev/tcp/www.w3.org/80
bash-4.2$ echo -e "GET / HTTP/1.0\n\n" >&3
bash-4.2$ cat <&3
HTTP/1.1 200 OK
Date: Tue, 18 Sep 2012 15:41:08 GMT
Server: Apache/2
Content-Location: Home.html
Vary: negotiate,accept
TCN: choice
Last-Modified: Tue, 18 Sep 2012 14:06:27 GMT
ETag: "8f75-4c9fa65657ec0;89-3f26bd17a2f00"
Accept-Ranges: bytes
Content-Length: 36725
Cache-Control: max-age=600
Expires: Tue, 18 Sep 2012 15:51:08 GMT
P3P: policyref="http://www.w3.org/2001/05/P3P/p3p.xml"
Connection: close
Content-Type: text/html; charset=utf-8
...

In bash source code, we can find below codes in redir.c.

    /* A list of pattern/value pairs for filenames that the redirection
       code handles specially. */
    static STRING_INT_ALIST _redir_special_filenames[] = {
    #if !defined (HAVE_DEV_FD)
      { "/dev/fd/[0-9]*", RF_DEVFD },
    #endif
    #if !defined (HAVE_DEV_STDIN)
      { "/dev/stderr", RF_DEVSTDERR },
      { "/dev/stdin", RF_DEVSTDIN },
      { "/dev/stdout", RF_DEVSTDOUT },
    #endif
    #if defined (NETWORK_REDIRECTIONS)
      { "/dev/tcp/*/*", RF_DEVTCP },
      { "/dev/udp/*/*", RF_DEVUDP },
    #endif
      { (char *)NULL, -1 }
    };
     
    ...
    static int
    redir_open (filename, flags, mode, ri)
         char *filename;
         int flags, mode;
         enum r_instruction ri;
    {
      int fd, r;
     
      r = find_string_in_alist (filename, _redir_special_filenames, 1);
      if (r>= 0)
        return (redir_special_open (r, filename, flags, mode, ri));
     
      /* If we are in noclobber mode, you are not allowed to overwrite
         existing files.  Check before opening. */
      if (noclobber && CLOBBERING_REDIRECT (ri))
        {
          fd = noclobber_open (filename, flags, mode, ri);
          if (fd == NOCLOBBER_REDIRECT)
            return (NOCLOBBER_REDIRECT);
        }
      else
        {
          fd = open (filename, flags, mode);
    #if defined (AFS)
          if ((fd <0) && (errno == EACCES))
            {
              fd = open (filename, flags & ~O_CREAT, mode);
              errno = EACCES;       /* restore errno */
            }
    #endif /* AFS */
        }
     
      return fd;
    }

When bash finds redirection, it will first check whether the file to be redirected is a special file or not. If yes, then bash will intercept it and parse it, otherwise it will open the file. The detailed definition is in of /dev/tcp/HOST/PORT is in lib/sh/netopen.c

In bash manual, we can find these special interfaces as well:

/dev/fd/fd
If fd is a valid integer, file descriptor fd is duplicated.
/dev/stdin
File descriptor 0 is duplicated.
/dev/stdout
File descriptor 1 is duplicated.
/dev/stderr
File descriptor 2 is duplicated.
/dev/tcp/host/port
If host is a valid hostname or Internet address, and port is an integer port number or service name, bash attempts
to open a TCP connection to the corresponding socket.
/dev/udp/host/port
If host is a valid hostname or Internet address, and port is an integer port number or service name, bash attempts
to open a UDP connection to the corresponding socket.

Reference : http://wangcong.org/blog/archives/2099

BASH  NETWORK INTERFACE  /DEV/TCP 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

Will you bring both?