@@ -174,8 +174,18 @@ func SocketGet(local, remote net.Addr) (*Socket, error) {
174
174
175
175
// SocketDiagTCPInfo requests INET_DIAG_INFO for TCP protocol for specified family type and return with extension TCP info.
176
176
func SocketDiagTCPInfo (family uint8 ) ([]* InetDiagTCPInfoResp , error ) {
177
+ // Construct the request
178
+ req := nl .NewNetlinkRequest (nl .SOCK_DIAG_BY_FAMILY , unix .NLM_F_DUMP )
179
+ req .AddData (& socketRequest {
180
+ Family : family ,
181
+ Protocol : unix .IPPROTO_TCP ,
182
+ Ext : (1 << (INET_DIAG_VEGASINFO - 1 )) | (1 << (INET_DIAG_INFO - 1 )),
183
+ States : uint32 (0xfff ), // all states
184
+ })
185
+
186
+ // Do the query and parse the result
177
187
var result []* InetDiagTCPInfoResp
178
- err := socketDiagTCPExecutor ( family , func (m syscall.NetlinkMessage ) error {
188
+ err := socketDiagExecutor ( req , func (m syscall.NetlinkMessage ) error {
179
189
sockInfo := & Socket {}
180
190
if err := sockInfo .deserialize (m .Data ); err != nil {
181
191
return err
@@ -201,8 +211,18 @@ func SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
201
211
202
212
// SocketDiagTCP requests INET_DIAG_INFO for TCP protocol for specified family type and return related socket.
203
213
func SocketDiagTCP (family uint8 ) ([]* Socket , error ) {
214
+ // Construct the request
215
+ req := nl .NewNetlinkRequest (nl .SOCK_DIAG_BY_FAMILY , unix .NLM_F_DUMP )
216
+ req .AddData (& socketRequest {
217
+ Family : family ,
218
+ Protocol : unix .IPPROTO_TCP ,
219
+ Ext : (1 << (INET_DIAG_VEGASINFO - 1 )) | (1 << (INET_DIAG_INFO - 1 )),
220
+ States : uint32 (0xfff ), // all states
221
+ })
222
+
223
+ // Do the query and parse the result
204
224
var result []* Socket
205
- err := socketDiagTCPExecutor ( family , func (m syscall.NetlinkMessage ) error {
225
+ err := socketDiagExecutor ( req , func (m syscall.NetlinkMessage ) error {
206
226
sockInfo := & Socket {}
207
227
if err := sockInfo .deserialize (m .Data ); err != nil {
208
228
return err
@@ -216,21 +236,82 @@ func SocketDiagTCP(family uint8) ([]*Socket, error) {
216
236
return result , nil
217
237
}
218
238
219
- // socketDiagTCPExecutor requests INET_DIAG_INFO for TCP protocol for specified family type.
220
- func socketDiagTCPExecutor (family uint8 , receiver func (syscall.NetlinkMessage ) error ) error {
221
- s , err := nl .Subscribe (unix .NETLINK_INET_DIAG )
239
+ // SocketDiagUDPInfo requests INET_DIAG_INFO for UDP protocol for specified family type and return with extension info.
240
+ func SocketDiagUDPInfo (family uint8 ) ([]* InetDiagUDPInfoResp , error ) {
241
+ // Construct the request
242
+ var extensions uint8
243
+ extensions = 1 << (INET_DIAG_VEGASINFO - 1 )
244
+ extensions |= 1 << (INET_DIAG_INFO - 1 )
245
+ extensions |= 1 << (INET_DIAG_MEMINFO - 1 )
246
+
247
+ req := nl .NewNetlinkRequest (nl .SOCK_DIAG_BY_FAMILY , unix .NLM_F_DUMP )
248
+ req .AddData (& socketRequest {
249
+ Family : family ,
250
+ Protocol : unix .IPPROTO_UDP ,
251
+ Ext : extensions ,
252
+ States : uint32 (0xfff ), // all states
253
+ })
254
+
255
+ // Do the query and parse the result
256
+ var result []* InetDiagUDPInfoResp
257
+ err := socketDiagExecutor (req , func (m syscall.NetlinkMessage ) error {
258
+ sockInfo := & Socket {}
259
+ if err := sockInfo .deserialize (m .Data ); err != nil {
260
+ return err
261
+ }
262
+ attrs , err := nl .ParseRouteAttr (m .Data [sizeofSocket :])
263
+ if err != nil {
264
+ return err
265
+ }
266
+
267
+ res , err := attrsToInetDiagUDPInfoResp (attrs , sockInfo )
268
+ if err != nil {
269
+ return err
270
+ }
271
+
272
+ result = append (result , res )
273
+ return nil
274
+ })
222
275
if err != nil {
223
- return err
276
+ return nil , err
224
277
}
225
- defer s .Close ()
278
+ return result , nil
279
+ }
226
280
281
+ // SocketDiagUDP requests INET_DIAG_INFO for UDP protocol for specified family type and return related socket.
282
+ func SocketDiagUDP (family uint8 ) ([]* Socket , error ) {
283
+ // Construct the request
227
284
req := nl .NewNetlinkRequest (nl .SOCK_DIAG_BY_FAMILY , unix .NLM_F_DUMP )
228
285
req .AddData (& socketRequest {
229
286
Family : family ,
230
- Protocol : unix .IPPROTO_TCP ,
287
+ Protocol : unix .IPPROTO_UDP ,
231
288
Ext : (1 << (INET_DIAG_VEGASINFO - 1 )) | (1 << (INET_DIAG_INFO - 1 )),
232
- States : uint32 (0xfff ), // All TCP states
289
+ States : uint32 (0xfff ), // all states
233
290
})
291
+
292
+ // Do the query and parse the result
293
+ var result []* Socket
294
+ err := socketDiagExecutor (req , func (m syscall.NetlinkMessage ) error {
295
+ sockInfo := & Socket {}
296
+ if err := sockInfo .deserialize (m .Data ); err != nil {
297
+ return err
298
+ }
299
+ result = append (result , sockInfo )
300
+ return nil
301
+ })
302
+ if err != nil {
303
+ return nil , err
304
+ }
305
+ return result , nil
306
+ }
307
+
308
+ // socketDiagExecutor requests diagnoses info from the NETLINK_INET_DIAG socket for the specified request.
309
+ func socketDiagExecutor (req * nl.NetlinkRequest , receiver func (syscall.NetlinkMessage ) error ) error {
310
+ s , err := nl .Subscribe (unix .NETLINK_INET_DIAG )
311
+ if err != nil {
312
+ return err
313
+ }
314
+ defer s .Close ()
234
315
s .Send (req )
235
316
236
317
loop:
@@ -240,7 +321,7 @@ loop:
240
321
return err
241
322
}
242
323
if from .Pid != nl .PidKernel {
243
- return fmt .Errorf ("Wrong sender portid %d, expected %d" , from .Pid , nl .PidKernel )
324
+ return fmt .Errorf ("wrong sender portid %d, expected %d" , from .Pid , nl .PidKernel )
244
325
}
245
326
if len (msgs ) == 0 {
246
327
return errors .New ("no message nor error from netlink" )
@@ -263,29 +344,40 @@ loop:
263
344
}
264
345
265
346
func attrsToInetDiagTCPInfoResp (attrs []syscall.NetlinkRouteAttr , sockInfo * Socket ) (* InetDiagTCPInfoResp , error ) {
266
- var tcpInfo * TCPInfo
267
- var tcpBBRInfo * TCPBBRInfo
347
+ info := & InetDiagTCPInfoResp {
348
+ InetDiagMsg : sockInfo ,
349
+ }
268
350
for _ , a := range attrs {
269
- if a .Attr .Type == INET_DIAG_INFO {
270
- tcpInfo = & TCPInfo {}
271
- if err := tcpInfo .deserialize (a .Value ); err != nil {
351
+ switch a .Attr .Type {
352
+ case INET_DIAG_INFO :
353
+ info .TCPInfo = & TCPInfo {}
354
+ if err := info .TCPInfo .deserialize (a .Value ); err != nil {
355
+ return nil , err
356
+ }
357
+ case INET_DIAG_BBRINFO :
358
+ info .TCPBBRInfo = & TCPBBRInfo {}
359
+ if err := info .TCPBBRInfo .deserialize (a .Value ); err != nil {
272
360
return nil , err
273
361
}
274
- continue
275
362
}
363
+ }
364
+
365
+ return info , nil
366
+ }
276
367
277
- if a .Attr .Type == INET_DIAG_BBRINFO {
278
- tcpBBRInfo = & TCPBBRInfo {}
279
- if err := tcpBBRInfo .deserialize (a .Value ); err != nil {
368
+ func attrsToInetDiagUDPInfoResp (attrs []syscall.NetlinkRouteAttr , sockInfo * Socket ) (* InetDiagUDPInfoResp , error ) {
369
+ info := & InetDiagUDPInfoResp {
370
+ InetDiagMsg : sockInfo ,
371
+ }
372
+ for _ , a := range attrs {
373
+ switch a .Attr .Type {
374
+ case INET_DIAG_MEMINFO :
375
+ info .Memory = & MemInfo {}
376
+ if err := info .Memory .deserialize (a .Value ); err != nil {
280
377
return nil , err
281
378
}
282
- continue
283
379
}
284
380
}
285
381
286
- return & InetDiagTCPInfoResp {
287
- InetDiagMsg : sockInfo ,
288
- TCPInfo : tcpInfo ,
289
- TCPBBRInfo : tcpBBRInfo ,
290
- }, nil
382
+ return info , nil
291
383
}
0 commit comments