예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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.");
            }
        }
예제 #7
0
        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;
                }
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        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.");
                }
            }
        }