Beispiel #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);
            }
        }
Beispiel #2
0
 /// <summary>
 /// Private constructor used for deserialization.
 /// </summary>
 private IpPacket(IpVersion version, byte ihl, byte dscp, ushort totalLength,
                  ushort identification, IpFlag flags, ushort fragmentOffset,
                  byte ttl, IpProtocol protocol, ushort checksum, IpAddress source,
                  IpAddress destination)
 {
     destination.ThrowIfNull("destination");
     source.ThrowIfNull("source");
     if (ihl > 0x0F)
     {
         throw new ArgumentException("The Internet Header Length field must " +
                                     "be in the range from 0 to 15.", nameof(ihl));
     }
     if (fragmentOffset > 0x1FFF)
     {
         throw new ArgumentException("The Fragment Offset field must be in " +
                                     "the range from 0 to 8191.", nameof(fragmentOffset));
     }
     Version        = version;
     Ihl            = ihl;
     Dscp           = dscp;
     TotalLength    = totalLength;
     Identification = identification;
     Flags          = flags;
     FragmentOffset = fragmentOffset;
     TimeToLive     = ttl;
     Protocol       = protocol;
     Checksum       = checksum;
     Source         = source;
     Destination    = destination;
     Data           = new byte[0];
 }
Beispiel #3
0
 /// <summary>
 /// Initializes a new instance of the IpPacket class using the specified
 /// values.
 /// </summary>
 /// <param name="destination">The IPv4 address of the destination
 /// host.</param>
 /// <param name="source">The IPv4 address of the sending host.</param>
 /// <param name="type">The type of the transport protocol encapsulated in
 /// the IP packet's data section.</param>
 /// <param name="fragmentOffset">The fragment offset of the packet.</param>
 /// <param name="data">The transport data to transfer as part of the IP
 /// packet.</param>
 /// <param name="ihl">The Internet Header Length.</param>
 /// <param name="dscp">The Differentiated Services Code Point.</param>
 /// <param name="ttl">The time-to-live of the IP packet.</param>
 /// <param name="identification">The idenfication used for uniquely identifying
 /// fragments of a fragmented IP packet.</param>
 /// <param name="flags">The flags set on the IP packet.</param>
 /// <exception cref="ArgumentNullException">Thrown if any of the arguments
 /// is null.</exception>
 public IpPacket(IpAddress destination, IpAddress source,
                 IpProtocol type, byte ihl, byte dscp, byte ttl, ushort identification,
                 IpFlag flags, ushort fragmentOffset, byte[] data)
 {
     destination.ThrowIfNull("destination");
     source.ThrowIfNull("source");
     data.ThrowIfNull("data");
     if (ihl > 0x0F)
     {
         throw new ArgumentException("The Internet Header Length field must " +
                                     "be in the range from 0 to 15.", nameof(ihl));
     }
     if (fragmentOffset > 0x1FFF)
     {
         throw new ArgumentException("The Fragment Offset field must be in " +
                                     "the range from 0 to 8191.", nameof(fragmentOffset));
     }
     Version        = IpVersion.Ipv4;
     Ihl            = ihl;
     Dscp           = dscp;
     Identification = identification;
     Flags          = flags;
     FragmentOffset = fragmentOffset;
     TimeToLive     = ttl;
     Protocol       = type;
     Source         = source;
     Destination    = destination;
     Data           = data;
     TotalLength    = (ushort)(20 + Data.Length);
     Checksum       = ComputeChecksum(this);
 }
Beispiel #4
0
 /// <summary>
 /// Sends the specified ICMP packet to the specified destination host.
 /// </summary>
 /// <param name="ifc">The interface through which the ICMP packet
 /// should be sent.</param>
 /// <param name="destination">The IP address of the destination host
 /// of the ICMP packet.</param>
 /// <param name="packet">The ICMP packet to send.</param>
 /// <exception cref="ArgumentNullException">Thrown if any of the arguments
 /// is null.</exception>
 void SendIcmp(Interface ifc, IpAddress destination, IcmpPacket packet)
 {
     ifc.ThrowIfNull("ifc");
     destination.ThrowIfNull("destination");
     packet.ThrowIfNull("packet");
     Simulation.WriteLine(OutputLevel.Icmp, ifc.FullName + " is queueing a " +
                          packet.Type + " ICMP packet to " + destination, ConsoleColor.Magenta);
     Output(ifc, destination, packet.Serialize(), IpProtocol.Icmp);
 }
