public static UdpFrame ParseFrame(IPFrame ip, bool checksum = true) { if (ip == null) { return(null); } UdpFrame frame = null; BufferSegment payload = ip.Payload; payload.UnsafeAddrOfPinnedArrayElement((p) => { udp_hdr *udphdr = (udp_hdr *)p; if (udphdr == null) { return; } if (payload.Length != CheckSum.ntohs(udphdr->len)) // 错误的数据报 { return; } int offset = sizeof(udp_hdr); int len = payload.Length - offset; if (len <= 0) { return; } if (checksum && udphdr->chksum != 0) { uint pseudo_checksum = CheckSum.inet_chksum_pseudo((byte *)p.ToPointer(), (uint)ProtocolType.Udp, (uint)payload.Length, ip.SourceAddressV4, ip.DestinationAddressV4); if (pseudo_checksum != 0) { return; } } BufferSegment message = new BufferSegment(payload.Buffer, payload.Offset + offset, len); frame = new UdpFrame( new IPEndPoint(ip.Source, CheckSum.ntohs(udphdr->src)), new IPEndPoint(ip.Destination, CheckSum.ntohs(udphdr->dest)), message) { Ttl = ip.Ttl, SourceMacAddress = ip.SourceMacAddress, DestinationMacAddress = ip.DestinationMacAddress }; }); return(frame); }
public static IPFrame ToIPFrame(UdpFrame frame) { if (frame == null) { throw new ArgumentNullException(nameof(frame)); } if (frame.AddressFamily != AddressFamily.InterNetwork) { throw new ArgumentNullException("UDP frames of this address family type are not supported."); } if (frame.Payload.Length <= 0) { return(null); } int offset = sizeof(udp_hdr); int payload_len = frame.Payload.Length; byte[] message = new byte[offset + payload_len]; fixed(byte *pinned = message) { udp_hdr *udphdr = (udp_hdr *)pinned; udphdr->dest = CheckSum.htons((ushort)frame.Destination.Port); udphdr->src = CheckSum.htons((ushort)frame.Source.Port); udphdr->len = CheckSum.htons((ushort)message.Length); using (MemoryStream ms = new MemoryStream(message, offset, payload_len)) { ms.Write(frame.Payload.Buffer, frame.Payload.Offset, payload_len); } ushort pseudo_checksum = CheckSum.inet_chksum_pseudo(pinned, (uint)ProtocolType.Udp, (uint)message.Length, IPFrame.GetAddressV4(frame.Source.Address), IPFrame.GetAddressV4(frame.Destination.Address)); if (pseudo_checksum == 0) { pseudo_checksum = 0xffff; } udphdr->chksum = pseudo_checksum; } return(new IPFrame(ProtocolType.Udp, frame.Source.Address, frame.Destination.Address, new BufferSegment(message)) { Ttl = frame.Ttl, SourceMacAddress = frame.SourceMacAddress, DestinationMacAddress = frame.DestinationMacAddress, }); }