@@ -106,7 +106,7 @@ public override IPEndPoint[] GetActiveTcpListeners()
106
106
107
107
///
108
108
/// Gets the active TCP connections. Uses the native GetTcpTable API.
109
- private List < SystemTcpConnectionInformation > GetAllTcpConnections ( )
109
+ private unsafe List < SystemTcpConnectionInformation > GetAllTcpConnections ( )
110
110
{
111
111
uint size = 0 ;
112
112
uint result = 0 ;
@@ -128,21 +128,20 @@ private List<SystemTcpConnectionInformation> GetAllTcpConnections()
128
128
129
129
if ( result == Interop . IpHlpApi . ERROR_SUCCESS )
130
130
{
131
+ var span = new ReadOnlySpan < byte > ( ( byte * ) buffer , ( int ) size ) ;
132
+
131
133
// The table info just gives us the number of rows.
132
- Interop . IpHlpApi . MibTcpTable tcpTableInfo = Marshal . PtrToStructure < Interop . IpHlpApi . MibTcpTable > ( buffer ) ;
134
+ ref readonly Interop . IpHlpApi . MibTcpTable tcpTableInfo = ref MemoryMarshal . AsRef < Interop . IpHlpApi . MibTcpTable > ( span ) ;
133
135
134
136
if ( tcpTableInfo . numberOfEntries > 0 )
135
137
{
136
138
// Skip over the tableinfo to get the inline rows.
137
- IntPtr newPtr = ( IntPtr ) ( ( long ) buffer + Marshal . SizeOf ( tcpTableInfo . numberOfEntries ) ) ;
139
+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibTcpTable ) ) ;
138
140
139
141
for ( int i = 0 ; i < tcpTableInfo . numberOfEntries ; i ++ )
140
142
{
141
- Interop . IpHlpApi . MibTcpRow tcpRow = Marshal . PtrToStructure < Interop . IpHlpApi . MibTcpRow > ( newPtr ) ;
142
- tcpConnections . Add ( new SystemTcpConnectionInformation ( tcpRow ) ) ;
143
-
144
- // Increment the pointer to the next row.
145
- newPtr = ( IntPtr ) ( ( long ) newPtr + Marshal . SizeOf ( tcpRow ) ) ;
143
+ tcpConnections . Add ( new SystemTcpConnectionInformation ( in MemoryMarshal . AsRef < Interop . IpHlpApi . MibTcpRow > ( span ) ) ) ;
144
+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibTcpRow ) ) ;
146
145
}
147
146
}
148
147
}
@@ -179,21 +178,22 @@ private List<SystemTcpConnectionInformation> GetAllTcpConnections()
179
178
Interop . IpHlpApi . TcpTableClass . TcpTableOwnerPidAll , 0 ) ;
180
179
if ( result == Interop . IpHlpApi . ERROR_SUCCESS )
181
180
{
181
+ var span = new ReadOnlySpan < byte > ( ( byte * ) buffer , ( int ) size ) ;
182
+
182
183
// The table info just gives us the number of rows.
183
- Interop . IpHlpApi . MibTcp6TableOwnerPid tcpTable6OwnerPid = Marshal . PtrToStructure < Interop . IpHlpApi . MibTcp6TableOwnerPid > ( buffer ) ;
184
+ ref readonly Interop . IpHlpApi . MibTcp6TableOwnerPid tcpTable6OwnerPid = ref MemoryMarshal . AsRef < Interop . IpHlpApi . MibTcp6TableOwnerPid > ( span ) ;
184
185
185
186
if ( tcpTable6OwnerPid . numberOfEntries > 0 )
186
187
{
187
188
// Skip over the tableinfo to get the inline rows.
188
- IntPtr newPtr = ( IntPtr ) ( ( long ) buffer + Marshal . SizeOf ( tcpTable6OwnerPid . numberOfEntries ) ) ;
189
+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibTcp6TableOwnerPid ) ) ;
189
190
190
191
for ( int i = 0 ; i < tcpTable6OwnerPid . numberOfEntries ; i ++ )
191
192
{
192
- Interop . IpHlpApi . MibTcp6RowOwnerPid tcp6RowOwnerPid = Marshal . PtrToStructure < Interop . IpHlpApi . MibTcp6RowOwnerPid > ( newPtr ) ;
193
- tcpConnections . Add ( new SystemTcpConnectionInformation ( tcp6RowOwnerPid ) ) ;
193
+ tcpConnections . Add ( new SystemTcpConnectionInformation ( in MemoryMarshal . AsRef < Interop . IpHlpApi . MibTcp6RowOwnerPid > ( span ) ) ) ;
194
194
195
195
// We increment the pointer to the next row.
196
- newPtr = ( IntPtr ) ( ( long ) newPtr + Marshal . SizeOf ( tcp6RowOwnerPid ) ) ;
196
+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibTcp6RowOwnerPid ) ) ;
197
197
}
198
198
}
199
199
}
@@ -215,7 +215,7 @@ private List<SystemTcpConnectionInformation> GetAllTcpConnections()
215
215
}
216
216
217
217
/// Gets the active UDP listeners. Uses the native GetUdpTable API.
218
- public override IPEndPoint [ ] GetActiveUdpListeners ( )
218
+ public unsafe override IPEndPoint [ ] GetActiveUdpListeners ( )
219
219
{
220
220
uint size = 0 ;
221
221
uint result = 0 ;
@@ -237,22 +237,25 @@ public override IPEndPoint[] GetActiveUdpListeners()
237
237
238
238
if ( result == Interop . IpHlpApi . ERROR_SUCCESS )
239
239
{
240
+ var span = new ReadOnlySpan < byte > ( ( byte * ) buffer , ( int ) size ) ;
241
+
240
242
// The table info just gives us the number of rows.
241
- Interop . IpHlpApi . MibUdpTable udpTableInfo = Marshal . PtrToStructure < Interop . IpHlpApi . MibUdpTable > ( buffer ) ;
243
+ ref readonly Interop . IpHlpApi . MibUdpTable udpTableInfo = ref MemoryMarshal . AsRef < Interop . IpHlpApi . MibUdpTable > ( span ) ;
242
244
243
245
if ( udpTableInfo . numberOfEntries > 0 )
244
246
{
245
247
// Skip over the tableinfo to get the inline rows.
246
- IntPtr newPtr = ( IntPtr ) ( ( long ) buffer + Marshal . SizeOf ( udpTableInfo . numberOfEntries ) ) ;
248
+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibUdpTable ) ) ;
249
+
247
250
for ( int i = 0 ; i < udpTableInfo . numberOfEntries ; i ++ )
248
251
{
249
- Interop . IpHlpApi . MibUdpRow udpRow = Marshal . PtrToStructure < Interop . IpHlpApi . MibUdpRow > ( newPtr ) ;
252
+ ref readonly Interop . IpHlpApi . MibUdpRow udpRow = ref MemoryMarshal . AsRef < Interop . IpHlpApi . MibUdpRow > ( span ) ;
250
253
int localPort = udpRow . localPort1 << 8 | udpRow . localPort2 ;
251
254
252
255
udpListeners . Add ( new IPEndPoint ( udpRow . localAddr , ( int ) localPort ) ) ;
253
256
254
257
// We increment the pointer to the next row.
255
- newPtr = ( IntPtr ) ( ( long ) newPtr + Marshal . SizeOf ( udpRow ) ) ;
258
+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibUdpRow ) ) ;
256
259
}
257
260
}
258
261
}
@@ -289,23 +292,26 @@ public override IPEndPoint[] GetActiveUdpListeners()
289
292
290
293
if ( result == Interop . IpHlpApi . ERROR_SUCCESS )
291
294
{
295
+ var span = new ReadOnlySpan < byte > ( ( byte * ) buffer , ( int ) size ) ;
296
+
292
297
// The table info just gives us the number of rows.
293
- Interop . IpHlpApi . MibUdp6TableOwnerPid udp6TableOwnerPid = Marshal . PtrToStructure < Interop . IpHlpApi . MibUdp6TableOwnerPid > ( buffer ) ;
298
+ ref readonly Interop . IpHlpApi . MibUdp6TableOwnerPid udp6TableOwnerPid = ref MemoryMarshal . AsRef < Interop . IpHlpApi . MibUdp6TableOwnerPid > ( span ) ;
294
299
295
300
if ( udp6TableOwnerPid . numberOfEntries > 0 )
296
301
{
297
302
// Skip over the tableinfo to get the inline rows.
298
- IntPtr newPtr = ( IntPtr ) ( ( long ) buffer + Marshal . SizeOf ( udp6TableOwnerPid . numberOfEntries ) ) ;
303
+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibUdp6TableOwnerPid ) ) ;
304
+
299
305
for ( int i = 0 ; i < udp6TableOwnerPid . numberOfEntries ; i ++ )
300
306
{
301
- Interop . IpHlpApi . MibUdp6RowOwnerPid udp6RowOwnerPid = Marshal . PtrToStructure < Interop . IpHlpApi . MibUdp6RowOwnerPid > ( newPtr ) ;
307
+ ref readonly Interop . IpHlpApi . MibUdp6RowOwnerPid udp6RowOwnerPid = ref MemoryMarshal . AsRef < Interop . IpHlpApi . MibUdp6RowOwnerPid > ( span ) ;
302
308
int localPort = udp6RowOwnerPid . localPort1 << 8 | udp6RowOwnerPid . localPort2 ;
303
309
304
- udpListeners . Add ( new IPEndPoint ( new IPAddress ( udp6RowOwnerPid . localAddr ,
310
+ udpListeners . Add ( new IPEndPoint ( new IPAddress ( udp6RowOwnerPid . localAddrAsSpan ,
305
311
udp6RowOwnerPid . localScopeId ) , localPort ) ) ;
306
312
307
313
// We increment the pointer to the next row.
308
- newPtr = ( IntPtr ) ( ( long ) newPtr + Marshal . SizeOf ( udp6RowOwnerPid ) ) ;
314
+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibUdp6RowOwnerPid ) ) ;
309
315
}
310
316
}
311
317
}
0 commit comments