[CMAKE]: Simplify makefiles.
[reactos.git] / lib / drivers / ip / network / checksum.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/checksum.c
5 * PURPOSE: Checksum routines
6 * NOTES: The checksum routine is from RFC 1071
7 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * REVISIONS:
9 * CSH 01/08-2000 Created
10 */
11
12 #include "precomp.h"
13
14
15 ULONG ChecksumFold(
16 ULONG Sum)
17 {
18 /* Fold 32-bit sum to 16 bits */
19 while (Sum >> 16)
20 {
21 Sum = (Sum & 0xFFFF) + (Sum >> 16);
22 }
23
24 return Sum;
25 }
26
27 ULONG ChecksumCompute(
28 PVOID Data,
29 UINT Count,
30 ULONG Seed)
31 /*
32 * FUNCTION: Calculate checksum of a buffer
33 * ARGUMENTS:
34 * Data = Pointer to buffer with data
35 * Count = Number of bytes in buffer
36 * Seed = Previously calculated checksum (if any)
37 * RETURNS:
38 * Checksum of buffer
39 */
40 {
41 register ULONG Sum = Seed;
42
43 while (Count > 1)
44 {
45 Sum += *(PUSHORT)Data;
46 Count -= 2;
47 Data = (PVOID)((ULONG_PTR) Data + 2);
48 }
49
50 /* Add left-over byte, if any */
51 if (Count > 0)
52 {
53 Sum += *(PUCHAR)Data;
54 }
55
56 return Sum;
57 }
58
59 ULONG
60 UDPv4ChecksumCalculate(
61 PIPv4_HEADER IPHeader,
62 PUCHAR PacketBuffer,
63 ULONG DataLength)
64 {
65 ULONG Sum = 0;
66 USHORT TmpSum;
67 ULONG i;
68 BOOLEAN Pad;
69
70 /* Pad the data if needed */
71 Pad = (DataLength & 1);
72 if (Pad)
73 DataLength++;
74
75 /* Add from the UDP header and data */
76 for (i = 0; i < DataLength; i += 2)
77 {
78 TmpSum = ((PacketBuffer[i] << 8) & 0xFF00) +
79 ((Pad && i == DataLength - 2) ? 0 : (PacketBuffer[i+1] & 0x00FF));
80 Sum += TmpSum;
81 }
82
83 /* Add the source address */
84 for (i = 0; i < sizeof(IPv4_RAW_ADDRESS); i += 2)
85 {
86 TmpSum = ((((PUCHAR)&IPHeader->SrcAddr)[i] << 8) & 0xFF00) +
87 (((PUCHAR)&IPHeader->SrcAddr)[i+1] & 0x00FF);
88 Sum += TmpSum;
89 }
90
91 /* Add the destination address */
92 for (i = 0; i < sizeof(IPv4_RAW_ADDRESS); i += 2)
93 {
94 TmpSum = ((((PUCHAR)&IPHeader->DstAddr)[i] << 8) & 0xFF00) +
95 (((PUCHAR)&IPHeader->DstAddr)[i+1] & 0x00FF);
96 Sum += TmpSum;
97 }
98
99 /* Add the proto number and length */
100 Sum += IPPROTO_UDP + (DataLength - (Pad ? 1 : 0));
101
102 /* Fold the checksum and return the one's complement */
103 return ~ChecksumFold(Sum);
104 }
105