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> /// Write IP and UDP headers and payload data into a /// byte array. /// </summary> /// <param name="pkt">Array of bytes representing /// packet to be sent.</param> /// <param name="offset">Offset of IP Header within /// packet.</param> /// <param name="ipHeader">IP header to be written /// to packet.</param> /// <param name="udpHeader">UDP header to be written /// to packet.</param> /// <param name="payload">Payload of UDP Packet.</param> /// <param name="payloadOffset">The offset of start /// of the payload data within the payload /// array.</param> /// <param name="payloadLength">The size of the payload data.</param> public static void WriteUdpPacket(byte[] !pkt, int offset, IPFormat.IPHeader !ipHeader, ref UdpHeader udpHeader, byte[] payload, int payloadOffset, int payloadLength) { int udpStart = IPFormat.WriteIPHeader(pkt, offset, ipHeader); int udpEnd = WriteUdpHeader(pkt, udpStart, ref udpHeader); if (pkt != payload || udpEnd != payloadOffset) { Array.Copy(payload, payloadOffset, pkt, udpEnd, payloadLength); } SetUdpChecksum(pkt, offset, ref udpHeader); }
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 void WriteUdpPacket(byte[] !pkt, int offset, IPFormat.IPHeader !ipHeader, ref UdpHeader udpHeader, byte[] !in ExHeap payload,
// a helper method to write the TCP segment (without data) public static void WriteTcpSegment(byte[] !pktData, ushort localPort, ushort destPort, uint ackSeq, uint seq, ushort wnd, IPv4 sIP, IPv4 dIP, ushort dataLen, bool isAck, bool isSyn, bool isRst, bool isFin, bool withOptions) { // now create the IP,TCP headers! int start = EthernetFormat.Size; // prepare it... TcpFormat.TcpHeader tcpHeader = new TcpFormat.TcpHeader(); tcpHeader.sourcePort = localPort; tcpHeader.destPort = destPort; if (withOptions) { tcpHeader.off_res1 = 0x60; } else { tcpHeader.off_res1 = 0x50; } tcpHeader.ackSeq = ackSeq; tcpHeader.seq = seq; tcpHeader.window = wnd; if (isFin) { TcpFormat.SetFIN(ref tcpHeader); } if (isSyn) { TcpFormat.SetSYN(ref tcpHeader); } if (isAck) { TcpFormat.SetACK(ref tcpHeader); } if (isRst) { TcpFormat.SetReset(ref tcpHeader); } IPFormat.IPHeader ipHeader = new IPFormat.IPHeader(); ipHeader.SetDefaults(IPFormat.Protocol.TCP); ipHeader.totalLength = (ushort)(IPFormat.Size + TcpFormat.Size + dataLen); ipHeader.srcAddr = sIP; ipHeader.destAddr = dIP; IPFormat.SetDontFragBit(ipHeader); // write the ip header + ip checksum start = IPFormat.WriteIPHeader(pktData, start, ipHeader); // write TCP header, no checksum start = TcpFormat.WriteTcpHeader(pktData, start, ref tcpHeader); // calc the checksum... TcpFormat.SetTcpChecksum(pktData, EthernetFormat.Size, ref tcpHeader); }