Exemple #1
0
        static DHCPArchitecture DetectArch(string ID)
        {
            DHCPArchitecture detectedarch = DHCPArchitecture.Undefined;

            if (ID.StartsWith("PXEClient:Arch:00000") == true)
            {
                detectedarch = DHCPArchitecture.IA32Legacy;
            }
            if (ID.StartsWith("PXEClient:Arch:00001") == true)
            {
                detectedarch = DHCPArchitecture.NEC_PC98;
            }
            if (ID.StartsWith("PXEClient:Arch:00002") == true)
            {
                detectedarch = DHCPArchitecture.EFI_ITANIUM;
            }
            if (ID.StartsWith("PXEClient:Arch:00003") == true)
            {
                detectedarch = DHCPArchitecture.DEC_ALPHA;
            }
            if (ID.StartsWith("PXEClient:Arch:00004") == true)
            {
                detectedarch = DHCPArchitecture.ARC_x86;
            }
            if (ID.StartsWith("PXEClient:Arch:00006") == true)
            {
                detectedarch = DHCPArchitecture.EFI_IA32;
            }
            if (ID.StartsWith("PXEClient:Arch:00007") == true)
            {
                detectedarch = DHCPArchitecture.EFI_ByteCode;
            }
            if (ID.StartsWith("PXEClient:Arch:00008") == true)
            {
                detectedarch = DHCPArchitecture.EFI_XScale;
            }
            if (ID.StartsWith("PXEClient:Arch:00009") == true)
            {
                detectedarch = DHCPArchitecture.EFI_EM64T;
            }
            return(detectedarch);
        }
Exemple #2
0
        public DHCPPacket(byte[] data)
        {
            DHCPHdr = DecodeBytes(data);

            if (DHCPHdr.Magic != 0x63538263)
            {
                Malformed = true;
                return;
            }

            if (DHCPHdr.MACLength > 16)
            {
                Malformed = true;
                return;
            }

            for (int i = 0xF0; i < data.Length;)
            {
                if (data[i] == 0xFF)
                {
                    break;
                }

                if (data.Length - i < 2)
                {
                    Malformed = true;
                    break;
                }

                DHCPOption o = new DHCPOption();
                o.Type = data[i + 0];
                o.Size = data[i + 1];

                if (o.Type == 0 || o.Size == 0)
                {
                    Malformed = true;
                    break;
                }

                if (data.Length - (i + o.Size) < 0)
                {
                    Malformed = true;
                    break;
                }

                o.Data = new byte[o.Size];
                Buffer.BlockCopy(data, i + 2, o.Data, 0, o.Size);

                DHCPOptions.Add(o);

                i += 2 + o.Size;
            }

            foreach (DHCPOption o in DHCPOptions)
            {
                switch (o.Type)
                {
                case 97:
                    if (o.Size != 17)
                    {
                        Malformed = true;
                        continue;
                    }
                    DHCP97ClientUUID = BytesToString(o.Data, 1);
                    break;

                case 61:
                    //if (o.Size != 17)
                    //{
                    //    Malformed = true;
                    //    continue;
                    //}
                    DHCP61ClientGUID = BytesToString(o.Data, 1);
                    break;

                case 55:
                    DHCP9ReqParameterList = new List <byte>();
                    foreach (byte b in o.Data)
                    {
                        if (b == 0 || b == 0xff)
                        {
                            Malformed = true;
                        }
                        if (DHCP9ReqParameterList.Contains(b) == false)
                        {
                            DHCP9ReqParameterList.Add(b);
                        }
                    }
                    break;

                case 53:
                    if (o.Size != 1)
                    {
                        Malformed = true;
                        continue;
                    }
                    DHCP53MessageType = (DHCPMessageType)o.Data[0];
                    break;

                case 57:
                    if (o.Size != 2)
                    {
                        Malformed = true;
                        continue;
                    }
                    DHCP57MessageLength = BitConverter.ToUInt16(o.Data.Reverse().ToArray(), 0);
                    break;

                case 60:
                    if (o.Size != 32)
                    {
                        Malformed = true;
                        continue;
                    }
                    DHCP60ClassIdentifier = Encoding.ASCII.GetString(o.Data);
                    break;

                case 66:
                    DHCP66BootServer = Encoding.ASCII.GetString(o.Data).NullTrim();
                    break;

                case 67:
                    DHCP67BootFilename = Encoding.ASCII.GetString(o.Data).NullTrim();
                    break;

                case 93:
                    if (o.Size != 2)
                    {
                        Malformed = true;
                        continue;
                    }
                    DHCP93Architecture = (DHCPArchitecture)BitConverter.ToUInt16(o.Data.Reverse().ToArray(), 0);
                    break;

                case 94:
                    if (o.Size != 3)
                    {
                        Malformed = true;
                        continue;
                    }
                    if (o.Data[0] == 1)
                    {
                        DHCP94ClientNIC = "UNDI.";
                    }
                    else
                    {
                        DHCP94ClientNIC = "UNKN.";
                    }
                    DHCP94ClientNIC += o.Data[1].ToString("0") + "." + o.Data[2].ToString("0");
                    break;

                default:
                    Debug.WriteLine("Unknown code: " + o.Type.ToString() + " (0x" + o.Type.ToString("X2") + ")");
                    break;
                }
            }

            Flags         = DHCPHdr.Flags;
            OperationCode = DHCPHdr.OperationCode;
            HardwareType  = DHCPHdr.HardwareType;
            XID           = DHCPHdr.XID;
            IPClient      = new IPAddress(DHCPHdr.CIAddr);
            IPYours       = new IPAddress(DHCPHdr.YIAddr);
            IPServer      = new IPAddress(DHCPHdr.SIAddr);
            IPGateway     = new IPAddress(DHCPHdr.GIAddr);
            MacAddress    = new byte[DHCPHdr.MACLength];
            Buffer.BlockCopy(DHCPHdr.CHAddr, 0, MacAddress, 0, DHCPHdr.MACLength);
            Servername = Encoding.ASCII.GetString(DHCPHdr.SName).NullTrim();
            BootFile   = Encoding.ASCII.GetString(DHCPHdr.File).NullTrim();
        }
