Cover V11, I12

Article
Figure 1
Figure 2
Figure 3

dec2002.tar

sockspy Knows TCP/IP

Cameron Laird

sockspy is a convenient tool for a range of networking diagnostic and programming problems. You probably already use a general-purpose "sniffer" such as tcpdump or ethereal; so do I. Although different from these, sockspy also has a place. It complements other networking tools by focusing specifically on the "dialogues" of typical TCP/IP protocols. sockspy's programmability means that it is also handy for prototyping proxy clients and servers for these protocols.

In this article, I'll explain when and when not to use sockspy, how you can quickly try out sockspy for yourself, mention a few of the other tools that overlap sockspy's domain, and provide references where you can read more.

An Inside Look at Networking

General-purpose packet sniffers are tools located on a particular host that report on all the network traffic visible to that host -- either everything to and from it, or, often, all the traffic on the local subnetwork, even the traffic neither originating from nor targeting the local host.

Prolific freelance programmer Tom Poindexter invented sockspy for a more specialized role. It "eavesdrops" on a TCP/IP connection between a client and server. If you need to monitor UDP, or traffic between many different hosts, or traffic on many different networking hosts, you'll probably want a different tool.

For a deep focus on only one connection on one specific port, though, sockspy can be invaluable. You might, for example, need to track down why a simple mail-transport protocol (SMTP) service treats two apparently identical clients differently. A general-purpose sniffer can overwhelm you with the mass of data it typically reports. By specializing your "spying" to just the protocol handshakes and acknowledgments between server and clients, you're likely to notice any differences much faster. In the next few sections, I will show how easy it is to perform such an experiment.

sockspy Experimentation

There are a couple of other differences between sockspy and other networking tools. One difference is in networking architecture. sockspy is generally used in an "intrusive" three-host configuration: the client, the server, and a third host for sockspy. Contrast this with packet sniffers that "passively" sit and watch traffic. These often run on a client or server machine. This characteristic makes sockspy valuable for situations where you don't want to perturb the configuration of client or server.

A final difference between sockspy and many other networking programs is that sockspy is written to be modified. sockspy is an application written in the Tcl/Tk programming language. It's rather compact, only 511 lines in version 2.0, and I'll show how easy it is to adjust sockspy to your own needs.

For a first experiment with sockspy, use Slashdot's Web server as the server, any convenient Web browser as client, and a development machine under your control as the sockspy host. Normal Web browsing has you direct the browser with a URL, such as http://slashdot.com/. The browser sends a TCP/IP message to the HTTP server, and receives an answer, as Figure 1 illustrates.

To use sockspy, be sure you have a copy of the Tcl interpreter on your host, and download the sockspy bundle to it from:

http://prdownloads.sourceforge.net/sockspy/sockspy.tcl
From a command line, launch:

tclsh sockspy.tcl | tee /tmp/log
and, as the process prompts you, type:

Client port (8080): 3567
Server host: slashdot.com
Server port (80):  
Leave this process running, turn to your Web browser, and enter the URL:

http://$my_sockspy_host:3567/
You'll want to substitute the real value of "$my_sockspy_host" -- any numeric or symbolic IP address the browser can resolve to reach the host where you've launched sockspy. This gives you the architecture of Figure 2.

At this point, you should see in your Web browser the usual Slashdot front page. As far as the browser knows, it's accessing a normal Web page, which happens to have a mildly unusual URL. Back on the sockspy host, though, /tmp/log records the client-server conversation, in a format that looks something like this:

Client port (8080): Server host: Server port (80): =localhost:3567 <--> \
     slashdot.com:80
