Пример #1
0
        /// <summary>
        /// Recalculate the checksum
        /// </summary>
        public override void UpdateCalculatedValues()
        {
            if (skipUpdating)
            {
                return;
            }

            // prevent us from entering this routine twice
            // by setting this flag, the act of retrieving the Bytes
            // property will cause this routine to be called which will
            // retrieve Bytes recursively and overflow the stack
            skipUpdating = true;

            // start with this packet with a zeroed out checksum field
            Checksum = 0;
            var originalBytes = Bytes;

            var ipv6Parent      = ParentPacket as IPv6Packet;
            var bytesToChecksum = ipv6Parent.AttachPseudoIPHeader(originalBytes);

            // calculate the one's complement sum of the tcp header
            Checksum = (ushort)ChecksumUtils.OnesComplementSum(bytesToChecksum);

            // clear the skip variable
            skipUpdating = false;
        }
Пример #2
0
        /// <summary>
        /// Calculates the transport layer checksum, either for the
        /// tcp or udp packet
        /// </summary>
        /// <param name="option">
        ///     <see cref="TransportChecksumOption" />
        /// </param>
        /// <returns>
        /// A <see cref="int" />
        /// </returns>
        internal int CalculateChecksum(TransportChecksumOption option)
        {
            // save the checksum field value so it can be restored, altering the checksum is not
            // an intended side effect of this method
            var originalChecksum = Checksum;

            // reset the checksum field (checksum is calculated when this field is
            // zeroed)
            Checksum = 0;

            // copy the tcp section with data
            var dataToChecksum = ((IPPacket)ParentPacket).PayloadPacket.BytesSegment;

            var bytes = option == TransportChecksumOption.IncludePseudoIPHeader
                ? ((IPPacket)ParentPacket).GetPseudoIPHeader(dataToChecksum.Length)
                : new byte[0];

            // calculate the one's complement sum of the tcp header
            var cs = ChecksumUtils.OnesComplementSum(dataToChecksum, bytes);

            // restore the checksum field value
            Checksum = originalChecksum;

            return(cs);
        }
Пример #3
0
        /// <summary>
        /// Calculates the transport layer checksum, either for the
        /// tcp or udp packet
        /// </summary>
        /// <param name="option"><see cref="TransportPacket.TransportChecksumOption"/></param>
        /// <returns>
        /// A <see cref="System.Int32"/>
        /// </returns>
        internal int CalculateChecksum(TransportChecksumOption option)
        {
            // save the checksum field value so it can be restored, altering the checksum is not
            // an intended side effect of this method
            var originalChecksum = Checksum;

            // reset the checksum field (checksum is calculated when this field is
            // zeroed)
            Checksum = 0;

            // copy the tcp section with data
            byte[] dataToChecksum = ((IpPacket)ParentPacket).PayloadPacket.Bytes;

            if (option == TransportChecksumOption.AttachPseudoIPHeader)
            {
                dataToChecksum = ((IpPacket)ParentPacket).AttachPseudoIPHeader(dataToChecksum);
            }

            // calculate the one's complement sum of the tcp header
            int cs = ChecksumUtils.OnesComplementSum(dataToChecksum);

            // restore the checksum field value
            Checksum = originalChecksum;

            return(cs);
        }
Пример #4
0
 internal int CalculateChecksum(TransportChecksumOption option)
 {
     this.Checksum = 0;
     byte[] bytes = ((IpPacket)this.ParentPacket).PayloadPacket.Bytes;
     if (option == TransportChecksumOption.AttachPseudoIPHeader)
     {
         bytes = ((IpPacket)this.ParentPacket).AttachPseudoIPHeader(bytes);
     }
     return(ChecksumUtils.OnesComplementSum(bytes));
 }
Пример #5
0
        public int CalculateIPChecksum()
        {
            byte[] header           = this.Header;
            byte[] destinationArray = new byte[header.Length];
            Array.Copy(header, destinationArray, header.Length);
            ushort num = 0;

            EndianBitConverter.Big.CopyBytes(num, destinationArray, IPv4Fields.ChecksumPosition);
            return(ChecksumUtils.OnesComplementSum(destinationArray, 0, destinationArray.Length));
        }
