/* This file is part of PacketDotNet PacketDotNet is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PacketDotNet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with PacketDotNet. If not, see . */ using System; using PacketDotNet.Utils; using MiscUtil.Conversion; namespace PacketDotNet { /// /// Transport layer packet /// public abstract class TransportPacket : Packet { // NOTE: No need to warn about lack of use, the compiler won't // put any calls to 'log' here but we need 'log' to exist to compile #pragma warning disable 0169, 0649 private static readonly ILogInactive log; #pragma warning restore 0169, 0649 /// /// Constructor /// public TransportPacket() { } /// /// The Checksum version /// public abstract ushort Checksum { get; set; } /// /// Calculates the transport layer checksum, either for the /// tcp or udp packet /// /// /// /// A /// internal int CalculateChecksum(TransportChecksumOption option) { // save the checksum field value so it can be restored, altering the checksum is not // an intended side effect of this method var originalChecksum = Checksum; // reset the checksum field (checksum is calculated when this field is // zeroed) Checksum = 0; // copy the tcp section with data byte[] dataToChecksum = ((IpPacket)ParentPacket).PayloadPacket.Bytes; if (option == TransportChecksumOption.AttachPseudoIPHeader) dataToChecksum = ((IpPacket)ParentPacket).AttachPseudoIPHeader(dataToChecksum); // calculate the one's complement sum of the tcp header int cs = ChecksumUtils.OnesComplementSum(dataToChecksum); // restore the checksum field value Checksum = originalChecksum; return cs; } /// /// Determine if the transport layer checksum is valid /// /// /// A /// /// /// A /// public virtual bool IsValidChecksum(TransportChecksumOption option) { var upperLayer = ((IpPacket)ParentPacket).PayloadPacket.Bytes; log.DebugFormat("option: {0}, upperLayer.Length {1}", option, upperLayer.Length); if (option == TransportChecksumOption.AttachPseudoIPHeader) upperLayer = ((IpPacket)ParentPacket).AttachPseudoIPHeader(upperLayer); var onesSum = ChecksumUtils.OnesSum(upperLayer); const int expectedOnesSum = 0xffff; log.DebugFormat("onesSum {0} expected {1}", onesSum, expectedOnesSum); return (onesSum == expectedOnesSum); } /// /// Options for use when creating a transport layer checksum /// public enum TransportChecksumOption { /// /// No extra options /// None, /// /// Attach a pseudo IP header to the transport data being checksummed /// AttachPseudoIPHeader, } } }