Commit 45344f31 authored by Brickner_cp's avatar Brickner_cp

IGMP

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