mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2025-07-07 00:04:57 +03:00
Preliminary IPC IPv6 implementation (untested)
This commit is contained in:
@ -7375,6 +7375,175 @@ void CopyIP(IP *dst, IP *src)
|
||||
Copy(dst, src, sizeof(IP));
|
||||
}
|
||||
|
||||
// Utility functions about IP and MAC address types
|
||||
// Identify whether the IP address is a normal unicast address
|
||||
bool IsValidUnicastIPAddress4(IP* ip)
|
||||
{
|
||||
UINT i;
|
||||
// Validate arguments
|
||||
if (IsIP4(ip) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsZeroIP(ip))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ip->addr[0] >= 224 && ip->addr[0] <= 239)
|
||||
{
|
||||
// IPv4 Multicast
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// TODO: this is kinda incorrect, but for the correct parsing we need the netmask anyway
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (ip->addr[i] != 255)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool IsValidUnicastIPAddressUINT4(UINT ip)
|
||||
{
|
||||
IP a;
|
||||
|
||||
UINTToIP(&a, ip);
|
||||
|
||||
return IsValidUnicastIPAddress4(&a);
|
||||
}
|
||||
|
||||
bool IsValidUnicastIPAddress6(IP* ip)
|
||||
{
|
||||
UINT ipv6Type;
|
||||
|
||||
if (!IsIP6(ip))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsZeroIP(ip))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ipv6Type = GetIPAddrType6(ip);
|
||||
|
||||
if (!(ipv6Type & IPV6_ADDR_LOCAL_UNICAST) &&
|
||||
!(ipv6Type & IPV6_ADDR_GLOBAL_UNICAST))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check whether the MAC address is valid
|
||||
bool IsMacInvalid(UCHAR* mac)
|
||||
{
|
||||
UINT i;
|
||||
// Validate arguments
|
||||
if (mac == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if (mac[i] != 0x00)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check whether the MAC address is a broadcast address
|
||||
bool IsMacBroadcast(UCHAR* mac)
|
||||
{
|
||||
UINT i;
|
||||
// Validate arguments
|
||||
if (mac == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if (mac[i] != 0xff)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check wether the MAC address is an IPv4 multicast or an IPv6 multicast
|
||||
bool IsMacMulticast(UCHAR* mac)
|
||||
{
|
||||
// Validate arguments
|
||||
if (mac == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mac[0] == 0x01 &&
|
||||
mac[1] == 0x00 &&
|
||||
mac[2] == 0x5e)
|
||||
{
|
||||
// Multicast IPv4 and other IANA multicasts
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mac[0] == 0x01)
|
||||
{
|
||||
// That's not a really reserved for multicast range, but it seems like anything with 0x01 is used as multicast anyway
|
||||
// Remove or specify if it causes problems
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mac[0] == 0x33 &&
|
||||
mac[1] == 0x33)
|
||||
{
|
||||
// Multicast IPv6
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check wether the MAC address is a unicast one
|
||||
bool IsMacUnicast(UCHAR* mac)
|
||||
{
|
||||
// Validate arguments
|
||||
if (mac == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsMacInvalid(mac))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsMacBroadcast(mac))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsMacMulticast(mac))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the number of clients connected from the specified IP address
|
||||
UINT GetNumIpClient(IP *ip)
|
||||
{
|
||||
|
@ -1302,6 +1302,15 @@ void IPAnd4(IP *dst, IP *a, IP *b);
|
||||
bool IsInSameNetwork4(IP *a1, IP *a2, IP *subnet);
|
||||
bool IsInSameNetwork4Standard(IP *a1, IP *a2);
|
||||
|
||||
// Utility functions about IP and MAC address types
|
||||
bool IsValidUnicastIPAddress4(IP* ip);
|
||||
bool IsValidUnicastIPAddressUINT4(UINT ip);
|
||||
bool IsValidUnicastIPAddress6(IP* ip);
|
||||
bool IsMacUnicast(UCHAR* mac);
|
||||
bool IsMacBroadcast(UCHAR* mac);
|
||||
bool IsMacMulticast(UCHAR* mac);
|
||||
bool IsMacInvalid(UCHAR* mac);
|
||||
|
||||
bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask);
|
||||
bool ParseIpAndSubnetMask46(char *src, IP *ip, IP *mask);
|
||||
bool ParseIpAndMask4(char *src, UINT *ip, UINT *mask);
|
||||
|
@ -889,6 +889,44 @@ BUF *BuildICMPv6NeighborSoliciation(IPV6_ADDR *src_ip, IPV6_ADDR *target_ip, UCH
|
||||
return ret;
|
||||
}
|
||||
|
||||
BUF *BuildICMPv6RouterSoliciation(IPV6_ADDR* src_ip, IPV6_ADDR* target_ip, UCHAR* my_mac_address, UINT id)
|
||||
{
|
||||
ICMPV6_OPTION_LIST opt;
|
||||
ICMPV6_OPTION_LINK_LAYER link;
|
||||
ICMPV6_ROUTER_SOLICIATION_HEADER header;
|
||||
BUF *b;
|
||||
BUF *b2;
|
||||
BUF *ret;
|
||||
|
||||
if (src_ip == NULL || target_ip == NULL || my_mac_address == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Zero(&link, sizeof(link));
|
||||
Copy(link.Address, my_mac_address, 6);
|
||||
|
||||
Zero(&opt, sizeof(opt));
|
||||
opt.SourceLinkLayer = &link;
|
||||
|
||||
b = BuildICMPv6Options(&opt);
|
||||
|
||||
Zero(&header, sizeof(header));
|
||||
|
||||
b2 = NewBuf();
|
||||
|
||||
WriteBuf(b2, &header, sizeof(header));
|
||||
WriteBufBuf(b2, b);
|
||||
|
||||
ret = BuildICMPv6(src_ip, target_ip, 255,
|
||||
ICMPV6_TYPE_ROUTER_SOLICIATION, 0, b2->Buf, b2->Size, id);
|
||||
|
||||
FreeBuf(b);
|
||||
FreeBuf(b2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the next header number from the queue
|
||||
UCHAR IPv6GetNextHeaderFromQueue(QUEUE *q)
|
||||
{
|
||||
@ -1452,6 +1490,12 @@ PKT *ClonePacket(PKT *p, bool copy_data)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Parse the packet but without data layer except for ICMP
|
||||
PKT* ParsePacketUpToICMPv6(UCHAR* buf, UINT size)
|
||||
{
|
||||
return ParsePacketEx5(buf, size, false, 0, true, true, false, true);
|
||||
}
|
||||
|
||||
// Parse the contents of the packet
|
||||
PKT *ParsePacket(UCHAR *buf, UINT size)
|
||||
{
|
||||
@ -1469,7 +1513,11 @@ PKT *ParsePacketEx3(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool b
|
||||
{
|
||||
return ParsePacketEx4(buf, size, no_l3, vlan_type_id, bridge_id_as_mac_address, false, false);
|
||||
}
|
||||
PKT *ParsePacketEx4(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum)
|
||||
PKT* ParsePacketEx4(UCHAR* buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum)
|
||||
{
|
||||
return ParsePacketEx5(buf, size, no_l3, vlan_type_id, bridge_id_as_mac_address, no_http, correct_checksum, false);
|
||||
}
|
||||
PKT* ParsePacketEx5(UCHAR* buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum, bool no_l3_l4_except_icmpv6)
|
||||
{
|
||||
PKT *p;
|
||||
USHORT vlan_type_id_16;
|
||||
@ -1559,7 +1607,7 @@ PKT *ParsePacketEx4(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool b
|
||||
}
|
||||
|
||||
// Do parse
|
||||
if (ParsePacketL2Ex(p, buf, size, no_l3) == false)
|
||||
if (ParsePacketL2Ex(p, buf, size, no_l3, no_l3_l4_except_icmpv6) == false)
|
||||
{
|
||||
// Parsing failure
|
||||
FreePacket(p);
|
||||
@ -1929,7 +1977,7 @@ HTTPLOG *ParseHttpAccessLog(PKT *pkt)
|
||||
|
||||
|
||||
// Layer-2 parsing
|
||||
bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3)
|
||||
bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3, bool no_l3_l4_except_icmpv6)
|
||||
{
|
||||
UINT i;
|
||||
bool b1, b2;
|
||||
@ -1994,7 +2042,7 @@ bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3)
|
||||
switch (type_id_16)
|
||||
{
|
||||
case MAC_PROTO_ARPV4: // ARPv4
|
||||
if (no_l3)
|
||||
if (no_l3 || no_l3_l4_except_icmpv6)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -2002,7 +2050,7 @@ bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3)
|
||||
return ParsePacketARPv4(p, buf, size);
|
||||
|
||||
case MAC_PROTO_IPV4: // IPv4
|
||||
if (no_l3)
|
||||
if (no_l3 || no_l3_l4_except_icmpv6)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -2015,7 +2063,7 @@ bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3)
|
||||
return true;
|
||||
}
|
||||
|
||||
return ParsePacketIPv6(p, buf, size);
|
||||
return ParsePacketIPv6(p, buf, size, no_l3_l4_except_icmpv6);
|
||||
|
||||
default: // Unknown
|
||||
if (type_id_16 == p->VlanTypeID)
|
||||
@ -2538,7 +2586,7 @@ void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src)
|
||||
}
|
||||
|
||||
// IPv6 parsing
|
||||
bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size)
|
||||
bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size, bool no_l3_l4_except_icmpv6)
|
||||
{
|
||||
// Validate arguments
|
||||
if (p == NULL || buf == NULL)
|
||||
@ -2585,9 +2633,17 @@ bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size)
|
||||
}
|
||||
|
||||
case IP_PROTO_TCP: // TCP
|
||||
if (no_l3_l4_except_icmpv6)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return ParseTCP(p, buf, size);
|
||||
|
||||
case IP_PROTO_UDP: // UDP
|
||||
if (no_l3_l4_except_icmpv6)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return ParseUDP(p, buf, size);
|
||||
|
||||
default: // Unknown
|
||||
|
@ -745,6 +745,8 @@ PKT *ParsePacketEx(UCHAR *buf, UINT size, bool no_l3);
|
||||
PKT *ParsePacketEx2(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id);
|
||||
PKT *ParsePacketEx3(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address);
|
||||
PKT *ParsePacketEx4(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum);
|
||||
PKT* ParsePacketEx5(UCHAR* buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum, bool no_l3_l4_except_icmpv6);
|
||||
PKT* ParsePacketUpToICMPv6(UCHAR* buf, UINT size);
|
||||
void FreePacket(PKT *p);
|
||||
void FreePacketWithData(PKT *p);
|
||||
void FreePacketIPv4(PKT *p);
|
||||
@ -754,7 +756,7 @@ void FreePacketUDPv4(PKT *p);
|
||||
void FreePacketTCPv4(PKT *p);
|
||||
void FreePacketICMPv4(PKT *p);
|
||||
void FreePacketDHCPv4(PKT *p);
|
||||
bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3);
|
||||
bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3, bool no_l3_l4_except_icmpv6);
|
||||
bool ParsePacketARPv4(PKT *p, UCHAR *buf, UINT size);
|
||||
bool ParsePacketIPv4(PKT *p, UCHAR *buf, UINT size);
|
||||
bool ParsePacketBPDU(PKT *p, UCHAR *buf, UINT size);
|
||||
@ -770,7 +772,7 @@ void FreeClonePacket(PKT *p);
|
||||
|
||||
void CorrectChecksum(PKT *p);
|
||||
|
||||
bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size);
|
||||
bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size, bool no_l3_l4_except_icmpv6);
|
||||
bool ParsePacketIPv6Header(IPV6_HEADER_PACKET_INFO *info, UCHAR *buf, UINT size);
|
||||
bool ParseIPv6ExtHeader(IPV6_HEADER_PACKET_INFO *info, UCHAR next_header, UCHAR *buf, UINT size);
|
||||
bool ParseICMPv6Options(ICMPV6_OPTION_LIST *o, UCHAR *buf, UINT size);
|
||||
@ -786,6 +788,7 @@ BUF *BuildIPv6PacketHeader(IPV6_HEADER_PACKET_INFO *info, UINT *bytes_before_pay
|
||||
UCHAR IPv6GetNextHeaderFromQueue(QUEUE *q);
|
||||
void BuildAndAddIPv6PacketOptionHeader(BUF *b, IPV6_OPTION_HEADER *opt, UCHAR next_header, UINT size);
|
||||
BUF *BuildICMPv6NeighborSoliciation(IPV6_ADDR *src_ip, IPV6_ADDR *target_ip, UCHAR *my_mac_address, UINT id);
|
||||
BUF *BuildICMPv6RouterSoliciation(IPV6_ADDR* src_ip, IPV6_ADDR* target_ip, UCHAR* my_mac_address, UINT id);
|
||||
BUF *BuildICMPv6(IPV6_ADDR *src_ip, IPV6_ADDR *dest_ip, UCHAR hop_limit, UCHAR type, UCHAR code, void *data, UINT size, UINT id);
|
||||
|
||||
bool VLanRemoveTag(void **packet_data, UINT *packet_size, UINT vlan_id, UINT vlan_tpid);
|
||||
|
Reference in New Issue
Block a user