Пример #6
0
        /// <summary> Computes the IP checksum, optionally updating the IP checksum header.
        ///
        /// </summary>
        /// <param name="update">Specifies whether or not to update the IP checksum
        /// header after computing the checksum.  A value of true indicates
        /// the header should be updated, a value of false indicates it
        /// should not be updated.
        /// </param>
        /// <returns> The computed IP checksum.
        /// </returns>
        public int ComputeIPChecksum(bool update)
        {
            //copy the ip header
            byte[] ip = ArrayHelper.copy(Bytes, _ethPayloadOffset, IPHeaderLength);
            //reset the checksum field (checksum is calculated when this field is zeroed)
            ArrayHelper.insertLong(ip, 0, IPv4Fields_Fields.IP_CSUM_POS, 2);
            //compute the one's complement sum of the ip header
            int cs = ChecksumUtils.OnesComplementSum(ip, 0, ip.Length);

            if (update)
            {
                IPChecksum = cs;
            }

            return(cs);
        }
Пример #7
0
        /// <summary>
        ///     Calculates the IP checksum, optionally updating the IP checksum header.
        /// </summary>
        /// <returns>
        ///     The calculated IP checksum.
        /// </returns>
        public ushort CalculateIPChecksum()
        {
            //copy the ip header
            var theHeader = this.Header;
            var ip        = new byte[theHeader.Length];

            Array.Copy(theHeader, ip, theHeader.Length);

            //reset the checksum field (checksum is calculated when this field is zeroed)
            var theValue = (UInt16)0;

            EndianBitConverter.Big.CopyBytes(theValue, ip, IPv4Fields.ChecksumPosition);

            //calculate the one's complement sum of the ip header
            var cs = ChecksumUtils.OnesComplementSum(ip, 0, ip.Length);

            return((ushort)cs);
        }
Пример #8
0
        private void updateIPChecksums(ref byte[] data)
        {
            int header_len = (data[IP_HEADER_IHL_OFFSET] & 0x0F) * 4;

            //reset the checksum field (checksum is calculated when this field is zeroed)
            data[IP_HEADER_CHECKSUM_OFFSET]     = 0;
            data[IP_HEADER_CHECKSUM_OFFSET + 1] = 0;
            //calculate the one's complement sum of the ip header
            var val = (UInt16)ChecksumUtils.OnesComplementSum(data, IP_HEADER_IHL_OFFSET, header_len);

            EndianBitConverter.Big.CopyBytes(val, data, IP_HEADER_CHECKSUM_OFFSET);

            // disable UDP checksum
            if (data[IP_HEADER_PROTOCOL_OFFSET] == (byte)IPProtocolType.UDP)
            {
                data[IP_HEADER_IHL_OFFSET + header_len + UDP_HEADER_CHECKSUM_OFFSET]     = 0;
                data[IP_HEADER_IHL_OFFSET + header_len + UDP_HEADER_CHECKSUM_OFFSET + 1] = 0;
            }
        }
Пример #9
0
        public int ComputeTransportLayerChecksum(int checksumOffset, bool update, bool pseudoIPHeader)
        {
            // copy the tcp section with data
            byte[] dataToChecksum = IPData;
            // reset the checksum field (checksum is calculated when this field is
            // zeroed)
            ArrayHelper.insertLong(dataToChecksum, 0, checksumOffset, 2);
            if (pseudoIPHeader)
            {
                dataToChecksum = AttachPseudoIPHeader(dataToChecksum);
            }
            // compute the one's complement sum of the tcp header
            int cs = ChecksumUtils.OnesComplementSum(dataToChecksum);

            if (update)
            {
                SetTransportLayerChecksum(cs, checksumOffset);
            }

            return(cs);
        }
Пример #10
0
        // create multicast IPv6 ping packet
        private EthernetPacket GenerateIpv6Ping()
        {
            var ethernetPacket = new EthernetPacket(physicalAddress, broadcastMAC, EthernetPacketType.Arp);
            var ipv6Packet     = new IPv6Packet(IPAddress.Parse((deviceInfo.IPv6 != string.Empty ? deviceInfo.IPv6 : deviceInfo.LinkLocal)), IPAddress.Parse("ff02::1"));

            ipv6Packet.NextHeader        = IPProtocolType.ICMPV6;
            ethernetPacket.PayloadPacket = ipv6Packet;

            var icmpv6Packet = new ICMPv6Packet(new ByteArraySegment(new byte[40]))
            {
                Type        = ICMPv6Types.EchoRequest,
                PayloadData = Encoding.ASCII.GetBytes("abcdefghijklmnopqrstuvwabcdefghi")
            };

            ipv6Packet.PayloadPacket = icmpv6Packet;

            // ICMPv6 checksum fix
            var pseudo = Network.GetPseudoHeader(ipv6Packet.SourceAddress, ipv6Packet.DestinationAddress, icmpv6Packet.Bytes.Length, 58);

            icmpv6Packet.Checksum = (ushort)(ChecksumUtils.OnesComplementSum(pseudo.Concat(icmpv6Packet.Bytes).ToArray()) + 4);

            return(ethernetPacket);
        }
