Class to represent UDP datagram which contains the UDP headers and Data.
Наследование: IUdpDatagram
Пример #1
0
        /// <summary>
        /// Creates UDP datagram based on the specified IP packet.
        /// </summary>
        /// <param name="ipPacket">A source IpPacket Object that contains a UDP datagram.</param>
        /// <param name="reuseOriginalBuffer">A flag that determines if the original packet's buffer needs to be reused.</param>
        /// <returns>A new UdpDatagram instance.</returns>
        /// <exception cref="System.ArgumentNullException">ipPacket is null</exception>
        /// <exception cref="System.NotSupportedException">Only UDP packets are supported.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">ipPacket.PacketData is empty.</exception>
        public static UdpDatagram ToUdpDatagram(this IIpPacket ipPacket, bool reuseOriginalBuffer = true)
        {
            if (ipPacket == null)
            {
                throw new ArgumentNullException("ipPacket");
            }

            if (ipPacket.ProtocolType != ProtocolType.Udp)
            {
                throw new NotSupportedException("Only UDP packets are supported.");
            }

            if (ipPacket.PacketData.Count <= 0)
            {
                throw new ArgumentOutOfRangeException();
            }

            var packetData = ipPacket.PacketData.AsByteArraySegment();

            UdpDatagramHeader udpDatagramHeader = null;

            if (ipPacket.PacketData.Count > 8)
            {
                udpDatagramHeader = new UdpDatagramHeader(
                    packetData.Array.ReadNetOrderUShort(packetData.Offset),
                    packetData.Array.ReadNetOrderUShort(2 + packetData.Offset),
                    packetData.Array.ReadNetOrderUShort(4 + packetData.Offset),
                    packetData.Array.ReadNetOrderUShort(6 + packetData.Offset));
            }

            ArraySegment <byte> udpData;

            if (reuseOriginalBuffer)
            {
                udpData = new ArraySegment <byte>(
                    packetData.Array,
                    packetData.Offset + 8,
                    packetData.Count - 8);
            }
            else
            {
                var ipOptionsDataArray = new byte[packetData.Count - 8];
                Array.Copy(packetData.Array, packetData.Offset + 8, ipOptionsDataArray, 0, packetData.Count - 8);
                udpData = new ArraySegment <byte>(ipOptionsDataArray);
            }

            var udpDatagram = new UdpDatagram
            {
                PacketHeader      = ipPacket.PacketHeader,
                UdpDatagramHeader = udpDatagramHeader,
                UdpData           = udpData,
                ReceivedTime      = ipPacket.ReceivedTime
            };

            return(udpDatagram);
        }
Пример #2
0
        /// <summary>
        /// Creates UDP datagram based on the specified IP packet.
        /// </summary>
        /// <param name="ipPacket">A source IpPacket Object that contains a UDP datagram.</param>
        /// <param name="reuseOriginalBuffer">A flag that determines if the original packet's buffer needs to be reused.</param>
        /// <returns>A new UdpDatagram instance.</returns>
        /// <exception cref="System.ArgumentNullException">ipPacket is null</exception>
        /// <exception cref="System.NotSupportedException">Only UDP packets are supported.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">ipPacket.PacketData is empty.</exception>
        public static UdpDatagram ToUdpDatagram(this IIpPacket ipPacket, bool reuseOriginalBuffer = true)
        {
            if (ipPacket == null)
            {
                throw new ArgumentNullException("ipPacket");
            }

            if (ipPacket.ProtocolType != ProtocolType.Udp)
            {
                throw new NotSupportedException("Only UDP packets are supported.");
            }

            if (ipPacket.PacketData.Count <= 0)
            {
                throw new ArgumentOutOfRangeException();
            }

            var packetData = ipPacket.PacketData.AsByteArraySegment();

            UdpDatagramHeader udpDatagramHeader = null;
            if (ipPacket.PacketData.Count > 8)
            {
                udpDatagramHeader = new UdpDatagramHeader(
                    packetData.Array.ReadNetOrderUShort(packetData.Offset),
                    packetData.Array.ReadNetOrderUShort(2 + packetData.Offset),
                    packetData.Array.ReadNetOrderUShort(4 + packetData.Offset),
                    packetData.Array.ReadNetOrderUShort(6 + packetData.Offset));
            }

            ArraySegment<byte> udpData;
            if (reuseOriginalBuffer)
            {
                udpData = new ArraySegment<byte>(
                    packetData.Array,
                    packetData.Offset + 8,
                    packetData.Count - 8);
            }
            else
            {
                var ipOptionsDataArray = new byte[packetData.Count - 8];
                Array.Copy(packetData.Array, packetData.Offset + 8, ipOptionsDataArray, 0, packetData.Count - 8);
                udpData = new ArraySegment<byte>(ipOptionsDataArray);
            }

            var udpDatagram = new UdpDatagram
            {
                PacketHeader = ipPacket.PacketHeader,
                UdpDatagramHeader = udpDatagramHeader,
                UdpData = udpData,
                ReceivedTime = ipPacket.ReceivedTime
            };

            return udpDatagram;
        }
