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; } }
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; }
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); }