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