Пример #11
0
        /// <summary> Computes the UDP checksum, optionally updating the UDP checksum header.
        ///
        /// </summary>
        /// <param name="update">Specifies whether or not to update the UDP checksum header
        /// after computing the checksum. A value of true indicates the
        /// header should be updated, a value of false indicates it should
        /// not be updated.
        /// </param>
        /// <returns> The computed UDP checksum.
        /// </returns>
        public int ComputeUDPChecksum(bool update)
        {
            if (IPVersion != IPVersions.IPv4)
            {
                throw new System.NotImplementedException("IPVersion of " + IPVersion + " is unrecognized");
            }

            // copy the udp section with data
            byte[] udp = IPData;
            // reset the checksum field (checksum is calculated when this field is
            // zeroed)
            ArrayHelper.insertLong(udp, 0, UDPFields_Fields.UDP_CSUM_POS, UDPFields_Fields.UDP_CSUM_LEN);
            //pseudo ip header should be attached to the udp+data
            udp = AttachPseudoIPHeader(udp);
            // compute the one's complement sum of the udp header
            int cs = ChecksumUtils.OnesComplementSum(udp);

            if (update)
            {
                UDPChecksum = cs;
            }

            return(cs);
        }
 public override void UpdateCalculatedValues()
 {
     byte[] dataToChecksum = ((IpPacket)ParentPacket).PayloadPacket.Bytes;
     Checksum = (ushort)ChecksumUtils.OnesComplementSum(dataToChecksum);
 }
Пример #13
0
        private void Ipv6ToIpv4(EthernetPacket orgPacket)
        {
            try
            {
                IPv6Packet ipv6 = (IPv6Packet)orgPacket.PayloadPacket;

                if (ipv6.PayloadPacket is PacketDotNet.ICMPv6Packet)
                {
                    ICMPv6Packet icmp = ipv6.PayloadPacket as ICMPv6Packet;
                    icmp.Type = ICMPv6Types.EchoReply;

                    icmp.UpdateCalculatedValues();
                    icmp.Checksum = (ushort)ChecksumUtils.OnesComplementSum(icmp.Bytes);

                    IPv6Packet ipv6Ack = new IPv6Packet(ipv6.DestinationAddress, ipv6.SourceAddress);
                    ipv6Ack.PayloadPacket = icmp;
                    EthernetPacket eth = new EthernetPacket(orgPacket.DestinationHwAddress, orgPacket.SourceHwAddress, EthernetPacketType.IpV6);
                    eth.PayloadPacket = ipv6Ack;

                    Program.CurrentProject.data.SendPacket(eth);
                }
                else if (ipv6.PayloadPacket is PacketDotNet.TcpPacket)
                {
                    TcpPacket tcp = ipv6.PayloadPacket as TcpPacket;

                    ushort          destPort      = tcp.SourcePort;
                    ushort          sourcePort    = tcp.DestinationPort;
                    IPAddress       destAddress   = ipv6.SourceAddress;
                    IPAddress       sourceAddress = ipv6.DestinationAddress;
                    PhysicalAddress sourceMac     = device.MacAddress;
                    PhysicalAddress destMac       = orgPacket.SourceHwAddress;

                    tcp.SourcePort      = sourcePort;
                    tcp.DestinationPort = destPort;

                    if (tcp.Syn && !tcp.Ack && !tcp.Rst && tcp.PayloadData.Length == 0)
                    {
                        if (sourcePort == 80)
                        {
                            tcp.Ack = true;
                            tcp.AcknowledgmentNumber = tcp.SequenceNumber + 1;
                            tcp.SequenceNumber       = tcp.SequenceNumber + 38;
                            tcp.WindowSize           = 14600;

                            IPv6Packet ipv6Ack = new IPv6Packet(sourceAddress, destAddress);
                            ipv6Ack.PayloadPacket = tcp;

                            EthernetPacket eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6);
                            eth.PayloadPacket = ipv6Ack;

                            (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum();
                            Program.CurrentProject.data.SendPacket(eth);
                        }
                        else if (sourcePort == 443)
                        {
                            tcp.Syn = false;
                            tcp.Ack = true;
                            tcp.Rst = true;
                            tcp.Psh = false;
                            uint ackOrg = tcp.AcknowledgmentNumber;
                            tcp.AcknowledgmentNumber = tcp.SequenceNumber + 1;
                            tcp.SequenceNumber       = 0;
                            tcp.WindowSize           = 0;
                            tcp.PayloadData          = new byte[0];

                            IPv6Packet ipv6Ack = new IPv6Packet(sourceAddress, destAddress);
                            ipv6Ack.PayloadPacket = tcp;
                            EthernetPacket eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6);
                            eth.PayloadPacket = ipv6Ack;
                            (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum();
                            Program.CurrentProject.data.SendPacket(eth);
                        }
                    }
                    else if (!tcp.Syn && tcp.Ack && tcp.PayloadData != null && !tcp.Rst && tcp.PayloadData.Length > 0 && sourcePort == 80)
                    {
                        string element = string.Format("{0}/{1}", tcp.SequenceNumber, tcp.AcknowledgmentNumber);
                        if (!Data.Data.SlaacReqList.Contains(element))
                        {
                            Data.Data.SlaacReqList.Add(element);
                            HttpPacket httpReq = new HttpPacket(tcp.PayloadData);
                            if (httpReq.IsCompleted)
                            {
                                SendHttpResponse(httpReq, orgPacket, tcp.SourcePort, tcp.DestinationPort, tcp.AcknowledgmentNumber, tcp.SequenceNumber + (uint)tcp.PayloadData.Length);
                            }
                            else
                            {
                                lock (htppLock)
                                {
                                    //incomplete packet

                                    TcpReconstructorPacket previousPacket = (from p in Program.CurrentProject.data.ReconstructedPackets
                                                                             where p.ExpectedSequenceNumber == tcp.SequenceNumber
                                                                             select p).FirstOrDefault();


                                    TcpReconstructorPacket nextPacket = (from p in Program.CurrentProject.data.ReconstructedPackets
                                                                         where p.FirstSequenceNumber == tcp.SequenceNumber + tcp.PayloadData.Length
                                                                         select p).FirstOrDefault();

                                    if (nextPacket != null || previousPacket != null)
                                    {
                                        bool packetSend = false;
                                        if (nextPacket != null)
                                        {
                                            nextPacket.InsertPreviousTcpPacket(tcp);
                                            httpReq = new HttpPacket(nextPacket.Data);
                                            if (httpReq.IsCompleted)
                                            {
                                                packetSend = true;
                                                Program.CurrentProject.data.ReconstructedPackets.Remove(nextPacket);
                                                SendHttpResponse(httpReq, orgPacket, tcp.SourcePort, tcp.DestinationPort, tcp.AcknowledgmentNumber, nextPacket.ExpectedSequenceNumber);
                                            }
                                        }
                                        if (previousPacket != null && !packetSend)
                                        {
                                            if (nextPacket != null)
                                            {
                                                previousPacket.AppendTcpPacket(nextPacket);
                                                Program.CurrentProject.data.ReconstructedPackets.Remove(nextPacket);
                                            }
                                            else
                                            {
                                                previousPacket.AppendTcpPacket(tcp);
                                            }

                                            httpReq = new HttpPacket(previousPacket.Data);
                                            if (httpReq.IsCompleted)
                                            {
                                                Program.CurrentProject.data.ReconstructedPackets.Remove(previousPacket);
                                                SendHttpResponse(httpReq, orgPacket, tcp.SourcePort, tcp.DestinationPort, tcp.AcknowledgmentNumber, previousPacket.ExpectedSequenceNumber);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Program.CurrentProject.data.ReconstructedPackets.Add(new TcpReconstructorPacket(tcp));
                                    }


                                    var toDelete = Program.CurrentProject.data.ReconstructedPackets.Where(p => DateTime.Now.Subtract(p.CreationTime).TotalMinutes > 2);
                                    foreach (var item in toDelete)
                                    {
                                        Program.CurrentProject.data.ReconstructedPackets.Remove(item);
                                    }
                                }
                            }
                        }
                    }
                    else if (tcp.Fin && tcp.Ack && !tcp.Rst && tcp.PayloadData.Length == 0)
                    {
                        tcp.Ack = true;
                        tcp.Fin = false;
                        uint ackOrg = tcp.AcknowledgmentNumber;
                        tcp.AcknowledgmentNumber = tcp.SequenceNumber + 1;
                        tcp.SequenceNumber       = ackOrg;
                        tcp.WindowSize           = 1400;

                        IPv6Packet ipv6Ack = new IPv6Packet(sourceAddress, destAddress);
                        ipv6Ack.PayloadPacket = tcp;
                        EthernetPacket eth = new EthernetPacket(sourceMac, destMac, EthernetPacketType.IpV6);
                        eth.PayloadPacket = ipv6Ack;
                        (eth.PayloadPacket.PayloadPacket as TcpPacket).UpdateTCPChecksum();
                        Program.CurrentProject.data.SendPacket(eth);
                    }
                }
            }
            catch
            {
            }
        }