/* 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 . */ /* * Copyright 2009 Chris Morgan * Copyright 2010 Evan Plaice */ using System; using System.Collections.Generic; using System.Text; using MiscUtil.Conversion; using PacketDotNet.Utils; namespace PacketDotNet { /// /// An IGMP packet. /// [Serializable] public class IGMPv2Packet : InternetPacket { /// /// The type of IGMP message /// virtual public IGMPMessageType Type { get { return (IGMPMessageType)header.Bytes[header.Offset + IGMPv2Fields.TypePosition]; } set { header.Bytes[header.Offset + IGMPv2Fields.TypePosition] = (byte)value; } } /// Fetch the IGMP max response time. virtual public byte MaxResponseTime { get { return header.Bytes[header.Offset + IGMPv2Fields.MaxResponseTimePosition]; } set { header.Bytes[header.Offset + IGMPv2Fields.MaxResponseTimePosition] = value; } } /// Fetch the IGMP header checksum. virtual public short Checksum { get { return BitConverter.ToInt16(header.Bytes, header.Offset + IGMPv2Fields.ChecksumPosition); } set { byte[] theValue = BitConverter.GetBytes(value); Array.Copy(theValue, 0, header.Bytes, (header.Offset + IGMPv2Fields.ChecksumPosition), 2); } } /// Fetch the IGMP group address. virtual public System.Net.IPAddress GroupAddress { get { return IpPacket.GetIPAddress(System.Net.Sockets.AddressFamily.InterNetwork, header.Offset + IGMPv2Fields.GroupAddressPosition, header.Bytes); } } /// Fetch ascii escape sequence of the color associated with this packet type. override public System.String Color { get { return AnsiEscapeSequences.Brown; } } /// /// Constructor /// /// /// A /// public IGMPv2Packet(ByteArraySegment bas) { // set the header field, header field values are retrieved from this byte array header = new ByteArraySegment(bas); RandomUtils.EnsurePacketLength(this, IGMPv2Fields.HeaderLength, header.Length); header.Length = UdpFields.HeaderLength; // store the payload bytes payloadPacketOrData = new PacketOrByteArraySegment(); payloadPacketOrData.TheByteArraySegment = header.EncapsulatedBytes(); } /// /// Constructor with parent /// /// /// A /// /// /// A /// public IGMPv2Packet(ByteArraySegment bas, Packet ParentPacket) : this(bas) { this.ParentPacket = ParentPacket; } /// /// Returns the encapsulated IGMPv2Packet of the Packet p or null if /// there is no encapsulated packet /// /// /// A /// /// /// A /// [Obsolete("Use Packet.Extract() instead")] public static IGMPv2Packet GetEncapsulated(Packet p) { if(p is InternetLinkLayerPacket) { var payload = InternetLinkLayerPacket.GetInnerPayload((InternetLinkLayerPacket)p); if(payload is IpPacket) { var innerPayload = payload.PayloadPacket; if(innerPayload is IGMPv2Packet) { return (IGMPv2Packet)innerPayload; } } } return null; } /// public override string ToString(StringOutputType outputFormat) { var buffer = new StringBuilder(); string color = ""; string colorEscape = ""; if(outputFormat == StringOutputType.Colored || outputFormat == StringOutputType.VerboseColored) { color = Color; colorEscape = AnsiEscapeSequences.Reset; } if(outputFormat == StringOutputType.Normal || outputFormat == StringOutputType.Colored) { // build the output string buffer.AppendFormat("{0}[IGMPv2Packet: Type={2}, MaxResponseTime={3}, GroupAddress={4}]{1}", color, colorEscape, Type, String.Format("{0:0.0}", (MaxResponseTime / 10)), GroupAddress); } if(outputFormat == StringOutputType.Verbose || outputFormat == StringOutputType.VerboseColored) { // collect the properties and their value Dictionary properties = new Dictionary(); properties.Add("type", Type + " (0x" + Type.ToString("x") + ")"); properties.Add("max response time", String.Format("{0:0.0}", MaxResponseTime / 10) + " sec (0x" + MaxResponseTime.ToString("x") + ")"); // TODO: Implement checksum validation for IGMPv2 properties.Add("header checksum", "0x" + Checksum.ToString("x")); properties.Add("group address", GroupAddress.ToString()); // calculate the padding needed to right-justify the property names int padLength = Utils.RandomUtils.LongestStringLength(new List(properties.Keys)); // build the output string buffer.AppendLine("IGMP: ******* IGMPv2 - \"Internet Group Management Protocol (Version 2)\" - offset=? length=" + TotalPacketLength); buffer.AppendLine("IGMP:"); foreach (var property in properties) { buffer.AppendLine("IGMP: " + property.Key.PadLeft(padLength) + " = " + property.Value); } buffer.AppendLine("IGMP:"); } // append the base string output buffer.Append(base.ToString(outputFormat)); return buffer.ToString(); } } }