/
NetInfoWrapper.cs
223 lines (194 loc) · 8.73 KB
/
NetInfoWrapper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*
* Copyright (C) 2011, Mobile and Internet Systems Laboratory.
* Department of Computer Science, Wayne State University.
* All rights reserved.
*
* Authors: Hui Chen (huichen@wayne.edu), Youhuizi Li (huizi@wayne.edu)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Runtime.InteropServices;
using System.Collections;
using System.Diagnostics;
namespace ptopw
{
static unsafe class NetInfoWrapper
{
private const int NO_ERROR = 0;
private const int MIB_TCP_STATE_CLOSED = 1;
private const int MIB_TCP_STATE_LISTEN = 2;
private const int MIB_TCP_STATE_SYN_SENT = 3;
private const int MIB_TCP_STATE_SYN_RCVD = 4;
private const int MIB_TCP_STATE_ESTAB = 5;
private const int MIB_TCP_STATE_FIN_WAIT1 = 6;
private const int MIB_TCP_STATE_FIN_WAIT2 = 7;
private const int MIB_TCP_STATE_CLOSE_WAIT = 8;
private const int MIB_TCP_STATE_CLOSING = 9;
private const int MIB_TCP_STATE_LAST_ACK = 10;
private const int MIB_TCP_STATE_TIME_WAIT = 11;
private const int MIB_TCP_STATE_DELETE_TCB = 12;
[DllImport("iphlpapi.dll", SetLastError = true)]
private extern static int GetUdpStatistics(ref MIB_UDPSTATS pStats);
[DllImport("iphlpapi.dll", SetLastError = true)]
private static extern int GetUdpTable(byte[] UcpTable, out int pdwSize, bool bOrder);
[DllImport("iphlpapi.dll", SetLastError = true)]
private extern static int GetTcpStatistics(ref MIB_TCPSTATS pStats);
[DllImport("iphlpapi.dll", SetLastError = true)]
private static extern int GetTcpTable(byte[] pTcpTable, out int pdwSize, bool bOrder);
[DllImport("iphlpapi.dll", SetLastError = true)]
private extern static int GetExtendedTcpTable(IntPtr pTable, ref UInt32 DwOutBufLen, bool sort, int ipVersion, TCP_TABLE_CLASS tblClass, int reserved);
[DllImport("iphlpapi.dll", SetLastError = true)]
private static extern int GetExtendedUdpTable(IntPtr pTable, ref UInt32 dwOutBufLen, bool sort, int ipVersion, UDP_TABLE_CLASS tblClass, int reserved);
[DllImport("IpHlpApi.dll")]
extern static public uint GetIfTable(byte[] pIfTable, ref uint pdwSize, bool bOrder);
public static MIB_TCPSTATS GetTcpStats()
{
MIB_TCPSTATS tcpStats = new MIB_TCPSTATS();
GetTcpStatistics(ref tcpStats);
return tcpStats;
}
public static MIB_UDPSTATS GetUdpStats()
{
MIB_UDPSTATS udpStats = new MIB_UDPSTATS();
GetUdpStatistics(ref udpStats);
return udpStats;
}
public static bool GetProcessTCPConns(ref MIB_TCPTABLE_OWNER_PID ExConns)
{
UInt32* ptable = (UInt32*)IntPtr.Zero;
UInt32 dwSize = 0;
GetExtendedTcpTable((IntPtr)ptable, ref dwSize, true, AFType.AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0);
char* tmp = stackalloc char[(int)dwSize];
ptable = (UInt32*)tmp;
if (GetExtendedTcpTable((IntPtr)ptable, ref dwSize, true, AFType.AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0) != NO_ERROR)
return false;
ExConns.dwNumEntries = (UInt32)ptable[0];
ExConns.table = new MIB_TCPROW_OWNER_PID[ExConns.dwNumEntries];
MIB_TCPROW_OWNER_PID * row = (MIB_TCPROW_OWNER_PID*)&ptable[1];
UInt32 j = 0;
for (int i = 0; i < ExConns.dwNumEntries; i++)
{
if (!IP.specialIP(row[i].dwLocalAddr) && !IP.specialIP(row[i].dwRemoteAddr))
ExConns.table[j++] = row[i];
}
ExConns.dwNumEntries = j;
return true;
}
private static string convert_state(int state)
{
string strg_state = "";
switch (state)
{
case MIB_TCP_STATE_CLOSED: strg_state = "CLOSED"; break;
case MIB_TCP_STATE_LISTEN: strg_state = "LISTEN"; break;
case MIB_TCP_STATE_SYN_SENT: strg_state = "SYN_SENT"; break;
case MIB_TCP_STATE_SYN_RCVD: strg_state = "SYN_RCVD"; break;
case MIB_TCP_STATE_ESTAB: strg_state = "ESTAB"; break;
case MIB_TCP_STATE_FIN_WAIT1: strg_state = "FIN_WAIT1"; break;
case MIB_TCP_STATE_FIN_WAIT2: strg_state = "FIN_WAIT2"; break;
case MIB_TCP_STATE_CLOSE_WAIT: strg_state = "CLOSE_WAIT"; break;
case MIB_TCP_STATE_CLOSING: strg_state = "CLOSING"; break;
case MIB_TCP_STATE_LAST_ACK: strg_state = "LAST_ACK"; break;
case MIB_TCP_STATE_TIME_WAIT: strg_state = "TIME_WAIT"; break;
case MIB_TCP_STATE_DELETE_TCB: strg_state = "DELETE_TCB"; break;
}
return strg_state;
}
public static bool GetProcessUDPConns(ref MIB_UDPTABLE_OWNER_PID UdpConns)
{
UInt32* ptable = (UInt32*)IntPtr.Zero;
UInt32 dwSize = 0;
GetExtendedUdpTable((IntPtr)ptable, ref dwSize, true, AFType.AF_INET, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID, 0);
char* tmp = stackalloc char[(int)dwSize];
ptable = (UInt32*)tmp;
if (GetExtendedUdpTable((IntPtr)ptable, ref dwSize, true, AFType.AF_INET, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID, 0) != NO_ERROR)
return false;
UdpConns.dwNumEntries = ptable[0];
UdpConns.table = new MIB_UDPROW_OWNER_PID[UdpConns.dwNumEntries];
MIB_UDPROW_OWNER_PID * row = (MIB_UDPROW_OWNER_PID*)&ptable[1];
UInt32 j = 0;
for (int i = 0; i < UdpConns.dwNumEntries; i++)
{
if(!IP.specialIP(row[i].dwLocalAddr))
UdpConns.table[j++] = row[i];
}
UdpConns.dwNumEntries = j;
return true;
}
private static UInt16 convert_Port(UInt32 dwPort)
{
byte[] b = new Byte[2];
// high weight byte
b[0] = byte.Parse((dwPort >> 8).ToString());
// low weight byte
b[1] = byte.Parse((dwPort & 0xFF).ToString());
return BitConverter.ToUInt16(b, 0);
}
public static bool tcpActive(MIB_TCPROW_OWNER_PID trow)
{
bool res = false;
switch(trow.dwState)
{
case MIB_TCP_STATE_CLOSED:
case MIB_TCP_STATE_LISTEN:
res = false;
break;
case MIB_TCP_STATE_SYN_SENT:
case MIB_TCP_STATE_SYN_RCVD:
case MIB_TCP_STATE_ESTAB:
res = true;
break;
case MIB_TCP_STATE_FIN_WAIT1:
case MIB_TCP_STATE_FIN_WAIT2:
case MIB_TCP_STATE_CLOSE_WAIT:
case MIB_TCP_STATE_CLOSING:
case MIB_TCP_STATE_LAST_ACK:
case MIB_TCP_STATE_TIME_WAIT:
case MIB_TCP_STATE_DELETE_TCB:
res = false;
break;
}
return res & (trow.dwRemotePort != 0);
}
public static HashSet<UInt32> netActiveProcesses()
{
HashSet<UInt32> processes = new HashSet<UInt32>();
MIB_UDPTABLE_OWNER_PID utable = new MIB_UDPTABLE_OWNER_PID();
bool res = GetProcessUDPConns(ref utable);
if(res)
{
for(int i = 0; i < utable.dwNumEntries; i++)
{
MIB_UDPROW_OWNER_PID urow = utable.table[i];
if (!processes.Contains(urow.dwOwningPid))
processes.Add(urow.dwOwningPid);
}
}
MIB_TCPTABLE_OWNER_PID ttable = new MIB_TCPTABLE_OWNER_PID();
res = GetProcessTCPConns(ref ttable);
if(res)
{
for(int i = 0; i < ttable.dwNumEntries; i++)
{
MIB_TCPROW_OWNER_PID trow = ttable.table[i];
if (!processes.Contains(trow.dwOwningPid) && tcpActive(trow))
processes.Add(trow.dwOwningPid);
}
}
return processes;
}
}
}