// 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); }
/// <summary> /// Update checksum when a 16-bit value that composed the original /// checksum changes. Useful for recomputing checksum when /// TTL changes when acting as a router. /// </summary> public static ushort UpdateChecksum(ushort checksum, ushort oldValue, ushort newValue) { // From RFC1624 ushort newChecksum; unchecked { newChecksum = (ushort)~checksum; newChecksum += (ushort)~oldValue; newChecksum += newValue; } return(IPFormat.ComplementAndFixZeroChecksum(newChecksum)); }
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); }
public static bool IsCheckSumOK(IPHeader !hdr) { ushort sum = (ushort)((((int)hdr.verLen) << 8) + ((int)hdr.tos)); sum = SumShortValues(sum, hdr.totalLength); sum = SumShortValues(sum, hdr.id); sum = SumShortValues(sum, hdr.offset); sum = SumShortValues(sum, (ushort)((((int)hdr.ttl) << 8) + ((int)hdr.protocol))); sum = SumShortValues(sum, (ushort)(((uint)hdr.srcAddr) >> 16)); sum = SumShortValues(sum, (ushort)(((uint)hdr.srcAddr) & 0xFFFFU)); sum = SumShortValues(sum, (ushort)(((uint)hdr.destAddr) >> 16)); sum = SumShortValues(sum, (ushort)(((uint)hdr.destAddr) & 0xFFFFU)); sum = IPFormat.ComplementAndFixZeroChecksum(sum); if (sum != hdr.checksum) { DebugStub.WriteLine("Bad IP Checksum {0:x4} != {1:x4}", __arglist(hdr.checksum, sum)); } return(sum == hdr.checksum); }