/// <summary> /// Initializes a new instance of the Interface class using the specified /// parameters. /// </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> /// <exception cref="ArgumentNullException">Thrown if any of the arguments /// is null.</exception> public Interface(Nic nic, string name, IpAddress ipAddress, IpAddress netmask, IpAddress gateway = null) { Init(nic, name, ipAddress, netmask, gateway); }
/// <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; }
/// <summary> /// Deserializes an IpPacket instance from the specified sequence of /// bytes. /// </summary> /// <param name="data">The sequence of bytes to deserialize an IpPacket /// object from.</param> /// <returns>A deserialized IpPacket object.</returns> /// <exception cref="ArgumentNullException">Thrown if the data argument is /// null.</exception> /// <exception cref="SerializationException">Thrown if the IP packet could /// not be deserialized from the specified byte array.</exception> public static IpPacket Deserialize(byte[] data) { data.ThrowIfNull("data"); using (var ms = new MemoryStream(data)) { using (var reader = new BinaryReader(ms)) { var vi = reader.ReadByte(); var version = (IpVersion)(vi & 0x0F); byte ihl = (byte) (vi >> 4), dscp = reader.ReadByte(); ushort totalLength = reader.ReadUInt16(), identification = reader.ReadUInt16(), ffo = reader.ReadUInt16(); var flags = (IpFlag) (ffo & 0x07); var fragmentOffset = (ushort) (ffo >> 3); var ttl = reader.ReadByte(); var type = (IpProtocol) reader.ReadByte(); var checksum = reader.ReadUInt16(); IpAddress src = new IpAddress(reader.ReadBytes(4)), dst = new IpAddress(reader.ReadBytes(4)); var packet = new IpPacket(version, ihl, dscp, totalLength, identification, flags, fragmentOffset, ttl, type, checksum, src, dst); // Computing the checksum should yield a value of 0 unless errors are // detected. if (ComputeChecksum(packet, true) != 0) throw new SerializationException("The IPv4 header is corrupted."); // If no errors have been detected, read the data section. packet.Data = reader.ReadBytes(totalLength - 20); return packet; } } }
/// <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]; }
/// <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); }
/// <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); }
/// <summary> /// Sends the specified data to the specified destination address through the /// specified local interface. /// </summary> /// <param name="ifName">The name of the local interface to send the data /// through.</param> /// <param name="destination">The IP-address of the destination host.</param> /// <param name="data">The data to transmit.</param> public void Output(string ifName, IpAddress destination, byte[] data) { Network.Output(Interfaces[ifName], destination, data, IpProtocol.Tcp); }