/// <summary> /// Adds the specified item. /// An item which cannot be associated with an interface will be ignored. /// </summary> /// <param name="dhItem">The item to add.</param> public void AddToPool(DHCPPoolItem dhItem) { if (dhItem.Address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) { throw new ArgumentException("Only IPv4 is supported at the moment"); } foreach (IPInterface ipi in GetInterfacesForAddress(dhItem.Address)) { DHCPPool dhPool = GetPoolForInterface(ipi); DHCPPoolItem dhPoolItem = new DHCPPoolItem(dhItem.Address, dhItem.Netmask, dhItem.Gateway, dhItem.DNSServer); AddPoolItem(dhPoolItem, dhPool, ipi); } }
/// <summary> /// Creates a pool from the given parameters /// </summary> /// <param name="ipaStart">The start address of the pool range</param> /// <param name="ipaEnd">The end address of the pool range</param> /// <param name="ipi">The IP idnterface to which this pool should be associated</param> /// <param name="iAddrCounter">The index of the address of the interface to use if the interface has multiple IP addresses assigned</param> protected virtual void CreatePool(IPAddress ipaStart, IPAddress ipaEnd, IPInterface ipi, int iAddrCounter) { if (ipaStart.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork || ipaEnd.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) { throw new ArgumentException("Only IPv4 is supported at the moment"); } DHCPPool dhPool = GetPoolForInterface(ipi); IPAddress[] ipRange = IPAddressAnalysis.GetIPRange(ipaStart, ipaEnd); foreach (IPAddress ipa in ipRange) { IPInterface ipiInterface = ipi; IPAddress ipAddress = ipa; IPAddress ipGateway; Subnetmask smMask = ipi.Subnetmasks[iAddrCounter]; IPAddress ipDnsServer = IPAddress.Any; if (ipaGateway == null) { ipGateway = ipi.IpAddresses[iAddrCounter]; } else { ipGateway = ipaGateway; } if (ipaDNSServer == null) { ipDnsServer = ipi.IpAddresses[iAddrCounter]; } else { ipDnsServer = ipaDNSServer; } if (dhPool.GetItemForAddress(ipAddress) == null) { DHCPPoolItem dhPoolItem = new DHCPPoolItem(ipAddress, smMask, ipGateway, ipDnsServer); AddPoolItem(dhPoolItem, dhPool, ipi); } } }
/// <summary> /// Creates a new instance of this class with the given parameters /// </summary> /// <param name="pPool">The pool item associated with the event</param> /// <param name="dhcpItem">The DHCP pool associated with the event</param> /// <param name="ipiInterface">The IP interface associated with the event</param> public DHCPServerEventArgs(DHCPPool pPool, DHCPPoolItem dhcpItem, IPInterface ipiInterface) { this.pPool = pPool; this.dhcpItem = dhcpItem; this.ipiInterface = ipiInterface; }
/// <summary> /// Handles a DHCP frame and sends responses or leases addresses according to its contents /// </summary> /// <param name="dhcFrame">The DHCP frame to handle</param> /// <param name="udpFrame">The UDP frame</param> /// <param name="ipFrame">The IP frame</param> /// <param name="tdf">The traffic description frame</param> /// <param name="fInputFrame">The original root frame</param> protected virtual void HandleDHCPFrame(DHCPFrame dhcFrame, eExNetworkLibrary.UDP.UDPFrame udpFrame, eExNetworkLibrary.IP.IPFrame ipFrame, TrafficDescriptionFrame tdf, Frame fInputFrame) { bool bIsRequest = false; bool bIsDiscover = false; foreach (DHCPTLVItem tlvItem in dhcFrame.GetDHCPTLVItems()) { if (tlvItem.DHCPOptionType == DHCPOptions.DHCPMessageType) { if (dhcFrame.MessageType == DHCPType.BootRequest && (DHCPMessageType)tlvItem.Data[0] == DHCPMessageType.Discover) { bIsDiscover = true; break; } if (dhcFrame.MessageType == DHCPType.BootRequest && (DHCPMessageType)tlvItem.Data[0] == DHCPMessageType.Request && lOpenServerTransactions.Contains(dhcFrame.TransactionID)) { bIsRequest = true; break; } } } if (bIsRequest) { #region Server Process request MACAddress mClientID = dhcFrame.ClientMac; if (tdf != null && tdf.SourceInterface != null) { if (dictInterfacePool.ContainsKey(tdf.SourceInterface)) { IPAddress ipaAddressRequestet = IPAddress.Any; string strHostname = ""; foreach (DHCPTLVItem tlvItemSearch in dhcFrame.GetDHCPTLVItems()) { if (tlvItemSearch.DHCPOptionType == DHCPOptions.AddressRequest) { ipaAddressRequestet = new IPAddress(tlvItemSearch.Data); } if (tlvItemSearch.DHCPOptionType == DHCPOptions.Hostname) { strHostname = ASCIIEncoding.ASCII.GetString(tlvItemSearch.Data); } } DHCPPool dhPool = dictInterfacePool[tdf.SourceInterface]; DHCPPoolItem dhItem = dhPool.GetItemForAddress(ipaAddressRequestet); if (dhItem != null) { IPAddress ipaServer = tdf.SourceInterface.IpAddresses[0]; IPAddress offeredAddress = dhItem.Address; DHCPFrame newDHCPFrame = new DHCPFrame(); newDHCPFrame.ClientAddress = IPAddress.Any; newDHCPFrame.ClientMac = mClientID; newDHCPFrame.Hardwarelen = 6; newDHCPFrame.HardwareType = eExNetworkLibrary.HardwareAddressType.Ethernet; newDHCPFrame.Hops = 0; newDHCPFrame.MessageType = DHCPType.BootReply; newDHCPFrame.OfferedAddress = offeredAddress; newDHCPFrame.RelayAddress = IPAddress.Any; newDHCPFrame.RequestedFile = ""; newDHCPFrame.RequestedServerName = ""; newDHCPFrame.Secs = dhcFrame.Secs + 1; newDHCPFrame.ServerAddress = ipaServer; newDHCPFrame.ValidIPFlag = true; newDHCPFrame.TransactionID = dhcFrame.TransactionID; DHCPTLVItem tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.DHCPMessageType; tlvItem.Data = new byte[] { (byte)DHCPMessageType.ACK }; newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.ClientID; byte[] bIDData = new byte[7]; bIDData[0] = (byte)HardwareAddressType.Ethernet; mClientID.AddressBytes.CopyTo(bIDData, 1); tlvItem.Data = bIDData; newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.SubnetMask; tlvItem.Data = dhItem.Netmask.MaskBytes; newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.Router; tlvItem.Data = dhItem.Gateway.GetAddressBytes(); newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.DomainNameServer; tlvItem.Data = dhItem.DNSServer.GetAddressBytes(); newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.LeaseTime; tlvItem.Data = BitConverter.GetBytes(iLeaseDuration); newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.DHCPServerID; tlvItem.Data = ipaServer.GetAddressBytes(); newDHCPFrame.AddDHCPTLVItem(tlvItem); UDP.UDPFrame newUDPFrame = new eExNetworkLibrary.UDP.UDPFrame(); newUDPFrame.DestinationPort = iDHCPInPort; newUDPFrame.SourcePort = iDHCPOutPort; newUDPFrame.EncapsulatedFrame = newDHCPFrame; IP.IPv4Frame newIPv4Frame = new eExNetworkLibrary.IP.IPv4Frame(); newIPv4Frame.Version = 4; newIPv4Frame.DestinationAddress = IPAddress.Broadcast; newIPv4Frame.SourceAddress = ipaServer; newIPv4Frame.Protocol = eExNetworkLibrary.IP.IPProtocol.UDP; newIPv4Frame.EncapsulatedFrame = newUDPFrame; newIPv4Frame.Identification = (uint)IncrementIPIDCounter(); newIPv4Frame.TimeToLive = 128; TrafficDescriptionFrame tdFrame = new TrafficDescriptionFrame(null, DateTime.Now); tdFrame.EncapsulatedFrame = newIPv4Frame; tdf.SourceInterface.Send(tdFrame, IPAddress.Broadcast); dhItem.LeasedTo = mClientID; dhItem.LeasedToHostname = strHostname; dhItem.LeaseDuration = new TimeSpan(0, 0, 0, iLeaseDuration, 0); lOpenServerTransactions.Remove(newDHCPFrame.TransactionID); InvokeAddressLeased(new DHCPServerEventArgs(dhPool, dhItem, tdf.SourceInterface)); } } } #endregion } else if (bIsDiscover) { #region Server Process discover MACAddress mClientID = dhcFrame.ClientMac; if (tdf != null && tdf.SourceInterface != null) { if (dictInterfacePool.ContainsKey(tdf.SourceInterface)) { DHCPPool dhPool = dictInterfacePool[tdf.SourceInterface]; DHCPPoolItem dhItem = dhPool.GetNextFreeAddress(); if (dhItem != null) { IPAddress ipaServer = tdf.SourceInterface.IpAddresses[0]; IPAddress offeredAddress = dhItem.Address; DHCPFrame newDHCPFrame = new DHCPFrame(); newDHCPFrame.ClientAddress = IPAddress.Any; newDHCPFrame.ClientMac = mClientID; newDHCPFrame.Hardwarelen = 6; newDHCPFrame.HardwareType = eExNetworkLibrary.HardwareAddressType.Ethernet; newDHCPFrame.Hops = 0; newDHCPFrame.MessageType = DHCPType.BootReply; newDHCPFrame.OfferedAddress = offeredAddress; newDHCPFrame.RelayAddress = IPAddress.Any; newDHCPFrame.RequestedFile = ""; newDHCPFrame.RequestedServerName = ""; newDHCPFrame.Secs = dhcFrame.Secs + 1; newDHCPFrame.ServerAddress = ipaServer; newDHCPFrame.ValidIPFlag = true; newDHCPFrame.TransactionID = dhcFrame.TransactionID; DHCPTLVItem tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.DHCPMessageType; tlvItem.Data = new byte[] { (byte)DHCPMessageType.Offer }; newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.ClientID; byte[] bIDData = new byte[7]; bIDData[0] = (byte)HardwareAddressType.Ethernet; mClientID.AddressBytes.CopyTo(bIDData, 1); tlvItem.Data = bIDData; newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.SubnetMask; tlvItem.Data = dhItem.Netmask.MaskBytes; newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.Router; tlvItem.Data = dhItem.Gateway.GetAddressBytes(); newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.DomainNameServer; tlvItem.Data = dhItem.DNSServer.GetAddressBytes(); newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.LeaseTime; tlvItem.Data = BitConverter.GetBytes(86400); newDHCPFrame.AddDHCPTLVItem(tlvItem); tlvItem = new DHCPTLVItem(); tlvItem.DHCPOptionType = DHCPOptions.DHCPServerID; tlvItem.Data = ipaServer.GetAddressBytes(); newDHCPFrame.AddDHCPTLVItem(tlvItem); UDP.UDPFrame newUDPFrame = new eExNetworkLibrary.UDP.UDPFrame(); newUDPFrame.DestinationPort = iDHCPInPort; newUDPFrame.SourcePort = iDHCPOutPort; newUDPFrame.EncapsulatedFrame = newDHCPFrame; IP.IPv4Frame newIPv4Frame = new eExNetworkLibrary.IP.IPv4Frame(); newIPv4Frame.Version = 4; newIPv4Frame.DestinationAddress = IPAddress.Broadcast; newIPv4Frame.SourceAddress = ipaServer; newIPv4Frame.Protocol = eExNetworkLibrary.IP.IPProtocol.UDP; newIPv4Frame.EncapsulatedFrame = newUDPFrame; newIPv4Frame.Identification = (uint)IncrementIPIDCounter(); newIPv4Frame.TimeToLive = 128; TrafficDescriptionFrame tdFrame = new TrafficDescriptionFrame(null, DateTime.Now); tdFrame.EncapsulatedFrame = newIPv4Frame; tdf.SourceInterface.Send(tdFrame, IPAddress.Broadcast); lOpenServerTransactions.Add(newDHCPFrame.TransactionID); } } } #endregion } }
/// <summary> /// Removes a pool item from a pool of an interface /// </summary> /// <param name="dhPoolItem">The pool item to remove</param> /// <param name="dhPool">The DHCP pool from which this item should be removed</param> /// <param name="ipi">The interface to which this pool item is associated (or null if it is unknown)</param> protected void RemovePoolItem(DHCPPoolItem dhPoolItem, DHCPPool dhPool, IPInterface ipi) { dhPool.RemoveFromPool(dhPoolItem); InvokeAddressRemoved(new DHCPServerEventArgs(dhPool, dhPoolItem, ipi)); }
/// <summary> /// Adds a pool item to a pool of an interface /// </summary> /// <param name="dhPoolItem">The pool item to add</param> /// <param name="dhPool">The DHCP pool to which this item should be added</param> /// <param name="ipi">The interface to which this pool item is associated (or null if it is unknown)</param> protected void AddPoolItem(DHCPPoolItem dhPoolItem, DHCPPool dhPool, IPInterface ipi) { dhPool.AddDHCPPoolItem(dhPoolItem); InvokeAddressCreated(new DHCPServerEventArgs(dhPool, dhPoolItem, ipi)); }