Exemple #3
0
        public bool RegisterSession(IPAddress Client, DHCPArchitecture Architecture, string PathOverride)
        {
            if (Client == IPAddress.Any)
            {
                return(false);
            }

            lock (RunningSessions)
            {
                if (RunningSessions.ContainsKey(Client) == true)
                {
                    if (RunningSessions[Client].currentfile != null)
                    {
                        RunningSessions[Client].currentfile.Close();
                    }
                    RunningSessions.Remove(Client);
                }
            }

            SessionData ses = new SessionData();

            ses.Architecture = Architecture;
            ses.IP           = Client;
            ses.TFTPRootPath = Settings.TFTPRootPath;

            if (string.IsNullOrWhiteSpace(PathOverride) == false)
            {
                ses.TFTPRootPath += PathOverride;
                if (ses.TFTPRootPath.EndsWith("\\") == false)
                {
                    ses.TFTPRootPath += "\\";
                }
                if (Directory.Exists(ses.TFTPRootPath) == false)
                {
                    PathOverride     = "";
                    ses.TFTPRootPath = Settings.TFTPRootPath;
                }
            }

            if (string.IsNullOrWhiteSpace(PathOverride) == true)
            {
                switch (Architecture)
                {
                case DHCPArchitecture.ARC_x86:
                    ses.TFTPRootPath += "ARC x86\\"; break;

                case DHCPArchitecture.DEC_ALPHA:
                    ses.TFTPRootPath += "DEC Alpha\\"; break;

                case DHCPArchitecture.EFI_ByteCode:
                    ses.TFTPRootPath += "EFI BC\\"; break;

                case DHCPArchitecture.EFI_EM64T:
                    ses.TFTPRootPath += "EFI X64\\"; break;

                case DHCPArchitecture.EFI_IA32:
                    ses.TFTPRootPath += "EFI X86\\"; break;

                case DHCPArchitecture.EFI_ITANIUM:
                    ses.TFTPRootPath += "EFI ITANIUM\\"; break;

                case DHCPArchitecture.EFI_XScale:
                    ses.TFTPRootPath += "EFI XScale\\"; break;

                case DHCPArchitecture.IA32Legacy:
                    ses.TFTPRootPath += "BIOS\\"; break;

                case DHCPArchitecture.NEC_PC98:
                    ses.TFTPRootPath += "NEC PC98\\"; break;

                default:
                    ses.TFTPRootPath += "Unknown\\"; break;
                }
            }

            lock (RunningSessions)
                RunningSessions.Add(Client, ses);

            return(true);
        }
