128 lines
4.2 KiB
C#
128 lines
4.2 KiB
C#
|
|
/*
|
||
|
|
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 <http://www.gnu.org/licenses/>.
|
||
|
|
*/
|
||
|
|
using System;
|
||
|
|
using PacketDotNet.Utils;
|
||
|
|
using MiscUtil.Conversion;
|
||
|
|
|
||
|
|
namespace PacketDotNet
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Transport layer packet
|
||
|
|
/// </summary>
|
||
|
|
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
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Constructor
|
||
|
|
/// </summary>
|
||
|
|
public TransportPacket()
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <value>
|
||
|
|
/// The Checksum version
|
||
|
|
/// </value>
|
||
|
|
public abstract ushort Checksum
|
||
|
|
{
|
||
|
|
get;
|
||
|
|
set;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Calculates the transport layer checksum, either for the
|
||
|
|
/// tcp or udp packet
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="option"><see cref="TransportPacket.TransportChecksumOption"/></param>
|
||
|
|
/// <returns>
|
||
|
|
/// A <see cref="System.Int32"/>
|
||
|
|
/// </returns>
|
||
|
|
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;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Determine if the transport layer checksum is valid
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="option">
|
||
|
|
/// A <see cref="TransportChecksumOption"/>
|
||
|
|
/// </param>
|
||
|
|
/// <returns>
|
||
|
|
/// A <see cref="System.Boolean"/>
|
||
|
|
/// </returns>
|
||
|
|
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);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Options for use when creating a transport layer checksum
|
||
|
|
/// </summary>
|
||
|
|
public enum TransportChecksumOption
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// No extra options
|
||
|
|
/// </summary>
|
||
|
|
None,
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Attach a pseudo IP header to the transport data being checksummed
|
||
|
|
/// </summary>
|
||
|
|
AttachPseudoIPHeader,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|