Skip to content

Commit 4d82b61

Browse files
rayfoRaymond Fowkes
andauthored
Improve geolocation and other descriptions of the IPAddress (#38)
Co-authored-by: Raymond Fowkes <REFowkes@frontier.com>
1 parent f3d2540 commit 4d82b61

3 files changed

Lines changed: 105 additions & 8 deletions

File tree

src/NetBlame/Auxiliary/GeoLocation.cs

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,62 @@ enum XmlName
2929
bitfAll = bitfCountry | bitfRegion | bitfCity | bitfStatus
3030
};
3131

32-
32+
33+
/*
34+
IPv4 CIDR (Classless Inter-Domain Routing)
35+
https://datatracker.ietf.org/doc/html/rfc1918
36+
10.*.*.* // 24-bit block / class A
37+
172.16-31.*.* // 20-bit block / class B
38+
192.168.*.* // 16-bit block / class C
39+
*/
40+
static bool IsIPv4CIDR(IPAddress ipAddr)
41+
{
42+
if (ipAddr.IsIPv4MappedToIPv6)
43+
ipAddr = ipAddr.MapToIPv4();
44+
else if (ipAddr.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)
45+
return false;
46+
47+
#pragma warning disable 0618 // obsolete: IPAddress.Address
48+
uint address = (uint)ipAddr.Address;
49+
#pragma warning restore 0618
50+
51+
// 10.*.*.*
52+
if ((byte)address == 10)
53+
return true;
54+
55+
// 192.168.*.* ie. C0.A8.*.*
56+
if ((ushort)address == 0xA8C0)
57+
return true;
58+
59+
// 172.16-31.*.* ie. AC.10-1F.*.* ie. 0x10AC <= address <= 0x1FAC
60+
if ((byte)address == 0xAC && (ushort)(address - 0x10AC) <= 0x0F00)
61+
return true;
62+
63+
// none of the above
64+
return false;
65+
}
66+
67+
68+
/*
69+
Return a string representing the geolocation of this IPAddress.
70+
Check first for special ranges representing LocalHost or a Local/Private Network.
71+
Then contact geoplugin.com to get a geo-location string.
72+
*/
3373
public static string GetGeoLocation(IPAddress ipAddr)
3474
{
3575
if (ipAddr == null)
3676
return string.Empty;
3777

38-
string strIpAddr = ipAddr.ToString();
39-
40-
if (strIpAddr.Equals(DNSClient.DNSTable.strAddrLocalHost))
78+
if (IPAddress.IsLoopback(ipAddr))
4179
return DNSClient.DNSTable.strLocalHost;
4280

43-
string strRequest = strGetXmlService + strIpAddr;
81+
if (IsIPv4CIDR(ipAddr) || ipAddr.IsIPv6UniqueLocal || ipAddr.IsIPv6SiteLocal || ipAddr.IsIPv6LinkLocal)
82+
return "Local/Private Network";
83+
84+
if (ipAddr.IsIPv6Multicast)
85+
return "Multicast";
86+
87+
string strRequest = strGetXmlService + ipAddr.ToString();
4488

4589
try
4690
{

src/NetBlame/Auxiliary/NetUtil.cs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ public static void BreakWhen(bool c)
8484
public static uint BitFromI(uint i) => (uint)1 << ((int)i - 1); // i: 1-based
8585

8686
// https://github.com/dotnet/runtime/issues/58378
87-
static AddressFamily AF_HYPERV = (AddressFamily)34;
88-
static AddressFamily AF_VSOCK = (AddressFamily)40;
87+
public static AddressFamily AF_HYPERV = (AddressFamily)34;
88+
public static AddressFamily AF_VSOCK = (AddressFamily)40;
8989

9090
static readonly IPEndPoint ipEndPointv4 = new IPEndPoint(0, 0);
9191
static readonly IPEndPoint ipEndPointv6 = new IPEndPoint(IPAddress.IPv6Any, 0);
@@ -110,6 +110,7 @@ public static IPEndPoint NewEndPoint(in SocketAddress socket)
110110
// AF_HYPERV & AF_VSOCK:
111111
// https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service#bind-to-a-hyper-v-socket
112112
// https://man7.org/linux/man-pages/man7/vsock.7.html
113+
// https://github.com/search?q=repo%3Amicrosoft%2FWSL2-Linux-Kernel+AF_HYPERV
113114

114115
if (socket.Family == AF_HYPERV && socket.Size >= 20)
115116
{
@@ -128,6 +129,18 @@ public static IPEndPoint NewEndPoint(in SocketAddress socket)
128129
return (IPEndPoint)ipEndPointv6.Create(sa);
129130
}
130131

132+
if (socket.Family == AF_HYPERV && socket.Size >= 16)
133+
{
134+
// Create an IpV6 socket and copy the data to the IpV6 address, and that's the best we can do.
135+
136+
SocketAddress sa = new SocketAddress(AddressFamily.InterNetworkV6, 64);
137+
138+
for (int i = 0; i < 12; ++i) { sa[i+12] = socket[i+4]; }
139+
sa[3] = (byte)AF_HYPERV; // port = HyperV tag, big-endian
140+
141+
return (IPEndPoint)ipEndPointv6.Create(sa);
142+
}
143+
131144
if (socket.Family == AF_VSOCK && socket.Size >= 12)
132145
{
133146
// Copy the svm_port and the svm_cid to the IPv6 address, and that's the best we can do.
@@ -235,6 +248,15 @@ static public string ServiceFromPort(int port)
235248
{
236249
switch (port)
237250
{
251+
case 20:
252+
case 21:
253+
return "FTP";
254+
case 22:
255+
return "SSH/SCP/SFTP";
256+
case 23:
257+
return "TELNET";
258+
case 25:
259+
return "SMTP";
238260
case 53:
239261
return "DNS";
240262
case 80:
@@ -243,17 +265,38 @@ static public string ServiceFromPort(int port)
243265
return "HTTP";
244266
case 88:
245267
return "Kerberos";
268+
case 110:
269+
return "POP3";
270+
case 119:
271+
return "NNTP";
272+
case 123:
273+
return "NTP";
246274
case 135:
247275
return "DCE/DHCP/DNS/WINS/DCOM";
248-
case portLDAP:
276+
case 137:
277+
return "NetBIOS";
278+
case 143:
279+
return "IMAP";
280+
case portLDAP: // 389
249281
return "LDAP";
250282
case 443:
251283
case 8443:
252284
return "HTTPS";
253285
case 445:
254286
return "AD/SMB";
287+
case 465:
288+
return "SMTPS";
289+
case 563:
290+
return "NNTPS";
255291
case 636:
256292
return "LDAPs";
293+
case 989:
294+
case 990:
295+
return "FTPS";
296+
case 993:
297+
return "IMAPS";
298+
case 995:
299+
return "POP3S";
257300
case 1433:
258301
return "MSSQL";
259302
case 2555:
@@ -264,6 +307,10 @@ static public string ServiceFromPort(int port)
264307
return "LDAPs/AD";
265308
case 3389:
266309
return "TS/RDP";
310+
case 5353:
311+
return "UDP";
312+
case 5355:
313+
return "LLMNR";
267314
case 5985:
268315
return "CIM/DMTF";
269316
case 7680:

src/NetBlame/Providers/WinsockAFD.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public enum IPPROTO : byte
4242
UDP = 17, // (datagram socket)
4343
IDP = 22,
4444
RDP = 27,
45+
HyperV = 34, // pseudo: AF_HYPERV
46+
VSock = 40, // pseudo: AF_VSOCK
4547
IPV6 = 41, // IPv6 header
4648
ROUTING = 43, // IPv6 Routing header
4749
FRAGMENT = 44, // IPv6 fragmentation header
@@ -503,6 +505,10 @@ public void Dispatch(in IGenericEvent evt)
503505
AssertImportant((cxn.ipProtocol==IPPROTO.TCP || cxn.ipProtocol==IPPROTO.ICMP) == (cxn.socktype==SOCKTYPE.SOCK_STREAM));
504506
AssertImportant((cxn.ipProtocol==IPPROTO.UDP) == (cxn.socktype==SOCKTYPE.SOCK_DGRAM));
505507

508+
var family = (System.Net.Sockets.AddressFamily)evt.GetUInt32("AddressFamily");
509+
if (family == AF_HYPERV) cxn.ipProtocol = IPPROTO.HyperV;
510+
else if (family == AF_VSOCK) cxn.ipProtocol = IPPROTO.VSock;
511+
506512
cxn.xlink.GetLink(evt.ThreadId, cxn.timeCreate, in allTables.threadTable);
507513
this.Add(cxn);
508514
}

0 commit comments

Comments
 (0)