private async Task ReceiveRequest(byte[] buffer, IPEndPoint remoteEndPoint) { DhcpData dhcpData = new DhcpData(remoteEndPoint, buffer); DhcpMessage dhcpMessage = ParseRequest(dhcpData, PacketSerializer, MessageSerializer); await HandleRequest(dhcpMessage).ConfigureAwait(false); }
public override bool Matches(byte[] duid, byte iatype, long iaid, DhcpMessage requestMsg) { bool rc = false; if (prefixBinding != null) { if (iatype == IdentityAssoc.PD_TYPE) { if (Array.Equals(duid, prefixBinding.duid.hexValue)) { if (prefixBinding.iaid == 0) { return(true); } else { if (iaid == prefixBinding.iaid) { return(true); } } } } } return(rc); }
public void Request(DhcpMessage requestMessage) { PresentedName = requestMessage.HostName ?? PresentedName; if (State == DhcpState.Forbidden) { AddEvent(new DhcpRequestRejectedEvent(this, requestMessage)); } var clientOffer = requestMessage.ClientIPAddress; if (requestMessage.Options.TryGetValue(DhcpMessage.DhcpOptionCode.RequestedIpAddress, out var requestedIpAddress)) { clientOffer = new IPAddress(requestedIpAddress); } if (clientOffer.Equals(ClientAddress)) { State = DhcpState.Accepted; AddEvent(new DhcpRequestAcceptedEvent(this, requestMessage)); } else { AddEvent(new DhcpRequestRejectedEvent(this, requestMessage)); } }
private async Task HandleRequest(DhcpMessage message) { if (message.OperationCode == DhcpOperation.BootRequest) { switch (message.DhcpMessageType) { case DhcpMessageType.Discover: Log.Debug($"[DISCOVER] Message Received From '{message.HostName}'"); await this.DhcpDiscover(message).ConfigureAwait(false); Log.Debug("[DISCOVER] Message Processed."); break; case DhcpMessageType.Request: Log.Debug($"[REQUEST] Message Received From '{message.HostName}'"); await this.DhcpRequest(message).ConfigureAwait(false); Log.Debug("[REQUEST] Message Processed."); break; case DhcpMessageType.Unknown: Log.Warn("Unknown DHCP message type. Ignoring."); break; default: Log.Debug($"Unhandled Dhcp Message ({message.DhcpMessageType}) Received, Ignoring."); break; } } else { Log.Debug("Message came in, but it was not a BootRequest. Ignoring."); } }
public override bool Matches(byte[] duid, byte iatype, long iaid, DhcpMessage requestMsg) { bool rc = false; if (addressBinding != null) { if (iatype == this.iaType) { if (Array.Equals(duid, addressBinding.duid)) { //if (!addressBinding.isSetIaid()) { if (addressBinding.iaid == 0) { return(true); } else { if (iaid == addressBinding.iaid) { return(true); } } } } } return(rc); }
/** * Build a BindingAddress for the given InetAddress and DhcpLink. * * @param inetAddr the inet addr * @param clientLink the client link * @param requestMsg the request msg * * @return the binding address */ protected override BindingObject BuildBindingObject(IPAddress inetAddr, DhcpLink clientLink, DhcpMessage requestMsg) { V6AddressBindingPool bp = (V6AddressBindingPool)FindBindingPool(clientLink.GetLink(), inetAddr, requestMsg); if (bp != null) { bp.SetUsed(inetAddr); // TODO check if this is necessary IaAddress iaAddr = new IaAddress(); iaAddr.SetIpAddress(inetAddr); V6BindingAddress bindingAddr = new V6BindingAddress(iaAddr, bp); SetBindingObjectTimes(bindingAddr, bp.GetPreferredLifetimeMs(), bp.GetPreferredLifetimeMs()); // TODO store the configured options in the persisted binding? // bindingAddr.setDhcpOptions(bp.getDhcpOptions()); return(bindingAddr); } else { log.Error("Failed to create BindingAddress: No BindingPool found for IP=" + inetAddr.ToString()); } // MUST have a BindingPool, otherwise something's broke return(null); }
private async Task DhcpRequest(DhcpMessage message) { await _requestLock.WaitAsync().ConfigureAwait(false); try { // Client specified an address they would like if (message.Options.ContainsKey(DhcpOptionCode.RequestedIpAddress)) { await KeepAddressRequest(message).ConfigureAwait(false); } else { var clientAddress = message.ClientIPAddress; if (clientAddress.Equals(IPAddress.Parse("0.0.0.0"))) { // A DHCP REQ should have an address throw new Exception("A DHCP Request must have an address specified"); } await LeaseManager.AddLease(clientAddress, message.ClientHardwareAddress, message.HostName) .ConfigureAwait(false); await this.SendAck(message, clientAddress).ConfigureAwait(false); } } catch (Exception ex) { Log.Error(ex.Message); } _requestLock.Release(); }
private async Task KeepAddressRequest(DhcpMessage message) { var addressRequestData = message.Options[DhcpOptionCode.RequestedIpAddress]; var addressRequest = new IPAddress(addressRequestData); Log.Debug($"[REQUEST] {message.ClientHardwareAddress} has requested to keep it's IP Address '{addressRequest}'"); if (addressRequest.IsInSameSubnet(Configuration.StartIpAddress, Configuration.SubnetMask) == false) { Log.Debug($"[REQUEST] {message.ClientHardwareAddress} request for '{addressRequest}' has been DENIED due to subnet mismatch"); await this.SendNak(message, addressRequest).ConfigureAwait(false); return; } var keepReservationResponse = await LeaseManager.KeepLeaseRequest(addressRequest, message.ClientHardwareAddress, message.HostName); if (keepReservationResponse) { await this.SendAck(message, addressRequest).ConfigureAwait(false); Log.Debug($"[REQUEST] {message.ClientHardwareAddress} has been approved!"); return; } await this.SendNak(message, addressRequest).ConfigureAwait(false); Log.Debug($"[REQUEST] {message.ClientHardwareAddress} has been DENIED."); }
/// <summary> /// Update an existing static binding. /// </summary> /// <param name="binding">existing client binding</param> /// <param name="clientLink">link for the client request message</param> /// <param name="duid">DUID of the client</param> /// <param name="iatype">IA type of the client request</param> /// <param name="iaid">IAID of the client request</param> /// <param name="staticBinding">static binding</param> /// <param name="requestMsg">client request message</param> /// <returns>updated Binding</returns> protected Binding UpdateStaticBinding(Binding binding, DhcpLink clientLink, byte[] duid, byte iatype, long iaid, StaticBinding staticBinding, DhcpMessage requestMsg) { List <IaAddress> addIaAddresses = null; List <IaAddress> updateIaAddresses = null; List <IaAddress> delIaAddresses = null; // not used currently if (staticBinding != null) { _log.Info("Updating static binding: " + binding); HashSet <BindingObject> bindingObjs = binding.GetBindingObjects(); if ((bindingObjs != null) && bindingObjs.Count > 0) { foreach (BindingObject bindingObj in bindingObjs) { if (bindingObj.GetIpAddress().Equals(staticBinding.GetIpAddress())) { SetBindingObjectTimes(bindingObj, staticBinding.GetPreferredLifetimeMs(), staticBinding.GetPreferredLifetimeMs()); break; } //TODO: what about bindingObjs that do NOT match the static binding? } // the existing IaAddress binding objects will be updated updateIaAddresses = binding.GetIaAddresses(); } else { IPAddress inetAddr = staticBinding.GetInetAddress(); if (inetAddr != null) { BindingObject bindingObj = BuildStaticBindingObject(inetAddr, staticBinding); bindingObjs = new HashSet <BindingObject>(); bindingObjs.Add(bindingObj); binding.SetBindingObjects(bindingObjs); // this new IaAddress binding object will be added addIaAddresses = binding.GetIaAddresses(); } } } else { _log.Error("StaticBindingObject is null"); } binding.SetState(IaAddress.STATIC); try { iaMgr.UpdateIA(binding, addIaAddresses, updateIaAddresses, delIaAddresses); return(binding); // if we get here, it worked } catch (Exception ex) { _log.Error("Failed to update binding"); return(null); } }
private async Task DhcpDiscover(DhcpMessage message) { var addressRequest = await LeaseManager.GetNextLease() .ConfigureAwait(false); await this.SendOffer(message, addressRequest) .ConfigureAwait(false); }
public static DhcpMessage AddAddressTime(this DhcpMessage message, int seconds) { var bytes = BitConverter.GetBytes(seconds); Array.Reverse(bytes); message.Options[DhcpMessage.DhcpOptionCode.AddressTime] = bytes; return(message); }
public Binding FindCurrentBinding(DhcpLink clientLink, DhcpV6ClientIdOption clientIdOption, DhcpV6IaPdOption iaPdOption, DhcpMessage requestMsg) { byte[] duid = clientIdOption.GetDuid(); long iaid = iaPdOption.GetIaId(); return(base.FindCurrentBinding(clientLink, duid, IdentityAssoc.PD_TYPE, iaid, requestMsg)); }
public Binding FindCurrentBinding(DhcpLink clientLink, byte[] macAddr, DhcpMessage requestMsg) { lock (_lock) { return(base.FindCurrentBinding(clientLink, macAddr, IdentityAssoc.V4_TYPE, 0, requestMsg)); } }
/// <summary> /// Create a binding in from a StaticBinding /// </summary> /// <param name="clientLink">link for the client request message</param> /// <param name="duid">DUID of the client</param> /// <param name="iatype">IA type of the client request</param> /// <param name="iaid">IAID of the client request</param> /// <param name="staticBinding">static binding</param> /// <param name="requestMsg">client request message</param> /// <returns>created Binding</returns> protected Binding CreateStaticBinding(DhcpLink clientLink, byte[] duid, byte iatype, long iaid, StaticBinding staticBinding, DhcpMessage requestMsg) { Binding binding = null; if (staticBinding != null) { binding = BuildBinding(clientLink, duid, iatype, iaid, IaAddress.STATIC); IPAddress inetAddr = staticBinding.GetInetAddress(); if (inetAddr != null) { IaAddress iaAddr = new IaAddress(); iaAddr.SetIpAddress(inetAddr); iaAddr.SetState(IaAddress.STATIC); V6BindingAddress bindingAddr = new V6BindingAddress(iaAddr, staticBinding); SetBindingObjectTimes(bindingAddr, staticBinding.GetPreferredLifetimeMs(), staticBinding.GetPreferredLifetimeMs()); // TODO store the configured options in the persisted binding? // bindingAddr.setDhcpOptions(bp.getDhcpOptions()); HashSet <BindingObject> bindingObjs = new HashSet <BindingObject>(); bindingObjs.Add(bindingAddr); binding.SetBindingObjects(bindingObjs); try { iaMgr.CreateIA(binding); } catch (Exception ex) { _log.Error("Failed to create persistent binding"); return(null); } } else { _log.Error("Failed to build binding object(s)"); return(null); } } else { _log.Error("StaticBinding object is null"); } String bindingType = (iatype == IdentityAssoc.V4_TYPE) ? "discover" : "solicit"; if (binding != null) { _log.Info("Created static " + bindingType + " binding: " + binding.ToString()); } else { _log.Warn("Failed to create static " + bindingType + " binding"); } return(binding); }
public void DhcpMessage_With_ILoggable() { DhcpMessage dhcpRequestMessage = new DhcpMessage(_iPhoneRequestDhcpMsgBytes, TestLoggerFactory); var logLevel = LogLevel.Debug; using (dhcpRequestMessage.PushLogProperties(logLevel)) { Logger?.LogDebug("TestDhcpRequest_DhcpRequest_With_ILoggable by {LogLevel}", logLevel); } }
public void DhcpMessage_With_None() { DhcpMessage dhcpRequestMessage = new DhcpMessage(_iPhoneRequestDhcpMsgBytes, TestLoggerFactory); var logLevel = LogLevel.None; using (Logger?.PushLogProperties( dhcpRequestMessage.GetLogPropertyListLevel(logLevel, LoggableFormat.ToLogWithParents), logLevel)) { Logger?.LogDebug("DhcpRequest_With_None by {LogLevel}", logLevel); } }
public void DhcpMessage_FormatPropertyList() { DhcpMessage dhcpRequestMessage = new DhcpMessage(_bcDenDiscoverDhcpMsgBytes, TestLoggerFactory); var logLevel = LogLevel.Trace; var sb = new StringBuilder(); PureLogPropertyLevel.FormatPropertyList(sb, LoggableFormat.ToLogWithParents, dhcpRequestMessage.GetLogPropertyListLevel(logLevel, LoggableFormat.ToStringWithParents), logLevel); TestOutputHelper.WriteLine(sb.ToString()); }
public static DhcpMessage AddMessageType(this DhcpMessage message, NetworkDevice.DhcpState type) { switch (type) { case NetworkDevice.DhcpState.Accepted: return(message.AddMessageType(DhcpMessage.DhcpMessageType.Ack)); case NetworkDevice.DhcpState.Offered: return(message.AddMessageType(DhcpMessage.DhcpMessageType.Offer)); } return(message); }
public void DhcpMessage_With() { DhcpMessage dhcpRequestMessage = new DhcpMessage(_iPhoneRequestDhcpMsgBytes, TestLoggerFactory); var logLevel = LogLevel.Debug; using (Logger?.PushLogProperties( dhcpRequestMessage.GetLogPropertyListLevel(logLevel, LoggableFormat.ToLogWithParents), logLevel)) { Logger?.LogDebug("DhcpRequest_With by {LogLevel}", logLevel); } TestOutputHelper.WriteLine(Environment.NewLine + dhcpRequestMessage); }
private DhcpPacket SetClientHardwareAddressFields(DhcpPacket packet, DhcpMessage message) { var addressBytes = message.ClientHardwareAddress.GetAddressBytes(); var addressLength = addressBytes.Length; byte[] chAddressArray = new byte[16]; addressBytes.CopyTo(chAddressArray, 0); packet.CHAddr = chAddressArray; packet.HLen = (byte)addressLength; return(packet); }
/** * Get the Requested IP addresses from the client message, if any was provided. * * @param requestMsg the request msg * * @return a list of InetAddresses containing the requested IP, or null if none requested or * if the requested IP is bogus */ private List <IPAddress> GetInetAddrs(DhcpMessage requestMsg) { List <IPAddress> inetAddrs = new List <IPAddress>(); DhcpV4RequestedIpAddressOption reqIpOption = (DhcpV4RequestedIpAddressOption) requestMsg.GetDhcpOption(DhcpConstants.V4OPTION_REQUESTED_IP); if (reqIpOption != null) { IPAddress inetAddr = IPAddress.Parse(reqIpOption.GetIpAddress()); inetAddrs = new List <IPAddress>(); inetAddrs.Add(inetAddr); } return(inetAddrs); }
public void TestDhcpOptionTypeMap(byte[] dhcpMessageBytes) { DhcpMessage dhcpRequestMessage = new DhcpMessage(dhcpMessageBytes, TestLoggerFactory); var maxLength = dhcpRequestMessage.DhcpOptionKeys().MaxStringLength() + 2; foreach (var dhcpOption in dhcpRequestMessage.DhcpOptionKeys()) { var dhcpOptionString = DhcpOptionTypeMap.GetDhcpOptionString(dhcpOption, dhcpRequestMessage.GetOptionData(dhcpOption), DhcpOptionTypeMap.DhcpRequestListFormat.StringCommaSeparated, Logger); TestOutputHelper.WriteLine($"{dhcpOption.ToString().PadWithDelim(": ", maxLength)}{dhcpOptionString}"); } }
/** * Instantiates a new ddns updater. * * @param requestMsg the request msg * @param clientLink the client link * @param bindingAddr the binding addr * @param fqdn the fqdn * @param doForwardUpdate the do forward update * @param isDelete the is delete */ public DdnsUpdater(DhcpMessage requestMsg, link clientLink, DhcpConfigObject configObj, IPAddress addr, string fqdn, byte[] duid, long lifetime, bool doForwardUpdate, bool isDelete, DdnsCallback callback) { this.requestMsg = requestMsg; this.duid = duid; this.clientLink = clientLink; this.configObj = configObj; this.addr = addr; this.fqdn = fqdn; this.lifetime = lifetime; this.doForwardUpdate = doForwardUpdate; this.isDelete = isDelete; this.callback = callback; }
public override bool Matches(byte[] duid, byte iatype, long iaid, DhcpMessage requestMsg) { bool rc = false; if (addressBinding != null) { if (iatype == IdentityAssoc.V4_TYPE) { if (Array.Equals(duid, addressBinding.chaddr)) { return(true); } } } return(rc); }
public Binding UpdateBinding(Binding binding, DhcpLink clientLink, byte[] macAddr, DhcpMessage requestMsg, byte state) { StaticBinding staticBinding = FindStaticBinding(clientLink.GetLink(), macAddr, IdentityAssoc.V4_TYPE, 0, requestMsg); if (staticBinding != null) { return(base.UpdateStaticBinding(binding, clientLink, macAddr, IdentityAssoc.V4_TYPE, 0, staticBinding, requestMsg)); } else { return(base.UpdateBinding(binding, clientLink, macAddr, IdentityAssoc.V4_TYPE, 0, GetInetAddrs(requestMsg), requestMsg, state, null)); } }
/** * Create a Binding given an IdentityAssoc loaded from the database. * * @param ia the ia * @param clientLink the client link * @param requestMsg the request msg * * @return the binding */ protected override Binding BuildBindingFromIa(IdentityAssoc ia, DhcpLink clientLink, DhcpMessage requestMsg) { Binding binding = new Binding(ia, clientLink); List <IaAddress> iaAddrs = ia.GetIaAddresses(); if ((iaAddrs != null) && iaAddrs.Count > 0) { List <IaAddress> bindingAddrs = new List <IaAddress>(); foreach (IaAddress iaAddr in iaAddrs) { if (!clientLink.GetSubnet().Contains(iaAddr.GetIpAddress())) { log.Info("Ignoring off-link binding address: " + iaAddr.GetIpAddress().ToString()); continue; } V4BindingAddress bindingAddr = null; StaticBinding staticBinding = FindStaticBinding(clientLink.GetLink(), ia.GetDuid(), ia.GetIatype(), ia.GetIaid(), requestMsg); if (staticBinding != null) { bindingAddr = BuildV4StaticBindingFromIaAddr(iaAddr, staticBinding); } else { bindingAddr = BuildV4BindingAddressFromIaAddr(iaAddr, clientLink.GetLink(), requestMsg); } if (bindingAddr != null) { bindingAddrs.Add(bindingAddr); } } // replace the collection of IaAddresses with BindingAddresses binding.SetIaAddresses(bindingAddrs); } else { log.Warn("IA has no addresses, binding is empty."); } return(binding); }
private async Task SendNak(DhcpMessage message, IPAddress requestedAddress) { Log.Debug("[NAK] Creating the negative acknowledgement"); message.OperationCode = DhcpOperation.BootReply; message.YourIPAddress = requestedAddress; message.ServerIPAddress = DhcpInterfaceAddress; var optionBuilder = new DhcpOptionBuilder(); optionBuilder.AddOption(DhcpOptionCode.DhcpMessageType, DhcpMessageType.Nak); var packet = MessageSerializer.ToPacket(message, optionBuilder.GetBytes()); await this.SendReply(packet).ConfigureAwait(false); Log.Debug($"[NAK] IP Address '{requestedAddress}' was sent over '{IPAddress.Broadcast}'"); }
/** * Create a Binding given an IdentityAssoc loaded from the database. * * @param ia the ia * @param clientLink the client link * @param requestMsg the request msg * * @return the binding */ protected override Binding BuildBindingFromIa(IdentityAssoc ia, DhcpLink clientLink, DhcpMessage requestMsg) { Binding binding = new Binding(ia, clientLink); List <IaAddress> iaPrefs = ia.GetIaAddresses(); if ((iaPrefs != null) && iaPrefs.Count > 0) { List <IaAddress> bindingPrefixes = new List <IaAddress>(); foreach (IaAddress iaAddr in iaPrefs) { // off-link check needed only for v4? // if (!clientLink.getSubnet().contains(iaAddr.getIpAddress())) { // log.info("Ignoring off-link binding address: " + // iaAddr.getIpAddress().getHostAddress()); // continue; // } V6BindingPrefix bindingPrefix = null; StaticBinding staticBinding = FindStaticBinding(clientLink.GetLink(), ia.GetDuid(), ia.GetIatype(), ia.GetIaid(), requestMsg); if (staticBinding != null) { bindingPrefix = BuildV6BindingPrefixFromIaPrefix((IaPrefix)iaAddr, staticBinding); } else { bindingPrefix = BuildBindingAddrFromIaPrefix((IaPrefix)iaAddr, clientLink.GetLink(), requestMsg); } if (bindingPrefix != null) { bindingPrefixes.Add(bindingPrefix); } } // replace the collection of IaPrefixes with BindingPrefixes binding.SetIaAddresses(bindingPrefixes); } else { log.Warn("IA has no prefixes, binding is empty."); } return(binding); }
static void Main(string[] args) { Int32 sessionId = (Int32)DateTime.Now.Ticks; using (Socket dhcpClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { dhcpClientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); dhcpClientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1); dhcpClientSocket.Bind(new IPEndPoint(IPAddress.Parse("0.0.0.0"), 68)); DhcpMessage discoverMessage = new DhcpMessage(); discoverMessage.SessionId = sessionId; discoverMessage.Operation = DhcpOperation.BootRequest; discoverMessage.Hardware = HardwareType.Ethernet; discoverMessage.Flags = 128; Byte[] physicalAddr = NetworkInterface.GetAllNetworkInterfaces()[0].GetPhysicalAddress().GetAddressBytes(); discoverMessage.ClientHardwareAddress = physicalAddr; discoverMessage.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Discover); Byte[] clientId = new Byte[physicalAddr.Length + 1]; clientId[0] = (Byte)1; physicalAddr.CopyTo(clientId, 1); discoverMessage.AddOption(DhcpOption.AutoConfig, 1); discoverMessage.AddOption(DhcpOption.Hostname, Encoding.ASCII.GetBytes(Environment.MachineName)); discoverMessage.AddOption(DhcpOption.ClassId, 77, 83, 70, 84, 32, 53, 46, 48); discoverMessage.AddOption(DhcpOption.ClientId, clientId); discoverMessage.AddOption(DhcpOption.ParameterList, 1, 15, 3, 6, 44, 46, 47, 31, 33, 121, 249, 43); dhcpClientSocket.SendTo(discoverMessage.ToArray(), new IPEndPoint(IPAddress.Broadcast, 67)); Byte[] buffer = new Byte[1024]; Int32 len = dhcpClientSocket.Receive(buffer); Byte[] messageData = new Byte[len]; Array.Copy(buffer, messageData, Math.Min(len, buffer.Length)); DhcpMessage responseMessage = new DhcpMessage(messageData); Console.ReadLine(); } }
public void Discover(DhcpMessage discoverMessage) { PresentedName = discoverMessage.HostName ?? PresentedName; if (State == DhcpState.Offered && UpdateTime.AddSeconds(10) > DateTime.Now) { return; } if (State == DhcpState.Forbidden) { AddEvent(new DhcpRequestRejectedEvent(this, discoverMessage)); } else { UpdateTime = DateTime.Now; State = DhcpState.Offered; AddEvent(new DhcpRequestAcceptedEvent(this, discoverMessage)); } }