9

Is there any way to get all opened sockets using ? I know the lsof command and this is what I'm looking for, but how to use it in a application?

The idea is to get the FD of an opened socket by its port number and the pid.

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187

5 Answers5

5

Just open the files in /proc/net, like /proc/net/tcp, /proc/net/udp, etc. No need to slog through the lsof sources. :)

  • and how can I make mapping port:FD from /proc/net/tcp ? I don't see such info there – Kiril Kirov Dec 17 '10 at 13:35
  • The port is hex encoded after the `:` of the local_address and remote_address in /proc/net/tcp. You then have to scan all of /proc/*/fd using readlink() and parse out the number of that symlink, e.g. `socket:[1771485]` 1771485 is the inode number, and you'll find that inode number in /proc/net/tcp (or any other similar file depending on whether it's tcp/udp and ipv4 or ipv6 etc. – nos Dec 17 '10 at 14:33
3

If you don't want to copy/paste or reimplement chunks of the lsof code, and it doesn't build any useful libraries you could leverage, you can still open a pipe to an lsof process and peruse its output.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • Thanks a lot, this will be my plan-b solution, of the Billy's solution fails for some reason. – Kiril Kirov Dec 17 '10 at 15:22
  • @Kiril: the main thing there might just be portability. lsof works out how to get the data on a wide variety of systems, only some of which provide /proc, and even amongst those the content of /proc can differ. Still, if you don't need a lot of portability, then cutting out lsof will make it much faster, and quite possibly simpler too. – Tony Delroy Dec 17 '10 at 15:27
  • I don't need a lot of portability, the application is supposed to work only for RHEL 4 and 5. Yes, I chose Billy's answer because of performance. Also, what bothers me, is that if the version of lsof is different from the version, I'm testing with, there could be problems with the parsing. But I'll implement this, in case the the first way fails, so I'll use both. – Kiril Kirov Dec 17 '10 at 16:00
2

The lsof command is prepared specifically such that it can be used from other programs including C, see the section: OUTPUT FOR OTHER PROGRAMS of man lsof for more information. For example you can invoke lsof with -F p and it will output the pid of the processes prefixed with 'p':

$ lsof -F p /some/file
p1234
p4321

you can then use popen to execute this commmand in a child process and read from its standard output.

lanoxx
  • 12,249
  • 13
  • 87
  • 142
2

check the lsof source?

ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/

rve
  • 5,897
  • 3
  • 40
  • 64
0

In C (or C++) you can use the NETLINK_SOCK_DIAG interface. This is a socket that gives you access to all that information. You can filter on various parameters such as the interface the socket is attached to.

The documentation is spares, however, but I wrote a low level test to see whether I could get events whenever someone opened a new socket, but that didn't work. That being said, to list existing sockets, you can use the following code as a good starting point:

Can the NETLINK/SOCK_DIAG interface be used to listen for `listen()` and `close()` events of said socket?

I think that this is cleaner than parsing the /proc/net/tcp and other similar files. You get the same information, but it comes to you in binary.

It may also be simpler to use the libnml library which is a layer over the socket. It does many additional verification on all the calls. However, just like the base NETLINK interface, it's not very well documented (i.e. whether binding is important, flags you can use with TCP or UDP, etc.) The good thing is: you can always read the source to better understand what's going on.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156