]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man7/sock_diag.7
Many pages: Use correct letter case in page titles (TH)
[thirdparty/man-pages.git] / man7 / sock_diag.7
CommitLineData
4f6a0a4a
PE
1.\" Copyright (c) 2016 Pavel Emelyanov <xemul@virtuozzo.com>
2.\" Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
3.\"
e4a74ca8 4.\" SPDX-License-Identifier: GPL-2.0-or-later
4c1c5274 5.TH sock_diag 7 (date) "Linux man-pages (unreleased)"
4f6a0a4a
PE
6.SH NAME
7sock_diag \- obtaining information about sockets
8.SH SYNOPSIS
9.nf
10.B #include <sys/socket.h>
11.B #include <linux/sock_diag.h>
12.BR "#include <linux/unix_diag.h>" " /* for UNIX domain sockets */"
13.BR "#include <linux/inet_diag.h>" " /* for IPv4 and IPv6 sockets */"
f90f031e 14.PP
4f6a0a4a
PE
15.BI "diag_socket = socket(AF_NETLINK, " socket_type ", NETLINK_SOCK_DIAG);"
16.fi
17.SH DESCRIPTION
18The sock_diag netlink subsystem provides a mechanism for obtaining
e2734d29 19information about sockets of various address families from the kernel.
4f6a0a4a
PE
20This subsystem can be used to obtain information about individual
21sockets or request a list of sockets.
9647e2d9 22.PP
e2734d29
MK
23In the request, the caller can specify additional information it would
24like to obtain about the socket, for example, memory information or
25information specific to the address family.
9647e2d9 26.PP
4f6a0a4a
PE
27When requesting a list of sockets, the caller can specify filters that
28would be applied by the kernel to select a subset of sockets to report.
e2734d29
MK
29For now, there is only the ability to filter sockets by state (connected,
30listening, and so on.)
9647e2d9 31.PP
e2734d29
MK
32Note that sock_diag reports only those sockets that have a name;
33that is, either sockets bound explicitly with
4f6a0a4a
PE
34.BR bind (2)
35or sockets that were automatically bound to an address (e.g., by
36.BR connect (2)).
37This is the same set of sockets that is available via
38.IR /proc/net/unix ,
39.IR /proc/net/tcp ,
40.IR /proc/net/udp ,
e2734d29
MK
41and so on.
42.\"
4f6a0a4a 43.SS Request
e2734d29 44The request starts with a
4f6a0a4a
PE
45.I "struct nlmsghdr"
46header described in
47.BR netlink (7)
48with
49.I nlmsg_type
50field set to
51.BR SOCK_DIAG_BY_FAMILY .
e2734d29
MK
52It is followed by a header specific to the address family that starts with
53a common part shared by all address families:
9647e2d9 54.PP
4f6a0a4a 55.in +4n
b8302363 56.EX
4f6a0a4a 57struct sock_diag_req {
115b4e0e
AC
58 __u8 sdiag_family;
59 __u8 sdiag_protocol;
4f6a0a4a 60};
b8302363 61.EE
4f6a0a4a
PE
62.in
63.PP
64The fields of this structure are as follows:
65.TP
66.I sdiag_family
e2734d29 67An address family.
6d654721 68It should be set to the appropriate
4f6a0a4a
PE
69.B AF_*
70constant.
71.TP
72.I sdiag_protocol
73Depends on
74.IR sdiag_family .
75It should be set to the appropriate
76.B IPPROTO_*
77constant for
78.B AF_INET
79and
d8012462 80.BR AF_INET6 ,
4f6a0a4a
PE
81and to 0 otherwise.
82.PP
e2734d29 83If the
4f6a0a4a
PE
84.I nlmsg_flags
85field of the
86.I "struct nlmsghdr"
e2734d29 87header has the
1ae6b2c7 88.B NLM_F_DUMP
e2734d29 89flag set, it means that a list of sockets is being requested;
4f6a0a4a 90otherwise it is a query about an individual socket.
e2734d29 91.\"
4f6a0a4a 92.SS Response
e2734d29 93The response starts with a
4f6a0a4a 94.I "struct nlmsghdr"
e2734d29 95header and is followed by an array of objects specific to the address family.
4f6a0a4a
PE
96The array is to be accessed with the standard
97.B NLMSG_*
e2734d29 98macros from the
4f6a0a4a
PE
99.BR netlink (3)
100API.
101.PP
102Each object is the NLA (netlink attributes) list that is to be accessed
103with the
104.B RTA_*
105macros from
106.BR rtnetlink (3)
107API.
9647e2d9 108.\"
4f6a0a4a
PE
109.SS UNIX domain sockets
110For UNIX domain sockets the request is represented in the following structure:
9647e2d9 111.PP
4f6a0a4a 112.in +4n
b8302363 113.EX
4f6a0a4a 114struct unix_diag_req {
115b4e0e
AC
115 __u8 sdiag_family;
116 __u8 sdiag_protocol;
117 __u16 pad;
118 __u32 udiag_states;
119 __u32 udiag_ino;
120 __u32 udiag_show;
121 __u32 udiag_cookie[2];
4f6a0a4a 122};
b8302363 123.EE
4f6a0a4a
PE
124.in
125.PP
126The fields of this structure are as follows:
127.TP
128.I sdiag_family
9e39d87d 129The address family; it should be set to
4f6a0a4a
PE
130.BR AF_UNIX .
131.PP
132.I sdiag_protocol
133.PD 0
134.TP
135.PD
136.I pad
137These fields should be set to 0.
138.TP
139.I udiag_states
140This is a bit mask that defines a filter of sockets states.
141Only those sockets whose states are in this mask will be reported.
142Ignored when querying for an individual socket.
143Supported values are:
9647e2d9 144.PP
9e39d87d 145.RS 12
4f6a0a4a
PE
1461 <<
147.B TCP_ESTABLISHED
5711c04f 148.PP
4f6a0a4a
PE
1491 <<
150.B TCP_LISTEN
151.RE
4f6a0a4a
PE
152.TP
153.I udiag_ino
154This is an inode number when querying for an individual socket.
155Ignored when querying for a list of sockets.
156.TP
157.I udiag_show
158This is a set of flags defining what kind of information to report.
159Each requested kind of information is reported back as a netlink
160attribute as described below:
161.RS
e6e0499e 162.TP
4f6a0a4a 163.B UDIAG_SHOW_NAME
4f6a0a4a
PE
164The attribute reported in answer to this request is
165.BR UNIX_DIAG_NAME .
166The payload associated with this attribute is the pathname to which
167the socket was bound (a sequence of bytes up to
168.B UNIX_PATH_MAX
169length).
e6e0499e 170.TP
4f6a0a4a 171.B UDIAG_SHOW_VFS
4f6a0a4a
PE
172The attribute reported in answer to this request is
173.BR UNIX_DIAG_VFS .
174The payload associated with this attribute is represented in the following
175structure:
9647e2d9 176.IP
4f6a0a4a 177.in +4n
b8302363 178.EX
4f6a0a4a 179struct unix_diag_vfs {
115b4e0e
AC
180 __u32 udiag_vfs_dev;
181 __u32 udiag_vfs_ino;
4f6a0a4a 182};
b8302363 183.EE
4f6a0a4a 184.in
9647e2d9 185.IP
4f6a0a4a 186The fields of this structure are as follows:
e6e0499e
MK
187.RS
188.TP
4f6a0a4a
PE
189.I udiag_vfs_dev
190The device number of the corresponding on-disk socket inode.
e6e0499e 191.TP
4f6a0a4a
PE
192.I udiag_vfs_ino
193The inode number of the corresponding on-disk socket inode.
194.RE
e6e0499e 195.TP
4f6a0a4a 196.B UDIAG_SHOW_PEER
4f6a0a4a
PE
197The attribute reported in answer to this request is
198.BR UNIX_DIAG_PEER .
115b4e0e 199The payload associated with this attribute is a __u32 value
4f6a0a4a
PE
200which is the peer's inode number.
201This attribute is reported for connected sockets only.
e6e0499e 202.TP
4f6a0a4a 203.B UDIAG_SHOW_ICONS
4f6a0a4a
PE
204The attribute reported in answer to this request is
205.BR UNIX_DIAG_ICONS .
115b4e0e 206The payload associated with this attribute is an array of __u32 values
4f6a0a4a
PE
207which are inode numbers of sockets that has passed the
208.BR connect (2)
209call, but hasn't been processed with
210.BR accept (2)
6d654721
MK
211yet.
212This attribute is reported for listening sockets only.
e6e0499e 213.TP
4f6a0a4a 214.B UDIAG_SHOW_RQLEN
4f6a0a4a
PE
215The attribute reported in answer to this request is
216.BR UNIX_DIAG_RQLEN .
217The payload associated with this attribute is represented in the following
218structure:
9647e2d9 219.IP
4f6a0a4a 220.in +4n
b8302363 221.EX
4f6a0a4a 222struct unix_diag_rqlen {
115b4e0e
AC
223 __u32 udiag_rqueue;
224 __u32 udiag_wqueue;
4f6a0a4a 225};
b8302363 226.EE
4f6a0a4a 227.in
9647e2d9 228.IP
4f6a0a4a 229The fields of this structure are as follows:
94dc419f
MK
230.RS
231.TP
4f6a0a4a 232.I udiag_rqueue
94dc419f
MK
233For listening sockets:
234the number of pending connections.
235The length of the array associated with the
4f6a0a4a
PE
236.B UNIX_DIAG_ICONS
237response attribute is equal to this value.
9647e2d9 238.IP
94dc419f
MK
239For established sockets:
240the amount of data in incoming queue.
241.TP
4f6a0a4a 242.I udiag_wqueue
94dc419f
MK
243For listening sockets:
244the backlog length which equals to the value passed as the second argument to
4f6a0a4a 245.BR listen (2).
9647e2d9 246.IP
94dc419f
MK
247For established sockets:
248the amount of memory available for sending.
4f6a0a4a 249.RE
e6e0499e 250.TP
4f6a0a4a 251.B UDIAG_SHOW_MEMINFO
4f6a0a4a
PE
252The attribute reported in answer to this request is
253.BR UNIX_DIAG_MEMINFO .
115b4e0e 254The payload associated with this attribute is an array of __u32 values
9e39d87d 255described below in the subsection "Socket memory information".
e6e0499e 256.PP
4f6a0a4a 257The following attributes are reported back without any specific request:
e6e0499e 258.TP
1ae6b2c7 259.B UNIX_DIAG_SHUTDOWN
115b4e0e 260The payload associated with this attribute is __u8 value which represents
4f6a0a4a
PE
261bits of
262.BR shutdown (2)
263state.
264.RE
265.TP
266.I udiag_cookie
267This is an array of opaque identifiers that could be used along with
268.I udiag_ino
6d654721
MK
269to specify an individual socket.
270It is ignored when querying for a list
4f6a0a4a
PE
271of sockets, as well as when all its elements are set to \-1.
272.PP
273The response to a query for UNIX domain sockets is represented as an array of
9647e2d9 274.PP
4f6a0a4a 275.in +4n
b8302363 276.EX
4f6a0a4a 277struct unix_diag_msg {
115b4e0e
AC
278 __u8 udiag_family;
279 __u8 udiag_type;
280 __u8 udiag_state;
281 __u8 pad;
282 __u32 udiag_ino;
283 __u32 udiag_cookie[2];
4f6a0a4a 284};
b8302363 285.EE
4f6a0a4a 286.in
9647e2d9 287.PP
4f6a0a4a
PE
288followed by netlink attributes.
289.PP
290The fields of this structure are as follows:
291.TP
292.I udiag_family
293This field has the same meaning as in
294.IR "struct unix_diag_req" .
295.TP
296.I udiag_type
9e39d87d
MK
297This is set to one of
298.BR SOCK_PACKET ,
299.BR SOCK_STREAM ,
300or
301.BR SOCK_SEQPACKET .
4f6a0a4a
PE
302.TP
303.I udiag_state
9e39d87d 304This is set to one of
1ae6b2c7 305.B TCP_LISTEN
9e39d87d
MK
306or
307.BR TCP_ESTABLISHED .
4f6a0a4a
PE
308.TP
309.I pad
310This field is set to 0.
311.TP
312.I udiag_ino
313This is the socket inode number.
314.TP
315.I udiag_cookie
316This is an array of opaque identifiers that could be used in subsequent
317queries.
9e39d87d 318.\"
4f6a0a4a 319.SS IPv4 and IPv6 sockets
9e39d87d
MK
320For IPv4 and IPv6 sockets,
321the request is represented in the following structure:
9647e2d9 322.PP
4f6a0a4a 323.in +4n
b8302363 324.EX
4f6a0a4a 325struct inet_diag_req_v2 {
115b4e0e
AC
326 __u8 sdiag_family;
327 __u8 sdiag_protocol;
328 __u8 idiag_ext;
329 __u8 pad;
330 __u32 idiag_states;
4f6a0a4a
PE
331 struct inet_diag_sockid id;
332};
b8302363 333.EE
4f6a0a4a 334.in
9647e2d9 335.PP
4f6a0a4a
PE
336where
337.I "struct inet_diag_sockid"
338is defined as follows:
9647e2d9 339.PP
4f6a0a4a 340.in +4n
b8302363 341.EX
4f6a0a4a 342struct inet_diag_sockid {
115b4e0e
AC
343 __be16 idiag_sport;
344 __be16 idiag_dport;
345 __be32 idiag_src[4];
346 __be32 idiag_dst[4];
347 __u32 idiag_if;
348 __u32 idiag_cookie[2];
4f6a0a4a 349};
b8302363 350.EE
4f6a0a4a
PE
351.in
352.PP
353The fields of
354.I "struct inet_diag_req_v2"
355are as follows:
356.TP
357.I sdiag_family
358This should be set to either
359.B AF_INET
360or
361.B AF_INET6
9e39d87d 362for IPv4 or IPv6 sockets respectively.
4f6a0a4a
PE
363.TP
364.I sdiag_protocol
9e39d87d
MK
365This should be set to one of
366.BR IPPROTO_TCP ,
367.BR IPPROTO_UDP ,
368or
369.BR IPPROTO_UDPLITE .
4f6a0a4a
PE
370.TP
371.I idiag_ext
372This is a set of flags defining what kind of extended information to report.
373Each requested kind of information is reported back as a netlink attribute
374as described below:
375.RS
376.TP
377.B INET_DIAG_TOS
115b4e0e 378The payload associated with this attribute is a __u8 value
4f6a0a4a
PE
379which is the TOS of the socket.
380.TP
381.B INET_DIAG_TCLASS
115b4e0e 382The payload associated with this attribute is a __u8 value
6d654721
MK
383which is the TClass of the socket.
384IPv6 sockets only.
9e39d87d 385For LISTEN and CLOSE sockets, this is followed by
4f6a0a4a 386.B INET_DIAG_SKV6ONLY
115b4e0e 387attribute with associated __u8 payload value meaning whether the socket
4f6a0a4a
PE
388is IPv6-only or not.
389.TP
390.B INET_DIAG_MEMINFO
391The payload associated with this attribute is represented in the following
392structure:
9647e2d9 393.IP
4f6a0a4a 394.in +4n
b8302363 395.EX
4f6a0a4a 396struct inet_diag_meminfo {
115b4e0e
AC
397 __u32 idiag_rmem;
398 __u32 idiag_wmem;
399 __u32 idiag_fmem;
400 __u32 idiag_tmem;
4f6a0a4a 401};
b8302363 402.EE
4f6a0a4a 403.in
9647e2d9 404.IP
4f6a0a4a
PE
405The fields of this structure are as follows:
406.RS
407.TP 12
408.I idiag_rmem
409The amount of data in the receive queue.
410.TP
411.I idiag_wmem
412The amount of data that is queued by TCP but not yet sent.
413.TP
414.I idiag_fmem
415The amount of memory scheduled for future use (TCP only).
416.TP
417.I idiag_tmem
418The amount of data in send queue.
419.RE
420.TP
421.B INET_DIAG_SKMEMINFO
115b4e0e 422The payload associated with this attribute is an array of __u32 values
9e39d87d 423described below in the subsection "Socket memory information".
4f6a0a4a
PE
424.TP
425.B INET_DIAG_INFO
e2734d29
MK
426The payload associated with this attribute is specific to the address family.
427For TCP sockets, it is an object of type
4f6a0a4a
PE
428.IR "struct tcp_info" .
429.TP
430.B INET_DIAG_CONG
431The payload associated with this attribute is a string that describes the
6d654721
MK
432congestion control algorithm used.
433For TCP sockets only.
4f6a0a4a
PE
434.RE
435.TP
436.I pad
437This should be set to 0.
438.TP
439.I idiag_states
9e39d87d 440This is a bit mask that defines a filter of socket states.
4f6a0a4a
PE
441Only those sockets whose states are in this mask will be reported.
442Ignored when querying for an individual socket.
443.TP
444.I id
9e39d87d 445This is a socket ID object that is used in dump requests, in queries
4f6a0a4a
PE
446about individual sockets, and is reported back in each response.
447Unlike UNIX domain sockets, IPv4 and IPv6 sockets are identified
6d654721
MK
448using addresses and ports.
449All values are in network byte order.
4f6a0a4a
PE
450.PP
451The fields of
452.I "struct inet_diag_sockid"
453are as follows:
454.TP
455.I idiag_sport
456The source port.
457.TP
458.I idiag_dport
459The destination port.
460.TP
461.I idiag_src
462The source address.
463.TP
464.I idiag_dst
465The destination address.
466.TP
467.I idiag_if
468The interface number the socket is bound to.
469.TP
470.I idiag_cookie
471This is an array of opaque identifiers that could be used along with
472other fields of this structure to specify an individual socket.
473It is ignored when querying for a list of sockets, as well as
474when all its elements are set to \-1.
475.PP
476The response to a query for IPv4 or IPv6 sockets is represented as an array of
9647e2d9 477.PP
4f6a0a4a 478.in +4n
b8302363 479.EX
4f6a0a4a 480struct inet_diag_msg {
115b4e0e
AC
481 __u8 idiag_family;
482 __u8 idiag_state;
483 __u8 idiag_timer;
484 __u8 idiag_retrans;
4f6a0a4a
PE
485
486 struct inet_diag_sockid id;
487
115b4e0e
AC
488 __u32 idiag_expires;
489 __u32 idiag_rqueue;
490 __u32 idiag_wqueue;
491 __u32 idiag_uid;
492 __u32 idiag_inode;
4f6a0a4a 493};
b8302363 494.EE
4f6a0a4a 495.in
9647e2d9 496.PP
4f6a0a4a
PE
497followed by netlink attributes.
498.PP
499The fields of this structure are as follows:
500.TP
501.I idiag_family
502This is the same field as in
503.IR "struct inet_diag_req_v2" .
504.TP
505.I idiag_state
506This denotes socket state as in
507.IR "struct inet_diag_req_v2" .
508.TP
509.I idiag_timer
510For TCP sockets, this field describes the type of timer that is currently
6d654721
MK
511active for the socket.
512It is set to one of the following constants:
9647e2d9 513.IP
9e39d87d
MK
514.PD 0
515.RS 12
4f6a0a4a
PE
516.TP
517.B 0
518no timer is active
519.TP
520.B 1
521a retransmit timer
522.TP
523.B 2
524a keep-alive timer
525.TP
526.B 3
527a TIME_WAIT timer
528.TP
529.B 4
530a zero window probe timer
531.RE
9e39d87d 532.PD
4f6a0a4a 533.IP
9e39d87d 534For non-TCP sockets, this field is set to 0.
4f6a0a4a
PE
535.TP
536.I idiag_retrans
537For
538.I idiag_timer
9e39d87d 539values 1, 2, and 4, this field contains the number of retransmits.
6d654721 540For other
4f6a0a4a 541.I idiag_timer
9e39d87d 542values, this field is set to 0.
4f6a0a4a
PE
543.TP
544.I idiag_expires
9e39d87d 545For TCP sockets that have an active timer, this field describes its expiration
6d654721 546time in milliseconds.
9e39d87d 547For other sockets, this field is set to 0.
4f6a0a4a
PE
548.TP
549.I idiag_rqueue
9e39d87d
MK
550For listening sockets:
551the number of pending connections.
9647e2d9 552.IP
9e39d87d
MK
553For other sockets:
554the amount of data in the incoming queue.
4f6a0a4a
PE
555.TP
556.I idiag_wqueue
9e39d87d
MK
557For listening sockets:
558the backlog length.
9647e2d9 559.IP
990b14c4 560For other sockets:
9e39d87d 561the amount of memory available for sending.
4f6a0a4a
PE
562.TP
563.I idiag_uid
564This is the socket owner UID.
565.TP
566.I idiag_inode
567This is the socket inode number.
9e39d87d 568.\"
4f6a0a4a
PE
569.SS Socket memory information
570The payload associated with
571.B UNIX_DIAG_MEMINFO
572and
1ae6b2c7 573.B INET_DIAG_SKMEMINFO
115b4e0e 574netlink attributes is an array of the following __u32 values:
4f6a0a4a
PE
575.TP
576.B SK_MEMINFO_RMEM_ALLOC
577The amount of data in receive queue.
578.TP
579.B SK_MEMINFO_RCVBUF
580The receive socket buffer as set by
581.BR SO_RCVBUF .
582.TP
583.B SK_MEMINFO_WMEM_ALLOC
584The amount of data in send queue.
585.TP
586.B SK_MEMINFO_SNDBUF
587The send socket buffer as set by
588.BR SO_SNDBUF .
589.TP
590.B SK_MEMINFO_FWD_ALLOC
591The amount of memory scheduled for future use (TCP only).
592.TP
593.B SK_MEMINFO_WMEM_QUEUED
594The amount of data queued by TCP, but not yet sent.
595.TP
596.B SK_MEMINFO_OPTMEM
9e39d87d 597The amount of memory allocated for the socket's service needs (e.g., socket
4f6a0a4a
PE
598filter).
599.TP
600.B SK_MEMINFO_BACKLOG
601The amount of packets in the backlog (not yet processed).
4f6a0a4a
PE
602.SH VERSIONS
603.B NETLINK_INET_DIAG
604was introduced in Linux 2.6.14 and supported
605.B AF_INET
606and
607.B AF_INET6
6d654721 608sockets only.
9e39d87d 609In Linux 3.3, it was renamed to
4f6a0a4a
PE
610.B NETLINK_SOCK_DIAG
611and extended to support
612.B AF_UNIX
613sockets.
614.PP
615.B UNIX_DIAG_MEMINFO
616and
1ae6b2c7 617.B INET_DIAG_SKMEMINFO
4f6a0a4a 618were introduced in Linux 3.6.
3113c7f3 619.SH STANDARDS
61d92a91 620The NETLINK_SOCK_DIAG API is Linux-specific.
a14af333 621.SH EXAMPLES
4f6a0a4a
PE
622The following example program prints inode number, peer's inode number,
623and name of all UNIX domain sockets in the current namespace.
9647e2d9 624.PP
9c40f2b9 625.EX
4f6a0a4a
PE
626#include <errno.h>
627#include <stdio.h>
628#include <string.h>
629#include <unistd.h>
630#include <sys/socket.h>
631#include <sys/un.h>
632#include <linux/netlink.h>
633#include <linux/rtnetlink.h>
634#include <linux/sock_diag.h>
635#include <linux/unix_diag.h>
636
637static int
638send_query(int fd)
639{
640 struct sockaddr_nl nladdr = {
641 .nl_family = AF_NETLINK
642 };
643 struct
644 {
645 struct nlmsghdr nlh;
646 struct unix_diag_req udr;
647 } req = {
648 .nlh = {
649 .nlmsg_len = sizeof(req),
650 .nlmsg_type = SOCK_DIAG_BY_FAMILY,
651 .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP
652 },
653 .udr = {
654 .sdiag_family = AF_UNIX,
655 .udiag_states = \-1,
656 .udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER
657 }
658 };
659 struct iovec iov = {
660 .iov_base = &req,
661 .iov_len = sizeof(req)
662 };
663 struct msghdr msg = {
44ab56cd 664 .msg_name = &nladdr,
4f6a0a4a
PE
665 .msg_namelen = sizeof(nladdr),
666 .msg_iov = &iov,
667 .msg_iovlen = 1
668 };
669
670 for (;;) {
671 if (sendmsg(fd, &msg, 0) < 0) {
672 if (errno == EINTR)
673 continue;
c974db09 674
4f6a0a4a
PE
675 perror("sendmsg");
676 return \-1;
677 }
c974db09 678
4f6a0a4a
PE
679 return 0;
680 }
681}
682
683static int
684print_diag(const struct unix_diag_msg *diag, unsigned int len)
685{
686 if (len < NLMSG_LENGTH(sizeof(*diag))) {
d1a71985 687 fputs("short response\en", stderr);
4f6a0a4a
PE
688 return \-1;
689 }
690 if (diag\->udiag_family != AF_UNIX) {
d1a71985 691 fprintf(stderr, "unexpected family %u\en", diag\->udiag_family);
4f6a0a4a
PE
692 return \-1;
693 }
694
4f6a0a4a
PE
695 unsigned int rta_len = len \- NLMSG_LENGTH(sizeof(*diag));
696 unsigned int peer = 0;
697 size_t path_len = 0;
698 char path[sizeof(((struct sockaddr_un *) 0)\->sun_path) + 1];
699
88893a77 700 for (struct rtattr *attr = (struct rtattr *) (diag + 1);
4f6a0a4a
PE
701 RTA_OK(attr, rta_len); attr = RTA_NEXT(attr, rta_len)) {
702 switch (attr\->rta_type) {
c974db09
MK
703 case UNIX_DIAG_NAME:
704 if (!path_len) {
705 path_len = RTA_PAYLOAD(attr);
706 if (path_len > sizeof(path) \- 1)
707 path_len = sizeof(path) \- 1;
708 memcpy(path, RTA_DATA(attr), path_len);
861d36ba 709 path[path_len] = \(aq\e0\(aq;
c974db09
MK
710 }
711 break;
712
713 case UNIX_DIAG_PEER:
714 if (RTA_PAYLOAD(attr) >= sizeof(peer))
715 peer = *(unsigned int *) RTA_DATA(attr);
716 break;
4f6a0a4a
PE
717 }
718 }
719
d064d41a 720 printf("inode=%u", diag\->udiag_ino);
4f6a0a4a
PE
721
722 if (peer)
723 printf(", peer=%u", peer);
724
725 if (path_len)
c974db09
MK
726 printf(", name=%s%s", *path ? "" : "@",
727 *path ? path : path + 1);
4f6a0a4a 728
861d36ba 729 putchar(\(aq\en\(aq);
4f6a0a4a
PE
730 return 0;
731}
732
733static int
734receive_responses(int fd)
735{
736 long buf[8192 / sizeof(long)];
bc766f2c 737 struct sockaddr_nl nladdr;
4f6a0a4a
PE
738 struct iovec iov = {
739 .iov_base = buf,
740 .iov_len = sizeof(buf)
741 };
742 int flags = 0;
743
744 for (;;) {
745 struct msghdr msg = {
44ab56cd 746 .msg_name = &nladdr,
4f6a0a4a
PE
747 .msg_namelen = sizeof(nladdr),
748 .msg_iov = &iov,
749 .msg_iovlen = 1
750 };
751
752 ssize_t ret = recvmsg(fd, &msg, flags);
753
754 if (ret < 0) {
755 if (errno == EINTR)
756 continue;
c974db09 757
4f6a0a4a
PE
758 perror("recvmsg");
759 return \-1;
760 }
761 if (ret == 0)
762 return 0;
763
bc766f2c
PR
764 if (nladdr.nl_family != AF_NETLINK) {
765 fputs("!AF_NETLINK\en", stderr);
766 return \-1;
767 }
768
4f6a0a4a
PE
769 const struct nlmsghdr *h = (struct nlmsghdr *) buf;
770
771 if (!NLMSG_OK(h, ret)) {
d1a71985 772 fputs("!NLMSG_OK\en", stderr);
4f6a0a4a
PE
773 return \-1;
774 }
c974db09 775
4f6a0a4a
PE
776 for (; NLMSG_OK(h, ret); h = NLMSG_NEXT(h, ret)) {
777 if (h\->nlmsg_type == NLMSG_DONE)
778 return 0;
c974db09 779
4f6a0a4a
PE
780 if (h\->nlmsg_type == NLMSG_ERROR) {
781 const struct nlmsgerr *err = NLMSG_DATA(h);
782
783 if (h\->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) {
d1a71985 784 fputs("NLMSG_ERROR\en", stderr);
4f6a0a4a
PE
785 } else {
786 errno = \-err\->error;
787 perror("NLMSG_ERROR");
788 }
c974db09 789
4f6a0a4a
PE
790 return \-1;
791 }
c974db09 792
4f6a0a4a 793 if (h\->nlmsg_type != SOCK_DIAG_BY_FAMILY) {
d1a71985 794 fprintf(stderr, "unexpected nlmsg_type %u\en",
4f6a0a4a
PE
795 (unsigned) h\->nlmsg_type);
796 return \-1;
797 }
798
799 if (print_diag(NLMSG_DATA(h), h\->nlmsg_len))
800 return \-1;
801 }
802 }
803}
804
805int
806main(void)
807{
808 int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
809
810 if (fd < 0) {
811 perror("socket");
812 return 1;
813 }
814
815 int ret = send_query(fd) || receive_responses(fd);
816
817 close(fd);
818 return ret;
819}
9c40f2b9 820.EE
4f6a0a4a
PE
821.SH SEE ALSO
822.BR netlink (3),
823.BR rtnetlink (3),
824.BR netlink (7),
825.BR tcp (7)