]>
Commit | Line | Data |
---|---|---|
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 |
26 | sock_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 | |
37 | The sock_diag netlink subsystem provides a mechanism for obtaining | |
e2734d29 | 38 | information about sockets of various address families from the kernel. |
4f6a0a4a PE |
39 | This subsystem can be used to obtain information about individual |
40 | sockets or request a list of sockets. | |
9647e2d9 | 41 | .PP |
e2734d29 MK |
42 | In the request, the caller can specify additional information it would |
43 | like to obtain about the socket, for example, memory information or | |
44 | information specific to the address family. | |
9647e2d9 | 45 | .PP |
4f6a0a4a PE |
46 | When requesting a list of sockets, the caller can specify filters that |
47 | would be applied by the kernel to select a subset of sockets to report. | |
e2734d29 MK |
48 | For now, there is only the ability to filter sockets by state (connected, |
49 | listening, and so on.) | |
9647e2d9 | 50 | .PP |
e2734d29 MK |
51 | Note that sock_diag reports only those sockets that have a name; |
52 | that is, either sockets bound explicitly with | |
4f6a0a4a PE |
53 | .BR bind (2) |
54 | or sockets that were automatically bound to an address (e.g., by | |
55 | .BR connect (2)). | |
56 | This 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 |
60 | and so on. |
61 | .\" | |
4f6a0a4a | 62 | .SS Request |
e2734d29 | 63 | The request starts with a |
4f6a0a4a PE |
64 | .I "struct nlmsghdr" |
65 | header described in | |
66 | .BR netlink (7) | |
67 | with | |
68 | .I nlmsg_type | |
69 | field set to | |
70 | .BR SOCK_DIAG_BY_FAMILY . | |
e2734d29 MK |
71 | It is followed by a header specific to the address family that starts with |
72 | a common part shared by all address families: | |
9647e2d9 | 73 | .PP |
4f6a0a4a | 74 | .in +4n |
b8302363 | 75 | .EX |
4f6a0a4a PE |
76 | struct sock_diag_req { |
77 | __u8 sdiag_family; | |
78 | __u8 sdiag_protocol; | |
79 | }; | |
b8302363 | 80 | .EE |
4f6a0a4a PE |
81 | .in |
82 | .PP | |
83 | The fields of this structure are as follows: | |
84 | .TP | |
85 | .I sdiag_family | |
e2734d29 | 86 | An address family. |
6d654721 | 87 | It should be set to the appropriate |
4f6a0a4a PE |
88 | .B AF_* |
89 | constant. | |
90 | .TP | |
91 | .I sdiag_protocol | |
92 | Depends on | |
93 | .IR sdiag_family . | |
94 | It should be set to the appropriate | |
95 | .B IPPROTO_* | |
96 | constant for | |
97 | .B AF_INET | |
98 | and | |
d8012462 | 99 | .BR AF_INET6 , |
4f6a0a4a PE |
100 | and to 0 otherwise. |
101 | .PP | |
e2734d29 | 102 | If the |
4f6a0a4a PE |
103 | .I nlmsg_flags |
104 | field of the | |
105 | .I "struct nlmsghdr" | |
e2734d29 | 106 | header has the |
4f6a0a4a | 107 | .BR NLM_F_DUMP |
e2734d29 | 108 | flag set, it means that a list of sockets is being requested; |
4f6a0a4a | 109 | otherwise it is a query about an individual socket. |
e2734d29 | 110 | .\" |
4f6a0a4a | 111 | .SS Response |
e2734d29 | 112 | The response starts with a |
4f6a0a4a | 113 | .I "struct nlmsghdr" |
e2734d29 | 114 | header and is followed by an array of objects specific to the address family. |
4f6a0a4a PE |
115 | The array is to be accessed with the standard |
116 | .B NLMSG_* | |
e2734d29 | 117 | macros from the |
4f6a0a4a PE |
118 | .BR netlink (3) |
119 | API. | |
120 | .PP | |
121 | Each object is the NLA (netlink attributes) list that is to be accessed | |
122 | with the | |
123 | .B RTA_* | |
124 | macros from | |
125 | .BR rtnetlink (3) | |
126 | API. | |
9647e2d9 | 127 | .\" |
4f6a0a4a PE |
128 | .SS UNIX domain sockets |
129 | For UNIX domain sockets the request is represented in the following structure: | |
9647e2d9 | 130 | .PP |
4f6a0a4a | 131 | .in +4n |
b8302363 | 132 | .EX |
4f6a0a4a PE |
133 | struct 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 | |
145 | The fields of this structure are as follows: | |
146 | .TP | |
147 | .I sdiag_family | |
9e39d87d | 148 | The 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 | |
156 | These fields should be set to 0. | |
157 | .TP | |
158 | .I udiag_states | |
159 | This is a bit mask that defines a filter of sockets states. | |
160 | Only those sockets whose states are in this mask will be reported. | |
161 | Ignored when querying for an individual socket. | |
162 | Supported values are: | |
9647e2d9 | 163 | .PP |
9e39d87d | 164 | .RS 12 |
4f6a0a4a PE |
165 | 1 << |
166 | .B TCP_ESTABLISHED | |
5711c04f | 167 | .PP |
4f6a0a4a PE |
168 | 1 << |
169 | .B TCP_LISTEN | |
170 | .RE | |
4f6a0a4a PE |
171 | .TP |
172 | .I udiag_ino | |
173 | This is an inode number when querying for an individual socket. | |
174 | Ignored when querying for a list of sockets. | |
175 | .TP | |
176 | .I udiag_show | |
177 | This is a set of flags defining what kind of information to report. | |
178 | Each requested kind of information is reported back as a netlink | |
179 | attribute as described below: | |
180 | .RS | |
e6e0499e | 181 | .TP |
4f6a0a4a | 182 | .B UDIAG_SHOW_NAME |
4f6a0a4a PE |
183 | The attribute reported in answer to this request is |
184 | .BR UNIX_DIAG_NAME . | |
185 | The payload associated with this attribute is the pathname to which | |
186 | the socket was bound (a sequence of bytes up to | |
187 | .B UNIX_PATH_MAX | |
188 | length). | |
e6e0499e | 189 | .TP |
4f6a0a4a | 190 | .B UDIAG_SHOW_VFS |
4f6a0a4a PE |
191 | The attribute reported in answer to this request is |
192 | .BR UNIX_DIAG_VFS . | |
193 | The payload associated with this attribute is represented in the following | |
194 | structure: | |
9647e2d9 | 195 | .IP |
4f6a0a4a | 196 | .in +4n |
b8302363 | 197 | .EX |
4f6a0a4a PE |
198 | struct unix_diag_vfs { |
199 | __u32 udiag_vfs_dev; | |
200 | __u32 udiag_vfs_ino; | |
201 | }; | |
b8302363 | 202 | .EE |
4f6a0a4a | 203 | .in |
9647e2d9 | 204 | .IP |
4f6a0a4a | 205 | The fields of this structure are as follows: |
e6e0499e MK |
206 | .RS |
207 | .TP | |
4f6a0a4a PE |
208 | .I udiag_vfs_dev |
209 | The device number of the corresponding on-disk socket inode. | |
e6e0499e | 210 | .TP |
4f6a0a4a PE |
211 | .I udiag_vfs_ino |
212 | The inode number of the corresponding on-disk socket inode. | |
213 | .RE | |
e6e0499e | 214 | .TP |
4f6a0a4a | 215 | .B UDIAG_SHOW_PEER |
4f6a0a4a PE |
216 | The attribute reported in answer to this request is |
217 | .BR UNIX_DIAG_PEER . | |
218 | The payload associated with this attribute is a __u32 value | |
219 | which is the peer's inode number. | |
220 | This attribute is reported for connected sockets only. | |
e6e0499e | 221 | .TP |
4f6a0a4a | 222 | .B UDIAG_SHOW_ICONS |
4f6a0a4a PE |
223 | The attribute reported in answer to this request is |
224 | .BR UNIX_DIAG_ICONS . | |
225 | The payload associated with this attribute is an array of __u32 values | |
226 | which are inode numbers of sockets that has passed the | |
227 | .BR connect (2) | |
228 | call, but hasn't been processed with | |
229 | .BR accept (2) | |
6d654721 MK |
230 | yet. |
231 | This attribute is reported for listening sockets only. | |
e6e0499e | 232 | .TP |
4f6a0a4a | 233 | .B UDIAG_SHOW_RQLEN |
4f6a0a4a PE |
234 | The attribute reported in answer to this request is |
235 | .BR UNIX_DIAG_RQLEN . | |
236 | The payload associated with this attribute is represented in the following | |
237 | structure: | |
9647e2d9 | 238 | .IP |
4f6a0a4a | 239 | .in +4n |
b8302363 | 240 | .EX |
4f6a0a4a PE |
241 | struct unix_diag_rqlen { |
242 | __u32 udiag_rqueue; | |
243 | __u32 udiag_wqueue; | |
244 | }; | |
b8302363 | 245 | .EE |
4f6a0a4a | 246 | .in |
9647e2d9 | 247 | .IP |
4f6a0a4a | 248 | The fields of this structure are as follows: |
94dc419f MK |
249 | .RS |
250 | .TP | |
4f6a0a4a | 251 | .I udiag_rqueue |
94dc419f MK |
252 | For listening sockets: |
253 | the number of pending connections. | |
254 | The length of the array associated with the | |
4f6a0a4a PE |
255 | .B UNIX_DIAG_ICONS |
256 | response attribute is equal to this value. | |
9647e2d9 | 257 | .IP |
94dc419f MK |
258 | For established sockets: |
259 | the amount of data in incoming queue. | |
260 | .TP | |
4f6a0a4a | 261 | .I udiag_wqueue |
94dc419f MK |
262 | For listening sockets: |
263 | the backlog length which equals to the value passed as the second argument to | |
4f6a0a4a | 264 | .BR listen (2). |
9647e2d9 | 265 | .IP |
94dc419f MK |
266 | For established sockets: |
267 | the amount of memory available for sending. | |
4f6a0a4a | 268 | .RE |
e6e0499e | 269 | .TP |
4f6a0a4a | 270 | .B UDIAG_SHOW_MEMINFO |
4f6a0a4a PE |
271 | The attribute reported in answer to this request is |
272 | .BR UNIX_DIAG_MEMINFO . | |
273 | The payload associated with this attribute is an array of __u32 values | |
9e39d87d | 274 | described below in the subsection "Socket memory information". |
e6e0499e | 275 | .PP |
4f6a0a4a | 276 | The following attributes are reported back without any specific request: |
e6e0499e MK |
277 | .TP |
278 | .BR UNIX_DIAG_SHUTDOWN | |
4f6a0a4a PE |
279 | The payload associated with this attribute is __u8 value which represents |
280 | bits of | |
281 | .BR shutdown (2) | |
282 | state. | |
283 | .RE | |
284 | .TP | |
285 | .I udiag_cookie | |
286 | This is an array of opaque identifiers that could be used along with | |
287 | .I udiag_ino | |
6d654721 MK |
288 | to specify an individual socket. |
289 | It is ignored when querying for a list | |
4f6a0a4a PE |
290 | of sockets, as well as when all its elements are set to \-1. |
291 | .PP | |
292 | The 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 |
296 | struct 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 |
307 | followed by netlink attributes. |
308 | .PP | |
309 | The fields of this structure are as follows: | |
310 | .TP | |
311 | .I udiag_family | |
312 | This field has the same meaning as in | |
313 | .IR "struct unix_diag_req" . | |
314 | .TP | |
315 | .I udiag_type | |
9e39d87d MK |
316 | This is set to one of |
317 | .BR SOCK_PACKET , | |
318 | .BR SOCK_STREAM , | |
319 | or | |
320 | .BR SOCK_SEQPACKET . | |
4f6a0a4a PE |
321 | .TP |
322 | .I udiag_state | |
9e39d87d MK |
323 | This is set to one of |
324 | .BR TCP_LISTEN | |
325 | or | |
326 | .BR TCP_ESTABLISHED . | |
4f6a0a4a PE |
327 | .TP |
328 | .I pad | |
329 | This field is set to 0. | |
330 | .TP | |
331 | .I udiag_ino | |
332 | This is the socket inode number. | |
333 | .TP | |
334 | .I udiag_cookie | |
335 | This is an array of opaque identifiers that could be used in subsequent | |
336 | queries. | |
9e39d87d | 337 | .\" |
4f6a0a4a | 338 | .SS IPv4 and IPv6 sockets |
9e39d87d MK |
339 | For IPv4 and IPv6 sockets, |
340 | the request is represented in the following structure: | |
9647e2d9 | 341 | .PP |
4f6a0a4a | 342 | .in +4n |
b8302363 | 343 | .EX |
4f6a0a4a PE |
344 | struct 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 |
355 | where |
356 | .I "struct inet_diag_sockid" | |
357 | is defined as follows: | |
9647e2d9 | 358 | .PP |
4f6a0a4a | 359 | .in +4n |
b8302363 | 360 | .EX |
4f6a0a4a PE |
361 | struct 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 | |
372 | The fields of | |
373 | .I "struct inet_diag_req_v2" | |
374 | are as follows: | |
375 | .TP | |
376 | .I sdiag_family | |
377 | This should be set to either | |
378 | .B AF_INET | |
379 | or | |
380 | .B AF_INET6 | |
9e39d87d | 381 | for IPv4 or IPv6 sockets respectively. |
4f6a0a4a PE |
382 | .TP |
383 | .I sdiag_protocol | |
9e39d87d MK |
384 | This should be set to one of |
385 | .BR IPPROTO_TCP , | |
386 | .BR IPPROTO_UDP , | |
387 | or | |
388 | .BR IPPROTO_UDPLITE . | |
4f6a0a4a PE |
389 | .TP |
390 | .I idiag_ext | |
391 | This is a set of flags defining what kind of extended information to report. | |
392 | Each requested kind of information is reported back as a netlink attribute | |
393 | as described below: | |
394 | .RS | |
395 | .TP | |
396 | .B INET_DIAG_TOS | |
397 | The payload associated with this attribute is a __u8 value | |
398 | which is the TOS of the socket. | |
399 | .TP | |
400 | .B INET_DIAG_TCLASS | |
401 | The payload associated with this attribute is a __u8 value | |
6d654721 MK |
402 | which is the TClass of the socket. |
403 | IPv6 sockets only. | |
9e39d87d | 404 | For LISTEN and CLOSE sockets, this is followed by |
4f6a0a4a PE |
405 | .B INET_DIAG_SKV6ONLY |
406 | attribute with associated __u8 payload value meaning whether the socket | |
407 | is IPv6-only or not. | |
408 | .TP | |
409 | .B INET_DIAG_MEMINFO | |
410 | The payload associated with this attribute is represented in the following | |
411 | structure: | |
9647e2d9 | 412 | .IP |
4f6a0a4a | 413 | .in +4n |
b8302363 | 414 | .EX |
4f6a0a4a PE |
415 | struct 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 |
424 | The fields of this structure are as follows: |
425 | .RS | |
426 | .TP 12 | |
427 | .I idiag_rmem | |
428 | The amount of data in the receive queue. | |
429 | .TP | |
430 | .I idiag_wmem | |
431 | The amount of data that is queued by TCP but not yet sent. | |
432 | .TP | |
433 | .I idiag_fmem | |
434 | The amount of memory scheduled for future use (TCP only). | |
435 | .TP | |
436 | .I idiag_tmem | |
437 | The amount of data in send queue. | |
438 | .RE | |
439 | .TP | |
440 | .B INET_DIAG_SKMEMINFO | |
441 | The payload associated with this attribute is an array of __u32 values | |
9e39d87d | 442 | described below in the subsection "Socket memory information". |
4f6a0a4a PE |
443 | .TP |
444 | .B INET_DIAG_INFO | |
e2734d29 MK |
445 | The payload associated with this attribute is specific to the address family. |
446 | For TCP sockets, it is an object of type | |
4f6a0a4a PE |
447 | .IR "struct tcp_info" . |
448 | .TP | |
449 | .B INET_DIAG_CONG | |
450 | The payload associated with this attribute is a string that describes the | |
6d654721 MK |
451 | congestion control algorithm used. |
452 | For TCP sockets only. | |
4f6a0a4a PE |
453 | .RE |
454 | .TP | |
455 | .I pad | |
456 | This should be set to 0. | |
457 | .TP | |
458 | .I idiag_states | |
9e39d87d | 459 | This is a bit mask that defines a filter of socket states. |
4f6a0a4a PE |
460 | Only those sockets whose states are in this mask will be reported. |
461 | Ignored when querying for an individual socket. | |
462 | .TP | |
463 | .I id | |
9e39d87d | 464 | This is a socket ID object that is used in dump requests, in queries |
4f6a0a4a PE |
465 | about individual sockets, and is reported back in each response. |
466 | Unlike UNIX domain sockets, IPv4 and IPv6 sockets are identified | |
6d654721 MK |
467 | using addresses and ports. |
468 | All values are in network byte order. | |
4f6a0a4a PE |
469 | .PP |
470 | The fields of | |
471 | .I "struct inet_diag_sockid" | |
472 | are as follows: | |
473 | .TP | |
474 | .I idiag_sport | |
475 | The source port. | |
476 | .TP | |
477 | .I idiag_dport | |
478 | The destination port. | |
479 | .TP | |
480 | .I idiag_src | |
481 | The source address. | |
482 | .TP | |
483 | .I idiag_dst | |
484 | The destination address. | |
485 | .TP | |
486 | .I idiag_if | |
487 | The interface number the socket is bound to. | |
488 | .TP | |
489 | .I idiag_cookie | |
490 | This is an array of opaque identifiers that could be used along with | |
491 | other fields of this structure to specify an individual socket. | |
492 | It is ignored when querying for a list of sockets, as well as | |
493 | when all its elements are set to \-1. | |
494 | .PP | |
495 | The 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 |
499 | struct 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 |
516 | followed by netlink attributes. |
517 | .PP | |
518 | The fields of this structure are as follows: | |
519 | .TP | |
520 | .I idiag_family | |
521 | This is the same field as in | |
522 | .IR "struct inet_diag_req_v2" . | |
523 | .TP | |
524 | .I idiag_state | |
525 | This denotes socket state as in | |
526 | .IR "struct inet_diag_req_v2" . | |
527 | .TP | |
528 | .I idiag_timer | |
529 | For TCP sockets, this field describes the type of timer that is currently | |
6d654721 MK |
530 | active for the socket. |
531 | It 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 | |
537 | no timer is active | |
538 | .TP | |
539 | .B 1 | |
540 | a retransmit timer | |
541 | .TP | |
542 | .B 2 | |
543 | a keep-alive timer | |
544 | .TP | |
545 | .B 3 | |
546 | a TIME_WAIT timer | |
547 | .TP | |
548 | .B 4 | |
549 | a zero window probe timer | |
550 | .RE | |
9e39d87d | 551 | .PD |
4f6a0a4a | 552 | .IP |
9e39d87d | 553 | For non-TCP sockets, this field is set to 0. |
4f6a0a4a PE |
554 | .TP |
555 | .I idiag_retrans | |
556 | For | |
557 | .I idiag_timer | |
9e39d87d | 558 | values 1, 2, and 4, this field contains the number of retransmits. |
6d654721 | 559 | For other |
4f6a0a4a | 560 | .I idiag_timer |
9e39d87d | 561 | values, this field is set to 0. |
4f6a0a4a PE |
562 | .TP |
563 | .I idiag_expires | |
9e39d87d | 564 | For TCP sockets that have an active timer, this field describes its expiration |
6d654721 | 565 | time in milliseconds. |
9e39d87d | 566 | For other sockets, this field is set to 0. |
4f6a0a4a PE |
567 | .TP |
568 | .I idiag_rqueue | |
9e39d87d MK |
569 | For listening sockets: |
570 | the number of pending connections. | |
9647e2d9 | 571 | .IP |
9e39d87d MK |
572 | For other sockets: |
573 | the amount of data in the incoming queue. | |
4f6a0a4a PE |
574 | .TP |
575 | .I idiag_wqueue | |
9e39d87d MK |
576 | For listening sockets: |
577 | the backlog length. | |
9647e2d9 | 578 | .IP |
990b14c4 | 579 | For other sockets: |
9e39d87d | 580 | the amount of memory available for sending. |
4f6a0a4a PE |
581 | .TP |
582 | .I idiag_uid | |
583 | This is the socket owner UID. | |
584 | .TP | |
585 | .I idiag_inode | |
586 | This is the socket inode number. | |
9e39d87d | 587 | .\" |
4f6a0a4a PE |
588 | .SS Socket memory information |
589 | The payload associated with | |
590 | .B UNIX_DIAG_MEMINFO | |
591 | and | |
592 | .BR INET_DIAG_SKMEMINFO | |
593 | netlink attributes is an array of the following __u32 values: | |
594 | .TP | |
595 | .B SK_MEMINFO_RMEM_ALLOC | |
596 | The amount of data in receive queue. | |
597 | .TP | |
598 | .B SK_MEMINFO_RCVBUF | |
599 | The receive socket buffer as set by | |
600 | .BR SO_RCVBUF . | |
601 | .TP | |
602 | .B SK_MEMINFO_WMEM_ALLOC | |
603 | The amount of data in send queue. | |
604 | .TP | |
605 | .B SK_MEMINFO_SNDBUF | |
606 | The send socket buffer as set by | |
607 | .BR SO_SNDBUF . | |
608 | .TP | |
609 | .B SK_MEMINFO_FWD_ALLOC | |
610 | The amount of memory scheduled for future use (TCP only). | |
611 | .TP | |
612 | .B SK_MEMINFO_WMEM_QUEUED | |
613 | The amount of data queued by TCP, but not yet sent. | |
614 | .TP | |
615 | .B SK_MEMINFO_OPTMEM | |
9e39d87d | 616 | The amount of memory allocated for the socket's service needs (e.g., socket |
4f6a0a4a PE |
617 | filter). |
618 | .TP | |
619 | .B SK_MEMINFO_BACKLOG | |
620 | The amount of packets in the backlog (not yet processed). | |
4f6a0a4a PE |
621 | .SH VERSIONS |
622 | .B NETLINK_INET_DIAG | |
623 | was introduced in Linux 2.6.14 and supported | |
624 | .B AF_INET | |
625 | and | |
626 | .B AF_INET6 | |
6d654721 | 627 | sockets only. |
9e39d87d | 628 | In Linux 3.3, it was renamed to |
4f6a0a4a PE |
629 | .B NETLINK_SOCK_DIAG |
630 | and extended to support | |
631 | .B AF_UNIX | |
632 | sockets. | |
633 | .PP | |
634 | .B UNIX_DIAG_MEMINFO | |
635 | and | |
636 | .BR INET_DIAG_SKMEMINFO | |
637 | were introduced in Linux 3.6. | |
61d92a91 MK |
638 | .SH CONFORMING TO |
639 | The NETLINK_SOCK_DIAG API is Linux-specific. | |
4f6a0a4a PE |
640 | .SH EXAMPLE |
641 | The following example program prints inode number, peer's inode number, | |
642 | and 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 | ||
656 | static int | |
657 | send_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 | ||
702 | static int | |
703 | print_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 | ||
753 | static int | |
754 | receive_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 | ||
822 | int | |
823 | main(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) |