private void SendNak(DhcpMessage message) { Trace.TraceInformation("{0} Sending Dhcp Negative Acknowledge.", Thread.CurrentThread.ManagedThreadId); var response = new DhcpMessage { Operation = DhcpOperation.BootReply, Hardware = HardwareType.Ethernet, HardwareAddressLength = 6, SecondsElapsed = message.SecondsElapsed, SessionId = message.SessionId, ClientHardwareAddress = message.ClientHardwareAddress }; response.AddOption(DhcpOption.DhcpMessageType, (byte) DhcpMessageType.Nak); response.AddOption(DhcpOption.DhcpAddress, _mDhcpInterfaceAddress.GetAddressBytes()); try { var clientIp = response.ClientAddress[0] + "." + response.ClientAddress[1] + "." + response.ClientAddress[2] + "." + response.ClientAddress[3]; _mDhcpSocket.SendTo(response.ToArray(), new IPEndPoint(IPAddress.Parse(clientIp), DhcpClientPort)); } catch (Exception ex) { TraceException("Error Sending Dhcp Reply", ex); return; } Trace.TraceInformation("{0} Dhcp Negative Acknowledge Sent.", Thread.CurrentThread.ManagedThreadId); }
private void SendOffer(DhcpMessage message) { 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; Byte[] hardwareAddressData = new Byte[6]; Array.Copy(message.ClientHardwareAddress, hardwareAddressData, 6); PhysicalAddress clientHardwareAddress = new PhysicalAddress(hardwareAddressData); response.NextServerAddress = this._mDhcpInterfaceAddress.GetAddressBytes(); response.ClientHardwareAddress = message.ClientHardwareAddress; response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Offer); response.AddOption(DhcpOption.ClassId, Encoding.UTF8.GetBytes("PXEClient")); Byte[] paramList = message.GetOptionData(DhcpOption.ParameterList); if (paramList != null) { response.OptionOrdering = paramList; } response.AddOption(DhcpOption.DhcpAddress, this._mDhcpInterfaceAddress.GetAddressBytes()); try { this._mDhcpSocket.SendTo(response.ToArray(), new IPEndPoint(IPAddress.Broadcast, DhcpClientPort)); } catch (Exception ex) { TraceException("Error Sending Dhcp Reply", ex); return; } Trace.TraceInformation("{0} Dhcp Offer Sent.", Thread.CurrentThread.ManagedThreadId); }
private void SendAck(DhcpMessage message) { Trace.TraceInformation("{0} Sending Dhcp Acknowledge.", Thread.CurrentThread.ManagedThreadId); var response = new DhcpMessage { Operation = DhcpOperation.BootReply, Hardware = HardwareType.Ethernet, HardwareAddressLength = 6, SecondsElapsed = message.SecondsElapsed, SessionId = message.SessionId }; var hardwareAddressData = new byte[6]; Array.Copy(message.ClientHardwareAddress, hardwareAddressData, 6); var clientHardwareAddress = new PhysicalAddress(hardwareAddressData); if (_mReservations.ContainsKey(clientHardwareAddress)) { response.NextServerAddress = IPAddress.Parse(_dReservations[clientHardwareAddress].ReserveNextServer).GetAddressBytes(); response.BootFileName = Encoding.UTF8.GetBytes(_dReservations[clientHardwareAddress].ReserveBootFile); } else { response.NextServerAddress = !string.IsNullOrEmpty(UserNextServer) ? IPAddress.Parse(UserNextServer).GetAddressBytes() : _mDhcpInterfaceAddress.GetAddressBytes(); response.BootFileName = Encoding.UTF8.GetBytes(AppleBootFile); } response.ClientAddress = message.ClientAddress; response.ClientHardwareAddress = message.ClientHardwareAddress; response.AddOption(DhcpOption.DhcpMessageType, (byte) DhcpMessageType.Ack); response.AddOption(DhcpOption.ClassId, Encoding.UTF8.GetBytes("AAPLBSDPC")); response.AddOption(DhcpOption.VendorSpecificInformation, StringToByteArray(VendorInfo)); response.AddOption(DhcpOption.RootPath, Encoding.UTF8.GetBytes(RootPath)); response.SourcePort = message.SourcePort; response.AddOption(DhcpOption.DhcpAddress, _mDhcpInterfaceAddress.GetAddressBytes()); try { var clientIp = response.ClientAddress[0] + "." + response.ClientAddress[1] + "." + response.ClientAddress[2] + "." + response.ClientAddress[3]; _mDhcpSocket.SendTo(response.ToArray(), new IPEndPoint(IPAddress.Parse(clientIp), DhcpClientPort)); } catch (Exception ex) { TraceException("Error Sending Dhcp Reply", ex); return; } Trace.TraceInformation("{0} Dhcp Acknowledge Sent.", Thread.CurrentThread.ManagedThreadId); }
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); // If this client is explicitly allowed, or they are not denied and the allow any flag is set if (this._mAcl.ContainsKey(clientHardwareAddress) && this._mAcl[clientHardwareAddress] || !this._mAcl.ContainsKey(clientHardwareAddress) && this._mAllowAny) { this.SendOffer(message); } else { this.SendNak(message); } }
private void Bsdp(DhcpMessage message) { // Assume we're on an ethernet network var hardwareAddressData = new byte[6]; Array.Copy(message.ClientHardwareAddress, hardwareAddressData, 6); var clientHardwareAddress = new PhysicalAddress(hardwareAddressData); // If this client is explicitly allowed, or they are not denied and the allow any flag is set if (_mAcl.ContainsKey(clientHardwareAddress) && _mAcl[clientHardwareAddress] || !_mAcl.ContainsKey(clientHardwareAddress) && _mAllowAny) { SendAck(message); } else { SendNak(message); } }
private void CompleteRequest(object state) { var messageData = (DhcpData) state; EndPoint source = new IPEndPoint(0, 0); _mAbortLock.AcquireReaderLock(-1); try { if (_mAbort) { return; } messageData.BufferSize = _mDhcpSocket.EndReceiveFrom(messageData.Result, ref source); messageData.Source = (IPEndPoint) source; } catch (SocketException) { return; } catch (Exception ex) { TraceException("Error", ex); return; } finally { _mAbortLock.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); return; } if (message.Operation == DhcpOperation.BootRequest) { var messageVendorIdData = message.GetOptionData(DhcpOption.ClassId); if (messageVendorIdData != null) { var strVendorId = Encoding.Default.GetString(messageVendorIdData); string bootType = null; if (strVendorId.Contains("PXEClient")) bootType = "pxe"; else if (strVendorId.Contains("AAPLBSDPC")) bootType = "bsdp"; else { Trace.TraceInformation("{0} Ignoring, Not A Boot Request", ByteArrayToString(message.ClientHardwareAddress)); return; } if (BsdpMode == "enabled" && bootType == "bsdp") { if (strVendorId.Length >= 14) { if (strVendorId.Substring(0, 14) == "AAPLBSDPC/i386") { var vendorOptions = message.GetOptionData(DhcpOption.VendorSpecificInformation); if (vendorOptions != null) { var strVendorInformation = ByteArrayToString(vendorOptions); if (strVendorInformation.Length >= 12) { if (strVendorInformation.Substring(0, 12) != "010101020201" && strVendorInformation.Substring(0, 12) != "010102020201") { Trace.TraceInformation( "{0} Ignoring, Not An Apple BSDP Request, Vendor Information Mismatch", ByteArrayToString(message.ClientHardwareAddress)); return; } } } else { Trace.TraceInformation("{0} Ignoring, No Vendor Information Data To Parse", ByteArrayToString(message.ClientHardwareAddress)); return; } } else { Trace.TraceInformation("{0} Ignoring, Not An Apple BSDP Request", ByteArrayToString(message.ClientHardwareAddress)); return; } } } } else { Trace.TraceInformation("{0} Ignoring, No Vendor ID Data To Parse", ByteArrayToString(message.ClientHardwareAddress)); return; } var messageTypeData = message.GetOptionData(DhcpOption.DhcpMessageType); if (messageTypeData != null && messageTypeData.Length == 1) { var 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.Inform: Trace.TraceInformation("{0}, {1} Dhcp Inform Message Received.", Thread.CurrentThread.ManagedThreadId, ByteArrayToString(message.ClientHardwareAddress)); Bsdp(message); Trace.TraceInformation("{0} Dhcp Inform Message Processed.", Thread.CurrentThread.ManagedThreadId); break; default: Trace.TraceWarning("Ignoring ({0}) Message On Port 67.", messageType); break; } } else { Trace.TraceWarning("Unknown Dhcp Data Received, Ignoring."); } } else { Trace.TraceInformation("Ignoring, Not a DHCP Boot Request."); } }
private void SendReply(DhcpMessage response,bool success) { response.AddOption(DhcpOption.DhcpAddress, this.m_DhcpInterfaceAddress.GetAddressBytes()); Byte[] sessionId = BitConverter.GetBytes(response.SessionId); if (success) { try { if (response.SourcePort == "4011") { string clientIP = response.ClientAddress[0] + "." + response.ClientAddress[1] + "." + response.ClientAddress[2] + "." + response.ClientAddress[3]; this.m_DhcpSocket.SendTo(response.ToArray(), new IPEndPoint(IPAddress.Parse(clientIP), DhcpClientProxyPort)); } else { string clientIP = response.ClientAddress[0] + "." + response.ClientAddress[1] + "." + response.ClientAddress[2] + "." + response.ClientAddress[3]; this.m_DhcpSocket.SendTo(response.ToArray(), new IPEndPoint(IPAddress.Parse(clientIP), DhcpClientPort)); } } catch (Exception ex) { TraceException("Error Sending Dhcp Reply", ex); return; } } else { try { this.m_DhcpSocket.SendTo(response.ToArray(), new IPEndPoint(IPAddress.Broadcast, DhcpClientPort)); } catch (Exception ex) { TraceException("Error Sending Dhcp Reply", ex); return; } } }
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,false); Trace.TraceInformation("{0} Dhcp Negative Acknowledge Sent.", Thread.CurrentThread.ManagedThreadId); }
private void SendAck(DhcpMessage message) { 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; Byte[] hardwareAddressData = new Byte[6]; Array.Copy(message.ClientHardwareAddress, hardwareAddressData, 6); PhysicalAddress clientHardwareAddress = new PhysicalAddress(hardwareAddressData); if (this.m_Reservations.ContainsKey(clientHardwareAddress)) { response.NextServerAddress = IPAddress.Parse(this.m_Reservations[clientHardwareAddress].ReserveNextServer).GetAddressBytes(); response.BootFileName = Encoding.UTF8.GetBytes(this.m_Reservations[clientHardwareAddress].ReserveBootFile); } else { if (!string.IsNullOrEmpty(UserNextServer)) response.NextServerAddress = IPAddress.Parse(UserNextServer).GetAddressBytes(); else response.NextServerAddress = this.m_DhcpInterfaceAddress.GetAddressBytes(); switch (message.ClientArchitecture) { case "00000": response.BootFileName = Encoding.UTF8.GetBytes(BiosBootFile); break; case "00006": response.BootFileName = Encoding.UTF8.GetBytes(Efi32BootFile); break; case "00007": response.BootFileName = Encoding.UTF8.GetBytes(Efi64BootFile); break; case "00009": response.BootFileName = Encoding.UTF8.GetBytes(Efi64BootFile); break; default: response.BootFileName = Encoding.UTF8.GetBytes(BiosBootFile); break; } } response.ClientAddress = message.ClientAddress; response.ClientHardwareAddress = message.ClientHardwareAddress; response.AddOption(DhcpOption.DhcpMessageType, (Byte)DhcpMessageType.Ack); response.SourcePort = message.SourcePort; this.SendReply(response,true); Trace.TraceInformation("{0} Dhcp Acknowledge Sent.", Thread.CurrentThread.ManagedThreadId); }
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 (SocketException) { return; } catch (Exception ex) { TraceException("Error", ex); return; } finally { this.m_AbortLock.ReleaseLock(); } DhcpMessage message; try { message = new DhcpMessage(messageData); message.SourcePort = messageData.Source.Port.ToString(); } 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); return; } if (message.Operation == DhcpOperation.BootRequest) { Byte[] messageVendorIDData = message.GetOptionData(DhcpOption.ClassId); if (messageVendorIDData != null) { var str = System.Text.Encoding.Default.GetString(messageVendorIDData); if (!str.Contains("PXEClient")) return; else { string[] values = str.Split(':'); if (values.Length >= 3) { message.ClientArchitecture = values[2]; if(message.ClientArchitecture != "00000" && message.ClientArchitecture != "00006" && message.ClientArchitecture!= "00007" && message.ClientArchitecture!="00009") return; } } } else return; Byte[] messageTypeData = message.GetOptionData(DhcpOption.DhcpMessageType); if (messageTypeData != null && messageTypeData.Length == 1) { DhcpMessageType messageType = (DhcpMessageType)messageTypeData[0]; switch (messageType) { 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("Ignoring ({0}) Message On Port 4011.", messageType.ToString()); break; } } else { Trace.TraceWarning("Unknown Dhcp Data Received, Ignoring."); } } }