Пример #3
0
        private bool IsDestinationListenEndpoint(byte[] Buffer, out IpPacket packet)
        {
            var upacket = new UdpDatagram(Buffer);

            packet = upacket;
            if (packet.Protocol != ProtocolType.Udp)
            {
                return(false);
            }

            return(upacket.DestinationIpAddress.Equals(ListenEndPoint.Address) && upacket.DestinationPort == ListenEndPoint.Port);
        }
Пример #4
0
 /// <summary>
 /// Takes a UDP Datagram object and encodes the UDP header for transmission on the network. Assumes UDP checksum is computed.
 /// </summary>
 /// <param name="Input">Datagram object to encode.</param>
 /// <returns>UDP header encoded in network order.</returns>
 public static byte[] UdpHeaderToWireBytes(this UdpDatagram Input)
 {
     //udp header is 8 bytes
     using (var outPacket = new MemoryStream())
     {
         outPacket.Write(BitConverter.GetBytes(NetworkOrderUshort(Input.SourcePort)), 0, 2);
         outPacket.Write(BitConverter.GetBytes(NetworkOrderUshort(Input.DestinationPort)), 0, 2);
         outPacket.Write(BitConverter.GetBytes(NetworkOrderUshort(Input.UdpLength)), 0, 2);
         outPacket.Write(BitConverter.GetBytes(NetworkOrderUshort(Input.UdpCheckSum)), 0, 2); //should be zero if we haven't calculated it yet.
         return(outPacket.ToArray());
     }
 }
Пример #5
0
        /// <summary>
        /// Creates an instance of a Log object.
        /// </summary>
        /// <param name="ReceivedPacket">An UdpDatagram object generated on data received on a Raw socket. </param>
        /// <param name="Parser">A regular expression that will be used to parse the internal message of the Log.</param>
        public Syslog(UdpDatagram ReceivedPacket, Regex Parser)
            : base(ReceivedPacket)
        {
            if (Protocol != ProtocolType.Udp)
            {
                throw new NotSupportedException("Datagrams other than UDP not supported to generate Syslogs.");
            }

            string LogMessage = Encoding.ASCII.GetString(UdpData);

            if (string.IsNullOrWhiteSpace(LogMessage))
            {
                throw new ArgumentOutOfRangeException("Incoming UDP datagram contained no Syslog data.");
            }

            Match defMatch    = DefaultParser.Match(LogMessage);
            var   privalMatch = defMatch.Groups["PRIVAL"].Value.Trim();

            if (!string.IsNullOrWhiteSpace(privalMatch))
            {
                var prival = int.Parse(privalMatch);
                LogSeverity = (Severity)Enum.ToObject(typeof(Severity), prival & 0x7);
                LogFacility = (Facility)Enum.ToObject(typeof(Facility), prival >> 3);
                Message     = defMatch.Groups["MESSAGE"].Value.Trim();
            }
            else
            {
                throw new ArgumentOutOfRangeException(
                          "Datagram does not contain the correct string indicating the PRIVAL of the Syslog");
            }

            if (SetRegex(Parser))
            {
                NamedCollectedMatches = new Dictionary <string, Group>(StringComparer.OrdinalIgnoreCase);

                //support needed for other encoding per IETF RFC.
                Match matchMe = this.Parser.Match(LogMessage);
                if (matchMe.Groups.Count < 1)
                {
                    throw new Exception("Only no parsable fields in the incoming Syslog");
                }

                foreach (var groupName in Parser.GetGroupNames())
                {
                    if (string.IsNullOrEmpty(matchMe.Groups[groupName].Value))
                    {
                        continue;
                    }
                    NamedCollectedMatches.Add(groupName, matchMe.Groups[groupName]);
                }
            }
        }
Пример #6
0
 /// <summary>
 /// Takes an UDPDatagram object and encodes it for transmission on the network in a byte array. Includes computing checksums.
 /// </summary>
 /// <param name="Input">UdpDatagram object for encoding.</param>
 /// <returns>Network order byte array with IP and UDP checksums included ready to send on a raw socket.</returns>
 public static byte[] ToWirebytes(this UdpDatagram Input)
 {
     using (var builderStream = new MemoryStream())
     {
         var ipHeader = PacketHeaderToWireBytes(Input);
         builderStream.Write(ipHeader, 0, ipHeader.Length);
         var udpCk = GetUdpCheckSum(Input);
         Input.UdpCheckSum = NetworkOrderUshort(udpCk);
         builderStream.Write(UdpHeaderToWireBytes(Input), 0, 8); //bytes now in network order here
         builderStream.Write(Input.UdpData, 0, Input.UdpData.Length);
         return(builderStream.ToArray());
     }
 }
