[comp.unix.wizards] What processes are on the ends of a TCP connection?

jc@heart-of-goldmitre.org (John M Chambers) (03/02/89)

OK all you BSD networking wizards, here's a simple one (;-):

When I run "netstat -a", I can see a lot of TCP connections, as well as
a bunch of ports (both TCP and UDP) being listened on.  How do I identify
the processes that are involved?

I've recently had the fun of watching a bunch of people treat me like an
idiot for asking such a silly question, and proceed to show me all sorts
of interesting network info that I can get displayed.  When I point out
that they haven't yet shown anything that tells me the process ids, they
tend to get huffy and indignant, but they don't answer the question.  I've
had this fun (?) at several sites over a number of years, and still haven't
come up with an answer.  It seems like a silly little question that should
have a trivial answer.  So can someone out there explain to me just how
trivial it is?

Note that I'm not asking for the IP addresses or the port numbers or any
of that good stuff.  I know all that.  What I want is process numbers; I
won't be impressed by something that gives me volumes of other info but
doesn't finger the processes involved.

-- 
From:	John Chambers <heart-of-gold.mitre.org!jc>
From	...!linus!!heart-of-gold!jc (John Chambers 617/217-2285)
[The above opinions were packaged by volume, not by weight;
some settling of contents may have occurred during distribution.]

matt@oddjob.uchicago.edu (Matt Crawford) (03/04/89)

In article <190@heart-of-goldmitre.org> jc writes:
) OK all you BSD networking wizards, here's a simple one (;-):
) 
) How do I identify the processes that are involved?  [in a TCP
) connection] ...
) So can someone out there explain to me just how trivial it is?

Trivial?  You decide.  You can try going through the following procedure
with adb, then think about writing a program to do it for you.

Use "netstat -a -A" and note the "PCB" address of the connection of
interest.  Call that address AAA.

adb /vmunix /dev/kmem
0xAAA$<tcpcb		Note the adress of the "inpcb".  Call it BBB.
0xBBB$<inpcb		Note the address of the "socket".  Call it CCC.

Now for the fun part.  Look through the "struct proc"s of all the
processes in the process table and examine their "u" (aka "user") area,
which will be in memory locatable through the "struct pte p_addr" if the
process is resident, or on disk locatable through the "swblk_t p_swaddr"
if it is swapped out.  Examine the "struct file *u_ofile[]" array of
each process, looking for one whose "caddr_t f_data" opints to the
address CCC you noted above.

Whew!  Trivial, wasn't it?
________________________________________________________
Matt Crawford	     		matt@oddjob.uchicago.edu

ed@mtxinu.COM (Ed Gould) (03/04/89)

>When I run "netstat -a", I can see a lot of TCP connections, as well as
>a bunch of ports (both TCP and UDP) being listened on.  How do I identify
>the processes that are involved?

In general, there is not a way to track backwards from the port to the
process.  The network code can be thought of as having a top half and a
bottom half.  When a packet arrives from the net, the bottom half
processes the packet and - driven by a port number - hangs it on the
queue of the associated socket.  When a program wants to read data from
a socket, the top half - driven by a file descriptor - looks up the
proper socket and dequeues the data.

One intuitive way to understand that it's not possible to track upwards
to a PID is to remember that many processes may have descriptors that
refer to the same socket.  This will happen when a process with an open
socket forks.

It's plsusible to write a program that would look at processes (if
they happened to be swapped in) and track down to a socket, but I don't
know of any such tool.  Even if there were such a beast, I don't think
it will always be able to answer your question.

-- 
Ed Gould                    mt Xinu, 2560 Ninth St., Berkeley, CA  94710  USA
ed@mtxinu.COM		    +1 415 644 0146

"I'll fight them as a woman, not a lady.  I'll fight them as an engineer."

abe@mace.cc.purdue.edu (Vic Abell) (03/04/89)

In article <190@heart-of-goldmitre.org>, jc@heart-of-goldmitre.org (John M Chambers) writes:
> OK all you BSD networking wizards, here's a simple one (;-):
> 
> When I run "netstat -a", I can see a lot of TCP connections, as well as
> a bunch of ports (both TCP and UDP) being listened on.  How do I identify
> the processes that are involved?

Here are the 4+ easy steps for 4.3BSD, ULTRIX 2.2 and DYNIX 3.1[24] hosts.

1.  Use -aA on the netstat command and record the TCP Protocol Control
    Block address that is displayed for the entry whose PID you want:

	netstat -aA

2.  Run adb on the kernel:

		adb -k /vmunix /dev/mem

	a) Display the TCPCB at the address that netstat displayed:

		<netstat address>$<tcpcb

	b) Display the Internet Protocol Control Block (INPCB) at the address
	   displayed under "inpcb":

		<inpcb address>$<inpcb

	c) Display the socket at the address displayed under "socket":

		<socket address>$<socket

	   Verify that this is the correct socket by comparing the address
	   displayed under "pcb" with the INPCB address used in step b.
	   This step isn't really necessary -- it's only a sanity check.

3.  Now that you know the socket address, use pstat to find the file
    structure address.

	pstat -f | grep <socket address>

4.  For each process, look up its associated user structure and match
    its file structure addresses to the file structure address you got
    from pstat and grep.

		*proc$<proc
		<next process address>$<proc
	and
		<u address>$<u

    I'm not sure that you can do this step wholly with adb, because user
    structures can be swapped out.  Besides, it's excruciatingly tedious.

    However, the ofiles program already scans process table entries and
    associated user structures when looking for files, and it can handle
    swapped-out user structures.  So, all of these steps can be automated
    by changing ofiles to perform steps 1, 2 and 3 before it starts
    scanning the process table and their associated user structures.  It
    will then do step 4, too.

    I have such a mod - it only took a few hours to do.

As always, you should be aware that all of this reading of kernel data
structures is scarcely atomic.  Consequently, if the structures change
while you are following their links, you will not get the results you
expect.

Good luck!  I hope this relieves you of the need to ask embarrassing
questions about netstat.  :-)

marc@ucbvax.BERKELEY.EDU (Marc Teitelbaum) (03/16/89)

We have a new utility which displays the per process open file
tables.  If the file is a TCP socket, it prints the address of the
tcpcb (exactly what netstat -A prints - this is no accident).
Finding the associated process(s) is simply a matter of noting the
address from netstat -A and doing a "fstat | grep (address)".
Unless I'm mistaken, fstat(1) was shipped in 4.3-tahoe, and will
be present in the next release.

Marc
-------------------------------
Marc Teitelbaum			+1-415-643-6448
457 Evans Hall
Computer Systems Research Group,  CSRG / DEC
University of California
Berkeley, CA 94720

abe@mace.cc.purdue.edu (Vic Abell) (03/17/89)

I've tried fstat on our 4.3BSD, ULTRIX 2.2, DYNIX 3.1[24] and SunOS 4.0
systems.  It works on 4.3BSD (pre-Tahoe) with no change.  It requires one
change to compile under ULTRIX 2.2.  It does not compile under SunOS 4.0
or DYNIX 3.1[24], because of proc structure and header file differences -
e. g., proc.p0br, vnodes versus inodes/gnodes, etc.

Fstat's output is very useful.

It is not lint free (why do people distribute programs that don't pass
lint?), and lint shows an elementary argument handling error in its
rerr2() function (easy to fix.)