/// ************************************************************************ /// Copyright (C) 2001, Patrick Charles and Jonas Lehmann * /// Distributed under the Mozilla Public License * /// http://www.mozilla.org/NPL/MPL-1.1.txt * /// ************************************************************************* /// using System; using AnsiEscapeSequences_Fields = SharpPcap.Packets.Util.AnsiEscapeSequences_Fields; using ArrayHelper = SharpPcap.Packets.Util.ArrayHelper; using Timeval = SharpPcap.Packets.Util.Timeval; namespace SharpPcap.Packets { /// An IGMP packet. ///

/// Extends an IP packet, adding an IGMP header and IGMP data payload. /// ///

[Serializable] public class IGMPPacket : IPPacket, IGMPFields { /// Fetch the IGMP header a byte array. virtual public byte[] IGMPHeader { get { if (_igmpHeaderBytes == null) { _igmpHeaderBytes = PacketEncoding.extractHeader(_ethOffset, IGMPFields_Fields.IGMP_HEADER_LEN, Bytes); } return _igmpHeaderBytes; } } /// Fetch the IGMP header as a byte array. override public byte[] Header { get { return IGMPHeader; } } /// Fetch the IGMP data as a byte array. virtual public byte[] IGMPData { get { if (_igmpDataBytes == null) { // set data length based on info in headers (note: tcpdump // can return extra junk bytes which bubble up to here int dataLen = Bytes.Length - _ethOffset - IGMPFields_Fields.IGMP_HEADER_LEN; _igmpDataBytes = PacketEncoding.extractData(_ethOffset, IGMPFields_Fields.IGMP_HEADER_LEN, Bytes, dataLen); } return _igmpDataBytes; } } /// Fetch the IGMP message type, including subcode. Return value can be /// used with IGMPMessage.getDescription(). /// /// a 2-byte value containing the message type in the high byte /// and the message type subcode in the low byte. /// virtual public int MessageType { get { return ArrayHelper.extractInteger(Bytes, _ipOffset + IGMPFields_Fields.IGMP_CODE_POS, IGMPFields_Fields.IGMP_CODE_LEN); } } /// Fetch the IGMP max response time. virtual public int MaxResponseTime { get { return ArrayHelper.extractInteger(Bytes, _ipOffset + IGMPFields_Fields.IGMP_MRSP_POS, IGMPFields_Fields.IGMP_MRSP_LEN); } } /// Fetch the IGMP header checksum. virtual public int IGMPChecksum { get { return ArrayHelper.extractInteger(Bytes, _ipOffset + IGMPFields_Fields.IGMP_CSUM_POS, IGMPFields_Fields.IGMP_CSUM_LEN); } } /// Fetch the IGMP group address. virtual public System.Net.IPAddress GroupAddress { get { return IPPacket.GetIPAddress(System.Net.Sockets.AddressFamily.InterNetwork, _ipOffset + IGMPFields_Fields.IGMP_GADDR_POS, Bytes); } } /// Fetch ascii escape sequence of the color associated with this packet type. override public System.String Color { get { return AnsiEscapeSequences_Fields.BROWN; } } public IGMPPacket(int lLen, byte[] bytes) : base(lLen, bytes) { } public IGMPPacket(int lLen, byte[] bytes, Timeval tv) : this(lLen, bytes) { this._timeval = tv; } private byte[] _igmpHeaderBytes = null; private byte[] _igmpDataBytes = null; /// Fetch the IGMP data as a byte array. public override byte[] Data { get { return IGMPData; } } /// Fetch the IGMP header checksum. public int Checksum { get { return IGMPChecksum; } } /// Convert this IGMP packet to a readable string. public override System.String ToString() { return ToColoredString(false); } /// Generate string with contents describing this IGMP packet. /// whether or not the string should contain ansi /// color escape sequences. /// public override System.String ToColoredString(bool colored) { System.Text.StringBuilder buffer = new System.Text.StringBuilder(); buffer.Append('['); if (colored) buffer.Append(Color); buffer.Append("IGMPPacket"); if (colored) buffer.Append(AnsiEscapeSequences_Fields.RESET); buffer.Append(": "); buffer.Append(IGMPMessage.getDescription(MessageType)); buffer.Append(", "); buffer.Append(GroupAddress + ": "); buffer.Append(SourceAddress + " -> " + DestinationAddress); buffer.Append(" l=" + IGMPFields_Fields.IGMP_HEADER_LEN + "," + (Bytes.Length - _ipOffset - IGMPFields_Fields.IGMP_HEADER_LEN)); buffer.Append(']'); return buffer.ToString(); } } }