=waiting for new connection...
=connect from 206.99.99.99 sockspy.my.host 3567 2291
>GET / HTTP/1.0
>Host: phaseit.net:3567
>Accept: text/html, text/plain, text/sgml, */*;q=0.01
>Accept-Encoding: gzip, compress
>Accept-Language: en
>User-Agent: Lynx/2.8.2rel.1 libwww-FM/2.14
>
>
<HTTP/1.1 200 OK
<Date: Mon, 20 May 2002 19:00:29 GMT
<Server: Apache/1.3.20 (Unix) mod_perl/1.25 mod_gzip/1.3.19.1a
<SLASH_LOG_DATA: shtml
<X-Powered-By: Slash 2.003000
<X-Fry: That doesn't look like an "L", unless you count lower case.
<Cache-Control: private
<Pragma: private
<Connection: close
<Content-Type: text/html
<Content-Encoding: gzip
<Content-Length: 10994
<
< ...
This might be valuable information to you. Slashdot's notorious for inserting X-* quips in its HTTP traffic; perhaps you want to monitor them. More soberly, sockspy can be a convenient way to track down problems in Content-Length, Encoding negotiation, and other error-prone HTTP aspects.

sockspy has several options. You can bring it up in a graphical user interface (GUI); in fact, the 1.0 release of sockspy had only a GUI, but current sockspy maintainer Keith Vetter retrofitted a command-line alternative. Data can be displayed in any of several formats (see Figure 3).

Why run a command-line process when a GUI's available? A command-line tool can be easier to explain; in a tutorial section like this one, it's less ambiguous for a recipe to say, "type the host name" than "click there". Also, a command-line interface (CLI) generally lends itself easier to "pipelining". It's quick work to pipe the output of the sockspy CLI into a grep or other filter.

Finally, as systems administrators, we're often in the position of working on hosts where GUI support is impaired or expensive. The CLI sockspy is easy to manage even over a low-speed dial-up connection, for example.

What's the Point?

Maybe this first example doesn't impress you much. It's true; there are plenty of tools available that help tune up HTTP service. sockspy wouldn't have been written if that were all it could do.

sockspy's point is that it nicely fills a niche between the very general-purpose packet sniffers and the protocol-specific debugging tools. sockspy works just as well with a new protocol you've invented as it does with such stalwarts as HTTP and SMTP. Its simplicity is a real comfort when tracking down thorny state- or time-dependent problems. I have a lot of confidence that the data I see in sockspy is truly the data showing up "on the wire".

Cut and Paste with sockspy

A final benefit of sockspy is that it invites hacking. The code to implement it is both compact and documented. "Proxy server" is jargon for a program that serves as the "mask" for a networking program that's doing the real work. You can think of a proxy server as a "valve" or "test chamber" that allows you to manage network traffic.

When I need a proxy server of some sort, my first reaction is to prototype it with sockspy. Suppose, for example, I'm testing out a new transaction service, and I'm encountering mysteries in network traffic that seem to depend on the implementation of the service. This is what I do: I set up alternative servers A and B, running continuously. I tell my user population to point their clients to $S:$P, that is, an endpoint such as 111.123.99.20:5678. On host $S, I set up sockspy.tcl. Without changing anything on the client side, I can redirect the real service from A to B, and back again, just by changing sockspy's startup parameters.

It takes only a few extra lines of code to embed sockspy.tcl in a larger program that automatically switches between endpoint services periodically. A few lines more, and I log the characteristics and content exchanged with specific clients. sockspy's connections are implemented in just a couple of dozen lines of Tcl/Tk code:

proc clntConnect {servHost servPort sockClnt ip port} {
    global state
    
    set state(sockClnt) $sockClnt
        
    INFO "connect from [fconfigure $sockClnt -sockname] $port"
    if {$servHost == {} || $servHost == "none"} {
        set sockServ ""
    } elseif {[catch {set sockServ [socket $servHost $servPort]} reason]} {
        INFO "cannot connect: $reason"
        tk_messageBox -icon error -type ok \
                -message "cannot connect to $servHost $servPort: $reason"
        exit
    }
    
    ;# Configure connection to the client
    fconfigure $sockClnt -blocking 0 -buffering none -translation binary
    fileevent $sockClnt readable \
            [list sockReadable $sockClnt $sockServ client]
    
    ;# Configure connection to the server
    if {[string length $sockServ]} {
        fconfigure $sockServ -blocking 0 -buffering none -translation binary
        fileevent $sockServ readable \
                [list sockReadable $sockServ $sockClnt server]
    }
}
I can insert my own command:

log "Connection from [fconfigure $sockClnt -sockname] ($sockClnt),
port $port, to [fconfigure $servHost -sockname] ($servHost)."
at the beginning of this procedure, and construct a problem-specific log of just the information I need.

It Dices, It Slices

sockspy is open source software, freely available through a SourceForge project. While it's impossible to know how many administrators currently use it, I can state that I've heard of dozens of interesting applications. Poindexter has passed on responsibility for leading maintenance of sockspy to Keith Vetter of SoftBook Press. In his own work, Vetter has used sockspy in these roles, among others:

  • Perl CGI debugging -- He captures HTTP payloads, then uses them as "fake STDIN" for the Perl debugger.
  • Regression testing of CGI scripts against captured HTTP payloads.
  • Firewall bypasses, where he has re-ported specific network services to "safe" ports.
  • Security investigations, where he monitored sensitive content transmitted by certain client applications.
  • Proxying of network connections to test or circumvent host-based security restrictions.
  • Education about the network dialogues email clients generate.

Learn sockspy. If you've had needs in the area of network management or programming, chances are that someone else has had them, too, and the right tool for you might be only a few clicks away. There are, in fact, at least a hundred programs that "sniff". For its simplicity, robustness, and flexibility, sockspy is one of the most useful.

To learn more about sockspy, visit:

http://wiki.tcl.tk/sockspy
and its SourceForge project home:

http://sockspy.sourceforge.net/sockspy.html
The former page also mentions related utilities that monitor serial-line traffic, low-level IP packets, and other communication channels.

Cameron Laird is vice president of Phaseit, Inc. http://www.phaseit.net, where he frequently consults on System Administration issues. He carries sockspy, among other tools, with him wherever he goes. Cameron welcomes correspondence to: claird@phaseit.net.