/// ************************************************************************ /// 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 { /// A UDP packet. ///

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

[Serializable] public class UDPPacket : IPPacket, UDPFields { /// Fetch the port number on the source host. virtual public int SourcePort { get { return ArrayHelper.extractInteger(Bytes, _ipOffset + UDPFields_Fields.UDP_SP_POS, UDPFields_Fields.UDP_PORT_LEN); } set { ArrayHelper.insertLong(Bytes, value, _ipOffset + UDPFields_Fields.UDP_SP_POS, UDPFields_Fields.UDP_PORT_LEN); } } /// Fetch the port number on the target host. virtual public int DestinationPort { get { return ArrayHelper.extractInteger(Bytes, _ipOffset + UDPFields_Fields.UDP_DP_POS, UDPFields_Fields.UDP_PORT_LEN); } set { ArrayHelper.insertLong(Bytes, value, _ipOffset + UDPFields_Fields.UDP_DP_POS, UDPFields_Fields.UDP_PORT_LEN); } } /// Fetch the total length of the UDP packet, including header and /// data payload, in bytes. /// virtual public int UDPLength { get { // should produce the same value as header.length + data.length return Length; } set { ArrayHelper.insertLong(Bytes, value, _ipOffset + UDPFields_Fields.UDP_LEN_POS, UDPFields_Fields.UDP_LEN_LEN); } } /// Fetch the header checksum. virtual public int UDPChecksum { get { return GetTransportLayerChecksum(_ipOffset + UDPFields_Fields.UDP_CSUM_POS); } set { SetTransportLayerChecksum(value, UDPFields_Fields.UDP_CSUM_POS); } } /// Check if the TCP packet is valid, checksum-wise. public override bool ValidChecksum { get { return ValidUDPChecksum; } } virtual public bool ValidUDPChecksum { get { return base.IsValidTransportLayerChecksum(true); } } /// Fetch the UDP header a byte array. virtual public byte[] UDPHeader { get { if (_udpHeaderBytes == null) { _udpHeaderBytes = PacketEncoding.extractHeader(_ipOffset, UDPFields_Fields.UDP_HEADER_LEN, Bytes); } return _udpHeaderBytes; } } /// Fetch the UDP header as a byte array. override public byte[] Header { get { return UDPHeader; } } /// Fetch the UDP header length in bytes. virtual public int UDPHeaderLength { get { return UDPFields_Fields.UDP_HEADER_LEN; } } /// Fetches the packet header length. override public int HeaderLength { get { return UDPHeaderLength; } } /// Fetches the length of the payload data. virtual public int PayloadDataLength { get { return (IPPayloadLength - UDPHeaderLength); } } /// Fetch the UDP data as a byte array. virtual public byte[] UDPData { get { if (_udpDataBytes == null) { _udpDataBytes = new byte[PayloadDataLength]; Array.Copy(Bytes, _ipOffset + UDPHeaderLength, _udpDataBytes, 0, PayloadDataLength); } return _udpDataBytes; } set { SetData(value); } } /// /// Sets the data section of this udp packet /// /// the data bytes public void SetData(byte[] data) { if (IPVersion != IPVersions.IPv4) throw new System.NotImplementedException("IPVersion of " + IPVersion + " is unrecognized"); byte[] headers = ArrayHelper.copy(Bytes, 0, UDPFields_Fields.UDP_HEADER_LEN + IPHeaderLength + EthernetHeaderLength); byte[] newBytes = ArrayHelper.join(headers, data); this.Bytes = newBytes; UDPLength = Bytes.Length - IPHeaderLength - EthernetHeaderLength; //update ip total length length IPTotalLength = IPHeaderLength + UDPFields_Fields.UDP_HEADER_LEN + data.Length; //update also offset and pcap header OnOffsetChanged(); } /// Fetch ascii escape sequence of the color associated with this packet type. override public System.String Color { get { return AnsiEscapeSequences_Fields.LIGHT_GREEN; } } /// Create a new UDP packet. public UDPPacket(int lLen, byte[] bytes) : base(lLen, bytes) { } /// Create a new UDP packet. public UDPPacket(int lLen, byte[] bytes, Timeval tv) : this(lLen, bytes) { this._timeval = tv; } /// Fetch the total length of the UDP packet, including header and /// data payload, in bytes. /// public int Length { get { // should produce the same value as header.length + data.length return ArrayHelper.extractInteger(Bytes, _ipOffset + UDPFields_Fields.UDP_LEN_POS, UDPFields_Fields.UDP_LEN_LEN); } } /// Fetch the header checksum. public int Checksum { get { return UDPChecksum; } set { UDPChecksum=value; } } /// Computes the UDP checksum, optionally updating the UDP checksum header. /// /// /// Specifies whether or not to update the UDP checksum header /// after computing the checksum. A value of true indicates the /// header should be updated, a value of false indicates it should /// not be updated. /// /// The computed UDP checksum. /// public int ComputeUDPChecksum(bool update) { if (IPVersion != IPVersions.IPv4) throw new System.NotImplementedException("IPVersion of " + IPVersion + " is unrecognized"); // copy the udp section with data byte[] udp = IPData; // reset the checksum field (checksum is calculated when this field is // zeroed) ArrayHelper.insertLong(udp, 0, UDPFields_Fields.UDP_CSUM_POS, UDPFields_Fields.UDP_CSUM_LEN); //pseudo ip header should be attached to the udp+data udp = AttachPseudoIPHeader(udp); // compute the one's complement sum of the udp header int cs = ChecksumUtils.OnesComplementSum(udp); if (update) { UDPChecksum = cs; } return cs; } public int ComputeUDPChecksum() { return ComputeUDPChecksum(true); } private byte[] _udpHeaderBytes = null; private byte[] _udpDataBytes = null; /// Fetch the UDP data as a byte array. public override byte[] Data { get { return UDPData; } } /// Convert this UDP packet to a readable string. public override System.String ToString() { return ToColoredString(false); } /// Generate string with contents describing this UDP 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("UDPPacket"); if (colored) buffer.Append(AnsiEscapeSequences_Fields.RESET); buffer.Append(": "); buffer.Append(SourceAddress); buffer.Append('.'); buffer.Append(IPPort.getName(SourcePort)); buffer.Append(" -> "); buffer.Append(DestinationAddress); buffer.Append('.'); buffer.Append(IPPort.getName(DestinationPort)); buffer.Append(" l=" + UDPFields_Fields.UDP_HEADER_LEN + "," + (Length - UDPFields_Fields.UDP_HEADER_LEN)); buffer.Append(']'); return buffer.ToString(); } } }