@@ -106,7 +106,7 @@ public override IPEndPoint[] GetActiveTcpListeners()
106106
107107 ///
108108 /// Gets the active TCP connections. Uses the native GetTcpTable API.
109- private List < SystemTcpConnectionInformation > GetAllTcpConnections ( )
109+ private unsafe List < SystemTcpConnectionInformation > GetAllTcpConnections ( )
110110 {
111111 uint size = 0 ;
112112 uint result = 0 ;
@@ -128,21 +128,20 @@ private List<SystemTcpConnectionInformation> GetAllTcpConnections()
128128
129129 if ( result == Interop . IpHlpApi . ERROR_SUCCESS )
130130 {
131+ var span = new ReadOnlySpan < byte > ( ( byte * ) buffer , ( int ) size ) ;
132+
131133 // 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 ) ;
133135
134136 if ( tcpTableInfo . numberOfEntries > 0 )
135137 {
136138 // 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 ) ) ;
138140
139141 for ( int i = 0 ; i < tcpTableInfo . numberOfEntries ; i ++ )
140142 {
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 ) ) ;
146145 }
147146 }
148147 }
@@ -179,21 +178,22 @@ private List<SystemTcpConnectionInformation> GetAllTcpConnections()
179178 Interop . IpHlpApi . TcpTableClass . TcpTableOwnerPidAll , 0 ) ;
180179 if ( result == Interop . IpHlpApi . ERROR_SUCCESS )
181180 {
181+ var span = new ReadOnlySpan < byte > ( ( byte * ) buffer , ( int ) size ) ;
182+
182183 // 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 ) ;
184185
185186 if ( tcpTable6OwnerPid . numberOfEntries > 0 )
186187 {
187188 // 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 ) ) ;
189190
190191 for ( int i = 0 ; i < tcpTable6OwnerPid . numberOfEntries ; i ++ )
191192 {
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 ) ) ) ;
194194
195195 // We increment the pointer to the next row.
196- newPtr = ( IntPtr ) ( ( long ) newPtr + Marshal . SizeOf ( tcp6RowOwnerPid ) ) ;
196+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibTcp6RowOwnerPid ) ) ;
197197 }
198198 }
199199 }
@@ -215,7 +215,7 @@ private List<SystemTcpConnectionInformation> GetAllTcpConnections()
215215 }
216216
217217 /// Gets the active UDP listeners. Uses the native GetUdpTable API.
218- public override IPEndPoint [ ] GetActiveUdpListeners ( )
218+ public unsafe override IPEndPoint [ ] GetActiveUdpListeners ( )
219219 {
220220 uint size = 0 ;
221221 uint result = 0 ;
@@ -237,22 +237,25 @@ public override IPEndPoint[] GetActiveUdpListeners()
237237
238238 if ( result == Interop . IpHlpApi . ERROR_SUCCESS )
239239 {
240+ var span = new ReadOnlySpan < byte > ( ( byte * ) buffer , ( int ) size ) ;
241+
240242 // 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 ) ;
242244
243245 if ( udpTableInfo . numberOfEntries > 0 )
244246 {
245247 // 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+
247250 for ( int i = 0 ; i < udpTableInfo . numberOfEntries ; i ++ )
248251 {
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 ) ;
250253 int localPort = udpRow . localPort1 << 8 | udpRow . localPort2 ;
251254
252255 udpListeners . Add ( new IPEndPoint ( udpRow . localAddr , ( int ) localPort ) ) ;
253256
254257 // We increment the pointer to the next row.
255- newPtr = ( IntPtr ) ( ( long ) newPtr + Marshal . SizeOf ( udpRow ) ) ;
258+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibUdpRow ) ) ;
256259 }
257260 }
258261 }
@@ -289,23 +292,26 @@ public override IPEndPoint[] GetActiveUdpListeners()
289292
290293 if ( result == Interop . IpHlpApi . ERROR_SUCCESS )
291294 {
295+ var span = new ReadOnlySpan < byte > ( ( byte * ) buffer , ( int ) size ) ;
296+
292297 // 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 ) ;
294299
295300 if ( udp6TableOwnerPid . numberOfEntries > 0 )
296301 {
297302 // 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+
299305 for ( int i = 0 ; i < udp6TableOwnerPid . numberOfEntries ; i ++ )
300306 {
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 ) ;
302308 int localPort = udp6RowOwnerPid . localPort1 << 8 | udp6RowOwnerPid . localPort2 ;
303309
304- udpListeners . Add ( new IPEndPoint ( new IPAddress ( udp6RowOwnerPid . localAddr ,
310+ udpListeners . Add ( new IPEndPoint ( new IPAddress ( udp6RowOwnerPid . localAddrAsSpan ,
305311 udp6RowOwnerPid . localScopeId ) , localPort ) ) ;
306312
307313 // We increment the pointer to the next row.
308- newPtr = ( IntPtr ) ( ( long ) newPtr + Marshal . SizeOf ( udp6RowOwnerPid ) ) ;
314+ span = span . Slice ( sizeof ( Interop . IpHlpApi . MibUdp6RowOwnerPid ) ) ;
309315 }
310316 }
311317 }
0 commit comments