Beispiel #5
0
 /// <summary>
 /// Initializes a new instance of the IpPacket class using the specified
 /// values.
 /// </summary>
 /// <param name="destination">The IPv4 address of the destination
 /// host.</param>
 /// <param name="source">The IPv4 address of the sending host.</param>
 /// <param name="type">The type of the transport protocol encapsulated in
 /// the IP packet's data section.</param>
 /// <param name="data">The transport data to transfer as part of the IP
 /// packet.</param>
 /// <exception cref="ArgumentNullException">Thrown if any of the arguments
 /// is null.</exception>
 public IpPacket(IpAddress destination, IpAddress source,
                 IpProtocol type, byte[] data)
 {
     destination.ThrowIfNull("destination");
     source.ThrowIfNull("source");
     data.ThrowIfNull("data");
     Destination = destination;
     Source      = source;
     Protocol    = type;
     Data        = data;
     TimeToLive  = 64;
     Ihl         = 5;
     TotalLength = (ushort)(20 + Data.Length);
     Version     = IpVersion.Ipv4;
     Checksum    = ComputeChecksum(this);
 }
Beispiel #6
0
        /// <summary>
        /// Wraps the specified higher-level data into IP packets and
        /// transmits them to the specified destination.
        /// </summary>
        /// <param name="ifc">The interface through which to output the data.</param>
        /// <param name="destination">The logical address of the destination
        /// host.</param>
        /// <param name="data">The higher-level data to transmit.</param>
        /// <param name="type">The type of the higher-level data.</param>
        /// <exception cref="ArgumentNullException">Thrown if any of the arguments
        /// is null.</exception>
        /// <remarks>This API is exposed to the next higher-up layer.</remarks>
        public void Output(Interface ifc, IpAddress destination, byte[] data,
                           IpProtocol type)
        {
            ifc.ThrowIfNull("ifc");
            destination.ThrowIfNull("destination");
            data.ThrowIfNull("data");
            // Construct IP packets of the size of the MTU of the data-link.
            var maxDataSize = ifc.MaximumTransmissionUnit - 20;
            var numPackets  = (int)Math.Ceiling(data.Length / (double)maxDataSize);
            var sameSubnet  = (destination & ifc.Netmask) == (ifc.IpAddress & ifc.Netmask);

            for (int i = 0, index = 0; i < numPackets; i++)
            {
                var numBytes   = Math.Min(maxDataSize, data.Length - index);
                var packetData = new byte[numBytes];
                Array.Copy(data, index, packetData, 0, numBytes);
                index = index + numBytes;
                // Construct the packet.
                var packet = new IpPacket(destination, ifc.IpAddress, type, packetData);
                // If source and destination are in the same subnet, we can deliver the
                // packet directly. Otherwise send it to the configured default gateway.
                Output(ifc, sameSubnet ? destination : ifc.Gateway, packet);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Initializes the interface.
        /// </summary>
		/// <param name="nic">The network interface card (NIC) this interface
		/// represents.</param>
		/// <param name="name">A unique name (such as eth0) for identifing the
		/// interface.</param>
		/// <param name="ipAddress">The IPv4 address to associate with this
		/// interface.</param>
		/// <param name="netmask">The subnetmask to assign to this interface.</param>
		/// <param name="gateway">The IPv4 address of the default gateway to
		/// configure this interface with.</param>
		void Init(Nic nic, string name, IpAddress ipAddress, IpAddress netmask,
			IpAddress gateway) {
			nic.ThrowIfNull("nic");
			name.ThrowIfNull("name");
			ipAddress.ThrowIfNull("ipAddress");
			netmask.ThrowIfNull("netmask");
			Nic = nic;
			Name = name;
			IpAddress = ipAddress;
			Netmask = netmask;
			Gateway = gateway;
			Nic.Interrupt += OnInterrupt;
		}
Beispiel #8
0
		/// <summary>
		/// Private constructor used for deserialization.
		/// </summary>
		private IpPacket(IpVersion version, byte ihl, byte dscp, ushort totalLength,
			ushort identification, IpFlag flags, ushort fragmentOffset,
			byte ttl, IpProtocol protocol, ushort checksum, IpAddress source,
			IpAddress destination) {
			destination.ThrowIfNull("destination");
			source.ThrowIfNull("source");
			if (ihl > 0x0F)
				throw new ArgumentException("The Internet Header Length field must " +
					"be in the range from 0 to 15.", nameof(ihl));
			if (fragmentOffset > 0x1FFF)
				throw new ArgumentException("The Fragment Offset field must be in " +
					"the range from 0 to 8191.", nameof(fragmentOffset));
			Version = version;
			Ihl = ihl;
			Dscp = dscp;
			TotalLength = totalLength;
			Identification = identification;
			Flags = flags;
			FragmentOffset = fragmentOffset;
			TimeToLive = ttl;
			Protocol = protocol;
			Checksum = checksum;
			Source = source;
			Destination = destination;
			Data = new byte[0];
		}
Beispiel #9
0
        /// <summary>
        /// Initializes a new instance of the IpPacket class using the specified
        /// values.
        /// </summary>
        /// <param name="destination">The IPv4 address of the destination
        /// host.</param>
        /// <param name="source">The IPv4 address of the sending host.</param>
        /// <param name="type">The type of the transport protocol encapsulated in
        /// the IP packet's data section.</param>
        /// <param name="fragmentOffset">The fragment offset of the packet.</param>
        /// <param name="data">The transport data to transfer as part of the IP
        /// packet.</param>
        /// <param name="ihl">The Internet Header Length.</param>
        /// <param name="dscp">The Differentiated Services Code Point.</param>
        /// <param name="ttl">The time-to-live of the IP packet.</param>
        /// <param name="identification">The idenfication used for uniquely identifying
        /// fragments of a fragmented IP packet.</param>
        /// <param name="flags">The flags set on the IP packet.</param>
        /// <exception cref="ArgumentNullException">Thrown if any of the arguments
        /// is null.</exception>
        public IpPacket(IpAddress destination, IpAddress source,
			IpProtocol type, byte ihl, byte dscp, byte ttl, ushort identification,
			IpFlag flags, ushort fragmentOffset, byte[] data) {
			destination.ThrowIfNull("destination");
			source.ThrowIfNull("source");
			data.ThrowIfNull("data");
			if (ihl > 0x0F)
				throw new ArgumentException("The Internet Header Length field must " +
					"be in the range from 0 to 15.", nameof(ihl));
			if (fragmentOffset > 0x1FFF)
				throw new ArgumentException("The Fragment Offset field must be in " +
					"the range from 0 to 8191.", nameof(fragmentOffset));
			Version = IpVersion.Ipv4;
			Ihl = ihl;
			Dscp = dscp;
			Identification = identification;
			Flags = flags;
			FragmentOffset = fragmentOffset;
			TimeToLive = ttl;
			Protocol = type;
			Source = source;
			Destination = destination;
			Data = data;
			TotalLength = (ushort) (20 + Data.Length);
			Checksum = ComputeChecksum(this);
		}
Beispiel #10
0
		/// <summary>
		/// Initializes a new instance of the IpPacket class using the specified
		/// values.
		/// </summary>
		/// <param name="destination">The IPv4 address of the destination
		/// host.</param>
		/// <param name="source">The IPv4 address of the sending host.</param>
		/// <param name="type">The type of the transport protocol encapsulated in
		/// the IP packet's data section.</param>
		/// <param name="data">The transport data to transfer as part of the IP
		/// packet.</param>
		/// <exception cref="ArgumentNullException">Thrown if any of the arguments
		/// is null.</exception>
		public IpPacket(IpAddress destination, IpAddress source,
			IpProtocol type, byte[] data) {
				destination.ThrowIfNull("destination");
				source.ThrowIfNull("source");
				data.ThrowIfNull("data");
				Destination = destination;
				Source = source;
				Protocol = type;
				Data = data;
				TimeToLive = 64;
				Ihl = 5;
				TotalLength = (ushort) (20 + Data.Length);
				Version = IpVersion.Ipv4;
				Checksum = ComputeChecksum(this);
        }