How to track raw sockets in Linux

M Castelino
3 min readApr 11, 2019

--

Example program

Say a program has opened a raw socket. How do you know it has it open

+       int sock_r;
+ struct ifreq ifrr;
+ size_t if_name_len=strlen("dummy0");
+ struct sockaddr_ll sll;
+
+ sock_r=socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if(sock_r < 0)
+ {
+ return 0;
+ }
+
+ if (if_name_len<sizeof(ifrr.ifr_name)) {
+ memcpy(ifrr.ifr_name,"dummy0",if_name_len);
+ ifrr.ifr_name[if_name_len]=0;
+ } else {
+ close(sock_r);
+ return 0;
+ }
+
+ if (ioctl(sock_r,SIOCGIFINDEX,&ifrr)==-1) {
+ close(sock_r);
+ return 0;
+ }
+
+ sll.sll_family = AF_PACKET;
+ sll.sll_protocol = htons(ETH_P_ALL);
+ sll.sll_ifindex = ifrr.ifr_ifindex;
+
+ if (bind(sock_r, (struct sockaddr *)&sll, sizeof(sll))==-1) {
+ close(sock_r);
+ return 0;
+ }

Using ss

ss -f link -lnp
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
p_raw UNCONN 0 0 *:dummy0 * users:(("lkvm",pid=12479,fd=17))
p_raw UNCONN 0 0 *:ens2 * users:(("dhclient",pid=897,fd=5))
root@amused-dagonet:/proc/12397/fd# ls -l /proc/12479/fd
total 0
lrwx------ 1 root root 64 Apr 5 18:33 0 -> /dev/pts/5
lrwx------ 1 root root 64 Apr 5 18:33 1 -> /dev/pts/5
lrwx------ 1 root root 64 Apr 5 18:33 10 -> anon_inode:kvm-vcpu
lrwx------ 1 root root 64 Apr 5 18:33 11 -> anon_inode:kvm-vcpu
lrwx------ 1 root root 64 Apr 5 18:33 12 -> /home/mrcastel/rootfs.ext4
lrwx------ 1 root root 64 Apr 5 18:33 13 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Apr 5 18:33 14 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Apr 5 18:33 15 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Apr 5 18:33 16 -> socket:[130535]
lrwx------ 1 root root 64 Apr 5 18:33 17 -> socket:[130536]
lrwx------ 1 root root 64 Apr 5 18:33 18 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Apr 5 18:33 19 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Apr 5 18:33 2 -> /dev/pts/5
lrwx------ 1 root root 64 Apr 5 18:33 20 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Apr 5 18:33 21 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Apr 5 18:33 22 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Apr 5 18:33 23 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Apr 5 18:33 3 -> /dev/kvm
lrwx------ 1 root root 64 Apr 5 18:33 4 -> anon_inode:kvm-vm
lrwx------ 1 root root 64 Apr 5 18:33 5 -> socket:[129805]
lrwx------ 1 root root 64 Apr 5 18:33 6 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Apr 5 18:33 7 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Apr 5 18:33 8 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Apr 5 18:33 9 -> anon_inode:[eventfd]

/proc

cat /proc/net/packet
sk RefCnt Type Proto Iface R Rmem User Inode
ffff8801b64e4000 3 3 0003 17 1 0 0 130536
ffff8800b9ed6000 3 3 0003 2 1 0 0 12971

Reference

http://sgros.blogspot.com/2012/02/whos-listening-on-interface.html

Can you write to the fd

Unfortunately you cannot

http://lxr.linux.no/#linux+v3.2.11/net/socket.c#L135

130/*
131 * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
132 * in the operation structures but are done directly via the socketcall() multiplexor.
133 */
134
135static const struct file_operations socket_file_ops = {
136 .owner = THIS_MODULE,
137 .llseek = no_llseek,
138 .aio_read = sock_aio_read,
139 .aio_write = sock_aio_write,
140 .poll = sock_poll,
141 .unlocked_ioctl = sock_ioctl,
142#ifdef CONFIG_COMPAT
143 .compat_ioctl = compat_sock_ioctl,
144#endif
145 .mmap = sock_mmap,
146 .open = sock_no_open, /* special open code to disallow open via /proc */
147 .release = sock_close,
148 .fasync = sock_fasync,
149 .sendpage = sock_sendpage,
150 .splice_write = generic_splice_sendpage,
151 .splice_read = sock_splice_read,
152};

https://unix.stackexchange.com/questions/33924/write-inside-a-socket-open-by-another-process-in-linux?rq=1

--

--