// set the checksum field, totalSize covers all the fields for // which the checksum is calculated // offset is points to the beginning of the IP header (!!!) // Should be called after the UDP header + data have been written public static void SetUdpChecksum(byte[] !packet, int ipOffset, ref UdpHeader udpHeader) { // sum IP pseudo ushort ipPayloadSize = 0; ushort headerSum = IPFormat.SumPseudoHeader(packet, ipOffset, ref ipPayloadSize); Debug.Assert(((ushort)udpHeader.length) == ipPayloadSize); // now add it to the udp header + data int ipHeaderSize = (packet[ipOffset] & 0xf) * 4; int udpOffset = ipOffset + ipHeaderSize; Debug.Assert(packet[udpOffset + 6] == 0); Debug.Assert(packet[udpOffset + 7] == 0); ushort payloadSum = IPFormat.SumShortValues(packet, udpOffset, ipPayloadSize); udpHeader.checksum = IPFormat.ComplementAndFixZeroChecksum( IPFormat.SumShortValues(headerSum, payloadSum)); packet[udpOffset + 6] = (byte)(udpHeader.checksum >> 8); packet[udpOffset + 7] = (byte)(udpHeader.checksum & 0xff); }
// set the checksum field // offset points to the beginning of the IP header (!!!) // Should be called after the TCP header + data have been written public static void SetTcpChecksum(byte[] !packet, int ipOffset, ref TcpHeader tcpHeader) { // sum IP pseudo ushort ipPayloadLength = 0; ushort headerSum = IPFormat.SumPseudoHeader(packet, ipOffset, ref ipPayloadLength); int ipHeaderSize = (packet[ipOffset] & 0xf) * 4; int tcpOffset = ipOffset + ipHeaderSize; Debug.Assert(packet[tcpOffset + 16] == 0); Debug.Assert(packet[tcpOffset + 17] == 0); // now add it to the TCP header + data ushort payloadSum = IPFormat.SumShortValues(packet, tcpOffset, ipPayloadLength); tcpHeader.checksum = (ushort) ~(IPFormat.SumShortValues(headerSum, payloadSum)); // Complement and change +0 to -0 if needed. ushort tcpChecksum = IPFormat.ComplementAndFixZeroChecksum( (IPFormat.SumShortValues(headerSum, payloadSum))); tcpHeader.checksum = tcpChecksum; unchecked { packet[tcpOffset + 16] = (byte)(tcpChecksum >> 8); packet[tcpOffset + 17] = (byte)(tcpChecksum >> 0); } }
public static bool IsChecksumValid(IPFormat.IPHeader !ipHeader, TcpHeader tcpHeader, NetPacket !payload) { // Compute partial checksums of headers ushort checksum = IPFormat.SumPseudoHeader(ipHeader); checksum = IPFormat.SumShortValues(checksum, SumHeader(tcpHeader)); // Checksum payload (without potential odd byte) int length = payload.Available; int end = length & ~1; int i = 0; uint payloadChecksum = 0; while (i != end) { byte b0 = payload.PeekAvailable(i++); byte b1 = payload.PeekAvailable(i++); payloadChecksum += ((((uint)b0) << 8) + (uint)b1); } // Handle odd byte. if (i != length) { payloadChecksum += (((uint)payload.PeekAvailable(i++)) << 8); } // Merge bits from payload checksum checksum = IPFormat.SumUInt16AndUInt32Values(checksum, payloadChecksum); // Complement and change +0 to -0 if needed. checksum = IPFormat.ComplementAndFixZeroChecksum(checksum); // Check for match. bool checksumMatch = (tcpHeader.checksum == checksum); // If checksum error, unconditionally output message to debugger. if (checksumMatch == false) { DebugStub.WriteLine("Bad TCP checksum {0:x4} != {1:x4}: SEQ {2:x8} ACK {3:x8}", __arglist(tcpHeader.checksum, checksum, tcpHeader.seq, tcpHeader.ackSeq )); } // IsValid is a Match. return(checksumMatch); }
public static bool IsChecksumValid(IPFormat.IPHeader !ipHeader, UdpHeader udpHeader, NetPacket !payload) { // Compute partial checksums of headers ushort checksum = IPFormat.SumPseudoHeader(ipHeader); checksum = IPFormat.SumShortValues(checksum, UdpFormat.SumHeader(udpHeader)); // Checksum payload int length = payload.Available; int end = length & ~1; int i = 0; while (i != end) { int x = ((((int)payload.PeekAvailable(i++)) << 8) + (int)payload.PeekAvailable(i++)); checksum = IPFormat.SumShortValues(checksum, (ushort)x); } if (i != length) { int x = (((int)payload.PeekAvailable(i++)) << 8); checksum = IPFormat.SumShortValues(checksum, (ushort)x); } checksum = IPFormat.ComplementAndFixZeroChecksum(checksum); if (udpHeader.checksum != checksum) { DebugStub.WriteLine("Bad UDP checksum {0:x4} != {1:x4}", __arglist(udpHeader.checksum, checksum)); } return(udpHeader.checksum == checksum); }