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()); }
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)); }
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 }); } }