Commit edd7c890 authored by Boaz Brickner's avatar Boaz Brickner

Code Coverage 97.48%

Improve IcmpLayer.GetHashCode()
parent bdca6bf7
......@@ -149,7 +149,8 @@ namespace PcapDotNet.Packets.Test
if (actualIcmpLayer.MessageType != IcmpMessageType.RouterSolicitation)
{
Assert.AreNotEqual(random.NextIcmpLayer(), actualIcmpLayer);
Assert.AreNotEqual(random.NextIcmpLayer().GetHashCode(), actualIcmpLayer.GetHashCode());
IcmpLayer otherIcmpLayer = random.NextIcmpLayer();
Assert.AreNotEqual(otherIcmpLayer.GetHashCode(), actualIcmpLayer.GetHashCode());
}
Assert.IsTrue(actualIcmp.IsChecksumCorrect);
Assert.AreEqual(icmpLayer.MessageType, actualIcmp.MessageType);
......
......@@ -512,5 +512,46 @@ namespace PcapDotNet.Packets.Test
Packet invalidPacket = new Packet(invalidPacketBuffer, DateTime.Now, DataLinkKind.Ethernet);
Assert.IsFalse(invalidPacket.IsValid);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException), AllowDerivedTypes = false)]
public void IgmpDatagramIsPrivateForNotCreateGroupRequestVersion0()
{
Packet packet = PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new IpV4Layer(), new IgmpQueryVersion1Layer());
Assert.IsTrue(packet.IsValid);
Assert.IsFalse(packet.Ethernet.IpV4.Igmp.IsPrivate);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException), AllowDerivedTypes = false)]
public void IgmpDatagramReplyCodeVersion0Reply()
{
Packet packet = PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new IpV4Layer(), new IgmpQueryVersion1Layer());
Assert.IsTrue(packet.IsValid);
Assert.IsNotNull(packet.Ethernet.IpV4.Igmp.ReplyCode);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException), AllowDerivedTypes = false)]
public void IgmpDatagramRetryInThisManySecondsForReplyCodeThatIsNotRequestPendingRetryInThisManySeconds()
{
Packet packet = PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new IpV4Layer(), new IgmpReplyVersion0Layer());
Assert.IsTrue(packet.IsValid);
Assert.IsNotNull(packet.Ethernet.IpV4.Igmp.RetryInThisManySeconds);
}
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException), AllowDerivedTypes = false)]
public void IgmpReplyVersion0LayerSetInvalidType()
{
Assert.IsNotNull(new IgmpReplyVersion0Layer {Type = IgmpMessageType.LeaveGroupVersion2});
}
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException), AllowDerivedTypes = false)]
public void IgmpRequestVersion0LayerSetInvalidType()
{
Assert.IsNotNull(new IgmpRequestVersion0Layer { Type = IgmpMessageType.LeaveGroupVersion2 });
}
}
}
\ No newline at end of file
......@@ -134,7 +134,7 @@ namespace PcapDotNet.Packets.Icmp
public sealed override int GetHashCode()
{
return base.GetHashCode() ^
Sequence.GetHashCode(MessageTypeAndCode, Variable) ^ Checksum.GetHashCode();
Sequence.GetHashCode(BitSequence.Merge((ushort)MessageTypeAndCode, Checksum ?? 0), Variable);
}
/// <summary>
......
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// RFC 988.
/// </summary>
public sealed class IgmpConfirmGroupRequestVersion0Layer : IgmpVersion0Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.ConfirmGroupRequestVersion0; }
}
public override uint IdentifierValue
{
get { return 0; }
}
public IpV4Address GroupAddress { get; set; }
public ulong AccessKey { get; set; }
public override ulong AccessKeyValue
{
get { return AccessKey; }
}
protected override byte CodeValue
{
get { return 0; }
}
protected override IpV4Address GroupAddressValue
{
get { return GroupAddress; }
}
}
}
\ No newline at end of file
using PcapDotNet.Base;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// RFC 988.
/// </summary>
public sealed class IgmpCreateGroupRequestVersion0Layer : IgmpVersion0Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.CreateGroupRequestVersion0; }
}
public bool IsPrivate { get; set; }
public uint Identifier { get; set; }
public override uint IdentifierValue
{
get { return Identifier; }
}
public override ulong AccessKeyValue
{
get { return 0; }
}
protected override byte CodeValue
{
get { return IsPrivate.ToByte(); }
}
protected override IpV4Address GroupAddressValue
{
get { return IpV4Address.Zero; }
}
}
}
\ No newline at end of file
using System;
using System.Runtime.InteropServices;
using PcapDotNet.Base;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
{
......@@ -30,259 +27,4 @@ namespace PcapDotNet.Packets.Igmp
}
}
}
/// <summary>
/// RFC 988.
/// </summary>
public abstract class IgmpVersion0Layer : IgmpLayer
{
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override sealed int Length
{
get { return IgmpDatagram.Version0HeaderLength; }
}
public abstract uint IdentifierValue { get; }
public abstract ulong AccessKeyValue { get; }
public override int GetHashCode()
{
return new[]
{
base.GetHashCode(),
CodeValue.GetHashCode(),
IdentifierValue.GetHashCode(),
GroupAddressValue.GetHashCode(),
AccessKeyValue.GetHashCode()
}.Xor();
}
protected override sealed bool EqualsVersionSpecific(IgmpLayer other)
{
return EqualsVersionSpecific(other as IgmpVersion0Layer);
}
protected abstract byte CodeValue { get; }
protected abstract IpV4Address GroupAddressValue { get; }
protected override void Write(byte[] buffer, int offset)
{
IgmpDatagram.WriteVersion0Header(buffer, offset, MessageType, CodeValue, IdentifierValue, GroupAddressValue, AccessKeyValue);
}
private bool EqualsVersionSpecific(IgmpVersion0Layer other)
{
return other != null &&
CodeValue == other.CodeValue &&
IdentifierValue == other.IdentifierValue &&
GroupAddressValue.Equals(other.GroupAddressValue) &&
AccessKeyValue == other.AccessKeyValue;
}
}
/// <summary>
/// RFC 988.
/// </summary>
public sealed class IgmpCreateGroupRequestVersion0Layer : IgmpVersion0Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.CreateGroupRequestVersion0; }
}
public bool IsPrivate { get; set; }
public uint Identifier { get; set; }
public override uint IdentifierValue
{
get { return Identifier; }
}
public override ulong AccessKeyValue
{
get { return 0; }
}
protected override byte CodeValue
{
get { return IsPrivate.ToByte(); }
}
protected override IpV4Address GroupAddressValue
{
get { return IpV4Address.Zero; }
}
}
/// <summary>
/// RFC 988.
/// </summary>
public sealed class IgmpReplyVersion0Layer : IgmpVersion0Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return Type; }
}
public IgmpMessageType Type
{
get { return _type; }
set
{
switch (value)
{
case IgmpMessageType.CreateGroupReplyVersion0:
case IgmpMessageType.JoinGroupReplyVersion0:
case IgmpMessageType.LeaveGroupReplyVersion0:
case IgmpMessageType.ConfirmGroupReplyVersion0:
_type = value;
break;
default:
throw new ArgumentOutOfRangeException("value", value, string.Format("Do not use {0} for {1}", GetType(), value));
}
}
}
public IgmpVersion0ReplyCode Code { get; set; }
public byte RetryInThisManySeconds { get; set; }
public uint Identifier { get; set; }
public override uint IdentifierValue
{
get { return Identifier; }
}
public IpV4Address GroupAddress { get; set; }
public ulong AccessKey { get; set; }
public override ulong AccessKeyValue
{
get { return AccessKey; }
}
protected override byte CodeValue
{
get { return Code == IgmpVersion0ReplyCode.RequestPendingRetryInThisManySeconds ? RetryInThisManySeconds : (byte)Code; }
}
protected override IpV4Address GroupAddressValue
{
get { return GroupAddress; }
}
private IgmpMessageType _type = IgmpMessageType.CreateGroupReplyVersion0;
}
/// <summary>
/// RFC 988.
/// </summary>
public sealed class IgmpRequestVersion0Layer : IgmpVersion0Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return Type; }
}
public IgmpMessageType Type
{
get { return _type; }
set
{
switch (value)
{
case IgmpMessageType.JoinGroupRequestVersion0:
case IgmpMessageType.LeaveGroupRequestVersion0:
_type = value;
break;
default:
throw new ArgumentOutOfRangeException("value", value, string.Format("Do not use {0} for {1}", GetType(), value));
}
}
}
public uint Identifier { get; set; }
public override uint IdentifierValue
{
get { return Identifier; }
}
public IpV4Address GroupAddress { get; set; }
public ulong AccessKey { get; set; }
public override ulong AccessKeyValue
{
get { return AccessKey; }
}
protected override byte CodeValue
{
get { return 0; }
}
protected override IpV4Address GroupAddressValue
{
get { return GroupAddress; }
}
private IgmpMessageType _type = IgmpMessageType.JoinGroupRequestVersion0;
}
/// <summary>
/// RFC 988.
/// </summary>
public sealed class IgmpConfirmGroupRequestVersion0Layer : IgmpVersion0Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return IgmpMessageType.ConfirmGroupRequestVersion0; }
}
public override uint IdentifierValue
{
get { return 0; }
}
public IpV4Address GroupAddress { get; set; }
public ulong AccessKey { get; set; }
public override ulong AccessKeyValue
{
get { return AccessKey; }
}
protected override byte CodeValue
{
get { return 0; }
}
protected override IpV4Address GroupAddressValue
{
get { return GroupAddress; }
}
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// RFC 988.
/// </summary>
public sealed class IgmpReplyVersion0Layer : IgmpVersion0Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return Type; }
}
public IgmpMessageType Type
{
get { return _type; }
set
{
switch (value)
{
case IgmpMessageType.CreateGroupReplyVersion0:
case IgmpMessageType.JoinGroupReplyVersion0:
case IgmpMessageType.LeaveGroupReplyVersion0:
case IgmpMessageType.ConfirmGroupReplyVersion0:
_type = value;
break;
default:
throw new ArgumentOutOfRangeException("value", value, string.Format("Do not use {0} for {1}", GetType(), value));
}
}
}
public IgmpVersion0ReplyCode Code { get; set; }
public byte RetryInThisManySeconds { get; set; }
public uint Identifier { get; set; }
public override uint IdentifierValue
{
get { return Identifier; }
}
public IpV4Address GroupAddress { get; set; }
public ulong AccessKey { get; set; }
public override ulong AccessKeyValue
{
get { return AccessKey; }
}
protected override byte CodeValue
{
get { return Code == IgmpVersion0ReplyCode.RequestPendingRetryInThisManySeconds ? RetryInThisManySeconds : (byte)Code; }
}
protected override IpV4Address GroupAddressValue
{
get { return GroupAddress; }
}
private IgmpMessageType _type = IgmpMessageType.CreateGroupReplyVersion0;
}
}
\ No newline at end of file
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// RFC 988.
/// </summary>
public sealed class IgmpRequestVersion0Layer : IgmpVersion0Layer
{
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public override IgmpMessageType MessageType
{
get { return Type; }
}
public IgmpMessageType Type
{
get { return _type; }
set
{
switch (value)
{
case IgmpMessageType.JoinGroupRequestVersion0:
case IgmpMessageType.LeaveGroupRequestVersion0:
_type = value;
break;
default:
throw new ArgumentOutOfRangeException("value", value, string.Format("Do not use {0} for {1}", GetType(), value));
}
}
}
public uint Identifier { get; set; }
public override uint IdentifierValue
{
get { return Identifier; }
}
public IpV4Address GroupAddress { get; set; }
public ulong AccessKey { get; set; }
public override ulong AccessKeyValue
{
get { return AccessKey; }
}
protected override byte CodeValue
{
get { return 0; }
}
protected override IpV4Address GroupAddressValue
{
get { return GroupAddress; }
}
private IgmpMessageType _type = IgmpMessageType.JoinGroupRequestVersion0;
}
}
\ No newline at end of file
using PcapDotNet.Base;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
{
/// <summary>
/// RFC 988.
/// </summary>
public abstract class IgmpVersion0Layer : IgmpLayer
{
/// <summary>
/// The number of bytes this layer will take.
/// </summary>
public override sealed int Length
{
get { return IgmpDatagram.Version0HeaderLength; }
}
public abstract uint IdentifierValue { get; }
public abstract ulong AccessKeyValue { get; }
public override int GetHashCode()
{
return new[]
{
base.GetHashCode(),
CodeValue.GetHashCode(),
IdentifierValue.GetHashCode(),
GroupAddressValue.GetHashCode(),
AccessKeyValue.GetHashCode()
}.Xor();
}
protected override sealed bool EqualsVersionSpecific(IgmpLayer other)
{
return EqualsVersionSpecific(other as IgmpVersion0Layer);
}
protected abstract byte CodeValue { get; }
protected abstract IpV4Address GroupAddressValue { get; }
protected override void Write(byte[] buffer, int offset)
{
IgmpDatagram.WriteVersion0Header(buffer, offset, MessageType, CodeValue, IdentifierValue, GroupAddressValue, AccessKeyValue);
}
private bool EqualsVersionSpecific(IgmpVersion0Layer other)
{
return other != null &&
CodeValue == other.CodeValue &&
IdentifierValue == other.IdentifierValue &&
GroupAddressValue.Equals(other.GroupAddressValue) &&
AccessKeyValue == other.AccessKeyValue;
}
}
}
\ No newline at end of file
......@@ -299,16 +299,21 @@
<Compile Include="Icmp\IcmpUnknownLayer.cs" />
<Compile Include="IDataLink.cs" />
<Compile Include="Ethernet\IEthernetNextLayer.cs" />
<Compile Include="Igmp\IgmpConfirmGroupRequestVersion0Layer.cs" />
<Compile Include="Igmp\IgmpCreateGroupRequestVersion0Code.cs" />
<Compile Include="Igmp\IgmpCreateGroupRequestVersion0Layer.cs" />
<Compile Include="Igmp\IgmpLayer.cs" />
<Compile Include="Igmp\IgmpLeaveGroupVersion2Layer.cs" />
<Compile Include="Igmp\IgmpQueryVersion1Layer.cs" />
<Compile Include="Igmp\IgmpQueryVersion2Layer.cs" />
<Compile Include="Igmp\IgmpQueryVersion3Layer.cs" />
<Compile Include="Igmp\IgmpReplyVersion0Code.cs" />
<Compile Include="Igmp\IgmpReplyVersion0Layer.cs" />
<Compile Include="Igmp\IgmpReportVersion1Layer.cs" />
<Compile Include="Igmp\IgmpReportVersion2Layer.cs" />
<Compile Include="Igmp\IgmpReportVersion3Layer.cs" />
<Compile Include="Igmp\IgmpRequestVersion0Layer.cs" />
<Compile Include="Igmp\IgmpVersion0Layer.cs" />
<Compile Include="Igmp\IgmpVersion1PlusLayer.cs" />
<Compile Include="Igmp\IgmpVersion1PlusSimpleLayer.cs" />
<Compile Include="Igmp\IgmpVersion0ReplyCode.cs" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment