Exemplo n.º 1
0
        public void Handle_DHCP_Request(DHCPPacket packet, ref DHCPClient client)
        {
            var parameterlist_offset = Functions.GetOptionOffset(ref packet, DHCPOptionEnum.ParameterRequestList);
            var parameterlistLength = packet.Data[(parameterlist_offset + 1)];
            var bootitem = (short)0;
            var pktlength = (ushort)1024;

            if (parameterlist_offset != 0)
                Array.Clear(packet.Data, parameterlist_offset, parameterlistLength);

            var vendoroffset = Functions.GetOptionOffset(ref packet, DHCPOptionEnum.Vendorclassidentifier);
            if (vendoroffset == 0)
                return;

            var vendor_str = Encoding.ASCII.GetString(packet.Data, vendoroffset + 2, packet.Data[vendoroffset + 1]);

            if (vendor_str.Contains("PXEClient"))
            {
                client.VendorIdent = "PXEClient";

                // Option contains additional Informations!
                if (vendor_str.Contains(":"))
                {
                    var vendor_parts = vendor_str.Split(':');
                    if (vendor_parts.Length > 1)
                    {
                        client.PXEFramework = PXEFrameworks.UNDI;
                        if (vendor_parts[1] == "ARCH")
                            client.Arch = (Architecture)short.Parse(vendor_parts[2]);

                        if (vendor_parts[3] == "UNDI")
                        {
                            client.UNDI_Major = short.Parse(vendor_parts[4].Substring(0, 3).Replace("00", string.Empty));
                            client.UNDI_Minor = short.Parse(vendor_parts[4].Substring(3, 3).Replace("00", string.Empty));
                        }
                    }
                }
            }
            else
                return;

            var response = new DHCPPacket(new byte[pktlength]);
            Array.Copy(packet.Data, 0, response.Data, 0, 242);

            response.BootpType = BootMessageType.Reply;
            response.ServerName = Settings.ServerName;
            response.NextServer = Settings.ServerIP;
            response.Type = client.Type;
            response.Offset += 243;

            if (Functions.GetOptionOffset(ref packet, DHCPOptionEnum.WDSNBP) != 0)
                client.IsWDSClient = true;
            else
                client.IsWDSClient = false;

            switch (packet.Type)
            {
                case SocketType.DHCP:
                    client.MsgType = DHCPMsgType.Offer;
                    break;
                case SocketType.BINL:

                    client.MsgType = DHCPMsgType.Ack;
                    break;
                default:
                    Clients.Remove(client.ID);
                    return;
            }

            // Option 53
            response.MessageType = client.MsgType;

            // Option 60
            var opt = Exts.SetDHCPOption(DHCPOptionEnum.Vendorclassidentifier, Exts.StringToByte(client.VendorIdent));

            Array.Copy(opt, 0, response.Data, response.Offset, opt.Length);
            response.Offset += opt.Length;

            // Option 54
            var dhcpident = Exts.SetDHCPOption(DHCPOptionEnum.ServerIdentifier, Settings.ServerIP.GetAddressBytes());

            Array.Copy(dhcpident, 0, response.Data, response.Offset, dhcpident.Length);
            response.Offset += dhcpident.Length;

            // Option 97
            var guidopt = Exts.SetDHCPOption(DHCPOptionEnum.GUID, Exts.GetOptionValue(packet.Data, DHCPOptionEnum.GUID));

            Array.Copy(guidopt, 0, response.Data, response.Offset, guidopt.Length);
            response.Offset += guidopt.Length;

            // Bootfile
            response.Bootfile = client.BootFile;

            Functions.SelectBootFile(ref client, client.IsWDSClient, client.NextAction);

            // Option 53
            response.MessageType = client.MsgType;

            if (Settings.Servermode == ServerMode.AllowAll)
                client.ActionDone = true;

            // Option 94
            var cii = new byte[3];
            cii[0] = Convert.ToByte(client.PXEFramework);
            cii[1] = Convert.ToByte(client.UNDI_Major);
            cii[2] = Convert.ToByte(client.UNDI_Minor);

            var clientIFIdent = Exts.SetDHCPOption(DHCPOptionEnum.ClientInterfaceIdent, cii);
            Array.Copy(clientIFIdent, 0, response.Data, response.Offset, clientIFIdent.Length);
            response.Offset += clientIFIdent.Length;

            if (Settings.DHCP_DEFAULT_BOOTFILE.ToLowerInvariant().Contains("pxelinux"))
            {
                var magicstring = Exts.SetDHCPOption(DHCPOptionEnum.MAGICOption, BitConverter.GetBytes(0xf100747e));
                Array.Copy(magicstring, 0, response.Data, response.Offset, magicstring.Length);
                response.Offset += magicstring.Length;
            }

            // Option 252 - BCDStore
            if (client.BCDPath != null && client.ActionDone && client.IsWDSClient)
            {
                var bcdstore = Exts.SetDHCPOption(DHCPOptionEnum.BCDPath, Exts.StringToByte(client.BCDPath));

                Array.Copy(bcdstore, 0, response.Data, response.Offset, bcdstore.Length);
                response.Offset += bcdstore.Length;
            }

            if (Settings.AdvertPXEServerList && Servers.Count > 0 && client.UNDI_Major > 1)
            {
                var optionoffset = Functions.GetOptionOffset(ref packet, DHCPOptionEnum.VendorSpecificInformation);
                if (optionoffset != 0)
                {
                    var data = new byte[packet.Data[optionoffset + 1]];

                    Array.Copy(packet.Data, optionoffset + 2, data, 0, packet.Data[optionoffset + 1]);

                    switch (data[0])
                    {
                        case (byte)Definitions.PXEVendorEncOptions.BootItem:
                            bootitem = BitConverter.ToInt16(data, 2);
                            break;
                        default:
                            break;
                    }
                }

                // Option 43:8
                var pxeservers = Functions.GenerateServerList(ref Servers, bootitem);
                if (pxeservers != null)
                {
                    var vendoropt = Exts.SetDHCPOption(DHCPOptionEnum.VendorSpecificInformation, pxeservers, true);
                    Array.Copy(vendoropt, 0, response.Data, response.Offset, vendoropt.Length);
                    response.Offset += vendoropt.Length;

                    response.Data[response.Offset] = Convert.ToByte(DHCPOptionEnum.End);
                    response.Offset += 1;
                }

                if (bootitem != 254 && bootitem != 0)
                {
                    var server = (from s in Servers where s.Value.Ident == bootitem select s.Value.Hostname).FirstOrDefault();

                    if (Clients.ContainsKey(client.ID))
                        Clients.Remove(client.ID);

                    response.NextServer = Servers[server].IPAddress;
                    response.Bootfile = Servers[server].Bootfile;
                    response.ServerName = Servers[server].Hostname;
                }
            }

            // Windows Deployment Server (WDSNBP Options)
            var wdsnbp = Exts.SetDHCPOption(DHCPOptionEnum.WDSNBP, this.Handle_WDS_Options(client.AdminMessage, ref client));
            Array.Copy(wdsnbp, 0, response.Data, response.Offset, wdsnbp.Length);
            response.Offset += wdsnbp.Length;

            // End of Packet (255)
            var endopt = new byte[1];
            endopt[0] = Convert.ToByte(DHCPOptionEnum.End);

            Array.Copy(endopt, 0, response.Data, response.Offset, endopt.Length);
            response.Offset += endopt.Length;

            switch (packet.Type)
            {
                case SocketType.DHCP:
                    this.Send(ref response, client.EndPoint);
                    break;
                case SocketType.BINL:
                    if (client.IsWDSClient)
                        if (client.ActionDone)
                        {
                            this.Send(ref response, client.EndPoint);
                            Clients.Remove(client.ID);
                            client = null;
                            requestid += 1;
                        }
                        else
                            break;
                    else
                        this.Send(ref response, client.EndPoint);
                    break;
                default:
                    break;
            }
        }
Exemplo n.º 2
0
        internal byte[] Handle_WDS_Options(string adminMessage, ref DHCPClient client)
        {
            var offset = 0;

            #region "Create Response Options"
            var nextaction = Functions.GenerateDHCPEncOption(Convert.ToByte(WDSNBPOptions.NextAction),
            sizeof(byte), BitConverter.GetBytes(Convert.ToByte(client.NextAction)));
            var length = nextaction.Length;

            var val = BitConverter.GetBytes(Convert.ToInt32(requestid));
            Array.Reverse(val);
            var reqid = Functions.GenerateDHCPEncOption(Convert.ToByte(WDSNBPOptions.RequestID), 4, val);
            length += reqid.Length;

            val = BitConverter.GetBytes(client.PollInterval);
            Array.Reverse(val);
            var pollintervall = Functions.GenerateDHCPEncOption(Convert.ToByte(WDSNBPOptions.PollInterval), 2, val);
            length += pollintervall.Length;

            val = BitConverter.GetBytes(client.RetryCount);
            Array.Reverse(val);
            var retrycount = Functions.GenerateDHCPEncOption(Convert.ToByte(WDSNBPOptions.PollRetryCount), 2, val);
            length += retrycount.Length;

            val = Exts.StringToByte(adminMessage);
            var message = Functions.GenerateDHCPEncOption(Convert.ToByte(WDSNBPOptions.Message), val.Length, val);
            length += message.Length;

            val = BitConverter.GetBytes(Convert.ToByte(client.BootFile != string.Empty && client.ActionDone && client.IsWDSClient ? 1 : 0));
            var actionDone = Functions.GenerateDHCPEncOption(Convert.ToByte(WDSNBPOptions.ActionDone), 1, val);
            length += actionDone.Length;

            /*
            val = IPAddress.Parse("192.168.1.1").GetAddressBytes();
            var referalserver = Functions.GenerateDHCPEncOption(Convert.ToByte(WDSNBPOptions.ReferralServer), val.Length, val);
            length += referalserver.Length;
            */

            var wdsend = BitConverter.GetBytes(Convert.ToByte(WDSNBPOptions.End));
            length += 1;

            var wdsBlock = new byte[length];
            Functions.CopyTo(ref actionDone, 0, ref wdsBlock, 0, actionDone.Length);
            offset = 3;

            Functions.CopyTo(ref nextaction, 0, ref wdsBlock, offset, nextaction.Length);
            offset += nextaction.Length;

            Functions.CopyTo(ref pollintervall, 0, ref wdsBlock, offset, pollintervall.Length);
            offset += pollintervall.Length;

            Functions.CopyTo(ref retrycount, 0, ref wdsBlock, offset, retrycount.Length);
            offset += retrycount.Length;

            Functions.CopyTo(ref reqid, 0, ref wdsBlock, offset, reqid.Length);
            offset += reqid.Length;

            /*
            if (client.NextAction == NextActionOptionValues.Referral)
            {
                Functions.CopyTo(ref referalserver, 0, ref wdsBlock, offset, referalserver.Length);
                offset += referalserver.Length;
            }
            */

            Functions.CopyTo(ref message, 0, ref wdsBlock, offset, message.Length);
            offset += message.Length;

            Functions.CopyTo(ref wdsend, 0, ref wdsBlock, offset, 1);
            #endregion

            return wdsBlock;
        }
Exemplo n.º 3
0
		public static void SelectBootFile(ref DHCPClient client, bool wdsclient, Definitions.NextActionOptionValues nextaction)
		{
			if (wdsclient)
				switch (client.Arch)
				{
					case Definitions.Architecture.Intelx86PC:
						if (nextaction == Definitions.NextActionOptionValues.Approval)
						{
							client.BootFile = Path.Combine(Settings.WDS_BOOT_PREFIX_X86, Settings.WDS_BOOTFILE_X86);
							client.BCDPath = Path.Combine(Settings.WDS_BOOT_PREFIX_X86, Settings.WDS_BCD_FileName);
						}
						else
						{
							client.BootFile = Path.Combine(Settings.WDS_BOOT_PREFIX_X86, Settings.WDS_BOOTFILE_ABORT);
						}

						break;
					case Definitions.Architecture.EFIItanium:
						if (nextaction == Definitions.NextActionOptionValues.Approval)
						{
							client.BootFile = Path.Combine(Settings.WDS_BOOT_PREFIX_IA64, Settings.WDS_BOOTFILE_IA64);
							client.BCDPath = Path.Combine(Settings.WDS_BOOT_PREFIX_IA64, Settings.WDS_BCD_FileName);
						}
						else
						{
							client.BootFile = Path.Combine(Settings.WDS_BOOT_PREFIX_IA64, Settings.WDS_BOOTFILE_ABORT);
						}

						break;
					case Definitions.Architecture.EFIx8664:
						if (nextaction == Definitions.NextActionOptionValues.Approval)
						{
							client.BootFile = Path.Combine(Settings.WDS_BOOT_PREFIX_X64, Settings.WDS_BOOTFILE_X64);
							client.BCDPath = Path.Combine(Settings.WDS_BOOT_PREFIX_X64, Settings.WDS_BCD_FileName);
						}
						else
						{
							client.BootFile = Path.Combine(Settings.WDS_BOOT_PREFIX_X64, Settings.WDS_BOOTFILE_ABORT);
						}

						break;
					case Definitions.Architecture.EFIBC:
						if (nextaction == Definitions.NextActionOptionValues.Approval)
						{
							client.BootFile = Path.Combine(Settings.WDS_BOOT_PREFIX_EFI, Settings.WDS_BOOTFILE_EFI);
							client.BCDPath = Path.Combine(Settings.WDS_BOOT_PREFIX_EFI, Settings.WDS_BCD_FileName);
						}
						else
						{
							client.BootFile = Path.Combine(Settings.WDS_BOOT_PREFIX_EFI, Settings.WDS_BOOTFILE_ABORT);
						}

						break;
					default:
						client.BootFile = Path.Combine(Settings.WDS_BOOT_PREFIX_X86, Settings.WDS_BOOTFILE_X86);
						client.BCDPath = Path.Combine(Settings.WDS_BOOT_PREFIX_X86, Settings.WDS_BCD_FileName);
						break;
				}
			else
				client.BootFile = Path.Combine(Settings.WDS_BOOT_PREFIX_X86, Settings.DHCP_DEFAULT_BOOTFILE);
		}