private void SendAck(DhcpMessage message, AddressLease lease) { Trace.TraceInformation("{0} Sending Dhcp Acknowledge.", Thread.CurrentThread.ManagedThreadId); DhcpMessage response = new DhcpMessage(); response.Operation = DhcpOperation.BootReply; response.Hardware = HardwareType.Ethernet; response.HardwareAddressLength = 6; response.SecondsElapsed = message.SecondsElapsed; response.SessionId = message.SessionId; response.AssignedAddress = lease.Address.ToArray(); response.ClientHardwareAddress = message.ClientHardwareAddress; response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Ack); response.AddOption(DhcpOption.AddressRequest, lease.Address.ToArray()); AddDhcpOptions(response); this.SendReply(response); if (OnNewClient != null) { OnNewClient(this, new OnNewDHCPClientEvent(lease.Owner.ToString(), lease.Address)); } Trace.TraceInformation("{0} Dhcp Acknowledge Sent:{1}", Thread.CurrentThread.ManagedThreadId, lease.Address.ToString()); }
private void SendOffer(DhcpMessage message, AddressLease offer) { Trace.TraceInformation("{0} Sending Dhcp Offer.", Thread.CurrentThread.ManagedThreadId); DhcpMessage response = new DhcpMessage(); response.Operation = DhcpOperation.BootReply; response.Hardware = HardwareType.Ethernet; response.HardwareAddressLength = 6; response.SecondsElapsed = message.SecondsElapsed; response.SessionId = message.SessionId; response.Flags = message.Flags; response.AssignedAddress = offer.Address.ToArray(); response.ClientHardwareAddress = message.ClientHardwareAddress; response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Offer); response.AddOption(DhcpOption.AddressRequest, offer.Address.ToArray()); AddDhcpOptions(response); Byte[] paramList = message.GetOptionData(DhcpOption.ParameterList); if (paramList != null) { response.OptionOrdering = paramList; } this.SendReply(response); Trace.TraceInformation("{0} Dhcp Offer Sent.", Thread.CurrentThread.ManagedThreadId); }
private void SendReply(DhcpMessage response) { response.AddOption(DhcpOption.DhcpAddress, this.m_DhcpInterfaceAddress.GetAddressBytes()); Byte[] sessionId = BitConverter.GetBytes(response.SessionId); try { this.m_DhcpSocket.SendTo(response.ToArray(), new IPEndPoint(IPAddress.Broadcast, DhcpClientPort)); } catch (Exception ex) { TraceException("Error Sending Dhcp Reply", ex); throw; } }
private void SendNak(DhcpMessage message) { Trace.TraceInformation("{0} Sending Dhcp Negative Acknowledge.", Thread.CurrentThread.ManagedThreadId); DhcpMessage response = new DhcpMessage(); response.Operation = DhcpOperation.BootReply; response.Hardware = HardwareType.Ethernet; response.HardwareAddressLength = 6; response.SecondsElapsed = message.SecondsElapsed; response.SessionId = message.SessionId; response.ClientHardwareAddress = message.ClientHardwareAddress; response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Nak); this.SendReply(response); Trace.TraceInformation("{0} Dhcp Negative Acknowledge Sent.", Thread.CurrentThread.ManagedThreadId); }
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(); } }
private void AddDhcpOptions(DhcpMessage response) { response.AddOption(DhcpOption.AddressTime, DhcpMessage.ReverseByteOrder(BitConverter.GetBytes((Int32)this.m_LeaseDuration.TotalSeconds))); response.AddOption(DhcpOption.Router, this.m_Gateway.ToArray()); response.AddOption(DhcpOption.SubnetMask, this.m_Subnet.ToArray()); if (!String.IsNullOrEmpty(this.m_DnsSuffix)) { response.AddOption(DhcpOption.DomainNameSuffix, Encoding.ASCII.GetBytes(this.m_DnsSuffix)); } if (this.m_DnsServers.Count > 0) { Byte[] dnsServerAddresses = new Byte[this.m_DnsServers.Count * 4]; for (Int32 i = 0; i < this.m_DnsServers.Count; i++) { this.m_DnsServers[i].ToArray().CopyTo(dnsServerAddresses, i * 4); } response.AddOption(DhcpOption.DomainNameServer, dnsServerAddresses); } }
private void SendAck(DhcpMessage message, AddressLease lease) { Trace.TraceInformation("{0} Sending Dhcp Acknowledge.", Thread.CurrentThread.ManagedThreadId); DhcpMessage response = new DhcpMessage(); response.Operation = DhcpOperation.BootReply; response.Hardware = HardwareType.Ethernet; response.HardwareAddressLength = 6; response.SecondsElapsed = message.SecondsElapsed; response.SessionId = message.SessionId; response.AssignedAddress = lease.Address.ToArray(); response.ClientHardwareAddress = message.ClientHardwareAddress; response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Ack); response.AddOption(DhcpOption.AddressRequest, lease.Address.ToArray()); AddDhcpOptions(response); this.SendReply(response); if (OnNewClient != null) OnNewClient(this, new OnNewDHCPClientEvent(lease.Owner.ToString(), lease.Address)); Trace.TraceInformation("{0} Dhcp Acknowledge Sent:{1}", Thread.CurrentThread.ManagedThreadId, lease.Address.ToString()); }
private void DhcpRequest(DhcpMessage message) { Byte[] addressRequestData = message.GetOptionData(DhcpOption.AddressRequest); if (addressRequestData == null) { addressRequestData = message.ClientAddress; } InternetAddress addressRequest = new InternetAddress(addressRequestData); if (addressRequest.IsEmpty) { this.SendNak(message); return; } // Assume we're on an ethernet network Byte[] hardwareAddressData = new Byte[6]; Array.Copy(message.ClientHardwareAddress, hardwareAddressData, 6); PhysicalAddress clientHardwareAddress = new PhysicalAddress(hardwareAddressData); AddressLease assignment = null; Boolean ack = false; // If this client is explicitly allowed, or they are not denied and the allow any flag is set if (this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_Acl[clientHardwareAddress] || !this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_AllowAny) { if (this.m_Reservations.ContainsKey(clientHardwareAddress)) { assignment = new AddressLease(clientHardwareAddress, this.m_Reservations[clientHardwareAddress], DateTime.Now.Add(this.m_LeaseDuration)); if (addressRequest.Equals(assignment.Address)) { ack = true; } } else { lock (this.m_LeaseSync) { if (this.m_ActiveLeases.ContainsKey(addressRequest) && (this.m_ActiveLeases[addressRequest].Owner.Equals(clientHardwareAddress) || this.m_ActiveLeases[addressRequest].SessionId == message.SessionId)) { assignment = this.m_ActiveLeases[addressRequest]; assignment.Acknowledged = true; assignment.Owner = clientHardwareAddress; assignment.Expiration = DateTime.Now.Add(this.m_LeaseDuration); ack = true; } } } } if (ack) { this.SendAck(message, assignment); } else { this.SendNak(message); } }
private void DhcpDiscover(DhcpMessage message) { Byte[] addressRequestData = message.GetOptionData(DhcpOption.AddressRequest); if (addressRequestData == null) { addressRequestData = message.ClientAddress; } InternetAddress addressRequest = new InternetAddress(addressRequestData); // Assume we're on an ethernet network Byte[] hardwareAddressData = new Byte[6]; Array.Copy(message.ClientHardwareAddress, hardwareAddressData, 6); PhysicalAddress clientHardwareAddress = new PhysicalAddress(hardwareAddressData); AddressLease offer = null; // If this client is explicitly allowed, or they are not denied and the allow any flag is set if (this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_Acl[clientHardwareAddress] || !this.m_Acl.ContainsKey(clientHardwareAddress) && this.m_AllowAny) { if (this.m_Reservations.ContainsKey(clientHardwareAddress)) { offer = new AddressLease(clientHardwareAddress, this.m_Reservations[clientHardwareAddress], DateTime.Now.Add(this.m_LeaseDuration)); } else { lock (this.m_LeaseSync) { if (!addressRequest.Equals(InternetAddress.Empty)) { if (this.m_InactiveLeases.ContainsKey(addressRequest)) { offer = this.m_InactiveLeases[addressRequest]; this.m_InactiveLeases.Remove(addressRequest); this.m_ActiveLeases.Add(addressRequest, offer); } else if (this.m_ActiveLeases.ContainsKey(addressRequest) && this.m_ActiveLeases[addressRequest].Owner.Equals(clientHardwareAddress)) { offer = this.m_ActiveLeases[addressRequest]; } } else if (this.m_InactiveLeases.Count > 0) { offer = this.m_InactiveLeases.Values[0]; this.m_InactiveLeases.Remove(offer.Address); this.m_ActiveLeases.Add(offer.Address, offer); } } } } if (offer == null) { this.SendNak(message); } else { offer.Acknowledged = false; offer.Expiration = DateTime.Now.Add(this.m_OfferTimeout); offer.SessionId = message.SessionId; offer.Owner = clientHardwareAddress; this.SendOffer(message, offer); } }
private void CompleteRequest(Object state) { DhcpData messageData = (DhcpData)state; EndPoint source = new IPEndPoint(0, 0); this.m_AbortLock.AcquireReaderLock(-1); try { if (this.m_Abort) { return; } messageData.BufferSize = this.m_DhcpSocket.EndReceiveFrom(messageData.Result, ref source); messageData.Source = (IPEndPoint)source; } catch (ArgumentException ex) { Trace.TraceInformation("DHCP: "+ex.Message); return; } finally { this.m_AbortLock.ReleaseLock(); } DhcpMessage message; try { message = new DhcpMessage(messageData); } catch (ArgumentException ex) { TraceException("Error Parsing Dhcp Message", ex); return; } catch (InvalidCastException ex) { TraceException("Error Parsing Dhcp Message", ex); return; } catch (IndexOutOfRangeException ex) { TraceException("Error Parsing Dhcp Message", ex); return; } catch (Exception ex) { TraceException("Error Parsing Dhcp Message", ex); throw; } if (message.Operation == DhcpOperation.BootRequest) { Byte[] messageTypeData = message.GetOptionData(DhcpOption.DhcpMessageType); if (messageTypeData != null && messageTypeData.Length == 1) { DhcpMessageType messageType = (DhcpMessageType)messageTypeData[0]; switch (messageType) { case DhcpMessageType.Discover: Trace.TraceInformation("{0} Dhcp DISCOVER Message Received.", Thread.CurrentThread.ManagedThreadId); this.DhcpDiscover(message); Trace.TraceInformation("{0} Dhcp DISCOVER Message Processed.", Thread.CurrentThread.ManagedThreadId); break; case DhcpMessageType.Request: Trace.TraceInformation("{0} Dhcp REQUEST Message Received.", Thread.CurrentThread.ManagedThreadId); this.DhcpRequest(message); Trace.TraceInformation("{0} Dhcp REQUEST Message Processed.", Thread.CurrentThread.ManagedThreadId); break; default: Trace.TraceWarning("Unknown Dhcp Message ({0}) Received, Ignoring.", messageType.ToString()); break; } } else { Trace.TraceWarning("Unknown Dhcp Data Received, Ignoring."); } } }
private void CompleteRequest(Object state) { DhcpData messageData = (DhcpData)state; EndPoint source = new IPEndPoint(0, 0); this.m_AbortLock.AcquireReaderLock(-1); try { if (this.m_Abort) { return; } messageData.BufferSize = this.m_DhcpSocket.EndReceiveFrom(messageData.Result, ref source); messageData.Source = (IPEndPoint)source; } catch (ArgumentException ex) { Trace.TraceInformation("DHCP: " + ex.Message); return; } finally { this.m_AbortLock.ReleaseLock(); } DhcpMessage message; try { message = new DhcpMessage(messageData); } catch (ArgumentException ex) { TraceException("Error Parsing Dhcp Message", ex); return; } catch (InvalidCastException ex) { TraceException("Error Parsing Dhcp Message", ex); return; } catch (IndexOutOfRangeException ex) { TraceException("Error Parsing Dhcp Message", ex); return; } catch (Exception ex) { TraceException("Error Parsing Dhcp Message", ex); throw; } if (message.Operation == DhcpOperation.BootRequest) { Byte[] messageTypeData = message.GetOptionData(DhcpOption.DhcpMessageType); if (messageTypeData != null && messageTypeData.Length == 1) { DhcpMessageType messageType = (DhcpMessageType)messageTypeData[0]; switch (messageType) { case DhcpMessageType.Discover: Trace.TraceInformation("{0} Dhcp DISCOVER Message Received.", Thread.CurrentThread.ManagedThreadId); this.DhcpDiscover(message); Trace.TraceInformation("{0} Dhcp DISCOVER Message Processed.", Thread.CurrentThread.ManagedThreadId); break; case DhcpMessageType.Request: Trace.TraceInformation("{0} Dhcp REQUEST Message Received.", Thread.CurrentThread.ManagedThreadId); this.DhcpRequest(message); Trace.TraceInformation("{0} Dhcp REQUEST Message Processed.", Thread.CurrentThread.ManagedThreadId); break; default: Trace.TraceWarning("Unknown Dhcp Message ({0}) Received, Ignoring.", messageType.ToString()); break; } } else { Trace.TraceWarning("Unknown Dhcp Data Received, Ignoring."); } } }