mirror of
https://github.com/reactos/reactos.git
synced 2025-06-03 08:20:27 +00:00
- Implement UDP checksum calculation
- Fixes issues with DHCP (and any other UDP traffic) over bridged networking on vbox and issues with other hardware that doesn't like a checksum of 0 - See bug #4754 svn path=/trunk/; revision=43637
This commit is contained in:
parent
6f08578e3c
commit
31ba6d7556
3 changed files with 78 additions and 9 deletions
|
@ -22,6 +22,12 @@ csum_partial(
|
||||||
int len,
|
int len,
|
||||||
unsigned int sum);
|
unsigned int sum);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
UDPv4ChecksumCalculate(
|
||||||
|
PIPv4_HEADER IPHeader,
|
||||||
|
PUCHAR PacketBuffer,
|
||||||
|
ULONG DataLength);
|
||||||
|
|
||||||
#define IPv4Checksum(Data, Count, Seed)(~ChecksumFold(ChecksumCompute(Data, Count, Seed)))
|
#define IPv4Checksum(Data, Count, Seed)(~ChecksumFold(ChecksumCompute(Data, Count, Seed)))
|
||||||
#define TCPv4Checksum(Data, Count, Seed)(~ChecksumFold(csum_partial(Data, Count, Seed)))
|
#define TCPv4Checksum(Data, Count, Seed)(~ChecksumFold(csum_partial(Data, Count, Seed)))
|
||||||
//#define TCPv4Checksum(Data, Count, Seed)(~ChecksumFold(ChecksumCompute(Data, Count, Seed)))
|
//#define TCPv4Checksum(Data, Count, Seed)(~ChecksumFold(ChecksumCompute(Data, Count, Seed)))
|
||||||
|
|
|
@ -55,3 +55,53 @@ ULONG ChecksumCompute(
|
||||||
|
|
||||||
return Sum;
|
return Sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
UDPv4ChecksumCalculate(
|
||||||
|
PIPv4_HEADER IPHeader,
|
||||||
|
PUCHAR PacketBuffer,
|
||||||
|
ULONG DataLength)
|
||||||
|
{
|
||||||
|
ULONG Sum = 0;
|
||||||
|
USHORT TmpSum;
|
||||||
|
ULONG i;
|
||||||
|
BOOLEAN Pad;
|
||||||
|
|
||||||
|
/* Pad the data if needed */
|
||||||
|
Pad = (DataLength & 1);
|
||||||
|
if (Pad) {
|
||||||
|
DbgPrint("Odd\n");
|
||||||
|
DataLength++;
|
||||||
|
} else DbgPrint("Even\n");
|
||||||
|
|
||||||
|
/* Add from the UDP header and data */
|
||||||
|
for (i = 0; i < DataLength; i += 2)
|
||||||
|
{
|
||||||
|
TmpSum = ((PacketBuffer[i] << 8) & 0xFF00) +
|
||||||
|
((Pad && i == DataLength - 1) ? 0 : (PacketBuffer[i+1] & 0x00FF));
|
||||||
|
Sum += TmpSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the source address */
|
||||||
|
for (i = 0; i < sizeof(IPv4_RAW_ADDRESS); i += 2)
|
||||||
|
{
|
||||||
|
TmpSum = ((((PUCHAR)&IPHeader->SrcAddr)[i] << 8) & 0xFF00) +
|
||||||
|
(((PUCHAR)&IPHeader->SrcAddr)[i+1] & 0x00FF);
|
||||||
|
Sum += TmpSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the destination address */
|
||||||
|
for (i = 0; i < sizeof(IPv4_RAW_ADDRESS); i += 2)
|
||||||
|
{
|
||||||
|
TmpSum = ((((PUCHAR)&IPHeader->DstAddr)[i] << 8) & 0xFF00) +
|
||||||
|
(((PUCHAR)&IPHeader->DstAddr)[i+1] & 0x00FF);
|
||||||
|
Sum += TmpSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the proto number and length */
|
||||||
|
Sum += IPPROTO_UDP + (DataLength - (Pad ? 1 : 0));
|
||||||
|
|
||||||
|
/* Fold the checksum and return the one's complement */
|
||||||
|
return ~ChecksumFold(Sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ NTSTATUS AddUDPHeaderIPv4(
|
||||||
PIP_ADDRESS LocalAddress,
|
PIP_ADDRESS LocalAddress,
|
||||||
USHORT LocalPort,
|
USHORT LocalPort,
|
||||||
PIP_PACKET IPPacket,
|
PIP_PACKET IPPacket,
|
||||||
|
PVOID Data,
|
||||||
UINT DataLength)
|
UINT DataLength)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Adds an IPv4 and UDP header to an IP packet
|
* FUNCTION: Adds an IPv4 and UDP header to an IP packet
|
||||||
|
@ -49,11 +50,21 @@ NTSTATUS AddUDPHeaderIPv4(
|
||||||
/* Port values are already big-endian values */
|
/* Port values are already big-endian values */
|
||||||
UDPHeader->SourcePort = LocalPort;
|
UDPHeader->SourcePort = LocalPort;
|
||||||
UDPHeader->DestPort = RemotePort;
|
UDPHeader->DestPort = RemotePort;
|
||||||
/* FIXME: Calculate UDP checksum and put it in UDP header */
|
|
||||||
UDPHeader->Checksum = 0;
|
UDPHeader->Checksum = 0;
|
||||||
/* Length of UDP header and data */
|
/* Length of UDP header and data */
|
||||||
UDPHeader->Length = WH2N(DataLength + sizeof(UDP_HEADER));
|
UDPHeader->Length = WH2N(DataLength + sizeof(UDP_HEADER));
|
||||||
|
|
||||||
|
TI_DbgPrint(MID_TRACE, ("Copying data (hdr %x data %x (%d))\n",
|
||||||
|
IPPacket->Header, IPPacket->Data,
|
||||||
|
(PCHAR)IPPacket->Data - (PCHAR)IPPacket->Header));
|
||||||
|
|
||||||
|
RtlCopyMemory(IPPacket->Data, Data, DataLength);
|
||||||
|
|
||||||
|
UDPHeader->Checksum = UDPv4ChecksumCalculate((PIPv4_HEADER)IPPacket->Header,
|
||||||
|
(PUCHAR)UDPHeader,
|
||||||
|
DataLength + sizeof(UDP_HEADER));
|
||||||
|
UDPHeader->Checksum = WH2N(UDPHeader->Checksum);
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE, ("Packet: %d ip %d udp %d payload\n",
|
TI_DbgPrint(MID_TRACE, ("Packet: %d ip %d udp %d payload\n",
|
||||||
(PCHAR)UDPHeader - (PCHAR)IPPacket->Header,
|
(PCHAR)UDPHeader - (PCHAR)IPPacket->Header,
|
||||||
(PCHAR)IPPacket->Data - (PCHAR)UDPHeader,
|
(PCHAR)IPPacket->Data - (PCHAR)UDPHeader,
|
||||||
|
@ -105,7 +116,7 @@ NTSTATUS BuildUDPPacket(
|
||||||
switch (RemoteAddress->Type) {
|
switch (RemoteAddress->Type) {
|
||||||
case IP_ADDRESS_V4:
|
case IP_ADDRESS_V4:
|
||||||
Status = AddUDPHeaderIPv4(RemoteAddress, RemotePort,
|
Status = AddUDPHeaderIPv4(RemoteAddress, RemotePort,
|
||||||
LocalAddress, LocalPort, Packet, DataLen);
|
LocalAddress, LocalPort, Packet, DataBuffer, DataLen);
|
||||||
break;
|
break;
|
||||||
case IP_ADDRESS_V6:
|
case IP_ADDRESS_V6:
|
||||||
/* FIXME: Support IPv6 */
|
/* FIXME: Support IPv6 */
|
||||||
|
@ -121,12 +132,6 @@ NTSTATUS BuildUDPPacket(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE, ("Copying data (hdr %x data %x (%d))\n",
|
|
||||||
Packet->Header, Packet->Data,
|
|
||||||
(PCHAR)Packet->Data - (PCHAR)Packet->Header));
|
|
||||||
|
|
||||||
RtlCopyMemory( Packet->Data, DataBuffer, DataLen );
|
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE, ("Displaying packet\n"));
|
TI_DbgPrint(MID_TRACE, ("Displaying packet\n"));
|
||||||
|
|
||||||
DISPLAY_IP_PACKET(Packet);
|
DISPLAY_IP_PACKET(Packet);
|
||||||
|
@ -258,7 +263,15 @@ VOID UDPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
|
||||||
|
|
||||||
UDPHeader = (PUDP_HEADER)IPPacket->Data;
|
UDPHeader = (PUDP_HEADER)IPPacket->Data;
|
||||||
|
|
||||||
/* FIXME: Calculate and validate UDP checksum */
|
/* Calculate and validate UDP checksum */
|
||||||
|
i = UDPv4ChecksumCalculate(IPv4Header,
|
||||||
|
(PUCHAR)UDPHeader,
|
||||||
|
WH2N(UDPHeader->Length));
|
||||||
|
if (i != DH2N(0x0000FFFF))
|
||||||
|
{
|
||||||
|
TI_DbgPrint(MIN_TRACE, ("Bad checksum on packet received.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
i = WH2N(UDPHeader->Length);
|
i = WH2N(UDPHeader->Length);
|
||||||
|
|
Loading…
Reference in a new issue