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 IcmpFrame ParseFrame(IPFrame ip, bool checksum = true) { if (ip == null) { return(null); } IcmpFrame frame = null; BufferSegment segment = ip.Payload; segment.UnsafeAddrOfPinnedArrayElement(p => { icmp_hdr *icmp = (icmp_hdr *)p; if (checksum && icmp->icmp_chksum != 0) { ushort cksum = CheckSum.inet_chksum(icmp, segment.Length); if (cksum != 0) { return; } } int payload_size = segment.Length - sizeof(icmp_hdr); if (payload_size < 0) { return; } frame = new IcmpFrame(ip.Source, ip.Destination, new BufferSegment(segment.Buffer, segment.Offset + sizeof(icmp_hdr), payload_size)) { Type = (IcmpType)icmp->icmp_type, Code = icmp->icmp_code, Identification = CheckSum.ntohs(icmp->icmp_id), Sequence = CheckSum.ntohs(icmp->icmp_seq), Ttl = ip.Ttl, SourceMacAddress = ip.SourceMacAddress, DestinationMacAddress = ip.DestinationMacAddress, }; }); return(frame); }
public static IPFrame ParseFrame(BufferSegment packet, bool checksum = true) { if (packet == null) { return(null); } IPFrame frame = null; packet.UnsafeAddrOfPinnedArrayElement((payload) => { ip_hdr *iphdr = (ip_hdr *)payload; if (iphdr == null) { return; } if (ip_hdr.IPH_V(iphdr) != 4) { return; } int iphdr_hlen = ip_hdr.IPH_HL(iphdr) << 2; if (iphdr_hlen > packet.Length) { return; } if (iphdr_hlen < IP_HLEN) { return; } int ttl = ip_hdr.IPH_TTL(iphdr); if (ttl <= 0) { return; } if (checksum && iphdr->_chksum != 0) { int cksum = CheckSum.inet_chksum(iphdr, iphdr_hlen); if (cksum != 0) { return; } } if (ip_addr_isbroadcast(iphdr->src) || ip_addr_isbroadcast(iphdr->dest)) { return; } if ((ip_hdr.IPH_OFFSET(iphdr) & CheckSum.ntohs((ushort)(IPFlags.IP_OFFMASK | IPFlags.IP_MF))) != 0) // 不允许IP分片(NAT不太容易处理好分片) { return; } ProtocolType protocolType = (ProtocolType)ip_hdr.IPH_PROTO(iphdr); if (protocolType == (ProtocolType)IP_PROTO_UDP || protocolType == (ProtocolType)IP_PROTO_TCP || protocolType == (ProtocolType)IP_PROTO_ICMP || protocolType == (ProtocolType)IP_PROTO_GRE) { BufferSegment message_data = new BufferSegment(packet.Buffer, packet.Offset + iphdr_hlen, packet.Length - iphdr_hlen); BufferSegment options_data = null; int options_size = (iphdr_hlen - sizeof(ip_hdr)); if (options_size <= 0) { options_data = new BufferSegment(BufferSegment.Empty); } else { options_data = new BufferSegment(packet.Buffer, packet.Offset + sizeof(ip_hdr), options_size); } frame = new IPFrame(protocolType, new IPAddress(iphdr->src), new IPAddress(iphdr->dest), message_data) { Id = CheckSum.ntohs(iphdr->_id), Ttl = ttl, Tos = iphdr->_tos, Options = options_data, Flags = (IPFlags)CheckSum.ntohs(iphdr->_flags), }; } }); return(frame); }
public static TcpFrame ParseFrame(IPFrame ip, bool checksum = true) { if (ip == null) { return(null); } TcpFrame frame = null; BufferSegment packet = ip.Payload; packet.UnsafeAddrOfPinnedArrayElement((p) => { tcp_hdr *tcphdr = (tcp_hdr *)p; if (tcphdr == null) { return; } int hdrlen_bytes = TCPH_HDRLEN_BYTES(tcphdr); if (hdrlen_bytes < TCP_HLEN || hdrlen_bytes > packet.Length) // 错误的数据报 { return; } int len = packet.Length - hdrlen_bytes; if (len < 0) { return; } TcpFlags flags = (TcpFlags)TCPH_FLAGS(tcphdr); if (checksum && tcphdr->chksum != 0) { uint pseudo_checksum = CheckSum.inet_chksum_pseudo((byte *)p.ToPointer(), (uint)ProtocolType.Tcp, (uint)packet.Length, ip.SourceAddressV4, ip.DestinationAddressV4); if (pseudo_checksum != 0) { return; } } long payload_offset = 0; fixed(byte *stream = packet.Buffer) { payload_offset = ((byte *)p + hdrlen_bytes) - stream; } BufferSegment message_data = new BufferSegment(packet.Buffer, unchecked ((int)payload_offset), len); BufferSegment options_data = null; int options_size = hdrlen_bytes - sizeof(tcp_hdr); if (options_size <= 0) { options_data = new BufferSegment(BufferSegment.Empty); } else { options_data = new BufferSegment(packet.Buffer, packet.Offset + sizeof(tcp_hdr), options_size); } frame = new TcpFrame(new IPEndPoint(ip.Source, CheckSum.ntohs(tcphdr->src)), new IPEndPoint(ip.Destination, CheckSum.ntohs(tcphdr->dest)), message_data) { Ttl = ip.Ttl, AcknowledgeNo = CheckSum.ntohl(tcphdr->ackno), SequenceNo = CheckSum.ntohl(tcphdr->seqno), WindowSize = CheckSum.ntohs(tcphdr->wnd), Flags = flags, SourceMacAddress = ip.SourceMacAddress, DestinationMacAddress = ip.DestinationMacAddress, Options = options_data, UrgentPointer = CheckSum.ntohs(tcphdr->urgp) }; }); return(frame); }