|
4 | 4 |
|
5 | 5 | using System; |
6 | 6 | using System.Runtime.InteropServices; |
| 7 | +using static SharpPcap.LibPcap.PcapUnmanagedStructures; |
7 | 8 |
|
8 | 9 | namespace SharpPcap.LibPcap |
9 | 10 | { |
@@ -36,66 +37,52 @@ internal PcapStatistics() { } |
36 | 37 | /// pcap_t* for the adapter |
37 | 38 | /// A <see cref="IntPtr"/> |
38 | 39 | /// </param> |
39 | | - internal PcapStatistics(PcapHandle pcap_t) |
| 40 | + internal unsafe PcapStatistics(PcapHandle pcap_t) |
40 | 41 | { |
41 | | - IntPtr stat; |
| 42 | + PcapStatUnix statUnix = new(); |
| 43 | + PcapStatWindows statWindows = new(); |
| 44 | + int result; |
42 | 45 |
|
43 | 46 | if (Environment.OSVersion.Platform == PlatformID.Unix) |
44 | 47 | { |
45 | | - // allocate memory for the struct |
46 | | - stat = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PcapUnmanagedStructures.pcap_stat_unix))); |
| 48 | + result = LibPcapSafeNativeMethods.pcap_stats(pcap_t, ref statUnix); |
47 | 49 | } |
48 | 50 | else |
49 | 51 | { |
50 | | - // allocate memory for the struct |
51 | | - stat = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PcapUnmanagedStructures.pcap_stat_windows))); |
| 52 | + result = LibPcapSafeNativeMethods.pcap_stats(pcap_t, ref statWindows); |
52 | 53 | } |
53 | 54 |
|
54 | 55 | // retrieve the stats |
55 | | - var result = (PcapUnmanagedStructures.PcapStatReturnValue)LibPcapSafeNativeMethods.pcap_stats(pcap_t, stat); |
56 | 56 |
|
57 | 57 | // process the return value |
58 | | - switch (result) |
| 58 | + switch ((PcapStatReturnValue)result) |
59 | 59 | { |
60 | | - case PcapUnmanagedStructures.PcapStatReturnValue.Error: |
| 60 | + case PcapStatReturnValue.Error: |
61 | 61 | // retrieve the error information |
62 | 62 | var error = LibPcapLiveDevice.GetLastError(pcap_t); |
63 | | - |
64 | | - // free the stats memory so we don't leak before we throw |
65 | | - Marshal.FreeHGlobal(stat); |
66 | | - |
67 | 63 | throw new StatisticsException(error); |
68 | | - case PcapUnmanagedStructures.PcapStatReturnValue.Success: |
| 64 | + case PcapStatReturnValue.Success: |
69 | 65 | // nothing to do upon success |
70 | 66 | break; |
71 | 67 | } |
72 | 68 |
|
73 | 69 | // marshal the unmanaged memory into an object of the proper type |
74 | 70 | if (Environment.OSVersion.Platform == PlatformID.Unix) |
75 | 71 | { |
76 | | - var managedStat = Marshal.PtrToStructure<PcapUnmanagedStructures.pcap_stat_unix>(stat); |
77 | | - |
78 | 72 | // copy the values |
79 | | - this.ReceivedPackets = (uint)managedStat.ps_recv.ToInt64(); |
80 | | - this.DroppedPackets = (uint)managedStat.ps_drop.ToInt64(); |
81 | | - // this.InterfaceDroppedPackets = (uint)managedStat.ps_ifdrop; |
| 73 | + this.ReceivedPackets = (uint)statUnix.ps_recv; |
| 74 | + this.DroppedPackets = (uint)statUnix.ps_drop; |
82 | 75 | } |
83 | 76 | else |
84 | 77 | { |
85 | | - var managedStat = Marshal.PtrToStructure<PcapUnmanagedStructures.pcap_stat_windows>(stat); |
86 | | - |
87 | 78 | // copy the values |
88 | | - this.ReceivedPackets = (uint)managedStat.ps_recv; |
89 | | - this.DroppedPackets = (uint)managedStat.ps_drop; |
90 | | - // this.InterfaceDroppedPackets = (uint)managedStat.ps_ifdrop; |
| 79 | + this.ReceivedPackets = statWindows.ps_recv; |
| 80 | + this.DroppedPackets = statWindows.ps_drop; |
91 | 81 | } |
92 | 82 |
|
93 | 83 | // NOTE: Not supported on unix or npcap, no need to |
94 | 84 | // put a bogus value in this field |
95 | 85 | this.InterfaceDroppedPackets = 0; |
96 | | - |
97 | | - // free the stats |
98 | | - Marshal.FreeHGlobal(stat); |
99 | 86 | } |
100 | 87 |
|
101 | 88 | /// <summary> |
|
0 commit comments