Пример #7
0
        /// <summary>
        /// From a UDP datagram object, creates the UDP pseudoheader that is used to compute the UDP checksum per RFC 768
        /// </summary>
        /// <param name="Input">The datagram object to use in encoding</param>
        /// <returns>Byte array of the pseudo header in Network Order</returns>
        public static byte[] UdpPseudoHeader(this UdpDatagram Input)
        {
            byte   Zeroes    = 0;
            byte   Protocol  = Input.ProtocolNumber;
            ushort UDPLength = Input.UdpLength;

            using (MemoryStream builder = new MemoryStream())
            {
                builder.Write(Input.SourceIpAddress.GetAddressBytes(), 0, 4);
                builder.Write(Input.DestinationIpAddress.GetAddressBytes(), 0, 4);
                builder.WriteByte(Zeroes);
                builder.WriteByte(Input.ProtocolNumber);
                builder.Write(BitConverter.GetBytes(NetworkOrderUshort(Input.UdpLength)), 0, 2);
                return(builder.ToArray());
            }
        }
Пример #8
0
        /// <summary>
        /// Uses the UDP Pseudoheader, UDP Header, and UDP payload to compute the checksum used in UDP transmission, per RFC 768
        /// </summary>
        /// <param name="Input">The UdpDatagram object to check</param>
        /// <returns>16bit integer sum in network order.</returns>
        public static ushort GetUdpCheckSum(this UdpDatagram Input)
        {
            using (var udpCk = new MemoryStream())
            {
                var udpPh = UdpPseudoHeader(Input);
                udpCk.Write(udpPh, 0, udpPh.Length);

                udpCk.Write(BitConverter.GetBytes(NetworkOrderUshort(Input.SourcePort)), 0, 2);
                udpCk.Write(BitConverter.GetBytes(NetworkOrderUshort(Input.DestinationPort)), 0, 2);
                udpCk.Write(BitConverter.GetBytes(NetworkOrderUshort(Input.UdpLength)), 0, 2);
                udpCk.WriteByte(0);
                udpCk.WriteByte(0);

                udpCk.Write(Input.UdpData, 0, Input.UdpData.Length);

                return(GetInternetChecksum(udpCk.ToArray()));
            }
        }
Пример #9
0
        static void UdpPackets()
        {
            Console.WriteLine("\n======================= {0} =======================\n", MethodInfo.GetCurrentMethod().Name);

            var packets = PcapNg.ReadForward(fileName)
                .Where(b => b.Type == BlockType.EnhancedPacketBlock)
                .Cast<EnhancedPacketBlock>()
                .Take(5);

            foreach (var packet in packets)
            {
                int ipLen = packet.PacketData.Length - 14; // 14 is the size of the Ethernet header

                byte[] datagram = new byte[ipLen];
                Array.Copy(packet.PacketData, 14, datagram, 0, ipLen);

                UdpDatagram udp = new UdpDatagram(datagram);

                Console.WriteLine(udp.PacketData.ToHexDump());
                Console.WriteLine();
            }
        }
Пример #10
0
        /// <summary>
        /// Creates an instance of a Log object.
        /// </summary>
        /// <param name="ReceivedPacket">An UdpDatagram object generated on data received on a Raw socket. </param>
        /// <param name="Parser">A regular expression that will be used to parse the internal message of the Log.</param>
        public Syslog(UdpDatagram ReceivedPacket, Regex Parser) : base(ReceivedPacket)
        {
            if (Protocol != ProtocolType.Udp)
            {
                throw new NotSupportedException("Datagrams other than UDP not supported to generate Syslogs.");
            }

            string LogMessage = Encoding.ASCII.GetString(UdpData);

            if (string.IsNullOrWhiteSpace(LogMessage))
            {
                throw new ArgumentOutOfRangeException("Incoming UDP datagram contained no Syslog data.");
            }

            Match defMatch = DefaultParser.Match(LogMessage);
            var privalMatch = defMatch.Groups["PRIVAL"].Value.Trim();

            if (!string.IsNullOrWhiteSpace(privalMatch))
            {
                var prival = int.Parse(privalMatch);
                LogSeverity = (Severity)Enum.ToObject(typeof(Severity), prival & 0x7);
                LogFacility = (Facility)Enum.ToObject(typeof(Facility), prival >> 3);
                Message = defMatch.Groups["MESSAGE"].Value.Trim();
            }
            else
            {
                throw new ArgumentOutOfRangeException("Datagram does not contain the correct string indicating the PRIVAL of the Syslog");
            }

            if (SetRegex(Parser))
            {
                NamedCollectedMatches = new Dictionary<string, Group>(StringComparer.OrdinalIgnoreCase);

                //support needed for other encoding per IETF RFC.
                Match matchMe = this.Parser.Match(LogMessage);
                if (matchMe.Groups.Count < 1) throw new Exception("Only no parsable fields in the incoming Syslog");

                foreach (var groupName in Parser.GetGroupNames())
                {
                    if (string.IsNullOrEmpty(matchMe.Groups[groupName].Value)) continue;
                    NamedCollectedMatches.Add(groupName, matchMe.Groups[groupName]);
                }
            }
        }