Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }