/// <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; }
/// <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); }
/// <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); }
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)); }
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)); }
/// <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); }
/// <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); }
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; } }
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); }
// 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); }
/// <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); }
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 { } }