/// <summary> /// Deserializes an IcmpPacket instance from the specified sequence of /// bytes. /// </summary> /// <param name="data">The sequence of bytes to deserialize an IcmpPacket /// object from.</param> /// <returns>A deserialized IpPacket object.</returns> /// <exception cref="ArgumentNullException">Thrown if the data argument is /// null.</exception> /// <exception cref="SerializationException">Thrown if the ICMP packet could /// not be deserialized from the specified byte array.</exception> public static IcmpPacket Deserialize(byte[] data) { data.ThrowIfNull("data"); using (var ms = new MemoryStream(data)) { using (var reader = new BinaryReader(ms)) { var type = (IcmpType)reader.ReadByte(); var code = (IcmpCode)reader.ReadByte(); var checksum = reader.ReadUInt16(); var icmpData = reader.ReadAllBytes(); var packet = new IcmpPacket(type, code, checksum, icmpData); if (ComputeChecksum(packet, true) != 0) { throw new SerializationException("The ICMP header is corrupted."); } return(packet); } } }
/// <summary> /// Computes the 16-bit checksum of the specified ICMP packet. /// </summary> /// <param name="packet">The packet to compute the checksum for.</param> /// <param name="withChecksumField">true to include the packet's /// checksum field in the calculation; otherwise false.</param> /// <returns>The checksum of the specified ICMP packet.</returns> /// <exception cref="ArgumentNullException">Thrown if the packet /// argument is null.</exception> public static ushort ComputeChecksum(IcmpPacket packet, bool withChecksumField = false) { packet.ThrowIfNull("packet"); var bytes = new ByteBuilder() .Append((byte)packet.Type) .Append((byte)packet.Code) .Append(withChecksumField ? packet.Checksum : (ushort)0) .Append(packet.Data) .ToArray(); var sum = 0; // Treat the header bytes as a sequence of unsigned 16-bit values and // sum them up. for (var n = 0; n < bytes.Length; n += 2) { sum += BitConverter.ToUInt16(bytes, n); } // Use carries to compute the 1's complement sum. sum = (sum >> 16) + (sum & 0xFFFF); // Return the inverted 16-bit result. return((ushort)(~sum)); }
/// <summary> /// Computes the 16-bit checksum of the specified ICMP packet. /// </summary> /// <param name="packet">The packet to compute the checksum for.</param> /// <param name="withChecksumField">true to include the packet's /// checksum field in the calculation; otherwise false.</param> /// <returns>The checksum of the specified ICMP packet.</returns> /// <exception cref="ArgumentNullException">Thrown if the packet /// argument is null.</exception> public static ushort ComputeChecksum(IcmpPacket packet, bool withChecksumField = false) { packet.ThrowIfNull("packet"); var bytes = new ByteBuilder() .Append((byte) packet.Type) .Append((byte) packet.Code) .Append(withChecksumField ? packet.Checksum : (ushort) 0) .Append(packet.Data) .ToArray(); var sum = 0; // Treat the header bytes as a sequence of unsigned 16-bit values and // sum them up. for (var n = 0; n < bytes.Length; n += 2) sum += BitConverter.ToUInt16(bytes, n); // Use carries to compute the 1's complement sum. sum = (sum >> 16) + (sum & 0xFFFF); // Return the inverted 16-bit result. return (ushort) (~sum); }
/// <summary> /// Deserializes an IcmpPacket instance from the specified sequence of /// bytes. /// </summary> /// <param name="data">The sequence of bytes to deserialize an IcmpPacket /// object from.</param> /// <returns>A deserialized IpPacket object.</returns> /// <exception cref="ArgumentNullException">Thrown if the data argument is /// null.</exception> /// <exception cref="SerializationException">Thrown if the ICMP packet could /// not be deserialized from the specified byte array.</exception> public static IcmpPacket Deserialize(byte[] data) { data.ThrowIfNull("data"); using (var ms = new MemoryStream(data)) { using (var reader = new BinaryReader(ms)) { var type = (IcmpType) reader.ReadByte(); var code = (IcmpCode) reader.ReadByte(); var checksum = reader.ReadUInt16(); var icmpData = reader.ReadAllBytes(); var packet = new IcmpPacket(type, code, checksum, icmpData); if(ComputeChecksum(packet, true) != 0) throw new SerializationException("The ICMP header is corrupted."); return packet; } } }