Beispiel #1
0
		/// <summary>
		/// Returns the offset of the specified DHCP option in the Packet.
		/// </summary>
		/// <param name="packet">The DHCP Packet</param>
		/// <param name="option">The DHCP Option</param>
		/// <returns>This function returns 0 if the DHCP option is not in the packet.</returns>
		public static int GetOptionOffset(ref DHCPPacket packet, Definitions.DHCPOptionEnum option)
		{
			for (var i = 0; i < packet.Data.Length; i++)
				if (packet.Data[i] == Convert.ToInt32(option))
					return i;

			return 0;
		}
Beispiel #2
0
 internal void Send(ref DHCPPacket packet, IPEndPoint endpoint)
 {
     switch (packet.Type)
     {
         case SocketType.DHCP:
             this.DHCPsocket.Send(endpoint, packet.Data, packet.Offset);
             break;
         case SocketType.BINL:
             this.BINLsocket.Send(endpoint, packet.Data, packet.Offset);
             break;
         default:
             break;
     }
 }
Beispiel #3
0
        internal override void DataReceived(object sender, DataReceivedEventArgs e)
        {
            switch (int.Parse(Exts.GetDataAsString(e.Data, 0, 1)))
            {
                case (int)BootMessageType.Request:
                    #region "BOTP - Request"
                    using (var request = new DHCPPacket(e.Data))
                    {
                        request.Type = e.Type;

                        var optvalue = Exts.GetOptionValue(e.Data, DHCPOptionEnum.Vendorclassidentifier);
                        if (optvalue.Length < 1 || optvalue[0] == byte.MaxValue || e.Data[0] != (byte)BootMessageType.Request)
                            return;

                        var cguid = Exts.GetOptionValue(request.Data, DHCPOptionEnum.GUID);
                        if (cguid.Length == 1)
                            return;

                        var guid = Guid.Parse(Exts.GetGuidAsString(cguid, cguid.Length, true));

                        var clientMAC = Exts.GetDataAsString(request.MacAddress, 0, request.MACAddresslength);
                        var clientTag = "{0}-{1}".F(guid, clientMAC);

                        if (!Clients.ContainsKey(clientTag))
                            Clients.Add(clientTag, new DHCPClient(guid, clientMAC, request.Type, e.RemoteEndpoint));
                        else
                        {
                            Clients[clientTag].Type = request.Type;
                            Clients[clientTag].EndPoint = e.RemoteEndpoint;
                        }

                        var c = Clients[clientTag];
                        switch (request.MessageType)
                        {
                            case DHCPMsgType.Request:
                                if (e.RemoteEndpoint.Address != IPAddress.None)
                                    this.Handle_DHCP_Request(request, ref c);
                                break;
                            case DHCPMsgType.Discover:
                                this.Handle_DHCP_Request(request, ref c);
                                break;
                            case DHCPMsgType.Release:
                                if (Clients.ContainsKey(clientTag))
                                    Clients.Remove(clientTag);
                                break;
                            default:
                                return;
                        }
                    }
                    #endregion
                    break;
                case (int)BootMessageType.RISRequest:
                    #region "RIS - Request"
                    var packet = new RISPacket(e.Data);
                    var client = new RISClient(e.RemoteEndpoint);

                    switch (packet.RequestType)
                    {
                        case "RQU":
                        case "REQ":
                            packet.OPCode = packet.RequestType == "REQ" ? RISOPCodes.REQ : RISOPCodes.RQU;
                            this.Handle_RIS_Request(packet, ref client, packet.RequestType == "REQ" ? true : false);
                            break;
                        case "NEG":
                        case "AUT":
                            packet.OPCode = packet.RequestType == "NEG" ? RISOPCodes.NEG : RISOPCodes.AUT;
                            this.Handle_RIS_Request(packet, ref client);
                            break;
                        case "NCQ":
                            packet.OPCode = RISOPCodes.NCQ;
                            this.Handle_RIS_Request(packet, ref client);
                            break;
                        default:
                            Errorhandler.Report(LogTypes.Info, "Got Unknown RIS Packet ({0})".F(packet.RequestType));
                            break;
                    }
                    #endregion
                    break;
                case (int)BootMessageType.RISReply:
                default:
                    break;
            }
        }
Beispiel #4
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;
            }
        }