#ifndef _PH_PHNET_H #define _PH_PHNET_H #include #include #define PH_IPV4_NETWORK_TYPE 0x1 #define PH_IPV6_NETWORK_TYPE 0x2 #define PH_NETWORK_TYPE_MASK 0x3 #define PH_TCP_PROTOCOL_TYPE 0x10 #define PH_UDP_PROTOCOL_TYPE 0x20 #define PH_PROTOCOL_TYPE_MASK 0x30 #define PH_NO_NETWORK_PROTOCOL 0x0 #define PH_TCP4_NETWORK_PROTOCOL (PH_IPV4_NETWORK_TYPE | PH_TCP_PROTOCOL_TYPE) #define PH_TCP6_NETWORK_PROTOCOL (PH_IPV6_NETWORK_TYPE | PH_TCP_PROTOCOL_TYPE) #define PH_UDP4_NETWORK_PROTOCOL (PH_IPV4_NETWORK_TYPE | PH_UDP_PROTOCOL_TYPE) #define PH_UDP6_NETWORK_PROTOCOL (PH_IPV6_NETWORK_TYPE | PH_UDP_PROTOCOL_TYPE) typedef struct _PH_IP_ADDRESS { ULONG Type; union { ULONG Ipv4; struct in_addr InAddr; UCHAR Ipv6[16]; struct in6_addr In6Addr; }; } PH_IP_ADDRESS, *PPH_IP_ADDRESS; FORCEINLINE BOOLEAN PhEqualIpAddress( _In_ PPH_IP_ADDRESS Address1, _In_ PPH_IP_ADDRESS Address2 ) { if ((Address1->Type | Address2->Type) == 0) // don't check addresses if both are invalid return TRUE; if (Address1->Type != Address2->Type) return FALSE; if (Address1->Type == PH_IPV4_NETWORK_TYPE) { return Address1->Ipv4 == Address2->Ipv4; } else { #ifdef _WIN64 return *(PULONG64)(Address1->Ipv6) == *(PULONG64)(Address2->Ipv6) && *(PULONG64)(Address1->Ipv6 + 8) == *(PULONG64)(Address2->Ipv6 + 8); #else return *(PULONG)(Address1->Ipv6) == *(PULONG)(Address2->Ipv6) && *(PULONG)(Address1->Ipv6 + 4) == *(PULONG)(Address2->Ipv6 + 4) && *(PULONG)(Address1->Ipv6 + 8) == *(PULONG)(Address2->Ipv6 + 8) && *(PULONG)(Address1->Ipv6 + 12) == *(PULONG)(Address2->Ipv6 + 12); #endif } } FORCEINLINE ULONG PhHashIpAddress( _In_ PPH_IP_ADDRESS Address ) { ULONG hash = 0; if (Address->Type == 0) return 0; hash = Address->Type | (Address->Type << 16); if (Address->Type == PH_IPV4_NETWORK_TYPE) { hash ^= Address->Ipv4; } else { hash += *(PULONG)(Address->Ipv6); hash ^= *(PULONG)(Address->Ipv6 + 4); hash += *(PULONG)(Address->Ipv6 + 8); hash ^= *(PULONG)(Address->Ipv6 + 12); } return hash; } FORCEINLINE BOOLEAN PhIsNullIpAddress( _In_ PPH_IP_ADDRESS Address ) { if (Address->Type == 0) { return TRUE; } else if (Address->Type == PH_IPV4_NETWORK_TYPE) { return Address->Ipv4 == 0; } else if (Address->Type == PH_IPV6_NETWORK_TYPE) { #ifdef _WIN64 return (*(PULONG64)(Address->Ipv6) | *(PULONG64)(Address->Ipv6 + 8)) == 0; #else return (*(PULONG)(Address->Ipv6) | *(PULONG)(Address->Ipv6 + 4) | *(PULONG)(Address->Ipv6 + 8) | *(PULONG)(Address->Ipv6 + 12)) == 0; #endif } else { return TRUE; } } typedef struct _PH_IP_ENDPOINT { PH_IP_ADDRESS Address; ULONG Port; } PH_IP_ENDPOINT, *PPH_IP_ENDPOINT; FORCEINLINE BOOLEAN PhEqualIpEndpoint( _In_ PPH_IP_ENDPOINT Endpoint1, _In_ PPH_IP_ENDPOINT Endpoint2 ) { return PhEqualIpAddress(&Endpoint1->Address, &Endpoint2->Address) && Endpoint1->Port == Endpoint2->Port; } FORCEINLINE ULONG PhHashIpEndpoint( _In_ PPH_IP_ENDPOINT Endpoint ) { return PhHashIpAddress(&Endpoint->Address) ^ Endpoint->Port; } #endif