Exemple #4
0
        static void recv4011(IAsyncResult res)
        {
            UdpClient u;

            try
            {
                u = (UdpClient)res.AsyncState;
            }
            catch
            {
                FoxEventLog.WriteEventLog("Invalid packet on UDP 4011", System.Diagnostics.EventLogEntryType.Warning);
                return;
            }
            try
            {
                IPEndPoint ip = new IPEndPoint(IPAddress.Any, 0);
                byte[]     buffer;

                try
                {
                    buffer = u.EndReceive(res, ref ip);
                }
                catch
                {
                    return;
                }

                DHCPPacket       dhcppacket   = new DHCPPacket(buffer);
                DHCPArchitecture detectedarch = DHCPArchitecture.Undefined;

                if (dhcppacket.Malformed == true)
                {
                    return;
                }
                if (dhcppacket.OperationCode != DHCPOperationCode.ClientToServer)
                {
                    return;
                }
                if (dhcppacket.DHCP53MessageType != DHCPMessageType.DHCPREQUEST)
                {
                    return;
                }
                if (dhcppacket.DHCP60ClassIdentifier.StartsWith("PXEClient") == false)
                {
                    return;
                }
                detectedarch = DetectArch(dhcppacket.DHCP60ClassIdentifier);
                //if (detectedarch == DHCPArchitecture.Undefined)
                //    return;

                string MACAddr  = dhcppacket.GetMacAddress();
                string BootFile = "bootmgfw.efi";
                string BootPath = null;

                do
                {
                    using (RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Fox\\PXEBoot\\MAC\\" + MACAddr))
                    {
                        if (key != null)
                        {
                            object o = key.GetValue("BootFile");
                            if (o != null)
                            {
                                BootFile = Convert.ToString(o);
                            }

                            o = key.GetValue("Path");
                            if (o != null)
                            {
                                BootPath = Convert.ToString(o);
                            }
                            break;
                        }
                    }
                    if (MACAddr.Length <= 2)
                    {
                        break;
                    }
                    MACAddr = MACAddr.Substring(0, MACAddr.Length - 2);
                } while (MACAddr.Length > 0);

                Session.RegisterSession(ip.Address, detectedarch, BootPath);

                DHCPPacket send = new DHCPPacket();
                send.MacAddress                  = dhcppacket.MacAddress;
                send.XID                         = dhcppacket.XID;
                send.DHCP53MessageType           = DHCPMessageType.DHCPACK;
                send.WantedDHCP9ParameterList    = DHCPPacket.DHCP9ParameterListBootFiles;
                send.SupportedDHCP9ParameterList = dhcppacket.DHCP9ReqParameterList;
                send.DHCP60ClassIdentifier       = "PXEClient";
                send.DHCP66BootServer            = GetCurrentIP().ToString();
                send.DHCP67BootFilename          = BootFile;

                //send.BootFile = "bootmgfw.efi";
                //send.Servername = GetCurrentIP().ToString();

                if (detectedarch == DHCPArchitecture.IA32Legacy)
                {
                    send.DHCP43VendorSpecificInfo = new byte[] { 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff };
                    send.WantedDHCP9ParameterList.Add(43);
                }

                byte[] data = send.GetBytes();
                if (data == null)
                {
                    return;
                }

                SendData(UDP4011, 4011, ip.Address, data);
                SendData(UDP4011, 68, IPAddress.Broadcast, data);

                Console.WriteLine(ip.Address.ToString() + " DHCP ack sent (System: " + detectedarch.ToString() + ")");
            }
            finally
            {
                if (RunService == true)
                {
                    try
                    {
                        u.BeginReceive(new AsyncCallback(recv4011), u);
                    }
                    catch
                    {
                        try
                        {
                            Thread.Sleep(1000);
                            u.BeginReceive(new AsyncCallback(recv4011), u);
                        }
                        catch
                        {
                            FoxEventLog.WriteEventLog("Cannot reset port 4011", System.Diagnostics.EventLogEntryType.Error);
                            Process.GetCurrentProcess().Kill();
                        }
                    }
                }
            }
        }