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.)