Commit 45344f31 authored by Brickner_cp's avatar Brickner_cp

IGMP

parent 32469b4d
......@@ -130,7 +130,10 @@ namespace PcapDotNet.Packets.Test
ipV4Payload);
Assert.IsTrue(ipV4Protocol == IpV4Protocol.Udp || ipV4Protocol == IpV4Protocol.Tcp || packet.IsValid, "IsValid");
Assert.IsTrue(ipV4Protocol == IpV4Protocol.Udp ||
ipV4Protocol == IpV4Protocol.Tcp ||
ipV4Protocol == IpV4Protocol.InternetGroupManagementProtocol ||
packet.IsValid, "IsValid");
// Ethernet
Assert.AreEqual(packet.Length - EthernetDatagram.HeaderLength, packet.Ethernet.PayloadLength, "PayloadLength");
......
......@@ -130,7 +130,7 @@ namespace PcapDotNet.Packets.Arp
}
/// <summary>
/// The default validity check always returns true.
/// The datagram is valid if the length is correct according to the header.
/// </summary>
protected override bool CalculateIsValid()
{
......
......@@ -47,6 +47,7 @@
<Word>wiegand</Word>
<Word>arp</Word>
<Word>multimegabit</Word>
<Word>igmp</Word>
</Recognized>
<Deprecated>
<!--Term PreferredAlternate="EnterpriseServices">complus</Term-->
......
using System;
using System.Collections.ObjectModel;
using System.Linq;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Igmp
......@@ -87,18 +88,19 @@ namespace PcapDotNet.Packets.Igmp
public class IgmpDatagram : Datagram
{
public const int HeaderLength = 8;
public const int QueryVersion3HeaderLength = 12;
private static class Offset
{
public const int Type = 0;
public const int MessageType = 0;
public const int MaxResponseCode = 1;
public const int Checksum = 2;
public const int GroupAddress = 4;
// Version 3 query
public const int IsSuppressRouterSideProcessing = 8;
public const int QueriersRobustnessVariable = 8;
public const int QueriersQueryIntervalCode = 9;
public const int QueryRobustnessVariable = 8;
public const int QueryIntervalCode = 9;
public const int NumberOfSources = 10;
public const int SourceAddresses = 12;
......@@ -110,9 +112,9 @@ namespace PcapDotNet.Packets.Igmp
/// <summary>
/// The type of the IGMP message of concern to the host-router interaction.
/// </summary>
public IgmpType Type
public IgmpType MessageType
{
get { return (IgmpType)this[Offset.Type]; }
get { return (IgmpType)this[Offset.MessageType]; }
}
/// <summary>
......@@ -129,13 +131,13 @@ namespace PcapDotNet.Packets.Igmp
{
get
{
if (Type != IgmpType.MembershipQuery)
if (MessageType != IgmpType.MembershipQuery)
return IgmpQueryVersion.None;
if (Length >= 12)
if (Length >= QueryVersion3HeaderLength)
return IgmpQueryVersion.Version3;
if (Length != 8)
if (Length != HeaderLength)
return IgmpQueryVersion.Unknown;
if (MaxResponseCode == 0)
......@@ -195,7 +197,7 @@ namespace PcapDotNet.Packets.Igmp
{
byte maxResponseCode = MaxResponseCode;
int numTenthOfASecond =
((maxResponseCode < 128 || Type != IgmpType.MembershipQuery || QueryVersion != IgmpQueryVersion.Version3)
((maxResponseCode < 128 || MessageType != IgmpType.MembershipQuery || QueryVersion != IgmpQueryVersion.Version3)
? maxResponseCode
: CodeToValue(maxResponseCode));
......@@ -259,9 +261,9 @@ namespace PcapDotNet.Packets.Igmp
/// <remarks>
/// Valid only on query of version 3.
/// </remarks>
public byte QueriersRobustnessVariable
public byte QueryRobustnessVariable
{
get { return (byte)(this[Offset.QueriersRobustnessVariable] & 0x07); }
get { return (byte)(this[Offset.QueryRobustnessVariable] & 0x07); }
}
/// <summary>
......@@ -286,9 +288,9 @@ namespace PcapDotNet.Packets.Igmp
/// <remarks>
/// Valid only on query of version 3.
/// </remarks>
public byte QueriersQueryIntervalCode
public byte QueryIntervalCode
{
get { return this[Offset.QueriersQueryIntervalCode]; }
get { return this[Offset.QueryIntervalCode]; }
}
/// <summary>
......@@ -310,13 +312,13 @@ namespace PcapDotNet.Packets.Igmp
/// <remarks>
/// Valid only on query of version 3.
/// </remarks>
public TimeSpan QueriersQueryInterval
public TimeSpan QueryInterval
{
get
{
int numSeconds = QueriersQueryIntervalCode < 128
? QueriersQueryIntervalCode
: CodeToValue(QueriersQueryIntervalCode);
int numSeconds = QueryIntervalCode < 128
? QueryIntervalCode
: CodeToValue(QueryIntervalCode);
return TimeSpan.FromSeconds(numSeconds);
}
......@@ -393,15 +395,41 @@ namespace PcapDotNet.Packets.Igmp
if (Length < HeaderLength || !IsChecksumCorrect)
return false;
// switch (Type)
// {
// case IgmpType.MembershipQuery:
// case IgmpType.LeaveGroupVersion2:
// case IgmpType.MembershipReportVersion1:
// case IgmpType.MembershipReportVersion2:
// case IgmpType.MembershipReportVersion3:
// }
return true;
switch (MessageType)
{
case IgmpType.MembershipQuery:
switch (QueryVersion)
{
case IgmpQueryVersion.Version1:
return Length == HeaderLength && MaxResponseCode == 0;
case IgmpQueryVersion.Version2:
return Length == HeaderLength;
case IgmpQueryVersion.Version3:
return Length >= QueryVersion3HeaderLength &&
Length == QueryVersion3HeaderLength + 4 * NumberOfSources &&
NumberOfSources == SourceAddresses.Count;
default:
return false;
}
case IgmpType.MembershipReportVersion1:
return Length == HeaderLength && MaxResponseCode == 0;
case IgmpType.LeaveGroupVersion2:
case IgmpType.MembershipReportVersion2:
return Length == HeaderLength;
case IgmpType.MembershipReportVersion3:
return MaxResponseCode == 0 && NumberOfGroupRecords == GroupRecords.Count &&
Length == HeaderLength + GroupRecords.Sum(record => record.Length) &&
GroupRecords.All(record => record.IsValid);
default:
return false;
}
}
private ushort CalculateChecksum()
......
......@@ -33,6 +33,7 @@ namespace PcapDotNet.Packets.Igmp
/// . . .
/// | | |
/// +-----+----------------------------------------------------+
/// </pre>
/// </summary>
public class IgmpGroupRecordDatagram : Datagram
{
......@@ -114,6 +115,9 @@ namespace PcapDotNet.Packets.Igmp
{
}
/// <summary>
/// The record is valid if the length is correct according to the header fields.
/// </summary>
protected override bool CalculateIsValid()
{
return Length >= HeaderMinimumLength &&
......
......@@ -5,6 +5,11 @@ namespace PcapDotNet.Packets.Igmp
/// </summary>
public enum IgmpRecordType : byte
{
/// <summary>
/// Illegal record type.
/// </summary>
None = 0,
/// <summary>
/// A "Current-State Record" is sent by a system in response to a Query received on an interface.
/// It reports the current reception state of that interface, with respect to a single multicast address.
......@@ -76,6 +81,7 @@ namespace PcapDotNet.Packets.Igmp
/// If the change was to an INCLUDE source list, these are the addresses that were deleted from the list; if the change was to an EXCLUDE source list,
/// these are the addresses that were added to the list.
/// </para>
/// <para>
/// If a change of source list results in both allowing new sources and blocking old sources,
/// then two Group Records are sent for the same multicast address, one of type ALLOW_NEW_SOURCES and one of type BLOCK_OLD_SOURCES.
/// </para>
......
......@@ -2,6 +2,11 @@ namespace PcapDotNet.Packets.Igmp
{
public enum IgmpType : byte
{
/// <summary>
/// Illegal type.
/// </summary>
None = 0x00,
/// <summary>
/// Membership Query (RFC3376).
/// </summary>
......
......@@ -231,7 +231,7 @@ namespace PcapDotNet.Packets.Transport
}
/// <summary>
/// The default validity check always returns true.
/// The datagram is valid if the length is correct according to the header and the options are valid.
/// </summary>
protected override bool CalculateIsValid()
{
......
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