Example #1
0
        /// <summary>
        /// Resolves the specified IPv4 destination address to a physical
        /// address and hands the specified IPv4 packet down to the link
        /// layer.
        /// </summary>
        /// <param name="ifc">The interface through which to output the
        /// data.</param>
        /// <param name="destination">The logical address of the destination
        /// host, which can different from the final destination address
        /// contained in the IP packet.</param>
        /// <param name="packet">The IPv4 packet to transmit.</param>
        /// <exception cref="ArgumentNullException">Thrown if any of the arguments
        /// is null.</exception>
        void Output(Interface ifc, IpAddress destination, IpPacket packet)
        {
            ifc.ThrowIfNull("ifc");
            destination.ThrowIfNull("destination");
            packet.ThrowIfNull("packet");
            // Translate IP address into MAC-Address.
            var macDestination = arp.Lookup(ifc, destination);

            // IP address is not in our ARP table.
            if (macDestination == null)
            {
                // Put packet on hold until the MAC-48 destination address has
                // been figured out.
                WaitingPacketsOf(ifc).Add(
                    new Tuple <IpAddress, IpPacket>(destination, packet));
                WriteLine(ifc.FullName + " is putting IP packet on-hold due to pending ARP request.");
                // Schedule a new ARP request.
                arp.Resolve(ifc, destination);
            }
            else
            {
                WriteLine(ifc.FullName + " is queueing IP packet for " + destination);
                Output(ifc, macDestination, packet);
            }
        }
Example #2
0
        /// <summary>
        /// Computes the 16-bit checksum of the specified IPv4 packet.
        /// </summary>
        /// <param name="packet">The packet to compute the checksum for.</param>
        /// <param name="withChecksumField">true to include the packet's
        /// checksum field in the calculation; otherwise false.</param>
        /// <returns>The checksum of the specified IPv4 packet.</returns>
        /// <exception cref="ArgumentNullException">Thrown if the packet
        /// argument is null.</exception>
        public static ushort ComputeChecksum(IpPacket packet,
                                             bool withChecksumField = false)
        {
            packet.ThrowIfNull("packet");
            // The version and IHL fields are 4 bit wide each.
            var vi = (byte)(((packet.Ihl & 0x0F) << 4) |
                            (((int)packet.Version) & 0x0F));
            // The flags field is 3 bits and the fragment offset 13 bits wide.
            var ffo = (ushort)(((packet.FragmentOffset & 0x1FFF) << 3) |
                               ((int)packet.Flags & 0x07));
            var bytes = new ByteBuilder()
                        .Append(vi)
                        .Append(packet.Dscp)
                        .Append(packet.TotalLength)
                        .Append(packet.Identification)
                        .Append(ffo)
                        .Append(packet.TimeToLive)
                        .Append((byte)packet.Protocol)
                        .Append(withChecksumField ? packet.Checksum : (ushort)0)
                        .Append(packet.Source.Bytes)
                        .Append(packet.Destination.Bytes)
                        .ToArray();
            var sum = 0;

            // Treat the header bytes as a sequence of unsigned 16-bit values and
            // sum them up.
            for (var n = 0; n < bytes.Length; n += 2)
            {
                sum += BitConverter.ToUInt16(bytes, n);
            }
            // Use carries to compute the 1's complement sum.
            sum = (sum >> 16) + (sum & 0xFFFF);
            // Return the inverted 16-bit result.
            return((ushort)(~sum));
        }
Example #3
0
		/// <summary>
		/// Computes the 16-bit checksum of the specified IPv4 packet.
		/// </summary>
		/// <param name="packet">The packet to compute the checksum for.</param>
		/// <param name="withChecksumField">true to include the packet's
		/// checksum field in the calculation; otherwise false.</param>
		/// <returns>The checksum of the specified IPv4 packet.</returns>
		/// <exception cref="ArgumentNullException">Thrown if the packet
		/// argument is null.</exception>
		public static ushort ComputeChecksum(IpPacket packet,
			bool withChecksumField = false) {
			packet.ThrowIfNull("packet");
			// The version and IHL fields are 4 bit wide each.
			var vi = (byte) (((packet.Ihl & 0x0F) << 4) |
				(((int) packet.Version) & 0x0F));
			// The flags field is 3 bits and the fragment offset 13 bits wide.
			var ffo = (ushort) (((packet.FragmentOffset & 0x1FFF) << 3) |
				((int) packet.Flags & 0x07));
			var bytes = new ByteBuilder()
				.Append(vi)
				.Append(packet.Dscp)
				.Append(packet.TotalLength)
				.Append(packet.Identification)
				.Append(ffo)
				.Append(packet.TimeToLive)
				.Append((byte) packet.Protocol)
				.Append(withChecksumField ? packet.Checksum : (ushort)0)
				.Append(packet.Source.Bytes)
				.Append(packet.Destination.Bytes)
				.ToArray();
			var sum = 0;
			// Treat the header bytes as a sequence of unsigned 16-bit values and
			// sum them up.
			for (var n = 0; n < bytes.Length; n += 2)
				sum += BitConverter.ToUInt16(bytes, n);
			// Use carries to compute the 1's complement sum.
			sum = (sum >> 16) + (sum & 0xFFFF);
			// Return the inverted 16-bit result.
			return (ushort)(~ sum);
		}