예제 #1
0
        public static string UDPToDebugString(IPAddress sourceAddr, IPAddress destAddr, UDPFrame frame)
        {
            var sb = new StringBuilder();

            var srcAddrWords = string.Join(" ",
                                           ChecksumFns.DataBytesToShorts(sourceAddr.GetAddressBytes())
                                           .Select(s => $"{s:x4}"));

            sb.AppendLine($"{srcAddrWords} source addr");

            var dstAddrWords = string.Join(" ",
                                           ChecksumFns.DataBytesToShorts(destAddr.GetAddressBytes())
                                           .Select(s => $"{s:x4}"));

            sb.AppendLine($"{dstAddrWords} dst addr");
            sb.AppendLine($"{17:x} protocol");
            sb.AppendLine($"{frame.Header.HeaderAndDataLength:x4} UDP length");
            sb.AppendLine($"{frame.Header.SourcePort:x4} source port");
            sb.AppendLine($"{frame.Header.DestinationPort:x4} dest port");
            sb.AppendLine($"{frame.Header.HeaderAndDataLength:x4} Length");
            sb.AppendLine($"{frame.Header.Checksum:x4} Checksum");
            sb.AppendLine($"DATA ({frame.Data.Length}B):");

            var byteStep = 8;

            for (int i = 0; i < frame.Data.Length; i += byteStep)
            {
                var words    = ChecksumFns.DataBytesToShorts(frame.Data.Skip(i).Take(byteStep).ToArray());
                var wordLine = string.Join(" ", words.Select(s => $"{s:x4}"));
                sb.AppendLine(wordLine);
            }

            return(sb.ToString());
        }
예제 #2
0
        public static ushort UDPChecksum(IPAddress sourceAddress, IPAddress destinationAddress, UDPFrame packet)
        {
            uint checksum = 0;

            checksum += ChecksumFns.SumAsUShorts(sourceAddress.GetAddressBytes());
            checksum += ChecksumFns.SumAsUShorts(destinationAddress.GetAddressBytes());
            checksum += 17;   // protocol udp = 17
            checksum += packet.Header.HeaderAndDataLength;
            checksum += packet.Header.SourcePort;
            checksum += packet.Header.DestinationPort;
            checksum += packet.Header.HeaderAndDataLength;
            checksum += ChecksumFns.SumAsUShorts(packet.Data);
            return(ChecksumFns.FinishChecksum(checksum));
        }
예제 #3
0
        public static IEnumerable <IPv4Frame> IterateFrames(Stream bytes)
        {
            byte[] headerBuffer = new byte[HeaderMinSizeBytes];

            while (bytes.CanRead)
            {
                int bytesRead = bytes.Read(headerBuffer, 0, HeaderMinSizeBytes);

                if (bytesRead != HeaderMinSizeBytes)
                {
                    yield break;
                }

                int internetHeaderLengthBytes = (int)(headerBuffer[0] & 0xf) * 4;
                if (internetHeaderLengthBytes != HeaderMinSizeBytes)
                {
                    throw new NotImplementedException("Header size other than 20 bytes not supported yet");
                }

                // Calculate header validity
                uint sum = 0;
                for (int ushortOffset = 0; ushortOffset < 20; ushortOffset += 2)
                {
                    sum += ByteFns.MakeUshort(headerBuffer[ushortOffset], headerBuffer[ushortOffset + 1]);
                }
                ushort onesComplementSum = ChecksumFns.AddCarryGetUshort(sum);

                int version     = (int)((headerBuffer[0] & 0xf0) >> 4);
                int totalLength = (int)((headerBuffer[2] << 16) | headerBuffer[3]);
                int protocol    = (int)headerBuffer[9];

                byte[] sourceAddressBytes = new byte[4];
                Array.Copy(headerBuffer, 12, sourceAddressBytes, 0, 4);

                byte[] destAddressBytes = new byte[4];
                Array.Copy(headerBuffer, 16, destAddressBytes, 0, 4);

                int optionalBytesToSkip = internetHeaderLengthBytes - HeaderMinSizeBytes;
                bytes.Position = bytes.Position + optionalBytesToSkip;

                int    dataLength = totalLength - internetHeaderLengthBytes;
                byte[] data       = new byte[dataLength];

                int dataBytesRead = bytes.Read(data, 0, dataLength);
                if (dataBytesRead != dataLength)
                {
                    throw new InvalidOperationException($"Could not read {dataLength} data bytes, got only {dataBytesRead}");
                }

                yield return(new IPv4Frame()
                {
                    Header = new IPv4Header()
                    {
                        InternetHeaderLength = internetHeaderLengthBytes,
                        TotalLength = totalLength,
                        SourceAddress = new IPAddress(sourceAddressBytes),
                        DestinationAddress = new IPAddress(destAddressBytes),
                        DatagramProtocol = protocol,
                        ChecksumOK = ((ushort)(onesComplementSum ^ 0xffff) == 0),
                        OnesComplementSum = onesComplementSum
                    },
                    Data = data
                });
            }
        }