Example #1
0
 private static byte TCPH_HDRLEN_BYTES(tcp_hdr *phdr)
 {
     return((byte)(TCPH_HDRLEN(phdr) << 2));
 }
Example #2
0
 private static byte TCPH_FLAGS(tcp_hdr *phdr)
 {
     return((byte)((CheckSum.ntohs((phdr)->_hdrlen_rsvd_flags) & (byte)TcpFlags.TCP_FLAGS)));
 }
Example #3
0
 private static ushort TCPH_HDRLEN(tcp_hdr *phdr)
 {
     return((ushort)(CheckSum.ntohs((phdr)->_hdrlen_rsvd_flags) >> 12));
 }
Example #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);
        }
Example #5
0
        public static IPFrame ToIPFrame(TcpFrame frame)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            if (frame.AddressFamily != AddressFamily.InterNetwork)
            {
                throw new ArgumentNullException("TCP frames of this address family type are not supported.");
            }

            BufferSegment options_data   = frame.Options;
            int           options_size   = options_data?.Length ?? 0;
            int           payload_offset = sizeof(tcp_hdr) + options_size;
            int           payload_size   = frame.Payload?.Length ?? 0;

            byte[] message = new byte[payload_offset + payload_size];
            fixed(byte *pinned = message)
            {
                tcp_hdr *tcphdr = (tcp_hdr *)pinned;

                tcphdr->dest  = CheckSum.htons((ushort)frame.Destination.Port);
                tcphdr->src   = CheckSum.htons((ushort)frame.Source.Port);
                tcphdr->seqno = CheckSum.htonl(frame.SequenceNo);
                tcphdr->ackno = CheckSum.htonl(frame.AcknowledgeNo);
                tcphdr->urgp  = CheckSum.htons(frame.UrgentPointer);
                tcphdr->wnd   = CheckSum.htons(frame.WindowSize);

                TCPH_HDRLEN_SET(tcphdr, payload_offset >> 2);
                TCPH_FLAGS_SET(tcphdr, (int)frame.Flags);

                if (options_size > 0)
                {
                    IntPtr destination_options = (IntPtr)(pinned + sizeof(tcp_hdr));
                    Marshal.Copy(options_data.Buffer, options_data.Offset, destination_options, options_size);
                }

                if (payload_size > 0)
                {
                    using (MemoryStream ms = new MemoryStream(message, payload_offset, payload_size))
                    {
                        ms.Write(frame.Payload.Buffer, frame.Payload.Offset, payload_size);
                    }
                }

                ushort pseudo_checksum = CheckSum.inet_chksum_pseudo(pinned, (uint)ProtocolType.Tcp, (uint)message.Length,
                                                                     IPFrame.GetAddressV4(frame.Source.Address),
                                                                     IPFrame.GetAddressV4(frame.Destination.Address));

                if (pseudo_checksum == 0)
                {
                    pseudo_checksum = 0xffff;
                }

                tcphdr->chksum = pseudo_checksum;
            }

            return(new IPFrame(ProtocolType.Tcp, frame.Source.Address, frame.Destination.Address, new BufferSegment(message))
            {
                Ttl = frame.Ttl,
                SourceMacAddress = frame.SourceMacAddress,
                DestinationMacAddress = frame.DestinationMacAddress,
            });
        }
Example #6
0
 private static ushort TCPH_FLAGS_SET(tcp_hdr *phdr, int flags)
 {
     return((phdr)->_hdrlen_rsvd_flags = (ushort)(((phdr)->_hdrlen_rsvd_flags &
                                                   PP_HTONS(~(ushort)TcpFlags.TCP_FLAGS)) | CheckSum.htons((ushort)flags)));
 }
Example #7
0
        private static ushort TCPH_HDRLEN_SET(tcp_hdr *phdr, int len)
        {
            var u = ((len) << 12) | TCPH_FLAGS(phdr);

            return((phdr)->_hdrlen_rsvd_flags = CheckSum.htons((ushort)u));
        }